|
@@ -96,7 +96,6 @@ int e1000_up(struct e1000_adapter *adapter);
|
|
|
void e1000_down(struct e1000_adapter *adapter);
|
|
|
void e1000_reinit_locked(struct e1000_adapter *adapter);
|
|
|
void e1000_reset(struct e1000_adapter *adapter);
|
|
|
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
|
|
|
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
|
|
|
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
|
|
|
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
|
|
@@ -4385,7 +4384,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
|
|
|
struct mii_ioctl_data *data = if_mii(ifr);
|
|
|
int retval;
|
|
|
u16 mii_reg;
|
|
|
- u16 spddplx;
|
|
|
unsigned long flags;
|
|
|
|
|
|
if (hw->media_type != e1000_media_type_copper)
|
|
@@ -4424,17 +4422,18 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
|
|
|
hw->autoneg = 1;
|
|
|
hw->autoneg_advertised = 0x2F;
|
|
|
} else {
|
|
|
+ u32 speed;
|
|
|
if (mii_reg & 0x40)
|
|
|
- spddplx = SPEED_1000;
|
|
|
+ speed = SPEED_1000;
|
|
|
else if (mii_reg & 0x2000)
|
|
|
- spddplx = SPEED_100;
|
|
|
+ speed = SPEED_100;
|
|
|
else
|
|
|
- spddplx = SPEED_10;
|
|
|
- spddplx += (mii_reg & 0x100)
|
|
|
- ? DUPLEX_FULL :
|
|
|
- DUPLEX_HALF;
|
|
|
- retval = e1000_set_spd_dplx(adapter,
|
|
|
- spddplx);
|
|
|
+ speed = SPEED_10;
|
|
|
+ retval = e1000_set_spd_dplx(
|
|
|
+ adapter, speed,
|
|
|
+ ((mii_reg & 0x100)
|
|
|
+ ? DUPLEX_FULL :
|
|
|
+ DUPLEX_HALF));
|
|
|
if (retval)
|
|
|
return retval;
|
|
|
}
|
|
@@ -4596,20 +4595,24 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
|
|
|
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
|
|
|
{
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
hw->autoneg = 0;
|
|
|
|
|
|
+ /* Make sure dplx is at most 1 bit and lsb of speed is not set
|
|
|
+ * for the switch() below to work */
|
|
|
+ if ((spd & 1) || (dplx & ~1))
|
|
|
+ goto err_inval;
|
|
|
+
|
|
|
/* Fiber NICs only allow 1000 gbps Full duplex */
|
|
|
if ((hw->media_type == e1000_media_type_fiber) &&
|
|
|
- spddplx != (SPEED_1000 + DUPLEX_FULL)) {
|
|
|
- e_err(probe, "Unsupported Speed/Duplex configuration\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
+ spd != SPEED_1000 &&
|
|
|
+ dplx != DUPLEX_FULL)
|
|
|
+ goto err_inval;
|
|
|
|
|
|
- switch (spddplx) {
|
|
|
+ switch (spd + dplx) {
|
|
|
case SPEED_10 + DUPLEX_HALF:
|
|
|
hw->forced_speed_duplex = e1000_10_half;
|
|
|
break;
|
|
@@ -4628,10 +4631,13 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
|
|
|
break;
|
|
|
case SPEED_1000 + DUPLEX_HALF: /* not supported */
|
|
|
default:
|
|
|
- e_err(probe, "Unsupported Speed/Duplex configuration\n");
|
|
|
- return -EINVAL;
|
|
|
+ goto err_inval;
|
|
|
}
|
|
|
return 0;
|
|
|
+
|
|
|
+err_inval:
|
|
|
+ e_err(probe, "Unsupported Speed/Duplex configuration\n");
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
|