Skip to content

Commit c57e558

Browse files
frank-wdavem330
authored andcommitted
net: ethernet: mtk_eth_soc: handle dma buffer size soc specific
The mainline MTK ethernet driver suffers long time from rarly but annoying tx queue timeouts. We think that this is caused by fixed dma sizes hardcoded for all SoCs. We suspect this problem arises from a low level of free TX DMADs, the TX Ring alomost full. The transmit timeout is caused by the Tx queue not waking up. The Tx queue stops when the free counter is less than ring->thres, and it will wake up once the free counter is greater than ring->thres. If the CPU is too late to wake up the Tx queues, it may cause a transmit timeout. Therefore, we increased the TX and RX DMADs to improve this error situation. Use the dma-size implementation from SDK in a per SoC manner. In difference to SDK we have no RSS feature yet, so all RX/TX sizes should be raised from 512 to 2048 byte except fqdma on mt7988 to avoid the tx timeout issue. Fixes: 656e705 ("net-next: mediatek: add support for MT7623 ethernet") Suggested-by: Daniel Golle <[email protected]> Signed-off-by: Frank Wunderlich <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5b4b62a commit c57e558

File tree

2 files changed

+77
-36
lines changed

2 files changed

+77
-36
lines changed

drivers/net/ethernet/mediatek/mtk_eth_soc.c

Lines changed: 70 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,9 +1131,9 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
11311131
{
11321132
const struct mtk_soc_data *soc = eth->soc;
11331133
dma_addr_t phy_ring_tail;
1134-
int cnt = MTK_QDMA_RING_SIZE;
1134+
int cnt = soc->tx.fq_dma_size;
11351135
dma_addr_t dma_addr;
1136-
int i;
1136+
int i, j, len;
11371137

11381138
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM))
11391139
eth->scratch_ring = eth->sram_base;
@@ -1142,40 +1142,46 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
11421142
cnt * soc->tx.desc_size,
11431143
&eth->phy_scratch_ring,
11441144
GFP_KERNEL);
1145+
11451146
if (unlikely(!eth->scratch_ring))
11461147
return -ENOMEM;
11471148

1148-
eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
1149-
if (unlikely(!eth->scratch_head))
1150-
return -ENOMEM;
1149+
phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
11511150

