• 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);

     
         这段代码对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)进行配置.
     
         

     
     
    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 标识。

     
     
    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消息。
     
  • 相关阅读:
    枚举
    交房租
    Schtasks 命令详解
    记录自己在 cmd 中执行 jar 文件遇到的一些错误
    Java 8 日期时间 API
    Java 8 Optional 类
    Java 8 Stream
    Java 8 默认方法
    Java 8 函数式接口
    Java 8 方法引用
  • 原文地址:https://www.cnblogs.com/zhuyp1015/p/2653289.html
Copyright © 2020-2023  润新知