diff options
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 137226d98d47..d21e29d09ddc 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -3376,6 +3376,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
3376 | int retval; | 3376 | int retval; |
3377 | uint16_t mii_reg; | 3377 | uint16_t mii_reg; |
3378 | uint16_t spddplx; | 3378 | uint16_t spddplx; |
3379 | unsigned long flags; | ||
3379 | 3380 | ||
3380 | if(adapter->hw.media_type != e1000_media_type_copper) | 3381 | if(adapter->hw.media_type != e1000_media_type_copper) |
3381 | return -EOPNOTSUPP; | 3382 | return -EOPNOTSUPP; |
@@ -3385,22 +3386,29 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
3385 | data->phy_id = adapter->hw.phy_addr; | 3386 | data->phy_id = adapter->hw.phy_addr; |
3386 | break; | 3387 | break; |
3387 | case SIOCGMIIREG: | 3388 | case SIOCGMIIREG: |
3388 | if (!capable(CAP_NET_ADMIN)) | 3389 | if(!capable(CAP_NET_ADMIN)) |
3389 | return -EPERM; | 3390 | return -EPERM; |
3390 | if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, | 3391 | spin_lock_irqsave(&adapter->stats_lock, flags); |
3391 | &data->val_out)) | 3392 | if(e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, |
3393 | &data->val_out)) { | ||
3394 | spin_unlock_irqrestore(&adapter->stats_lock, flags); | ||
3392 | return -EIO; | 3395 | return -EIO; |
3396 | } | ||
3397 | spin_unlock_irqrestore(&adapter->stats_lock, flags); | ||
3393 | break; | 3398 | break; |
3394 | case SIOCSMIIREG: | 3399 | case SIOCSMIIREG: |
3395 | if (!capable(CAP_NET_ADMIN)) | 3400 | if(!capable(CAP_NET_ADMIN)) |
3396 | return -EPERM; | 3401 | return -EPERM; |
3397 | if (data->reg_num & ~(0x1F)) | 3402 | if(data->reg_num & ~(0x1F)) |
3398 | return -EFAULT; | 3403 | return -EFAULT; |
3399 | mii_reg = data->val_in; | 3404 | mii_reg = data->val_in; |
3400 | if (e1000_write_phy_reg(&adapter->hw, data->reg_num, | 3405 | spin_lock_irqsave(&adapter->stats_lock, flags); |
3401 | mii_reg)) | 3406 | if(e1000_write_phy_reg(&adapter->hw, data->reg_num, |
3407 | mii_reg)) { | ||
3408 | spin_unlock_irqrestore(&adapter->stats_lock, flags); | ||
3402 | return -EIO; | 3409 | return -EIO; |
3403 | if (adapter->hw.phy_type == e1000_phy_m88) { | 3410 | } |
3411 | if(adapter->hw.phy_type == e1000_phy_m88) { | ||
3404 | switch (data->reg_num) { | 3412 | switch (data->reg_num) { |
3405 | case PHY_CTRL: | 3413 | case PHY_CTRL: |
3406 | if(mii_reg & MII_CR_POWER_DOWN) | 3414 | if(mii_reg & MII_CR_POWER_DOWN) |
@@ -3420,8 +3428,12 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
3420 | HALF_DUPLEX; | 3428 | HALF_DUPLEX; |
3421 | retval = e1000_set_spd_dplx(adapter, | 3429 | retval = e1000_set_spd_dplx(adapter, |
3422 | spddplx); | 3430 | spddplx); |
3423 | if(retval) | 3431 | if(retval) { |
3432 | spin_unlock_irqrestore( | ||
3433 | &adapter->stats_lock, | ||
3434 | flags); | ||
3424 | return retval; | 3435 | return retval; |
3436 | } | ||
3425 | } | 3437 | } |
3426 | if(netif_running(adapter->netdev)) { | 3438 | if(netif_running(adapter->netdev)) { |
3427 | e1000_down(adapter); | 3439 | e1000_down(adapter); |
@@ -3431,8 +3443,11 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
3431 | break; | 3443 | break; |
3432 | case M88E1000_PHY_SPEC_CTRL: | 3444 | case M88E1000_PHY_SPEC_CTRL: |
3433 | case M88E1000_EXT_PHY_SPEC_CTRL: | 3445 | case M88E1000_EXT_PHY_SPEC_CTRL: |
3434 | if (e1000_phy_reset(&adapter->hw)) | 3446 | if(e1000_phy_reset(&adapter->hw)) { |
3447 | spin_unlock_irqrestore( | ||
3448 | &adapter->stats_lock, flags); | ||
3435 | return -EIO; | 3449 | return -EIO; |
3450 | } | ||
3436 | break; | 3451 | break; |
3437 | } | 3452 | } |
3438 | } else { | 3453 | } else { |
@@ -3448,6 +3463,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
3448 | break; | 3463 | break; |
3449 | } | 3464 | } |
3450 | } | 3465 | } |
3466 | spin_unlock_irqrestore(&adapter->stats_lock, flags); | ||
3451 | break; | 3467 | break; |
3452 | default: | 3468 | default: |
3453 | return -EOPNOTSUPP; | 3469 | return -EOPNOTSUPP; |