| .. | .. |
|---|
| 119 | 119 | #include <linux/tcp.h> |
|---|
| 120 | 120 | #include <linux/if_vlan.h> |
|---|
| 121 | 121 | #include <linux/interrupt.h> |
|---|
| 122 | | -#include <net/busy_poll.h> |
|---|
| 123 | 122 | #include <linux/clk.h> |
|---|
| 124 | 123 | #include <linux/if_ether.h> |
|---|
| 125 | 124 | #include <linux/net_tstamp.h> |
|---|
| .. | .. |
|---|
| 404 | 403 | return false; |
|---|
| 405 | 404 | } |
|---|
| 406 | 405 | |
|---|
| 407 | | -static void xgbe_ecc_isr_task(unsigned long data) |
|---|
| 406 | +static void xgbe_ecc_isr_task(struct tasklet_struct *t) |
|---|
| 408 | 407 | { |
|---|
| 409 | | - struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data; |
|---|
| 408 | + struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_ecc); |
|---|
| 410 | 409 | unsigned int ecc_isr; |
|---|
| 411 | 410 | bool stop = false; |
|---|
| 412 | 411 | |
|---|
| .. | .. |
|---|
| 469 | 468 | if (pdata->isr_as_tasklet) |
|---|
| 470 | 469 | tasklet_schedule(&pdata->tasklet_ecc); |
|---|
| 471 | 470 | else |
|---|
| 472 | | - xgbe_ecc_isr_task((unsigned long)pdata); |
|---|
| 471 | + xgbe_ecc_isr_task(&pdata->tasklet_ecc); |
|---|
| 473 | 472 | |
|---|
| 474 | 473 | return IRQ_HANDLED; |
|---|
| 475 | 474 | } |
|---|
| 476 | 475 | |
|---|
| 477 | | -static void xgbe_isr_task(unsigned long data) |
|---|
| 476 | +static void xgbe_isr_task(struct tasklet_struct *t) |
|---|
| 478 | 477 | { |
|---|
| 479 | | - struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data; |
|---|
| 478 | + struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_dev); |
|---|
| 480 | 479 | struct xgbe_hw_if *hw_if = &pdata->hw_if; |
|---|
| 481 | 480 | struct xgbe_channel *channel; |
|---|
| 482 | 481 | unsigned int dma_isr, dma_ch_isr; |
|---|
| .. | .. |
|---|
| 583 | 582 | |
|---|
| 584 | 583 | /* If there is not a separate ECC irq, handle it here */ |
|---|
| 585 | 584 | if (pdata->vdata->ecc_support && (pdata->dev_irq == pdata->ecc_irq)) |
|---|
| 586 | | - xgbe_ecc_isr_task((unsigned long)pdata); |
|---|
| 585 | + xgbe_ecc_isr_task(&pdata->tasklet_ecc); |
|---|
| 587 | 586 | |
|---|
| 588 | 587 | /* If there is not a separate I2C irq, handle it here */ |
|---|
| 589 | 588 | if (pdata->vdata->i2c_support && (pdata->dev_irq == pdata->i2c_irq)) |
|---|
| .. | .. |
|---|
| 608 | 607 | if (pdata->isr_as_tasklet) |
|---|
| 609 | 608 | tasklet_schedule(&pdata->tasklet_dev); |
|---|
| 610 | 609 | else |
|---|
| 611 | | - xgbe_isr_task((unsigned long)pdata); |
|---|
| 610 | + xgbe_isr_task(&pdata->tasklet_dev); |
|---|
| 612 | 611 | |
|---|
| 613 | 612 | return IRQ_HANDLED; |
|---|
| 614 | 613 | } |
|---|
| .. | .. |
|---|
| 907 | 906 | } |
|---|
| 908 | 907 | } |
|---|
| 909 | 908 | |
|---|
| 910 | | -static void xgbe_disable_vxlan_offloads(struct xgbe_prv_data *pdata) |
|---|
| 909 | +static int xgbe_vxlan_set_port(struct net_device *netdev, unsigned int table, |
|---|
| 910 | + unsigned int entry, struct udp_tunnel_info *ti) |
|---|
| 911 | 911 | { |
|---|
| 912 | | - struct net_device *netdev = pdata->netdev; |
|---|
| 912 | + struct xgbe_prv_data *pdata = netdev_priv(netdev); |
|---|
| 913 | 913 | |
|---|
| 914 | | - if (!pdata->vxlan_offloads_set) |
|---|
| 915 | | - return; |
|---|
| 914 | + pdata->vxlan_port = be16_to_cpu(ti->port); |
|---|
| 915 | + pdata->hw_if.enable_vxlan(pdata); |
|---|
| 916 | 916 | |
|---|
| 917 | | - netdev_info(netdev, "disabling VXLAN offloads\n"); |
|---|
| 918 | | - |
|---|
| 919 | | - netdev->hw_enc_features &= ~(NETIF_F_SG | |
|---|
| 920 | | - NETIF_F_IP_CSUM | |
|---|
| 921 | | - NETIF_F_IPV6_CSUM | |
|---|
| 922 | | - NETIF_F_RXCSUM | |
|---|
| 923 | | - NETIF_F_TSO | |
|---|
| 924 | | - NETIF_F_TSO6 | |
|---|
| 925 | | - NETIF_F_GRO | |
|---|
| 926 | | - NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 927 | | - NETIF_F_GSO_UDP_TUNNEL_CSUM); |
|---|
| 928 | | - |
|---|
| 929 | | - netdev->features &= ~(NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 930 | | - NETIF_F_GSO_UDP_TUNNEL_CSUM); |
|---|
| 931 | | - |
|---|
| 932 | | - pdata->vxlan_offloads_set = 0; |
|---|
| 917 | + return 0; |
|---|
| 933 | 918 | } |
|---|
| 934 | 919 | |
|---|
| 935 | | -static void xgbe_disable_vxlan_hw(struct xgbe_prv_data *pdata) |
|---|
| 920 | +static int xgbe_vxlan_unset_port(struct net_device *netdev, unsigned int table, |
|---|
| 921 | + unsigned int entry, struct udp_tunnel_info *ti) |
|---|
| 936 | 922 | { |
|---|
| 937 | | - if (!pdata->vxlan_port_set) |
|---|
| 938 | | - return; |
|---|
| 923 | + struct xgbe_prv_data *pdata = netdev_priv(netdev); |
|---|
| 939 | 924 | |
|---|
| 940 | 925 | pdata->hw_if.disable_vxlan(pdata); |
|---|
| 941 | | - |
|---|
| 942 | | - pdata->vxlan_port_set = 0; |
|---|
| 943 | 926 | pdata->vxlan_port = 0; |
|---|
| 927 | + |
|---|
| 928 | + return 0; |
|---|
| 944 | 929 | } |
|---|
| 945 | 930 | |
|---|
| 946 | | -static void xgbe_disable_vxlan_accel(struct xgbe_prv_data *pdata) |
|---|
| 931 | +static const struct udp_tunnel_nic_info xgbe_udp_tunnels = { |
|---|
| 932 | + .set_port = xgbe_vxlan_set_port, |
|---|
| 933 | + .unset_port = xgbe_vxlan_unset_port, |
|---|
| 934 | + .flags = UDP_TUNNEL_NIC_INFO_OPEN_ONLY, |
|---|
| 935 | + .tables = { |
|---|
| 936 | + { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, |
|---|
| 937 | + }, |
|---|
| 938 | +}; |
|---|
| 939 | + |
|---|
| 940 | +const struct udp_tunnel_nic_info *xgbe_get_udp_tunnel_info(void) |
|---|
| 947 | 941 | { |
|---|
| 948 | | - xgbe_disable_vxlan_offloads(pdata); |
|---|
| 949 | | - |
|---|
| 950 | | - xgbe_disable_vxlan_hw(pdata); |
|---|
| 951 | | -} |
|---|
| 952 | | - |
|---|
| 953 | | -static void xgbe_enable_vxlan_offloads(struct xgbe_prv_data *pdata) |
|---|
| 954 | | -{ |
|---|
| 955 | | - struct net_device *netdev = pdata->netdev; |
|---|
| 956 | | - |
|---|
| 957 | | - if (pdata->vxlan_offloads_set) |
|---|
| 958 | | - return; |
|---|
| 959 | | - |
|---|
| 960 | | - netdev_info(netdev, "enabling VXLAN offloads\n"); |
|---|
| 961 | | - |
|---|
| 962 | | - netdev->hw_enc_features |= NETIF_F_SG | |
|---|
| 963 | | - NETIF_F_IP_CSUM | |
|---|
| 964 | | - NETIF_F_IPV6_CSUM | |
|---|
| 965 | | - NETIF_F_RXCSUM | |
|---|
| 966 | | - NETIF_F_TSO | |
|---|
| 967 | | - NETIF_F_TSO6 | |
|---|
| 968 | | - NETIF_F_GRO | |
|---|
| 969 | | - pdata->vxlan_features; |
|---|
| 970 | | - |
|---|
| 971 | | - netdev->features |= pdata->vxlan_features; |
|---|
| 972 | | - |
|---|
| 973 | | - pdata->vxlan_offloads_set = 1; |
|---|
| 974 | | -} |
|---|
| 975 | | - |
|---|
| 976 | | -static void xgbe_enable_vxlan_hw(struct xgbe_prv_data *pdata) |
|---|
| 977 | | -{ |
|---|
| 978 | | - struct xgbe_vxlan_data *vdata; |
|---|
| 979 | | - |
|---|
| 980 | | - if (pdata->vxlan_port_set) |
|---|
| 981 | | - return; |
|---|
| 982 | | - |
|---|
| 983 | | - if (list_empty(&pdata->vxlan_ports)) |
|---|
| 984 | | - return; |
|---|
| 985 | | - |
|---|
| 986 | | - vdata = list_first_entry(&pdata->vxlan_ports, |
|---|
| 987 | | - struct xgbe_vxlan_data, list); |
|---|
| 988 | | - |
|---|
| 989 | | - pdata->vxlan_port_set = 1; |
|---|
| 990 | | - pdata->vxlan_port = be16_to_cpu(vdata->port); |
|---|
| 991 | | - |
|---|
| 992 | | - pdata->hw_if.enable_vxlan(pdata); |
|---|
| 993 | | -} |
|---|
| 994 | | - |
|---|
| 995 | | -static void xgbe_enable_vxlan_accel(struct xgbe_prv_data *pdata) |
|---|
| 996 | | -{ |
|---|
| 997 | | - /* VXLAN acceleration desired? */ |
|---|
| 998 | | - if (!pdata->vxlan_features) |
|---|
| 999 | | - return; |
|---|
| 1000 | | - |
|---|
| 1001 | | - /* VXLAN acceleration possible? */ |
|---|
| 1002 | | - if (pdata->vxlan_force_disable) |
|---|
| 1003 | | - return; |
|---|
| 1004 | | - |
|---|
| 1005 | | - xgbe_enable_vxlan_hw(pdata); |
|---|
| 1006 | | - |
|---|
| 1007 | | - xgbe_enable_vxlan_offloads(pdata); |
|---|
| 1008 | | -} |
|---|
| 1009 | | - |
|---|
| 1010 | | -static void xgbe_reset_vxlan_accel(struct xgbe_prv_data *pdata) |
|---|
| 1011 | | -{ |
|---|
| 1012 | | - xgbe_disable_vxlan_hw(pdata); |
|---|
| 1013 | | - |
|---|
| 1014 | | - if (pdata->vxlan_features) |
|---|
| 1015 | | - xgbe_enable_vxlan_offloads(pdata); |
|---|
| 1016 | | - |
|---|
| 1017 | | - pdata->vxlan_force_disable = 0; |
|---|
| 942 | + return &xgbe_udp_tunnels; |
|---|
| 1018 | 943 | } |
|---|
| 1019 | 944 | |
|---|
| 1020 | 945 | static void xgbe_napi_enable(struct xgbe_prv_data *pdata, unsigned int add) |
|---|
| .. | .. |
|---|
| 1068 | 993 | unsigned int i; |
|---|
| 1069 | 994 | int ret; |
|---|
| 1070 | 995 | |
|---|
| 1071 | | - tasklet_init(&pdata->tasklet_dev, xgbe_isr_task, (unsigned long)pdata); |
|---|
| 1072 | | - tasklet_init(&pdata->tasklet_ecc, xgbe_ecc_isr_task, |
|---|
| 1073 | | - (unsigned long)pdata); |
|---|
| 996 | + tasklet_setup(&pdata->tasklet_dev, xgbe_isr_task); |
|---|
| 997 | + tasklet_setup(&pdata->tasklet_ecc, xgbe_ecc_isr_task); |
|---|
| 1074 | 998 | |
|---|
| 1075 | 999 | ret = devm_request_irq(pdata->dev, pdata->dev_irq, xgbe_isr, 0, |
|---|
| 1076 | 1000 | netdev_name(netdev), pdata); |
|---|
| .. | .. |
|---|
| 1139 | 1063 | unsigned int i; |
|---|
| 1140 | 1064 | |
|---|
| 1141 | 1065 | devm_free_irq(pdata->dev, pdata->dev_irq, pdata); |
|---|
| 1066 | + |
|---|
| 1067 | + tasklet_kill(&pdata->tasklet_dev); |
|---|
| 1068 | + tasklet_kill(&pdata->tasklet_ecc); |
|---|
| 1142 | 1069 | |
|---|
| 1143 | 1070 | if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq)) |
|---|
| 1144 | 1071 | devm_free_irq(pdata->dev, pdata->ecc_irq, pdata); |
|---|
| .. | .. |
|---|
| 1409 | 1336 | hw_if->enable_tx(pdata); |
|---|
| 1410 | 1337 | hw_if->enable_rx(pdata); |
|---|
| 1411 | 1338 | |
|---|
| 1412 | | - udp_tunnel_get_rx_info(netdev); |
|---|
| 1339 | + udp_tunnel_nic_reset_ntf(netdev); |
|---|
| 1413 | 1340 | |
|---|
| 1414 | 1341 | netif_tx_start_all_queues(netdev); |
|---|
| 1415 | 1342 | |
|---|
| .. | .. |
|---|
| 1451 | 1378 | xgbe_stop_timers(pdata); |
|---|
| 1452 | 1379 | flush_workqueue(pdata->dev_workqueue); |
|---|
| 1453 | 1380 | |
|---|
| 1454 | | - xgbe_reset_vxlan_accel(pdata); |
|---|
| 1381 | + xgbe_vxlan_unset_port(netdev, 0, 0, NULL); |
|---|
| 1455 | 1382 | |
|---|
| 1456 | 1383 | hw_if->disable_tx(pdata); |
|---|
| 1457 | 1384 | hw_if->disable_rx(pdata); |
|---|
| .. | .. |
|---|
| 1616 | 1543 | /* PTP v2, UDP, any kind of event packet */ |
|---|
| 1617 | 1544 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: |
|---|
| 1618 | 1545 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1); |
|---|
| 1619 | | - /* PTP v1, UDP, any kind of event packet */ |
|---|
| 1546 | + fallthrough; /* to PTP v1, UDP, any kind of event packet */ |
|---|
| 1620 | 1547 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: |
|---|
| 1621 | 1548 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1); |
|---|
| 1622 | 1549 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1); |
|---|
| .. | .. |
|---|
| 1627 | 1554 | /* PTP v2, UDP, Sync packet */ |
|---|
| 1628 | 1555 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: |
|---|
| 1629 | 1556 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1); |
|---|
| 1630 | | - /* PTP v1, UDP, Sync packet */ |
|---|
| 1557 | + fallthrough; /* to PTP v1, UDP, Sync packet */ |
|---|
| 1631 | 1558 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: |
|---|
| 1632 | 1559 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1); |
|---|
| 1633 | 1560 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1); |
|---|
| .. | .. |
|---|
| 1638 | 1565 | /* PTP v2, UDP, Delay_req packet */ |
|---|
| 1639 | 1566 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: |
|---|
| 1640 | 1567 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1); |
|---|
| 1641 | | - /* PTP v1, UDP, Delay_req packet */ |
|---|
| 1568 | + fallthrough; /* to PTP v1, UDP, Delay_req packet */ |
|---|
| 1642 | 1569 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: |
|---|
| 1643 | 1570 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1); |
|---|
| 1644 | 1571 | XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1); |
|---|
| .. | .. |
|---|
| 1777 | 1704 | return 0; |
|---|
| 1778 | 1705 | } |
|---|
| 1779 | 1706 | |
|---|
| 1780 | | -static bool xgbe_is_vxlan(struct xgbe_prv_data *pdata, struct sk_buff *skb) |
|---|
| 1707 | +static bool xgbe_is_vxlan(struct sk_buff *skb) |
|---|
| 1781 | 1708 | { |
|---|
| 1782 | | - struct xgbe_vxlan_data *vdata; |
|---|
| 1783 | | - |
|---|
| 1784 | | - if (pdata->vxlan_force_disable) |
|---|
| 1785 | | - return false; |
|---|
| 1786 | | - |
|---|
| 1787 | 1709 | if (!skb->encapsulation) |
|---|
| 1788 | 1710 | return false; |
|---|
| 1789 | 1711 | |
|---|
| .. | .. |
|---|
| 1805 | 1727 | return false; |
|---|
| 1806 | 1728 | } |
|---|
| 1807 | 1729 | |
|---|
| 1808 | | - /* See if we have the UDP port in our list */ |
|---|
| 1809 | | - list_for_each_entry(vdata, &pdata->vxlan_ports, list) { |
|---|
| 1810 | | - if ((skb->protocol == htons(ETH_P_IP)) && |
|---|
| 1811 | | - (vdata->sa_family == AF_INET) && |
|---|
| 1812 | | - (vdata->port == udp_hdr(skb)->dest)) |
|---|
| 1813 | | - return true; |
|---|
| 1814 | | - else if ((skb->protocol == htons(ETH_P_IPV6)) && |
|---|
| 1815 | | - (vdata->sa_family == AF_INET6) && |
|---|
| 1816 | | - (vdata->port == udp_hdr(skb)->dest)) |
|---|
| 1817 | | - return true; |
|---|
| 1818 | | - } |
|---|
| 1730 | + if (skb->inner_protocol_type != ENCAP_TYPE_ETHER || |
|---|
| 1731 | + skb->inner_protocol != htons(ETH_P_TEB) || |
|---|
| 1732 | + (skb_inner_mac_header(skb) - skb_transport_header(skb) != |
|---|
| 1733 | + sizeof(struct udphdr) + sizeof(struct vxlanhdr))) |
|---|
| 1734 | + return false; |
|---|
| 1819 | 1735 | |
|---|
| 1820 | | - return false; |
|---|
| 1736 | + return true; |
|---|
| 1821 | 1737 | } |
|---|
| 1822 | 1738 | |
|---|
| 1823 | 1739 | static int xgbe_is_tso(struct sk_buff *skb) |
|---|
| .. | .. |
|---|
| 1837 | 1753 | struct xgbe_ring *ring, struct sk_buff *skb, |
|---|
| 1838 | 1754 | struct xgbe_packet_data *packet) |
|---|
| 1839 | 1755 | { |
|---|
| 1840 | | - struct skb_frag_struct *frag; |
|---|
| 1756 | + skb_frag_t *frag; |
|---|
| 1841 | 1757 | unsigned int context_desc; |
|---|
| 1842 | 1758 | unsigned int len; |
|---|
| 1843 | 1759 | unsigned int i; |
|---|
| .. | .. |
|---|
| 1868 | 1784 | XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, |
|---|
| 1869 | 1785 | CSUM_ENABLE, 1); |
|---|
| 1870 | 1786 | |
|---|
| 1871 | | - if (xgbe_is_vxlan(pdata, skb)) |
|---|
| 1787 | + if (xgbe_is_vxlan(skb)) |
|---|
| 1872 | 1788 | XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, |
|---|
| 1873 | 1789 | VXLAN, 1); |
|---|
| 1874 | 1790 | |
|---|
| .. | .. |
|---|
| 2156 | 2072 | return 0; |
|---|
| 2157 | 2073 | } |
|---|
| 2158 | 2074 | |
|---|
| 2159 | | -static void xgbe_tx_timeout(struct net_device *netdev) |
|---|
| 2075 | +static void xgbe_tx_timeout(struct net_device *netdev, unsigned int txqueue) |
|---|
| 2160 | 2076 | { |
|---|
| 2161 | 2077 | struct xgbe_prv_data *pdata = netdev_priv(netdev); |
|---|
| 2162 | 2078 | |
|---|
| .. | .. |
|---|
| 2275 | 2191 | netdev_features_t features) |
|---|
| 2276 | 2192 | { |
|---|
| 2277 | 2193 | struct xgbe_prv_data *pdata = netdev_priv(netdev); |
|---|
| 2278 | | - netdev_features_t vxlan_base, vxlan_mask; |
|---|
| 2194 | + netdev_features_t vxlan_base; |
|---|
| 2279 | 2195 | |
|---|
| 2280 | 2196 | vxlan_base = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_RX_UDP_TUNNEL_PORT; |
|---|
| 2281 | | - vxlan_mask = vxlan_base | NETIF_F_GSO_UDP_TUNNEL_CSUM; |
|---|
| 2282 | 2197 | |
|---|
| 2283 | | - pdata->vxlan_features = features & vxlan_mask; |
|---|
| 2284 | | - |
|---|
| 2285 | | - /* Only fix VXLAN-related features */ |
|---|
| 2286 | | - if (!pdata->vxlan_features) |
|---|
| 2287 | | - return features; |
|---|
| 2288 | | - |
|---|
| 2289 | | - /* If VXLAN isn't supported then clear any features: |
|---|
| 2290 | | - * This is needed because NETIF_F_RX_UDP_TUNNEL_PORT gets |
|---|
| 2291 | | - * automatically set if ndo_udp_tunnel_add is set. |
|---|
| 2292 | | - */ |
|---|
| 2293 | 2198 | if (!pdata->hw_feat.vxn) |
|---|
| 2294 | | - return features & ~vxlan_mask; |
|---|
| 2199 | + return features; |
|---|
| 2295 | 2200 | |
|---|
| 2296 | 2201 | /* VXLAN CSUM requires VXLAN base */ |
|---|
| 2297 | 2202 | if ((features & NETIF_F_GSO_UDP_TUNNEL_CSUM) && |
|---|
| .. | .. |
|---|
| 2322 | 2227 | } |
|---|
| 2323 | 2228 | } |
|---|
| 2324 | 2229 | |
|---|
| 2325 | | - pdata->vxlan_features = features & vxlan_mask; |
|---|
| 2326 | | - |
|---|
| 2327 | | - /* Adjust UDP Tunnel based on current state */ |
|---|
| 2328 | | - if (pdata->vxlan_force_disable) { |
|---|
| 2329 | | - netdev_notice(netdev, |
|---|
| 2330 | | - "VXLAN acceleration disabled, turning off udp tunnel features\n"); |
|---|
| 2331 | | - features &= ~vxlan_mask; |
|---|
| 2332 | | - } |
|---|
| 2333 | | - |
|---|
| 2334 | 2230 | return features; |
|---|
| 2335 | 2231 | } |
|---|
| 2336 | 2232 | |
|---|
| .. | .. |
|---|
| 2340 | 2236 | struct xgbe_prv_data *pdata = netdev_priv(netdev); |
|---|
| 2341 | 2237 | struct xgbe_hw_if *hw_if = &pdata->hw_if; |
|---|
| 2342 | 2238 | netdev_features_t rxhash, rxcsum, rxvlan, rxvlan_filter; |
|---|
| 2343 | | - netdev_features_t udp_tunnel; |
|---|
| 2344 | 2239 | int ret = 0; |
|---|
| 2345 | 2240 | |
|---|
| 2346 | 2241 | rxhash = pdata->netdev_features & NETIF_F_RXHASH; |
|---|
| 2347 | 2242 | rxcsum = pdata->netdev_features & NETIF_F_RXCSUM; |
|---|
| 2348 | 2243 | rxvlan = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX; |
|---|
| 2349 | 2244 | rxvlan_filter = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_FILTER; |
|---|
| 2350 | | - udp_tunnel = pdata->netdev_features & NETIF_F_GSO_UDP_TUNNEL; |
|---|
| 2351 | 2245 | |
|---|
| 2352 | 2246 | if ((features & NETIF_F_RXHASH) && !rxhash) |
|---|
| 2353 | 2247 | ret = hw_if->enable_rss(pdata); |
|---|
| .. | .. |
|---|
| 2371 | 2265 | else if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER) && rxvlan_filter) |
|---|
| 2372 | 2266 | hw_if->disable_rx_vlan_filtering(pdata); |
|---|
| 2373 | 2267 | |
|---|
| 2374 | | - if ((features & NETIF_F_GSO_UDP_TUNNEL) && !udp_tunnel) |
|---|
| 2375 | | - xgbe_enable_vxlan_accel(pdata); |
|---|
| 2376 | | - else if (!(features & NETIF_F_GSO_UDP_TUNNEL) && udp_tunnel) |
|---|
| 2377 | | - xgbe_disable_vxlan_accel(pdata); |
|---|
| 2378 | | - |
|---|
| 2379 | 2268 | pdata->netdev_features = features; |
|---|
| 2380 | 2269 | |
|---|
| 2381 | 2270 | DBGPR("<--xgbe_set_features\n"); |
|---|
| 2382 | 2271 | |
|---|
| 2383 | 2272 | return 0; |
|---|
| 2384 | | -} |
|---|
| 2385 | | - |
|---|
| 2386 | | -static void xgbe_udp_tunnel_add(struct net_device *netdev, |
|---|
| 2387 | | - struct udp_tunnel_info *ti) |
|---|
| 2388 | | -{ |
|---|
| 2389 | | - struct xgbe_prv_data *pdata = netdev_priv(netdev); |
|---|
| 2390 | | - struct xgbe_vxlan_data *vdata; |
|---|
| 2391 | | - |
|---|
| 2392 | | - if (!pdata->hw_feat.vxn) |
|---|
| 2393 | | - return; |
|---|
| 2394 | | - |
|---|
| 2395 | | - if (ti->type != UDP_TUNNEL_TYPE_VXLAN) |
|---|
| 2396 | | - return; |
|---|
| 2397 | | - |
|---|
| 2398 | | - pdata->vxlan_port_count++; |
|---|
| 2399 | | - |
|---|
| 2400 | | - netif_dbg(pdata, drv, netdev, |
|---|
| 2401 | | - "adding VXLAN tunnel, family=%hx/port=%hx\n", |
|---|
| 2402 | | - ti->sa_family, be16_to_cpu(ti->port)); |
|---|
| 2403 | | - |
|---|
| 2404 | | - if (pdata->vxlan_force_disable) |
|---|
| 2405 | | - return; |
|---|
| 2406 | | - |
|---|
| 2407 | | - vdata = kzalloc(sizeof(*vdata), GFP_ATOMIC); |
|---|
| 2408 | | - if (!vdata) { |
|---|
| 2409 | | - /* Can no longer properly track VXLAN ports */ |
|---|
| 2410 | | - pdata->vxlan_force_disable = 1; |
|---|
| 2411 | | - netif_dbg(pdata, drv, netdev, |
|---|
| 2412 | | - "internal error, disabling VXLAN accelerations\n"); |
|---|
| 2413 | | - |
|---|
| 2414 | | - xgbe_disable_vxlan_accel(pdata); |
|---|
| 2415 | | - |
|---|
| 2416 | | - return; |
|---|
| 2417 | | - } |
|---|
| 2418 | | - vdata->sa_family = ti->sa_family; |
|---|
| 2419 | | - vdata->port = ti->port; |
|---|
| 2420 | | - |
|---|
| 2421 | | - list_add_tail(&vdata->list, &pdata->vxlan_ports); |
|---|
| 2422 | | - |
|---|
| 2423 | | - /* First port added? */ |
|---|
| 2424 | | - if (pdata->vxlan_port_count == 1) { |
|---|
| 2425 | | - xgbe_enable_vxlan_accel(pdata); |
|---|
| 2426 | | - |
|---|
| 2427 | | - return; |
|---|
| 2428 | | - } |
|---|
| 2429 | | -} |
|---|
| 2430 | | - |
|---|
| 2431 | | -static void xgbe_udp_tunnel_del(struct net_device *netdev, |
|---|
| 2432 | | - struct udp_tunnel_info *ti) |
|---|
| 2433 | | -{ |
|---|
| 2434 | | - struct xgbe_prv_data *pdata = netdev_priv(netdev); |
|---|
| 2435 | | - struct xgbe_vxlan_data *vdata; |
|---|
| 2436 | | - |
|---|
| 2437 | | - if (!pdata->hw_feat.vxn) |
|---|
| 2438 | | - return; |
|---|
| 2439 | | - |
|---|
| 2440 | | - if (ti->type != UDP_TUNNEL_TYPE_VXLAN) |
|---|
| 2441 | | - return; |
|---|
| 2442 | | - |
|---|
| 2443 | | - netif_dbg(pdata, drv, netdev, |
|---|
| 2444 | | - "deleting VXLAN tunnel, family=%hx/port=%hx\n", |
|---|
| 2445 | | - ti->sa_family, be16_to_cpu(ti->port)); |
|---|
| 2446 | | - |
|---|
| 2447 | | - /* Don't need safe version since loop terminates with deletion */ |
|---|
| 2448 | | - list_for_each_entry(vdata, &pdata->vxlan_ports, list) { |
|---|
| 2449 | | - if (vdata->sa_family != ti->sa_family) |
|---|
| 2450 | | - continue; |
|---|
| 2451 | | - |
|---|
| 2452 | | - if (vdata->port != ti->port) |
|---|
| 2453 | | - continue; |
|---|
| 2454 | | - |
|---|
| 2455 | | - list_del(&vdata->list); |
|---|
| 2456 | | - kfree(vdata); |
|---|
| 2457 | | - |
|---|
| 2458 | | - break; |
|---|
| 2459 | | - } |
|---|
| 2460 | | - |
|---|
| 2461 | | - pdata->vxlan_port_count--; |
|---|
| 2462 | | - if (!pdata->vxlan_port_count) { |
|---|
| 2463 | | - xgbe_reset_vxlan_accel(pdata); |
|---|
| 2464 | | - |
|---|
| 2465 | | - return; |
|---|
| 2466 | | - } |
|---|
| 2467 | | - |
|---|
| 2468 | | - if (pdata->vxlan_force_disable) |
|---|
| 2469 | | - return; |
|---|
| 2470 | | - |
|---|
| 2471 | | - /* See if VXLAN tunnel id needs to be changed */ |
|---|
| 2472 | | - vdata = list_first_entry(&pdata->vxlan_ports, |
|---|
| 2473 | | - struct xgbe_vxlan_data, list); |
|---|
| 2474 | | - if (pdata->vxlan_port == be16_to_cpu(vdata->port)) |
|---|
| 2475 | | - return; |
|---|
| 2476 | | - |
|---|
| 2477 | | - pdata->vxlan_port = be16_to_cpu(vdata->port); |
|---|
| 2478 | | - pdata->hw_if.set_vxlan_id(pdata); |
|---|
| 2479 | 2273 | } |
|---|
| 2480 | 2274 | |
|---|
| 2481 | 2275 | static netdev_features_t xgbe_features_check(struct sk_buff *skb, |
|---|
| .. | .. |
|---|
| 2507 | 2301 | .ndo_setup_tc = xgbe_setup_tc, |
|---|
| 2508 | 2302 | .ndo_fix_features = xgbe_fix_features, |
|---|
| 2509 | 2303 | .ndo_set_features = xgbe_set_features, |
|---|
| 2510 | | - .ndo_udp_tunnel_add = xgbe_udp_tunnel_add, |
|---|
| 2511 | | - .ndo_udp_tunnel_del = xgbe_udp_tunnel_del, |
|---|
| 2304 | + .ndo_udp_tunnel_add = udp_tunnel_nic_add_port, |
|---|
| 2305 | + .ndo_udp_tunnel_del = udp_tunnel_nic_del_port, |
|---|
| 2512 | 2306 | .ndo_features_check = xgbe_features_check, |
|---|
| 2513 | 2307 | }; |
|---|
| 2514 | 2308 | |
|---|