Skip to content

Commit 40d0af5

Browse files
committed
Merge branch 'stmmac-Improvements-for-multi-queuing-and-for-AVB'
Jose Abreu says: ==================== net: stmmac: Improvements for multi-queuing and for AVB Two improvements for stmmac: First one corrects the available fifo size per queue, second one corrects enabling of AVB queues. More info in commit log. Cc: David S. Miller <[email protected]> Cc: Joao Pinto <[email protected]> Cc: Giuseppe Cavallaro <[email protected]> Cc: Alexandre Torgue <[email protected]> Changes from v1: - Fix typo in second patch ==================== Signed-off-by: David S. Miller <[email protected]> Acked-by: Giuseppe Cavallaro <[email protected]>
2 parents 258bbb1 + a0daae1 commit 40d0af5

File tree

4 files changed

+56
-17
lines changed

4 files changed

+56
-17
lines changed

drivers/net/ethernet/stmicro/stmmac/common.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,9 @@ struct stmmac_dma_ops {
442442
void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode,
443443
int rxfifosz);
444444
void (*dma_rx_mode)(void __iomem *ioaddr, int mode, u32 channel,
445-
int fifosz);
446-
void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel);
445+
int fifosz, u8 qmode);
446+
void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel,
447+
int fifosz, u8 qmode);
447448
/* To track extra statistic (if supported) */
448449
void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
449450
void __iomem *ioaddr);

drivers/net/ethernet/stmicro/stmmac/dwmac4.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ enum power_event {
225225
#define MTL_CHAN_RX_DEBUG(x) (MTL_CHANX_BASE_ADDR(x) + 0x38)
226226

227227
#define MTL_OP_MODE_RSF BIT(5)
228+
#define MTL_OP_MODE_TXQEN_MASK GENMASK(3, 2)
229+
#define MTL_OP_MODE_TXQEN_AV BIT(2)
228230
#define MTL_OP_MODE_TXQEN BIT(3)
229231
#define MTL_OP_MODE_TSF BIT(1)
230232

drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 number_chan)
191191
}
192192

193193
static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode,
194-
u32 channel, int fifosz)
194+
u32 channel, int fifosz, u8 qmode)
195195
{
196196
unsigned int rqs = fifosz / 256 - 1;
197197
u32 mtl_rx_op, mtl_rx_int;
@@ -218,8 +218,10 @@ static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode,
218218
mtl_rx_op &= ~MTL_OP_MODE_RQS_MASK;
219219
mtl_rx_op |= rqs << MTL_OP_MODE_RQS_SHIFT;
220220

221-
/* enable flow control only if each channel gets 4 KiB or more FIFO */
222-
if (fifosz >= 4096) {
221+
/* Enable flow control only if each channel gets 4 KiB or more FIFO and
222+
* only if channel is not an AVB channel.
223+
*/
224+
if ((fifosz >= 4096) && (qmode != MTL_QUEUE_AVB)) {
223225
unsigned int rfd, rfa;
224226

225227
mtl_rx_op |= MTL_OP_MODE_EHFC;
@@ -271,9 +273,10 @@ static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode,
271273
}
272274

273275
static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode,
274-
u32 channel)
276+
u32 channel, int fifosz, u8 qmode)
275277
{
276278
u32 mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));
279+
unsigned int tqs = fifosz / 256 - 1;
277280

