.. | .. |
---|
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 | |
---|