nfp: slice .ndo_open() and .ndo_stop() up
authorJakub Kicinski <jakub.kicinski@netronome.com>
Thu, 7 Apr 2016 18:39:43 +0000 (19:39 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Apr 2016 19:26:05 +0000 (15:26 -0400)
Divide .ndo_open() and .ndo_stop() into logical, callable
chunks.  No functional changes.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/nfp_net_common.c

index 342335d09fb296b5e7881d416ae09c11a82e85c5..6c1ed8914416911ddbf33cfee6768346a337adb6 100644 (file)
@@ -1672,6 +1672,82 @@ nfp_net_vec_write_ring_data(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,
        nn_writeb(nn, NFP_NET_CFG_TXR_VEC(idx), r_vec->irq_idx);
 }
 
+static int __nfp_net_set_config_and_enable(struct nfp_net *nn)
+{
+       u32 new_ctrl, update = 0;
+       unsigned int r;
+       int err;
+
+       new_ctrl = nn->ctrl;
+
+       if (nn->cap & NFP_NET_CFG_CTRL_RSS) {
+               nfp_net_rss_write_key(nn);
+               nfp_net_rss_write_itbl(nn);
+               nn_writel(nn, NFP_NET_CFG_RSS_CTRL, nn->rss_cfg);
+               update |= NFP_NET_CFG_UPDATE_RSS;
+       }
+
+       if (nn->cap & NFP_NET_CFG_CTRL_IRQMOD) {
+               nfp_net_coalesce_write_cfg(nn);
+
+               new_ctrl |= NFP_NET_CFG_CTRL_IRQMOD;
+               update |= NFP_NET_CFG_UPDATE_IRQMOD;
+       }
+
+       for (r = 0; r < nn->num_r_vecs; r++)
+               nfp_net_vec_write_ring_data(nn, &nn->r_vecs[r], r);
+
+       nn_writeq(nn, NFP_NET_CFG_TXRS_ENABLE, nn->num_tx_rings == 64 ?
+                 0xffffffffffffffffULL : ((u64)1 << nn->num_tx_rings) - 1);
+
+       nn_writeq(nn, NFP_NET_CFG_RXRS_ENABLE, nn->num_rx_rings == 64 ?
+                 0xffffffffffffffffULL : ((u64)1 << nn->num_rx_rings) - 1);
+
+       nfp_net_write_mac_addr(nn, nn->netdev->dev_addr);
+
+       nn_writel(nn, NFP_NET_CFG_MTU, nn->netdev->mtu);
+       nn_writel(nn, NFP_NET_CFG_FLBUFSZ, nn->fl_bufsz);
+
+       /* Enable device */
+       new_ctrl |= NFP_NET_CFG_CTRL_ENABLE;
+       update |= NFP_NET_CFG_UPDATE_GEN;
+       update |= NFP_NET_CFG_UPDATE_MSIX;
+       update |= NFP_NET_CFG_UPDATE_RING;
+       if (nn->cap & NFP_NET_CFG_CTRL_RINGCFG)
+               new_ctrl |= NFP_NET_CFG_CTRL_RINGCFG;
+
+       nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl);
+       err = nfp_net_reconfig(nn, update);
+
+       nn->ctrl = new_ctrl;
+
+       /* Since reconfiguration requests while NFP is down are ignored we
+        * have to wipe the entire VXLAN configuration and reinitialize it.
+        */
+       if (nn->ctrl & NFP_NET_CFG_CTRL_VXLAN) {
+               memset(&nn->vxlan_ports, 0, sizeof(nn->vxlan_ports));
+               memset(&nn->vxlan_usecnt, 0, sizeof(nn->vxlan_usecnt));
+               vxlan_get_rx_port(nn->netdev);
+       }
+
+       return err;
+}
+
+/**
+ * nfp_net_set_config_and_enable() - Write control BAR and enable NFP
+ * @nn:      NFP Net device to reconfigure
+ */
+static int nfp_net_set_config_and_enable(struct nfp_net *nn)
+{
+       int err;
+
+       err = __nfp_net_set_config_and_enable(nn);
+       if (err)
+               nfp_net_clear_config_and_disable(nn);
+
+       return err;
+}
+
 /**
  * nfp_net_start_vec() - Start ring vector
  * @nn:      NFP Net device structure
@@ -1692,20 +1768,33 @@ nfp_net_start_vec(struct nfp_net *nn, struct nfp_net_r_vector *r_vec)
        enable_irq(irq_vec);
 }
 
+/**
+ * nfp_net_open_stack() - Start the device from stack's perspective
+ * @nn:      NFP Net device to reconfigure
+ */
+static void nfp_net_open_stack(struct nfp_net *nn)
+{
+       unsigned int r;
+
+       for (r = 0; r < nn->num_r_vecs; r++)
+               nfp_net_start_vec(nn, &nn->r_vecs[r]);
+
+       netif_tx_wake_all_queues(nn->netdev);
+
+       enable_irq(nn->irq_entries[NFP_NET_CFG_LSC].vector);
+       nfp_net_read_link_status(nn);
+}
+
 static int nfp_net_netdev_open(struct net_device *netdev)
 {
        struct nfp_net *nn = netdev_priv(netdev);
        int err, r;
-       u32 update = 0;
-       u32 new_ctrl;
 
        if (nn->ctrl & NFP_NET_CFG_CTRL_ENABLE) {
                nn_err(nn, "Dev is already enabled: 0x%08x\n", nn->ctrl);
                return -EBUSY;
        }
 
-       new_ctrl = nn->ctrl;
-
        /* Step 1: Allocate resources for rings and the like
         * - Request interrupts
         * - Allocate RX and TX ring resources
@@ -1758,20 +1847,6 @@ static int nfp_net_netdev_open(struct net_device *netdev)
        if (err)
                goto err_free_rings;
 
-       if (nn->cap & NFP_NET_CFG_CTRL_RSS) {
-               nfp_net_rss_write_key(nn);
-               nfp_net_rss_write_itbl(nn);
-               nn_writel(nn, NFP_NET_CFG_RSS_CTRL, nn->rss_cfg);
-               update |= NFP_NET_CFG_UPDATE_RSS;
-       }
-
-       if (nn->cap & NFP_NET_CFG_CTRL_IRQMOD) {
-               nfp_net_coalesce_write_cfg(nn);
-
-               new_ctrl |= NFP_NET_CFG_CTRL_IRQMOD;
-               update |= NFP_NET_CFG_UPDATE_IRQMOD;
-       }
-
        /* Step 2: Configure the NFP
         * - Enable rings from 0 to tx_rings/rx_rings - 1.
         * - Write MAC address (in case it changed)
@@ -1779,43 +1854,9 @@ static int nfp_net_netdev_open(struct net_device *netdev)
         * - Set the Freelist buffer size
         * - Enable the FW
         */
-       for (r = 0; r < nn->num_r_vecs; r++)
-               nfp_net_vec_write_ring_data(nn, &nn->r_vecs[r], r);
-
-       nn_writeq(nn, NFP_NET_CFG_TXRS_ENABLE, nn->num_tx_rings == 64 ?
-                 0xffffffffffffffffULL : ((u64)1 << nn->num_tx_rings) - 1);
-
-       nn_writeq(nn, NFP_NET_CFG_RXRS_ENABLE, nn->num_rx_rings == 64 ?
-                 0xffffffffffffffffULL : ((u64)1 << nn->num_rx_rings) - 1);
-
-       nfp_net_write_mac_addr(nn, netdev->dev_addr);
-
-       nn_writel(nn, NFP_NET_CFG_MTU, netdev->mtu);
-       nn_writel(nn, NFP_NET_CFG_FLBUFSZ, nn->fl_bufsz);
-
-       /* Enable device */
-       new_ctrl |= NFP_NET_CFG_CTRL_ENABLE;
-       update |= NFP_NET_CFG_UPDATE_GEN;
-       update |= NFP_NET_CFG_UPDATE_MSIX;
-       update |= NFP_NET_CFG_UPDATE_RING;
-       if (nn->cap & NFP_NET_CFG_CTRL_RINGCFG)
-               new_ctrl |= NFP_NET_CFG_CTRL_RINGCFG;
-
-       nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl);
-       err = nfp_net_reconfig(nn, update);
+       err = nfp_net_set_config_and_enable(nn);
        if (err)
