Intel 82599 ixgbe & ixgbevf CNA 卡驱动分析03——部分功能代码分析

I/O Operations and Activities
 
     使用SR-IOV 的根本原因就是使得虚拟机中的一个驱动可以直接访问PCI进行I/O操作,并能够在虚拟机之间共享设备。Intel VF 驱动了解自己运行在一个虚拟化的环境中拥有优先的PCI资源。
     
     可用的资源包括基本的接收和发送以太网包的能力,Intel VF 还提供了额外的硬件包括:
     ·状态信息:
          ·链路速度
          ·链路状态
          ·复用模式
     ·统计数据包括:
          ·收到的包计数
          ·发送的包计数
          ·收到的八位组计数
          ·发送的八位组计数
          ·收到的多播包计数
          ·功能级的复位(Function Level Reset)
          ·VLAN 标号插入
          ·校验和插入
          
 
Actions taken via Mailbox system   - VF to PF
 
VF 暴露给VF驱动的PCI资源并不一定满足所有PF 驱动的需求,比如VLAN 标识配置和多播地址配置。
 
在这种情况下,VF驱动利用信箱 系统来向PF驱动传递消息,这样来使得PF驱动进行需要的操作。
 
现在定义的可以使用信箱机制实现的行为包括:
·VF复位
·配置VF MAC 地址
·设置多播地址
·设置VLAN过滤器
·设置最大包长
·信箱消息的ID实在ixgbe_mbx.h中定义的,适用于ixgbe PF 驱动和 ixgbevf VF 驱动
 
Virtual Function 复位:
 
消息ID:IXGBE_VF_RESET
驱动在执行了功能级的复位(Function Level Reset)后就会把这个消息发送给PF驱动。
 
一个例子:
     文件:ixgbe_vf.c
     函数:ixgbe_reset_hw_vf
     msgbuf[0] = IXGBE_VF_RESET;
     mbx->ops.write_posted(hw,msgbuf,1,0);

 

 
当PF驱动接收到消息,就会进行回复,并发送回MAC地址给VF。
 
 
Configuring a MAC Address
 
消息ID: IXGBE_VF_SET_MAC_ADDR
当VF驱动想要定义自己的MAC地址时,就会发送该消息(而不是使用当PF初始化时分配给VF的默认MAC地址)。
 
实例:
     文件:ixgbex_vf.c
     函数:ixgbe_set_rar_vf
     msbuf[0] = IXGBE_VF_SET_MAC_ADDR;
     memcpy(msg_addr, addr,6);
     ret_val = mbx->ops.write_posted(hw, msbug, 3);

 

 
Setting Multicast Address
 
消息ID:IXGBE_VF_SET_MULTICAST
当VF驱动需要设置一个多播地址来过滤达到的包时就会发送该消息。
 
实例:
          文件:ixgbe_vf.c
          函数:ixgbe_update_mc_addr_list_vf
复制代码
          cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
          msgbuf[0] = IXGBE_VF_SET_MULTICAST;
          msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT;
          
          for( i = 0; i < cnt; i++)
          {
               vector = ixgbe_mta_vector(hw, next(hw, &mc_addr_list, &vmdq));
               hw_dbg(hw, "Hash value = 0x%03x\n",vector);
               vector_list[i] = (u16) vector;
          }
 
          mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0);
复制代码

 

 
Setting VLAN Filter
 
消息ID:IXGBE_VF_VLAN
VF驱动想要设置一个VLAN 标识来过滤到达的包就会发送该消息
 
实例:
     文件:ixgbe_vf.c
     函数:ixgbe_set_vfta_vf
     msgbuf[0] = IXGBE_VF_SET_VLAN;
     msgbuf[1] = vlan;
     
     msgbuf[0] |= vlan_on << IXGBE_VTMSGINFO_SHIFT;
     mbx-ops.write_posted(hw, msgbuf, 2, 0);

 

 
PF to VF Mailbox Messages
 
 
Physical Function Driver
     
     该驱动负责物理资源和针对VF配置的一些处理。
     
     当驱动在探测发现设备的时候,在驱动初始化执行的众多任务中,有一项就是将自己注册为一个SR-IOV设备。
     文件:ixgbe_main.c
     函数:__devinit ixgbe_probe_vf
     
     err = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
     这个函数调用将82599注册为一个SR-IOV设备,表明支持特定数量的VF。
     
