二、AEN报文的处理
控制端口连接状态变化的AEN报文,主要是通过插拔网线引起,由网卡发送给系统内核驱动处理,控制网卡端口连接状态。
ncsi_rcv_rsp函数中,判断是否是aen报文,Packet type为NCSI_PKT_AEN 0xff,调用aen报
问处理函数ncsi_aen_handler
控制端口连接状态变化的ncsi aen报文的type是NCSI_PKT_AEN_LSC 0x00, 调用ncsi_aen_handler_lsc
如果端口原来是连接的,又来一个up的aen报文,不处理。不连接也是一样
另外,如果已经正在处理aen报文,再来一个aen报文,不处理(是否合理?有部分网卡插拔网线会连续发多个信号)
chained = !list_empty(&nc->link); nc->link 理解是连接状态发生变化的节点
如果端口原来是连接的,又来一个up的aen报文,不处理。不连接也是一样
另外,如果已经正在处理aen报文,再来一个aen报文,不处理(是否合理?有部分网卡插拔网线会连续发多个信号)
chained = !list_empty(&nc->link); nc->link 理解是连接状态发生变化的节点
Aen报文中会携带报文来自于哪个package,channel,是连接是down还是up等信息。
这里先要来说下,这四个变量
ndp->multi_package 如果为1
系统允许有多张网卡支持ncsi
nc->package->multi_channel 如果为1
系统允许一张网卡上有多个端口支持ncsi,但不代表可以同时多个端口都作为ncsi通道的使用口。一般来说,1张4端口的网卡,只能选择其中一个端口作为ncsi通道的使用口,这个端口的是active的,且TX是打开的。其他3个端口也是active的,但是TX是关闭的。如果有多个端口连接网络,那么第一个连接着网络的端口作为ncsi通道的使用口;此端口网络断开,重新从1到4端口查找第一个连接着网络的端口。如果没有其他端口连接网络,则默认构建active第一个端口,TX打开,即端口1。
为什么所有端口是active的?因为系统内核aen报文的接收会受到端口ncsi inactive影响。如果端口是ncsi inactive的,端口插拔网线,内核就不会接收到该端口的up的aen报文。
虽然所有端口都active了,但是只有其中一个端口的TX会打开,其他TX关闭的端口,网络断开连接发送的aen报文,不作处理。
TX开启意思是可以通过端口网线向外发包,TX的打开和关闭是ncsi命令控制的,ncsi命令的发送不受TX,RX开启关闭的影响。Aen报文则会受到影响。
ndp->package_whitelist
package白名单,只有白名单内的package,允许被active。
np->channel_whitelist
channel白名单,只有白名单内的channel,允许被active,且TX是打开的。如果白名单内有多个端口,只有第一个连接网络的端口会被active,且TX打开。其他白名单内的端口都是inactive的(在ncsi_choose_active_channel函数中,其他端口不会加到channel_queue里面,所以不会去active)。如果所有白名单内的端口都没有连接网络,那么会默认会active第一个白名单内的端口,且TX打开。
白名单变量规则:
package->channel_whitelist = 0x1 << channel->id;
端口0在白名单里,channel->id为0,channel_whitelist为0x1
端口0,1在白名单里,channel_whitelist为0x11
所有端口都在白名单里,channel_whitelist为UINT_MAX
收到aen报文,这里又分两种情况:
ndp->multi_package,nc->package->multi_channel是否允许多个package,channel
1.不支持多个package,channel,只允许active单个端口。
这种情况下,只处理down的事件,ncsi_suspend_channel函数disable掉端口;ncsi_configure_channel函数enable端口,ncsi_channel_is_tx函数会判断是否端口TX是否需要打开。白名单内第一个插着网线的端口active,TX打开;都没插着网线,第一个白名单内的端口active,TX打开。
这个函数的逻辑真的很严谨,包含了所有的情况。multi_channel时,ndp->channel_queue有网卡的所有端口,channel_whitelist时,ndp->channel_queue只有需要enable的端口。
2.支持多个package,channel,允许active多个端口。
断开网络时if (had_link),需要从第一个端口开始检测是否其他端口连接网络ncsi_update_tx_channel,如果有,使用该端口。如果没有,重置ncsi_reset_dev,重新选择使用端口。
连接网络时,else if (has_link),原来TX打开的端口TX关掉,连接网络的端口TX打开即可。