fm10k: convert to new udp_tunnel_nic infra
authorJakub Kicinski <kuba@kernel.org>
Tue, 14 Jul 2020 19:18:28 +0000 (12:18 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 15 Jul 2020 00:04:27 +0000 (17:04 -0700)
Straightforward conversion to new infra. Driver restores info
after close/open cycle by calling its internal restore function
so just use that, no need for udp_tunnel_nic_reset_ntf() here.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/fm10k/fm10k.h
drivers/net/ethernet/intel/fm10k/fm10k_main.c
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/intel/fm10k/fm10k_pci.c

index f9be10a04dd6cc75197fd137161aaded00724151..6119a410883815ff3d1ff74302a7f2d85e6a7b24 100644 (file)
@@ -221,12 +221,6 @@ struct fm10k_iov_data {
        struct fm10k_vf_info    vf_info[];
 };
 
-struct fm10k_udp_port {
-       struct list_head        list;
-       sa_family_t             sa_family;
-       __be16                  port;
-};
-
 enum fm10k_macvlan_request_type {
        FM10K_UC_MAC_REQUEST,
        FM10K_MC_MAC_REQUEST,
@@ -370,8 +364,8 @@ struct fm10k_intfc {
        u32 rssrk[FM10K_RSSRK_SIZE];
 
        /* UDP encapsulation port tracking information */
-       struct list_head vxlan_port;
-       struct list_head geneve_port;
+       __be16 vxlan_port;
+       __be16 geneve_port;
 
        /* MAC/VLAN update queue */
        struct list_head macvlan_requests;
index 34f1f5350f68cfb73cfb3dd136e85474892555cc..d88dd41a94422b38a6914be96ca264f5ffc27b3b 100644 (file)
@@ -635,15 +635,8 @@ static int fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
 static struct ethhdr *fm10k_port_is_vxlan(struct sk_buff *skb)
 {
        struct fm10k_intfc *interface = netdev_priv(skb->dev);
-       struct fm10k_udp_port *vxlan_port;
 
-       /* we can only offload a vxlan if we recognize it as such */
-       vxlan_port = list_first_entry_or_null(&interface->vxlan_port,
-                                             struct fm10k_udp_port, list);
-
-       if (!vxlan_port)
-               return NULL;
-       if (vxlan_port->port != udp_hdr(skb)->dest)
+       if (interface->vxlan_port != udp_hdr(skb)->dest)
                return NULL;
 
        /* return offset of udp_hdr plus 8 bytes for VXLAN header */
index 1450a9f98c5a6964452cd7325b17089384fa916d..5c19ff4525587e2d76a0b168e210ac9a75587c05 100644 (file)
@@ -366,39 +366,6 @@ static void fm10k_request_glort_range(struct fm10k_intfc *interface)
        }
 }
 
-/**
- * fm10k_free_udp_port_info
- * @interface: board private structure
- *
- * This function frees both geneve_port and vxlan_port structures
- **/
-static void fm10k_free_udp_port_info(struct fm10k_intfc *interface)
-{
-       struct fm10k_udp_port *port;
-
-       /* flush all entries from vxlan list */
-       port = list_first_entry_or_null(&interface->vxlan_port,
-                                       struct fm10k_udp_port, list);
-       while (port) {
-               list_del(&port->list);
-               kfree(port);
-               port = list_first_entry_or_null(&interface->vxlan_port,
-                                               struct fm10k_udp_port,
-                                               list);
-       }
-
-       /* flush all entries from geneve list */
-       port = list_first_entry_or_null(&interface->geneve_port,
-                                       struct fm10k_udp_port, list);
-       while (port) {
-               list_del(&port->list);
-               kfree(port);
-               port = list_first_entry_or_null(&interface->vxlan_port,
-                                               struct fm10k_udp_port,
-                                               list);
-       }
-}
-
 /**
  * fm10k_restore_udp_port_info
  * @interface: board private structure
@@ -408,131 +375,52 @@ static void fm10k_free_udp_port_info(struct fm10k_intfc *interface)
 static void fm10k_restore_udp_port_info(struct fm10k_intfc *interface)
 {
        struct fm10k_hw *hw = &interface->hw;
-       struct fm10k_udp_port *port;
 
        /* only the PF supports configuring tunnels */
        if (hw->mac.type != fm10k_mac_pf)
                return;
 
-       port = list_first_entry_or_null(&interface->vxlan_port,
-                                       struct fm10k_udp_port, list);
-
        /* restore tunnel configuration register */
        fm10k_write_reg(hw, FM10K_TUNNEL_CFG,
-                       (port ? ntohs(port->port) : 0) |
+                       ntohs(interface->vxlan_port) |
                        (ETH_P_TEB << FM10K_TUNNEL_CFG_NVGRE_SHIFT));
 
-       port = list_first_entry_or_null(&interface->geneve_port,
-                                       struct fm10k_udp_port, list);
-
        /* restore Geneve tunnel configuration register */
        fm10k_write_reg(hw, FM10K_TUNNEL_CFG_GENEVE,
-                       (port ? ntohs(port->port) : 0));
-}
-
-static struct fm10k_udp_port *
-fm10k_remove_tunnel_port(struct list_head *ports,
-                        struct udp_tunnel_info *ti)
-{
-       struct fm10k_udp_port *port;
-
-       list_for_each_entry(port, ports, list) {
-               if ((port->port == ti->port) &&
-                   (port->sa_family == ti->sa_family)) {
-                       list_del(&port->list);
-                       return port;
-               }
-       }
-
-       return NULL;
-}
-
-static void fm10k_insert_tunnel_port(struct list_head *ports,
-                                    struct udp_tunnel_info *ti)
-{
-       struct fm10k_udp_port *port;
-
-       /* remove existing port entry from the list so that the newest items
-        * are always at the tail of the list.
-        */
-       port = fm10k_remove_tunnel_port(ports, ti);
-       if (!port) {
-               port = kmalloc(sizeof(*port), GFP_ATOMIC);
-               if  (!port)
-                       return;
-               port->port = ti->port;
-               port->sa_family = ti->sa_family;
-       }
-
-       list_add_tail(&port->list, ports);
+                       ntohs(interface->geneve_port));
 }
 
 /**
- * fm10k_udp_tunnel_add
+ * fm10k_udp_tunnel_sync - Called when UDP tunnel ports change
  * @dev: network interface device structure
- * @ti: Tunnel endpoint information
+ * @table: Tunnel table (according to tables of @fm10k_udp_tunnels)
  *
- * This function is called when a new UDP tunnel port has been added.
+ * This function is called when a new UDP tunnel port is added or deleted.
  * Due to hardware restrictions, only one port per type can be offloaded at
- * once.
+ * once. Core will send to the driver a port of its choice.
  **/
