mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-19 05:38:00 +00:00
generic: 5.15: backport stmmac patches to change MTU
Backport stmmac patches to change MTU while the interface is up. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
parent
7ace30aeb6
commit
691b3dd35e
@ -0,0 +1,142 @@
|
||||
From f9ec5723c3dbfcede9c7b0dcdf85e401ce16316c Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sat, 23 Jul 2022 16:29:29 +0200
|
||||
Subject: [PATCH 1/5] net: ethernet: stmicro: stmmac: move queue reset to
|
||||
dedicated functions
|
||||
|
||||
Move queue reset to dedicated functions. This aside from a simple
|
||||
cleanup is also required to allocate a dma conf without resetting the tx
|
||||
queue while the device is temporarily detached as now the reset is not
|
||||
part of the dma init function and can be done later in the code flow.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 59 ++++++++++---------
|
||||
1 file changed, 31 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -130,6 +130,9 @@ static irqreturn_t stmmac_mac_interrupt(
|
||||
static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id);
|
||||
static irqreturn_t stmmac_msi_intr_tx(int irq, void *data);
|
||||
static irqreturn_t stmmac_msi_intr_rx(int irq, void *data);
|
||||
+static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue);
|
||||
+static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue);
|
||||
+static void stmmac_reset_queues_param(struct stmmac_priv *priv);
|
||||
static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue);
|
||||
static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue);
|
||||
|
||||
@@ -1696,9 +1699,6 @@ static int __init_dma_rx_desc_rings(stru
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- rx_q->cur_rx = 0;
|
||||
- rx_q->dirty_rx = 0;
|
||||
-
|
||||
/* Setup the chained descriptor addresses */
|
||||
if (priv->mode == STMMAC_CHAIN_MODE) {
|
||||
if (priv->extend_desc)
|
||||
@@ -1804,12 +1804,6 @@ static int __init_dma_tx_desc_rings(stru
|
||||
tx_q->tx_skbuff[i] = NULL;
|
||||
}
|
||||
|
||||
- tx_q->dirty_tx = 0;
|
||||
- tx_q->cur_tx = 0;
|
||||
- tx_q->mss = 0;
|
||||
-
|
||||
- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2678,10 +2672,7 @@ static void stmmac_tx_err(struct stmmac_
|
||||
stmmac_stop_tx_dma(priv, chan);
|
||||
dma_free_tx_skbufs(priv, chan);
|
||||
stmmac_clear_tx_descriptors(priv, chan);
|
||||
- tx_q->dirty_tx = 0;
|
||||
- tx_q->cur_tx = 0;
|
||||
- tx_q->mss = 0;
|
||||
- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, chan));
|
||||
+ stmmac_reset_tx_queue(priv, chan);
|
||||
stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
|
||||
tx_q->dma_tx_phy, chan);
|
||||
stmmac_start_tx_dma(priv, chan);
|
||||
@@ -3756,6 +3747,8 @@ static int stmmac_open(struct net_device
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
+ stmmac_reset_queues_param(priv);
|
||||
+
|
||||
ret = stmmac_hw_setup(dev, true);
|
||||
if (ret < 0) {
|
||||
netdev_err(priv->dev, "%s: Hw setup failed\n", __func__);
|
||||
@@ -6395,6 +6388,7 @@ void stmmac_enable_rx_queue(struct stmma
|
||||
return;
|
||||
}
|
||||
|
||||
+ stmmac_reset_rx_queue(priv, queue);
|
||||
stmmac_clear_rx_descriptors(priv, queue);
|
||||
|
||||
stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
|
||||
@@ -6456,6 +6450,7 @@ void stmmac_enable_tx_queue(struct stmma
|
||||
return;
|
||||
}
|
||||
|
||||
+ stmmac_reset_tx_queue(priv, queue);
|
||||
stmmac_clear_tx_descriptors(priv, queue);
|
||||
|
||||
stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
|
||||
@@ -7383,6 +7378,25 @@ int stmmac_suspend(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(stmmac_suspend);
|
||||
|
||||
+static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue)
|
||||
+{
|
||||
+ struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
+
|
||||
+ rx_q->cur_rx = 0;
|
||||
+ rx_q->dirty_rx = 0;
|
||||
+}
|
||||
+
|
||||
+static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue)
|
||||
+{
|
||||
+ struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
|
||||
+
|
||||
+ tx_q->cur_tx = 0;
|
||||
+ tx_q->dirty_tx = 0;
|
||||
+ tx_q->mss = 0;
|
||||
+
|
||||
+ netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* stmmac_reset_queues_param - reset queue parameters
|
||||
* @priv: device pointer
|
||||
@@ -7393,22 +7407,11 @@ static void stmmac_reset_queues_param(st
|
||||
u32 tx_cnt = priv->plat->tx_queues_to_use;
|
||||
u32 queue;
|
||||
|
||||
- for (queue = 0; queue < rx_cnt; queue++) {
|
||||
- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
+ for (queue = 0; queue < rx_cnt; queue++)
|
||||
+ stmmac_reset_rx_queue(priv, queue);
|
||||
|
||||
- rx_q->cur_rx = 0;
|
||||
- rx_q->dirty_rx = 0;
|
||||
- }
|
||||
-
|
||||
- for (queue = 0; queue < tx_cnt; queue++) {
|
||||
- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
|
||||
-
|
||||
- tx_q->cur_tx = 0;
|
||||
- tx_q->dirty_tx = 0;
|
||||
- tx_q->mss = 0;
|
||||
-
|
||||
- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
|
||||
- }
|
||||
+ for (queue = 0; queue < tx_cnt; queue++)
|
||||
+ stmmac_reset_tx_queue(priv, queue);
|
||||
}
|
||||
|
||||
/**
|
@ -0,0 +1,37 @@
|
||||
From 7028471edb646bfc532fec0973e50e784cdcb7c6 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sat, 23 Jul 2022 16:29:30 +0200
|
||||
Subject: [PATCH 2/5] net: ethernet: stmicro: stmmac: first disable all queues
|
||||
and disconnect in release
|
||||
|
||||
Disable all queues and disconnect before tx_disable in stmmac_release to
|
||||
prevent a corner case where packet may be still queued at the same time
|
||||
tx_disable is called resulting in kernel panic if some packet still has
|
||||
to be processed.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -3808,8 +3808,6 @@ static int stmmac_release(struct net_dev
|
||||
struct stmmac_priv *priv = netdev_priv(dev);
|
||||
u32 chan;
|
||||
|
||||
- netif_tx_disable(dev);
|
||||
-
|
||||
if (device_may_wakeup(priv->device))
|
||||
phylink_speed_down(priv->phylink, false);
|
||||
/* Stop and disconnect the PHY */
|
||||
@@ -3821,6 +3819,8 @@ static int stmmac_release(struct net_dev
|
||||
for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
|
||||
hrtimer_cancel(&priv->tx_queue[chan].txtimer);
|
||||
|
||||
+ netif_tx_disable(dev);
|
||||
+
|
||||
/* Free the IRQ lines */
|
||||
stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,73 @@
|
||||
From 3470079687448abac42deb62774253be1d6bdef3 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sat, 23 Jul 2022 16:29:33 +0200
|
||||
Subject: [PATCH 5/5] net: ethernet: stmicro: stmmac: permit MTU change with
|
||||
interface up
|
||||
|
||||
Remove the limitation where the interface needs to be down to change
|
||||
MTU by releasing and opening the stmmac driver to set the new MTU.
|
||||
Also call the set_filter function to correctly init the port.
|
||||
This permits to remove the EBUSY error while the ethernet port is
|
||||
running permitting a correct MTU change if for example a DSA request
|
||||
a MTU change for a switch CPU port.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 30 +++++++++++++++----
|
||||
1 file changed, 24 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -5597,18 +5597,15 @@ static int stmmac_change_mtu(struct net_
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(dev);
|
||||
int txfifosz = priv->plat->tx_fifo_size;
|
||||
+ struct stmmac_dma_conf *dma_conf;
|
||||
const int mtu = new_mtu;
|
||||
+ int ret;
|
||||
|
||||
if (txfifosz == 0)
|
||||
txfifosz = priv->dma_cap.tx_fifo_size;
|
||||
|
||||
txfifosz /= priv->plat->tx_queues_to_use;
|
||||
|
||||
- if (netif_running(dev)) {
|
||||
- netdev_err(priv->dev, "must be stopped to change its MTU\n");
|
||||
- return -EBUSY;
|
||||
- }
|
||||
-
|
||||
if (stmmac_xdp_is_enabled(priv) && new_mtu > ETH_DATA_LEN) {
|
||||
netdev_dbg(priv->dev, "Jumbo frames not supported for XDP\n");
|
||||
return -EINVAL;
|
||||
@@ -5620,8 +5617,29 @@ static int stmmac_change_mtu(struct net_
|
||||
if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB))
|
||||
return -EINVAL;
|
||||
|
||||
- dev->mtu = mtu;
|
||||
+ if (netif_running(dev)) {
|
||||
+ netdev_dbg(priv->dev, "restarting interface to change its MTU\n");
|
||||
+ /* Try to allocate the new DMA conf with the new mtu */
|
||||
+ dma_conf = stmmac_setup_dma_desc(priv, mtu);
|
||||
+ if (IS_ERR(dma_conf)) {
|
||||
+ netdev_err(priv->dev, "failed allocating new dma conf for new MTU %d\n",
|
||||
+ mtu);
|
||||
+ return PTR_ERR(dma_conf);
|
||||
+ }
|
||||
+
|
||||
+ stmmac_release(dev);
|
||||
+
|
||||
+ ret = __stmmac_open(dev, dma_conf);
|
||||
+ kfree(dma_conf);
|
||||
+ if (ret) {
|
||||
+ netdev_err(priv->dev, "failed reopening the interface after MTU change\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ stmmac_set_rx_mode(dev);
|
||||
+ }
|
||||
|
||||
+ dev->mtu = mtu;
|
||||
netdev_update_features(dev);
|
||||
|
||||
return 0;
|
Loading…
Reference in New Issue
Block a user