diff options
author | Shahed Shaikh <shahed.shaikh@qlogic.com> | 2014-03-21 12:41:17 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-24 08:44:23 +0400 |
commit | 2b3d7b758c68775cdebd95787454d12e0b8247e7 (patch) | |
tree | bdd7a6ba0ae3c31914d29ecb47d34309a4ddd676 /drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |
parent | 381709de1582ed868161d37a1ad54ba110c4353c (diff) | |
download | linux-2b3d7b758c68775cdebd95787454d12e0b8247e7.tar.xz |
qlcnic: Add VXLAN Rx offload support
This patch adds Rx checksum offload support for VXLAN.
Implements .ndo_{add|del}_vxlan_port netdev ops.
Adapter supports only one VXLAN port, so program adapter with
very first UDP port which VXLAN driver is listening to.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 6655bf49c79b..79be451a3ffc 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -21,6 +21,7 @@ #include <linux/aer.h> #include <linux/log2.h> #include <linux/pci.h> +#include <net/vxlan.h> MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver"); MODULE_LICENSE("GPL"); @@ -461,6 +462,35 @@ static int qlcnic_get_phys_port_id(struct net_device *netdev, return 0; } +static void qlcnic_add_vxlan_port(struct net_device *netdev, + sa_family_t sa_family, __be16 port) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + struct qlcnic_hardware_context *ahw = adapter->ahw; + + /* Adapter supports only one VXLAN port. Use very first port + * for enabling offload + */ + if (!qlcnic_encap_rx_offload(adapter) || ahw->vxlan_port) + return; + + ahw->vxlan_port = ntohs(port); + adapter->flags |= QLCNIC_ADD_VXLAN_PORT; +} + +static void qlcnic_del_vxlan_port(struct net_device *netdev, + sa_family_t sa_family, __be16 port) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + struct qlcnic_hardware_context *ahw = adapter->ahw; + + if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port || + (ahw->vxlan_port != ntohs(port))) + return; + + adapter->flags |= QLCNIC_DEL_VXLAN_PORT; +} + static const struct net_device_ops qlcnic_netdev_ops = { .ndo_open = qlcnic_open, .ndo_stop = qlcnic_close, @@ -479,6 +509,8 @@ static const struct net_device_ops qlcnic_netdev_ops = { .ndo_fdb_del = qlcnic_fdb_del, .ndo_fdb_dump = qlcnic_fdb_dump, .ndo_get_phys_port_id = qlcnic_get_phys_port_id, + .ndo_add_vxlan_port = qlcnic_add_vxlan_port, + .ndo_del_vxlan_port = qlcnic_del_vxlan_port, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = qlcnic_poll_controller, #endif @@ -1943,6 +1975,9 @@ qlcnic_attach(struct qlcnic_adapter *adapter) qlcnic_create_sysfs_entries(adapter); + if (qlcnic_encap_rx_offload(adapter)) + vxlan_get_rx_port(netdev); + adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; return 0; @@ -2215,6 +2250,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, NETIF_F_TSO6; } + if (qlcnic_encap_rx_offload(adapter)) + netdev->hw_enc_features |= NETIF_F_RXCSUM; + netdev->hw_features = netdev->features; netdev->priv_flags |= IFF_UNICAST_FLT; netdev->irq = adapter->msix_entries[0].vector; |