Skip to content

Commit a993db8

Browse files
joabreudavem330
authored andcommitted
net: stmmac: Enable support for > 32 Bits addressing in XGMAC
Currently, stmmac only supports 32 bits addressing for SKB. Enable the support for upto 48 bits addressing in XGMAC core. This avoids the use of bounce buffers and increases performance. Changes from v1: - Fallback to 32 bits in failure (Andrew) Signed-off-by: Jose Abreu <[email protected]> Cc: Joao Pinto <[email protected]> Cc: David S. Miller <[email protected]> Cc: Giuseppe Cavallaro <[email protected]> Cc: Alexandre Torgue <[email protected]> Cc: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a66b588 commit a993db8

File tree

5 files changed

+66
-15
lines changed

5 files changed

+66
-15
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ struct dma_features {
351351
unsigned int frpsel;
352352
unsigned int frpbs;
353353
unsigned int frpes;
354+
unsigned int addr64;
354355
};
355356

356357
/* GMAC TX FIFO is 8K, Rx FIFO is 16K */

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
#define XGMAC_HWFEAT_GMIISEL BIT(1)
8888
#define XGMAC_HW_FEATURE1 0x00000120
8989
#define XGMAC_HWFEAT_TSOEN BIT(18)
90+
#define XGMAC_HWFEAT_ADDR64 GENMASK(15, 14)
9091
#define XGMAC_HWFEAT_TXFIFOSIZE GENMASK(10, 6)
9192
#define XGMAC_HWFEAT_RXFIFOSIZE GENMASK(4, 0)
9293
#define XGMAC_HW_FEATURE2 0x00000124
@@ -172,6 +173,7 @@
172173
#define XGMAC_EN_LPI BIT(15)
173174
#define XGMAC_LPI_XIT_PKT BIT(14)
174175
#define XGMAC_AAL BIT(12)
176+
#define XGMAC_EAME BIT(11)
175177
#define XGMAC_BLEN GENMASK(7, 1)
176178
#define XGMAC_BLEN256 BIT(7)
177179
#define XGMAC_BLEN128 BIT(6)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ static void dwxgmac2_get_addr(struct dma_desc *p, unsigned int *addr)
242242

243243
static void dwxgmac2_set_addr(struct dma_desc *p, dma_addr_t addr)
244244
{
245-
p->des0 = cpu_to_le32(addr);
246-
p->des1 = 0;
245+
p->des0 = cpu_to_le32(lower_32_bits(addr));
246+
p->des1 = cpu_to_le32(upper_32_bits(addr));
247247
}
248248

249249
static void dwxgmac2_clear(struct dma_desc *p)

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ static void dwxgmac2_dma_init(void __iomem *ioaddr,
2727
if (dma_cfg->aal)
2828
value |= XGMAC_AAL;
2929

30-
writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
30+
writel(value | XGMAC_EAME, ioaddr + XGMAC_DMA_SYSBUS_MODE);
3131
}
3232

