diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 118 |
1 files changed, 113 insertions, 5 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 67b02bde179e..70cc4c5c0a01 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 | ||
1434 | static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, | 1455 | static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, |
@@ -3564,10 +3585,24 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) | |||
3564 | /* Enable MAC Anti-Spoofing */ | 3585 | /* Enable MAC Anti-Spoofing */ |
3565 | hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0), | 3586 | hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0), |
3566 | adapter->num_vfs); | 3587 | adapter->num_vfs); |
3588 | |||
3589 | /* Ensure LLDP is set for Ethertype Antispoofing if we will be | ||
3590 | * calling set_ethertype_anti_spoofing for each VF in loop below | ||
3591 | */ | ||
3592 | if (hw->mac.ops.set_ethertype_anti_spoofing) | ||
3593 | IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_LLDP), | ||
3594 | (IXGBE_ETQF_FILTER_EN | /* enable filter */ | ||
3595 | IXGBE_ETQF_TX_ANTISPOOF | /* tx antispoof */ | ||
3596 | IXGBE_ETH_P_LLDP)); /* LLDP eth type */ | ||
3597 | |||
3567 | /* For VFs that have spoof checking turned off */ | 3598 | /* For VFs that have spoof checking turned off */ |
3568 | for (i = 0; i < adapter->num_vfs; i++) { | 3599 | for (i = 0; i < adapter->num_vfs; i++) { |
3569 | if (!adapter->vfinfo[i].spoofchk_enabled) | 3600 | if (!adapter->vfinfo[i].spoofchk_enabled) |
3570 | ixgbe_ndo_set_vf_spoofchk(adapter->netdev, i, false); | 3601 | ixgbe_ndo_set_vf_spoofchk(adapter->netdev, i, false); |
3602 | |||
3603 | /* enable ethertype anti spoofing if hw supports it */ | ||
3604 | if (hw->mac.ops.set_ethertype_anti_spoofing) | ||
3605 | hw->mac.ops.set_ethertype_anti_spoofing(hw, true, i); | ||
3571 | } | 3606 | } |
3572 | } | 3607 | } |
3573 | 3608 | ||
@@ -5627,6 +5662,10 @@ static int ixgbe_open(struct net_device *netdev) | |||
5627 | 5662 | ||
5628 | ixgbe_up_complete(adapter); | 5663 | ixgbe_up_complete(adapter); |
5629 | 5664 | ||
5665 | #if IS_ENABLED(CONFIG_IXGBE_VXLAN) | ||
5666 | vxlan_get_rx_port(netdev); | ||
5667 | |||
5668 | #endif | ||
5630 | return 0; | 5669 | return 0; |
5631 | 5670 | ||
5632 | err_set_queues: | 5671 | err_set_queues: |
@@ -7217,8 +7256,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, | |||
7217 | first->gso_segs = 1; | 7256 | first->gso_segs = 1; |
7218 | 7257 | ||
7219 | /* if we have a HW VLAN tag being added default to the HW one */ | 7258 | /* if we have a HW VLAN tag being added default to the HW one */ |
7220 | if (vlan_tx_tag_present(skb)) { | 7259 | if (skb_vlan_tag_present(skb)) { |
7221 | tx_flags |= vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT; | 7260 | tx_flags |= skb_vlan_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT; |
7222 | tx_flags |= IXGBE_TX_FLAGS_HW_VLAN; | 7261 | tx_flags |= IXGBE_TX_FLAGS_HW_VLAN; |
7223 | /* else if it is a SW VLAN check the next protocol and store the tag */ | 7262 | /* else if it is a SW VLAN check the next protocol and store the tag */ |
7224 | } else if (protocol == htons(ETH_P_8021Q)) { | 7263 | } else if (protocol == htons(ETH_P_8021Q)) { |
@@ -7771,6 +7810,64 @@ static int ixgbe_set_features(struct net_device *netdev, | |||
7771 | return 0; | 7810 | return 0; |
7772 | } | 7811 | } |
7773 | 7812 | ||
7813 | /** | ||
7814 | * ixgbe_add_vxlan_port - Get notifications about VXLAN ports that come up | ||
7815 | * @dev: The port's netdev | ||
7816 | * @sa_family: Socket Family that VXLAN is notifiying us about | ||
7817 | * @port: New UDP port number that VXLAN started listening to | ||
7818 | **/ | ||
7819 | static void ixgbe_add_vxlan_port(struct net_device *dev, sa_family_t sa_family, | ||
7820 | __be16 port) | ||
7821 | { | ||
7822 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
7823 | struct ixgbe_hw *hw = &adapter->hw; | ||
7824 | u16 new_port = ntohs(port); | ||
7825 | |||
7826 | if (sa_family == AF_INET6) | ||
7827 | return; | ||
7828 | |||
7829 | if (adapter->vxlan_port == new_port) { | ||
7830 | netdev_info(dev, "Port %d already offloaded\n", new_port); | ||
7831 | return; | ||
7832 | } | ||
7833 | |||
7834 | if (adapter->vxlan_port) { | ||
7835 | netdev_info(dev, | ||
7836 | "Hit Max num of UDP ports, not adding port %d\n", | ||
7837 | new_port); | ||
7838 | return; | ||
7839 | } | ||
7840 | |||
7841 | adapter->vxlan_port = new_port; | ||
7842 | IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, new_port); | ||
7843 | } | ||
7844 | |||
7845 | /** | ||
7846 | * ixgbe_del_vxlan_port - Get notifications about VXLAN ports that go away | ||
7847 | * @dev: The port's netdev | ||
7848 | * @sa_family: Socket Family that VXLAN is notifying us about | ||
7849 | * @port: UDP port number that VXLAN stopped listening to | ||
7850 | **/ | ||
7851 | static void ixgbe_del_vxlan_port(struct net_device *dev, sa_family_t sa_family, | ||
7852 | __be16 port) | ||
7853 | { | ||
7854 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
7855 | struct ixgbe_hw *hw = &adapter->hw; | ||
7856 | u16 new_port = ntohs(port); | ||
7857 | |||
7858 | if (sa_family == AF_INET6) | ||
7859 | return; | ||
7860 | |||
7861 | if (adapter->vxlan_port != new_port) { | ||
7862 | netdev_info(dev, "Port %d was not found, not deleting\n", | ||
7863 | new_port); | ||
7864 | return; | ||
7865 | } | ||
7866 | |||
7867 | adapter->vxlan_port = 0; | ||
7868 | IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, 0); | ||
7869 | } | ||
7870 | |||
7774 | static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | 7871 | static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], |
7775 | struct net_device *dev, | 7872 | struct net_device *dev, |
7776 | const unsigned char *addr, u16 vid, | 7873 | const unsigned char *addr, u16 vid, |
@@ -7786,7 +7883,7 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | |||
7786 | } | 7883 | } |
7787 | 7884 | ||
7788 | static int ixgbe_ndo_bridge_setlink(struct net_device *dev, | 7885 | static int ixgbe_ndo_bridge_setlink(struct net_device *dev, |
7789 | struct nlmsghdr *nlh) | 7886 | struct nlmsghdr *nlh, u16 flags) |
7790 | { | 7887 | { |
7791 | struct ixgbe_adapter *adapter = netdev_priv(dev); | 7888 | struct ixgbe_adapter *adapter = netdev_priv(dev); |
7792 | struct nlattr *attr, *br_spec; | 7889 | struct nlattr *attr, *br_spec; |
@@ -7982,6 +8079,8 @@ static const struct net_device_ops ixgbe_netdev_ops = { | |||
7982 | .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink, | 8079 | .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink, |
7983 | .ndo_dfwd_add_station = ixgbe_fwd_add, | 8080 | .ndo_dfwd_add_station = ixgbe_fwd_add, |
7984 | .ndo_dfwd_del_station = ixgbe_fwd_del, | 8081 | .ndo_dfwd_del_station = ixgbe_fwd_del, |
8082 | .ndo_add_vxlan_port = ixgbe_add_vxlan_port, | ||
8083 | .ndo_del_vxlan_port = ixgbe_del_vxlan_port, | ||
7985 | }; | 8084 | }; |
7986 | 8085 | ||
7987 | /** | 8086 | /** |
@@ -8339,6 +8438,15 @@ skip_sriov: | |||
8339 | netdev->priv_flags |= IFF_UNICAST_FLT; | 8438 | netdev->priv_flags |= IFF_UNICAST_FLT; |
8340 | netdev->priv_flags |= IFF_SUPP_NOFCS; | 8439 | netdev->priv_flags |= IFF_SUPP_NOFCS; |
8341 | 8440 | ||
8441 | switch (adapter->hw.mac.type) { | ||
8442 | case ixgbe_mac_X550: | ||
8443 | case ixgbe_mac_X550EM_x: | ||
8444 | netdev->hw_enc_features |= NETIF_F_RXCSUM; | ||
8445 | break; | ||
8446 | default: | ||
8447 | break; | ||
8448 | } | ||
8449 | |||
8342 | #ifdef CONFIG_IXGBE_DCB | 8450 | #ifdef CONFIG_IXGBE_DCB |
8343 | netdev->dcbnl_ops = &dcbnl_ops; | 8451 | netdev->dcbnl_ops = &dcbnl_ops; |
8344 | #endif | 8452 | #endif |