Default Configuration
     
     在驱动初始化阶段进行了很多项默认配置。这些默认配置包括VF的个数,VF流量配置,VFMAC地址分配。
 
     
Assignment of Queue's to Pools
     
     82599 PF 驱动 默认支持配置63个VF。每个池内有两个队列对与其相关,总共4个队列
     文件:ixgbe_main.c
     函数:ixgbe_up_complete
复制代码
     if ( adapter->flags & IXGBE_FLAG_SRIOV_ENABLED )
     {
          gpie &= ~IXGBE_GPIE_VTMODE_MASK;
          gpie |=  IXGBE_GPIE_VTMODE_64;
     }
 
     IXGBE_WRITE_REG(hw, IXGBE_GPID, gpie);
复制代码

 

Intel 82599 ixgbe & ixgbevf CNA 卡驱动分析03——部分功能代码分析_第1张图片

 
     这段代码对PCIe 控制寄存(GCR_EXT-0x11050)器进行了配置,默认支持64个VF。
     
     文件:ixgbe_main.c
     函数:ixgbe_up_complete
     if ( adapter->flags & IXGBE_FLGA_SRIOV_ENABLED)
     {
          gpie &= ~IXGBE_GPIE_VTMODE_MASK;
          gpie |= IXGBE_GPIE_VTMODE_64;
     }

 

     IXGBE_WRITE_REG(hw, IXGBE_GPIE,gpie);
     该代码片段配置 VT_Mode (15:14)比特,目的是对中断寄存器(GPIE-0x00898)进行配置.
 
     

Intel 82599 ixgbe & ixgbevf CNA 卡驱动分析03——部分功能代码分析_第2张图片

 
 
Enabling VF to VF Bridging 
 
VF 到 VF 的桥接在函数ixgbe_configure_rx() 函数中实现,该函数位于ixgbe_main.c
该函数使能了PF DMA 传输交换控制寄存器(PFDTXGSWC)的回环使能位(LBE)
 
文件:ixgbe_main.c
函数:ixgbe_configure_rx
 
复制代码
          #ifdef     CONFIG_PCI_IOV
                        if( adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
                         {
                              IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
                              ixgbe_set_vmolr(hw, adapter->num_vfs);
                         }
          #endif
复制代码

 

 
          该代码片段同时也使能了VF的流量,通过ixgbe_set_vmolr函数的调用。
 
Default Pool
     
          当一些包不会送到某个VF则会送到默认池去处理。这个池资源是为PF准备的。默认池是不分配给VF的池。如果有32个池资源已经进行了配置,第33个池就会配配置为默认池。
 
          文件:ixgbe_main.c
          函数:ixgbe_configure_rx
                    
复制代码
                    if(adapter->num_vfs )
                    {
                         vt_reg_bits &= ~IXGBE_VT_CTL_POOL_MASK;
                         vt_reg_bits |= (adapter->num_vfs << IXGBE_VT_CTL_POOL_SHIFT);
                    }
 
                    u32     vt_reg;
                    u32     vt_reg_bits;
                    if ( hw->mac.type = ixgbe_mac_82599EB)
                    {
                         vt_reg = IXGBE_VT_CTL;
                         vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN | IXGBE_VT_CTL_REPLEN
                         
                         if ( adapter->num_vfs )
                         {
                              vt_reg_bits &= ~IXGBE_VT_CTL_POOL_MASK; 
                              vt_reg_bits |= (adapter->num_vfs << IXGBE_VT_CTL_POOL_SHIFT); 

                          }
                      } 
                      else {
                           vt_reg = IXGBE_VMD_CTL;
                           vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN;
                     }
                     vmdctl = IXGBE_READ_REG(hw, vt_reg);
                     IXGBE_WRITE_REG(hw, vt_reg, vmdctl | vt_reg_bits); 
复制代码

 

                     驱动操作PFVTCTL(0x051B0)寄存器来配置默认池。主要操作DEF_PF 位(12:7)
       

 
Replication Enable
 
Broadcast Accept Mode
 
 
Accept Packet Matching PFUTA Table
     
     这里允许VF接收一个域PF 单波表(PFUTA 0x0F400)中某个单波地址入口匹配的包。
     文件:ixgbe_sriov.c
     函数:ixgbe_set_vmolr
               
               u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
               vmolr |= (IXGBE_VMOLR_AUPE | IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_ROPE |      
                              IXGBE_VMOLR_BAM);
               IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);

 

     
          驱动操作PF VM L2 控制寄存器(PFVML2FLT 0x0F000 + 4 *n [n=0..63] )的ROPE域(第26比特)使能作者禁止VF 接收赖在PFUTA表的包。
 
