* [PATCH 1/1] net: phylib: remove the length limitation of mii bus id
From: Dong Aisheng @ 2012-03-20 4:23 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-kernel, linux-arm-kernel
From: Dong Aisheng <dong.aisheng@linaro.org>
When convert to dt, the length of old mii bus id (17 bytes) is not
sufficent to use.
For example, the bus id could be 800f0000.ethernet-1:00 in DT.
This patch removes the bus id length limitation by changing the
bus id to a const char pionter and user could dynamically set the
bus id via kasprintf function call.
Since then no users use MII_BUS_ID_SIZE any more, just remove it.
Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
---
The simplest way may just change MII_BUS_ID_SIZE to a more bigger size,
but i'm not sure that's gonna be accepted.
So changed to remove the bus id length limitation, a lot of handwork.
Since this patch changes a lot of other ethernet drivers and i did
not have condition to test it, need each corresponding driver owners
to help review.
I just greped the macro MII_BUS_ID_SIZE in the latest kernel tree and
did the replacement.
In case any one missed(may not use MII_BUS_ID_SIZE), that driver owner
should help change it.
Only tested the fec driver on i.MX28 EVK board.
---
arch/powerpc/platforms/82xx/ep8248e.c | 2 +-
arch/powerpc/platforms/pasemi/gpio_mdio.c | 2 +-
drivers/net/ethernet/8390/ax88796.c | 4 +---
drivers/net/ethernet/adi/bfin_mac.c | 3 +--
drivers/net/ethernet/aeroflex/greth.c | 2 +-
drivers/net/ethernet/amd/au1000_eth.c | 3 +--
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 10 +++++-----
drivers/net/ethernet/broadcom/sb1250-mac.c | 2 +-
drivers/net/ethernet/broadcom/tg3.c | 4 ++--
drivers/net/ethernet/cadence/macb.c | 2 +-
drivers/net/ethernet/dnet.c | 2 +-
drivers/net/ethernet/ethoc.c | 2 +-
drivers/net/ethernet/faraday/ftgmac100.c | 2 +-
drivers/net/ethernet/freescale/fec.c | 16 +++++++++-------
drivers/net/ethernet/freescale/fec_mpc52xx_phy.c | 2 +-
.../net/ethernet/freescale/fs_enet/mii-bitbang.c | 2 +-
drivers/net/ethernet/freescale/fs_enet/mii-fec.c | 2 +-
drivers/net/ethernet/freescale/fsl_pq_mdio.c | 6 +++---
drivers/net/ethernet/freescale/fsl_pq_mdio.h | 2 +-
drivers/net/ethernet/lantiq_etop.c | 2 +-
drivers/net/ethernet/marvell/mv643xx_eth.c | 2 +-
drivers/net/ethernet/marvell/pxa168_eth.c | 2 +-
drivers/net/ethernet/rdc/r6040.c | 4 ++--
drivers/net/ethernet/renesas/sh_eth.c | 7 ++++---
drivers/net/ethernet/s6gmac.c | 2 +-
drivers/net/ethernet/smsc/smsc911x.c | 4 ++--
drivers/net/ethernet/smsc/smsc9420.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 ++++++----
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 4 ++--
drivers/net/ethernet/ti/cpmac.c | 16 ++++++++--------
drivers/net/ethernet/ti/davinci_mdio.c | 4 ++--
drivers/net/ethernet/toshiba/tc35815.c | 2 +-
drivers/net/ethernet/xilinx/ll_temac_mdio.c | 2 +-
drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +-
drivers/net/ethernet/xscale/ixp4xx_eth.c | 7 ++++---
drivers/net/phy/fixed.c | 2 +-
drivers/net/phy/mdio-gpio.c | 2 +-
drivers/net/phy/mdio-octeon.c | 2 +-
drivers/net/phy/phy_device.c | 2 +-
drivers/of/of_mdio.c | 5 +++--
drivers/staging/et131x/et131x.c | 2 +-
include/linux/phy.h | 10 ++--------
net/dsa/slave.c | 2 +-
43 files changed, 83 insertions(+), 86 deletions(-)
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index 10ff526..21658de 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -139,7 +139,7 @@ static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev)
bus->name = "ep8248e-mdio-bitbang";
bus->parent = &ofdev->dev;
- snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ bus->id = kasprintf(GFP_KERNEL, "%x", res.start);
ret = of_mdiobus_register(bus, ofdev->dev.of_node);
if (ret)
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index 9886296..3b55962 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -241,7 +241,7 @@ static int __devinit gpio_mdio_probe(struct platform_device *ofdev)
new_bus->reset = &gpio_mdio_reset;
prop = of_get_property(np, "reg", NULL);
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
+ new_bus->id = kasprintf(GFP_KERNEL, "%x", *prop);
new_bus->priv = priv;
new_bus->irq = priv->mdio_irqs;
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
index 0f92e35..c70067c 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -623,9 +623,7 @@ static int ax_mii_init(struct net_device *dev)
ax->mii_bus->name = "ax88796_mii_bus";
ax->mii_bus->parent = dev->dev.parent;
- snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, pdev->id);
-
+ ax->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x", pdev->name, pdev->id);
ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
if (!ax->mii_bus->irq) {
err = -ENOMEM;
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index d812a10..77d473a 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -1670,8 +1670,7 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev)
miibus->name = "bfin_mii_bus";
miibus->phy_mask = mii_bus_pd->phy_mask;
- snprintf(miibus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, pdev->id);
+ miibus->id = kasprintf(GFP_KERNEL, "%s-%x", pdev->name, pdev->id);
miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
if (!miibus->irq)
goto out_err_irq_alloc;
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
index c885aa9..df635f2 100644
--- a/drivers/net/ethernet/aeroflex/greth.c
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -1332,7 +1332,7 @@ static int greth_mdio_init(struct greth_private *greth)
}
greth->mdio->name = "greth-mdio";
- snprintf(greth->mdio->id, MII_BUS_ID_SIZE, "%s-%d", greth->mdio->name, greth->irq);
+ greth->mdio->id = kasprintf(GFP_KERNEL, "%s-%d", greth->mdio->name, greth->irq);
greth->mdio->read = greth_mdio_read;
greth->mdio->write = greth_mdio_write;
greth->mdio->reset = greth_mdio_reset;
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 8b95dd3..99e0ebb 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -1171,8 +1171,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
aup->mii_bus->write = au1000_mdiobus_write;
aup->mii_bus->reset = au1000_mdiobus_reset;
aup->mii_bus->name = "au1000_eth_mii";
- snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, aup->mac_id);
+ aup->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x", pdev->name, aup->mac_id);
aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
if (aup->mii_bus->irq == NULL)
goto err_out;
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index 986019b..8118878 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -787,7 +787,7 @@ static int bcm_enet_open(struct net_device *dev)
struct phy_device *phydev;
int i, ret;
unsigned int size;
- char phy_id[MII_BUS_ID_SIZE + 3];
+ const char *phy_id;
void *p;
u32 val;
@@ -796,12 +796,12 @@ static int bcm_enet_open(struct net_device *dev)
if (priv->has_phy) {
/* connect to PHY */
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
- priv->mac_id ? "1" : "0", priv->phy_id);
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT,
+ priv->mac_id ? "1" : "0", priv->phy_id);
phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0,
PHY_INTERFACE_MODE_MII);
-
+ kfree(phy_id);
if (IS_ERR(phydev)) {
dev_err(kdev, "could not attach to PHY\n");
return PTR_ERR(phydev);
@@ -1727,7 +1727,7 @@ static int __devinit bcm_enet_probe(struct platform_device *pdev)
bus->priv = priv;
bus->read = bcm_enet_mdio_read_phylib;
bus->write = bcm_enet_mdio_write_phylib;
- sprintf(bus->id, "%s-%d", pdev->name, priv->mac_id);
+ bus->id = kasprintf(GFP_KERNEL, "%s-%d", pdev->name, priv->mac_id);
/* only probe bus where we think the PHY is, because
* the mdio read operation return 0 instead of 0xffff
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c
index 084904c..7fd5654 100644
--- a/drivers/net/ethernet/broadcom/sb1250-mac.c
+++ b/drivers/net/ethernet/broadcom/sb1250-mac.c
@@ -2259,7 +2259,7 @@ static int sbmac_init(struct platform_device *pldev, long long base)
}
sc->mii_bus->name = sbmac_mdio_string;
- snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ sc->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
pldev->name, idx);
sc->mii_bus->priv = sc;
sc->mii_bus->read = sbmac_mii_read;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index d529af9..2750e49 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -1328,8 +1328,8 @@ static int tg3_mdio_init(struct tg3 *tp)
return -ENOMEM;
tp->mdio_bus->name = "tg3 mdio bus";
- snprintf(tp->mdio_bus->id, MII_BUS_ID_SIZE, "%x",
- (tp->pdev->bus->number << 8) | tp->pdev->devfn);
+ tp->mdio_bus->id = kasprintf(GFP_KERNEL, "%x",
+ (tp->pdev->bus->number << 8) | tp->pdev->devfn);
tp->mdio_bus->priv = tp;
tp->mdio_bus->parent = &tp->pdev->dev;
tp->mdio_bus->read = &tg3_mdio_read;
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 2320068..62e4465 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -243,7 +243,7 @@ static int macb_mii_init(struct macb *bp)
bp->mii_bus->read = &macb_mdio_read;
bp->mii_bus->write = &macb_mdio_write;
bp->mii_bus->reset = &macb_mdio_reset;
- snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ bp->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
bp->pdev->name, bp->pdev->id);
bp->mii_bus->priv = bp;
bp->mii_bus->parent = &bp->dev->dev;
diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c
index 925c9ba..18c3c92 100644
--- a/drivers/net/ethernet/dnet.c
+++ b/drivers/net/ethernet/dnet.c
@@ -325,7 +325,7 @@ static int dnet_mii_init(struct dnet *bp)
bp->mii_bus->write = &dnet_mdio_write;
bp->mii_bus->reset = &dnet_mdio_reset;
- snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ bp->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
bp->pdev->name, bp->pdev->id);
bp->mii_bus->priv = bp;
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index 60f0e78..e9195a5 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -1063,7 +1063,7 @@ static int __devinit ethoc_probe(struct platform_device *pdev)
}
priv->mdio->name = "ethoc-mdio";
- snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "%s-%d",
+ priv->mdio->id = kasprintf(GFP_KERNEL, "%s-%d",
priv->mdio->name, pdev->id);
priv->mdio->read = ethoc_mdio_read;
priv->mdio->write = ethoc_mdio_write;
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index fb5579a..af418cd 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -1255,7 +1255,7 @@ static int ftgmac100_probe(struct platform_device *pdev)
}
priv->mii_bus->name = "ftgmac100_mdio";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "ftgmac100_mii");
+ priv->mii_bus->id = kstrdup("ftgmac100_mii", GFP_KERNEL);
priv->mii_bus->priv = netdev;
priv->mii_bus->read = ftgmac100_mdiobus_read;
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 7b25e9c..6e82c2d 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -961,8 +961,8 @@ static int fec_enet_mii_probe(struct net_device *ndev)
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
struct phy_device *phy_dev = NULL;
- char mdio_bus_id[MII_BUS_ID_SIZE];
- char phy_name[MII_BUS_ID_SIZE + 3];
+ const char *mdio_bus_id;
+ const char *phy_name;
int phy_id;
int dev_id = fep->dev_id;
@@ -978,7 +978,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
continue;
if (dev_id--)
continue;
- strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
+ mdio_bus_id = kstrdup(fep->mii_bus->id, GFP_KERNEL);
break;
}
@@ -986,13 +986,15 @@ static int fec_enet_mii_probe(struct net_device *ndev)
printk(KERN_INFO
"%s: no PHY, assuming direct connection to switch\n",
ndev->name);
- strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE);
+ mdio_bus_id = kstrdup("0", GFP_KERNEL);
phy_id = 0;
}
- snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
+ phy_name= kasprintf(GFP_KERNEL, PHY_ID_FMT, mdio_bus_id, phy_id);
phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0,
fep->phy_interface);
+ kfree(mdio_bus_id);
+ kfree(phy_name);
if (IS_ERR(phy_dev)) {
printk(KERN_ERR "%s: could not attach to PHY\n", ndev->name);
return PTR_ERR(phy_dev);
@@ -1080,8 +1082,8 @@ static int fec_enet_mii_init(struct platform_device *pdev)
fep->mii_bus->read = fec_enet_mdio_read;
fep->mii_bus->write = fec_enet_mdio_write;
fep->mii_bus->reset = fec_enet_mdio_reset;
- snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, fep->dev_id + 1);
+ fep->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ pdev->name, fep->dev_id +1);
fep->mii_bus->priv = fep;
fep->mii_bus->parent = &pdev->dev;
diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
index 360a578..7724be7 100644
--- a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
+++ b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
@@ -96,7 +96,7 @@ static int mpc52xx_fec_mdio_probe(struct platform_device *of)
goto out_free;
}
- snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ bus->id = kasprintf(GFP_KERNEL, "%x", res.start);
bus->priv = priv;
bus->parent = dev;
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
index 0f2d1a7..9e6eac9 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
@@ -127,7 +127,7 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
* we get is an int, and the odds of multiple bitbang mdio buses
* is low enough that it's not worth going too crazy.
*/
- snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ bus->id = kasprintf(GFP_KERNEL, "%x", res.start);
data = of_get_property(np, "fsl,mdio-pin", &len);
if (!data || len != 4)
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
index 55bb867..5242f4d 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
@@ -134,7 +134,7 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev)
if (ret)
goto out_res;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ new_bus->id = kasprintf(GFP_KERNEL, "%x", res.start);
fec->fecp = ioremap(res.start, resource_size(&res));
if (!fec->fecp)
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
index 9eb8159..773acd5 100644
--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c
+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
@@ -169,7 +169,7 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
return 0;
}
-void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
+void fsl_pq_mdio_bus_name(char **name, struct device_node *np)
{
const u32 *addr;
u64 taddr = OF_BAD_ADDR;
@@ -178,7 +178,7 @@ void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
if (addr)
taddr = of_translate_address(np, addr);
- snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name,
+ *name = kasprintf(GFP_KERNEL, "%s@%llx", np->name,
(unsigned long long)taddr);
}
EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name);
@@ -277,7 +277,7 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev)
new_bus->write = &fsl_pq_mdio_write,
new_bus->reset = &fsl_pq_mdio_reset,
new_bus->priv = priv;
- fsl_pq_mdio_bus_name(new_bus->id, np);
+ fsl_pq_mdio_bus_name(&new_bus->id, np);
addrp = of_get_address(np, 0, &size, NULL);
if (!addrp) {
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.h b/drivers/net/ethernet/freescale/fsl_pq_mdio.h
index bd17a2a..b563ef7 100644
--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.h
+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.h
@@ -48,5 +48,5 @@ int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum);
int __init fsl_pq_mdio_init(void);
void fsl_pq_mdio_exit(void);
-void fsl_pq_mdio_bus_name(char *name, struct device_node *np);
+void fsl_pq_mdio_bus_name(char **name, struct device_node *np);
#endif /* FSL_PQ_MDIO_H */
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 85e2c6c..742e7dd 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -437,7 +437,7 @@ ltq_etop_mdio_init(struct net_device *dev)
priv->mii_bus->read = ltq_etop_mdio_rd;
priv->mii_bus->write = ltq_etop_mdio_wr;
priv->mii_bus->name = "ltq_mii";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ priv->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
priv->pdev->name, priv->pdev->id);
priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
if (!priv->mii_bus->irq) {
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 9c049d2..e18707f 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2613,7 +2613,7 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
msp->smi_bus->name = "mv643xx_eth smi";
msp->smi_bus->read = smi_bus_read;
msp->smi_bus->write = smi_bus_write,
- snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d",
+ msp->smi_bus->id = kasprintf(GFP_KERNEL, "%s-%d",
pdev->name, pdev->id);
msp->smi_bus->parent = &pdev->dev;
msp->smi_bus->phy_mask = 0xffffffff;
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 953ba58..bf19af7 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -1552,7 +1552,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
pep->smi_bus->name = "pxa168_eth smi";
pep->smi_bus->read = pxa168_smi_read;
pep->smi_bus->write = pxa168_smi_write;
- snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d",
+ pep->smi_bus->id = kasprintf(GFP_KERNEL, "%s-%d",
pdev->name, pdev->id);
pep->smi_bus->parent = &pdev->dev;
pep->smi_bus->phy_mask = 0xffffffff;
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index cb0eca8..9d890b2 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -1181,8 +1181,8 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
lp->mii_bus->write = r6040_mdiobus_write;
lp->mii_bus->reset = r6040_mdiobus_reset;
lp->mii_bus->name = "r6040_eth_mii";
- snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- dev_name(&pdev->dev), card_idx);
+ lp->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ dev_name(&pdev->dev), card_idx);
lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
if (!lp->mii_bus->irq) {
dev_err(&pdev->dev, "mii_bus irq allocation failed\n");
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 813d41c..3210fd9 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1213,10 +1213,10 @@ static void sh_eth_adjust_link(struct net_device *ndev)
static int sh_eth_phy_init(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- char phy_id[MII_BUS_ID_SIZE + 3];
+ const char *phy_id;
struct phy_device *phydev = NULL;
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT,
mdp->mii_bus->id , mdp->phy_id);
mdp->link = PHY_DOWN;
@@ -1226,6 +1226,7 @@ static int sh_eth_phy_init(struct net_device *ndev)
/* Try connect to PHY */
phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
0, mdp->phy_interface);
+ kfree(phy_id);
if (IS_ERR(phydev)) {
dev_err(&ndev->dev, "phy_connect failed\n");
return PTR_ERR(phydev);
@@ -1702,7 +1703,7 @@ static int sh_mdio_init(struct net_device *ndev, int id,
/* Hook up MII support for ethtool */
mdp->mii_bus->name = "sh_mii";
mdp->mii_bus->parent = &ndev->dev;
- snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ mdp->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
mdp->pdev->name, id);
/* PHY IRQ */
diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c
index 22e9c01..dd5f29b 100644
--- a/drivers/net/ethernet/s6gmac.c
+++ b/drivers/net/ethernet/s6gmac.c
@@ -1004,7 +1004,7 @@ static int __devinit s6gmac_probe(struct platform_device *pdev)
mb->write = s6mii_write;
mb->reset = s6mii_reset;
mb->priv = pd;
- snprintf(mb->id, MII_BUS_ID_SIZE, "%s-%x", pdev->name, pdev->id);
+ mb->id = kasprintf(GFP_KERNEL, "%s-%x", pdev->name, pdev->id);
mb->phy_mask = ~(1 << 0);
mb->irq = &pd->mii.irq[0];
for (i = 0; i < PHY_MAX_ADDR; i++) {
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 24d2df0..4aab696 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -1044,8 +1044,8 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
}
pdata->mii_bus->name = SMSC_MDIONAME;
- snprintf(pdata->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, pdev->id);
+ pdata->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ pdev->name, pdev->id);
pdata->mii_bus->priv = pdata;
pdata->mii_bus->read = smsc911x_mii_read;
pdata->mii_bus->write = smsc911x_mii_write;
diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c
index a9efbdf..bffd175 100644
--- a/drivers/net/ethernet/smsc/smsc9420.c
+++ b/drivers/net/ethernet/smsc/smsc9420.c
@@ -1211,7 +1211,7 @@ static int smsc9420_mii_init(struct net_device *dev)
goto err_out_1;
}
pd->mii_bus->name = DRV_MDIONAME;
- snprintf(pd->mii_bus->id, MII_BUS_ID_SIZE, "%x",
+ pd->mii_bus->id = kasprintf(GFP_KERNEL, "%x",
(pd->pdev->bus->number << 8) | pd->pdev->devfn);
pd->mii_bus->priv = pd;
pd->mii_bus->read = smsc9420_mii_read;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 96fa2da..c72a50e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -300,19 +300,21 @@ static int stmmac_init_phy(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phydev;
- char phy_id[MII_BUS_ID_SIZE + 3];
- char bus_id[MII_BUS_ID_SIZE];
+ const char *phy_id;
+ const char *bus_id;
int interface = priv->plat->interface;
priv->oldlink = 0;
priv->speed = 0;
priv->oldduplex = -1;
- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", priv->plat->bus_id);
- snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+ bus_id = kasprintf(GFP_KERNEL, "stmmac-%x", priv->plat->bus_id);
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT, bus_id,
priv->plat->phy_addr);
pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, interface);
+ kfree(phy_id);
+ kfree(bus_id);
if (IS_ERR(phydev)) {
pr_err("%s: Could not attach to PHY\n", dev->name);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index da4a104..6a72265 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -158,8 +158,8 @@ int stmmac_mdio_register(struct net_device *ndev)
new_bus->read = &stmmac_mdio_read;
new_bus->write = &stmmac_mdio_write;
new_bus->reset = &stmmac_mdio_reset;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- new_bus->name, mdio_bus_data->bus_id);
+ new_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ new_bus->name, mdio_bus_data->bus_id);
new_bus->priv = ndev;
new_bus->irq = irqlist;
new_bus->phy_mask = mdio_bus_data->phy_mask;
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index 4d9a28f..b448cca 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -205,7 +205,7 @@ struct cpmac_priv {
void __iomem *regs;
struct mii_bus *mii_bus;
struct phy_device *phy;
- char phy_name[MII_BUS_ID_SIZE + 3];
+ const char *phy_name;
int oldlink, oldspeed, oldduplex;
u32 msg_enable;
struct net_device *dev;
@@ -1113,7 +1113,7 @@ static int external_switch;
static int __devinit cpmac_probe(struct platform_device *pdev)
{
int rc, phy_id;
- char mdio_bus_id[MII_BUS_ID_SIZE];
+ const char *mdio_bus_id;
struct resource *mem;
struct cpmac_priv *priv;
struct net_device *dev;
@@ -1122,7 +1122,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
pdata = pdev->dev.platform_data;
if (external_switch || dumb_switch) {
- strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
+ mdio_bus_id = kstrdup("0", GFP_KERNEL); /* fixed phys bus */
phy_id = pdev->id;
} else {
for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
@@ -1130,7 +1130,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
continue;
if (!cpmac_mii->phy_map[phy_id])
continue;
- strncpy(mdio_bus_id, cpmac_mii->id, MII_BUS_ID_SIZE);
+ mdio_bus_id = kstrdup(cpmac_mii->id, GFP_KERNEL);
break;
}
}
@@ -1138,7 +1138,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
if (phy_id == PHY_MAX_ADDR) {
dev_err(&pdev->dev, "no PHY present, falling back "
"to switch on MDIO bus 0\n");
- strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
+ mdio_bus_id = kstrdup("0", GFP_KERNEL); /* fixed phys bus */
phy_id = pdev->id;
}
@@ -1173,8 +1173,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr));
- snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT,
- mdio_bus_id, phy_id);
+ priv->phy_name= kasprintf(GFP_KERNEL, PHY_ID_FMT, mdio_bus_id, phy_id);
+ kfree(mdio_bus_id);
priv->phy = phy_connect(dev, priv->phy_name, cpmac_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
@@ -1269,7 +1269,7 @@ int __devinit cpmac_init(void)
}
cpmac_mii->phy_mask = ~(mask | 0x80000000);
- snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "cpmac-1");
+ cpmac_mii->id = kstrdup("cpmac-1", GFP_KERNEL);
res = mdiobus_register(cpmac_mii);
if (res)
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index ef7c9c1..67ddf87 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -313,8 +313,8 @@ static int __devinit davinci_mdio_probe(struct platform_device *pdev)
data->bus->reset = davinci_mdio_reset,
data->bus->parent = dev;
data->bus->priv = data;
- snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, pdev->id);
+ data->bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ pdev->name, pdev->id);
data->clk = clk_get(dev, NULL);
if (IS_ERR(data->clk)) {
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index 71b785c..8ffacd6 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -682,7 +682,7 @@ static int tc_mii_init(struct net_device *dev)
lp->mii_bus->name = "tc35815_mii_bus";
lp->mii_bus->read = tc_mdio_read;
lp->mii_bus->write = tc_mdio_write;
- snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%x",
+ lp->mii_bus->id = kasprintf(GFP_KERNEL, "%x",
(lp->pci_dev->bus->number << 8) | lp->pci_dev->devfn);
lp->mii_bus->priv = dev;
lp->mii_bus->parent = &lp->pci_dev->dev;
diff --git a/drivers/net/ethernet/xilinx/ll_temac_mdio.c b/drivers/net/ethernet/xilinx/ll_temac_mdio.c
index 8cf9d4f..aa9d0d5 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_mdio.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_mdio.c
@@ -86,7 +86,7 @@ int temac_mdio_setup(struct temac_local *lp, struct device_node *np)
return -ENOMEM;
of_address_to_resource(np, 0, &res);
- snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+ bus->id = kasprintf(GFP_KERNEL, "%.8llx",
(unsigned long long)res.start);
bus->priv = lp;
bus->name = "Xilinx TEMAC MDIO";
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 79013e5..c476861 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -866,7 +866,7 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev)
return -ENOMEM;
of_address_to_resource(np, 0, &res);
- snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+ bus->id = kasprintf(GFP_KERNEL, "%.8llx",
(unsigned long long)res.start);
bus->priv = lp;
bus->name = "Xilinx Emaclite MDIO";
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 72a854f..3794959 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -529,7 +529,7 @@ static int ixp4xx_mdio_register(void)
mdio_bus->name = "IXP4xx MII Bus";
mdio_bus->read = &ixp4xx_mdio_read;
mdio_bus->write = &ixp4xx_mdio_write;
- snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "ixp4xx-eth-0");
+ mdio_bus->id = kstrdup("ixp4xx-eth-0", GFP_KERNEL);
if ((err = mdiobus_register(mdio_bus)))
mdiobus_free(mdio_bus);
@@ -1353,7 +1353,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
struct net_device *dev;
struct eth_plat_info *plat = pdev->dev.platform_data;
u32 regs_phys;
- char phy_id[MII_BUS_ID_SIZE + 3];
+ const char *phy_id;
int err;
if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
@@ -1416,9 +1416,10 @@ static int __devinit eth_init_one(struct platform_device *pdev)
__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
udelay(50);
- snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy);
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT, "0", plat->phy);
port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
+ kfree(phy_id);
if (IS_ERR(port->phydev)) {
err = PTR_ERR(port->phydev);
goto err_free_mem;
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 633680d..947c7e1 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -220,7 +220,7 @@ static int __init fixed_mdio_bus_init(void)
goto err_mdiobus_reg;
}
- snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
+ fmb->mii_bus->id = kstrdup("fixed-0", GFP_KERNEL);
fmb->mii_bus->name = "Fixed MDIO Bus";
fmb->mii_bus->priv = fmb;
fmb->mii_bus->parent = &pdev->dev;
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 50e8e5e..0a89f0b 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -116,7 +116,7 @@ static struct mii_bus * __devinit mdio_gpio_bus_init(struct device *dev,
if (!new_bus->irq[i])
new_bus->irq[i] = PHY_POLL;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id);
+ new_bus->id = kasprintf(GFP_KERNEL, "gpio-%x", bus_id);
if (gpio_request(bitbang->mdc, "mdc"))
goto out_free_bus;
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index 826d961..1158353 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -118,7 +118,7 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
bus->mii_bus->priv = bus;
bus->mii_bus->irq = bus->phy_irq;
bus->mii_bus->name = "mdio-octeon";
- snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ bus->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
bus->mii_bus->name, bus->unit);
bus->mii_bus->parent = &pdev->dev;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f320f46..6879e86 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -78,7 +78,7 @@ int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
if (!fixup)
return -ENOMEM;
- strlcpy(fixup->bus_id, bus_id, sizeof(fixup->bus_id));
+ fixup->bus_id = kstrdup(bus_id, GFP_KERNEL);
fixup->phy_uid = phy_uid;
fixup->phy_uid_mask = phy_uid_mask;
fixup->run = run;
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 980c079..4150655 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -166,7 +166,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
phy_interface_t iface)
{
struct device_node *net_np;
- char bus_id[MII_BUS_ID_SIZE + 3];
+ const char *bus_id;
struct phy_device *phy;
const __be32 *phy_id;
int sz;
@@ -182,9 +182,10 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
if (!phy_id || sz < sizeof(*phy_id))
return NULL;
- sprintf(bus_id, PHY_ID_FMT, "0", be32_to_cpu(phy_id[0]));
+ bus_id = kasprintf(GFP_KERNEL, PHY_ID_FMT, "0", be32_to_cpu(phy_id[0]));
phy = phy_connect(dev, bus_id, hndlr, 0, iface);
+ kfree(bus_id);
return IS_ERR(phy) ? NULL : phy;
}
EXPORT_SYMBOL(of_phy_connect_fixed_link);
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index 2c4069f..5199386 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -5358,7 +5358,7 @@ static int __devinit et131x_pci_setup(struct pci_dev *pdev,
}
adapter->mii_bus->name = "et131x_eth_mii";
- snprintf(adapter->mii_bus->id, MII_BUS_ID_SIZE, "%x",
+ adapter->mii_bus->id = kasprintf(GFP_KERNEL, "%x",
(adapter->pdev->bus->number << 8) | adapter->pdev->devfn);
adapter->mii_bus->priv = netdev;
adapter->mii_bus->read = et131x_mdio_read;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index c599f7e..bf051a7 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -78,12 +78,6 @@ typedef enum {
/* Used when trying to connect to a specific phy (mii bus id:phy device id) */
#define PHY_ID_FMT "%s:%02x"
-/*
- * Need to be a little smaller than phydev->dev.bus_id to leave room
- * for the ":%02x"
- */
-#define MII_BUS_ID_SIZE (20 - 3)
-
/* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
IEEE 802.3ae clause 45 addressing mode used by 10GIGE phy chips. */
#define MII_ADDR_C45 (1<<30)
@@ -94,7 +88,7 @@ typedef enum {
*/
struct mii_bus {
const char *name;
- char id[MII_BUS_ID_SIZE];
+ const char *id;
void *priv;
int (*read)(struct mii_bus *bus, int phy_id, int regnum);
int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);
@@ -441,7 +435,7 @@ struct phy_driver {
/* A Structure for boards to register fixups with the PHY Lib */
struct phy_fixup {
struct list_head list;
- char bus_id[20];
+ const char *bus_id;
u32 phy_uid;
u32 phy_uid_mask;
int (*run)(struct phy_device *phydev);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 56cf9b8..ae0e3ea 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -41,7 +41,7 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds)
ds->slave_mii_bus->name = "dsa slave smi";
ds->slave_mii_bus->read = dsa_slave_phy_read;
ds->slave_mii_bus->write = dsa_slave_phy_write;
- snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s:%.2x",
+ ds->slave_mii_bus->id = kasprintf(GFP_KERNEL, "%s:%.2x",
ds->master_mii_bus->id, ds->pd->sw_addr);
ds->slave_mii_bus->parent = &ds->master_mii_bus->dev;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/1] net: phylib: remove the length limitation of mii bus id
From: Dong Aisheng @ 2012-03-20 4:27 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-kernel, linux-arm-kernel
From: Dong Aisheng <dong.aisheng@linaro.org>
When convert to dt, the length of old mii bus id (17 bytes) is not
sufficent to use.
For example, the bus id could be 800f0000.ethernet-1:00 in DT.
This patch removes the bus id length limitation by changing the
bus id to a const char pionter and user could dynamically set the
bus id via kasprintf function call.
Since then no users use MII_BUS_ID_SIZE any more, just remove it.
Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
---
The simplest way may just change MII_BUS_ID_SIZE to a more bigger size,
but i'm not sure that's gonna be accepted.
So changed to remove the bus id length limitation, a lot of handwork.
Since this patch changes a lot of other ethernet drivers and i did
not have condition to test it, need each corresponding driver owners
to help review.
I just greped the macro MII_BUS_ID_SIZE in the latest kernel tree and
did the replacement.
In case any one missed(may not use MII_BUS_ID_SIZE), that driver owner
should help change it.
Only tested the fec driver on i.MX28 EVK board.
---
arch/powerpc/platforms/82xx/ep8248e.c | 2 +-
arch/powerpc/platforms/pasemi/gpio_mdio.c | 2 +-
drivers/net/ethernet/8390/ax88796.c | 4 +---
drivers/net/ethernet/adi/bfin_mac.c | 3 +--
drivers/net/ethernet/aeroflex/greth.c | 2 +-
drivers/net/ethernet/amd/au1000_eth.c | 3 +--
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 7 ++++---
drivers/net/ethernet/broadcom/sb1250-mac.c | 2 +-
drivers/net/ethernet/broadcom/tg3.c | 4 ++--
drivers/net/ethernet/cadence/macb.c | 2 +-
drivers/net/ethernet/dnet.c | 2 +-
drivers/net/ethernet/ethoc.c | 2 +-
drivers/net/ethernet/faraday/ftgmac100.c | 2 +-
drivers/net/ethernet/freescale/fec.c | 16 +++++++++-------
drivers/net/ethernet/freescale/fec_mpc52xx_phy.c | 2 +-
.../net/ethernet/freescale/fs_enet/mii-bitbang.c | 2 +-
drivers/net/ethernet/freescale/fs_enet/mii-fec.c | 2 +-
drivers/net/ethernet/freescale/fsl_pq_mdio.c | 6 +++---
drivers/net/ethernet/freescale/fsl_pq_mdio.h | 2 +-
drivers/net/ethernet/lantiq_etop.c | 2 +-
drivers/net/ethernet/marvell/mv643xx_eth.c | 2 +-
drivers/net/ethernet/marvell/pxa168_eth.c | 2 +-
drivers/net/ethernet/octeon/octeon_mgmt.c | 6 +++---
drivers/net/ethernet/rdc/r6040.c | 4 ++--
drivers/net/ethernet/renesas/sh_eth.c | 7 ++++---
drivers/net/ethernet/s6gmac.c | 2 +-
drivers/net/ethernet/smsc/smsc911x.c | 4 ++--
drivers/net/ethernet/smsc/smsc9420.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 ++++++----
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 4 ++--
drivers/net/ethernet/ti/cpmac.c | 16 ++++++++--------
drivers/net/ethernet/ti/davinci_mdio.c | 4 ++--
drivers/net/ethernet/toshiba/tc35815.c | 2 +-
drivers/net/ethernet/xilinx/ll_temac_mdio.c | 2 +-
drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +-
drivers/net/ethernet/xscale/ixp4xx_eth.c | 9 +++++----
drivers/net/phy/fixed.c | 2 +-
drivers/net/phy/mdio-gpio.c | 2 +-
drivers/net/phy/mdio-octeon.c | 2 +-
drivers/net/phy/phy_device.c | 2 +-
drivers/of/of_mdio.c | 5 +++--
drivers/staging/et131x/et131x.c | 2 +-
include/linux/phy.h | 10 ++--------
net/dsa/slave.c | 2 +-
44 files changed, 86 insertions(+), 88 deletions(-)
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index 10ff526..21658de 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -139,7 +139,7 @@ static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev)
bus->name = "ep8248e-mdio-bitbang";
bus->parent = &ofdev->dev;
- snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ bus->id = kasprintf(GFP_KERNEL, "%x", res.start);
ret = of_mdiobus_register(bus, ofdev->dev.of_node);
if (ret)
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index 9886296..3b55962 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -241,7 +241,7 @@ static int __devinit gpio_mdio_probe(struct platform_device *ofdev)
new_bus->reset = &gpio_mdio_reset;
prop = of_get_property(np, "reg", NULL);
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
+ new_bus->id = kasprintf(GFP_KERNEL, "%x", *prop);
new_bus->priv = priv;
new_bus->irq = priv->mdio_irqs;
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
index 0f92e35..c70067c 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -623,9 +623,7 @@ static int ax_mii_init(struct net_device *dev)
ax->mii_bus->name = "ax88796_mii_bus";
ax->mii_bus->parent = dev->dev.parent;
- snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, pdev->id);
-
+ ax->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x", pdev->name, pdev->id);
ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
if (!ax->mii_bus->irq) {
err = -ENOMEM;
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index d812a10..77d473a 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -1670,8 +1670,7 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev)
miibus->name = "bfin_mii_bus";
miibus->phy_mask = mii_bus_pd->phy_mask;
- snprintf(miibus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, pdev->id);
+ miibus->id = kasprintf(GFP_KERNEL, "%s-%x", pdev->name, pdev->id);
miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
if (!miibus->irq)
goto out_err_irq_alloc;
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
index c885aa9..df635f2 100644
--- a/drivers/net/ethernet/aeroflex/greth.c
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -1332,7 +1332,7 @@ static int greth_mdio_init(struct greth_private *greth)
}
greth->mdio->name = "greth-mdio";
- snprintf(greth->mdio->id, MII_BUS_ID_SIZE, "%s-%d", greth->mdio->name, greth->irq);
+ greth->mdio->id = kasprintf(GFP_KERNEL, "%s-%d", greth->mdio->name, greth->irq);
greth->mdio->read = greth_mdio_read;
greth->mdio->write = greth_mdio_write;
greth->mdio->reset = greth_mdio_reset;
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 8b95dd3..99e0ebb 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -1171,8 +1171,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
aup->mii_bus->write = au1000_mdiobus_write;
aup->mii_bus->reset = au1000_mdiobus_reset;
aup->mii_bus->name = "au1000_eth_mii";
- snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, aup->mac_id);
+ aup->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x", pdev->name, aup->mac_id);
aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
if (aup->mii_bus->irq == NULL)
goto err_out;
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index c7ca7ec..5635be3 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -787,7 +787,7 @@ static int bcm_enet_open(struct net_device *dev)
struct phy_device *phydev;
int i, ret;
unsigned int size;
- char phy_id[MII_BUS_ID_SIZE + 3];
+ const char *phy_id;
void *p;
u32 val;
@@ -796,12 +796,13 @@ static int bcm_enet_open(struct net_device *dev)
if (priv->has_phy) {
/* connect to PHY */
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT,
priv->mii_bus->id, priv->phy_id);
phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0,
PHY_INTERFACE_MODE_MII);
+ kfree(phy_id);
if (IS_ERR(phydev)) {
dev_err(kdev, "could not attach to PHY\n");
return PTR_ERR(phydev);
@@ -1727,7 +1728,7 @@ static int __devinit bcm_enet_probe(struct platform_device *pdev)
bus->priv = priv;
bus->read = bcm_enet_mdio_read_phylib;
bus->write = bcm_enet_mdio_write_phylib;
- sprintf(bus->id, "%s-%d", pdev->name, priv->mac_id);
+ bus->id = kasprintf(GFP_KERNEL, "%s-%d", pdev->name, priv->mac_id);
/* only probe bus where we think the PHY is, because
* the mdio read operation return 0 instead of 0xffff
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c
index 084904c..7fd5654 100644
--- a/drivers/net/ethernet/broadcom/sb1250-mac.c
+++ b/drivers/net/ethernet/broadcom/sb1250-mac.c
@@ -2259,7 +2259,7 @@ static int sbmac_init(struct platform_device *pldev, long long base)
}
sc->mii_bus->name = sbmac_mdio_string;
- snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ sc->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
pldev->name, idx);
sc->mii_bus->priv = sc;
sc->mii_bus->read = sbmac_mii_read;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 35c2a20..df6c3a3 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -1328,8 +1328,8 @@ static int tg3_mdio_init(struct tg3 *tp)
return -ENOMEM;
tp->mdio_bus->name = "tg3 mdio bus";
- snprintf(tp->mdio_bus->id, MII_BUS_ID_SIZE, "%x",
- (tp->pdev->bus->number << 8) | tp->pdev->devfn);
+ tp->mdio_bus->id = kasprintf(GFP_KERNEL, "%x",
+ (tp->pdev->bus->number << 8) | tp->pdev->devfn);
tp->mdio_bus->priv = tp;
tp->mdio_bus->parent = &tp->pdev->dev;
tp->mdio_bus->read = &tg3_mdio_read;
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 2320068..62e4465 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -243,7 +243,7 @@ static int macb_mii_init(struct macb *bp)
bp->mii_bus->read = &macb_mdio_read;
bp->mii_bus->write = &macb_mdio_write;
bp->mii_bus->reset = &macb_mdio_reset;
- snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ bp->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
bp->pdev->name, bp->pdev->id);
bp->mii_bus->priv = bp;
bp->mii_bus->parent = &bp->dev->dev;
diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c
index 925c9ba..18c3c92 100644
--- a/drivers/net/ethernet/dnet.c
+++ b/drivers/net/ethernet/dnet.c
@@ -325,7 +325,7 @@ static int dnet_mii_init(struct dnet *bp)
bp->mii_bus->write = &dnet_mdio_write;
bp->mii_bus->reset = &dnet_mdio_reset;
- snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ bp->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
bp->pdev->name, bp->pdev->id);
bp->mii_bus->priv = bp;
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index 60f0e78..e9195a5 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -1063,7 +1063,7 @@ static int __devinit ethoc_probe(struct platform_device *pdev)
}
priv->mdio->name = "ethoc-mdio";
- snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "%s-%d",
+ priv->mdio->id = kasprintf(GFP_KERNEL, "%s-%d",
priv->mdio->name, pdev->id);
priv->mdio->read = ethoc_mdio_read;
priv->mdio->write = ethoc_mdio_write;
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 47f85c3..a2901db 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -1256,7 +1256,7 @@ static int ftgmac100_probe(struct platform_device *pdev)
}
priv->mii_bus->name = "ftgmac100_mdio";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "ftgmac100_mii");
+ priv->mii_bus->id = kstrdup("ftgmac100_mii", GFP_KERNEL);
priv->mii_bus->priv = netdev;
priv->mii_bus->read = ftgmac100_mdiobus_read;
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index e92ef1b..2551181 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -961,8 +961,8 @@ static int fec_enet_mii_probe(struct net_device *ndev)
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
struct phy_device *phy_dev = NULL;
- char mdio_bus_id[MII_BUS_ID_SIZE];
- char phy_name[MII_BUS_ID_SIZE + 3];
+ const char *mdio_bus_id;
+ const char *phy_name;
int phy_id;
int dev_id = fep->dev_id;
@@ -978,7 +978,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
continue;
if (dev_id--)
continue;
- strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
+ mdio_bus_id = kstrdup(fep->mii_bus->id, GFP_KERNEL);
break;
}
@@ -986,13 +986,15 @@ static int fec_enet_mii_probe(struct net_device *ndev)
printk(KERN_INFO
"%s: no PHY, assuming direct connection to switch\n",
ndev->name);
- strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE);
+ mdio_bus_id = kstrdup("fixed-0", GFP_KERNEL);
phy_id = 0;
}
- snprintf(phy_name, sizeof(phy_name), PHY_ID_FMT, mdio_bus_id, phy_id);
+ phy_name= kasprintf(GFP_KERNEL, PHY_ID_FMT, mdio_bus_id, phy_id);
phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0,
fep->phy_interface);
+ kfree(mdio_bus_id);
+ kfree(phy_name);
if (IS_ERR(phy_dev)) {
printk(KERN_ERR "%s: could not attach to PHY\n", ndev->name);
return PTR_ERR(phy_dev);
@@ -1080,8 +1082,8 @@ static int fec_enet_mii_init(struct platform_device *pdev)
fep->mii_bus->read = fec_enet_mdio_read;
fep->mii_bus->write = fec_enet_mdio_write;
fep->mii_bus->reset = fec_enet_mdio_reset;
- snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, fep->dev_id + 1);
+ fep->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ pdev->name, fep->dev_id +1);
fep->mii_bus->priv = fep;
fep->mii_bus->parent = &pdev->dev;
diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
index 360a578..7724be7 100644
--- a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
+++ b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
@@ -96,7 +96,7 @@ static int mpc52xx_fec_mdio_probe(struct platform_device *of)
goto out_free;
}
- snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ bus->id = kasprintf(GFP_KERNEL, "%x", res.start);
bus->priv = priv;
bus->parent = dev;
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
index 0f2d1a7..9e6eac9 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
@@ -127,7 +127,7 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
* we get is an int, and the odds of multiple bitbang mdio buses
* is low enough that it's not worth going too crazy.
*/
- snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ bus->id = kasprintf(GFP_KERNEL, "%x", res.start);
data = of_get_property(np, "fsl,mdio-pin", &len);
if (!data || len != 4)
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
index 55bb867..5242f4d 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
@@ -134,7 +134,7 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev)
if (ret)
goto out_res;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ new_bus->id = kasprintf(GFP_KERNEL, "%x", res.start);
fec->fecp = ioremap(res.start, resource_size(&res));
if (!fec->fecp)
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
index 9eb8159..773acd5 100644
--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c
+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
@@ -169,7 +169,7 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
return 0;
}
-void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
+void fsl_pq_mdio_bus_name(char **name, struct device_node *np)
{
const u32 *addr;
u64 taddr = OF_BAD_ADDR;
@@ -178,7 +178,7 @@ void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
if (addr)
taddr = of_translate_address(np, addr);
- snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name,
+ *name = kasprintf(GFP_KERNEL, "%s@%llx", np->name,
(unsigned long long)taddr);
}
EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name);
@@ -277,7 +277,7 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev)
new_bus->write = &fsl_pq_mdio_write,
new_bus->reset = &fsl_pq_mdio_reset,
new_bus->priv = priv;
- fsl_pq_mdio_bus_name(new_bus->id, np);
+ fsl_pq_mdio_bus_name(&new_bus->id, np);
addrp = of_get_address(np, 0, &size, NULL);
if (!addrp) {
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.h b/drivers/net/ethernet/freescale/fsl_pq_mdio.h
index bd17a2a..b563ef7 100644
--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.h
+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.h
@@ -48,5 +48,5 @@ int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum);
int __init fsl_pq_mdio_init(void);
void fsl_pq_mdio_exit(void);
-void fsl_pq_mdio_bus_name(char *name, struct device_node *np);
+void fsl_pq_mdio_bus_name(char **name, struct device_node *np);
#endif /* FSL_PQ_MDIO_H */
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 85e2c6c..742e7dd 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -437,7 +437,7 @@ ltq_etop_mdio_init(struct net_device *dev)
priv->mii_bus->read = ltq_etop_mdio_rd;
priv->mii_bus->write = ltq_etop_mdio_wr;
priv->mii_bus->name = "ltq_mii";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ priv->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
priv->pdev->name, priv->pdev->id);
priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
if (!priv->mii_bus->irq) {
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 9edecfa..496b24c 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2627,7 +2627,7 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
msp->smi_bus->name = "mv643xx_eth smi";
msp->smi_bus->read = smi_bus_read;
msp->smi_bus->write = smi_bus_write,
- snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d",
+ msp->smi_bus->id = kasprintf(GFP_KERNEL, "%s-%d",
pdev->name, pdev->id);
msp->smi_bus->parent = &pdev->dev;
msp->smi_bus->phy_mask = 0xffffffff;
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 953ba58..bf19af7 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -1552,7 +1552,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
pep->smi_bus->name = "pxa168_eth smi";
pep->smi_bus->read = pxa168_smi_read;
pep->smi_bus->write = pxa168_smi_write;
- snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d",
+ pep->smi_bus->id = kasprintf(GFP_KERNEL, "%s-%d",
pdev->name, pdev->id);
pep->smi_bus->parent = &pdev->dev;
pep->smi_bus->phy_mask = 0xffffffff;
diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c
index cd827ff..54380df 100644
--- a/drivers/net/ethernet/octeon/octeon_mgmt.c
+++ b/drivers/net/ethernet/octeon/octeon_mgmt.c
@@ -670,7 +670,7 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev)
static int octeon_mgmt_init_phy(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- char phy_id[MII_BUS_ID_SIZE + 3];
+ const char *phy_id;
if (octeon_is_simulation()) {
/* No PHYs in the simulator. */
@@ -678,11 +678,11 @@ static int octeon_mgmt_init_phy(struct net_device *netdev)
return 0;
}
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "mdio-octeon-0", p->port);
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT, "mdio-octeon-0", p->port);
p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
-
+ kfree(phy_id);
if (IS_ERR(p->phydev)) {
p->phydev = NULL;
return -1;
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index cb0eca8..9d890b2 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -1181,8 +1181,8 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
lp->mii_bus->write = r6040_mdiobus_write;
lp->mii_bus->reset = r6040_mdiobus_reset;
lp->mii_bus->name = "r6040_eth_mii";
- snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- dev_name(&pdev->dev), card_idx);
+ lp->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ dev_name(&pdev->dev), card_idx);
lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
if (!lp->mii_bus->irq) {
dev_err(&pdev->dev, "mii_bus irq allocation failed\n");
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 87b6501..a81a33b 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1215,10 +1215,10 @@ static void sh_eth_adjust_link(struct net_device *ndev)
static int sh_eth_phy_init(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- char phy_id[MII_BUS_ID_SIZE + 3];
+ const char *phy_id;
struct phy_device *phydev = NULL;
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT,
mdp->mii_bus->id , mdp->phy_id);
mdp->link = PHY_DOWN;
@@ -1228,6 +1228,7 @@ static int sh_eth_phy_init(struct net_device *ndev)
/* Try connect to PHY */
phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
0, mdp->phy_interface);
+ kfree(phy_id);
if (IS_ERR(phydev)) {
dev_err(&ndev->dev, "phy_connect failed\n");
return PTR_ERR(phydev);
@@ -1704,7 +1705,7 @@ static int sh_mdio_init(struct net_device *ndev, int id,
/* Hook up MII support for ethtool */
mdp->mii_bus->name = "sh_mii";
mdp->mii_bus->parent = &ndev->dev;
- snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ mdp->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
mdp->pdev->name, id);
/* PHY IRQ */
diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c
index 22e9c01..dd5f29b 100644
--- a/drivers/net/ethernet/s6gmac.c
+++ b/drivers/net/ethernet/s6gmac.c
@@ -1004,7 +1004,7 @@ static int __devinit s6gmac_probe(struct platform_device *pdev)
mb->write = s6mii_write;
mb->reset = s6mii_reset;
mb->priv = pd;
- snprintf(mb->id, MII_BUS_ID_SIZE, "%s-%x", pdev->name, pdev->id);
+ mb->id = kasprintf(GFP_KERNEL, "%s-%x", pdev->name, pdev->id);
mb->phy_mask = ~(1 << 0);
mb->irq = &pd->mii.irq[0];
for (i = 0; i < PHY_MAX_ADDR; i++) {
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 24d2df0..4aab696 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -1044,8 +1044,8 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
}
pdata->mii_bus->name = SMSC_MDIONAME;
- snprintf(pdata->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, pdev->id);
+ pdata->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ pdev->name, pdev->id);
pdata->mii_bus->priv = pdata;
pdata->mii_bus->read = smsc911x_mii_read;
pdata->mii_bus->write = smsc911x_mii_write;
diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c
index a9efbdf..bffd175 100644
--- a/drivers/net/ethernet/smsc/smsc9420.c
+++ b/drivers/net/ethernet/smsc/smsc9420.c
@@ -1211,7 +1211,7 @@ static int smsc9420_mii_init(struct net_device *dev)
goto err_out_1;
}
pd->mii_bus->name = DRV_MDIONAME;
- snprintf(pd->mii_bus->id, MII_BUS_ID_SIZE, "%x",
+ pd->mii_bus->id = kasprintf(GFP_KERNEL, "%x",
(pd->pdev->bus->number << 8) | pd->pdev->devfn);
pd->mii_bus->priv = pd;
pd->mii_bus->read = smsc9420_mii_read;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6ee593a..150b130 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -300,19 +300,21 @@ static int stmmac_init_phy(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phydev;
- char phy_id[MII_BUS_ID_SIZE + 3];
- char bus_id[MII_BUS_ID_SIZE];
+ const char *phy_id;
+ const char *bus_id;
int interface = priv->plat->interface;
priv->oldlink = 0;
priv->speed = 0;
priv->oldduplex = -1;
- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", priv->plat->bus_id);
- snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+ bus_id = kasprintf(GFP_KERNEL, "stmmac-%x", priv->plat->bus_id);
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT, bus_id,
priv->plat->phy_addr);
pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, interface);
+ kfree(phy_id);
+ kfree(bus_id);
if (IS_ERR(phydev)) {
pr_err("%s: Could not attach to PHY\n", dev->name);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 7319532..269ff54 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -158,8 +158,8 @@ int stmmac_mdio_register(struct net_device *ndev)
new_bus->read = &stmmac_mdio_read;
new_bus->write = &stmmac_mdio_write;
new_bus->reset = &stmmac_mdio_reset;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- new_bus->name, mdio_bus_data->bus_id);
+ new_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ new_bus->name, mdio_bus_data->bus_id);
new_bus->priv = ndev;
new_bus->irq = irqlist;
new_bus->phy_mask = mdio_bus_data->phy_mask;
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index cbc8df7..64cde9f 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -205,7 +205,7 @@ struct cpmac_priv {
void __iomem *regs;
struct mii_bus *mii_bus;
struct phy_device *phy;
- char phy_name[MII_BUS_ID_SIZE + 3];
+ const char *phy_name;
int oldlink, oldspeed, oldduplex;
u32 msg_enable;
struct net_device *dev;
@@ -1113,7 +1113,7 @@ static int external_switch;
static int __devinit cpmac_probe(struct platform_device *pdev)
{
int rc, phy_id;
- char mdio_bus_id[MII_BUS_ID_SIZE];
+ const char *mdio_bus_id;
struct resource *mem;
struct cpmac_priv *priv;
struct net_device *dev;
@@ -1122,7 +1122,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
pdata = pdev->dev.platform_data;
if (external_switch || dumb_switch) {
- strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */
+ mdio_bus_id = kstrdup("fixed-0", GFP_KERNEL); /* fixed phys bus */
phy_id = pdev->id;
} else {
for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
@@ -1130,7 +1130,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
continue;
if (!cpmac_mii->phy_map[phy_id])
continue;
- strncpy(mdio_bus_id, cpmac_mii->id, MII_BUS_ID_SIZE);
+ mdio_bus_id = kstrdup(cpmac_mii->id, GFP_KERNEL);
break;
}
}
@@ -1138,7 +1138,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
if (phy_id == PHY_MAX_ADDR) {
dev_err(&pdev->dev, "no PHY present, falling back "
"to switch on MDIO bus 0\n");
- strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */
+ mdio_bus_id = kstrdup("fixed-0", GFP_KERNEL); /* fixed phys bus */
phy_id = pdev->id;
}
@@ -1173,8 +1173,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr));
- snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT,
- mdio_bus_id, phy_id);
+ priv->phy_name= kasprintf(GFP_KERNEL, PHY_ID_FMT, mdio_bus_id, phy_id);
+ kfree(mdio_bus_id);
priv->phy = phy_connect(dev, priv->phy_name, cpmac_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
@@ -1269,7 +1269,7 @@ int __devinit cpmac_init(void)
}
cpmac_mii->phy_mask = ~(mask | 0x80000000);
- snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "cpmac-1");
+ cpmac_mii->id = kstrdup("cpmac-1", GFP_KERNEL);
res = mdiobus_register(cpmac_mii);
if (res)
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index af8b8fc..2b99461 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -313,8 +313,8 @@ static int __devinit davinci_mdio_probe(struct platform_device *pdev)
data->bus->reset = davinci_mdio_reset,
data->bus->parent = dev;
data->bus->priv = data;
- snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s-%x",
- pdev->name, pdev->id);
+ data->bus->id = kasprintf(GFP_KERNEL, "%s-%x",
+ pdev->name, pdev->id);
data->clk = clk_get(dev, NULL);
if (IS_ERR(data->clk)) {
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index 71b785c..8ffacd6 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -682,7 +682,7 @@ static int tc_mii_init(struct net_device *dev)
lp->mii_bus->name = "tc35815_mii_bus";
lp->mii_bus->read = tc_mdio_read;
lp->mii_bus->write = tc_mdio_write;
- snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%x",
+ lp->mii_bus->id = kasprintf(GFP_KERNEL, "%x",
(lp->pci_dev->bus->number << 8) | lp->pci_dev->devfn);
lp->mii_bus->priv = dev;
lp->mii_bus->parent = &lp->pci_dev->dev;
diff --git a/drivers/net/ethernet/xilinx/ll_temac_mdio.c b/drivers/net/ethernet/xilinx/ll_temac_mdio.c
index 8cf9d4f..aa9d0d5 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_mdio.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_mdio.c
@@ -86,7 +86,7 @@ int temac_mdio_setup(struct temac_local *lp, struct device_node *np)
return -ENOMEM;
of_address_to_resource(np, 0, &res);
- snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+ bus->id = kasprintf(GFP_KERNEL, "%.8llx",
(unsigned long long)res.start);
bus->priv = lp;
bus->name = "Xilinx TEMAC MDIO";
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 79013e5..c476861 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -866,7 +866,7 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev)
return -ENOMEM;
of_address_to_resource(np, 0, &res);
- snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+ bus->id = kasprintf(GFP_KERNEL, "%.8llx",
(unsigned long long)res.start);
bus->priv = lp;
bus->name = "Xilinx Emaclite MDIO";
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 41a8b5a..d44a3ae 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -529,7 +529,7 @@ static int ixp4xx_mdio_register(void)
mdio_bus->name = "IXP4xx MII Bus";
mdio_bus->read = &ixp4xx_mdio_read;
mdio_bus->write = &ixp4xx_mdio_write;
- snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "ixp4xx-eth-0");
+ mdio_bus->id = kstrdup("ixp4xx-eth-0", GFP_KERNEL);
if ((err = mdiobus_register(mdio_bus)))
mdiobus_free(mdio_bus);
@@ -1353,7 +1353,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
struct net_device *dev;
struct eth_plat_info *plat = pdev->dev.platform_data;
u32 regs_phys;
- char phy_id[MII_BUS_ID_SIZE + 3];
+ const char *phy_id;
int err;
if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
@@ -1416,10 +1416,11 @@ static int __devinit eth_init_one(struct platform_device *pdev)
__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
udelay(50);
- snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT,
- mdio_bus->id, plat->phy);
+ phy_id = kasprintf(GFP_KERNEL, PHY_ID_FMT,
+ mdio_bus->id, plat->phy);
port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
+ kfree(phy_id);
if (IS_ERR(port->phydev)) {
err = PTR_ERR(port->phydev);
goto err_free_mem;
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 633680d..947c7e1 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -220,7 +220,7 @@ static int __init fixed_mdio_bus_init(void)
goto err_mdiobus_reg;
}
- snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
+ fmb->mii_bus->id = kstrdup("fixed-0", GFP_KERNEL);
fmb->mii_bus->name = "Fixed MDIO Bus";
fmb->mii_bus->priv = fmb;
fmb->mii_bus->parent = &pdev->dev;
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 50e8e5e..0a89f0b 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -116,7 +116,7 @@ static struct mii_bus * __devinit mdio_gpio_bus_init(struct device *dev,
if (!new_bus->irq[i])
new_bus->irq[i] = PHY_POLL;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id);
+ new_bus->id = kasprintf(GFP_KERNEL, "gpio-%x", bus_id);
if (gpio_request(bitbang->mdc, "mdc"))
goto out_free_bus;
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index 826d961..1158353 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -118,7 +118,7 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
bus->mii_bus->priv = bus;
bus->mii_bus->irq = bus->phy_irq;
bus->mii_bus->name = "mdio-octeon";
- snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ bus->mii_bus->id = kasprintf(GFP_KERNEL, "%s-%x",
bus->mii_bus->name, bus->unit);
bus->mii_bus->parent = &pdev->dev;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f320f46..6879e86 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -78,7 +78,7 @@ int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
if (!fixup)
return -ENOMEM;
- strlcpy(fixup->bus_id, bus_id, sizeof(fixup->bus_id));
+ fixup->bus_id = kstrdup(bus_id, GFP_KERNEL);
fixup->phy_uid = phy_uid;
fixup->phy_uid_mask = phy_uid_mask;
fixup->run = run;
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 483c0ad..b4d7d29 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -166,7 +166,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
phy_interface_t iface)
{
struct device_node *net_np;
- char bus_id[MII_BUS_ID_SIZE + 3];
+ const char *bus_id;
struct phy_device *phy;
const __be32 *phy_id;
int sz;
@@ -182,9 +182,10 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
if (!phy_id || sz < sizeof(*phy_id))
return NULL;
- sprintf(bus_id, PHY_ID_FMT, "fixed-0", be32_to_cpu(phy_id[0]));
+ bus_id = kasprintf(GFP_KERNEL, PHY_ID_FMT, "fixed-0", be32_to_cpu(phy_id[0]));
phy = phy_connect(dev, bus_id, hndlr, 0, iface);
+ kfree(bus_id);
return IS_ERR(phy) ? NULL : phy;
}
EXPORT_SYMBOL(of_phy_connect_fixed_link);
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index 2c4069f..5199386 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -5358,7 +5358,7 @@ static int __devinit et131x_pci_setup(struct pci_dev *pdev,
}
adapter->mii_bus->name = "et131x_eth_mii";
- snprintf(adapter->mii_bus->id, MII_BUS_ID_SIZE, "%x",
+ adapter->mii_bus->id = kasprintf(GFP_KERNEL, "%x",
(adapter->pdev->bus->number << 8) | adapter->pdev->devfn);
adapter->mii_bus->priv = netdev;
adapter->mii_bus->read = et131x_mdio_read;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index c599f7e..bf051a7 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -78,12 +78,6 @@ typedef enum {
/* Used when trying to connect to a specific phy (mii bus id:phy device id) */
#define PHY_ID_FMT "%s:%02x"
-/*
- * Need to be a little smaller than phydev->dev.bus_id to leave room
- * for the ":%02x"
- */
-#define MII_BUS_ID_SIZE (20 - 3)
-
/* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
IEEE 802.3ae clause 45 addressing mode used by 10GIGE phy chips. */
#define MII_ADDR_C45 (1<<30)
@@ -94,7 +88,7 @@ typedef enum {
*/
struct mii_bus {
const char *name;
- char id[MII_BUS_ID_SIZE];
+ const char *id;
void *priv;
int (*read)(struct mii_bus *bus, int phy_id, int regnum);
int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);
@@ -441,7 +435,7 @@ struct phy_driver {
/* A Structure for boards to register fixups with the PHY Lib */
struct phy_fixup {
struct list_head list;
- char bus_id[20];
+ const char *bus_id;
u32 phy_uid;
u32 phy_uid_mask;
int (*run)(struct phy_device *phydev);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 56cf9b8..ae0e3ea 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -41,7 +41,7 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds)
ds->slave_mii_bus->name = "dsa slave smi";
ds->slave_mii_bus->read = dsa_slave_phy_read;
ds->slave_mii_bus->write = dsa_slave_phy_write;
- snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s:%.2x",
+ ds->slave_mii_bus->id = kasprintf(GFP_KERNEL, "%s:%.2x",
ds->master_mii_bus->id, ds->pd->sw_addr);
ds->slave_mii_bus->parent = &ds->master_mii_bus->dev;
}
--
1.7.0.4
^ permalink raw reply related
* Re: Kernel Panic with bonding + IPoIB on 3.2.9
From: Jay Vosburgh @ 2012-03-20 4:30 UTC (permalink / raw)
To: Joseph Glanville; +Cc: Roland Dreier, linux-rdma, linux-kernel, netdev
In-Reply-To: <CAOzFzEgSWHqabw9yq6JxhD+CxQY61O+gqGwPMdbWPC=M+_oZAw@mail.gmail.com>
Joseph Glanville <joseph.glanville@orionvm.com.au> wrote:
>On 20 March 2012 06:05, Roland Dreier <roland@purestorage.com> wrote:
>> On Sun, Mar 18, 2012 at 1:21 PM, Joseph Glanville
>> <joseph.glanville@orionvm.com.au> wrote:
>>> [ 422.047024] kernel BUG at net/core/dev.c:1896!
>>
>> So this line is
>>
>> BUG_ON(offset >= skb_headlen(skb));
>>
>> right? No paritcular idea how we hit this, though...
>
>Yep... I have looked through most of /drivers/net/bonding and I can't
>really see why it should be blowing up there.. it really should cause
>the BUG_ON under normal IPoIB if the MTU was the cause - yet I have
>not experienced this.
>The bonding code doesn't seem to do anything special with the MTU
>other than propagating changes to the slaves.
For IPoIB, though, there is some extra initialization stuff in
bond_setup_by_slave(), and the hard_header_len will end up being set to
something different from the usual Ethernet value.
In looking at ipoib_setup, I see that hard_header_len appears to
be set to 4 (IPOIB_ENCAP_LEN). My recollection was that the IPoIB
hard_header_len was quite a bit larger than that; it looks like it
changed very recently from IPOIB_ENCAP_LEN + INFINIBAND_ALEN to what it
is now:
commit afd87adacb5de00768b2e54f0bd851278f2e6179
Author: Roland Dreier <roland@purestorage.com>
Date: Tue Feb 7 14:51:21 2012 +0000
IPoIB: Stop lying about hard_header_len and use skb->cb to stash LL addresses
[ Upstream commit 936d7de3d736e0737542641269436f4b5968e9ef ]
Commit a0417fa3a18a ("net: Make qdisc_skb_cb upper size bound
explicit.") made it possible for a netdev driver to use skb->cb
between its header_ops.create method and its .ndo_start_xmit
method. Use this in ipoib_hard_header() to stash away the LL address
(GID + QPN), instead of the "ipoib_pseudoheader" hack. This allows
IPoIB to stop lying about its hard_header_len, which will let us fix
the L2 check for GRO.
I don't know if this change could be causing the problem (it
appears to be new in 3.2.9), but the hard_header_len is one of the few
areas in the TX path of bonding that IPoIB ends up being different from
regular Ethernet.
-J
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* Re: [PATCH v5 0/2] Adding new TI Common Platform ethernet SWitch driver
From: David Miller @ 2012-03-20 4:34 UTC (permalink / raw)
To: eric.dumazet; +Cc: mugunthanvnm, netdev
In-Reply-To: <1332216396.22737.29.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 19 Mar 2012 21:06:36 -0700
> For an ethernet driver, using eth_change_mtu seems the right thing.
I just tossed that into the tree, as follows:
--------------------
[PATCH] cpsw: Hook up default ndo_change_mtu.
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/ti/cpsw.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index c68c9d9..6685bbb 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -665,6 +665,7 @@ static const struct net_device_ops cpsw_netdev_ops = {
.ndo_start_xmit = cpsw_ndo_start_xmit,
.ndo_change_rx_flags = cpsw_ndo_change_rx_flags,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
.ndo_tx_timeout = cpsw_ndo_tx_timeout,
.ndo_get_stats = cpsw_ndo_get_stats,
#ifdef CONFIG_NET_POLL_CONTROLLER
--
1.7.7.6
^ permalink raw reply related
* Re: ath: DMA failed to stop in 10 ms AR_CR=0x00000024 AR_DIAG_SW=0x02000020 DMADBG_7=0x00008040
From: Justin P. Mattock @ 2012-03-20 5:54 UTC (permalink / raw)
To: Linux-wireless
Cc: Felix Fietkau, Mohammed Shafi,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Linux-netdev
In-Reply-To: <4F6751B2.1030809-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
On 03/19/2012 08:33 AM, Felix Fietkau wrote:
> On 2012-03-19 4:25 PM, Justin P. Mattock wrote:
>> On 03/19/2012 08:20 AM, Mohammed Shafi wrote:
>>> Hi Justin,
>>>
>>>> seems I got this when waking up from suspend, was trying to connect with NM
>>>> then all of a sudden Xorg shut off and this appeared on the screen(image
>>>> links below I could not save dmesg only pic)
>>>> http://flic.kr/p/bEhf2K
>>>> http://flic.kr/p/bEhf2x
>>>> http://flic.kr/p/bEhf2n
>>>> http://flic.kr/p/bEhf26
>>>>
>>>> I see ath9k in the image, but am unsure if its related.
>>>> kernel is: 3.3.0-rc7-next-20120316
>>>
>>> this looks like some new issue in ath9k, lets try to recreate it here
>>>
>>>>
>>>> Justin P. Mattock
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>> would be nice to recreate, then bisecting will be more accurate to do..
>> I am trying userspace tweaks here and there but no luck(hostapd etc..)
>> keep in mind this is for the RX DMA, the above just occured..
>> as for writing a small app I still need to try, but my C skills only go
>> so far(anything to trigger!).
> Was your kernel compiled with debug info? If so, please run gdb on the
> ath9k.ko module and enter this:
> l *ath9k_tx+start+0x284
> Then send me the output of that.
>
> - Felix
>
I changed the Cc''s so hopefully its correct..
anyway I tried the above but might have gotten it wrong..:
Reading symbols from
/home/kernel/linux-next/drivers/net/wireless/ath/ath9k/ath9k.o...done.
(gdb) list *ath9k_tx+0xa3
0x4673 is in ath9k_tx (drivers/net/wireless/ath/ath9k/main.c:1136).
1131 memset(&txctl, 0, sizeof(struct ath_tx_control));
1132 txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
1133
1134 ath_dbg(common, XMIT, "transmitting packet, skb: %p\n", skb);
1135
1136 if (ath_tx_start(hw, skb, &txctl) != 0) {
1137 ath_dbg(common, XMIT, "TX failed\n");
1138 goto exit;
1139 }
1140
(gdb) list *ath9k_tx+start+0x284
No symbol "start" in current context.
before receiving the email to do the above code with gdb I had cleaned
the tree out with git clean -fx so rebuilding might have misalighned
things(but could be wrong)..
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next v4] ipv6: Allocate unique metrics for icmp6 packets to prevent tainting dst metrics
From: Nick Jones @ 2012-03-20 5:48 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, netdev
In-Reply-To: <20120319.180415.1274216814977167410.davem@davemloft.net>
On Mon, 2012-03-19 at 18:04 -0400, David Miller wrote:
> From: Nick Jones <nick.jones@network-box.com>
> Date: Sun, 18 Mar 2012 01:43:39 +0800
>
> > + return ERR_CAST(-ENOMEM);
>
> Really, please, stop wasting my time. There is no way your compiler
> didn't emit a warning for that garbage.
>
This is really sloppy, I apologise. I'll work on tightening up my
workflow for build testing, runtime testing and patch submission before
I bother you again.
> Furthermore, callers are only ready to handle NULL vs. non-NULL as
> return values from this function. So this return value you are adding
> will result in crashes.
This one I did check. icmp6_dst_alloc returns error encoded pointers
and all call sites test the return value with IS_ERR, I simply didn't
understand the correct formatting macro, nor check the build properly.
I think you got it mixed up with ip6_dst_alloc
The 'return NULL' at the bottom of the second fragment was a bug, but
this again exposes my newness to kernel patch submission workflow: that
bug was fixed recently and this patch wouldn't have applied, further
wasting your time... wonderful.
I'll let the merge window close to let things settle down for you before
bringing this fix up again.
^ permalink raw reply
* Re: ath: DMA failed to stop in 10 ms AR_CR=0x00000024 AR_DIAG_SW=0x02000020 DMADBG_7=0x00008040
From: Mohammed Shafi @ 2012-03-20 6:19 UTC (permalink / raw)
To: Justin P. Mattock
Cc: Linux-wireless, Felix Fietkau, linux-kernel, Linux-netdev
In-Reply-To: <4F681B78.9000207@gmail.com>
> (gdb) list *ath9k_tx+start+0x284
> No symbol "start" in current context.
hey, pls try l *(ath9k_tx_start+0x284), yesterday i did the same in
the latest wireless testing tree it pointed to line 1929 of xmit.c
sc->tx.seq_no +=0x10;
also did few suspend/resume in my machine, nothing interesting happened
>
> before receiving the email to do the above code with gdb I had cleaned the
> tree out with git clean -fx so rebuilding might have misalighned things(but
> could be wrong)..
>
--
thanks,
shafi
^ permalink raw reply
* Re: VLAN regression caused by: e1000: do vlan cleanup (799d531).
From: Jiri Pirko @ 2012-03-20 6:26 UTC (permalink / raw)
To: Ben Greear; +Cc: e1000-devel list, netdev
In-Reply-To: <4F67C014.1090500@candelatech.com>
Tue, Mar 20, 2012 at 12:24:04AM CET, greearb@candelatech.com wrote:
>On 03/19/2012 06:08 AM, Jiri Pirko wrote:
>>Tue, Mar 13, 2012 at 07:44:18PM CET, greearb@candelatech.com wrote:
>
>>>>I have suspition that vlan filter must be on/offed along with vlan
>>>>accel.
>>>
>>>Ok, if I disable rx-vlan-hw-parse on both NICs, traffic starts working.
>>>
>>>And, if I re-enable rx-vlan-hw-parse on both NICs, it continues to work.
>>>
>>>Maybe the initialization logic needs some fixing?
>>
>>Could you please try following patch?
>
>That patches fixes the problem for me. Only lightly tested
>at this point, but I have verified VLAN traffic works as desired.
Thank you. I'm going to do proper post of this.
Jirka
>
>Thanks,
>Ben
>
>>
>>diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
>>index 6419a88..b06c31c 100644
>>--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
>>+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
>>@@ -164,6 +164,8 @@ static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
>> static bool e1000_vlan_used(struct e1000_adapter *adapter);
>> static void e1000_vlan_mode(struct net_device *netdev,
>> netdev_features_t features);
>>+static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
>>+ bool filter_on);
>> static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
>> static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
>> static void e1000_restore_vlan(struct e1000_adapter *adapter);
>>@@ -1214,7 +1216,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
>> if (err)
>> goto err_register;
>>
>>- e1000_vlan_mode(netdev, netdev->features);
>>+ e1000_vlan_filter_on_off(adapter, false);
>>
>> /* print bus type/speed/width info */
>> e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n",
>>@@ -4772,6 +4774,22 @@ static bool e1000_vlan_used(struct e1000_adapter *adapter)
>> return false;
>> }
>>
>>+static void __e1000_vlan_mode(struct e1000_adapter *adapter,
>>+ netdev_features_t features)
>>+{
>>+ struct e1000_hw *hw =&adapter->hw;
>>+ u32 ctrl;
>>+
>>+ ctrl = er32(CTRL);
>>+ if (features& NETIF_F_HW_VLAN_RX) {
>>+ /* enable VLAN tag insert/strip */
>>+ ctrl |= E1000_CTRL_VME;
>>+ } else {
>>+ /* disable VLAN tag insert/strip */
>>+ ctrl&= ~E1000_CTRL_VME;
>>+ }
>>+ ew32(CTRL, ctrl);
>>+}
>> static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
>> bool filter_on)
>> {
>>@@ -4781,6 +4799,7 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
>> if (!test_bit(__E1000_DOWN,&adapter->flags))
>> e1000_irq_disable(adapter);
>>
>>+ __e1000_vlan_mode(adapter, adapter->netdev->features);
>> if (filter_on) {
>> /* enable VLAN receive filtering */
>> rctl = er32(RCTL);
>>@@ -4801,24 +4820,14 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
>> }
>>
>> static void e1000_vlan_mode(struct net_device *netdev,
>>- netdev_features_t features)
>>+ netdev_features_t features)
>> {
>> struct e1000_adapter *adapter = netdev_priv(netdev);
>>- struct e1000_hw *hw =&adapter->hw;
>>- u32 ctrl;
>>
>> if (!test_bit(__E1000_DOWN,&adapter->flags))
>> e1000_irq_disable(adapter);
>>
>>- ctrl = er32(CTRL);
>>- if (features& NETIF_F_HW_VLAN_RX) {
>>- /* enable VLAN tag insert/strip */
>>- ctrl |= E1000_CTRL_VME;
>>- } else {
>>- /* disable VLAN tag insert/strip */
>>- ctrl&= ~E1000_CTRL_VME;
>>- }
>>- ew32(CTRL, ctrl);
>>+ __e1000_vlan_mode(adapter, features);
>>
>> if (!test_bit(__E1000_DOWN,&adapter->flags))
>> e1000_irq_enable(adapter);
>
>
>--
>Ben Greear <greearb@candelatech.com>
>Candela Technologies Inc http://www.candelatech.com
>
------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: ath: DMA failed to stop in 10 ms AR_CR=0x00000024 AR_DIAG_SW=0x02000020 DMADBG_7=0x00008040
From: Justin P. Mattock @ 2012-03-20 6:27 UTC (permalink / raw)
To: Mohammed Shafi; +Cc: Linux-wireless, Felix Fietkau, linux-kernel, Linux-netdev
In-Reply-To: <CAD2nsn0d-3edYGH8u+v5mhrUZBMsznDNRDkDHE-tErG8uGk84Q@mail.gmail.com>
On 03/19/2012 11:19 PM, Mohammed Shafi wrote:
>> (gdb) list *ath9k_tx+start+0x284
>> No symbol "start" in current context.
>
> hey, pls try l *(ath9k_tx_start+0x284), yesterday i did the same in
> the latest wireless testing tree it pointed to line 1929 of xmit.c
>
> sc->tx.seq_no +=0x10;
>
> also did few suspend/resume in my machine, nothing interesting happened
>
>>
>> before receiving the email to do the above code with gdb I had cleaned the
>> tree out with git clean -fx so rebuilding might have misalighned things(but
>> could be wrong)..
>>
>
>
>
seems gdb is not working with that code but works if I remove _start.
(maybe -next took this out or something)
(gdb) l *(ath9k_tx_start+0x284)
No symbol "ath9k_tx_start" in current context.
(gdb) l *(ath9k_tx+0x284)
0x4854 is in ath_paprd_activate (drivers/net/wireless/ath/ath9k/main.c:395).
390 continue;
391
392 ar9003_paprd_populate_single_table(ah, caldata, chain);
393 }
394
395 ar9003_paprd_enable(ah, true);
396 ath9k_ps_restore(sc);
397 }
398
399 static bool ath_paprd_send_frame(struct ath_softc *sc, struct
sk_buff *skb, int chain)
right now I am running next, will wait for the RX DMA to get a clean
trace, then will look to see.. as for the other issue I just rebooted
and hit this during bootup.
Justin P. Mattock
^ permalink raw reply
* Re: ath: DMA failed to stop in 10 ms AR_CR=0x00000024 AR_DIAG_SW=0x02000020 DMADBG_7=0x00008040
From: Mohammed Shafi @ 2012-03-20 6:32 UTC (permalink / raw)
To: Justin P. Mattock
Cc: Linux-wireless, Felix Fietkau, linux-kernel, Linux-netdev
In-Reply-To: <4F68235C.5090701@gmail.com>
On Tue, Mar 20, 2012 at 11:57 AM, Justin P. Mattock
<justinmattock@gmail.com> wrote:
> On 03/19/2012 11:19 PM, Mohammed Shafi wrote:
>>>
>>> (gdb) list *ath9k_tx+start+0x284
>>> No symbol "start" in current context.
>>
>>
>> hey, pls try l *(ath9k_tx_start+0x284), yesterday i did the same in
>> the latest wireless testing tree it pointed to line 1929 of xmit.c
>>
>> sc->tx.seq_no +=0x10;
>>
>> also did few suspend/resume in my machine, nothing interesting happened
>>
>>>
>>> before receiving the email to do the above code with gdb I had cleaned
>>> the
>>> tree out with git clean -fx so rebuilding might have misalighned
>>> things(but
>>> could be wrong)..
>>>
>>
>>
>>
>
>
> seems gdb is not working with that code but works if I remove _start.
> (maybe -next took this out or something)
>
> (gdb) l *(ath9k_tx_start+0x284)
> No symbol "ath9k_tx_start" in current context.
sorry its
l *(ath_tx_start+0x284)
> (gdb) l *(ath9k_tx+0x284)
> 0x4854 is in ath_paprd_activate (drivers/net/wireless/ath/ath9k/main.c:395).
> 390 continue;
> 391
> 392 ar9003_paprd_populate_single_table(ah, caldata,
> chain);
> 393 }
> 394
> 395 ar9003_paprd_enable(ah, true);
> 396 ath9k_ps_restore(sc);
> 397 }
> 398
> 399 static bool ath_paprd_send_frame(struct ath_softc *sc, struct
> sk_buff *skb, int chain)
>
> right now I am running next, will wait for the RX DMA to get a clean trace,
> then will look to see.. as for the other issue I just rebooted and hit this
> during bootup.
>
> Justin P. Mattock
--
thanks,
shafi
^ permalink raw reply
* Re: ath: DMA failed to stop in 10 ms AR_CR=0x00000024 AR_DIAG_SW=0x02000020 DMADBG_7=0x00008040
From: Justin P. Mattock @ 2012-03-20 6:36 UTC (permalink / raw)
To: Mohammed Shafi; +Cc: Linux-wireless, Felix Fietkau, linux-kernel, Linux-netdev
In-Reply-To: <CAD2nsn0toAjyWw48J7oREES0=x6D72hMntP+WpAjHmR5drd-tQ@mail.gmail.com>
On 03/19/2012 11:32 PM, Mohammed Shafi wrote:
> On Tue, Mar 20, 2012 at 11:57 AM, Justin P. Mattock
> <justinmattock@gmail.com> wrote:
>> On 03/19/2012 11:19 PM, Mohammed Shafi wrote:
>>>>
>>>> (gdb) list *ath9k_tx+start+0x284
>>>> No symbol "start" in current context.
>>>
>>>
>>> hey, pls try l *(ath9k_tx_start+0x284), yesterday i did the same in
>>> the latest wireless testing tree it pointed to line 1929 of xmit.c
>>>
>>> sc->tx.seq_no +=0x10;
>>>
>>> also did few suspend/resume in my machine, nothing interesting happened
>>>
>>>>
>>>> before receiving the email to do the above code with gdb I had cleaned
>>>> the
>>>> tree out with git clean -fx so rebuilding might have misalighned
>>>> things(but
>>>> could be wrong)..
>>>>
>>>
>>>
>>>
>>
>>
>> seems gdb is not working with that code but works if I remove _start.
>> (maybe -next took this out or something)
>>
>> (gdb) l *(ath9k_tx_start+0x284)
>> No symbol "ath9k_tx_start" in current context.
>
> sorry its
> l *(ath_tx_start+0x284)
>
>> (gdb) l *(ath9k_tx+0x284)
>> 0x4854 is in ath_paprd_activate (drivers/net/wireless/ath/ath9k/main.c:395).
>> 390 continue;
>> 391
>> 392 ar9003_paprd_populate_single_table(ah, caldata,
>> chain);
>> 393 }
>> 394
>> 395 ar9003_paprd_enable(ah, true);
>> 396 ath9k_ps_restore(sc);
>> 397 }
>> 398
>> 399 static bool ath_paprd_send_frame(struct ath_softc *sc, struct
>> sk_buff *skb, int chain)
>>
>> right now I am running next, will wait for the RX DMA to get a clean trace,
>> then will look to see.. as for the other issue I just rebooted and hit this
>> during bootup.
>>
>> Justin P. Mattock
>
>
>
yeah this works:
eading symbols from
/home/kernel/linux-next/drivers/net/wireless/ath/ath9k/ath9k.o...done.
(gdb) l *(ath_tx_start+0x284)
0xcad4 is in ath_tx_start (drivers/net/wireless/ath/ath9k/xmit.c:1878).
1873 ieee80211_is_data_qos(hdr->frame_control)) {
1874 tidno = ieee80211_get_qos_ctl(hdr)[0] &
1875 IEEE80211_QOS_CTL_TID_MASK;
1876 tid = ATH_AN_2_TID(txctl->an, tidno);
1877
1878 WARN_ON(tid->ac->txq != txctl->txq);
1879 }
1880
1881 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
1882 /*
(gdb)
^ permalink raw reply
* Re: [PATCH net-next v4] ipv6: Allocate unique metrics for icmp6 packets to prevent tainting dst metrics
From: David Miller @ 2012-03-20 7:10 UTC (permalink / raw)
To: nick.jones; +Cc: eric.dumazet, netdev
In-Reply-To: <1332222481.25418.540.camel@nbnickhq4>
From: Nick Jones <nick.jones@network-box.com>
Date: Tue, 20 Mar 2012 13:48:01 +0800
> On Mon, 2012-03-19 at 18:04 -0400, David Miller wrote:
>> Furthermore, callers are only ready to handle NULL vs. non-NULL as
>> return values from this function. So this return value you are adding
>> will result in crashes.
>
> This one I did check. icmp6_dst_alloc returns error encoded pointers
> and all call sites test the return value with IS_ERR, I simply didn't
> understand the correct formatting macro, nor check the build properly.
> I think you got it mixed up with ip6_dst_alloc
Indeed you're right on this one. We changed this recently, in fact.
^ permalink raw reply
* Re: 3.0.23 WARNING: at net/ipv4/tcp_input.c:3375 tcp_ack+0x1d62/0x2030()
From: Stefan Priebe - Profihost AG @ 2012-03-20 7:30 UTC (permalink / raw)
To: David Miller; +Cc: ncardwell, eric.dumazet, greg, stable, netdev
In-Reply-To: <20120319.142412.1284054436734248444.davem@davemloft.net>
Am 19.03.2012 19:24, schrieb David Miller:
>> Perfect, thanks!
>>
>> Greg any ETA?
>
> He released it the very second he told you to use it.
Thanks - Greg is just too fast for me ;-)
Stefan
^ permalink raw reply
* Re: ath: DMA failed to stop in 10 ms AR_CR=0x00000024 AR_DIAG_SW=0x02000020 DMADBG_7=0x00008040
From: Mohammed Shafi @ 2012-03-20 7:44 UTC (permalink / raw)
To: Justin P. Mattock
Cc: Linux-wireless, Felix Fietkau, linux-kernel, Linux-netdev
In-Reply-To: <4F682555.3020502@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1319 bytes --]
> /home/kernel/linux-next/drivers/net/wireless/ath/ath9k/ath9k.o...done.
> (gdb) l *(ath_tx_start+0x284)
> 0xcad4 is in ath_tx_start (drivers/net/wireless/ath/ath9k/xmit.c:1878).
> 1873 ieee80211_is_data_qos(hdr->frame_control)) {
> 1874 tidno = ieee80211_get_qos_ctl(hdr)[0] &
> 1875 IEEE80211_QOS_CTL_TID_MASK;
> 1876 tid = ATH_AN_2_TID(txctl->an, tidno);
> 1877
> 1878 WARN_ON(tid->ac->txq != txctl->txq);
> 1879 }
> 1880
> 1881 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
> 1882 /*
> (gdb
please check with the attached debug patch if tid is 'NULL'
its my theory that tid is not initialized in ath_tx_node_init just after resume.
during suspend ath9k_sta_remove may be called
ieee80211_suspend -> drv_sta_state ->
drv_sta_remove->ath9k_sta_remove->ath_node_detach->ath_tx_node_cleanup
during resume
ieee80211_resume ->
ieee80211_reconfig->drv_sta_state->ath9k_sta_add->ath_node_attach->ath_tx_node_init
now sta.ht_cap.ht_supported should be true. it will be set to true in
assoc_sucess path and then sta_add is called.
let me see if i had missed something or my analysis itself is wrong.
>
--
thanks,
shafi
[-- Attachment #2: debug-panic.patch --]
[-- Type: text/x-diff, Size: 493 bytes --]
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 834e6bc..eb22156 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1875,6 +1875,12 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
IEEE80211_QOS_CTL_TID_MASK;
tid = ATH_AN_2_TID(txctl->an, tidno);
+ if (!tid) {
+ printk("\ntid is NULL!!!");
+ return;
+ }
+
+
WARN_ON(tid->ac->txq != txctl->txq);
}
^ permalink raw reply related
* Re: [PATCH 1/1] net: phylib: remove the length limitation of mii bus id
From: Wolfram Sang @ 2012-03-20 7:50 UTC (permalink / raw)
To: Dong Aisheng; +Cc: netdev, davem, linux-kernel, linux-arm-kernel
In-Reply-To: <1332217679-3703-1-git-send-email-b29396@freescale.com>
[-- Attachment #1: Type: text/plain, Size: 501 bytes --]
Hi Aisheng,
> So changed to remove the bus id length limitation, a lot of handwork.
You might want to try 'coccinelle' [1] next time. This is a tool exactly for
such kind of work. Already some basic knowledge can help you for a
number of tasks.
Regards,
Wolfram
[1] http://en.wikipedia.org/wiki/Coccinelle_%28software%29
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH v2] ipv6: fix incorrent ipv6 ipsec packet fragment
From: Steffen Klassert @ 2012-03-20 7:58 UTC (permalink / raw)
To: Gao feng; +Cc: davem, netdev
In-Reply-To: <1332213779-19528-1-git-send-email-gaofeng@cn.fujitsu.com>
On Tue, Mar 20, 2012 at 11:22:59AM +0800, Gao feng wrote:
> Since commit 299b0767(ipv6: Fix IPsec slowpath fragmentation problem)
> In func ip6_append_data,after call skb_put(skb, fraglen + dst_exthdrlen)
> the skb->len contains dst_exthdrlen,and we don't reduce dst_exthdrlen at last
> This will make fraggap>0 in next "while cycle",and cause the size of skb incorrent
>
> Fix this by reserve headroom for dst_exthdrlen.
>
> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> ---
> net/ipv6/ip6_output.c | 8 +++++---
> 1 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
> index d97e071..8d5d204 100644
> --- a/net/ipv6/ip6_output.c
> +++ b/net/ipv6/ip6_output.c
> @@ -1418,6 +1418,8 @@ alloc_new_skb:
> skb->csum = 0;
> /* reserve for fragmentation */
> skb_reserve(skb, hh_len+sizeof(struct frag_hdr));
> + /* reserve for ipsec header */
> + skb_reserve(skb, dst_exthdrlen);
Why not 'reserve for fragmentation and ipsec header' instead
of calling skb_reserve() two times?
The rest of the patch looks good.
^ permalink raw reply
* RE: [PATCH 1/1] net: phylib: remove the length limitation of mii bus id
From: Dong Aisheng-B29396 @ 2012-03-20 8:13 UTC (permalink / raw)
To: Wolfram Sang
Cc: netdev@vger.kernel.org, davem@davemloft.net,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20120320075059.GA3849@pengutronix.de>
Hi Wolfram,
> > So changed to remove the bus id length limitation, a lot of handwork.
>
> You might want to try 'coccinelle' [1] next time. This is a tool exactly for
> such kind of work. Already some basic knowledge can help you for a number of
> tasks.
>
Good tool.
Thanks for the info. :-)
> Regards,
>
> Wolfram
>
> [1] http://en.wikipedia.org/wiki/Coccinelle_%28software%29
>
Regards
Dong Aisheng
^ permalink raw reply
* Re: ath: DMA failed to stop in 10 ms AR_CR=0x00000024 AR_DIAG_SW=0x02000020 DMADBG_7=0x00008040
From: Sujith Manoharan @ 2012-03-20 8:29 UTC (permalink / raw)
To: Justin P. Mattock
Cc: Mohammed Shafi, Linux-wireless, Felix Fietkau,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Linux-netdev
In-Reply-To: <4F682555.3020502-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Justin P. Mattock wrote:
> yeah this works:
>
> eading symbols from
> /home/kernel/linux-next/drivers/net/wireless/ath/ath9k/ath9k.o...done.
> (gdb) l *(ath_tx_start+0x284)
> 0xcad4 is in ath_tx_start (drivers/net/wireless/ath/ath9k/xmit.c:1878).
> 1873 ieee80211_is_data_qos(hdr->frame_control)) {
> 1874 tidno = ieee80211_get_qos_ctl(hdr)[0] &
> 1875 IEEE80211_QOS_CTL_TID_MASK;
> 1876 tid = ATH_AN_2_TID(txctl->an, tidno);
> 1877
> 1878 WARN_ON(tid->ac->txq != txctl->txq);
> 1879 }
> 1880
> 1881 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
> 1882 /*
> (gdb)
Can you try this patch ?
From: Sujith Manoharan <c_manoha-A+ZNKFmMK5xy9aJCnZT0Uw@public.gmane.org>
Date: Tue, 20 Mar 2012 13:51:26 +0530
Subject: [PATCH] ath9k: Use HW HT capabilites properly
The commit "ath9k: Remove aggregation flags" changed how
nodes were being initialized. Use the HW HT cap bits
to initialize/de-initialize nodes, else we would be
accessing an uninitialized entry during a suspend/resume cycle,
resulting in a panic.
Reported-by: Justin P. Mattock <justinmattock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Sujith Manoharan <c_manoha-A+ZNKFmMK5xy9aJCnZT0Uw@public.gmane.org>
---
drivers/net/wireless/ath/ath9k/main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3879485..215eb25 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -640,7 +640,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
an->sta = sta;
an->vif = vif;
- if (sta->ht_cap.ht_supported) {
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
ath_tx_node_init(sc, an);
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor);
@@ -659,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
an->sta = NULL;
#endif
- if (sta->ht_cap.ht_supported)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
ath_tx_node_cleanup(sc, an);
}
--
1.7.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH 1/1] net: phylib: remove the length limitation of mii bus id
From: Shawn Guo @ 2012-03-20 8:32 UTC (permalink / raw)
To: Dong Aisheng; +Cc: netdev, davem, linux-kernel, linux-arm-kernel
In-Reply-To: <1332217386-3586-1-git-send-email-b29396@freescale.com>
On 20 March 2012 12:23, Dong Aisheng <b29396@freescale.com> wrote:
> From: Dong Aisheng <dong.aisheng@linaro.org>
>
> When convert to dt, the length of old mii bus id (17 bytes) is not
> sufficent to use.
> For example, the bus id could be 800f0000.ethernet-1:00 in DT.
>
> This patch removes the bus id length limitation by changing the
> bus id to a const char pionter and user could dynamically set the
> bus id via kasprintf function call.
>
> Since then no users use MII_BUS_ID_SIZE any more, just remove it.
>
> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> ---
> The simplest way may just change MII_BUS_ID_SIZE to a more bigger size,
> but i'm not sure that's gonna be accepted.
The simplest fix has been applied on -next tree as below.
commit a7ed07d51c8abdb407be454c6cb6cfad613759d9
Author: Richard Zhao <richard.zhao@linaro.org>
Date: Sun Jan 29 22:08:12 2012 +0000
net: fec: correct phy_name buffer length when init phy_name
Fix the bug that we got wrong phy_name on imx6q sabrelite board.
snprintf used wrong length of phy_name.
phy_name length is MII_BUS_ID_SIZE + 3 rather not MII_BUS_ID_SIZE.
I change it to sizeof(phy_name).
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/ethernet/freescale/fec.c
b/drivers/net/ethernet/freescale/fec.c
index 7b25e9c..1c7aad8 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -990,7 +990,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
phy_id = 0;
}
- snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
+ snprintf(phy_name, sizeof(phy_name), PHY_ID_FMT, mdio_bus_id, phy_id);
phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0,
fep->phy_interface);
if (IS_ERR(phy_dev)) {
^ permalink raw reply related
* [PATCH v3] ipv6: fix incorrent ipv6 ipsec packet fragment
From: Gao feng @ 2012-03-20 8:36 UTC (permalink / raw)
To: davem; +Cc: steffen.klassert, netdev, Gao feng
In-Reply-To: <20120320075846.GF29891@secunet.com>
Since commit 299b0767(ipv6: Fix IPsec slowpath fragmentation problem)
In func ip6_append_data,after call skb_put(skb, fraglen + dst_exthdrlen)
the skb->len contains dst_exthdrlen,and we don't reduce dst_exthdrlen at last
This will make fraggap>0 in next "while cycle",and cause the size of skb incorrent
Fix this by reserve headroom for dst_exthdrlen.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
net/ipv6/ip6_output.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index d97e071..ea58e27a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1416,8 +1416,9 @@ alloc_new_skb:
*/
skb->ip_summed = csummode;
skb->csum = 0;
- /* reserve for fragmentation */
- skb_reserve(skb, hh_len+sizeof(struct frag_hdr));
+ /* reserve for fragmentation and ipsec header */
+ skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
+ dst_exthdrlen);
if (sk->sk_type == SOCK_DGRAM)
skb_shinfo(skb)->tx_flags = tx_flags;
@@ -1425,9 +1426,9 @@ alloc_new_skb:
/*
* Find where to start putting bytes
*/
- data = skb_put(skb, fraglen + dst_exthdrlen);
- skb_set_network_header(skb, exthdrlen + dst_exthdrlen);
- data += fragheaderlen + dst_exthdrlen;
+ data = skb_put(skb, fraglen);
+ skb_set_network_header(skb, exthdrlen);
+ data += fragheaderlen;
skb->transport_header = (skb->network_header +
fragheaderlen);
if (fraggap) {
--
1.7.7.6
^ permalink raw reply related
* Re: [PATCH] ARC VMAC driver.
From: Andreas Fenkart @ 2012-03-20 8:40 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120305.153004.120141018357651846.davem@davemloft.net>
David,
Am 5. März 2012 21:30 schrieb David Miller <davem@davemloft.net>:
> From: Andreas Fenkart <afenkart@gmail.com>
> Date: Mon, 5 Mar 2012 10:59:45 +0100
>
>> + unsigned mac_lo, mac_hi;
>
> Please never say just "unsigned" but instead use "unsigned int"
> But in this case you're dealing with a fixed sized value so
> "u32" is most appropriate.
>
>> + unsigned mac_lo, mac_hi;
>
> Same here.
>
>> +static void vmac_mdio_xmit(struct vmac_priv *ap, unsigned val)
>
> Again. So please fix this up in the entire driver.
>
>> + int report_change = 0;
>
> Please use 'bool' as the type and 'true' and 'false' as the values.
>
>> + ap->mii_bus = mdiobus_alloc();
>> + if (ap->mii_bus == NULL)
>> + return -ENOMEM;
>
> Use "if (!ap->mii_bus)" for null pointer checks.
>
>> + ap->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
>> + if (!ap->mii_bus->irq)
>
> Which inconsistently you do correctly here.
>
>> + struct vmac_priv *ap = netdev_priv(dev);
>> + dev_dbg(&ap->pdev->dev, "rx error counter overrun. status = 0x%x\n",
>> + status);
>
> Please add an empty line between the function variable declarations and
> the first actual code statement.
>
>> + if (!fifo_empty(&ap->rx_ring)) {
>> + dev_err(&ap->pdev->dev, "failed to reclaim %d rx sk_buff\n",
>> + fifo_used(&ap->rx_ring));
>> + }
>
> You don't need openning and closing braces for a single line basic
> block. It just takes up an unnecessary extra line in the source.
>
>> + /* locking: fct owns rx_ring tail to current DMA read position, alias
>> + * 'received packets'. rx_refill owns area outside rx_ring, doesn't
>> + * modify tail */
>
> Code comments:
>
> /* Like
> * this.
> */
>
> /* Or like this. */
>
> /* But not
> * like this. */
>
>
> There are other instances of this issue in the driver, please fix those
> too.
>
>> + unsigned long tmp;
>
> This is a 32-bit value not a long which is a non-fixed-sized type
> and might be 64-bit. You definitely want to use "u32" for these.
>
>> +static void vmac_toggle_rxint_unlocked(struct net_device *dev, int enable)
>
> Use 'bool' for all the places where you do this "enable" argument in
> functions.
>
>> + if ((status & RXINT_MASK) && (vmac_readl(ap, ENABLE) && RXINT_MASK) &&
>
> All of these register bit tests are wrong, you're using "&&
> RXINT_MASK" instead of "& RXINT_MASK".
>
>> + if ((status & TXINT_MASK) && (vmac_readl(ap, ENABLE) && TXINT_MASK)) {
>
> Same bug.
>
>> +static int vmac_tx_reclaim_unlocked(struct net_device *dev, int force)
>> +{
>> + struct vmac_priv *ap = netdev_priv(dev);
>> + int released = 0;
>
> Use 'bool' and true/false for 'force' and 'released'.
>
>> + dev_kfree_skb_any(skb);
>
> You only need to use the significantly more expensive dev_kfree_skb_any() if this
> code can run in a hardware interrupt handler.
>
> This is a NAPI driver and therefore it should only do reclaim from
> NAPI poll and thus software interrupt context. Therefore you can use
> dev_kfree_skb() which is 10 times faster than dev_kfree_skb_any()
> which results in a new software interrupt getting queued up.
>
>> + if (unlikely(skb->len < ETH_ZLEN)) {
>> + struct sk_buff *short_skb;
>> + short_skb = netdev_alloc_skb(dev, ETH_ZLEN);
>> + if (!short_skb)
>> + return NETDEV_TX_LOCKED;
>> +
>> + memset(short_skb->data, 0, ETH_ZLEN);
>> + memcpy(skb_put(short_skb, ETH_ZLEN), skb->data, skb->len);
>> + dev_kfree_skb(skb);
>> + skb = short_skb;
>> + }
>
> Don't reinvent the wheel, use skb_pad() or similar, which is much more efficient
> than this open-coded version.
>
>> + desc->data = dma_map_single(&ap->pdev->dev, skb->data, skb->len,
>> + DMA_TO_DEVICE);
>
> Align the argument up to the openning parenthesis on the previous line:
>
> desc->data = dma_map_single(&ap->pdev->dev, skb->data, skb->len,
> DMA_TO_DEVICE);
>
>> + ap->rxbd = dma_alloc_coherent(&ap->pdev->dev, size,
>> + &ap->rxbd_dma,
>> + GFP_KERNEL);
>
> Same problem.
>
>> + if (ap->rxbd == NULL)
>
> Test with "if (!ptr)" not "if (ptr == NULL)"
>
>> + ap->txbd = dma_alloc_coherent(&ap->pdev->dev, size,
>> + &ap->txbd_dma,
>> + GFP_KERNEL);
>
> Argument alignment.
>
>> + dma_free_coherent(&ap->pdev->dev, sizeof(*ap->txbd) * ap->tx_ring.size,
>> + ap->txbd, ap->txbd_dma);
> ...
>> + dma_free_coherent(&ap->pdev->dev, sizeof(*ap->rxbd) * ap->rx_ring.size,
>> + ap->rxbd, ap->rxbd_dma);
>
> Again and again.
>
>> + dma_free_coherent(&ap->pdev->dev, sizeof(ap->txbd) * ap->tx_ring.size,
>> + ap->txbd, ap->txbd_dma);
>> + dma_free_coherent(&ap->pdev->dev, sizeof(ap->rxbd) * ap->rx_ring.size,
>> + ap->rxbd, ap->rxbd_dma);
>
> More of the same.
>
>> + if (ap == NULL)
>
> Test "if (!ap)" instad.
>
>> + dev_err(&ap->pdev->dev, "Unable to request IRQ %d (error %d)\n",
>> + dev->irq, err);
>
> Argument alignment.
>
>> + temp |= ERR_MASK | TXCH_MASK | MSER_MASK | RXCR_MASK | RXFR_MASK | \
>> + RXFL_MASK;
>
> There is no reason to escape the newline with a "\" here, get rid of that.
>
>> + dev_info(&ap->pdev->dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
>> + phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
>
> Argument alignment.
>
>> + unsigned int temp;
>
> Use "u32" for the type.
>
>> +static void create_multicast_filter(struct net_device *dev,
>> + int32_t *bitmask)
>
> Argument alignment.
>
>> + int promisc, reg;
>
> Use 'bool' for 'promisc', use 'u32' for 'reg'.
>
>> + int32_t bitmask[2];
>
> Don't use int32_t in the kernel, use 'u32' instead.
>
>> + if (dma_get_mask(&pdev->dev) > DMA_BIT_MASK(32) ||
>> + pdev->dev.coherent_dma_mask > DMA_BIT_MASK(32)) {
>
> Align things properly:
>
> if (dma_get_mask(&pdev->dev) > DMA_BIT_MASK(32) ||
> pdev->dev.coherent_dma_mask > DMA_BIT_MASK(32)) {
>
>> + dev->flags |= IFF_MULTICAST;
>
> Why in the world do you need to do this? The ethernet generic setup takes
> care of this for you.
>
>> + if (!is_valid_ether_addr(dev->dev_addr))
>> + random_ether_addr(dev->dev_addr);
>
> Use dev_hw_addr_random() which will properly set the NET_ADDR_RANDOM attribute
> properly too.
>
>> + dev_info(&pdev->dev, "ARC VMAC at 0x%pP irq %d %pM\n", &mem->start,
>> + dev->irq, dev->dev_addr);
>
> Align the arguments properly.
>
>> +struct vmac_priv {
>
> Get rid of that ugly tab, use a single space instead.
>
>> +static inline int fifo_empty(struct dma_fifo *f)
>
> Return 'bool'.
>
>> +static inline int fifo_full(struct dma_fifo *f)
>
> Return 'bool'.
>> + pr_info("fifo: head %d, tail %d, size %d\n", fifo->head,
>> + fifo->tail,
>> + fifo->size);
>
> Align arguments properly.
Thanks. I fixed and I'll be sending out a rev 2 shortly.
Regards
Andi
^ permalink raw reply
* [PATCH 1/1] ARC VMAC driver.
From: Andreas Fenkart @ 2012-03-20 8:42 UTC (permalink / raw)
To: davem; +Cc: netdev, Andreas Fenkart
In-Reply-To: <CALtMJECEj7dtseSas9708L6xKs2fobS9_m3bVY_BCe6icLWRsA@mail.gmail.com>
This is a driver for the MAC IP block from ARC International. It
is based on an existing driver found in ARC Linux distribution,
but essentially, a full rewrite.
Signed-off-by: Andreas Fenkart <afenkart@gmail.com>
---
drivers/net/ethernet/Kconfig | 9 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/arcvmac.c | 1472 ++++++++++++++++++++++++++++++++++++++++
drivers/net/ethernet/arcvmac.h | 269 ++++++++
4 files changed, 1751 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index 597f4d4..4b6baf8 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -23,6 +23,15 @@ source "drivers/net/ethernet/aeroflex/Kconfig"
source "drivers/net/ethernet/alteon/Kconfig"
source "drivers/net/ethernet/amd/Kconfig"
source "drivers/net/ethernet/apple/Kconfig"
+
+config ARCVMAC
+ tristate "ARC VMAC ethernet driver"
+ select MII
+ select PHYLIB
+ select CRC32
+ help
+ MAC present Zoran43xx, IP from ARC international
+
source "drivers/net/ethernet/atheros/Kconfig"
source "drivers/net/ethernet/cadence/Kconfig"
source "drivers/net/ethernet/adi/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index be5dde0..cb61799 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_GRETH) += aeroflex/
obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
obj-$(CONFIG_NET_VENDOR_AMD) += amd/
obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
+obj-$(CONFIG_ARCVMAC) += arcvmac.o
obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
obj-$(CONFIG_NET_ATMEL) += cadence/
obj-$(CONFIG_NET_BFIN) += adi/
diff --git a/drivers/net/ethernet/arcvmac.c b/drivers/net/ethernet/arcvmac.c
new file mode 100644
index 0000000..d512806
--- /dev/null
+++ b/drivers/net/ethernet/arcvmac.c
@@ -0,0 +1,1472 @@
+/*
+ * ARC VMAC Driver
+ *
+ * Copyright (C) 2009-2012 Andreas Fenkart
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Initial work taken from arc linux distribution, any bugs are mine
+ *
+ * -----<snip>-----
+ * Copyright (C) 2003-2006 Codito Technologies, for linux-2.4 port
+ * Copyright (C) 2006-2007 Celunite Inc, for linux-2.6 port
+ * Authors: amit.bhor@celunite.com, sameer.dhavale@celunite.com
+ * -----<snip>-----
+ */
+
+#include <linux/clk.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+
+#include "arcvmac.h"
+
+/* Register access macros */
+#define vmac_writel(port, value, reg) \
+ writel(cpu_to_le32(value), (port)->regs + VMAC_##reg)
+#define vmac_readl(port, reg) le32_to_cpu(readl((port)->regs + VMAC_##reg))
+
+static int get_register_map(struct vmac_priv *ap);
+static int put_register_map(struct vmac_priv *ap);
+static void update_vmac_stats_unlocked(struct net_device *dev);
+static int vmac_tx_reclaim_unlocked(struct net_device *dev, bool force);
+
+static unsigned char *read_mac_reg(struct net_device *dev,
+ unsigned char hwaddr[ETH_ALEN])
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ u32 mac_lo, mac_hi;
+
+ WARN_ON(!hwaddr);
+ mac_lo = vmac_readl(ap, ADDRL);
+ mac_hi = vmac_readl(ap, ADDRH);
+
+ hwaddr[0] = (mac_lo >> 0) & 0xff;
+ hwaddr[1] = (mac_lo >> 8) & 0xff;
+ hwaddr[2] = (mac_lo >> 16) & 0xff;
+ hwaddr[3] = (mac_lo >> 24) & 0xff;
+ hwaddr[4] = (mac_hi >> 0) & 0xff;
+ hwaddr[5] = (mac_hi >> 8) & 0xff;
+ return hwaddr;
+}
+
+static void write_mac_reg(struct net_device *dev, unsigned char* hwaddr)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ u32 mac_lo, mac_hi;
+
+ mac_lo = hwaddr[3] << 24 | hwaddr[2] << 16 | hwaddr[1] << 8 |
+ hwaddr[0];
+ mac_hi = hwaddr[5] << 8 | hwaddr[4];
+
+ vmac_writel(ap, mac_lo, ADDRL);
+ vmac_writel(ap, mac_hi, ADDRH);
+}
+
+static void vmac_mdio_xmit(struct vmac_priv *ap, u32 val)
+{
+ init_completion(&ap->mdio_complete);
+ vmac_writel(ap, val, MDIO_DATA);
+ wait_for_completion(&ap->mdio_complete);
+}
+
+static int vmac_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
+{
+ struct vmac_priv *vmac = bus->priv;
+ u32 val;
+
+ /* only 5 bits allowed for phy-addr and reg_offset */
+ WARN_ON(phy_id & ~0x1f || phy_reg & ~0x1f);
+
+ val = MDIO_BASE | MDIO_OP_READ;
+ val |= phy_id << 23 | phy_reg << 18;
+ vmac_mdio_xmit(vmac, val);
+
+ val = vmac_readl(vmac, MDIO_DATA);
+ return val & MDIO_DATA_MASK;
+}
+
+static int vmac_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg,
+ u16 value)
+{
+ struct vmac_priv *vmac = bus->priv;
+ u32 val;
+
+ /* only 5 bits allowed for phy-addr and reg_offset */
+ WARN_ON(phy_id & ~0x1f || phy_reg & ~0x1f);
+
+ val = MDIO_BASE | MDIO_OP_WRITE;
+ val |= phy_id << 23 | phy_reg << 18;
+ val |= (value & MDIO_DATA_MASK);
+ vmac_mdio_xmit(vmac, val);
+
+ return 0;
+}
+
+static void vmac_handle_link_change(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct phy_device *phydev = ap->phy_dev;
+ unsigned long flags;
+ bool report_change = false;
+
+ spin_lock_irqsave(&ap->lock, flags);
+
+ if (phydev->duplex != ap->duplex) {
+ u32 tmp;
+
+ tmp = vmac_readl(ap, ENABLE);
+
+ if (phydev->duplex)
+ tmp |= ENFL_MASK;
+ else
+ tmp &= ~ENFL_MASK;
+
+ vmac_writel(ap, tmp, ENABLE);
+
+ ap->duplex = phydev->duplex;
+ report_change = true;
+ }
+
+ if (phydev->speed != ap->speed) {
+ ap->speed = phydev->speed;
+ report_change = true;
+ }
+
+ if (phydev->link != ap->link) {
+ ap->link = phydev->link;
+ report_change = true;
+ }
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ if (report_change)
+ phy_print_status(ap->phy_dev);
+}
+
+static int __devinit vmac_mii_probe(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct phy_device *phydev = NULL;
+ struct clk *vmac_clk;
+ unsigned long clock_rate;
+ int phy_addr, err;
+
+ /* find the first phy */
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+ if (ap->mii_bus->phy_map[phy_addr]) {
+ phydev = ap->mii_bus->phy_map[phy_addr];
+ break;
+ }
+ }
+
+ if (!phydev) {
+ dev_err(&ap->pdev->dev, "no PHY found\n");
+ return -ENODEV;
+ }
+
+ /* FIXME: add pin_irq, if avail */
+
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
+ &vmac_handle_link_change, 0,
+ PHY_INTERFACE_MODE_MII);
+
+ if (IS_ERR(phydev)) {
+ err = PTR_ERR(phydev);
+ dev_err(&ap->pdev->dev, "could not attach to PHY %d\n", err);
+ goto err_out;
+ }
+
+ phydev->supported &= PHY_BASIC_FEATURES;
+ phydev->supported |= SUPPORTED_Asym_Pause | SUPPORTED_Pause;
+
+ vmac_clk = clk_get(&ap->pdev->dev, "arcvmac");
+ if (IS_ERR(vmac_clk)) {
+ err = PTR_ERR(vmac_clk);
+ goto err_disconnect;
+ }
+
+ clock_rate = clk_get_rate(vmac_clk);
+ clk_put(vmac_clk);
+
+ dev_dbg(&ap->pdev->dev, "vmac_clk: %lu Hz\n", clock_rate);
+
+ if (clock_rate < 25000000)
+ phydev->supported &= ~(SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full);
+
+ phydev->advertising = phydev->supported;
+
+ ap->link = 0;
+ ap->speed = 0;
+ ap->duplex = -1;
+ ap->phy_dev = phydev;
+
+ return 0;
+
+err_disconnect:
+ phy_disconnect(phydev);
+err_out:
+ return err;
+}
+
+static int __devinit vmac_mii_init(struct vmac_priv *ap)
+{
+ unsigned long flags;
+ int err, i;
+
+ spin_lock_irqsave(&ap->lock, flags);
+
+ ap->mii_bus = mdiobus_alloc();
+ if (!ap->mii_bus)
+ return -ENOMEM;
+
+ ap->mii_bus->name = "vmac_mii_bus";
+ ap->mii_bus->read = &vmac_mdio_read;
+ ap->mii_bus->write = &vmac_mdio_write;
+
+ snprintf(ap->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
+
+ ap->mii_bus->priv = ap;
+
+ err = -ENOMEM;
+ ap->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!ap->mii_bus->irq)
+ goto err_out;
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ ap->mii_bus->irq[i] = PHY_POLL;
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ /* locking: mdio concurrency */
+
+ err = mdiobus_register(ap->mii_bus);
+ if (err)
+ goto err_out_free_mdio_irq;
+
+ err = vmac_mii_probe(ap->dev);
+ if (err)
+ goto err_out_unregister_bus;
+
+ return 0;
+
+err_out_unregister_bus:
+ mdiobus_unregister(ap->mii_bus);
+err_out_free_mdio_irq:
+ kfree(ap->mii_bus->irq);
+err_out:
+ mdiobus_free(ap->mii_bus);
+ return err;
+}
+
+static void vmac_mii_exit_unlocked(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+
+ if (ap->phy_dev)
+ phy_disconnect(ap->phy_dev);
+
+ mdiobus_unregister(ap->mii_bus);
+ kfree(ap->mii_bus->irq);
+ mdiobus_free(ap->mii_bus);
+}
+
+static int vmacether_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct phy_device *phydev = ap->phy_dev;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_ethtool_gset(phydev, cmd);
+}
+
+static int vmacether_set_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct phy_device *phydev = ap->phy_dev;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phydev, cmd);
+}
+
+static int vmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct phy_device *phydev = ap->phy_dev;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_mii_ioctl(phydev, rq, cmd);
+}
+
+static void vmacether_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ snprintf(info->bus_info, sizeof(info->bus_info),
+ "platform 0x%pP", &ap->mem->start);
+}
+
+static int update_error_counters_unlocked(struct net_device *dev, int status)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+
+ dev_dbg(&ap->pdev->dev, "rx error counter overrun. status = 0x%x\n",
+ status);
+
+ /* programming error */
+ WARN_ON(status & TXCH_MASK);
+ WARN_ON(!(status & (MSER_MASK | RXCR_MASK | RXFR_MASK | RXFL_MASK)));
+
+ if (status & MSER_MASK)
+ dev->stats.rx_over_errors += 256; /* ran out of BD */
+ if (status & RXCR_MASK)
+ dev->stats.rx_crc_errors += 256;
+ if (status & RXFR_MASK)
+ dev->stats.rx_frame_errors += 256;
+ if (status & RXFL_MASK)
+ dev->stats.rx_fifo_errors += 256;
+
+ return 0;
+}
+
+static void update_tx_errors_unlocked(struct net_device *dev, int status)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+
+ if (status & BD_UFLO)
+ dev->stats.tx_fifo_errors++;
+
+ if (ap->duplex)
+ return;
+
+ /* half duplex flags */
+ if (status & BD_LTCL)
+ dev->stats.tx_window_errors++;
+ if (status & BD_RETRY_CT)
+ dev->stats.collisions += (status & BD_RETRY_CT) >> 24;
+ if (status & BD_DROP) /* too many retries */
+ dev->stats.tx_aborted_errors++;
+ if (status & BD_DEFER)
+ dev_vdbg(&ap->pdev->dev, "\"defer to traffic\"\n");
+ if (status & BD_CARLOSS)
+ dev->stats.tx_carrier_errors++;
+}
+
+static int vmac_rx_reclaim_force_unlocked(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ int ct;
+
+ /* locking: no concurrency, runs only during shutdown */
+ WARN_ON(!ap->shutdown);
+
+ dev_dbg(&ap->pdev->dev, "need to release %d rx sk_buff\n",
+ fifo_used(&ap->rx_ring));
+
+ ct = 0;
+ while (!fifo_empty(&ap->rx_ring) && ct++ < ap->rx_ring.size) {
+ struct vmac_buffer_desc *desc;
+ struct sk_buff *skb;
+ int desc_idx;
+
+ desc_idx = ap->rx_ring.tail;
+ desc = &ap->rxbd[desc_idx];
+ fifo_inc_tail(&ap->rx_ring);
+
+ if (!ap->rx_skbuff[desc_idx]) {
+ dev_err(&ap->pdev->dev,
+ "non-populated rx_skbuff found %d\n",
+ desc_idx);
+ continue;
+ }
+
+ skb = ap->rx_skbuff[desc_idx];
+ ap->rx_skbuff[desc_idx] = NULL;
+
+ dma_unmap_single(&ap->pdev->dev, desc->data, skb->len,
+ DMA_TO_DEVICE);
+
+ dev_kfree_skb(skb);
+ }
+
+ if (!fifo_empty(&ap->rx_ring))
+ dev_err(&ap->pdev->dev, "failed to reclaim %d rx sk_buff\n",
+ fifo_used(&ap->rx_ring));
+
+ return 0;
+}
+
+/* Function refills empty buffer descriptors and passes ownership to DMA */
+static int vmac_rx_refill_unlocked(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+
+ /* locking1: protect from refill_timer
+ * locking2: fct owns area outside rx_ring, head exclusive tail,
+ * modifies head
+ */
+
+ spin_lock(&ap->refill_lock);
+
+ WARN_ON(fifo_full(&ap->rx_ring));
+
+ while (!fifo_full(&ap->rx_ring)) {
+ struct vmac_buffer_desc *desc;
+ struct sk_buff *skb;
+ dma_addr_t p;
+ int desc_idx;
+
+ desc_idx = ap->rx_ring.head;
+ desc = &ap->rxbd[desc_idx];
+
+ /* make sure we read the actual descriptor status */
+ rmb();
+
+ if (ap->rx_skbuff[desc_idx]) {
+ /* dropped packet / buffer chaining */
+ fifo_inc_head(&ap->rx_ring);
+
+ /* return to DMA */
+ wmb();
+ desc->info = cpu_to_le32(BD_DMA_OWN | ap->rx_skb_size);
+ continue;
+ }
+
+ skb = netdev_alloc_skb_ip_align(dev, ap->rx_skb_size);
+ if (!skb) {
+ dev_info(&ap->pdev->dev,
+ "failed to allocate rx_skb, skb's left %d\n",
+ fifo_used(&ap->rx_ring));
+ break;
+ }
+
+ ap->rx_skbuff[desc_idx] = skb;
+
+ p = dma_map_single(&ap->pdev->dev, skb->data, ap->rx_skb_size,
+ DMA_FROM_DEVICE);
+
+ desc->data = p;
+
+ wmb();
+ desc->info = cpu_to_le32(BD_DMA_OWN | ap->rx_skb_size);
+
+ fifo_inc_head(&ap->rx_ring);
+ }
+
+ spin_unlock(&ap->refill_lock);
+
+ /* If rx ring is still empty, set a timer to try allocating
+ * again at a later time.
+ */
+ if (fifo_empty(&ap->rx_ring) && netif_running(dev)) {
+ dev_warn(&ap->pdev->dev, "unable to refill rx ring\n");
+ ap->refill_timer.expires = jiffies + HZ;
+ add_timer(&ap->refill_timer);
+ }
+
+ return 0;
+}
+
+/* timer callback to defer refill rx queue in case we're OOM */
+static void vmac_refill_rx_timer(unsigned long data)
+{
+ vmac_rx_refill_unlocked((struct net_device *)data);
+}
+
+/* merge buffer chaining */
+static struct sk_buff *vmac_merge_rx_buffers(struct net_device *dev,
+ struct vmac_buffer_desc *after,
+ int pkt_len) /* data */
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct sk_buff *first_skb, **tail, *cur_skb;
+ struct dma_fifo *rx_ring;
+ struct vmac_buffer_desc *desc;
+
+ /* locking1: same as vmac_rx_receive */
+ /* desc->info = le32_to_cpu(desc-info) already done */
+
+ first_skb = NULL;
+ tail = NULL;
+ rx_ring = &ap->rx_ring;
+ desc = &ap->rxbd[rx_ring->tail];
+
+ WARN_ON(desc == after);
+
+ pkt_len -= ETH_FCS_LEN; /* this might obsolete 'after' */
+
+ while (desc != after && pkt_len) {
+ int buf_len, valid;
+
+ /* desc needs wrapping */
+ desc = &ap->rxbd[rx_ring->tail];
+ cur_skb = ap->rx_skbuff[rx_ring->tail];
+ ap->rx_skbuff[rx_ring->tail] = NULL;
+ WARN_ON(!cur_skb);
+
+ dma_unmap_single(&ap->pdev->dev, desc->data, ap->rx_skb_size,
+ DMA_FROM_DEVICE);
+
+ /* do not copy FCS */
+ buf_len = desc->info & BD_LEN;
+ valid = min(pkt_len, buf_len);
+ pkt_len -= valid;
+
+ skb_put(cur_skb, valid);
+
+ if (!first_skb) {
+ first_skb = cur_skb;
+ tail = &skb_shinfo(first_skb)->frag_list;
+ } else {
+ first_skb->truesize += cur_skb->truesize;
+ first_skb->data_len += valid;
+ first_skb->len += valid;
+ *tail = cur_skb;
+ tail = &cur_skb->next;
+ }
+
+ fifo_inc_tail(rx_ring);
+ }
+
+#ifdef DEBUG
+ if (unlikely(pkt_len != 0))
+ dev_err(&ap->pdev->dev, "buffer chaining bytes missing %d\n",
+ pkt_len);
+
+ if (desc != after) {
+ int buf_len = le32_to_cpu(after->info) & BD_LEN;
+ WARN_ON(buf_len > ETH_FCS_LEN);
+ }
+#endif
+
+ return first_skb;
+}
+
+static int vmac_rx_receive(struct net_device *dev, int budget)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct vmac_buffer_desc *first;
+ int processed, pkt_len, pkt_err;
+ struct dma_fifo lookahead;
+
+ /* true concurrency -> DMA engine running in parallel */
+ /* locking1: fct owns rx_ring tail to current DMA read position, alias
+ * 'received packets'. rx_refill owns area outside rx_ring, doesn't
+ * modify tail
+ */
+
+ processed = 0;
+
+ first = NULL;
+ pkt_err = pkt_len = 0;
+
+ /* look ahead, till packet complete */
+ lookahead = ap->rx_ring;
+
+ do {
+ struct vmac_buffer_desc *desc; /* cur_ */
+ int desc_idx; /* cur_ */
+ struct sk_buff *skb; /* pkt_ */
+
+ desc_idx = lookahead.tail;
+ desc = &ap->rxbd[desc_idx];
+
+ /* make sure we read the actual descriptor status */
+ rmb();
+
+ /* break if dma ownership belongs to hw */
+ if (desc->info & cpu_to_le32(BD_DMA_OWN)) {
+ /* safe the dma position */
+ ap->dma_rx_head = vmac_readl(ap, MAC_RXRING_HEAD);
+ break;
+ }
+
+ desc->info = le32_to_cpu(desc->info);
+ if (desc->info & BD_FRST) {
+ pkt_len = 0;
+ pkt_err = 0;
+
+ /* free packets up till current */
+ ap->rx_ring.tail = lookahead.tail;
+ first = desc;
+ }
+
+ fifo_inc_tail(&lookahead);
+
+ /* check bd */
+ pkt_len += desc->info & BD_LEN;
+ pkt_err |= desc->info & BD_BUFF;
+
+ if (!(desc->info & BD_LAST))
+ continue;
+
+ /* received complete packet */
+ if (unlikely(pkt_err || !first)) {
+ /* recycle buffers */
+ ap->rx_ring.tail = lookahead.tail;
+ continue;
+ }
+
+#ifdef DEBUG
+ WARN_ON(!(first->info & BD_FRST) || !(desc->info & BD_LAST));
+ WARN_ON(pkt_err);
+#endif
+
+ /* -- valid packet -- */
+
+ if (first != desc) {
+ skb = vmac_merge_rx_buffers(dev, desc, pkt_len);
+
+ if (!skb) {
+ /* kill packet */
+ ap->rx_ring.tail = lookahead.tail;
+ ap->rx_merge_error++;
+ continue;
+ }
+ } else {
+ dma_unmap_single(&ap->pdev->dev, desc->data,
+ ap->rx_skb_size, DMA_FROM_DEVICE);
+
+ skb = ap->rx_skbuff[desc_idx];
+ ap->rx_skbuff[desc_idx] = NULL;
+ /* desc->data != skb->data => desc->data DMA mapped */
+
+ /* strip FCS */
+ skb_put(skb, pkt_len - ETH_FCS_LEN);
+ }
+
+ /* free buffers */
+ ap->rx_ring.tail = lookahead.tail;
+
+#ifdef DEBUG
+ WARN_ON(skb->len != pkt_len - ETH_FCS_LEN);
+#endif
+ processed++;
+ skb->protocol = eth_type_trans(skb, dev);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ netif_receive_skb(skb);
+
+ } while (!fifo_empty(&lookahead) && (processed < budget));
+
+ dev_vdbg(&ap->pdev->dev, "processed pkt %d, remaining rx buff %d\n",
+ processed,
+ fifo_used(&ap->rx_ring));
+
+ if (processed || fifo_empty(&ap->rx_ring))
+ vmac_rx_refill_unlocked(dev);
+
+ return processed;
+}
+
+static void vmac_toggle_irqmask_unlocked(struct net_device *dev, bool enable,
+ int mask)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ u32 tmp;
+
+ tmp = vmac_readl(ap, ENABLE);
+ if (enable)
+ tmp |= mask;
+ else
+ tmp &= ~mask;
+ vmac_writel(ap, tmp, ENABLE);
+}
+
+static void vmac_toggle_rxint_unlocked(struct net_device *dev, bool enable)
+{
+ vmac_toggle_irqmask_unlocked(dev, enable, RXINT_MASK);
+}
+
+static void vmac_toggle_txint_unlocked(struct net_device *dev, bool enable)
+{
+ vmac_toggle_irqmask_unlocked(dev, enable, TXINT_MASK);
+}
+
+static int vmac_poll(struct napi_struct *napi, int budget)
+{
+ struct vmac_priv *ap;
+ int rx_work_done;
+
+ ap = container_of(napi, struct vmac_priv, napi);
+
+ vmac_tx_reclaim_unlocked(ap->dev, false);
+
+ rx_work_done = vmac_rx_receive(ap->dev, budget);
+ if (rx_work_done >= budget) {
+ /* rx queue is not yet empty/clean */
+ return rx_work_done;
+ }
+
+ /* no more packet in rx/tx queue, remove device from poll queue */
+ napi_complete(napi);
+
+ /* clear status, only 1' affect register state */
+ vmac_writel(ap, RXINT_MASK | TXINT_MASK, STAT);
+
+ /* reenable IRQ */
+ vmac_toggle_rxint_unlocked(ap->dev, true);
+ vmac_toggle_txint_unlocked(ap->dev, true);
+
+ return rx_work_done;
+}
+
+static irqreturn_t vmac_intr(int irq, void *dev_instance)
+{
+ struct net_device *dev = dev_instance;
+ struct vmac_priv *ap = netdev_priv(dev);
+ u32 status;
+
+ spin_lock(&ap->lock);
+
+ status = vmac_readl(ap, STAT);
+ vmac_writel(ap, status, STAT);
+
+ if (unlikely(ap->shutdown))
+ dev_err(&ap->pdev->dev, "ISR during close\n");
+
+ if (unlikely(!status & (RXINT_MASK|MDIO_MASK|ERR_MASK)))
+ dev_err(&ap->pdev->dev, "Spurious IRQ\n");
+
+ if ((status & RXINT_MASK) && (vmac_readl(ap, ENABLE) & RXINT_MASK) &&
+ (ap->dma_rx_head != vmac_readl(ap, MAC_RXRING_HEAD))) {
+ vmac_toggle_rxint_unlocked(dev, false);
+ napi_schedule(&ap->napi);
+ }
+
+ if ((status & TXINT_MASK) && (vmac_readl(ap, ENABLE) & TXINT_MASK)) {
+ vmac_toggle_txint_unlocked(dev, false);
+ napi_schedule(&ap->napi);
+ }
+
+ if (status & MDIO_MASK)
+ complete(&ap->mdio_complete);
+
+ if (unlikely(status & ERR_MASK))
+ update_error_counters_unlocked(dev, status);
+
+ spin_unlock(&ap->lock);
+
+ return IRQ_HANDLED;
+}
+
+static int vmac_tx_reclaim_unlocked(struct net_device *dev, bool force)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ int released = 0;
+
+ /* locking1: modifies tx_ring tail, head only during shutdown */
+ /* locking2: call with ap->lock held */
+ WARN_ON(force && !ap->shutdown);
+
+ /* buffer chaining not used, see vmac_start_xmit */
+
+ while (!fifo_empty(&ap->tx_ring)) {
+ struct vmac_buffer_desc *desc;
+ struct sk_buff *skb;
+ int desc_idx;
+
+ desc_idx = ap->tx_ring.tail;
+ desc = &ap->txbd[desc_idx];
+
+ /* ensure other field of the descriptor were not read
+ * before we checked ownership
+ */
+ rmb();
+
+ if ((desc->info & cpu_to_le32(BD_DMA_OWN)) && !force)
+ break;
+
+ if (desc->info & cpu_to_le32(BD_TX_ERR))
+ /* recycle packet, let upper level deal with it */
+ update_tx_errors_unlocked(dev, le32_to_cpu(desc->info));
+
+ skb = ap->tx_skbuff[desc_idx];
+ ap->tx_skbuff[desc_idx] = NULL;
+ WARN_ON(!skb);
+
+ dma_unmap_single(&ap->pdev->dev, desc->data, skb->len,
+ DMA_TO_DEVICE);
+
+ dev_kfree_skb(skb);
+
+ released++;
+ fifo_inc_tail(&ap->tx_ring);
+ }
+
+ if (unlikely(netif_queue_stopped(dev)) && released)
+ netif_wake_queue(dev);
+
+ if (unlikely(force && !fifo_empty(&ap->tx_ring)))
+ dev_err(&ap->pdev->dev, "failed to reclaim %d tx sk_buff\n",
+ fifo_used(&ap->tx_ring));
+
+ return released;
+}
+
+static int vmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct vmac_buffer_desc *desc;
+
+ /* running under xmit lock */
+ /* locking: modifies tx_ring head, tx_reclaim only tail */
+
+ /* no scatter/gatter see features below */
+ WARN_ON(skb_shinfo(skb)->nr_frags != 0);
+ WARN_ON(skb->len > MAX_TX_BUFFER_LEN);
+
+ if (unlikely(fifo_full(&ap->tx_ring))) {
+ netif_stop_queue(dev);
+ dev_err(&ap->pdev->dev,
+ "xmit called while no tx desc available\n");
+ return NETDEV_TX_BUSY;
+ }
+
+ if (unlikely(skb->len < ETH_ZLEN)) {
+ if (skb_padto(skb, ETH_ZLEN))
+ return NETDEV_TX_OK;
+ skb_put(skb, ETH_ZLEN - skb->len);
+ }
+
+ /* fill descriptor */
+ ap->tx_skbuff[ap->tx_ring.head] = skb;
+ desc = &ap->txbd[ap->tx_ring.head];
+ WARN_ON(desc->info & cpu_to_le32(BD_DMA_OWN));
+
+ desc->data = dma_map_single(&ap->pdev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+
+ /* dma might already be polling */
+ wmb();
+ desc->info = cpu_to_le32(BD_DMA_OWN | BD_FRST | BD_LAST | skb->len);
+
+ /* kick tx dma, only 1' affect register */
+ vmac_writel(ap, TXPL_MASK, STAT);
+
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+ fifo_inc_head(&ap->tx_ring);
+
+ /* stop queue if no more desc available */
+ if (fifo_full(&ap->tx_ring))
+ netif_stop_queue(dev);
+
+ return NETDEV_TX_OK;
+}
+
+static int alloc_buffers_unlocked(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ int size, err = -ENOMEM;
+
+ fifo_init(&ap->rx_ring, RX_BDT_LEN);
+ fifo_init(&ap->tx_ring, TX_BDT_LEN);
+
+ /* initialize skb list */
+ memset(ap->rx_skbuff, 0, sizeof(ap->rx_skbuff));
+ memset(ap->tx_skbuff, 0, sizeof(ap->tx_skbuff));
+
+ /* allocate DMA received descriptors */
+ size = sizeof(*ap->rxbd) * ap->rx_ring.size;
+ ap->rxbd = dma_alloc_coherent(&ap->pdev->dev, size,
+ &ap->rxbd_dma,
+ GFP_KERNEL);
+ if (!ap->rxbd)
+ goto err_out;
+
+ /* allocate DMA transmit descriptors */
+ size = sizeof(*ap->txbd) * ap->tx_ring.size;
+ ap->txbd = dma_alloc_coherent(&ap->pdev->dev, size,
+ &ap->txbd_dma,
+ GFP_KERNEL);
+ if (!ap->txbd)
+ goto err_free_rxbd;
+
+ /* ensure 8-byte aligned */
+ WARN_ON(((uintptr_t)ap->txbd & 0x7) || ((uintptr_t)ap->rxbd & 0x7));
+
+ memset(ap->txbd, 0, sizeof(*ap->txbd) * ap->tx_ring.size);
+ memset(ap->rxbd, 0, sizeof(*ap->rxbd) * ap->rx_ring.size);
+
+ /* allocate rx skb */
+ err = vmac_rx_refill_unlocked(dev);
+ if (err)
+ goto err_free_txbd;
+
+ return 0;
+
+err_free_txbd:
+ dma_free_coherent(&ap->pdev->dev, sizeof(*ap->txbd) * ap->tx_ring.size,
+ ap->txbd, ap->txbd_dma);
+err_free_rxbd:
+ dma_free_coherent(&ap->pdev->dev, sizeof(*ap->rxbd) * ap->rx_ring.size,
+ ap->rxbd, ap->rxbd_dma);
+err_out:
+ return err;
+}
+
+static int free_buffers_unlocked(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+
+ /* free skbuff */
+ vmac_tx_reclaim_unlocked(dev, true);
+ vmac_rx_reclaim_force_unlocked(dev);
+
+ /* free DMA ring */
+ dma_free_coherent(&ap->pdev->dev, sizeof(ap->txbd) * ap->tx_ring.size,
+ ap->txbd, ap->txbd_dma);
+ dma_free_coherent(&ap->pdev->dev, sizeof(ap->rxbd) * ap->rx_ring.size,
+ ap->rxbd, ap->rxbd_dma);
+
+ return 0;
+}
+
+static int vmac_hw_init(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+
+ /* clear IRQ mask */
+ vmac_writel(ap, 0, ENABLE);
+
+ /* clear pending IRQ */
+ vmac_writel(ap, 0xffffffff, STAT);
+
+ /* Initialize logical address filter */
+ vmac_writel(ap, 0x0, LAFL);
+ vmac_writel(ap, 0x0, LAFH);
+
+ return 0;
+}
+
+static int vmac_open(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ struct phy_device *phydev;
+ unsigned long flags;
+ u32 mask, ctrl;
+ int err = 0;
+
+ /* locking: no concurrency yet */
+
+ if (!ap)
+ return -ENODEV;
+
+ spin_lock_irqsave(&ap->lock, flags);
+ ap->shutdown = false;
+
+ err = get_register_map(ap);
+ if (err)
+ return err;
+
+ vmac_hw_init(dev);
+
+ /* mac address changed? */
+ write_mac_reg(dev, dev->dev_addr);
+
+ err = alloc_buffers_unlocked(dev);
+ if (err)
+ return err;
+
+ /* install DMA ring pointers */
+ vmac_writel(ap, ap->rxbd_dma, RXRINGPTR);
+ vmac_writel(ap, ap->txbd_dma, TXRINGPTR);
+
+ /* set poll rate to 1 ms */
+ vmac_writel(ap, POLLRATE_TIME, POLLRATE);
+
+ /* Set control */
+ ctrl = (RX_BDT_LEN << 24) | (TX_BDT_LEN << 16) | TXRN_MASK | RXRN_MASK;
+ vmac_writel(ap, ctrl, CONTROL);
+
+ /* make sure we enable napi before rx interrupt */
+ napi_enable(&ap->napi);
+
+ err = request_irq(dev->irq, &vmac_intr, 0, dev->name, dev);
+ if (err) {
+ dev_err(&ap->pdev->dev, "Unable to request IRQ %d (error %d)\n",
+ dev->irq, err);
+ goto err_free_buffers;
+ }
+
+ /* IRQ mask */
+ mask = RXINT_MASK | MDIO_MASK | TXINT_MASK;
+ mask |= ERR_MASK | TXCH_MASK | MSER_MASK | RXCR_MASK | RXFR_MASK |
+ RXFL_MASK;
+ vmac_writel(ap, mask, ENABLE);
+
+ /* enable, after all other bits are set */
+ vmac_writel(ap, ctrl | EN_MASK, CONTROL);
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ /* locking: concurrency */
+
+ netif_start_queue(dev);
+ netif_carrier_off(dev);
+
+ /* register the PHY board fixup, if needed */
+ err = vmac_mii_init(ap);
+ if (err)
+ goto err_free_irq;
+
+ /* schedule a link state check */
+ phy_start(ap->phy_dev);
+
+ phydev = ap->phy_dev;
+ dev_info(&ap->pdev->dev,
+ "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
+
+ return 0;
+
+err_free_irq:
+ free_irq(dev->irq, dev);
+err_free_buffers:
+ napi_disable(&ap->napi);
+ free_buffers_unlocked(dev);
+ return err;
+}
+
+static int vmac_close(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ unsigned long flags;
+ u32 tmp;
+
+ /* locking: protect everything, DMA / IRQ / timer */
+ spin_lock_irqsave(&ap->lock, flags);
+
+ /* complete running transfer, then stop */
+ tmp = vmac_readl(ap, CONTROL);
+ tmp &= ~(TXRN_MASK | RXRN_MASK);
+ vmac_writel(ap, tmp, CONTROL);
+
+ /* save statistics, before unmapping */
+ update_vmac_stats_unlocked(dev);
+
+ /* reenable IRQ, process pending */
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(20));
+
+ /* shut it down now */
+ spin_lock_irqsave(&ap->lock, flags);
+ ap->shutdown = true;
+
+ netif_stop_queue(dev);
+ napi_disable(&ap->napi);
+
+ /* disable phy */
+ phy_stop(ap->phy_dev);
+ vmac_mii_exit_unlocked(dev);
+ netif_carrier_off(dev);
+
+ /* disable interrupts */
+ vmac_writel(ap, 0, ENABLE);
+ free_irq(dev->irq, dev);
+
+ /* turn off vmac */
+ vmac_writel(ap, 0, CONTROL);
+ /* vmac_reset_hw(vmac) */
+
+ /* locking: concurrency off */
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ del_timer_sync(&ap->refill_timer);
+ free_buffers_unlocked(dev);
+
+ put_register_map(ap);
+
+ return 0;
+}
+
+static void update_vmac_stats_unlocked(struct net_device *dev)
+{
+ struct net_device_stats *_stats = &dev->stats;
+ struct vmac_priv *ap = netdev_priv(dev);
+ unsigned int rxfram, rxcrc, rxoflow;
+ u32 miss, rxerr;
+
+ /* compare with /proc/net/dev,
+ * see net/core/dev.c:dev_seq_printf_stats */
+
+ if (ap->shutdown)
+ /* device already unmapped */
+ return;
+
+ /* rx stats */
+ rxerr = vmac_readl(ap, RXERR);
+ miss = vmac_readl(ap, MISS);
+
+ rxcrc = (rxerr & RXERR_CRC);
+ rxfram = (rxerr & RXERR_FRM) >> 8;
+ rxoflow = (rxerr & RXERR_OFLO) >> 16;
+
+ _stats->rx_length_errors = 0;
+ _stats->rx_over_errors += miss;
+ _stats->rx_crc_errors += rxcrc;
+ _stats->rx_frame_errors += rxfram;
+ _stats->rx_fifo_errors += rxoflow;
+ _stats->rx_missed_errors = 0;
+
+ /* TODO check rx_dropped/rx_errors/tx_dropped/tx_errors have not
+ * been updated elsewhere
+ */
+ _stats->rx_dropped = _stats->rx_over_errors +
+ _stats->rx_fifo_errors +
+ ap->rx_merge_error;
+
+ _stats->rx_errors = _stats->rx_length_errors + _stats->rx_crc_errors +
+ _stats->rx_frame_errors +
+ _stats->rx_missed_errors +
+ _stats->rx_dropped;
+
+ /* tx stats */
+ _stats->tx_dropped = 0; /* otherwise queue stopped */
+
+ _stats->tx_errors = _stats->tx_aborted_errors +
+ _stats->tx_carrier_errors +
+ _stats->tx_fifo_errors +
+ _stats->tx_heartbeat_errors +
+ _stats->tx_window_errors +
+ _stats->tx_dropped +
+ ap->tx_timeout_error;
+}
+
+static struct net_device_stats *vmac_stats(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ap->lock, flags);
+ update_vmac_stats_unlocked(dev);
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ return &dev->stats;
+}
+
+static void vmac_tx_timeout(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ unsigned long flags;
+ u32 status;
+
+ spin_lock_irqsave(&ap->lock, flags);
+
+ /* queue did not progress for timeo jiffies */
+ WARN_ON(!netif_queue_stopped(dev));
+ WARN_ON(!fifo_full(&ap->tx_ring));
+
+ /* TX IRQ lost? */
+ status = vmac_readl(ap, STAT);
+ if (status & TXINT_MASK) {
+ dev_err(&ap->pdev->dev, "lost tx interrupt, IRQ mask %x\n",
+ vmac_readl(ap, ENABLE));
+ vmac_writel(ap, TXINT_MASK, STAT);
+ }
+
+ /* TODO RX/MDIO/ERR as well? */
+
+ vmac_tx_reclaim_unlocked(dev, false);
+ if (fifo_full(&ap->tx_ring))
+ dev_err(&ap->pdev->dev, "DMA state machine not active\n");
+
+ /* We can accept TX packets again */
+ ap->tx_timeout_error++;
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+}
+
+static void create_multicast_filter(struct net_device *dev,
+ int32_t *bitmask)
+{
+ char *addrs;
+ u32 crc;
+
+ /* locking: done by net_device */
+
+ WARN_ON(netdev_mc_count(dev) == 0);
+ WARN_ON(dev->flags & IFF_ALLMULTI);
+
+ bitmask[0] = bitmask[1] = 0;
+
+ {
+ struct netdev_hw_addr *ha;
+ netdev_for_each_mc_addr(ha, dev) {
+ addrs = ha->addr;
+
+ /* skip non-multicast addresses */
+ if (!(*addrs & 1))
+ continue;
+
+ /* map to 0..63 */
+ crc = ether_crc_le(ETH_ALEN, addrs) >> 26;
+ bitmask[crc >= 32] |= 1UL << (crc & 31);
+ }
+ }
+}
+
+static void vmac_set_multicast_list(struct net_device *dev)
+{
+ struct vmac_priv *ap = netdev_priv(dev);
+ unsigned long flags;
+ u32 bitmask[2], reg;
+ bool promisc;
+
+ spin_lock_irqsave(&ap->lock, flags);
+
+ promisc = !!(dev->flags & IFF_PROMISC);
+ reg = vmac_readl(ap, ENABLE);
+ if (promisc != !!(reg & PROM_MASK)) {
+ reg ^= PROM_MASK;
+ vmac_writel(ap, reg, ENABLE);
+ }
+
+ if (dev->flags & IFF_ALLMULTI)
+ memset(bitmask, 1, sizeof(bitmask));
+ else if (netdev_mc_count(dev) == 0)
+ memset(bitmask, 0, sizeof(bitmask));
+ else
+ create_multicast_filter(dev, bitmask);
+
+ vmac_writel(ap, bitmask[0], LAFL);
+ vmac_writel(ap, bitmask[1], LAFH);
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+}
+
+static const struct ethtool_ops vmac_ethtool_ops = {
+ .get_settings = vmacether_get_settings,
+ .set_settings = vmacether_set_settings,
+ .get_drvinfo = vmacether_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+};
+
+static const struct net_device_ops vmac_netdev_ops = {
+ .ndo_open = vmac_open,
+ .ndo_stop = vmac_close,
+ .ndo_get_stats = vmac_stats,
+ .ndo_start_xmit = vmac_start_xmit,
+ .ndo_do_ioctl = vmac_ioctl,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_tx_timeout = vmac_tx_timeout,
+ .ndo_set_rx_mode = vmac_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+};
+
+static int get_register_map(struct vmac_priv *ap)
+{
+ int err;
+
+ err = -EBUSY;
+ if (!request_mem_region(ap->mem->start, resource_size(ap->mem),
+ DRV_NAME)) {
+ dev_err(&ap->pdev->dev, "no memory region available\n");
+ return err;
+ }
+
+ err = -ENOMEM;
+ ap->regs = ioremap(ap->mem->start, resource_size(ap->mem));
+ if (!ap->regs) {
+ dev_err(&ap->pdev->dev, "failed to map registers, aborting.\n");
+ goto err_out_release_mem;
+ }
+
+ return 0;
+
+err_out_release_mem:
+ release_mem_region(ap->mem->start, resource_size(ap->mem));
+ return err;
+}
+
+static int put_register_map(struct vmac_priv *ap)
+{
+ iounmap(ap->regs);
+ release_mem_region(ap->mem->start, resource_size(ap->mem));
+ return 0;
+}
+
+static int __devinit vmac_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct vmac_priv *ap;
+ struct resource *mem;
+ int err;
+
+ /* locking: no concurrency */
+
+ if (dma_get_mask(&pdev->dev) > DMA_BIT_MASK(32) ||
+ pdev->dev.coherent_dma_mask > DMA_BIT_MASK(32)) {
+ dev_err(&pdev->dev,
+ "arcvmac supports only 32-bit DMA addresses\n");
+ return -ENODEV;
+ }
+
+ dev = alloc_etherdev(sizeof(*ap));
+ if (!dev) {
+ dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n");
+ return -ENOMEM;
+ }
+
+ ap = netdev_priv(dev);
+
+ err = -ENODEV;
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "no mmio resource defined\n");
+ goto err_out;
+ }
+ ap->mem = mem;
+
+ err = platform_get_irq(pdev, 0);
+ if (err < 0) {
+ dev_err(&pdev->dev, "no irq found\n");
+ goto err_out;
+ }
+ dev->irq = err;
+
+ spin_lock_init(&ap->lock);
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ ap->dev = dev;
+ ap->pdev = pdev;
+
+ /* init rx timeout (used for oom) */
+ init_timer(&ap->refill_timer);
+ ap->refill_timer.function = vmac_refill_rx_timer;
+ ap->refill_timer.data = (unsigned long)dev;
+ spin_lock_init(&ap->refill_lock);
+
+ netif_napi_add(dev, &ap->napi, vmac_poll, 64);
+ dev->netdev_ops = &vmac_netdev_ops;
+ dev->ethtool_ops = &vmac_ethtool_ops;
+
+ dev->base_addr = (unsigned long)ap->regs;
+
+ /* prevent buffer chaining, favor speed over space */
+ ap->rx_skb_size = ETH_FRAME_LEN + VMAC_BUFFER_PAD;
+
+ /* private struct functional */
+
+ /* temporarily map registers to fetch mac addr */
+ err = get_register_map(ap);
+ if (err)
+ goto err_out;
+
+ /* mac address intialize, set vmac_open */
+ read_mac_reg(dev, dev->dev_addr);
+
+ if (!is_valid_ether_addr(dev->dev_addr))
+ dev_hw_addr_random(dev, dev->dev_addr);
+
+ err = register_netdev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
+ goto err_out;
+ }
+
+ /* release the memory region, till open is called */
+ put_register_map(ap);
+
+ dev_info(&pdev->dev, "ARC VMAC at 0x%pP irq %d %pM\n", &mem->start,
+ dev->irq, dev->dev_addr);
+ platform_set_drvdata(pdev, ap);
+
+ return 0;
+
+err_out:
+ free_netdev(dev);
+ return err;
+}
+
+static int __devexit vmac_remove(struct platform_device *pdev)
+{
+ struct vmac_priv *ap;
+
+ /* locking: no concurrency */
+
+ ap = platform_get_drvdata(pdev);
+ if (!ap) {
+ dev_err(&pdev->dev, "vmac_remove no valid dev found\n");
+ return 0;
+ }
+
+ /* MAC */
+ unregister_netdev(ap->dev);
+ netif_napi_del(&ap->napi);
+
+ platform_set_drvdata(pdev, NULL);
+ free_netdev(ap->dev);
+ return 0;
+}
+
+static struct platform_driver arcvmac_driver = {
+ .probe = vmac_probe,
+ .remove = __devexit_p(vmac_remove),
+ .driver = {
+ .name = "arcvmac",
+ },
+};
+
+static int __init vmac_init(void)
+{
+ return platform_driver_register(&arcvmac_driver);
+}
+
+static void __exit vmac_exit(void)
+{
+ platform_driver_unregister(&arcvmac_driver);
+}
+
+module_init(vmac_init);
+module_exit(vmac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ARC VMAC Ethernet driver");
+MODULE_AUTHOR("afenkart@gmail.com");
diff --git a/drivers/net/ethernet/arcvmac.h b/drivers/net/ethernet/arcvmac.h
new file mode 100644
index 0000000..f94ab38
--- /dev/null
+++ b/drivers/net/ethernet/arcvmac.h
@@ -0,0 +1,269 @@
+/*
+ * ARC VMAC Driver
+ *
+ * Copyright (C) 2009-2012 Andreas Fenkart
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Initial work taken from arc linux distribution, any bugs are mine
+ *
+ * -----<snip>-----
+ * Copyright (C) 2003-2006 Codito Technologies, for linux-2.4 port
+ * Copyright (C) 2006-2007 Celunite Inc, for linux-2.6 port
+ * Authors: amit.bhor@celunite.com, sameer.dhavale@celunite.com
+ * -----<snip>-----
+ */
+
+#ifndef _ARCVMAC_H
+#define _ARCVMAC_H
+
+#define DRV_NAME "arcvmac"
+#define DRV_VERSION "1.0"
+
+/* Buffer descriptors */
+#define TX_BDT_LEN 128 /* Number of receive BD's */
+#define RX_BDT_LEN 128 /* Number of transmit BD's */
+
+/* BD poll rate, in 1024 cycles. @100Mhz: x * 1024 cy * 10ns = 1ms */
+#define POLLRATE_TIME 200
+
+/* next power of two, bigger than ETH_FRAME_LEN + VLAN */
+#define MAX_RX_BUFFER_LEN 0x800 /* 2^11 = 2048 = 0x800 */
+#define MAX_TX_BUFFER_LEN 0x800 /* 2^11 = 2048 = 0x800 */
+
+/* 14 bytes of ethernet header, 4 bytes VLAN, FCS,
+ * plus extra pad to prevent buffer chaining of
+ * maximum sized ethernet packets (1514 bytes) */
+#define VMAC_BUFFER_PAD (ETH_HLEN + 4 + ETH_FCS_LEN + 4)
+
+/* VMAC register definitions, offsets in bytes */
+#define VMAC_ID 0x00
+
+/* stat/enable use same bit mask */
+#define VMAC_STAT 0x04
+#define VMAC_ENABLE 0x08
+# define TXINT_MASK 0x00000001 /* Transmit interrupt */
+# define RXINT_MASK 0x00000002 /* Receive interrupt */
+# define ERR_MASK 0x00000004 /* Error interrupt */
+# define TXCH_MASK 0x00000008 /* Transmit chaining error */
+# define MSER_MASK 0x00000010 /* Missed packet counter error */
+# define RXCR_MASK 0x00000100 /* RXCRCERR counter rolled over */
+# define RXFR_MASK 0x00000200 /* RXFRAMEERR counter rolled over */
+# define RXFL_MASK 0x00000400 /* RXOFLOWERR counter rolled over */
+# define MDIO_MASK 0x00001000 /* MDIO complete */
+# define TXPL_MASK 0x80000000 /* TXPOLL */
+
+#define VMAC_CONTROL 0x0c
+# define EN_MASK 0x00000001 /* VMAC enable */
+# define TXRN_MASK 0x00000008 /* TX enable */
+# define RXRN_MASK 0x00000010 /* RX enable */
+# define DSBC_MASK 0x00000100 /* Disable receive broadcast */
+# define ENFL_MASK 0x00000400 /* Enable Full Duplex */
+# define PROM_MASK 0x00000800 /* Promiscuous mode */
+
+#define VMAC_POLLRATE 0x10
+
+#define VMAC_RXERR 0x14
+# define RXERR_CRC 0x000000ff
+# define RXERR_FRM 0x0000ff00
+# define RXERR_OFLO 0x00ff0000 /* fifo overflow */
+
+#define VMAC_MISS 0x18
+#define VMAC_TXRINGPTR 0x1c
+#define VMAC_RXRINGPTR 0x20
+#define VMAC_ADDRL 0x24
+#define VMAC_ADDRH 0x28
+#define VMAC_LAFL 0x2c
+#define VMAC_LAFH 0x30
+#define VMAC_MAC_TXRING_HEAD 0x38
+#define VMAC_MAC_RXRING_HEAD 0x3C
+
+#define VMAC_MDIO_DATA 0x34
+# define MDIO_SFD 0xC0000000
+# define MDIO_OP 0x30000000
+# define MDIO_ID_MASK 0x0F800000
+# define MDIO_REG_MASK 0x007C0000
+# define MDIO_TA 0x00030000
+# define MDIO_DATA_MASK 0x0000FFFF
+/* common combinations */
+# define MDIO_BASE 0x40020000
+# define MDIO_OP_READ 0x20000000
+# define MDIO_OP_WRITE 0x10000000
+
+/* Buffer descriptor INFO bit masks */
+#define BD_DMA_OWN 0x80000000 /* buffer ownership, 0 CPU, 1 DMA */
+#define BD_BUFF 0x40000000 /* buffer invalid, rx */
+#define BD_UFLO 0x20000000 /* underflow, tx */
+#define BD_LTCL 0x10000000 /* late collision, tx */
+#define BD_RETRY_CT 0x0f000000 /* tx */
+#define BD_DROP 0x00800000 /* drop, more than 16 retries, tx */
+#define BD_DEFER 0x00400000 /* traffic on the wire, tx */
+#define BD_CARLOSS 0x00200000 /* carrier loss while transmission, tx, rx? */
+/* 20:19 reserved */
+#define BD_ADCR 0x00040000 /* add crc, ignored if not disaddcrc */
+#define BD_LAST 0x00020000 /* Last buffer in chain */
+#define BD_FRST 0x00010000 /* First buffer in chain */
+/* 15:11 reserved */
+#define BD_LEN 0x000007FF
+
+/* common combinations */
+#define BD_TX_ERR (BD_UFLO | BD_LTCL | BD_RETRY_CT | BD_DROP | \
+ BD_DEFER | BD_CARLOSS)
+
+
+/* arcvmac private data structures */
+struct vmac_buffer_desc {
+ __le32 info;
+ __le32 data;
+};
+
+struct dma_fifo {
+ int head; /* head */
+ int tail; /* tail */
+ int size;
+};
+
+struct vmac_priv {
+ struct net_device *dev;
+ struct platform_device *pdev;
+
+ struct completion mdio_complete;
+ spinlock_t lock; /* protects structure plus hw regs of device */
+
+ /* base address of register set */
+ char *regs;
+ struct resource *mem;
+
+ /* DMA ring buffers */
+ struct vmac_buffer_desc *rxbd;
+ dma_addr_t rxbd_dma;
+
+ struct vmac_buffer_desc *txbd;
+ dma_addr_t txbd_dma;
+
+ /* socket buffers */
+ struct sk_buff *rx_skbuff[RX_BDT_LEN];
+ struct sk_buff *tx_skbuff[TX_BDT_LEN];
+ int rx_skb_size;
+
+ /* skb / dma desc managing */
+ struct dma_fifo rx_ring; /* valid rx buffers */
+ struct dma_fifo tx_ring;
+
+ /* descriptor last polled/processed by the VMAC */
+ unsigned long dma_rx_head;
+
+ /* timer to retry rx skb allocation, if failed during receive */
+ struct timer_list refill_timer;
+ spinlock_t refill_lock;
+
+ struct napi_struct napi;
+
+ /* rx buffer chaining */
+ int rx_merge_error;
+ int tx_timeout_error;
+
+ /* PHY stuff */
+ struct mii_bus *mii_bus;
+ struct phy_device *phy_dev;
+
+ int link;
+ int speed;
+ int duplex;
+
+ /* debug */
+ bool shutdown;
+};
+
+/* DMA ring management */
+
+/* for a fifo with size n,
+ * - [0..n] fill levels are n + 1 states
+ * - there are only n different deltas (head - tail) values
+ * => not all fill levels can be represented with head, tail
+ * pointers only
+ * we give up the n fill level, aka fifo full */
+
+/* sacrifice one elt as a sentinel */
+static inline int fifo_used(struct dma_fifo *f);
+static inline int fifo_inc_ct(int ct, int size);
+static inline void fifo_dump(struct dma_fifo *fifo);
+
+static inline bool fifo_empty(struct dma_fifo *f)
+{
+ return f->head == f->tail;
+}
+
+static inline int fifo_free(struct dma_fifo *f)
+{
+ int free;
+
+ free = f->tail - f->head;
+ if (free <= 0)
+ free += f->size;
+
+ return free;
+}
+
+static inline int fifo_used(struct dma_fifo *f)
+{
+ int used;
+
+ used = f->head - f->tail;
+ if (used < 0)
+ used += f->size;
+
+ return used;
+}
+
+static inline bool fifo_full(struct dma_fifo *f)
+{
+ return (fifo_used(f) + 1) == f->size;
+}
+
+/* manipulate */
+static inline void fifo_init(struct dma_fifo *fifo, int size)
+{
+ fifo->size = size;
+ fifo->head = fifo->tail = 0; /* empty */
+}
+
+static inline void fifo_inc_head(struct dma_fifo *fifo)
+{
+ BUG_ON(fifo_full(fifo));
+ fifo->head = fifo_inc_ct(fifo->head, fifo->size);
+}
+
+static inline void fifo_inc_tail(struct dma_fifo *fifo)
+{
+ BUG_ON(fifo_empty(fifo));
+ fifo->tail = fifo_inc_ct(fifo->tail, fifo->size);
+}
+
+/* internal funcs */
+static inline void fifo_dump(struct dma_fifo *fifo)
+{
+ pr_info("fifo: head %d, tail %d, size %d\n", fifo->head,
+ fifo->tail,
+ fifo->size);
+}
+
+static inline int fifo_inc_ct(int ct, int size)
+{
+ return (++ct == size) ? 0 : ct;
+}
+
+#endif /* _ARCVMAC_H */
--
1.7.9.1
^ permalink raw reply related
* Re: [PATCH v3 4/4] ath9k: Support ethtool getstats api.
From: Florian Fainelli @ 2012-03-20 8:42 UTC (permalink / raw)
To: greearb-my8/4N5VtI7c+919tysfdA
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1332183105-4447-4-git-send-email-greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
Hi,
Le 03/19/12 19:51, greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org a écrit :
> From: Ben Greear<greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
>
> This returns many of the values that formerly could
> only be obtained from debugfs. This should be an
> improvement when trying to access these counters
> programatically. Currently this support is only
> enabled when DEBUGFS is enabled because otherwise
> these stats are not accumulated.
>
> Signed-off-by: Ben Greear<greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
> ---
>
> v3: No changes from v2
>
> :100644 100644 4a00806... 7261f88... M drivers/net/wireless/ath/ath9k/main.c
> drivers/net/wireless/ath/ath9k/main.c | 134 +++++++++++++++++++++++++++++++++
> 1 files changed, 134 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> index 4a00806..7261f88 100644
> --- a/drivers/net/wireless/ath/ath9k/main.c
> +++ b/drivers/net/wireless/ath/ath9k/main.c
> @@ -2430,6 +2430,134 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
> return 0;
> }
>
> +#ifdef CONFIG_ATH9K_DEBUGFS
These are ethtool knobs, so you might want to introduce a new config
symbol dedicated to it, which depends on CONFIG_ATH9K_DEBUGFS eventually.
> +
> +/* Ethtool support for get-stats */
> +
> +#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
> +static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
> + "tx_pkts_nic",
> + "tx_bytes_nic",
> + "rx_pkts_nic",
> + "rx_bytes_nic",
> + AMKSTR(d_tx_pkts),
> + AMKSTR(d_tx_bytes),
> + AMKSTR(d_tx_mpdus_queued),
> + AMKSTR(d_tx_mpdus_completed),
> + AMKSTR(d_tx_mpdu_retries),
> + AMKSTR(d_tx_aggregates),
> + AMKSTR(d_tx_ampdus_queued_hw),
> + AMKSTR(d_tx_ampdus_queued_sw),
> + AMKSTR(d_tx_ampdus_completed),
> + AMKSTR(d_tx_ampdu_retries),
> + AMKSTR(d_tx_ampdu_xretries),
> + AMKSTR(d_tx_fifo_underrun),
> + AMKSTR(d_tx_op_exceeded),
> + AMKSTR(d_tx_timer_expiry),
> + AMKSTR(d_tx_desc_cfg_err),
> + AMKSTR(d_tx_data_underrun),
> + AMKSTR(d_tx_delim_underrun),
> +
> + "d_rx_decrypt_crc_err",
> + "d_rx_phy_err",
> + "d_rx_mic_err",
> + "d_rx_pre_delim_crc_err",
> + "d_rx_post_delim_crc_err",
> + "d_rx_decrypt_busy_err",
> +
> + "d_rx_phyerr_radar",
> + "d_rx_phyerr_ofdm_timing",
> + "d_rx_phyerr_cck_timing",
> +
> +};
> +#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats)
> +
> +static void ath9k_get_et_strings(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + u32 sset, u8 *data)
> +{
> + if (sset == ETH_SS_STATS)
> + memcpy(data, *ath9k_gstrings_stats,
> + sizeof(ath9k_gstrings_stats));
> +}
> +
> +static int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif, int sset)
> +{
> + if (sset == ETH_SS_STATS)
> + return ATH9K_SSTATS_LEN;
> + return 0;
> +}
> +
> +#define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum)
> +#define AWDATA(elem) \
> + do { \
> + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \
> + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \
> + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \
> + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \
> + } while (0)
> +
> +#define AWDATA_RX(elem) \
> + do { \
> + data[i++] = sc->debug.stats.rxstats.elem; \
> + } while (0)
> +
> +static void ath9k_get_et_stats(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ethtool_stats *stats, u64 *data)
> +{
> + struct ath_softc *sc = hw->priv;
> + int i = 0;
> +
> + data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all +
> + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all +
> + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all +
> + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all);
> + data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all +
> + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all +
> + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all +
> + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all);
> + AWDATA_RX(rx_pkts_all);
> + AWDATA_RX(rx_bytes_all);
> +
> + AWDATA(tx_pkts_all);
> + AWDATA(tx_bytes_all);
> + AWDATA(queued);
> + AWDATA(completed);
> + AWDATA(xretries);
> + AWDATA(a_aggr);
> + AWDATA(a_queued_hw);
> + AWDATA(a_queued_sw);
> + AWDATA(a_completed);
> + AWDATA(a_retries);
> + AWDATA(a_xretries);
> + AWDATA(fifo_underrun);
> + AWDATA(xtxop);
> + AWDATA(timer_exp);
> + AWDATA(desc_cfg_err);
> + AWDATA(data_underrun);
> + AWDATA(delim_underrun);
> +
> + AWDATA_RX(decrypt_crc_err);
> + AWDATA_RX(phy_err);
> + AWDATA_RX(mic_err);
> + AWDATA_RX(pre_delim_crc_err);
> + AWDATA_RX(post_delim_crc_err);
> + AWDATA_RX(decrypt_busy_err);
> +
> + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]);
> + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]);
> + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]);
> +
> + BUG_ON(i != ATH9K_SSTATS_LEN);
> +}
> +
> +/* End of ethtool get-stats functions */
> +
> +#endif
> +
> +
> struct ieee80211_ops ath9k_ops = {
> .tx = ath9k_tx,
> .start = ath9k_start,
> @@ -2458,4 +2586,10 @@ struct ieee80211_ops ath9k_ops = {
> .get_stats = ath9k_get_stats,
> .set_antenna = ath9k_set_antenna,
> .get_antenna = ath9k_get_antenna,
> +
> +#ifdef CONFIG_ATH9K_DEBUGFS
> + .get_et_sset_count = ath9k_get_et_sset_count,
> + .get_et_stats = ath9k_get_et_stats,
> + .get_et_strings = ath9k_get_et_strings,
> +#endif
> };
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3] ipv6: fix incorrent ipv6 ipsec packet fragment
From: Steffen Klassert @ 2012-03-20 8:54 UTC (permalink / raw)
To: Gao feng; +Cc: davem, netdev
In-Reply-To: <1332232570-17424-1-git-send-email-gaofeng@cn.fujitsu.com>
On Tue, Mar 20, 2012 at 04:36:10PM +0800, Gao feng wrote:
> Since commit 299b0767(ipv6: Fix IPsec slowpath fragmentation problem)
> In func ip6_append_data,after call skb_put(skb, fraglen + dst_exthdrlen)
> the skb->len contains dst_exthdrlen,and we don't reduce dst_exthdrlen at last
> This will make fraggap>0 in next "while cycle",and cause the size of skb incorrent
>
> Fix this by reserve headroom for dst_exthdrlen.
>
> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
Acked-by: Steffen Klassert <steffen.klassert@secunet.com>
Thanks a lot!
^ permalink raw reply
* [PATCH] e1000: Silence sparse warnings by correcting type
From: Andrei Emeltchenko @ 2012-03-20 8:59 UTC (permalink / raw)
To: netdev
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Silence sparse warnings shown below:
...
drivers/net/ethernet/intel/e1000/e1000_main.c:3435:17: warning:
cast to restricted __le64
drivers/net/ethernet/intel/e1000/e1000_main.c:3435:17: warning:
cast to restricted __le64
...
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
drivers/net/ethernet/intel/e1000/e1000_main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 6419a88..1bf73cf 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -3377,7 +3377,7 @@ static void e1000_dump(struct e1000_adapter *adapter)
for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i];
- struct my_u { u64 a; u64 b; };
+ struct my_u { __le64 a; __le64 b; };
struct my_u *u = (struct my_u *)tx_desc;
const char *type;
@@ -3421,7 +3421,7 @@ rx_ring_summary:
for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i];
- struct my_u { u64 a; u64 b; };
+ struct my_u { __le64 a; __le64 b; };
struct my_u *u = (struct my_u *)rx_desc;
const char *type;
--
1.7.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox