aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Glendinning <steve.glendinning@smsc.com>2009-11-30 02:14:45 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-30 02:14:45 -0500
commit6c53b1b15e222244358d3cbbefd2a13920faa352 (patch)
tree365c523513c54ab2b4eed1ca710fa007b8f84cce
parentcc098dc705895f6b0109b7e8e026ac2b8ae1c0a1 (diff)
smsc9420: prevent BUG() if ethtool is called with interface down
This patch fixes a null pointer dereference BUG() if ethtool is used on an smsc9420 interface while it is down, because the phy_dev is only allocated while the interface is up. Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/smsc9420.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index b4909a2dec66..0f7909276237 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings(struct net_device *dev,
252{ 252{
253 struct smsc9420_pdata *pd = netdev_priv(dev); 253 struct smsc9420_pdata *pd = netdev_priv(dev);
254 254
255 if (!pd->phy_dev)
256 return -ENODEV;
257
255 cmd->maxtxpkt = 1; 258 cmd->maxtxpkt = 1;
256 cmd->maxrxpkt = 1; 259 cmd->maxrxpkt = 1;
257 return phy_ethtool_gset(pd->phy_dev, cmd); 260 return phy_ethtool_gset(pd->phy_dev, cmd);
@@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings(struct net_device *dev,
262{ 265{
263 struct smsc9420_pdata *pd = netdev_priv(dev); 266 struct smsc9420_pdata *pd = netdev_priv(dev);
264 267
268 if (!pd->phy_dev)
269 return -ENODEV;
270
265 return phy_ethtool_sset(pd->phy_dev, cmd); 271 return phy_ethtool_sset(pd->phy_dev, cmd);
266} 272}
267 273
@@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data)
290static int smsc9420_ethtool_nway_reset(struct net_device *netdev) 296static int smsc9420_ethtool_nway_reset(struct net_device *netdev)
291{ 297{
292 struct smsc9420_pdata *pd = netdev_priv(netdev); 298 struct smsc9420_pdata *pd = netdev_priv(netdev);
299
300 if (!pd->phy_dev)
301 return -ENODEV;
302
293 return phy_start_aneg(pd->phy_dev); 303 return phy_start_aneg(pd->phy_dev);
294} 304}
295 305
@@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
312 for (i = 0; i < 0x100; i += (sizeof(u32))) 322 for (i = 0; i < 0x100; i += (sizeof(u32)))
313 data[j++] = smsc9420_reg_read(pd, i); 323 data[j++] = smsc9420_reg_read(pd, i);
314 324
325 // cannot read phy registers if the net device is down
326 if (!phy_dev)
327 return;
328
315 for (i = 0; i <= 31; i++) 329 for (i = 0; i <= 31; i++)
316 data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i); 330 data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i);
317} 331}