FreeBSD Bugzilla – Attachment 219194 Details for
Bug 232472
ixgbe(4): SR-IOV passthru not working on Hyper-V 13-CURRENT guest with Intel X540 (0x152E)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Make FreeBSD 11.3 to support SRIOV on Intel NIC 82599 VF (0x152E) on HyperV
freebsd11.3_ixv_sriov_hyperv.patch (text/plain), 15.53 KB, created by
Wei Hu
on 2020-10-29 10:13:43 UTC
(
hide
)
Description:
Make FreeBSD 11.3 to support SRIOV on Intel NIC 82599 VF (0x152E) on HyperV
Filename:
MIME Type:
Creator:
Wei Hu
Created:
2020-10-29 10:13:43 UTC
Size:
15.53 KB
patch
obsolete
>Index: sys/dev/ixgbe/if_ixv.c >=================================================================== >--- sys/dev/ixgbe/if_ixv.c (revision 351623) >+++ sys/dev/ixgbe/if_ixv.c (working copy) >@@ -57,6 +57,7 @@ > static ixgbe_vendor_info_t ixv_vendor_info_array[] = > { > {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF, 0, 0, 0}, >+ {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF_HV, 0, 0, 0}, > {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF, 0, 0, 0}, > {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF, 0, 0, 0}, > {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF, 0, 0, 0}, >@@ -326,6 +327,7 @@ > /* A subset of set_mac_type */ > switch (hw->device_id) { > case IXGBE_DEV_ID_82599_VF: >+ case IXGBE_DEV_ID_82599_VF_HV: > hw->mac.type = ixgbe_mac_82599_vf; > break; > case IXGBE_DEV_ID_X540_VF: >@@ -351,7 +353,10 @@ > ixv_init_device_features(adapter); > > /* Initialize the shared code */ >- error = ixgbe_init_ops_vf(hw); >+ if (hw->device_id == IXGBE_DEV_ID_82599_VF_HV) >+ error = ixgbe_hv_init_ops_vf(hw); >+ else >+ error = ixgbe_init_ops_vf(hw); > if (error) { > device_printf(dev, "ixgbe_init_ops_vf() failed!\n"); > error = EIO; >@@ -359,7 +364,10 @@ > } > > /* Setup the mailbox */ >- ixgbe_init_mbx_params_vf(hw); >+ if (hw->device_id == IXGBE_DEV_ID_82599_VF_HV) >+ ixgbe_hv_init_mbx_params_vf(hw); >+ else >+ ixgbe_init_mbx_params_vf(hw); > > /* Set the right number of segments */ > adapter->num_segs = IXGBE_82599_SCATTER; >@@ -384,8 +392,9 @@ > } > > /* Negotiate mailbox API version */ >- error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_12); >- if (error) { >+ // error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_12); >+ error = hw->mac.ops.negotiate_api_version(hw, ixgbe_mbox_api_12); >+ if (error && hw->device_id != IXGBE_DEV_ID_82599_VF_HV) { > device_printf(dev, "MBX API 1.2 negotiation failed! Error %d\n", > error); > error = EIO; >@@ -584,7 +593,8 @@ > > /* Reset VF and renegotiate mailbox API version */ > hw->mac.ops.reset_hw(hw); >- error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_12); >+ // error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_12); >+ error = hw->mac.ops.negotiate_api_version(hw, ixgbe_mbox_api_12); > if (error) > device_printf(dev, "MBX API 1.2 negotiation failed! Error %d\n", > error); >@@ -1416,7 +1426,8 @@ > IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); > > /* Tell PF our max_frame size */ >- if (ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size) != 0) { >+ // if (ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size) != 0) { >+ if (hw->mac.ops.set_rlpml(hw, adapter->max_frame_size) != 0) { > device_printf(adapter->dev, "There is a problem with the PF setup. It is likely the receive unit for this VF will not function correctly.\n"); > } > >Index: sys/dev/ixgbe/ixgbe_mbx.c >=================================================================== >--- sys/dev/ixgbe/ixgbe_mbx.c (revision 351623) >+++ sys/dev/ixgbe/ixgbe_mbx.c (working copy) >@@ -413,6 +413,39 @@ > mbx->stats.rsts = 0; > } > >+/** >+ * ixgbe_hv_init_mbx_params_vf - HyperV guest set initial values for vf mailbox >+ * On HyperV, most mail box operations are noop. >+ * @hw: pointer to the HW structure >+ * >+ * Initializes the hw->mbx struct to correct values for vf mailbox >+ */ >+void ixgbe_hv_init_mbx_params_vf(struct ixgbe_hw *hw) >+{ >+ struct ixgbe_mbx_info *mbx = &hw->mbx; >+ >+ /* start mailbox as timed out and let the reset_hw call set the timeout >+ * value to begin communications */ >+ mbx->timeout = 0; >+ mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; >+ >+ mbx->size = IXGBE_VFMAILBOX_SIZE; >+ >+ mbx->ops.read = NULL; >+ mbx->ops.write = NULL; >+ mbx->ops.read_posted = NULL; >+ mbx->ops.write_posted = NULL; >+ mbx->ops.check_for_msg = NULL; >+ mbx->ops.check_for_ack = NULL; >+ mbx->ops.check_for_rst = ixgbe_check_for_rst_vf; >+ >+ mbx->stats.msgs_tx = 0; >+ mbx->stats.msgs_rx = 0; >+ mbx->stats.reqs = 0; >+ mbx->stats.acks = 0; >+ mbx->stats.rsts = 0; >+} >+ > static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) > { > u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index)); >Index: sys/dev/ixgbe/ixgbe_mbx.h >=================================================================== >--- sys/dev/ixgbe/ixgbe_mbx.h (revision 351623) >+++ sys/dev/ixgbe/ixgbe_mbx.h (working copy) >@@ -154,6 +154,7 @@ > > void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw); > void ixgbe_init_mbx_params_vf(struct ixgbe_hw *); >+void ixgbe_hv_init_mbx_params_vf(struct ixgbe_hw *); > void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); > > #endif /* _IXGBE_MBX_H_ */ >Index: sys/dev/ixgbe/ixgbe_vf.c >=================================================================== >--- sys/dev/ixgbe/ixgbe_vf.c (revision 351623) >+++ sys/dev/ixgbe/ixgbe_vf.c (working copy) >@@ -43,6 +43,13 @@ > #endif > > /** >+ * On Hyper-V, to reset, we need to read from this offset >+ * from the PCI config space. This is the mechanism used on >+ * Hyper-V to support PF/VF communication. >+ */ >+#define IXGBE_HV_RESET_OFFSET 0x201 >+ >+/** > * ixgbe_init_ops_vf - Initialize the pointers for vf > * @hw: pointer to hardware structure > * >@@ -90,6 +97,54 @@ > return IXGBE_SUCCESS; > } > >+/** >+ * ixgbe_hv_init_ops_vf - Hyper-V guest Initialize the pointers for vf >+ * @hw: pointer to hardware structure >+ * >+ * This will assign function pointers, adapter-specific functions can >+ * override the assignment of generic function pointers by assigning >+ * their own adapter-specific function pointers. >+ * Does not touch the hardware. >+ **/ >+s32 ixgbe_hv_init_ops_vf(struct ixgbe_hw *hw) >+{ >+ /* MAC */ >+ hw->mac.ops.init_hw = ixgbe_init_hw_vf; >+ hw->mac.ops.reset_hw = ixgbe_hv_reset_hw_vf; >+ hw->mac.ops.start_hw = ixgbe_start_hw_vf; >+ /* Cannot clear stats on VF */ >+ hw->mac.ops.clear_hw_cntrs = NULL; >+ hw->mac.ops.get_media_type = NULL; >+ hw->mac.ops.get_mac_addr = ixgbe_get_mac_addr_vf; >+ hw->mac.ops.stop_adapter = ixgbe_stop_adapter_vf; >+ hw->mac.ops.get_bus_info = NULL; >+ hw->mac.ops.negotiate_api_version = ixgbevf_hv_negotiate_api_version; >+ >+ /* Link */ >+ hw->mac.ops.setup_link = ixgbe_setup_mac_link_vf; >+ hw->mac.ops.check_link = ixgbe_hv_check_mac_link_vf; >+ hw->mac.ops.get_link_capabilities = NULL; >+ >+ /* RAR, Multicast, VLAN */ >+ hw->mac.ops.set_rar = ixgbe_hv_set_rar_vf; >+ hw->mac.ops.set_uc_addr = ixgbevf_hv_set_uc_addr_vf; >+ hw->mac.ops.init_rx_addrs = NULL; >+ hw->mac.ops.update_mc_addr_list = ixgbe_hv_update_mc_addr_list_vf; >+ hw->mac.ops.update_xcast_mode = ixgbevf_hv_update_xcast_mode; >+ hw->mac.ops.enable_mc = NULL; >+ hw->mac.ops.disable_mc = NULL; >+ hw->mac.ops.clear_vfta = NULL; >+ hw->mac.ops.set_vfta = ixgbe_hv_set_vfta_vf; >+ hw->mac.ops.set_rlpml = ixgbevf_hv_rlpml_set_vf; >+ >+ hw->mac.max_tx_queues = 1; >+ hw->mac.max_rx_queues = 1; >+ >+ hw->mbx.ops.init_params = ixgbe_hv_init_mbx_params_vf; >+ >+ return IXGBE_SUCCESS; >+} >+ > /* ixgbe_virt_clr_reg - Set register to default (power on) state. > * @hw: pointer to hardware structure > */ >@@ -239,6 +294,23 @@ > } > > /** >+ * ixgbe_hv_reset_hw_vf - HyperV guest Performs hardware reset >+ * @hw: pointer to hardware structure >+ * >+ * VF/PF communication is through the PCI config space. >+ **/ >+s32 ixgbe_hv_reset_hw_vf(struct ixgbe_hw *hw) >+{ >+ int i; >+ >+ for (i = 0; i < 6; i++) >+ hw->mac.perm_addr[i] = pci_read_config(((struct adapter *)hw->back)->dev, >+ (i + IXGBE_HV_RESET_OFFSET), 1); >+ >+ return IXGBE_SUCCESS; >+} >+ >+/** > * ixgbe_stop_adapter_vf - Generic stop Tx/Rx units > * @hw: pointer to hardware structure > * >@@ -370,6 +442,28 @@ > } > > /** >+ * ixgbe_hv_set_rar_vf - HyperV guest set device MAC address >+ * @hw: pointer to hardware structure >+ * @index: Receive address register to write >+ * @addr: Address to put into receive address register >+ * @vmdq: VMDq "set" or "pool" index >+ * @enable_addr: set flag that address is active >+ * We don't really allow setting the device MAC address. However, >+ * if the address being set is the permanent MAC address we will >+ * permit that. >+ **/ >+s32 ixgbe_hv_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, >+ u32 enable_addr) >+{ >+ UNREFERENCED_3PARAMETER(vmdq, enable_addr, index); >+ >+ if (memcmp(addr, hw->mac.perm_addr, 6) == 0) >+ return IXGBE_SUCCESS; >+ >+ return IXGBE_NOT_IMPLEMENTED; >+} >+ >+/** > * ixgbe_update_mc_addr_list_vf - Update Multicast addresses > * @hw: pointer to the HW structure > * @mc_addr_list: array of multicast addresses to program >@@ -418,6 +512,16 @@ > } > > /** >+ * HyperVvariant - just a stub. >+ */ >+s32 ixgbe_hv_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, >+ u32 mc_addr_count, ixgbe_mc_addr_itr next, >+ bool clear) >+{ >+ return IXGBE_NOT_IMPLEMENTED; >+} >+ >+/** > * ixgbevf_update_xcast_mode - Update Multicast mode > * @hw: pointer to the HW structure > * @xcast_mode: new multicast mode >@@ -455,6 +559,16 @@ > } > > /** >+ * HyperVvariant - just a stub. >+ */ >+s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode) >+{ >+ UNREFERENCED_2PARAMETER(hw, xcast_mode); >+ >+ return IXGBE_NOT_IMPLEMENTED; >+} >+ >+/** > * ixgbe_set_vfta_vf - Set/Unset vlan filter table address > * @hw: pointer to the HW structure > * @vlan: 12 bit VLAN ID >@@ -484,6 +598,15 @@ > } > > /** >+ * HyperVvariant - just a stub. >+ */ >+s32 ixgbe_hv_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, >+ bool vlan_on, bool vlvf_bypass) >+{ >+ return IXGBE_NOT_IMPLEMENTED; >+} >+ >+/** > * ixgbe_get_num_of_tx_queues_vf - Get number of TX queues > * @hw: pointer to hardware structure > * >@@ -551,6 +674,13 @@ > return ret_val; > } > >+s32 ixgbevf_hv_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) >+{ >+ UNREFERENCED_3PARAMETER(hw, index, addr); >+ >+ return IXGBE_NOT_IMPLEMENTED; >+} >+ > /** > * ixgbe_setup_mac_link_vf - Setup MAC link settings > * @hw: pointer to hardware structure >@@ -671,6 +801,89 @@ > } > > /** >+ * ixgbe_hv_check_mac_link_vf - HyperV guest Get link/speed status >+ * @hw: pointer to hardware structure >+ * @speed: pointer to link speed >+ * @link_up: TRUE is link is up, FALSE otherwise >+ * @autoneg_wait_to_complete: TRUE when waiting for completion is needed >+ * >+ * Reads the links register to determine if link is up and the current speed >+ **/ >+s32 ixgbe_hv_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, >+ bool *link_up, bool autoneg_wait_to_complete) >+{ >+ struct ixgbe_mbx_info *mbx = &hw->mbx; >+ struct ixgbe_mac_info *mac = &hw->mac; >+ s32 ret_val = IXGBE_SUCCESS; >+ u32 links_reg; >+ UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); >+ >+ /* If we were hit with a reset drop the link */ >+ if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout) >+ mac->get_link_status = TRUE; >+ >+ if (!mac->get_link_status) >+ goto out; >+ >+ /* if link status is down no point in checking to see if pf is up */ >+ links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); >+ if (!(links_reg & IXGBE_LINKS_UP)) >+ goto out; >+ >+ /* for SFP+ modules and DA cables on 82599 it can take up to 500usecs >+ * before the link status is correct >+ */ >+ if (mac->type == ixgbe_mac_82599_vf) { >+ int i; >+ >+ for (i = 0; i < 5; i++) { >+ usec_delay(100); >+ links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); >+ >+ if (!(links_reg & IXGBE_LINKS_UP)) >+ goto out; >+ } >+ } >+ >+ switch (links_reg & IXGBE_LINKS_SPEED_82599) { >+ case IXGBE_LINKS_SPEED_10G_82599: >+ *speed = IXGBE_LINK_SPEED_10GB_FULL; >+ if (hw->mac.type >= ixgbe_mac_X550) { >+ if (links_reg & IXGBE_LINKS_SPEED_NON_STD) >+ *speed = IXGBE_LINK_SPEED_2_5GB_FULL; >+ } >+ break; >+ case IXGBE_LINKS_SPEED_1G_82599: >+ *speed = IXGBE_LINK_SPEED_1GB_FULL; >+ break; >+ case IXGBE_LINKS_SPEED_100_82599: >+ *speed = IXGBE_LINK_SPEED_100_FULL; >+ if (hw->mac.type == ixgbe_mac_X550) { >+ if (links_reg & IXGBE_LINKS_SPEED_NON_STD) >+ *speed = IXGBE_LINK_SPEED_5GB_FULL; >+ } >+ break; >+ case IXGBE_LINKS_SPEED_10_X550EM_A: >+ *speed = IXGBE_LINK_SPEED_UNKNOWN; >+ /* Since Reserved in older MAC's */ >+ if (hw->mac.type >= ixgbe_mac_X550) >+ *speed = IXGBE_LINK_SPEED_10_FULL; >+ break; >+ default: >+ *speed = IXGBE_LINK_SPEED_UNKNOWN; >+ } >+ >+ /* if we passed all the tests above then the link is up and we no >+ * longer need to check for link >+ */ >+ mac->get_link_status = FALSE; >+ >+out: >+ *link_up = !mac->get_link_status; >+ return ret_val; >+} >+ >+/** > * ixgbevf_rlpml_set_vf - Set the maximum receive packet length > * @hw: pointer to the HW structure > * @max_size: value to assign to max frame size >@@ -694,6 +907,26 @@ > } > > /** >+ * ixgbevf_hv_rlpml_set_vf - Set the maximum receive packet length >+ * @hw: pointer to the HW structure >+ * @max_size: value to assign to max frame size >+ * HyperV variant. >+ **/ >+s32 ixgbevf_hv_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size) >+{ >+ u32 reg; >+ >+ /* If we are on Hyper-V, we implement this functionality >+ * differently. >+ */ >+ reg = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(0)); >+ reg |= ((max_size + 4) | IXGBE_RXDCTL_RLPML_EN); >+ IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(0), reg); >+ >+ return 0; >+} >+ >+/** > * ixgbevf_negotiate_api_version - Negotiate supported API version > * @hw: pointer to the HW structure > * @api: integer containing requested API version >@@ -724,6 +957,21 @@ > return err; > } > >+ >+/** >+ * ixgbevf_hv_negotiate_api_version - HyperV guest Negotiate supported API version >+ * @hw: pointer to the HW structure >+ * @api: integer containing requested API version >+ * Hyper-V version - only ixgbe_mbox_api_10 supported. >+ **/ >+int ixgbevf_hv_negotiate_api_version(struct ixgbe_hw *hw, int api) >+{ >+ if (api != ixgbe_mbox_api_10) >+ return IXGBE_ERR_INVALID_ARGUMENT; >+ >+ return IXGBE_SUCCESS; >+} >+ > int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, > unsigned int *default_tc) > { >Index: sys/dev/ixgbe/ixgbe_vf.h >=================================================================== >--- sys/dev/ixgbe/ixgbe_vf.h (revision 351623) >+++ sys/dev/ixgbe/ixgbe_vf.h (working copy) >@@ -116,9 +116,11 @@ > }; > > s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw); >+s32 ixgbe_hv_init_ops_vf(struct ixgbe_hw *hw); > s32 ixgbe_init_hw_vf(struct ixgbe_hw *hw); > s32 ixgbe_start_hw_vf(struct ixgbe_hw *hw); > s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw); >+s32 ixgbe_hv_reset_hw_vf(struct ixgbe_hw *hw); > s32 ixgbe_stop_adapter_vf(struct ixgbe_hw *hw); > u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw); > u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw); >@@ -127,17 +129,30 @@ > bool autoneg_wait_to_complete); > s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, > bool *link_up, bool autoneg_wait_to_complete); >+s32 ixgbe_hv_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, >+ bool *link_up, bool autoneg_wait_to_complete); > s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, > u32 enable_addr); >+s32 ixgbe_hv_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, >+ u32 enable_addr); > s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr); >+s32 ixgbevf_hv_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr); > s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, > u32 mc_addr_count, ixgbe_mc_addr_itr, > bool clear); >+s32 ixgbe_hv_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, >+ u32 mc_addr_count, ixgbe_mc_addr_itr, >+ bool clear); > s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode); >+s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode); > s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, > bool vlan_on, bool vlvf_bypass); >+s32 ixgbe_hv_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, >+ bool vlan_on, bool vlvf_bypass); > s32 ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); >+s32 ixgbevf_hv_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); > int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api); >+int ixgbevf_hv_negotiate_api_version(struct ixgbe_hw *hw, int api); > int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, > unsigned int *default_tc); >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
koobs
:
maintainer-approval?
(
freebsd
)
Actions:
View
|
Diff
Attachments on
bug 232472
: 219194