aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDon Skidmore <donald.c.skidmore@intel.com>2014-12-23 02:40:34 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-02-05 22:57:49 -0500
commit3f207800a998fb1b0b36df251e826ee7682294f7 (patch)
treea943a6de0631fe8232511f76b9313af7f1a16e27
parent4dedadcbae35c84366c2543bce37e045b1665196 (diff)
ixgbe: add VXLAN offload support for X550 devices
Add support VXLAN receive checksum offload in X550 hardware. Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/Kconfig11
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c98
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h5
4 files changed, 113 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index 4d61ef50b465..f4ff465584a0 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -192,6 +192,17 @@ config IXGBE
192 To compile this driver as a module, choose M here. The module 192 To compile this driver as a module, choose M here. The module
193 will be called ixgbe. 193 will be called ixgbe.
194 194
195config IXGBE_VXLAN
196 bool "Virtual eXtensible Local Area Network Support"
197 default n
198 depends on IXGBE && VXLAN && !(IXGBE=y && VXLAN=m)
199 ---help---
200 This allows one to create VXLAN virtual interfaces that provide
201 Layer 2 Networks over Layer 3 Networks. VXLAN is often used
202 to tunnel virtual network infrastructure in virtualized environments.
203 Say Y here if you want to use Virtual eXtensible Local Area Network
204 (VXLAN) in the driver.
205
195config IXGBE_HWMON 206config IXGBE_HWMON
196 bool "Intel(R) 10GbE PCI Express adapters HWMON support" 207 bool "Intel(R) 10GbE PCI Express adapters HWMON support"
197 default y 208 default y
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 38fc64cf5dca..699117aff5fe 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -753,6 +753,7 @@ struct ixgbe_adapter {
753 u32 timer_event_accumulator; 753 u32 timer_event_accumulator;
754 u32 vferr_refcount; 754 u32 vferr_refcount;
755 struct ixgbe_mac_addr *mac_table; 755 struct ixgbe_mac_addr *mac_table;
756 u16 vxlan_port;
756 struct kobject *info_kobj; 757 struct kobject *info_kobj;
757#ifdef CONFIG_IXGBE_HWMON 758#ifdef CONFIG_IXGBE_HWMON
758 struct hwmon_buff *ixgbe_hwmon_buff; 759 struct hwmon_buff *ixgbe_hwmon_buff;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index e9e3a1eb9a97..6aa9b96b2e10 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -50,6 +50,7 @@
50#include <linux/if_bridge.h> 50#include <linux/if_bridge.h>
51#include <linux/prefetch.h> 51#include <linux/prefetch.h>
52#include <scsi/fc/fc_fcoe.h> 52#include <scsi/fc/fc_fcoe.h>
53#include <net/vxlan.h>
53 54
54#ifdef CONFIG_OF 55#ifdef CONFIG_OF
55#include <linux/of_net.h> 56#include <linux/of_net.h>
@@ -1396,12 +1397,23 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
1396 union ixgbe_adv_rx_desc *rx_desc, 1397 union ixgbe_adv_rx_desc *rx_desc,
1397 struct sk_buff *skb) 1398 struct sk_buff *skb)
1398{ 1399{
1400 __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
1401 __le16 hdr_info = rx_desc->wb.lower.lo_dword.hs_rss.hdr_info;
1402 bool encap_pkt = false;
1403
1399 skb_checksum_none_assert(skb); 1404 skb_checksum_none_assert(skb);
1400 1405
1401 /* Rx csum disabled */ 1406 /* Rx csum disabled */
1402 if (!(ring->netdev->features & NETIF_F_RXCSUM)) 1407 if (!(ring->netdev->features & NETIF_F_RXCSUM))
1403 return; 1408 return;
1404 1409
1410 if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) &&
1411 (hdr_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_TUNNEL >> 16))) {
1412 encap_pkt = true;
1413 skb->encapsulation = 1;
1414 skb->ip_summed = CHECKSUM_NONE;
1415 }
1416
1405 /* if IP and error */ 1417 /* if IP and error */
1406 if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_IPCS) && 1418 if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_IPCS) &&
1407 ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_IPE)) { 1419 ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_IPE)) {
@@ -1413,8 +1425,6 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
1413 return; 1425 return;
1414 1426
1415 if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) { 1427 if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) {
1416 __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
1417
1418 /* 1428 /*
1419 * 82599 errata, UDP frames with a 0 checksum can be marked as 1429 * 82599 errata, UDP frames with a 0 checksum can be marked as
1420 * checksum errors. 1430 * checksum errors.
@@ -1429,6 +1439,17 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
1429 1439
1430 /* It must be a TCP or UDP packet with a valid checksum */ 1440 /* It must be a TCP or UDP packet with a valid checksum */
1431 skb->ip_summed = CHECKSUM_UNNECESSARY; 1441 skb->ip_summed = CHECKSUM_UNNECESSARY;
1442 if (encap_pkt) {
1443 if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_OUTERIPCS))
1444 return;
1445
1446 if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_OUTERIPER)) {
1447 ring->rx_stats.csum_err++;
1448 return;
1449 }
1450 /* If we checked the outer header let the stack know */
1451 skb->csum_level = 1;
1452 }
1432} 1453}
1433 1454
1434static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, 1455static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring,
@@ -5627,6 +5648,10 @@ static int ixgbe_open(struct net_device *netdev)
5627 5648
5628 ixgbe_up_complete(adapter); 5649 ixgbe_up_complete(adapter);
5629 5650
5651#if IS_ENABLED(CONFIG_IXGBE_VXLAN)
5652 vxlan_get_rx_port(netdev);
5653
5654#endif
5630 return 0; 5655 return 0;
5631 5656
5632err_set_queues: 5657err_set_queues:
@@ -7771,6 +7796,64 @@ static int ixgbe_set_features(struct net_device *netdev,
7771 return 0; 7796 return 0;
7772} 7797}
7773 7798
7799/**
7800 * ixgbe_add_vxlan_port - Get notifications about VXLAN ports that come up
7801 * @dev: The port's netdev
7802 * @sa_family: Socket Family that VXLAN is notifiying us about
7803 * @port: New UDP port number that VXLAN started listening to
7804 **/
7805static void ixgbe_add_vxlan_port(struct net_device *dev, sa_family_t sa_family,
7806 __be16 port)
7807{
7808 struct ixgbe_adapter *adapter = netdev_priv(dev);
7809 struct ixgbe_hw *hw = &adapter->hw;
7810 u16 new_port = ntohs(port);
7811
7812 if (sa_family == AF_INET6)
7813 return;
7814
7815 if (adapter->vxlan_port == new_port) {
7816 netdev_info(dev, "Port %d already offloaded\n", new_port);
7817 return;
7818 }
7819
7820 if (adapter->vxlan_port) {
7821 netdev_info(dev,
7822 "Hit Max num of UDP ports, not adding port %d\n",
7823 new_port);
7824 return;
7825 }
7826
7827 adapter->vxlan_port = new_port;
7828 IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, new_port);
7829}
7830
7831/**
7832 * ixgbe_del_vxlan_port - Get notifications about VXLAN ports that go away
7833 * @dev: The port's netdev
7834 * @sa_family: Socket Family that VXLAN is notifying us about
7835 * @port: UDP port number that VXLAN stopped listening to
7836 **/
7837static void ixgbe_del_vxlan_port(struct net_device *dev, sa_family_t sa_family,
7838 __be16 port)
7839{
7840 struct ixgbe_adapter *adapter = netdev_priv(dev);
7841 struct ixgbe_hw *hw = &adapter->hw;
7842 u16 new_port = ntohs(port);
7843
7844 if (sa_family == AF_INET6)
7845 return;
7846
7847 if (adapter->vxlan_port != new_port) {
7848 netdev_info(dev, "Port %d was not found, not deleting\n",
7849 new_port);
7850 return;
7851 }
7852
7853 adapter->vxlan_port = 0;
7854 IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, 0);
7855}
7856
7774static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], 7857static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
7775 struct net_device *dev, 7858 struct net_device *dev,
7776 const unsigned char *addr, u16 vid, 7859 const unsigned char *addr, u16 vid,
@@ -7982,6 +8065,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
7982 .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink, 8065 .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink,
7983 .ndo_dfwd_add_station = ixgbe_fwd_add, 8066 .ndo_dfwd_add_station = ixgbe_fwd_add,
7984 .ndo_dfwd_del_station = ixgbe_fwd_del, 8067 .ndo_dfwd_del_station = ixgbe_fwd_del,
8068 .ndo_add_vxlan_port = ixgbe_add_vxlan_port,
8069 .ndo_del_vxlan_port = ixgbe_del_vxlan_port,
7985}; 8070};
7986 8071
7987/** 8072/**
@@ -8339,6 +8424,15 @@ skip_sriov:
8339 netdev->priv_flags |= IFF_UNICAST_FLT; 8424 netdev->priv_flags |= IFF_UNICAST_FLT;
8340 netdev->priv_flags |= IFF_SUPP_NOFCS; 8425 netdev->priv_flags |= IFF_SUPP_NOFCS;
8341 8426
8427 switch (adapter->hw.mac.type) {
8428 case ixgbe_mac_X550:
8429 case ixgbe_mac_X550EM_x:
8430 netdev->hw_enc_features |= NETIF_F_RXCSUM;
8431 break;
8432 default:
8433 break;
8434 }
8435
8342#ifdef CONFIG_IXGBE_DCB 8436#ifdef CONFIG_IXGBE_DCB
8343 netdev->dcbnl_ops = &dcbnl_ops; 8437 netdev->dcbnl_ops = &dcbnl_ops;
8344#endif 8438#endif
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index d101b25dc4b6..02b57bfe72b0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -399,6 +399,7 @@ struct ixgbe_thermal_sensor_data {
399 399
400#define IXGBE_WUPL 0x05900 400#define IXGBE_WUPL 0x05900
401#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */ 401#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
402#define IXGBE_VXLANCTRL 0x0000507C /* Rx filter VXLAN UDPPORT Register */
402#define IXGBE_FHFT(_n) (0x09000 + ((_n) * 0x100)) /* Flex host filter table */ 403#define IXGBE_FHFT(_n) (0x09000 + ((_n) * 0x100)) /* Flex host filter table */
403#define IXGBE_FHFT_EXT(_n) (0x09800 + ((_n) * 0x100)) /* Ext Flexible Host 404#define IXGBE_FHFT_EXT(_n) (0x09800 + ((_n) * 0x100)) /* Ext Flexible Host
404 * Filter Table */ 405 * Filter Table */
@@ -2122,6 +2123,7 @@ enum {
2122#define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ 2123#define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
2123#define IXGBE_RXD_STAT_PIF 0x80 /* passed in-exact filter */ 2124#define IXGBE_RXD_STAT_PIF 0x80 /* passed in-exact filter */
2124#define IXGBE_RXD_STAT_CRCV 0x100 /* Speculative CRC Valid */ 2125#define IXGBE_RXD_STAT_CRCV 0x100 /* Speculative CRC Valid */
2126#define IXGBE_RXD_STAT_OUTERIPCS 0x100 /* Cloud IP xsum calculated */
2125#define IXGBE_RXD_STAT_VEXT 0x200 /* 1st VLAN found */ 2127#define IXGBE_RXD_STAT_VEXT 0x200 /* 1st VLAN found */
2126#define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ 2128#define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
2127#define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */ 2129#define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
@@ -2139,6 +2141,7 @@ enum {
2139#define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */ 2141#define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */
2140#define IXGBE_RXDADV_ERR_MASK 0xfff00000 /* RDESC.ERRORS mask */ 2142#define IXGBE_RXDADV_ERR_MASK 0xfff00000 /* RDESC.ERRORS mask */
2141#define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */ 2143#define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */
2144#define IXGBE_RXDADV_ERR_OUTERIPER 0x04000000 /* CRC IP Header error */
2142#define IXGBE_RXDADV_ERR_FCEOFE 0x80000000 /* FCoEFe/IPE */ 2145#define IXGBE_RXDADV_ERR_FCEOFE 0x80000000 /* FCoEFe/IPE */
2143#define IXGBE_RXDADV_ERR_FCERR 0x00700000 /* FCERR/FDIRERR */ 2146#define IXGBE_RXDADV_ERR_FCERR 0x00700000 /* FCERR/FDIRERR */
2144#define IXGBE_RXDADV_ERR_FDIR_LEN 0x00100000 /* FDIR Length error */ 2147#define IXGBE_RXDADV_ERR_FDIR_LEN 0x00100000 /* FDIR Length error */
@@ -2227,6 +2230,8 @@ enum {
2227#define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ 2230#define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */
2228#define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ 2231#define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */
2229#define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ 2232#define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */
2233#define IXGBE_RXDADV_PKTTYPE_VXLAN 0x00000800 /* VXLAN hdr present */
2234#define IXGBE_RXDADV_PKTTYPE_TUNNEL 0x00010000 /* Tunnel type */
2230#define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */ 2235#define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */
2231#define IXGBE_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */ 2236#define IXGBE_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */
2232#define IXGBE_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */ 2237#define IXGBE_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */