diff options
| author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2016-04-07 14:39:43 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-04-08 15:26:05 -0400 |
| commit | 1cd0cfc498f7e928c5ff8e9ced537d41fa46df50 (patch) | |
| tree | 77c391a831a1db1773727719cc342a90c25a70f4 /drivers | |
| parent | ca40feab8f3d46a69bde7a13d652db2c9246c067 (diff) | |
nfp: slice .ndo_open() and .ndo_stop() up
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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 218 |
1 files changed, 136 insertions, 82 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 342335d09fb2..6c1ed8914416 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c | |||
| @@ -1672,6 +1672,82 @@ nfp_net_vec_write_ring_data(struct nfp_net *nn, struct nfp_net_r_vector *r_vec, | |||
| 1672 | nn_writeb(nn, NFP_NET_CFG_TXR_VEC(idx), r_vec->irq_idx); | 1672 | nn_writeb(nn, NFP_NET_CFG_TXR_VEC(idx), r_vec->irq_idx); |
| 1673 | } | 1673 | } |
| 1674 | 1674 | ||
| 1675 | static int __nfp_net_set_config_and_enable(struct nfp_net *nn) | ||
| 1676 | { | ||
| 1677 | u32 new_ctrl, update = 0; | ||
| 1678 | unsigned int r; | ||
| 1679 | int err; | ||
| 1680 | |||
| 1681 | new_ctrl = nn->ctrl; | ||
| 1682 | |||
| 1683 | if (nn->cap & NFP_NET_CFG_CTRL_RSS) { | ||
| 1684 | nfp_net_rss_write_key(nn); | ||
| 1685 | nfp_net_rss_write_itbl(nn); | ||
| 1686 | nn_writel(nn, NFP_NET_CFG_RSS_CTRL, nn->rss_cfg); | ||
| 1687 | update |= NFP_NET_CFG_UPDATE_RSS; | ||
| 1688 | } | ||
| 1689 | |||
| 1690 | if (nn->cap & NFP_NET_CFG_CTRL_IRQMOD) { | ||
| 1691 | nfp_net_coalesce_write_cfg(nn); | ||
| 1692 | |||
| 1693 | new_ctrl |= NFP_NET_CFG_CTRL_IRQMOD; | ||
| 1694 | update |= NFP_NET_CFG_UPDATE_IRQMOD; | ||
| 1695 | } | ||
| 1696 | |||
| 1697 | for (r = 0; r < nn->num_r_vecs; r++) | ||
| 1698 | nfp_net_vec_write_ring_data(nn, &nn->r_vecs[r], r); | ||
| 1699 | |||
| 1700 | nn_writeq(nn, NFP_NET_CFG_TXRS_ENABLE, nn->num_tx_rings == 64 ? | ||
| 1701 | 0xffffffffffffffffULL : ((u64)1 << nn->num_tx_rings) - 1); | ||
| 1702 | |||
| 1703 | nn_writeq(nn, NFP_NET_CFG_RXRS_ENABLE, nn->num_rx_rings == 64 ? | ||
| 1704 | 0xffffffffffffffffULL : ((u64)1 << nn->num_rx_rings) - 1); | ||
| 1705 | |||
| 1706 | nfp_net_write_mac_addr(nn, nn->netdev->dev_addr); | ||
| 1707 | |||
| 1708 | nn_writel(nn, NFP_NET_CFG_MTU, nn->netdev->mtu); | ||
| 1709 | nn_writel(nn, NFP_NET_CFG_FLBUFSZ, nn->fl_bufsz); | ||
| 1710 | |||
| 1711 | /* Enable device */ | ||
| 1712 | new_ctrl |= NFP_NET_CFG_CTRL_ENABLE; | ||
| 1713 | update |= NFP_NET_CFG_UPDATE_GEN; | ||
| 1714 | update |= NFP_NET_CFG_UPDATE_MSIX; | ||
| 1715 | update |= NFP_NET_CFG_UPDATE_RING; | ||
| 1716 | if (nn->cap & NFP_NET_CFG_CTRL_RINGCFG) | ||
| 1717 | new_ctrl |= NFP_NET_CFG_CTRL_RINGCFG; | ||
| 1718 | |||
| 1719 | nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl); | ||
| 1720 | err = nfp_net_reconfig(nn, update); | ||
| 1721 | |||
| 1722 | nn->ctrl = new_ctrl; | ||
| 1723 | |||
| 1724 | /* Since reconfiguration requests while NFP is down are ignored we | ||
| 1725 | * have to wipe the entire VXLAN configuration and reinitialize it. | ||
| 1726 | */ | ||
| 1727 | if (nn->ctrl & NFP_NET_CFG_CTRL_VXLAN) { | ||
| 1728 | memset(&nn->vxlan_ports, 0, sizeof(nn->vxlan_ports)); | ||
| 1729 | memset(&nn->vxlan_usecnt, 0, sizeof(nn->vxlan_usecnt)); | ||
| 1730 | vxlan_get_rx_port(nn->netdev); | ||
| 1731 | } | ||
| 1732 | |||
| 1733 | return err; | ||
| 1734 | } | ||
| 1735 | |||
| 1736 | /** | ||
| 1737 | * nfp_net_set_config_and_enable() - Write control BAR and enable NFP | ||
| 1738 | * @nn: NFP Net device to reconfigure | ||
| 1739 | */ | ||
| 1740 | static int nfp_net_set_config_and_enable(struct nfp_net *nn) | ||
| 1741 | { | ||
| 1742 | int err; | ||
| 1743 | |||
| 1744 | err = __nfp_net_set_config_and_enable(nn); | ||
| 1745 | if (err) | ||
| 1746 | nfp_net_clear_config_and_disable(nn); | ||
| 1747 | |||
| 1748 | return err; | ||
| 1749 | } | ||
| 1750 | |||
| 1675 | /** | 1751 | /** |
| 1676 | * nfp_net_start_vec() - Start ring vector | 1752 | * nfp_net_start_vec() - Start ring vector |
| 1677 | * @nn: NFP Net device structure | 1753 | * @nn: NFP Net device structure |
| @@ -1692,20 +1768,33 @@ nfp_net_start_vec(struct nfp_net *nn, struct nfp_net_r_vector *r_vec) | |||
| 1692 | enable_irq(irq_vec); | 1768 | enable_irq(irq_vec); |
| 1693 | } | 1769 | } |
| 1694 | 1770 | ||
| 1771 | /** | ||
| 1772 | * nfp_net_open_stack() - Start the device from stack's perspective | ||
| 1773 | * @nn: NFP Net device to reconfigure | ||
| 1774 | */ | ||
| 1775 | static void nfp_net_open_stack(struct nfp_net *nn) | ||
| 1776 | { | ||
| 1777 | unsigned int r; | ||
| 1778 | |||
| 1779 | for (r = 0; r < nn->num_r_vecs; r++) | ||
| 1780 | nfp_net_start_vec(nn, &nn->r_vecs[r]); | ||
| 1781 | |||
| 1782 | netif_tx_wake_all_queues(nn->netdev); | ||
| 1783 | |||
| 1784 | enable_irq(nn->irq_entries[NFP_NET_CFG_LSC].vector); | ||
| 1785 | nfp_net_read_link_status(nn); | ||
| 1786 | } | ||
| 1787 | |||
| 1695 | static int nfp_net_netdev_open(struct net_device *netdev) | 1788 | static int nfp_net_netdev_open(struct net_device *netdev) |
| 1696 | { | 1789 | { |
| 1697 | struct nfp_net *nn = netdev_priv(netdev); | 1790 | struct nfp_net *nn = netdev_priv(netdev); |
| 1698 | int err, r; | 1791 | int err, r; |
| 1699 | u32 update = 0; | ||
| 1700 | u32 new_ctrl; | ||
| 1701 | 1792 | ||
| 1702 | if (nn->ctrl & NFP_NET_CFG_CTRL_ENABLE) { | 1793 | if (nn->ctrl & NFP_NET_CFG_CTRL_ENABLE) { |
| 1703 | nn_err(nn, "Dev is already enabled: 0x%08x\n", nn->ctrl); | 1794 | nn_err(nn, "Dev is already enabled: 0x%08x\n", nn->ctrl); |
| 1704 | return -EBUSY; | 1795 | return -EBUSY; |
| 1705 | } | 1796 | } |
| 1706 | 1797 | ||
| 1707 | new_ctrl = nn->ctrl; | ||
| 1708 | |||
| 1709 | /* Step 1: Allocate resources for rings and the like | 1798 | /* Step 1: Allocate resources for rings and the like |
| 1710 | * - Request interrupts | 1799 | * - Request interrupts |
| 1711 | * - Allocate RX and TX ring resources | 1800 | * - Allocate RX and TX ring resources |
| @@ -1758,20 +1847,6 @@ static int nfp_net_netdev_open(struct net_device *netdev) | |||
| 1758 | if (err) | 1847 | if (err) |
| 1759 | goto err_free_rings; | 1848 | goto err_free_rings; |
| 1760 | 1849 | ||
| 1761 | if (nn->cap & NFP_NET_CFG_CTRL_RSS) { | ||
| 1762 | nfp_net_rss_write_key(nn); | ||
| 1763 | nfp_net_rss_write_itbl(nn); | ||
| 1764 | nn_writel(nn, NFP_NET_CFG_RSS_CTRL, nn->rss_cfg); | ||
| 1765 | update |= NFP_NET_CFG_UPDATE_RSS; | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | if (nn->cap & NFP_NET_CFG_CTRL_IRQMOD) { | ||
| 1769 | nfp_net_coalesce_write_cfg(nn); | ||
| 1770 | |||
| 1771 | new_ctrl |= NFP_NET_CFG_CTRL_IRQMOD; | ||
| 1772 | update |= NFP_NET_CFG_UPDATE_IRQMOD; | ||
| 1773 | } | ||
| 1774 | |||
| 1775 | /* Step 2: Configure the NFP | 1850 | /* Step 2: Configure the NFP |
| 1776 | * - Enable rings from 0 to tx_rings/rx_rings - 1. | 1851 | * - Enable rings from 0 to tx_rings/rx_rings - 1. |
| 1777 | * - Write MAC address (in case it changed) | 1852 | * - Write MAC address (in case it changed) |
| @@ -1779,43 +1854,9 @@ static int nfp_net_netdev_open(struct net_device *netdev) | |||
| 1779 | * - Set the Freelist buffer size | 1854 | * - Set the Freelist buffer size |
| 1780 | * - Enable the FW | 1855 | * - Enable the FW |
| 1781 | */ | 1856 | */ |
| 1782 | for (r = 0; r < nn->num_r_vecs; r++) | 1857 | err = nfp_net_set_config_and_enable(nn); |
| 1783 | nfp_net_vec_write_ring_data(nn, &nn->r_vecs[r], r); | ||
| 1784 | |||
| 1785 | nn_writeq(nn, NFP_NET_CFG_TXRS_ENABLE, nn->num_tx_rings == 64 ? | ||
| 1786 | 0xffffffffffffffffULL : ((u64)1 << nn->num_tx_rings) - 1); | ||
| 1787 | |||
| 1788 | nn_writeq(nn, NFP_NET_CFG_RXRS_ENABLE, nn->num_rx_rings == 64 ? | ||
| 1789 | 0xffffffffffffffffULL : ((u64)1 << nn->num_rx_rings) - 1); | ||
| 1790 | |||
| 1791 | nfp_net_write_mac_addr(nn, netdev->dev_addr); | ||
| 1792 | |||
| 1793 | nn_writel(nn, NFP_NET_CFG_MTU, netdev->mtu); | ||
| 1794 | nn_writel(nn, NFP_NET_CFG_FLBUFSZ, nn->fl_bufsz); | ||
| 1795 | |||
| 1796 | /* Enable device */ | ||
| 1797 | new_ctrl |= NFP_NET_CFG_CTRL_ENABLE; | ||
| 1798 | update |= NFP_NET_CFG_UPDATE_GEN; | ||
| 1799 | update |= NFP_NET_CFG_UPDATE_MSIX; | ||
| 1800 | update |= NFP_NET_CFG_UPDATE_RING; | ||
| 1801 | if (nn->cap & NFP_NET_CFG_CTRL_RINGCFG) | ||
| 1802 | new_ctrl |= NFP_NET_CFG_CTRL_RINGCFG; | ||
| 1803 | |||
| 1804 | nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl); | ||
| 1805 | err = nfp_net_reconfig(nn, update); | ||
| 1806 | if (err) | 1858 | if (err) |
| 1807 | goto err_clear_config; | 1859 | goto err_free_rings; |
| 1808 | |||
| 1809 | nn->ctrl = new_ctrl; | ||
| 1810 | |||
| 1811 | /* Since reconfiguration requests while NFP is down are ignored we | ||
| 1812 | * have to wipe the entire VXLAN configuration and reinitialize it. | ||
| 1813 | */ | ||
| 1814 | if (nn->ctrl & NFP_NET_CFG_CTRL_VXLAN) { | ||
| 1815 | memset(&nn->vxlan_ports, 0, sizeof(nn->vxlan_ports)); | ||
| 1816 | memset(&nn->vxlan_usecnt, 0, sizeof(nn->vxlan_usecnt)); | ||
| 1817 | vxlan_get_rx_port(netdev); | ||
| 1818 | } | ||
| 1819 | 1860 | ||
| 1820 | /* Step 3: Enable for kernel | 1861 | /* Step 3: Enable for kernel |
| 1821 | * - put some freelist descriptors on each RX ring | 1862 | * - put some freelist descriptors on each RX ring |
| @@ -1823,18 +1864,10 @@ static int nfp_net_netdev_open(struct net_device *netdev) | |||
| 1823 | * - enable all TX queues | 1864 | * - enable all TX queues |
| 1824 | * - set link state | 1865 | * - set link state |
| 1825 | */ | 1866 | */ |
| 1826 | for (r = 0; r < nn->num_r_vecs; r++) | 1867 | nfp_net_open_stack(nn); |
| 1827 | nfp_net_start_vec(nn, &nn->r_vecs[r]); | ||
| 1828 | |||
| 1829 | netif_tx_wake_all_queues(netdev); | ||
| 1830 | |||
| 1831 | enable_irq(nn->irq_entries[NFP_NET_CFG_LSC].vector); | ||
| 1832 | nfp_net_read_link_status(nn); | ||
| 1833 | 1868 | ||
| 1834 | return 0; | 1869 | return 0; |
| 1835 | 1870 | ||
| 1836 | err_clear_config: | ||
| 1837 | nfp_net_clear_config_and_disable(nn); | ||
| 1838 | err_free_rings: | 1871 | err_free_rings: |
| 1839 | r = nn->num_r_vecs; | 1872 | r = nn->num_r_vecs; |
| 1840 | err_free_prev_vecs: | 1873 | err_free_prev_vecs: |
| @@ -1858,36 +1891,31 @@ err_free_exn: | |||
| 1858 | } | 1891 | } |
| 1859 | 1892 | ||
| 1860 | /** | 1893 | /** |
| 1861 | * nfp_net_netdev_close() - Called when the device is downed | 1894 | * nfp_net_close_stack() - Quiescent the stack (part of close) |
| 1862 | * @netdev: netdev structure | 1895 | * @nn: NFP Net device to reconfigure |
| 1863 | */ | 1896 | */ |
| 1864 | static int nfp_net_netdev_close(struct net_device *netdev) | 1897 | static void nfp_net_close_stack(struct nfp_net *nn) |
| 1865 | { | 1898 | { |
| 1866 | struct nfp_net *nn = netdev_priv(netdev); | 1899 | unsigned int r; |
| 1867 | int r; | ||
| 1868 | |||
| 1869 | if (!(nn->ctrl & NFP_NET_CFG_CTRL_ENABLE)) { | ||
| 1870 | nn_err(nn, "Dev is not up: 0x%08x\n", nn->ctrl); | ||
| 1871 | return 0; | ||
| 1872 | } | ||
| 1873 | 1900 | ||
| 1874 | /* Step 1: Disable RX and TX rings from the Linux kernel perspective | ||
| 1875 | */ | ||
| 1876 | disable_irq(nn->irq_entries[NFP_NET_CFG_LSC].vector); | 1901 | disable_irq(nn->irq_entries[NFP_NET_CFG_LSC].vector); |
| 1877 | netif_carrier_off(netdev); | 1902 | netif_carrier_off(nn->netdev); |
| 1878 | nn->link_up = false; | 1903 | nn->link_up = false; |
| 1879 | 1904 | ||
| 1880 | for (r = 0; r < nn->num_r_vecs; r++) | 1905 | for (r = 0; r < nn->num_r_vecs; r++) |
| 1881 | napi_disable(&nn->r_vecs[r].napi); | 1906 | napi_disable(&nn->r_vecs[r].napi); |
| 1882 | 1907 | ||
| 1883 | netif_tx_disable(netdev); | 1908 | netif_tx_disable(nn->netdev); |
| 1909 | } | ||
| 1884 | 1910 | ||
| 1885 | /* Step 2: Tell NFP | 1911 | /** |
| 1886 | */ | 1912 | * nfp_net_close_free_all() - Free all runtime resources |
| 1887 | nfp_net_clear_config_and_disable(nn); | 1913 | * @nn: NFP Net device to reconfigure |
| 1914 | */ | ||
| 1915 | static void nfp_net_close_free_all(struct nfp_net *nn) | ||
| 1916 | { | ||
| 1917 | unsigned int r; | ||
| 1888 | 1918 | ||
| 1889 | /* Step 3: Free resources | ||
| 1890 | */ | ||
| 1891 | for (r = 0; r < nn->num_r_vecs; r++) { | 1919 | for (r = 0; r < nn->num_r_vecs; r++) { |
| 1892 | nfp_net_rx_ring_reset(nn->r_vecs[r].rx_ring); | 1920 | nfp_net_rx_ring_reset(nn->r_vecs[r].rx_ring); |
| 1893 | nfp_net_rx_ring_bufs_free(nn, nn->r_vecs[r].rx_ring); | 1921 | 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) | |||
| 1902 | 1930 | ||
| 1903 | nfp_net_aux_irq_free(nn, NFP_NET_CFG_LSC, NFP_NET_IRQ_LSC_IDX); | 1931 | nfp_net_aux_irq_free(nn, NFP_NET_CFG_LSC, NFP_NET_IRQ_LSC_IDX); |
| 1904 | nfp_net_aux_irq_free(nn, NFP_NET_CFG_EXN, NFP_NET_IRQ_EXN_IDX); | 1932 | nfp_net_aux_irq_free(nn, NFP_NET_CFG_EXN, NFP_NET_IRQ_EXN_IDX); |
| 1933 | } | ||
| 1934 | |||
| 1935 | /** | ||
| 1936 | * nfp_net_netdev_close() - Called when the device is downed | ||
| 1937 | * @netdev: netdev structure | ||
| 1938 | */ | ||
| 1939 | static int nfp_net_netdev_close(struct net_device *netdev) | ||
| 1940 | { | ||
| 1941 | struct nfp_net *nn = netdev_priv(netdev); | ||
| 1942 | |||
| 1943 | if (!(nn->ctrl & NFP_NET_CFG_CTRL_ENABLE)) { | ||
| 1944 | nn_err(nn, "Dev is not up: 0x%08x\n", nn->ctrl); | ||
| 1945 | return 0; | ||
| 1946 | } | ||
| 1947 | |||
| 1948 | /* Step 1: Disable RX and TX rings from the Linux kernel perspective | ||
| 1949 | */ | ||
| 1950 | nfp_net_close_stack(nn); | ||
| 1951 | |||
| 1952 | /* Step 2: Tell NFP | ||
| 1953 | */ | ||
| 1954 | nfp_net_clear_config_and_disable(nn); | ||
| 1955 | |||
| 1956 | /* Step 3: Free resources | ||
| 1957 | */ | ||
| 1958 | nfp_net_close_free_all(nn); | ||
| 1905 | 1959 | ||
| 1906 | nn_dbg(nn, "%s down", netdev->name); | 1960 | nn_dbg(nn, "%s down", netdev->name); |
| 1907 | return 0; | 1961 | return 0; |
