net: stmmac: dump gmac4 DMA registers correctly
Unlike gmac100, gmac1000, gmac4 has 27 DMA registers and they are
located at DMA_CHAN_BASE_ADDR (0x1100). In order for ethtool to dump
gmac4 DMA registers correctly, this commit checks if a net_device has
gmac4 and uses different logic to dump its DMA registers.
This fixes the following KASAN warning, which can normally be triggered
by a command similar like "ethtool -d eth0":
BUG: KASAN: vmalloc-out-of-bounds in dwmac4_dump_dma_regs+0x6d4/0xb30
Write of size 4 at addr ffffffc010177100 by task ethtool/1839
kasan_report+0x200/0x21c
__asan_report_store4_noabort+0x34/0x60
dwmac4_dump_dma_regs+0x6d4/0xb30
stmmac_ethtool_gregs+0x110/0x204
ethtool_get_regs+0x200/0x4b0
dev_ethtool+0x1dac/0x3800
dev_ioctl+0x7c0/0xb50
sock_ioctl+0x298/0x6c4
...
Fixes: fbf68229ff
("net: stmmac: unify registers dumps methods")
Signed-off-by: Camel Guo <camelg@axis.com>
Link: https://lore.kernel.org/r/20220131083841.3346801-1-camel.guo@axis.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
4223f86512
commit
7af037c39b
|
@ -150,6 +150,7 @@
|
||||||
|
|
||||||
#define NUM_DWMAC100_DMA_REGS 9
|
#define NUM_DWMAC100_DMA_REGS 9
|
||||||
#define NUM_DWMAC1000_DMA_REGS 23
|
#define NUM_DWMAC1000_DMA_REGS 23
|
||||||
|
#define NUM_DWMAC4_DMA_REGS 27
|
||||||
|
|
||||||
void dwmac_enable_dma_transmission(void __iomem *ioaddr);
|
void dwmac_enable_dma_transmission(void __iomem *ioaddr);
|
||||||
void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx);
|
void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx);
|
||||||
|
|
|
@ -21,10 +21,18 @@
|
||||||
#include "dwxgmac2.h"
|
#include "dwxgmac2.h"
|
||||||
|
|
||||||
#define REG_SPACE_SIZE 0x1060
|
#define REG_SPACE_SIZE 0x1060
|
||||||
|
#define GMAC4_REG_SPACE_SIZE 0x116C
|
||||||
#define MAC100_ETHTOOL_NAME "st_mac100"
|
#define MAC100_ETHTOOL_NAME "st_mac100"
|
||||||
#define GMAC_ETHTOOL_NAME "st_gmac"
|
#define GMAC_ETHTOOL_NAME "st_gmac"
|
||||||
#define XGMAC_ETHTOOL_NAME "st_xgmac"
|
#define XGMAC_ETHTOOL_NAME "st_xgmac"
|
||||||
|
|
||||||
|
/* Same as DMA_CHAN_BASE_ADDR defined in dwmac4_dma.h
|
||||||
|
*
|
||||||
|
* It is here because dwmac_dma.h and dwmac4_dam.h can not be included at the
|
||||||
|
* same time due to the conflicting macro names.
|
||||||
|
*/
|
||||||
|
#define GMAC4_DMA_CHAN_BASE_ADDR 0x00001100
|
||||||
|
|
||||||
#define ETHTOOL_DMA_OFFSET 55
|
#define ETHTOOL_DMA_OFFSET 55
|
||||||
|
|
||||||
struct stmmac_stats {
|
struct stmmac_stats {
|
||||||
|
@ -434,6 +442,8 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev)
|
||||||
|
|
||||||
if (priv->plat->has_xgmac)
|
if (priv->plat->has_xgmac)
|
||||||
return XGMAC_REGSIZE * 4;
|
return XGMAC_REGSIZE * 4;
|
||||||
|
else if (priv->plat->has_gmac4)
|
||||||
|
return GMAC4_REG_SPACE_SIZE;
|
||||||
return REG_SPACE_SIZE;
|
return REG_SPACE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,8 +456,13 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
|
||||||
stmmac_dump_mac_regs(priv, priv->hw, reg_space);
|
stmmac_dump_mac_regs(priv, priv->hw, reg_space);
|
||||||
stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
|
stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
|
||||||
|
|
||||||
if (!priv->plat->has_xgmac) {
|
/* Copy DMA registers to where ethtool expects them */
|
||||||
/* Copy DMA registers to where ethtool expects them */
|
if (priv->plat->has_gmac4) {
|
||||||
|
/* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */
|
||||||
|
memcpy(®_space[ETHTOOL_DMA_OFFSET],
|
||||||
|
®_space[GMAC4_DMA_CHAN_BASE_ADDR / 4],
|
||||||
|
NUM_DWMAC4_DMA_REGS * 4);
|
||||||
|
} else if (!priv->plat->has_xgmac) {
|
||||||
memcpy(®_space[ETHTOOL_DMA_OFFSET],
|
memcpy(®_space[ETHTOOL_DMA_OFFSET],
|
||||||
®_space[DMA_BUS_MODE / 4],
|
®_space[DMA_BUS_MODE / 4],
|
||||||
NUM_DWMAC1000_DMA_REGS * 4);
|
NUM_DWMAC1000_DMA_REGS * 4);
|
||||||
|
|
Loading…
Reference in New Issue