-               goto err_clear_config;
-
-       nn->ctrl = new_ctrl;
-
-       /* Since reconfiguration requests while NFP is down are ignored we
-        * have to wipe the entire VXLAN configuration and reinitialize it.
-        */
-       if (nn->ctrl & NFP_NET_CFG_CTRL_VXLAN) {
-               memset(&nn->vxlan_ports, 0, sizeof(nn->vxlan_ports));
-               memset(&nn->vxlan_usecnt, 0, sizeof(nn->vxlan_usecnt));
-               vxlan_get_rx_port(netdev);
-       }
+               goto err_free_rings;
 
        /* Step 3: Enable for kernel
         * - put some freelist descriptors on each RX ring
@@ -1823,18 +1864,10 @@ static int nfp_net_netdev_open(struct net_device *netdev)
         * - enable all TX queues
         * - set link state
         */
-       for (r = 0; r < nn->num_r_vecs; r++)
-               nfp_net_start_vec(nn, &nn->r_vecs[r]);
-
-       netif_tx_wake_all_queues(netdev);
-
-       enable_irq(nn->irq_entries[NFP_NET_CFG_LSC].vector);
-       nfp_net_read_link_status(nn);
+       nfp_net_open_stack(nn);
 
        return 0;
 
-err_clear_config:
-       nfp_net_clear_config_and_disable(nn);
 err_free_rings:
        r = nn->num_r_vecs;
 err_free_prev_vecs:
