diff options
Diffstat (limited to 'drivers/net/ethernet/ti/cpsw_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/ti/cpsw_ethtool.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/net/ethernet/ti/cpsw_ethtool.c b/drivers/net/ethernet/ti/cpsw_ethtool.c index e4d7185fde49..31248a6cc642 100644 --- a/drivers/net/ethernet/ti/cpsw_ethtool.c +++ b/drivers/net/ethernet/ti/cpsw_ethtool.c @@ -578,6 +578,18 @@ static int cpsw_update_channels_res(struct cpsw_priv *priv, int ch_num, int rx, return 0; } +static void cpsw_fail(struct cpsw_common *cpsw) +{ + struct net_device *ndev; + int i; + + for (i = 0; i < cpsw->data.slaves; i++) { + ndev = cpsw->slaves[i].ndev; + if (ndev) + dev_close(ndev); + } +} + int cpsw_set_channels_common(struct net_device *ndev, struct ethtool_channels *chs, cpdma_handler_fn rx_handler) @@ -585,7 +597,7 @@ int cpsw_set_channels_common(struct net_device *ndev, struct cpsw_priv *priv = netdev_priv(ndev); struct cpsw_common *cpsw = priv->cpsw; struct net_device *sl_ndev; - int i, ret; + int i, new_pools, ret; ret = cpsw_check_ch_settings(cpsw, chs); if (ret < 0) @@ -593,6 +605,8 @@ int cpsw_set_channels_common(struct net_device *ndev, cpsw_suspend_data_pass(ndev); + new_pools = (chs->rx_count != cpsw->rx_ch_num) && cpsw->usage_count; + ret = cpsw_update_channels_res(priv, chs->rx_count, 1, rx_handler); if (ret) goto err; @@ -622,12 +636,19 @@ int cpsw_set_channels_common(struct net_device *ndev, cpsw_split_res(cpsw); + if (new_pools) { + cpsw_destroy_xdp_rxqs(cpsw); + ret = cpsw_create_xdp_rxqs(cpsw); + if (ret) + goto err; + } + ret = cpsw_resume_data_pass(ndev); if (!ret) return 0; err: dev_err(priv->dev, "cannot update channels number, closing device\n"); - dev_close(ndev); + cpsw_fail(cpsw); return ret; } @@ -647,8 +668,7 @@ void cpsw_get_ringparam(struct net_device *ndev, int cpsw_set_ringparam(struct net_device *ndev, struct ethtool_ringparam *ering) { - struct cpsw_priv *priv = netdev_priv(ndev); - struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); int descs_num, ret; /* ignore ering->tx_pending - only rx_pending adjustment is supported */ @@ -672,13 +692,20 @@ int cpsw_set_ringparam(struct net_device *ndev, return ret; } + if (cpsw->usage_count) { + cpsw_destroy_xdp_rxqs(cpsw); + ret = cpsw_create_xdp_rxqs(cpsw); + if (ret) + goto err; + } + ret = cpsw_resume_data_pass(ndev); if (!ret) return 0; err: cpdma_set_num_rx_descs(cpsw->dma, descs_num); dev_err(cpsw->dev, "cannot set ring params, closing device\n"); - dev_close(ndev); + cpsw_fail(cpsw); return ret; } |