summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cavium/thunder/nicvf_main.c
diff options
context:
space:
mode:
authorSunil Goutham2015-08-30 11:29:16 +0200
committerDavid S. Miller2015-08-31 06:54:12 +0200
commitd77a2384988fd397cf4f71417b9d971aa435758d (patch)
tree9fbca2f38512934f9b1a5a5fc23960bf19af777a /drivers/net/ethernet/cavium/thunder/nicvf_main.c
parentnet: thunderx: Support for upto 96 queues for a VF (diff)
downloadkernel-qcow2-linux-d77a2384988fd397cf4f71417b9d971aa435758d.tar.gz
kernel-qcow2-linux-d77a2384988fd397cf4f71417b9d971aa435758d.tar.xz
kernel-qcow2-linux-d77a2384988fd397cf4f71417b9d971aa435758d.zip
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.c30
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;