-static void fm10k_udp_tunnel_add(struct net_device *dev,
-                                struct udp_tunnel_info *ti)
+static int fm10k_udp_tunnel_sync(struct net_device *dev, unsigned int table)
 {
        struct fm10k_intfc *interface = netdev_priv(dev);
+       struct udp_tunnel_info ti;
 
-       /* only the PF supports configuring tunnels */
-       if (interface->hw.mac.type != fm10k_mac_pf)
-               return;
-
-       switch (ti->type) {
-       case UDP_TUNNEL_TYPE_VXLAN:
-               fm10k_insert_tunnel_port(&interface->vxlan_port, ti);
-               break;
-       case UDP_TUNNEL_TYPE_GENEVE:
-               fm10k_insert_tunnel_port(&interface->geneve_port, ti);
-               break;
-       default:
-               return;
-       }
+       udp_tunnel_nic_get_port(dev, table, 0, &ti);
+       if (!table)
+               interface->vxlan_port = ti.port;
+       else
+               interface->geneve_port = ti.port;
 
        fm10k_restore_udp_port_info(interface);
+       return 0;
 }
 
-/**
- * fm10k_udp_tunnel_del
- * @dev: network interface device structure
- * @ti: Tunnel end point information
- *
- * This function is called when a new UDP tunnel port is deleted. The freed
- * port will be removed from the list, then we reprogram the offloaded port
- * based on the head of the list.
- **/
-static void fm10k_udp_tunnel_del(struct net_device *dev,
-                                struct udp_tunnel_info *ti)
-{
-       struct fm10k_intfc *interface = netdev_priv(dev);
-       struct fm10k_udp_port *port = NULL;
-
-       if (interface->hw.mac.type != fm10k_mac_pf)
-               return;
-
-       switch (ti->type) {
-       case UDP_TUNNEL_TYPE_VXLAN:
-               port = fm10k_remove_tunnel_port(&interface->vxlan_port, ti);
-               break;
-       case UDP_TUNNEL_TYPE_GENEVE:
-               port = fm10k_remove_tunnel_port(&interface->geneve_port, ti);
-               break;
-       default:
-               return;
-       }
-
-       /* if we did remove a port we need to free its memory */
-       kfree(port);
-
-       fm10k_restore_udp_port_info(interface);
-}
+static const struct udp_tunnel_nic_info fm10k_udp_tunnels = {
+       .sync_table     = fm10k_udp_tunnel_sync,
+       .tables         = {
+               { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN,  },
+               { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+       },
+};
 
 /**
  * fm10k_open - Called when a network interface is made active
@@ -580,8 +468,6 @@ int fm10k_open(struct net_device *netdev)
        if (err)
                goto err_set_queues;
 
-       udp_tunnel_get_rx_info(netdev);
-
        fm10k_up(interface);
 
        return 0;
@@ -615,8 +501,6 @@ int fm10k_close(struct net_device *netdev)
 
        fm10k_qv_free_irq(interface);
 
-       fm10k_free_udp_port_info(interface);
-
        fm10k_free_all_tx_resources(interface);
        fm10k_free_all_rx_resources(interface);
 
@@ -1647,8 +1531,8 @@ static const struct net_device_ops fm10k_netdev_ops = {
        .ndo_set_vf_rate        = fm10k_ndo_set_vf_bw,
        .ndo_get_vf_config      = fm10k_ndo_get_vf_config,
        .ndo_get_vf_stats       = fm10k_ndo_get_vf_stats,
-       .ndo_udp_tunnel_add     = fm10k_udp_tunnel_add,
-       .ndo_udp_tunnel_del     = fm10k_udp_tunnel_del,
+       .ndo_udp_tunnel_add     = udp_tunnel_nic_add_port,
+       .ndo_udp_tunnel_del     = udp_tunnel_nic_del_port,
        .ndo_dfwd_add_station   = fm10k_dfwd_add_station,
        .ndo_dfwd_del_station   = fm10k_dfwd_del_station,
        .ndo_features_check     = fm10k_features_check,
@@ -1695,6 +1579,8 @@ struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info)
                                       NETIF_F_SG;
 
                dev->features |= NETIF_F_GSO_UDP_TUNNEL;
+
+               dev->udp_tunnel_nic_info = &fm10k_udp_tunnels;
        }
 
        /* all features defined to this point should be changeable */
index d122d0087191144ab26767f0a49e5edf4d7dd6d3..140212bfe08b854555b94e611f87b6349c7a2a29 100644 (file)
@@ -2066,10 +2066,6 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
        interface->tx_itr = FM10K_TX_ITR_DEFAULT;
        interface->rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
 
-       /* initialize udp port lists */
-       INIT_LIST_HEAD(&interface->vxlan_port);
-       INIT_LIST_HEAD(&interface->geneve_port);
-
        /* Initialize the MAC/VLAN queue */
        INIT_LIST_HEAD(&interface->macvlan_requests);