summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2025-08-27 11:00:50 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:33:46 +0300
commit26d5628d45bac9aab4fcd82515f0a4a549b0a4d9 (patch)
tree0537a63b4d27a1a1ca2cce381846b1f0247b585c
parente43ea4fb081a9595a2dd4a7c708637a87f61d2b1 (diff)
downloadlinux-26d5628d45bac9aab4fcd82515f0a4a549b0a4d9.tar.gz
linux-26d5628d45bac9aab4fcd82515f0a4a549b0a4d9.zip
net: stmmac: Move FIFO size calc to dedicated method
As a preparation to the PBL and MTU constraint implementation let's introduce a dedicated method which would just calculate the Tx/Rx FIFO sizes based on the currently active queues settings. Thus the driver would have the duplicated code of the FIFO depth calculation moved to one coherent method and be prepare for the announced fixes. Note there is no point in checking whether there is a FIFO size passed via the platform configs storage each time the Tx/Rx FIFO size values are required, since neither the FIFO size platform setting nor the FIFO size DMA-capability get changed after the corresponding devices are probed and added to the system. Thus the total Tx/Rx FIFO size can be set just once on the device probe (HW-initialization) procedure: if non-zero platform FIFO size is detected then the FIFO size DMA-capability will be ignored. Also note this change fixes the Loongson GMAC/GNET device support which the only DW GMAC v3.70a device currently declared to support the multi-channel feature. The commit ad72f783de06 ("net: stmmac: Add multi-channel support") has forgotten to fix stmmac_change_mtu() so the method wouldn't divide the MTL FIFO memory between the queues/channels. The multi-channels DW GMACs have the per-channel non-configurable MTL FIFO memory. So the stmmac_change_mtu() has been wrong in unconditionally dividing the total MTL FIFO memory and using the resultant as the upper limit of MTU. Fixes: ad72f783de06 ("net: stmmac: Add multi-channel support") Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c89
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c6
2 files changed, 52 insertions, 43 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 94b05994fe53..f99b189ab571 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1552,6 +1552,44 @@ static void stmmac_display_rings(struct stmmac_priv *priv,
}
/**
+ * stmmac_get_txfifosz - retrieve Tx MTL FIFO size
+ * @priv: driver private structure
+ * Description: calculate the Tx MTL FIFO depth in accordance with
+ * the amount of the activated queues.
+ * Return: current Tx FIFO depth.
+ */
+static unsigned int stmmac_get_txfifosz(struct stmmac_priv *priv)
+{
+
+ unsigned int txfifosz = priv->plat->tx_fifo_size;
+
+ /* Tx FIFO is shared between queues on the modern devices */
+ if (dwmac_is_xmac(priv->plat->core_type))
+ txfifosz /= priv->plat->tx_queues_to_use;
+
+ return txfifosz;
+}
+
+/**
+ * stmmac_get_rxfifosz - retrieve Rx MTL FIFO size
+ * @priv: driver private structure
+ * Description: calculate the Rx MTL FIFO depth in accordance with
+ * the amount of the activated queues.
+ * Return: current Rx FIFO depth.
+ */
+static unsigned int stmmac_get_rxfifosz(struct stmmac_priv *priv)
+{
+
+ unsigned int rxfifosz = priv->plat->rx_fifo_size;
+
+ /* Rx FIFO is shared between queues on the modern devices */
+ if (dwmac_is_xmac(priv->plat->core_type))
+ rxfifosz /= priv->plat->rx_queues_to_use;
+
+ return rxfifosz;
+}
+
+/**
* stmmac_get_min_mtu - retrieve minimal supported MTU
* @priv: driver private structure
* Return: minimal MTU.
@@ -2705,24 +2743,13 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
{
u32 rx_channels_count = priv->plat->rx_queues_to_use;
u32 tx_channels_count = priv->plat->tx_queues_to_use;
- int rxfifosz = priv->plat->rx_fifo_size;
- int txfifosz = priv->plat->tx_fifo_size;
+ int txfifosz = stmmac_get_txfifosz(priv);
+ int rxfifosz = stmmac_get_rxfifosz(priv);
u32 txmode = 0;
u32 rxmode = 0;
u32 chan = 0;
u8 qmode = 0;
- if (rxfifosz == 0)
- rxfifosz = priv->dma_cap.rx_fifo_size;
- if (txfifosz == 0)
- txfifosz = priv->dma_cap.tx_fifo_size;
-
- /* Split up the shared Tx/Rx FIFO memory on DW QoS Eth and DW XGMAC */
- if (dwmac_is_xmac(priv->plat->core_type)) {
- rxfifosz /= rx_channels_count;
- txfifosz /= tx_channels_count;
- }
-
if (priv->plat->force_thresh_dma_mode) {
txmode = ttc;
rxmode = rtc;
@@ -6283,15 +6310,10 @@ static void stmmac_set_rx_mode(struct net_device *dev)
static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
{
struct stmmac_priv *priv = netdev_priv(dev);
- int txfifosz = priv->plat->tx_fifo_size;
+ int txfifosz = stmmac_get_txfifosz(priv);
struct stmmac_dma_conf *dma_conf;
int ret;
- if (txfifosz == 0)
- txfifosz = priv->dma_cap.tx_fifo_size;
-
- txfifosz /= priv->plat->tx_queues_to_use;
-
if (stmmac_xdp_is_enabled(priv) && new_mtu > ETH_DATA_LEN) {
netdev_dbg(priv->dev, "Jumbo frames not supported for XDP\n");
return -EINVAL;
@@ -6371,13 +6393,7 @@ static int stmmac_set_features(struct net_device *netdev,
for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++) {
struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan];
u8 rxqmode = priv->plat->rx_queues_cfg[chan].mode_to_use;
- int rxfifosz = priv->plat->rx_fifo_size;
-
- if (rxfifosz == 0)
- rxfifosz = priv->dma_cap.rx_fifo_size;
-
- if (dwmac_is_xmac(priv->plat->core_type))
- rxfifosz /= priv->plat->rx_queues_to_use;
+ int rxfifosz = stmmac_get_rxfifosz(priv);
stmmac_dma_rx_mode(priv, priv->ioaddr, rx_q->rtc, chan,
rxfifosz, rxqmode, features & NETIF_F_RXALL);
@@ -7711,8 +7727,8 @@ static void stmmac_reset_tx_subtask(struct stmmac_priv *priv, u32 queue)
*/
static void stmmac_drop_rtc_subtask(struct stmmac_priv *priv, u32 queue)
{
- int rxfifosz = priv->plat->rx_fifo_size;
struct stmmac_rx_queue *rx_q;
+ int rxfifosz;
u8 rxqmode;
rx_q = &priv->dma_conf.rx_queue[queue];
@@ -7723,11 +7739,7 @@ static void stmmac_drop_rtc_subtask(struct stmmac_priv *priv, u32 queue)
return;
}
- if (rxfifosz == 0)
- rxfifosz = priv->dma_cap.rx_fifo_size;
-
- if (dwmac_is_xmac(priv->plat->core_type))
- rxfifosz /= priv->plat->rx_queues_to_use;
+ rxfifosz = stmmac_get_rxfifosz(priv);
/* Lower limits: DW GMAC/GMAC4 - 32, DW XGMAC/XLGMAC - 64 */
if (rx_q->rtc <= 32) {
@@ -7761,9 +7773,9 @@ static void stmmac_drop_rtc_subtask(struct stmmac_priv *priv, u32 queue)
*/
static void stmmac_bump_ttc_subtask(struct stmmac_priv *priv, u32 queue)
{
- int txfifosz = priv->plat->tx_fifo_size;
struct stmmac_tx_queue *tx_q;
u8 txqmode, addend;
+ int txfifosz;
tx_q = &priv->dma_conf.tx_queue[queue];
@@ -7773,11 +7785,7 @@ static void stmmac_bump_ttc_subtask(struct stmmac_priv *priv, u32 queue)
return;
}
- if (txfifosz == 0)
- txfifosz = priv->dma_cap.tx_fifo_size;
-
- if (dwmac_is_xmac(priv->plat->core_type))
- txfifosz /= priv->plat->tx_queues_to_use;
+ txfifosz = stmmac_get_txfifosz(priv);
/* 64-bytes step threshold: DW GMAC - 64, DW QoS/XGMAC/etc - 128.
* 128-bytes step threshold: DW QoS/XGMAC/etc - 256.
@@ -7962,6 +7970,11 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
ilog2(priv->hw->multicast_filter_bins);
}
+ if (!priv->plat->rx_fifo_size)
+ priv->plat->rx_fifo_size = priv->dma_cap.rx_fifo_size;
+ if (!priv->plat->tx_fifo_size)
+ priv->plat->tx_fifo_size = priv->dma_cap.tx_fifo_size;
+
/* TXCOE doesn't work in thresh DMA mode */
if (priv->plat->force_thresh_dma_mode)
priv->plat->tx_coe = 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index e50097d64abc..c7be1559fc3e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -757,11 +757,7 @@ static int stmmac_test_flowctrl(struct stmmac_priv *priv)
dev_add_pack(&tpriv->pt);
/* Compute minimum number of packets to make FIFO full */
- pkt_count = priv->plat->rx_fifo_size;
- if (!pkt_count)
- pkt_count = priv->dma_cap.rx_fifo_size;
- pkt_count /= 1400;
- pkt_count *= 2;
+ pkt_count = priv->plat->rx_fifo_size / 1400 * 2;
for (i = 0; i < rx_cnt; i++)
stmmac_stop_rx(priv, priv->ioaddr, i);