summaryrefslogtreecommitdiff
path: root/drivers/net/e1000/e1000_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r--drivers/net/e1000/e1000_main.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 477e066a1cf0..76e8af00d86d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -29,6 +29,7 @@
#include "e1000.h"
#include <net/ip6_checksum.h>
#include <linux/io.h>
+#include <linux/prefetch.h>
/* Intel Media SOC GbE MDIO physical base address */
static unsigned long ce4100_gbe_mdio_base_phy;
@@ -96,7 +97,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 +4385,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 +4423,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 +4596,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 +4632,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)