@@ -1858,36 +1891,31 @@ err_free_exn:
 }
 
 /**
- * nfp_net_netdev_close() - Called when the device is downed
- * @netdev:      netdev structure
+ * nfp_net_close_stack() - Quiescent the stack (part of close)
+ * @nn:             NFP Net device to reconfigure
  */
-static int nfp_net_netdev_close(struct net_device *netdev)
+static void nfp_net_close_stack(struct nfp_net *nn)
 {
-       struct nfp_net *nn = netdev_priv(netdev);
-       int r;
-
-       if (!(nn->ctrl & NFP_NET_CFG_CTRL_ENABLE)) {
-               nn_err(nn, "Dev is not up: 0x%08x\n", nn->ctrl);
-               return 0;
-       }
+       unsigned int r;
 
-       /* Step 1: Disable RX and TX rings from the Linux kernel perspective
-        */
        disable_irq(nn->irq_entries[NFP_NET_CFG_LSC].vector);
-       netif_carrier_off(netdev);
+       netif_carrier_off(nn->netdev);
        nn->link_up = false;
 
        for (r = 0; r < nn->num_r_vecs; r++)
                napi_disable(&nn->r_vecs[r].napi);
 
-       netif_tx_disable(netdev);
+       netif_tx_disable(nn->netdev);
+}
 
-       /* Step 2: Tell NFP
-        */
-       nfp_net_clear_config_and_disable(nn);
+/**
+ * nfp_net_close_free_all() - Free all runtime resources
+ * @nn:      NFP Net device to reconfigure
+ */
+static void nfp_net_close_free_all(struct nfp_net *nn)
+{
+       unsigned int r;
 
-       /* Step 3: Free resources
-        */
        for (r = 0; r < nn->num_r_vecs; r++) {
                nfp_net_rx_ring_reset(nn->r_vecs[r].rx_ring);
                nfp_net_rx_ring_bufs_free(nn, nn->r_vecs[r].rx_ring);
@@ -1902,6 +1930,32 @@ static int nfp_net_netdev_close(struct net_device *netdev)
 
        nfp_net_aux_irq_free(nn, NFP_NET_CFG_LSC, NFP_NET_IRQ_LSC_IDX);
        nfp_net_aux_irq_free(nn, NFP_NET_CFG_EXN, NFP_NET_IRQ_EXN_IDX);
+}
+
+/**
+ * nfp_net_netdev_close() - Called when the device is downed
+ * @netdev:      netdev structure
+ */
+static int nfp_net_netdev_close(struct net_device *netdev)
+{
+       struct nfp_net *nn = netdev_priv(netdev);
+
+       if (!(nn->ctrl & NFP_NET_CFG_CTRL_ENABLE)) {
+               nn_err(nn, "Dev is not up: 0x%08x\n", nn->ctrl);
+               return 0;
+       }
+
+       /* Step 1: Disable RX and TX rings from the Linux kernel perspective
+        */
+       nfp_net_close_stack(nn);
+
+       /* Step 2: Tell NFP
+        */
+       nfp_net_clear_config_and_disable(nn);
+
+       /* Step 3: Free resources
+        */
+       nfp_net_close_free_all(nn);
 
        nn_dbg(nn, "%s down", netdev->name);
        return 0;