278281
if (mode == SF_DMA_MODE) {
279282
pr_debug("GMAC: enable TX store and forward mode\n");
@@ -306,12 +309,18 @@ static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode,
306309
* For an IP with DWC_EQOS_NUM_TXQ > 1, the fields TXQEN and TQS are R/W
307310
* with reset values: TXQEN off, TQS 256 bytes.
308311
*
309-
* Write the bits in both cases, since it will have no effect when RO.
310-
* For DWC_EQOS_NUM_TXQ > 1, the top bits in MTL_OP_MODE_TQS_MASK might
311-
* be RO, however, writing the whole TQS field will result in a value
312-
* equal to DWC_EQOS_TXFIFO_SIZE, just like for DWC_EQOS_NUM_TXQ == 1.
312+
* TXQEN must be written for multi-channel operation and TQS must
313+
* reflect the available fifo size per queue (total fifo size / number
314+
* of enabled queues).
313315
*/
314-
mtl_tx_op |= MTL_OP_MODE_TXQEN | MTL_OP_MODE_TQS_MASK;
316+
mtl_tx_op &= ~MTL_OP_MODE_TXQEN_MASK;
317+
if (qmode != MTL_QUEUE_AVB)
318+
mtl_tx_op |= MTL_OP_MODE_TXQEN;
319+
else
320+
mtl_tx_op |= MTL_OP_MODE_TXQEN_AV;
321+
mtl_tx_op &= ~MTL_OP_MODE_TQS_MASK;
322+
mtl_tx_op |= tqs << MTL_OP_MODE_TQS_SHIFT;
323+
315324
writel(mtl_tx_op, ioaddr + MTL_CHAN_TX_OP_MODE(channel));
316325
}
317326

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,12 +1750,20 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
17501750
u32 rx_channels_count = priv->plat->rx_queues_to_use;
17511751
u32 tx_channels_count = priv->plat->tx_queues_to_use;
17521752
int rxfifosz = priv->plat->rx_fifo_size;
1753+
int txfifosz = priv->plat->tx_fifo_size;
17531754
u32 txmode = 0;
17541755
u32 rxmode = 0;
17551756
u32 chan = 0;
1757+
u8 qmode = 0;
17561758

17571759
if (rxfifosz == 0)
17581760
rxfifosz = priv->dma_cap.rx_fifo_size;
1761+
if (txfifosz == 0)
1762+
txfifosz = priv->dma_cap.tx_fifo_size;
1763+
1764+
/* Adjust for real per queue fifo size */
1765+
rxfifosz /= rx_channels_count;
1766+
txfifosz /= tx_channels_count;
17591767

17601768
if (priv->plat->force_thresh_dma_mode) {
17611769
txmode = tc;
@@ -1778,12 +1786,19 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
17781786

17791787
/* configure all channels */
17801788
if (priv->synopsys_id >= DWMAC_CORE_4_00) {
1781-
for (chan = 0; chan < rx_channels_count; chan++)
1789+
for (chan = 0; chan < rx_channels_count; chan++) {
1790+
qmode = priv->plat->rx_queues_cfg[chan].mode_to_use;
1791+
17821792
priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan,
1783-
rxfifosz);
1793+
rxfifosz, qmode);
1794+
}
17841795

1785-
for (chan = 0; chan < tx_channels_count; chan++)
1786-
priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan);
1796+
for (chan = 0; chan < tx_channels_count; chan++) {
1797+
qmode = priv->plat->tx_queues_cfg[chan].mode_to_use;
1798+
1799+
priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan,
1800+
txfifosz, qmode);
1801+
}
17871802
} else {
17881803
priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode,
17891804
rxfifosz);
@@ -1946,15 +1961,27 @@ static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan)
19461961
static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode,
19471962
u32 rxmode, u32 chan)
19481963
{
1964+
u8 rxqmode = priv->plat->rx_queues_cfg[chan].mode_to_use;
1965+
u8 txqmode = priv->plat->tx_queues_cfg[chan].mode_to_use;
1966+
u32 rx_channels_count = priv->plat->rx_queues_to_use;
1967+
u32 tx_channels_count = priv->plat->tx_queues_to_use;
19491968
int rxfifosz = priv->plat->rx_fifo_size;
1969+
int txfifosz = priv->plat->tx_fifo_size;
19501970

19511971
if (rxfifosz == 0)
19521972
rxfifosz = priv->dma_cap.rx_fifo_size;
1973+
if (txfifosz == 0)
1974+
txfifosz = priv->dma_cap.tx_fifo_size;
1975+
1976+
/* Adjust for real per queue fifo size */
1977+
rxfifosz /= rx_channels_count;
1978+
txfifosz /= tx_channels_count;
19531979

19541980
if (priv->synopsys_id >= DWMAC_CORE_4_00) {
19551981
priv->hw->dma->dma_rx_mode(priv->ioaddr, rxmode, chan,
1956-
rxfifosz);
1957-
priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan);
1982+
rxfifosz, rxqmode);
1983+
priv->hw->dma->dma_tx_mode(priv->ioaddr, txmode, chan,
1984+
txfifosz, txqmode);
19581985
} else {
19591986
priv->hw->dma->dma_mode(priv->ioaddr, txmode, rxmode,
19601987
rxfifosz);

0 commit comments

Comments
 (0)