Accept Packets Matching MTA Table
          
     该功能允许VF接收在多播表阵列(UTA 0xA000)中匹配多播地址入口的包。
     默认是接收。
     文件:ixgbe_sriov.c
     函数:ixgbe_set_vmolr
               
               u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
               vmolr |= (IXGBE_VMOLR_AUPE | IXGBE_VMOLR_ROMPE |
                              IXGBE_VMOLR_ROPE | IXGBE_VMOLR_BAM);
               IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);

 

     驱动操作 PF VM L2 控制寄存器(PFVML2FLT 0x0F000 + 4 *n [n = 0..63]的ROMPE域(第25bit)注册使能或者禁止接收来自MTA 表的包。
 

 
 
Accept Untagged Packets Enable
 
     这种方式允许VF接收一个MAC地址匹配但是VLAN 标识不一定要匹配的包。
     默认情况下,未加标识的包的接收功能已经使能。
     文件:ixgbe_sriov.c
     函数:ixgbe_set_vmolr
     
          u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
          vmolr |= ( IXGBE_VMOLR_AUPE | IXGBE_VMOLR_ROMPE | 
                          IXGBE_VMOLR_ROPE | IXGBE_VMOLR_BAM);
          IXGBE_WRTIE_REG(hw, IXGBE_VMOLR(vf),vmolr);

 

     驱动操作PF VM L2 控制寄存器(PFVML2FLT 0x0F000 + 4*n [n=0..63])注册使能或禁止VF接收未加标识的包
 
     

 
 
Strip VLAN Tag for Incoming Packets
 
这允许一个VF 剥去一个通过L2 过滤传过来的包的VLAN 标识
默认情况下,这项功能是开启的。
 
     文件:ixgbe_main.c
     函数:ixgbe_vlan_rx_register
复制代码
               for( i = 0; i < adpater->num_rx_queues; i++)
               {
                    j = adpter->rx_ring[i]->reg_idx;
                    ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(j));
                    ctrl |= IXGBE_RXDCTL_VME;
                    IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(j), ctrl);
               }
复制代码

 

    驱动操作接收描述符控制寄存器(RXDCTL[n] (0x01208 + 0x40*n, n= 0..63 and 0x0D028 + 0x40*(n-64)), n=64..127; RW)的VLAN 模式使能位(第30bit)注册使能或禁止剥除到来包的VLAN 标识。

Intel 82599 ixgbe & ixgbevf CNA 卡驱动分析03——部分功能代码分析_第3张图片

 
 
VF MAC 地址赋值
 
PF 驱动使用random_ether_add()函数(由内核提供【哪个内核,操作系统还是Hypervisor?】)动态的给每一个VF赋予一个MAC地址。下面的代码片段是一个展示示例:
          文件:ixgbe_sriov.c
          函数:ixgbe_vf_configuration
               random_ether_addr(vf_mac_addr);
               memcpy( adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr,6);

 

     __devinit ixgbe_probe() 例程为每一个创建的VF调用ixgbe_vf_configuration() 一次。VF获得MAC地址当进行功能级的复位时,VF通过信箱发送IXGBE_VF_RESET消息到PF。PF发回VF  MAC地址作为回复。
     此外,VF驱动亦可以指定自己的MAC地址使用IXGBE_VF_SET_MAC消息。
 
make it simple, make it happen

你可能感兴趣的:(Intel 82599 ixgbe & ixgbevf CNA 卡驱动分析03——部分功能代码分析)