diff options
author | Sunil Goutham <sgoutham@cavium.com> | 2015-08-30 12:29:16 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-30 21:54:12 -0700 |
commit | d77a2384988fd397cf4f71417b9d971aa435758d (patch) | |
tree | 9fbca2f38512934f9b1a5a5fc23960bf19af777a /drivers/net/ethernet/cavium/thunder/nicvf_main.c | |
parent | 92dc87697e6a71675a9e9eec04ebecd8cf4837a3 (diff) |
net: thunderx: Support for internal loopback mode
Support for setting VF's corresponding BGX LMAC in internal
loopback mode. This mode can be used for verifying basic HW
functionality such as packet I/O, RX checksum validation,
CQ/RBDR interrupts, stats e.t.c. Useful when DUT has no external
network connectivity.
'loopback' mode can be enabled or disabled via ethtool.
Note: This feature is not supported when no of VFs enabled are
morethan no of physical interfaces i.e active BGX LMACs
Signed-off-by: Sunil Goutham <sgoutham@cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov@caviumnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cavium/thunder/nicvf_main.c')
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/nicvf_main.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 68b2dce9229d..b63e579aeb12 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -202,6 +202,7 @@ static void nicvf_handle_mbx_intr(struct nicvf *nic) ether_addr_copy(nic->netdev->dev_addr, mbx.nic_cfg.mac_addr); nic->sqs_mode = mbx.nic_cfg.sqs_mode; + nic->loopback_supported = mbx.nic_cfg.loopback_supported; nic->link_up = false; nic->duplex = 0; nic->speed = 0; @@ -1404,6 +1405,30 @@ static void nicvf_reset_task(struct work_struct *work) nic->netdev->trans_start = jiffies; } +static int nicvf_config_loopback(struct nicvf *nic, + netdev_features_t features) +{ + union nic_mbx mbx = {}; + + mbx.lbk.msg = NIC_MBOX_MSG_LOOPBACK; + mbx.lbk.vf_id = nic->vf_id; + mbx.lbk.enable = (features & NETIF_F_LOOPBACK) != 0; + + return nicvf_send_msg_to_pf(nic, &mbx); +} + +static netdev_features_t nicvf_fix_features(struct net_device *netdev, + netdev_features_t features) +{ + struct nicvf *nic = netdev_priv(netdev); + + if ((features & NETIF_F_LOOPBACK) && + netif_running(netdev) && !nic->loopback_supported) + features &= ~NETIF_F_LOOPBACK; + + return features; +} + static int nicvf_set_features(struct net_device *netdev, netdev_features_t features) { @@ -1413,6 +1438,9 @@ static int nicvf_set_features(struct net_device *netdev, if (changed & NETIF_F_HW_VLAN_CTAG_RX) nicvf_config_vlan_stripping(nic, features); + if ((changed & NETIF_F_LOOPBACK) && netif_running(netdev)) + return nicvf_config_loopback(nic, features); + return 0; } @@ -1424,6 +1452,7 @@ static const struct net_device_ops nicvf_netdev_ops = { .ndo_set_mac_address = nicvf_set_mac_address, .ndo_get_stats64 = nicvf_get_stats64, .ndo_tx_timeout = nicvf_tx_timeout, + .ndo_fix_features = nicvf_fix_features, .ndo_set_features = nicvf_set_features, }; @@ -1518,6 +1547,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->hw_features |= NETIF_F_RXHASH; netdev->features |= netdev->hw_features; + netdev->hw_features |= NETIF_F_LOOPBACK; netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; |