Commit bfaf91ca authored by Joakim Zhang's avatar Joakim Zhang Committed by Jakub Kicinski

net: stmmac: fix dma physical address of descriptor when display ring

Driver uses dma_alloc_coherent to allocate dma memory for descriptors,
dma_alloc_coherent will return both the virtual address and physical
address. AFAIK, virt_to_phys could not convert virtual address to
physical address, for which memory is allocated by dma_alloc_coherent.

dwmac4_display_ring() function is broken for various descriptor, it only
support normal descriptor(struct dma_desc) now, this patch also extends to
support all descriptor types.
Signed-off-by: default avatarJoakim Zhang <qiangqing.zhang@nxp.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c511819d
...@@ -402,19 +402,53 @@ static void dwmac4_rd_set_tx_ic(struct dma_desc *p) ...@@ -402,19 +402,53 @@ static void dwmac4_rd_set_tx_ic(struct dma_desc *p)
p->des2 |= cpu_to_le32(TDES2_INTERRUPT_ON_COMPLETION); p->des2 |= cpu_to_le32(TDES2_INTERRUPT_ON_COMPLETION);
} }
static void dwmac4_display_ring(void *head, unsigned int size, bool rx) static void dwmac4_display_ring(void *head, unsigned int size, bool rx,
dma_addr_t dma_rx_phy, unsigned int desc_size)
{ {
struct dma_desc *p = (struct dma_desc *)head; dma_addr_t dma_addr;
int i; int i;
pr_info("%s descriptor ring:\n", rx ? "RX" : "TX"); pr_info("%s descriptor ring:\n", rx ? "RX" : "TX");
for (i = 0; i < size; i++) { if (desc_size == sizeof(struct dma_desc)) {
pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", struct dma_desc *p = (struct dma_desc *)head;
i, (unsigned int)virt_to_phys(p),
le32_to_cpu(p->des0), le32_to_cpu(p->des1), for (i = 0; i < size; i++) {
le32_to_cpu(p->des2), le32_to_cpu(p->des3)); dma_addr = dma_rx_phy + i * sizeof(*p);
p++; pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x\n",
i, &dma_addr,
le32_to_cpu(p->des0), le32_to_cpu(p->des1),
le32_to_cpu(p->des2), le32_to_cpu(p->des3));
p++;
}
} else if (desc_size == sizeof(struct dma_extended_desc)) {
struct dma_extended_desc *extp = (struct dma_extended_desc *)head;
for (i = 0; i < size; i++) {
dma_addr = dma_rx_phy + i * sizeof(*extp);
pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
i, &dma_addr,
le32_to_cpu(extp->basic.des0), le32_to_cpu(extp->basic.des1),
le32_to_cpu(extp->basic.des2), le32_to_cpu(extp->basic.des3),
le32_to_cpu(extp->des4), le32_to_cpu(extp->des5),
le32_to_cpu(extp->des6), le32_to_cpu(extp->des7));
extp++;
}
} else if (desc_size == sizeof(struct dma_edesc)) {
struct dma_edesc *ep = (struct dma_edesc *)head;
for (i = 0; i < size; i++) {
dma_addr = dma_rx_phy + i * sizeof(*ep);
pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
i, &dma_addr,
le32_to_cpu(ep->des4), le32_to_cpu(ep->des5),
le32_to_cpu(ep->des6), le32_to_cpu(ep->des7),
le32_to_cpu(ep->basic.des0), le32_to_cpu(ep->basic.des1),
le32_to_cpu(ep->basic.des2), le32_to_cpu(ep->basic.des3));
ep++;
}
} else {
pr_err("unsupported descriptor!");
} }
} }
......
...@@ -417,19 +417,22 @@ static int enh_desc_get_rx_timestamp_status(void *desc, void *next_desc, ...@@ -417,19 +417,22 @@ static int enh_desc_get_rx_timestamp_status(void *desc, void *next_desc,
} }
} }
static void enh_desc_display_ring(void *head, unsigned int size, bool rx) static void enh_desc_display_ring(void *head, unsigned int size, bool rx,
dma_addr_t dma_rx_phy, unsigned int desc_size)
{ {
struct dma_extended_desc *ep = (struct dma_extended_desc *)head; struct dma_extended_desc *ep = (struct dma_extended_desc *)head;
dma_addr_t dma_addr;
int i; int i;
pr_info("Extended %s descriptor ring:\n", rx ? "RX" : "TX"); pr_info("Extended %s descriptor ring:\n", rx ? "RX" : "TX");
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
u64 x; u64 x;
dma_addr = dma_rx_phy + i * sizeof(*ep);
x = *(u64 *)ep; x = *(u64 *)ep;
pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x\n",
i, (unsigned int)virt_to_phys(ep), i, &dma_addr,
(unsigned int)x, (unsigned int)(x >> 32), (unsigned int)x, (unsigned int)(x >> 32),
ep->basic.des2, ep->basic.des3); ep->basic.des2, ep->basic.des3);
ep++; ep++;
......
...@@ -78,7 +78,8 @@ struct stmmac_desc_ops { ...@@ -78,7 +78,8 @@ struct stmmac_desc_ops {
/* get rx timestamp status */ /* get rx timestamp status */
int (*get_rx_timestamp_status)(void *desc, void *next_desc, u32 ats); int (*get_rx_timestamp_status)(void *desc, void *next_desc, u32 ats);
/* Display ring */ /* Display ring */
void (*display_ring)(void *head, unsigned int size, bool rx); void (*display_ring)(void *head, unsigned int size, bool rx,
dma_addr_t dma_rx_phy, unsigned int desc_size);
/* set MSS via context descriptor */ /* set MSS via context descriptor */
void (*set_mss)(struct dma_desc *p, unsigned int mss); void (*set_mss)(struct dma_desc *p, unsigned int mss);
/* get descriptor skbuff address */ /* get descriptor skbuff address */
......
...@@ -269,19 +269,22 @@ static int ndesc_get_rx_timestamp_status(void *desc, void *next_desc, u32 ats) ...@@ -269,19 +269,22 @@ static int ndesc_get_rx_timestamp_status(void *desc, void *next_desc, u32 ats)
return 1; return 1;
} }
static void ndesc_display_ring(void *head, unsigned int size, bool rx) static void ndesc_display_ring(void *head, unsigned int size, bool rx,
dma_addr_t dma_rx_phy, unsigned int desc_size)
{ {
struct dma_desc *p = (struct dma_desc *)head; struct dma_desc *p = (struct dma_desc *)head;
dma_addr_t dma_addr;
int i; int i;
pr_info("%s descriptor ring:\n", rx ? "RX" : "TX"); pr_info("%s descriptor ring:\n", rx ? "RX" : "TX");
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
u64 x; u64 x;
dma_addr = dma_rx_phy + i * sizeof(*p);
x = *(u64 *)p; x = *(u64 *)p;
pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x", pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x",
i, (unsigned int)virt_to_phys(p), i, &dma_addr,
(unsigned int)x, (unsigned int)(x >> 32), (unsigned int)x, (unsigned int)(x >> 32),
p->des2, p->des3); p->des2, p->des3);
p++; p++;
......
...@@ -1133,6 +1133,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv) ...@@ -1133,6 +1133,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
static void stmmac_display_rx_rings(struct stmmac_priv *priv) static void stmmac_display_rx_rings(struct stmmac_priv *priv)
{ {
u32 rx_cnt = priv->plat->rx_queues_to_use; u32 rx_cnt = priv->plat->rx_queues_to_use;
unsigned int desc_size;
void *head_rx; void *head_rx;
u32 queue; u32 queue;
...@@ -1142,19 +1143,24 @@ static void stmmac_display_rx_rings(struct stmmac_priv *priv) ...@@ -1142,19 +1143,24 @@ static void stmmac_display_rx_rings(struct stmmac_priv *priv)
pr_info("\tRX Queue %u rings\n", queue); pr_info("\tRX Queue %u rings\n", queue);
if (priv->extend_desc) if (priv->extend_desc) {
head_rx = (void *)rx_q->dma_erx; head_rx = (void *)rx_q->dma_erx;
else desc_size = sizeof(struct dma_extended_desc);
} else {
head_rx = (void *)rx_q->dma_rx; head_rx = (void *)rx_q->dma_rx;
desc_size = sizeof(struct dma_desc);
}
/* Display RX ring */ /* Display RX ring */
stmmac_display_ring(priv, head_rx, priv->dma_rx_size, true); stmmac_display_ring(priv, head_rx, priv->dma_rx_size, true,
rx_q->dma_rx_phy, desc_size);
} }
} }
static void stmmac_display_tx_rings(struct stmmac_priv *priv) static void stmmac_display_tx_rings(struct stmmac_priv *priv)
{ {
u32 tx_cnt = priv->plat->tx_queues_to_use; u32 tx_cnt = priv->plat->tx_queues_to_use;
unsigned int desc_size;
void *head_tx; void *head_tx;
u32 queue; u32 queue;
...@@ -1164,14 +1170,19 @@ static void stmmac_display_tx_rings(struct stmmac_priv *priv) ...@@ -1164,14 +1170,19 @@ static void stmmac_display_tx_rings(struct stmmac_priv *priv)
pr_info("\tTX Queue %d rings\n", queue); pr_info("\tTX Queue %d rings\n", queue);
if (priv->extend_desc) if (priv->extend_desc) {
head_tx = (void *)tx_q->dma_etx; head_tx = (void *)tx_q->dma_etx;
else if (tx_q->tbs & STMMAC_TBS_AVAIL) desc_size = sizeof(struct dma_extended_desc);
} else if (tx_q->tbs & STMMAC_TBS_AVAIL) {
head_tx = (void *)tx_q->dma_entx; head_tx = (void *)tx_q->dma_entx;
else desc_size = sizeof(struct dma_edesc);
} else {
head_tx = (void *)tx_q->dma_tx; head_tx = (void *)tx_q->dma_tx;
desc_size = sizeof(struct dma_desc);
}
stmmac_display_ring(priv, head_tx, priv->dma_tx_size, false); stmmac_display_ring(priv, head_tx, priv->dma_tx_size, false,
tx_q->dma_tx_phy, desc_size);
} }
} }
...@@ -3736,18 +3747,23 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) ...@@ -3736,18 +3747,23 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
unsigned int count = 0, error = 0, len = 0; unsigned int count = 0, error = 0, len = 0;
int status = 0, coe = priv->hw->rx_csum; int status = 0, coe = priv->hw->rx_csum;
unsigned int next_entry = rx_q->cur_rx; unsigned int next_entry = rx_q->cur_rx;
unsigned int desc_size;
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
if (netif_msg_rx_status(priv)) { if (netif_msg_rx_status(priv)) {
void *rx_head; void *rx_head;
netdev_dbg(priv->dev, "%s: descriptor ring:\n", __func__); netdev_dbg(priv->dev, "%s: descriptor ring:\n", __func__);
if (priv->extend_desc) if (priv->extend_desc) {
rx_head = (void *)rx_q->dma_erx; rx_head = (void *)rx_q->dma_erx;
else desc_size = sizeof(struct dma_extended_desc);
} else {
rx_head = (void *)rx_q->dma_rx; rx_head = (void *)rx_q->dma_rx;
desc_size = sizeof(struct dma_desc);
}
stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true); stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true,
rx_q->dma_rx_phy, desc_size);
} }
while (count < limit) { while (count < limit) {
unsigned int buf1_len = 0, buf2_len = 0; unsigned int buf1_len = 0, buf2_len = 0;
...@@ -4315,24 +4331,27 @@ static int stmmac_set_mac_address(struct net_device *ndev, void *addr) ...@@ -4315,24 +4331,27 @@ static int stmmac_set_mac_address(struct net_device *ndev, void *addr)
static struct dentry *stmmac_fs_dir; static struct dentry *stmmac_fs_dir;
static void sysfs_display_ring(void *head, int size, int extend_desc, static void sysfs_display_ring(void *head, int size, int extend_desc,
struct seq_file *seq) struct seq_file *seq, dma_addr_t dma_phy_addr)
{ {
int i; int i;
struct dma_extended_desc *ep = (struct dma_extended_desc *)head; struct dma_extended_desc *ep = (struct dma_extended_desc *)head;
struct dma_desc *p = (struct dma_desc *)head; struct dma_desc *p = (struct dma_desc *)head;
dma_addr_t dma_addr;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
if (extend_desc) { if (extend_desc) {
seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", dma_addr = dma_phy_addr + i * sizeof(*ep);
i, (unsigned int)virt_to_phys(ep), seq_printf(seq, "%d [%pad]: 0x%x 0x%x 0x%x 0x%x\n",
i, &dma_addr,
le32_to_cpu(ep->basic.des0), le32_to_cpu(ep->basic.des0),
le32_to_cpu(ep->basic.des1), le32_to_cpu(ep->basic.des1),
le32_to_cpu(ep->basic.des2), le32_to_cpu(ep->basic.des2),
le32_to_cpu(ep->basic.des3)); le32_to_cpu(ep->basic.des3));
ep++; ep++;
} else { } else {
seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", dma_addr = dma_phy_addr + i * sizeof(*p);
i, (unsigned int)virt_to_phys(p), seq_printf(seq, "%d [%pad]: 0x%x 0x%x 0x%x 0x%x\n",
i, &dma_addr,
le32_to_cpu(p->des0), le32_to_cpu(p->des1), le32_to_cpu(p->des0), le32_to_cpu(p->des1),
le32_to_cpu(p->des2), le32_to_cpu(p->des3)); le32_to_cpu(p->des2), le32_to_cpu(p->des3));
p++; p++;
...@@ -4360,11 +4379,11 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v) ...@@ -4360,11 +4379,11 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v)
if (priv->extend_desc) { if (priv->extend_desc) {
seq_printf(seq, "Extended descriptor ring:\n"); seq_printf(seq, "Extended descriptor ring:\n");
sysfs_display_ring((void *)rx_q->dma_erx, sysfs_display_ring((void *)rx_q->dma_erx,
priv->dma_rx_size, 1, seq); priv->dma_rx_size, 1, seq, rx_q->dma_rx_phy);
} else { } else {
seq_printf(seq, "Descriptor ring:\n"); seq_printf(seq, "Descriptor ring:\n");
sysfs_display_ring((void *)rx_q->dma_rx, sysfs_display_ring((void *)rx_q->dma_rx,
priv->dma_rx_size, 0, seq); priv->dma_rx_size, 0, seq, rx_q->dma_rx_phy);
} }
} }
...@@ -4376,11 +4395,11 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v) ...@@ -4376,11 +4395,11 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v)
if (priv->extend_desc) { if (priv->extend_desc) {
seq_printf(seq, "Extended descriptor ring:\n"); seq_printf(seq, "Extended descriptor ring:\n");
sysfs_display_ring((void *)tx_q->dma_etx, sysfs_display_ring((void *)tx_q->dma_etx,
priv->dma_tx_size, 1, seq); priv->dma_tx_size, 1, seq, tx_q->dma_tx_phy);
} else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) { } else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) {
seq_printf(seq, "Descriptor ring:\n"); seq_printf(seq, "Descriptor ring:\n");
sysfs_display_ring((void *)tx_q->dma_tx, sysfs_display_ring((void *)tx_q->dma_tx,
priv->dma_tx_size, 0, seq); priv->dma_tx_size, 0, seq, tx_q->dma_tx_phy);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment