ixgbe hardware supports enabling TX loopback for VF's through the PFVMTXSW registers on the PF. Add a new mbox api enabling the VF to set its respective PFVMTXSW bit via the PF. Bump the mbox api to level 12. VF loopback is enabled/disabled through the netdevice API.
Signed-off-by: Yotam Rubin <yo...@weka.io> --- drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h | 4 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 28 ++++++++++++++ drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 45 ++++++++++++++++++++++- drivers/net/ethernet/intel/ixgbevf/mbx.h | 4 ++ drivers/net/ethernet/intel/ixgbevf/vf.c | 29 +++++++++++++++ drivers/net/ethernet/intel/ixgbevf/vf.h | 3 +- 6 files changed, 110 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h index a5cb755..43877ca 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h @@ -73,6 +73,7 @@ enum ixgbe_pfvf_api_rev { ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ + ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */ /* This value should always be last */ ixgbe_mbox_api_unknown, /* indicates that API version is not known */ }; @@ -91,6 +92,9 @@ enum ixgbe_pfvf_api_rev { /* mailbox API, version 1.1 VF requests */ #define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */ +/* mailbox API, version 1.2 VF requests */ +#define IXGBE_VF_ENABLE_TX_LOOPBACK 0x0a + /* GET_QUEUES return data indices within the mailbox */ #define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */ #define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 00f74bb..53d662d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -429,6 +429,7 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) #endif /* CONFIG_FCOE */ switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: /* * Version 1.1 supports jumbo frames on VFs if PF has * jumbo frames enabled which means legacy VFs are @@ -760,6 +761,28 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter, return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0; } +static int ixgbe_set_vf_tx_loopback(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + u8 *loopback_enabled; + + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_12: + break; + default: + return -1; + } + + if (!adapter->hw.mac.ops.set_tx_loopback) { + return -1; + } + + loopback_enabled = ((u8 *)(&msgbuf[1])); + adapter->vfinfo[vf].tx_loopback_enabled = !!(*loopback_enabled); + adapter->hw.mac.ops.set_tx_loopback(&adapter->hw, *loopback_enabled, vf); + return 0; +} + static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan) { u32 vlvf; @@ -900,6 +923,7 @@ static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter, switch (api) { case ixgbe_mbox_api_10: case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: adapter->vfinfo[vf].vf_api = api; return 0; default: @@ -923,6 +947,7 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter, switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_20: case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: break; default: return -1; @@ -1006,6 +1031,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) case IXGBE_VF_GET_QUEUES: retval = ixgbe_get_vf_queues(adapter, msgbuf, vf); break; + case IXGBE_VF_ENABLE_TX_LOOPBACK: + retval = ixgbe_set_vf_tx_loopback(adapter, msgbuf, vf); + break; default: e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); retval = IXGBE_ERR_MBX; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 4186981..43e48b8 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -2026,7 +2026,8 @@ static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter) static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - int api[] = { ixgbe_mbox_api_11, + int api[] = { ixgbe_mbox_api_12, + ixgbe_mbox_api_11, ixgbe_mbox_api_10, ixgbe_mbox_api_unknown }; int err = 0, idx = 0; @@ -2288,6 +2289,18 @@ static int ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, return 0; } +static int ixgbevf_set_tx_loopback(struct ixgbevf_adapter *adapter, + bool enabled) +{ + int err; + + spin_lock_bh(&adapter->mbx_lock); + err = ixgbevf_enable_tx_loopback(&adapter->hw, enabled); + spin_unlock_bh(&adapter->mbx_lock); + + return err; +} + /** * ixgbevf_set_num_queues - Allocate queues for device, feature dependent * @adapter: board private structure to initialize @@ -2328,6 +2341,7 @@ static void ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter) switch (hw->api_version) { case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: adapter->num_rx_queues = rss; adapter->num_tx_queues = rss; default: @@ -3712,6 +3726,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) switch (adapter->hw.api_version) { case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; break; default: @@ -3735,6 +3750,23 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) return 0; } +static int ixgbevf_set_features(struct net_device *netdev, + netdev_features_t features) +{ + struct ixgbevf_adapter *adapter = netdev_priv(netdev); + int err = 0; + + if (features & NETIF_F_LOOPBACK) + err = ixgbevf_set_tx_loopback(adapter, true); + else if (netdev->hw_features & NETIF_F_LOOPBACK) + err = ixgbevf_set_tx_loopback(adapter, false); + + if (!err) + netdev->features = features; + + return err; +} + #ifdef CONFIG_NET_POLL_CONTROLLER /* Polling 'interrupt' - used by things like netconsole to send skbs * without having to re-enable interrupts. It's not called while @@ -3883,6 +3915,7 @@ static const struct net_device_ops ixgbevf_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ixgbevf_set_mac, .ndo_change_mtu = ixgbevf_change_mtu, + .ndo_set_features = ixgbevf_set_features, .ndo_tx_timeout = ixgbevf_tx_timeout, .ndo_vlan_rx_add_vid = ixgbevf_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbevf_vlan_rx_kill_vid, @@ -4004,7 +4037,15 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) NETIF_F_TSO6 | NETIF_F_RXCSUM; - netdev->features = netdev->hw_features | + switch (hw->api_version) { + case ixgbe_mbox_api_12: + netdev->hw_features |= NETIF_F_LOOPBACK; + break; + default: + break; + } + + netdev->features = (netdev->hw_features & (~NETIF_F_LOOPBACK)) | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h b/drivers/net/ethernet/intel/ixgbevf/mbx.h index 0bc3005..a094a01 100644 --- a/drivers/net/ethernet/intel/ixgbevf/mbx.h +++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h @@ -86,6 +86,7 @@ enum ixgbe_pfvf_api_rev { ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ + ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */ /* This value should always be last */ ixgbe_mbox_api_unknown, /* indicates that API version is not known */ }; @@ -104,6 +105,9 @@ enum ixgbe_pfvf_api_rev { /* mailbox API, version 1.1 VF requests */ #define IXGBE_VF_GET_QUEUE 0x09 /* get queue configuration */ +/* mailbox API, version 1.2 VF requests */ +#define IXGBE_VF_ENABLE_TX_LOOPBACK 0x0a + /* GET_QUEUES return data indices within the mailbox */ #define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */ #define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */ diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index cdb53be..82bda53 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c @@ -536,6 +536,35 @@ int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api) return err; } +int ixgbevf_enable_tx_loopback(struct ixgbe_hw *hw, bool enabled) +{ + int err; + u32 msg[2]; + + switch (hw->api_version) { + case ixgbe_mbox_api_12: + break; + default: + return -1; + } + + msg[0] = IXGBE_VF_ENABLE_TX_LOOPBACK; + msg[1] = enabled; + err = hw->mbx.ops.write_posted(hw, msg, 2); + + if (!err) + err = hw->mbx.ops.read_posted(hw, msg, 2); + + if (!err) { + msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; + if (msg[0] != + (IXGBE_VF_ENABLE_TX_LOOPBACK | IXGBE_VT_MSGTYPE_ACK)) + return IXGBE_ERR_MBX; + } + + return err; +} + int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, unsigned int *default_tc) { diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h index 5b17242..6ae29fb 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.h +++ b/drivers/net/ethernet/intel/ixgbevf/vf.h @@ -87,7 +87,7 @@ struct ixgbe_mac_info { enum ixgbe_mac_type type; s32 mc_filter_type; - + bool tx_loopback_enabled; bool get_link_status; u32 max_tx_queues; u32 max_rx_queues; @@ -208,5 +208,6 @@ void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); int ixgbevf_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); +int ixgbevf_enable_tx_loopback(struct ixgbe_hw *hw, bool enabled); #endif /* __IXGBE_VF_H__ */ -- 1.9.1 ------------------------------------------------------------------------------ Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server from Actuate! Instantly Supercharge Your Business Reports and Dashboards with Interactivity, Sharing, Native Excel Exports, App Integration & more Get technology previously reserved for billion-dollar corporations, FREE http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk _______________________________________________ E1000-devel mailing list E1000-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/e1000-devel To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired