diff options
| author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2016-04-07 14:39:44 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-04-08 15:26:05 -0400 |
| commit | aba52df80b1a2d15fe1745dfe187e9823821f5c0 (patch) | |
| tree | 59a66a79d6a0190f43db0034c5feb83b3763d47e /drivers/net/ethernet | |
| parent | 1cd0cfc498f7e928c5ff8e9ced537d41fa46df50 (diff) | |
nfp: sync ring state during FW reconfiguration
FW reconfiguration in .ndo_open()/.ndo_stop() should reset/
restore queue state. Since we need IRQs to be disabled when
filling rings on RX path we have to move disable_irq() from
.ndo_open() all the way up to IRQ allocation.
nfp_net_start_vec() becomes trivial now so it's inlined.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
| -rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 45 |
1 files changed, 16 insertions, 29 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 6c1ed8914416..ed23b9d348c3 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c | |||
| @@ -1519,6 +1519,7 @@ nfp_net_prepare_vector(struct nfp_net *nn, struct nfp_net_r_vector *r_vec, | |||
| 1519 | nn_err(nn, "Error requesting IRQ %d\n", entry->vector); | 1519 | nn_err(nn, "Error requesting IRQ %d\n", entry->vector); |
| 1520 | return err; | 1520 | return err; |
| 1521 | } | 1521 | } |
| 1522 | disable_irq(entry->vector); | ||
| 1522 | 1523 | ||
| 1523 | /* Setup NAPI */ | 1524 | /* Setup NAPI */ |
| 1524 | netif_napi_add(nn->netdev, &r_vec->napi, | 1525 | netif_napi_add(nn->netdev, &r_vec->napi, |
| @@ -1647,13 +1648,14 @@ static void nfp_net_clear_config_and_disable(struct nfp_net *nn) | |||
| 1647 | 1648 | ||
| 1648 | nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl); | 1649 | nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl); |
| 1649 | err = nfp_net_reconfig(nn, update); | 1650 | err = nfp_net_reconfig(nn, update); |
| 1650 | if (err) { | 1651 | if (err) |
| 1651 | nn_err(nn, "Could not disable device: %d\n", err); | 1652 | nn_err(nn, "Could not disable device: %d\n", err); |
| 1652 | return; | ||
| 1653 | } | ||
| 1654 | 1653 | ||
| 1655 | for (r = 0; r < nn->num_r_vecs; r++) | 1654 | for (r = 0; r < nn->num_r_vecs; r++) { |
| 1655 | nfp_net_rx_ring_reset(nn->r_vecs[r].rx_ring); | ||
| 1656 | nfp_net_tx_ring_reset(nn, nn->r_vecs[r].tx_ring); | ||
| 1656 | nfp_net_vec_clear_ring_data(nn, r); | 1657 | nfp_net_vec_clear_ring_data(nn, r); |
| 1658 | } | ||
| 1657 | 1659 | ||
| 1658 | nn->ctrl = new_ctrl; | 1660 | nn->ctrl = new_ctrl; |
| 1659 | } | 1661 | } |
| @@ -1721,6 +1723,9 @@ static int __nfp_net_set_config_and_enable(struct nfp_net *nn) | |||
| 1721 | 1723 | ||
| 1722 | nn->ctrl = new_ctrl; | 1724 | nn->ctrl = new_ctrl; |
| 1723 | 1725 | ||
| 1726 | for (r = 0; r < nn->num_r_vecs; r++) | ||
| 1727 | nfp_net_rx_ring_fill_freelist(nn->r_vecs[r].rx_ring); | ||
| 1728 | |||
| 1724 | /* Since reconfiguration requests while NFP is down are ignored we | 1729 | /* Since reconfiguration requests while NFP is down are ignored we |
| 1725 | * have to wipe the entire VXLAN configuration and reinitialize it. | 1730 | * have to wipe the entire VXLAN configuration and reinitialize it. |
| 1726 | */ | 1731 | */ |
| @@ -1749,26 +1754,6 @@ static int nfp_net_set_config_and_enable(struct nfp_net *nn) | |||
| 1749 | } | 1754 | } |
| 1750 | 1755 | ||
| 1751 | /** | 1756 | /** |
| 1752 | * nfp_net_start_vec() - Start ring vector | ||
| 1753 | * @nn: NFP Net device structure | ||
| 1754 | * @r_vec: Ring vector to be started | ||
| 1755 | */ | ||
| 1756 | static void | ||
| 1757 | nfp_net_start_vec(struct nfp_net *nn, struct nfp_net_r_vector *r_vec) | ||
| 1758 | { | ||
| 1759 | unsigned int irq_vec; | ||
| 1760 | |||
| 1761 | irq_vec = nn->irq_entries[r_vec->irq_idx].vector; | ||
| 1762 | |||
| 1763 | disable_irq(irq_vec); | ||
| 1764 | |||
| 1765 | nfp_net_rx_ring_fill_freelist(r_vec->rx_ring); | ||
| 1766 | napi_enable(&r_vec->napi); | ||
| 1767 | |||
| 1768 | enable_irq(irq_vec); | ||
| 1769 | } | ||
| 1770 | |||
| 1771 | /** | ||
| 1772 | * nfp_net_open_stack() - Start the device from stack's perspective | 1757 | * nfp_net_open_stack() - Start the device from stack's perspective |
| 1773 | * @nn: NFP Net device to reconfigure | 1758 | * @nn: NFP Net device to reconfigure |
| 1774 | */ | 1759 | */ |
| @@ -1776,8 +1761,10 @@ static void nfp_net_open_stack(struct nfp_net *nn) | |||
| 1776 | { | 1761 | { |
| 1777 | unsigned int r; | 1762 | unsigned int r; |
| 1778 | 1763 | ||
| 1779 | for (r = 0; r < nn->num_r_vecs; r++) | 1764 | for (r = 0; r < nn->num_r_vecs; r++) { |
| 1780 | nfp_net_start_vec(nn, &nn->r_vecs[r]); | 1765 | napi_enable(&nn->r_vecs[r].napi); |
| 1766 | enable_irq(nn->irq_entries[nn->r_vecs[r].irq_idx].vector); | ||
| 1767 | } | ||
| 1781 | 1768 | ||
| 1782 | netif_tx_wake_all_queues(nn->netdev); | 1769 | netif_tx_wake_all_queues(nn->netdev); |
| 1783 | 1770 | ||
| @@ -1902,8 +1889,10 @@ static void nfp_net_close_stack(struct nfp_net *nn) | |||
| 1902 | netif_carrier_off(nn->netdev); | 1889 | netif_carrier_off(nn->netdev); |
| 1903 | nn->link_up = false; | 1890 | nn->link_up = false; |
| 1904 | 1891 | ||
| 1905 | for (r = 0; r < nn->num_r_vecs; r++) | 1892 | for (r = 0; r < nn->num_r_vecs; r++) { |
| 1893 | disable_irq(nn->irq_entries[nn->r_vecs[r].irq_idx].vector); | ||
| 1906 | napi_disable(&nn->r_vecs[r].napi); | 1894 | napi_disable(&nn->r_vecs[r].napi); |
| 1895 | } | ||
| 1907 | 1896 | ||
| 1908 | netif_tx_disable(nn->netdev); | 1897 | netif_tx_disable(nn->netdev); |
| 1909 | } | 1898 | } |
| @@ -1917,9 +1906,7 @@ static void nfp_net_close_free_all(struct nfp_net *nn) | |||
| 1917 | unsigned int r; | 1906 | unsigned int r; |
| 1918 | 1907 | ||
| 1919 | for (r = 0; r < nn->num_r_vecs; r++) { | 1908 | for (r = 0; r < nn->num_r_vecs; r++) { |
| 1920 | nfp_net_rx_ring_reset(nn->r_vecs[r].rx_ring); | ||
| 1921 | nfp_net_rx_ring_bufs_free(nn, nn->r_vecs[r].rx_ring); | 1909 | nfp_net_rx_ring_bufs_free(nn, nn->r_vecs[r].rx_ring); |
| 1922 | nfp_net_tx_ring_reset(nn, nn->r_vecs[r].tx_ring); | ||
| 1923 | nfp_net_rx_ring_free(nn->r_vecs[r].rx_ring); | 1910 | nfp_net_rx_ring_free(nn->r_vecs[r].rx_ring); |
| 1924 | nfp_net_tx_ring_free(nn->r_vecs[r].tx_ring); | 1911 | nfp_net_tx_ring_free(nn->r_vecs[r].tx_ring); |
| 1925 | nfp_net_cleanup_vector(nn, &nn->r_vecs[r]); | 1912 | nfp_net_cleanup_vector(nn, &nn->r_vecs[r]); |