1152-
dma_addr = dma_map_single(eth->dma_dev,
1153-
eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
1154-
DMA_FROM_DEVICE);
1155-
if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
1156-
return -ENOMEM;
1151+
for (j = 0; j < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); j++) {
1152+
len = min_t(int, cnt - j * MTK_FQ_DMA_LENGTH, MTK_FQ_DMA_LENGTH);
1153+
eth->scratch_head[j] = kcalloc(len, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
11571154

1158-
phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
1155+
if (unlikely(!eth->scratch_head[j]))
1156+
return -ENOMEM;
11591157

1160-
for (i = 0; i < cnt; i++) {
1161-
dma_addr_t addr = dma_addr + i * MTK_QDMA_PAGE_SIZE;
1162-
struct mtk_tx_dma_v2 *txd;
1158+
dma_addr = dma_map_single(eth->dma_dev,
1159+
eth->scratch_head[j], len * MTK_QDMA_PAGE_SIZE,
1160+
DMA_FROM_DEVICE);
11631161

1164-
txd = eth->scratch_ring + i * soc->tx.desc_size;
1165-
txd->txd1 = addr;
1166-
if (i < cnt - 1)
1167-
txd->txd2 = eth->phy_scratch_ring +
1168-
(i + 1) * soc->tx.desc_size;
1162+
if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
1163+
return -ENOMEM;
11691164

1170-
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
1171-
if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
1172-
txd->txd3 |= TX_DMA_PREP_ADDR64(addr);
1173-
txd->txd4 = 0;
1174-
if (mtk_is_netsys_v2_or_greater(eth)) {
1175-
txd->txd5 = 0;
1176-
txd->txd6 = 0;
1177-
txd->txd7 = 0;
1178-
txd->txd8 = 0;
1165+
for (i = 0; i < cnt; i++) {
1166+
struct mtk_tx_dma_v2 *txd;
1167+
1168+
txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size;
1169+
txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
1170+
if (j * MTK_FQ_DMA_LENGTH + i < cnt)
1171+
txd->txd2 = eth->phy_scratch_ring +
1172+
(j * MTK_FQ_DMA_LENGTH + i + 1) * soc->tx.desc_size;
1173+
1174+
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
1175+
if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
1176+
txd->txd3 |= TX_DMA_PREP_ADDR64(dma_addr + i * MTK_QDMA_PAGE_SIZE);
1177+
1178+
txd->txd4 = 0;
1179+
if (mtk_is_netsys_v2_or_greater(eth)) {
1180+
txd->txd5 = 0;
1181+
txd->txd6 = 0;
1182+
txd->txd7 = 0;
1183+
txd->txd8 = 0;
1184+
}
11791185
}
11801186
}
11811187

@@ -2457,16 +2463,16 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
24572463
if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
24582464
ring_size = MTK_QDMA_RING_SIZE;
24592465
else
2460-
ring_size = MTK_DMA_SIZE;
2466+
ring_size = soc->tx.dma_size;
24612467

24622468
ring->buf = kcalloc(ring_size, sizeof(*ring->buf),
24632469
GFP_KERNEL);
24642470
if (!ring->buf)
24652471
goto no_tx_mem;
24662472

24672473
if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
2468-
ring->dma = eth->sram_base + ring_size * sz;
2469-
ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
2474+
ring->dma = eth->sram_base + soc->tx.fq_dma_size * sz;
2475+
ring->phys = eth->phy_scratch_ring + soc->tx.fq_dma_size * (dma_addr_t)sz;
24702476
} else {
24712477
ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
24722478
&ring->phys, GFP_KERNEL);
@@ -2588,14 +2594,15 @@ static void mtk_tx_clean(struct mtk_eth *eth)
25882594
static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
25892595
{
25902596
const struct mtk_reg_map *reg_map = eth->soc->reg_map;
2597+
const struct mtk_soc_data *soc = eth->soc;
25912598
struct mtk_rx_ring *ring;
25922599
int rx_data_len, rx_dma_size, tx_ring_size;
25932600
int i;
25942601

25952602
if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
25962603
tx_ring_size = MTK_QDMA_RING_SIZE;
25972604
else
2598-
tx_ring_size = MTK_DMA_SIZE;
2605+
tx_ring_size = soc->tx.dma_size;
25992606

26002607
if (rx_flag == MTK_RX_FLAGS_QDMA) {
26012608
if (ring_no)
@@ -2610,7 +2617,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
26102617
rx_dma_size = MTK_HW_LRO_DMA_SIZE;
26112618
} else {
26122619
rx_data_len = ETH_DATA_LEN;
2613-
rx_dma_size = MTK_DMA_SIZE;
2620+
rx_dma_size = soc->rx.dma_size;
26142621
}
26152622

26162623
ring->frag_size = mtk_max_frag_size(rx_data_len);
@@ -3139,7 +3146,10 @@ static void mtk_dma_free(struct mtk_eth *eth)
31393146
mtk_rx_clean(eth, &eth->rx_ring[i], false);
31403147
}
31413148

3142-
kfree(eth->scratch_head);
3149+
for (i = 0; i < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); i++) {
3150+
kfree(eth->scratch_head[i]);
3151+
eth->scratch_head[i] = NULL;
3152+
}
31433153
}
31443154