3333
static void dwxgmac2_dma_init_chan(void __iomem *ioaddr,
@@ -361,6 +361,23 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
361361
/* MAC HW feature 1 */
362362
hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
363363
dma_cap->tsoen = (hw_cap & XGMAC_HWFEAT_TSOEN) >> 18;
364+
365+
dma_cap->addr64 = (hw_cap & XGMAC_HWFEAT_ADDR64) >> 14;
366+
switch (dma_cap->addr64) {
367+
case 0:
368+
dma_cap->addr64 = 32;
369+
break;
370+
case 1:
371+
dma_cap->addr64 = 40;
372+
break;
373+
case 2:
374+
dma_cap->addr64 = 48;
375+
break;
376+
default:
377+
dma_cap->addr64 = 32;
378+
break;
379+
}
380+
364381
dma_cap->tx_fifo_size =
365382
128 << ((hw_cap & XGMAC_HWFEAT_TXFIFOSIZE) >> 6);
366383
dma_cap->rx_fifo_size =

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

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2772,7 +2772,7 @@ static int stmmac_release(struct net_device *dev)
27722772
* This function fills descriptor and request new descriptors according to
27732773
* buffer length to fill
27742774
*/
2775-
static void stmmac_tso_allocator(struct stmmac_priv *priv, unsigned int des,
2775+
static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des,
27762776
int total_len, bool last_segment, u32 queue)
27772777
{
27782778
struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
@@ -2783,11 +2783,18 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, unsigned int des,
27832783
tmp_len = total_len;
27842784

27852785
while (tmp_len > 0) {
2786+
dma_addr_t curr_addr;
2787+
27862788
tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE);
27872789
WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
27882790
desc = tx_q->dma_tx + tx_q->cur_tx;
27892791

2790-
desc->des0 = cpu_to_le32(des + (total_len - tmp_len));
2792+
curr_addr = des + (total_len - tmp_len);
2793+
if (priv->dma_cap.addr64 <= 32)
2794+
desc->des0 = cpu_to_le32(curr_addr);
2795+
else
2796+
stmmac_set_desc_addr(priv, desc, curr_addr);
2797+
27912798
buff_size = tmp_len >= TSO_MAX_BUFF_SIZE ?
27922799
TSO_MAX_BUFF_SIZE : tmp_len;
27932800

@@ -2833,11 +2840,12 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
28332840
struct stmmac_priv *priv = netdev_priv(dev);
28342841
int nfrags = skb_shinfo(skb)->nr_frags;
28352842
u32 queue = skb_get_queue_mapping(skb);
2836-
unsigned int first_entry, des;
2843+
unsigned int first_entry;
28372844
struct stmmac_tx_queue *tx_q;
28382845
int tmp_pay_len = 0;
28392846
u32 pay_len, mss;
28402847
u8 proto_hdr_len;
2848+
dma_addr_t des;
28412849
int i;
28422850

28432851
tx_q = &priv->tx_queue[queue];
@@ -2894,14 +2902,19 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
28942902
tx_q->tx_skbuff_dma[first_entry].buf = des;
28952903
tx_q->tx_skbuff_dma[first_entry].len = skb_headlen(skb);
28962904

2897-
first->des0 = cpu_to_le32(des);
2905+
if (priv->dma_cap.addr64 <= 32) {
2906+
first->des0 = cpu_to_le32(des);
28982907

2899-
/* Fill start of payload in buff2 of first descriptor */
2900-
if (pay_len)
2901-
first->des1 = cpu_to_le32(des + proto_hdr_len);
2908+
/* Fill start of payload in buff2 of first descriptor */
2909+
if (pay_len)
2910+
first->des1 = cpu_to_le32(des + proto_hdr_len);
29022911

2903-
/* If needed take extra descriptors to fill the remaining payload */
2904-
tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
2912+
/* If needed take extra descriptors to fill the remaining payload */
2913+
tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
2914+
} else {
2915+
stmmac_set_desc_addr(priv, first, des);
2916+
tmp_pay_len = pay_len;
2917+
}
29052918

29062919
stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
29072920

@@ -3031,12 +3044,12 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
30313044
int i, csum_insertion = 0, is_jumbo = 0;
30323045
u32 queue = skb_get_queue_mapping(skb);
30333046
int nfrags = skb_shinfo(skb)->nr_frags;
3034-
int entry;
3035-
unsigned int first_entry;
30363047
struct dma_desc *desc, *first;
30373048
struct stmmac_tx_queue *tx_q;
3049+
unsigned int first_entry;
30383050
unsigned int enh_desc;
3039-
unsigned int des;
3051+
dma_addr_t des;
3052+
int entry;
30403053

30413054
tx_q = &priv->tx_queue[queue];
30423055

@@ -4316,6 +4329,24 @@ int stmmac_dvr_probe(struct device *device,
43164329
priv->tso = true;
43174330
dev_info(priv->device, "TSO feature enabled\n");
43184331
}
4332+
4333+
if (priv->dma_cap.addr64) {
4334+
ret = dma_set_mask_and_coherent(device,
4335+
DMA_BIT_MASK(priv->dma_cap.addr64));
4336+
if (!ret) {
4337+
dev_info(priv->device, "Using %d bits DMA width\n",
4338+
priv->dma_cap.addr64);
4339+
} else {
4340+
ret = dma_set_mask_and_coherent(device, DMA_BIT_MASK(32));
4341+
if (ret) {
4342+
dev_err(priv->device, "Failed to set DMA Mask\n");
4343+
goto error_hw_init;
4344+
}
4345+
4346+
priv->dma_cap.addr64 = 32;
4347+
}
4348+
}
4349+
43194350
ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
43204351
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
43214352
#ifdef STMMAC_VLAN_TAG_USED

0 commit comments

Comments
 (0)