diff options
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
| -rw-r--r-- | drivers/net/e1000/e1000_main.c | 43 | 
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 477e066a1cf..76e8af00d86 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)  |