31453155
static bool mtk_hw_reset_check(struct mtk_eth *eth)
@@ -5052,11 +5062,14 @@ static const struct mtk_soc_data mt2701_data = {
50525062
.desc_size = sizeof(struct mtk_tx_dma),
50535063
.dma_max_len = MTK_TX_DMA_BUF_LEN,
50545064
.dma_len_offset = 16,
5065+
.dma_size = MTK_DMA_SIZE(2K),
5066+
.fq_dma_size = MTK_DMA_SIZE(2K),
50555067
},
50565068
.rx = {
50575069
.desc_size = sizeof(struct mtk_rx_dma),
50585070
.irq_done_mask = MTK_RX_DONE_INT,
50595071
.dma_l4_valid = RX_DMA_L4_VALID,
5072+
.dma_size = MTK_DMA_SIZE(2K),
50605073
.dma_max_len = MTK_TX_DMA_BUF_LEN,
50615074
.dma_len_offset = 16,
50625075
},
@@ -5076,11 +5089,14 @@ static const struct mtk_soc_data mt7621_data = {
50765089
.desc_size = sizeof(struct mtk_tx_dma),
50775090
.dma_max_len = MTK_TX_DMA_BUF_LEN,
50785091
.dma_len_offset = 16,
5092+
.dma_size = MTK_DMA_SIZE(2K),
5093+
.fq_dma_size = MTK_DMA_SIZE(2K),
50795094
},
50805095
.rx = {
50815096
.desc_size = sizeof(struct mtk_rx_dma),
50825097
.irq_done_mask = MTK_RX_DONE_INT,
50835098
.dma_l4_valid = RX_DMA_L4_VALID,
5099+
.dma_size = MTK_DMA_SIZE(2K),
50845100
.dma_max_len = MTK_TX_DMA_BUF_LEN,
50855101
.dma_len_offset = 16,
50865102
},
@@ -5102,11 +5118,14 @@ static const struct mtk_soc_data mt7622_data = {
51025118
.desc_size = sizeof(struct mtk_tx_dma),
51035119
.dma_max_len = MTK_TX_DMA_BUF_LEN,
51045120
.dma_len_offset = 16,
5121+
.dma_size = MTK_DMA_SIZE(2K),
5122+
.fq_dma_size = MTK_DMA_SIZE(2K),
51055123
},
51065124
.rx = {
51075125
.desc_size = sizeof(struct mtk_rx_dma),
51085126
.irq_done_mask = MTK_RX_DONE_INT,
51095127
.dma_l4_valid = RX_DMA_L4_VALID,
5128+
.dma_size = MTK_DMA_SIZE(2K),
51105129
.dma_max_len = MTK_TX_DMA_BUF_LEN,
51115130
.dma_len_offset = 16,
51125131
},
@@ -5127,11 +5146,14 @@ static const struct mtk_soc_data mt7623_data = {
51275146
.desc_size = sizeof(struct mtk_tx_dma),
51285147
.dma_max_len = MTK_TX_DMA_BUF_LEN,
51295148
.dma_len_offset = 16,
5149+
.dma_size = MTK_DMA_SIZE(2K),
5150+
.fq_dma_size = MTK_DMA_SIZE(2K),
51305151
},
51315152
.rx = {
51325153
.desc_size = sizeof(struct mtk_rx_dma),
51335154
.irq_done_mask = MTK_RX_DONE_INT,
51345155
.dma_l4_valid = RX_DMA_L4_VALID,
5156+
.dma_size = MTK_DMA_SIZE(2K),
51355157
.dma_max_len = MTK_TX_DMA_BUF_LEN,
51365158
.dma_len_offset = 16,
51375159
},
@@ -5150,11 +5172,14 @@ static const struct mtk_soc_data mt7629_data = {
51505172
.desc_size = sizeof(struct mtk_tx_dma),
51515173
.dma_max_len = MTK_TX_DMA_BUF_LEN,
51525174
.dma_len_offset = 16,
5175+
.dma_size = MTK_DMA_SIZE(2K),
5176+
.fq_dma_size = MTK_DMA_SIZE(2K),
51535177
},
51545178
.rx = {
51555179
.desc_size = sizeof(struct mtk_rx_dma),
51565180
.irq_done_mask = MTK_RX_DONE_INT,
51575181
.dma_l4_valid = RX_DMA_L4_VALID,
5182+
.dma_size = MTK_DMA_SIZE(2K),
51585183
.dma_max_len = MTK_TX_DMA_BUF_LEN,
51595184
.dma_len_offset = 16,
51605185
},
@@ -5176,13 +5201,16 @@ static const struct mtk_soc_data mt7981_data = {
51765201
.desc_size = sizeof(struct mtk_tx_dma_v2),
51775202
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
51785203
.dma_len_offset = 8,
5204+
.dma_size = MTK_DMA_SIZE(2K),
5205+
.fq_dma_size = MTK_DMA_SIZE(2K),
51795206
},
51805207
.rx = {
51815208
.desc_size = sizeof(struct mtk_rx_dma),
51825209
.irq_done_mask = MTK_RX_DONE_INT,
51835210
.dma_l4_valid = RX_DMA_L4_VALID_V2,
51845211
.dma_max_len = MTK_TX_DMA_BUF_LEN,
51855212
.dma_len_offset = 16,
5213+
.dma_size = MTK_DMA_SIZE(2K),
51865214
},
51875215
};
51885216

