Commit 22447534 authored by Tom Lendacky's avatar Tom Lendacky Committed by David S. Miller

amd-xgbe: Prepare for ethtool set-channel support

In order to support being able to dynamically set/change the number of
Rx and Tx channels, update the code to:
 - Move alloc and free of device memory into callable functions
 - Move setting of the real number of Rx and Tx channels to device startup
 - Move mapping of the RSS channels to device startup
Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bab748de
...@@ -1312,14 +1312,72 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller) ...@@ -1312,14 +1312,72 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller)
return 0; return 0;
} }
static void xgbe_free_memory(struct xgbe_prv_data *pdata)
{
struct xgbe_desc_if *desc_if = &pdata->desc_if;
/* Free the ring descriptors and buffers */
desc_if->free_ring_resources(pdata);
/* Free the channel and ring structures */
xgbe_free_channels(pdata);
}
static int xgbe_alloc_memory(struct xgbe_prv_data *pdata)
{
struct xgbe_desc_if *desc_if = &pdata->desc_if;
struct net_device *netdev = pdata->netdev;
int ret;
/* Calculate the Rx buffer size before allocating rings */
pdata->rx_buf_size = xgbe_calc_rx_buf_size(netdev, netdev->mtu);
/* Allocate the channel and ring structures */
ret = xgbe_alloc_channels(pdata);
if (ret)
return ret;
/* Allocate the ring descriptors and buffers */
ret = desc_if->alloc_ring_resources(pdata);
if (ret)
goto err_channels;
/* Initialize the service and Tx timers */
xgbe_init_timers(pdata);
return 0;
err_channels:
xgbe_free_memory(pdata);
return ret;
}
static int xgbe_start(struct xgbe_prv_data *pdata) static int xgbe_start(struct xgbe_prv_data *pdata)
{ {
struct xgbe_hw_if *hw_if = &pdata->hw_if; struct xgbe_hw_if *hw_if = &pdata->hw_if;
struct xgbe_phy_if *phy_if = &pdata->phy_if; struct xgbe_phy_if *phy_if = &pdata->phy_if;
struct net_device *netdev = pdata->netdev; struct net_device *netdev = pdata->netdev;
unsigned int i;
int ret; int ret;
DBGPR("-->xgbe_start\n"); /* Set the number of queues */
ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count);
if (ret) {
netdev_err(netdev, "error setting real tx queue count\n");
return ret;
}
ret = netif_set_real_num_rx_queues(netdev, pdata->rx_ring_count);
if (ret) {
netdev_err(netdev, "error setting real rx queue count\n");
return ret;
}
/* Set RSS lookup table data for programming */
for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++)
XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH,
i % pdata->rx_ring_count);
ret = hw_if->init(pdata); ret = hw_if->init(pdata);
if (ret) if (ret)
...@@ -1347,8 +1405,6 @@ static int xgbe_start(struct xgbe_prv_data *pdata) ...@@ -1347,8 +1405,6 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
clear_bit(XGBE_STOPPED, &pdata->dev_state); clear_bit(XGBE_STOPPED, &pdata->dev_state);
DBGPR("<--xgbe_start\n");
return 0; return 0;
err_irqs: err_irqs:
...@@ -1823,11 +1879,8 @@ static void xgbe_packet_info(struct xgbe_prv_data *pdata, ...@@ -1823,11 +1879,8 @@ static void xgbe_packet_info(struct xgbe_prv_data *pdata,
static int xgbe_open(struct net_device *netdev) static int xgbe_open(struct net_device *netdev)
{ {
struct xgbe_prv_data *pdata = netdev_priv(netdev); struct xgbe_prv_data *pdata = netdev_priv(netdev);
struct xgbe_desc_if *desc_if = &pdata->desc_if;
int ret; int ret;
DBGPR("-->xgbe_open\n");
/* Create the various names based on netdev name */ /* Create the various names based on netdev name */
snprintf(pdata->an_name, sizeof(pdata->an_name) - 1, "%s-pcs", snprintf(pdata->an_name, sizeof(pdata->an_name) - 1, "%s-pcs",
netdev_name(netdev)); netdev_name(netdev));
...@@ -1872,43 +1925,25 @@ static int xgbe_open(struct net_device *netdev) ...@@ -1872,43 +1925,25 @@ static int xgbe_open(struct net_device *netdev)
goto err_sysclk; goto err_sysclk;
} }
/* Calculate the Rx buffer size before allocating rings */
ret = xgbe_calc_rx_buf_size(netdev, netdev->mtu);
if (ret < 0)
goto err_ptpclk;
pdata->rx_buf_size = ret;
/* Allocate the channel and ring structures */
ret = xgbe_alloc_channels(pdata);
if (ret)
goto err_ptpclk;
/* Allocate the ring descriptors and buffers */
ret = desc_if->alloc_ring_resources(pdata);
if (ret)
goto err_channels;
INIT_WORK(&pdata->service_work, xgbe_service); INIT_WORK(&pdata->service_work, xgbe_service);
INIT_WORK(&pdata->restart_work, xgbe_restart); INIT_WORK(&pdata->restart_work, xgbe_restart);
INIT_WORK(&pdata->stopdev_work, xgbe_stopdev); INIT_WORK(&pdata->stopdev_work, xgbe_stopdev);
INIT_WORK(&pdata->tx_tstamp_work, xgbe_tx_tstamp); INIT_WORK(&pdata->tx_tstamp_work, xgbe_tx_tstamp);
xgbe_init_timers(pdata);
ret = xgbe_alloc_memory(pdata);
if (ret)
goto err_ptpclk;
ret = xgbe_start(pdata); ret = xgbe_start(pdata);
if (ret) if (ret)
goto err_rings; goto err_mem;
clear_bit(XGBE_DOWN, &pdata->dev_state); clear_bit(XGBE_DOWN, &pdata->dev_state);
DBGPR("<--xgbe_open\n");
return 0; return 0;
err_rings: err_mem:
desc_if->free_ring_resources(pdata); xgbe_free_memory(pdata);
err_channels:
xgbe_free_channels(pdata);
err_ptpclk: err_ptpclk:
clk_disable_unprepare(pdata->ptpclk); clk_disable_unprepare(pdata->ptpclk);
...@@ -1928,18 +1963,11 @@ static int xgbe_open(struct net_device *netdev) ...@@ -1928,18 +1963,11 @@ static int xgbe_open(struct net_device *netdev)
static int xgbe_close(struct net_device *netdev) static int xgbe_close(struct net_device *netdev)
{ {
struct xgbe_prv_data *pdata = netdev_priv(netdev); struct xgbe_prv_data *pdata = netdev_priv(netdev);
struct xgbe_desc_if *desc_if = &pdata->desc_if;
DBGPR("-->xgbe_close\n");
/* Stop the device */ /* Stop the device */
xgbe_stop(pdata); xgbe_stop(pdata);
/* Free the ring descriptors and buffers */ xgbe_free_memory(pdata);
desc_if->free_ring_resources(pdata);
/* Free the channel and ring structures */
xgbe_free_channels(pdata);
/* Disable the clocks */ /* Disable the clocks */
clk_disable_unprepare(pdata->ptpclk); clk_disable_unprepare(pdata->ptpclk);
...@@ -1953,8 +1981,6 @@ static int xgbe_close(struct net_device *netdev) ...@@ -1953,8 +1981,6 @@ static int xgbe_close(struct net_device *netdev)
set_bit(XGBE_DOWN, &pdata->dev_state); set_bit(XGBE_DOWN, &pdata->dev_state);
DBGPR("<--xgbe_close\n");
return 0; return 0;
} }
......
...@@ -265,7 +265,6 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) ...@@ -265,7 +265,6 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
{ {
struct net_device *netdev = pdata->netdev; struct net_device *netdev = pdata->netdev;
struct device *dev = pdata->dev; struct device *dev = pdata->dev;
unsigned int i;
int ret; int ret;
netdev->irq = pdata->dev_irq; netdev->irq = pdata->dev_irq;
...@@ -324,26 +323,9 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) ...@@ -324,26 +323,9 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
pdata->tx_ring_count, pdata->rx_ring_count); pdata->tx_ring_count, pdata->rx_ring_count);
} }
/* Set the number of queues */ /* Initialize RSS hash key */
ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count);
if (ret) {
dev_err(dev, "error setting real tx queue count\n");
return ret;
}
ret = netif_set_real_num_rx_queues(netdev, pdata->rx_ring_count);
if (ret) {
dev_err(dev, "error setting real rx queue count\n");
return ret;
}
/* Initialize RSS hash key and lookup table */
netdev_rss_key_fill(pdata->rss_key, sizeof(pdata->rss_key)); netdev_rss_key_fill(pdata->rss_key, sizeof(pdata->rss_key));
for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++)
XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH,
i % pdata->rx_ring_count);
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1); XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1);
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1); XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1);
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1); XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment