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: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
bab748de98
commit
2244753409
@ -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)
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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 @@ err_dev_wq:
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user