@@ -5202,13 +5230,16 @@ static const struct mtk_soc_data mt7986_data = {
52025230
.desc_size = sizeof(struct mtk_tx_dma_v2),
52035231
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
52045232
.dma_len_offset = 8,
5233+
.dma_size = MTK_DMA_SIZE(2K),
5234+
.fq_dma_size = MTK_DMA_SIZE(2K),
52055235
},
52065236
.rx = {
52075237
.desc_size = sizeof(struct mtk_rx_dma),
52085238
.irq_done_mask = MTK_RX_DONE_INT,
52095239
.dma_l4_valid = RX_DMA_L4_VALID_V2,
52105240
.dma_max_len = MTK_TX_DMA_BUF_LEN,
52115241
.dma_len_offset = 16,
5242+
.dma_size = MTK_DMA_SIZE(2K),
52125243
},
52135244
};
52145245

@@ -5228,13 +5259,16 @@ static const struct mtk_soc_data mt7988_data = {
52285259
.desc_size = sizeof(struct mtk_tx_dma_v2),
52295260
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
52305261
.dma_len_offset = 8,
5262+
.dma_size = MTK_DMA_SIZE(2K),
5263+
.fq_dma_size = MTK_DMA_SIZE(4K),
52315264
},
52325265
.rx = {
52335266
.desc_size = sizeof(struct mtk_rx_dma_v2),
52345267
.irq_done_mask = MTK_RX_DONE_INT_V2,
52355268
.dma_l4_valid = RX_DMA_L4_VALID_V2,
52365269
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
52375270
.dma_len_offset = 8,
5271+
.dma_size = MTK_DMA_SIZE(2K),
52385272
},
52395273
};
52405274

@@ -5249,13 +5283,15 @@ static const struct mtk_soc_data rt5350_data = {
52495283
.desc_size = sizeof(struct mtk_tx_dma),
52505284
.dma_max_len = MTK_TX_DMA_BUF_LEN,
52515285
.dma_len_offset = 16,
5286+
.dma_size = MTK_DMA_SIZE(2K),
52525287
},
52535288
.rx = {
52545289
.desc_size = sizeof(struct mtk_rx_dma),
52555290
.irq_done_mask = MTK_RX_DONE_INT,
52565291
.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
52575292
.dma_max_len = MTK_TX_DMA_BUF_LEN,
52585293
.dma_len_offset = 16,
5294+
.dma_size = MTK_DMA_SIZE(2K),
52595295
},
52605296
};
52615297

drivers/net/ethernet/mediatek/mtk_eth_soc.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
#define MTK_TX_DMA_BUF_LEN 0x3fff
3333
#define MTK_TX_DMA_BUF_LEN_V2 0xffff
3434
#define MTK_QDMA_RING_SIZE 2048
35-
#define MTK_DMA_SIZE 512
35+
#define MTK_DMA_SIZE(x) (SZ_##x)
36+
#define MTK_FQ_DMA_HEAD 32
37+
#define MTK_FQ_DMA_LENGTH 2048
3638
#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN)
3739
#define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
3840
#define MTK_DMA_DUMMY_DESC 0xffffffff
@@ -1176,13 +1178,16 @@ struct mtk_soc_data {
11761178
u32 desc_size;
11771179
u32 dma_max_len;
11781180
u32 dma_len_offset;
1181+
u32 dma_size;
1182+
u32 fq_dma_size;
11791183
} tx;
11801184
struct {
11811185
u32 desc_size;
11821186
u32 irq_done_mask;
11831187
u32 dma_l4_valid;
11841188
u32 dma_max_len;
11851189
u32 dma_len_offset;
1190+
u32 dma_size;
11861191
} rx;
11871192
};
11881193

@@ -1264,7 +1269,7 @@ struct mtk_eth {
12641269
struct napi_struct rx_napi;
12651270
void *scratch_ring;
12661271
dma_addr_t phy_scratch_ring;
1267-
void *scratch_head;
1272+
void *scratch_head[MTK_FQ_DMA_HEAD];
12681273
struct clk *clks[MTK_CLK_MAX];
12691274

12701275
struct mii_bus *mii_bus;

0 commit comments

Comments
 (0)