diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2016-04-07 14:39:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-08 15:26:05 -0400 |
commit | 114bdef0be28aa9aa71e291d133e79edd514f8dc (patch) | |
tree | 5ea9bd1da9787d8fbac4c5d1c94843964844a05a | |
parent | 1934680f5582b69a708181741cd77473a0d530ed (diff) |
nfp: preallocate RX buffers early in .ndo_open
We want the .ndo_open() to have following structure:
- allocate resources;
- configure HW/FW;
- enable the device from stack perspective.
Therefore filling RX rings needs to be moved to the beginning
of .ndo_open().
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 34 |
1 files changed, 11 insertions, 23 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 0c3c37ad28a4..a6a917fe8e31 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c | |||
@@ -1666,28 +1666,19 @@ static void nfp_net_clear_config_and_disable(struct nfp_net *nn) | |||
1666 | * @nn: NFP Net device structure | 1666 | * @nn: NFP Net device structure |
1667 | * @r_vec: Ring vector to be started | 1667 | * @r_vec: Ring vector to be started |
1668 | */ | 1668 | */ |
1669 | static int nfp_net_start_vec(struct nfp_net *nn, struct nfp_net_r_vector *r_vec) | 1669 | static void |
1670 | nfp_net_start_vec(struct nfp_net *nn, struct nfp_net_r_vector *r_vec) | ||
1670 | { | 1671 | { |
1671 | unsigned int irq_vec; | 1672 | unsigned int irq_vec; |
1672 | int err = 0; | ||
1673 | 1673 | ||
1674 | irq_vec = nn->irq_entries[r_vec->irq_idx].vector; | 1674 | irq_vec = nn->irq_entries[r_vec->irq_idx].vector; |
1675 | 1675 | ||
1676 | disable_irq(irq_vec); | 1676 | disable_irq(irq_vec); |
1677 | 1677 | ||
1678 | err = nfp_net_rx_ring_bufs_alloc(r_vec->nfp_net, r_vec->rx_ring); | ||
1679 | if (err) { | ||
1680 | nn_err(nn, "RV%02d: couldn't allocate enough buffers\n", | ||
1681 | r_vec->irq_idx); | ||
1682 | goto out; | ||
1683 | } | ||
1684 | nfp_net_rx_ring_fill_freelist(r_vec->rx_ring); | 1678 | nfp_net_rx_ring_fill_freelist(r_vec->rx_ring); |
1685 | |||
1686 | napi_enable(&r_vec->napi); | 1679 | napi_enable(&r_vec->napi); |
1687 | out: | ||
1688 | enable_irq(irq_vec); | ||
1689 | 1680 | ||
1690 | return err; | 1681 | enable_irq(irq_vec); |
1691 | } | 1682 | } |
1692 | 1683 | ||
1693 | static int nfp_net_netdev_open(struct net_device *netdev) | 1684 | static int nfp_net_netdev_open(struct net_device *netdev) |
@@ -1742,6 +1733,10 @@ static int nfp_net_netdev_open(struct net_device *netdev) | |||
1742 | err = nfp_net_rx_ring_alloc(nn->r_vecs[r].rx_ring); | 1733 | err = nfp_net_rx_ring_alloc(nn->r_vecs[r].rx_ring); |
1743 | if (err) | 1734 | if (err) |
1744 | goto err_free_tx_ring_p; | 1735 | goto err_free_tx_ring_p; |
1736 | |||
1737 | err = nfp_net_rx_ring_bufs_alloc(nn, nn->r_vecs[r].rx_ring); | ||
1738 | if (err) | ||
1739 | goto err_flush_rx_ring_p; | ||
1745 | } | 1740 | } |
1746 | 1741 | ||
1747 | err = netif_set_real_num_tx_queues(netdev, nn->num_tx_rings); | 1742 | err = netif_set_real_num_tx_queues(netdev, nn->num_tx_rings); |
@@ -1814,11 +1809,8 @@ static int nfp_net_netdev_open(struct net_device *netdev) | |||
1814 | * - enable all TX queues | 1809 | * - enable all TX queues |
1815 | * - set link state | 1810 | * - set link state |
1816 | */ | 1811 | */ |
1817 | for (r = 0; r < nn->num_r_vecs; r++) { | 1812 | for (r = 0; r < nn->num_r_vecs; r++) |
1818 | err = nfp_net_start_vec(nn, &nn->r_vecs[r]); | 1813 | nfp_net_start_vec(nn, &nn->r_vecs[r]); |
1819 | if (err) | ||
1820 | goto err_disable_napi; | ||
1821 | } | ||
1822 | 1814 | ||
1823 | netif_tx_wake_all_queues(netdev); | 1815 | netif_tx_wake_all_queues(netdev); |
1824 | 1816 | ||
@@ -1827,18 +1819,14 @@ static int nfp_net_netdev_open(struct net_device *netdev) | |||
1827 | 1819 | ||
1828 | return 0; | 1820 | return 0; |
1829 | 1821 | ||
1830 | err_disable_napi: | ||
1831 | while (r--) { | ||
1832 | napi_disable(&nn->r_vecs[r].napi); | ||
1833 | nfp_net_rx_ring_reset(nn->r_vecs[r].rx_ring); | ||
1834 | nfp_net_rx_ring_bufs_free(nn, nn->r_vecs[r].rx_ring); | ||
1835 | } | ||
1836 | err_clear_config: | 1822 | err_clear_config: |
1837 | nfp_net_clear_config_and_disable(nn); | 1823 | nfp_net_clear_config_and_disable(nn); |
1838 | err_free_rings: | 1824 | err_free_rings: |
1839 | r = nn->num_r_vecs; | 1825 | r = nn->num_r_vecs; |
1840 | err_free_prev_vecs: | 1826 | err_free_prev_vecs: |
1841 | while (r--) { | 1827 | while (r--) { |
1828 | nfp_net_rx_ring_bufs_free(nn, nn->r_vecs[r].rx_ring); | ||
1829 | err_flush_rx_ring_p: | ||
1842 | nfp_net_rx_ring_free(nn->r_vecs[r].rx_ring); | 1830 | nfp_net_rx_ring_free(nn->r_vecs[r].rx_ring); |
1843 | err_free_tx_ring_p: | 1831 | err_free_tx_ring_p: |
1844 | nfp_net_tx_ring_free(nn->r_vecs[r].tx_ring); | 1832 | nfp_net_tx_ring_free(nn->r_vecs[r].tx_ring); |