‌‌‌  网络中传递着各种各样的数据包,当设备连接到网络后,为了减少对接收到的数据进行处理的负荷,就需要对设备接收到的数据包进行过滤。STM32MCU 的以太网外设提供多种数据包过滤的模式。可以根据以太网帧的目标 MAC  地址,源 MAC 地址进行过滤,STM32H7系列还提供对 VLANtag 和 IP 地址,UDP/TCP 端口的过滤。

‌‌‌  拿 MAC地址过滤来说,SM32MCU支持:单播目标地址过滤,多播目标地址过滤,单播源地址过滤和广播地址过滤。单播目标地址过滤和多播目标地址过滤又分为:Perfect地址过滤和 Hash地址过滤

‌‌‌  perfect地址过滤就是把接收到的以太网帧中的目标地址与 MAC地址寄存器中保存的地址进行比较,如果匹配,数据包就被接受,否则就被丢掉。还可以通过设置“反向过滤”,来翻转过滤的结果,接收到的以太网帧中的目标地址与MAC地址寄存器中保存的地址如果不匹配,数据包就被接收,否则就被丢掉。

‌‌‌  Hash 地址过滤不是直接比较 MAC 地址,而是计算目标 MAC 地址的 CRC32值,取其高 6位作为索引去查询 Hash 表寄存器中对应的值,来判断是否接收该数据帧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
‌‌‌  * The hash address register is 64 bits long and takes up two locations in the memory map.
* The least significant bits are stored in EMAC_HSL and the most significant
* bits in EMAC_HSH.
*
* The unicast hash enable and the multicast hash enable bits in the network configuration
* register enable the reception of hash matched frames. The destination address is
* reduced to a 6 bit index into the 64 bit hash register using the following hash function.
* The hash function is an exclusive or of every sixth bit of the destination address.
* hash_index[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
* hash_index[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
* hash_index[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
* hash_index[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
* hash_index[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
* hash_index[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
* da[0] represents the least significant bit of the first byte received, that is, the multicast/
* unicast indicator, and da[47] represents the most significant bit of the last byte
* received.
* If the hash index points to a bit that is set in the hash register then the frame will be
* matched according to whether the frame is multicast or unicast.
* A multicast match will be signalled if the multicast hash enable bit is set, da[0] is 1 and
* the hash index points to a bit set in the hash register.
* A unicast match will be signalled if the unicast hash enable bit is set, da[0] is 0 and the
* hash index points to a bit set in the hash register.
* To receive all multicast frames, the hash register should be set with all ones and the
* multicast hash enable bit should be set in the network configuration register.

过滤原理

‌‌‌  在 Hash 地址过滤模式下,以太网 MAC 通过一张 64位的 Hash 表来进行过滤,表中的每一位对应一个 MAC 地址。这张表存储在两个 32位的寄存器中 ( 在 dm 9051 中是 8 个 8 位寄存器,在 dm 9051 驱动中是 4 个 16 位变量 )。STM32H743的寄存器 ETH_MACHT0R 保存着 Hash 表的前 32位,ETH_MACHT1R 中保存着 Hash 表的后 32位值。

‌‌‌  MAC 接收到以太网帧后,会自动计算目标 MAC 地址的 CRC 值,然后用该 CRC 值的高 6位,作为索引号去前面提到的 Hash 表寄存器中查找对应位(具体的 6 位索引和 Hash 表 64 位数据一一对应关系根据不同的 MAC 控制器有所不同)。查找后如果该位的值是 1,则收到的以太网帧通过。否则就丢掉。例如,计算出的 CRC 高6位是 0,则对应 ETH_MACHT0R 的 bit0,如果该位是 1,则接收该帧。

‌‌‌  因此对于组播来说,在初始化的时候,应该根据想要接收的目标 MAC 地址,提前设置好 Hash 表寄存器的值。

‌‌‌  注意:
‌‌‌  Hash 地址过滤将 48位的 MAC 地址,对应到 6位的 Hash 值,肯定会出现多个 MAC 地址对应到一个 6位 Hash 值的情况,所以这种过滤方式也被称作 imperfect 过滤模式。

‌‌‌  对于整个组播流程来说:
‌‌‌  1. IP 映射到组播虚拟 MAC 地址时,32 位 IP 映射为 23 位 MAC 地址
‌‌‌  2. MAC 过滤时,23 位 MAC 经过 CRC 后只剩 6 位索引值
‌‌‌  3. 必然存在多个组播地址映射到一个 MAC ,多个 MAC 映射到同一个 Hash 索引的情况
‌‌‌  4. 进一步过滤需要到网络层通过 IP 进行过滤