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消息。