diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2011-09-15 15:08:05 +0200 | 
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2011-09-15 15:08:18 +0200 | 
| commit | e060c38434b2caa78efe7cedaff4191040b65a15 (patch) | |
| tree | 407361230bf6733f63d8e788e4b5e6566ee04818 /drivers/net | |
| parent | 10e4ac572eeffe5317019bd7330b6058a400dfc2 (diff) | |
| parent | cc39c6a9bbdebfcf1a7dee64d83bf302bc38d941 (diff) | |
| download | olio-linux-3.10-e060c38434b2caa78efe7cedaff4191040b65a15.tar.xz olio-linux-3.10-e060c38434b2caa78efe7cedaff4191040b65a15.zip  | |
Merge branch 'master' into for-next
Fast-forward merge with Linus to be able to merge patches
based on more recent version of the tree.
Diffstat (limited to 'drivers/net')
133 files changed, 1373 insertions, 766 deletions
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index b7622c3745f..e1eca2ab505 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -282,6 +282,7 @@ obj-$(CONFIG_USB_HSO)		+= usb/  obj-$(CONFIG_USB_USBNET)        += usb/  obj-$(CONFIG_USB_ZD1201)        += usb/  obj-$(CONFIG_USB_IPHETH)        += usb/ +obj-$(CONFIG_USB_CDC_PHONET)   += usb/  obj-$(CONFIG_WLAN) += wireless/  obj-$(CONFIG_NET_TULIP) += tulip/ diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 536038b2271..31798f5f5d0 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -1502,13 +1502,13 @@ static int __devinit ace_init(struct net_device *dev)  	 * firmware to wipe the ring without re-initializing it.  	 */  	if (!test_and_set_bit(0, &ap->std_refill_busy)) -		ace_load_std_rx_ring(ap, RX_RING_SIZE); +		ace_load_std_rx_ring(dev, RX_RING_SIZE);  	else  		printk(KERN_ERR "%s: Someone is busy refilling the RX ring\n",  		       ap->name);  	if (ap->version >= 2) {  		if (!test_and_set_bit(0, &ap->mini_refill_busy)) -			ace_load_mini_rx_ring(ap, RX_MINI_SIZE); +			ace_load_mini_rx_ring(dev, RX_MINI_SIZE);  		else  			printk(KERN_ERR "%s: Someone is busy refilling "  			       "the RX mini ring\n", ap->name); @@ -1584,9 +1584,10 @@ static void ace_watchdog(struct net_device *data)  } -static void ace_tasklet(unsigned long dev) +static void ace_tasklet(unsigned long arg)  { -	struct ace_private *ap = netdev_priv((struct net_device *)dev); +	struct net_device *dev = (struct net_device *) arg; +	struct ace_private *ap = netdev_priv(dev);  	int cur_size;  	cur_size = atomic_read(&ap->cur_rx_bufs); @@ -1595,7 +1596,7 @@ static void ace_tasklet(unsigned long dev)  #ifdef DEBUG  		printk("refilling buffers (current %i)\n", cur_size);  #endif -		ace_load_std_rx_ring(ap, RX_RING_SIZE - cur_size); +		ace_load_std_rx_ring(dev, RX_RING_SIZE - cur_size);  	}  	if (ap->version >= 2) { @@ -1606,7 +1607,7 @@ static void ace_tasklet(unsigned long dev)  			printk("refilling mini buffers (current %i)\n",  			       cur_size);  #endif -			ace_load_mini_rx_ring(ap, RX_MINI_SIZE - cur_size); +			ace_load_mini_rx_ring(dev, RX_MINI_SIZE - cur_size);  		}  	} @@ -1616,7 +1617,7 @@ static void ace_tasklet(unsigned long dev)  #ifdef DEBUG  		printk("refilling jumbo buffers (current %i)\n", cur_size);  #endif -		ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE - cur_size); +		ace_load_jumbo_rx_ring(dev, RX_JUMBO_SIZE - cur_size);  	}  	ap->tasklet_pending = 0;  } @@ -1642,8 +1643,9 @@ static void ace_dump_trace(struct ace_private *ap)   * done only before the device is enabled, thus no interrupts are   * generated and by the interrupt handler/tasklet handler.   */ -static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs) +static void ace_load_std_rx_ring(struct net_device *dev, int nr_bufs)  { +	struct ace_private *ap = netdev_priv(dev);  	struct ace_regs __iomem *regs = ap->regs;  	short i, idx; @@ -1657,11 +1659,10 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)  		struct rx_desc *rd;  		dma_addr_t mapping; -		skb = dev_alloc_skb(ACE_STD_BUFSIZE + NET_IP_ALIGN); +		skb = netdev_alloc_skb_ip_align(dev, ACE_STD_BUFSIZE);  		if (!skb)  			break; -		skb_reserve(skb, NET_IP_ALIGN);  		mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),  				       offset_in_page(skb->data),  				       ACE_STD_BUFSIZE, @@ -1705,8 +1706,9 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)  } -static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs) +static void ace_load_mini_rx_ring(struct net_device *dev, int nr_bufs)  { +	struct ace_private *ap = netdev_priv(dev);  	struct ace_regs __iomem *regs = ap->regs;  	short i, idx; @@ -1718,11 +1720,10 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)  		struct rx_desc *rd;  		dma_addr_t mapping; -		skb = dev_alloc_skb(ACE_MINI_BUFSIZE + NET_IP_ALIGN); +		skb = netdev_alloc_skb_ip_align(dev, ACE_MINI_BUFSIZE);  		if (!skb)  			break; -		skb_reserve(skb, NET_IP_ALIGN);  		mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),  				       offset_in_page(skb->data),  				       ACE_MINI_BUFSIZE, @@ -1762,8 +1763,9 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)   * Load the jumbo rx ring, this may happen at any time if the MTU   * is changed to a value > 1500.   */ -static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs) +static void ace_load_jumbo_rx_ring(struct net_device *dev, int nr_bufs)  { +	struct ace_private *ap = netdev_priv(dev);  	struct ace_regs __iomem *regs = ap->regs;  	short i, idx; @@ -1774,11 +1776,10 @@ static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs)  		struct rx_desc *rd;  		dma_addr_t mapping; -		skb = dev_alloc_skb(ACE_JUMBO_BUFSIZE + NET_IP_ALIGN); +		skb = netdev_alloc_skb_ip_align(dev, ACE_JUMBO_BUFSIZE);  		if (!skb)  			break; -		skb_reserve(skb, NET_IP_ALIGN);  		mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),  				       offset_in_page(skb->data),  				       ACE_JUMBO_BUFSIZE, @@ -2196,7 +2197,7 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)  #ifdef DEBUG  				printk("low on std buffers %i\n", cur_size);  #endif -				ace_load_std_rx_ring(ap, +				ace_load_std_rx_ring(dev,  						     RX_RING_SIZE - cur_size);  			} else  				run_tasklet = 1; @@ -2212,7 +2213,8 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)  					printk("low on mini buffers %i\n",  					       cur_size);  #endif -					ace_load_mini_rx_ring(ap, RX_MINI_SIZE - cur_size); +					ace_load_mini_rx_ring(dev, +							      RX_MINI_SIZE - cur_size);  				} else  					run_tasklet = 1;  			} @@ -2228,7 +2230,8 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)  					printk("low on jumbo buffers %i\n",  					       cur_size);  #endif -					ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE - cur_size); +					ace_load_jumbo_rx_ring(dev, +							       RX_JUMBO_SIZE - cur_size);  				} else  					run_tasklet = 1;  			} @@ -2267,7 +2270,7 @@ static int ace_open(struct net_device *dev)  	if (ap->jumbo &&  	    !test_and_set_bit(0, &ap->jumbo_refill_busy)) -		ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE); +		ace_load_jumbo_rx_ring(dev, RX_JUMBO_SIZE);  	if (dev->flags & IFF_PROMISC) {  		cmd.evt = C_SET_PROMISC_MODE; @@ -2575,7 +2578,7 @@ static int ace_change_mtu(struct net_device *dev, int new_mtu)  			       "support\n", dev->name);  			ap->jumbo = 1;  			if (!test_and_set_bit(0, &ap->jumbo_refill_busy)) -				ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE); +				ace_load_jumbo_rx_ring(dev, RX_JUMBO_SIZE);  			ace_set_rxtx_parms(dev, 1);  		}  	} else { diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h index f67dc9b0eb8..51c486cfbb8 100644 --- a/drivers/net/acenic.h +++ b/drivers/net/acenic.h @@ -766,9 +766,9 @@ static inline void ace_unmask_irq(struct net_device *dev)   * Prototypes   */  static int ace_init(struct net_device *dev); -static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs); -static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs); -static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs); +static void ace_load_std_rx_ring(struct net_device *dev, int nr_bufs); +static void ace_load_mini_rx_ring(struct net_device *dev, int nr_bufs); +static void ace_load_jumbo_rx_ring(struct net_device *dev, int nr_bufs);  static irqreturn_t ace_interrupt(int irq, void *dev_id);  static int ace_load_firmware(struct net_device *dev);  static int ace_open(struct net_device *dev); diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 52fe21e1e2c..3b1416e3d21 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -308,8 +308,11 @@ static void am79c961_timer(unsigned long data)  	struct net_device *dev = (struct net_device *)data;  	struct dev_priv *priv = netdev_priv(dev);  	unsigned int lnkstat, carrier; +	unsigned long flags; +	spin_lock_irqsave(&priv->chip_lock, flags);  	lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST; +	spin_unlock_irqrestore(&priv->chip_lock, flags);  	carrier = netif_carrier_ok(dev);  	if (lnkstat && !carrier) { diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index c346e65e51e..9f3e5306ef7 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -44,7 +44,7 @@   * SMP torture testing   */ -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/byteorder.h>  #include <linux/compiler.h> diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index e0f87cf1e2b..d4f7dda3972 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -20,7 +20,7 @@   * Temple Place - Suite 330, Boston, MA  02111-1307, USA.   */ -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <linux/crc32.h>  #include <linux/dma-mapping.h>  #include <linux/etherdevice.h> diff --git a/drivers/net/atlx/atl2.h b/drivers/net/atlx/atl2.h index 78344ddf4bf..bf9016ebdd9 100644 --- a/drivers/net/atlx/atl2.h +++ b/drivers/net/atlx/atl2.h @@ -25,7 +25,7 @@  #ifndef _ATL2_H_  #define _ATL2_H_ -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <linux/netdevice.h>  #ifndef _ATL2_HW_H_ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 5b0dba6d4ef..37e5790681a 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -63,8 +63,9 @@ static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)  	fp->disable_tpa = ((bp->flags & TPA_ENABLE_FLAG) == 0);  #ifdef BCM_CNIC -	/* We don't want TPA on FCoE, FWD and OOO L2 rings */ -	bnx2x_fcoe(bp, disable_tpa) = 1; +	/* We don't want TPA on an FCoE L2 ring */ +	if (IS_FCOE_FP(fp)) +		fp->disable_tpa = 1;  #endif  } @@ -1404,10 +1405,9 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)  u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb)  {  	struct bnx2x *bp = netdev_priv(dev); +  #ifdef BCM_CNIC -	if (NO_FCOE(bp)) -		return skb_tx_hash(dev, skb); -	else { +	if (!NO_FCOE(bp)) {  		struct ethhdr *hdr = (struct ethhdr *)skb->data;  		u16 ether_type = ntohs(hdr->h_proto); @@ -1424,8 +1424,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb)  			return bnx2x_fcoe_tx(bp, txq_index);  	}  #endif -	/* Select a none-FCoE queue:  if FCoE is enabled, exclude FCoE L2 ring -	 */ +	/* select a non-FCoE queue */  	return __skb_tx_hash(dev, skb, BNX2X_NUM_ETH_QUEUES(bp));  } @@ -1448,6 +1447,28 @@ void bnx2x_set_num_queues(struct bnx2x *bp)  	bp->num_queues += NON_ETH_CONTEXT_USE;  } +/** + * bnx2x_set_real_num_queues - configure netdev->real_num_[tx,rx]_queues + * + * @bp:		Driver handle + * + * We currently support for at most 16 Tx queues for each CoS thus we will + * allocate a multiple of 16 for ETH L2 rings according to the value of the + * bp->max_cos. + * + * If there is an FCoE L2 queue the appropriate Tx queue will have the next + * index after all ETH L2 indices. + * + * If the actual number of Tx queues (for each CoS) is less than 16 then there + * will be the holes at the end of each group of 16 ETh L2 indices (0..15, + * 16..31,...) with indicies that are not coupled with any real Tx queue. + * + * The proper configuration of skb->queue_mapping is handled by + * bnx2x_select_queue() and __skb_tx_hash(). + * + * bnx2x_setup_tc() takes care of the proper TC mappings so that __skb_tx_hash() + * will return a proper Tx index if TC is enabled (netdev->num_tc > 0). + */  static inline int bnx2x_set_real_num_queues(struct bnx2x *bp)  {  	int rc, tx, rx; @@ -1989,14 +2010,20 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)  		return -EINVAL;  	} +	/* +	 * It's important to set the bp->state to the value different from +	 * BNX2X_STATE_OPEN and only then stop the Tx. Otherwise bnx2x_tx_int() +	 * may restart the Tx from the NAPI context (see bnx2x_tx_int()). +	 */ +	bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; +	smp_mb(); +  	/* Stop Tx */  	bnx2x_tx_disable(bp);  #ifdef BCM_CNIC  	bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);  #endif -	bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; -	smp_mb();  	bp->rx_mode = BNX2X_RX_MODE_NONE; diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index a4ea35f6a45..a1e004a82f7 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -920,7 +920,7 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp,  void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled)  { -	if (!CHIP_IS_E1x(bp)) { +	if (!CHIP_IS_E1x(bp) && !CHIP_IS_E3(bp)) {  		bp->dcb_state = dcb_on;  		bp->dcbx_enabled = dcbx_enabled;  	} else { diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 06727f32e50..dc24de40e33 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -1204,6 +1204,8 @@ struct drv_port_mb {  	#define LINK_STATUS_PFC_ENABLED				0x20000000 +	#define LINK_STATUS_PHYSICAL_LINK_FLAG			0x40000000 +  	u32 port_stx;  	u32 stat_nig_timer; diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index bcd8f003862..d45b1555a60 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1546,6 +1546,12 @@ static void bnx2x_umac_enable(struct link_params *params,  			       vars->line_speed);  		break;  	} +	if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) +		val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE; + +	if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) +		val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE; +  	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);  	udelay(50); @@ -1661,10 +1667,20 @@ static void bnx2x_xmac_disable(struct link_params *params)  {  	u8 port = params->port;  	struct bnx2x *bp = params->bp; -	u32 xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; +	u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;  	if (REG_RD(bp, MISC_REG_RESET_REG_2) &  	    MISC_REGISTERS_RESET_REG_2_XMAC) { +		/* +		 * Send an indication to change the state in the NIG back to XON +		 * Clearing this bit enables the next set of this bit to get +		 * rising edge +		 */ +		pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI); +		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, +		       (pfc_ctrl & ~(1<<1))); +		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, +		       (pfc_ctrl | (1<<1)));  		DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);  		REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);  		usleep_range(1000, 1000); @@ -1729,6 +1745,10 @@ static int bnx2x_emac_enable(struct link_params *params,  	DP(NETIF_MSG_LINK, "enabling EMAC\n"); +	/* Disable BMAC */ +	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, +	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); +  	/* enable emac and not bmac */  	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1); @@ -2583,12 +2603,6 @@ static int bnx2x_bmac1_enable(struct link_params *params,  	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,  		    wb_data, 2); -	if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) { -		REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LSS_STATUS, -			    wb_data, 2); -		if (wb_data[0] > 0) -			return -ESRCH; -	}  	return 0;  } @@ -2654,16 +2668,6 @@ static int bnx2x_bmac2_enable(struct link_params *params,  	udelay(30);  	bnx2x_update_pfc_bmac2(params, vars, is_lb); -	if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) { -		REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LSS_STAT, -			    wb_data, 2); -		if (wb_data[0] > 0) { -			DP(NETIF_MSG_LINK, "Got bad LSS status 0x%x\n", -				       wb_data[0]); -			return -ESRCH; -		} -	} -  	return 0;  } @@ -2949,7 +2953,9 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,  	u32 val;  	u16 i;  	int rc = 0; - +	if (phy->flags & FLAGS_MDC_MDIO_WA_B0) +		bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, +			      EMAC_MDIO_STATUS_10MB);  	/* address */  	val = ((phy->addr << 21) | (devad << 16) | reg |  	       EMAC_MDIO_COMM_COMMAND_ADDRESS | @@ -3003,6 +3009,9 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,  		}  	} +	if (phy->flags & FLAGS_MDC_MDIO_WA_B0) +		bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, +			       EMAC_MDIO_STATUS_10MB);  	return rc;  } @@ -3012,6 +3021,9 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,  	u32 tmp;  	u8 i;  	int rc = 0; +	if (phy->flags & FLAGS_MDC_MDIO_WA_B0) +		bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, +			      EMAC_MDIO_STATUS_10MB);  	/* address */ @@ -3065,7 +3077,9 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,  			bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);  		}  	} - +	if (phy->flags & FLAGS_MDC_MDIO_WA_B0) +		bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, +			       EMAC_MDIO_STATUS_10MB);  	return rc;  } @@ -4353,6 +4367,9 @@ void bnx2x_link_status_update(struct link_params *params,  	vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);  	vars->phy_flags = PHY_XGXS_FLAG; +	if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG) +		vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG; +  	if (vars->link_up) {  		DP(NETIF_MSG_LINK, "phy link up\n"); @@ -4444,6 +4461,8 @@ void bnx2x_link_status_update(struct link_params *params,  		/* indicate no mac active */  		vars->mac_type = MAC_TYPE_NONE; +		if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG) +			vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;  	}  	/* Sync media type */ @@ -5903,20 +5922,30 @@ int bnx2x_set_led(struct link_params *params,  				tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);  				EMAC_WR(bp, EMAC_REG_EMAC_LED,  					(tmp | EMAC_LED_OVERRIDE)); -				return rc; +				/* +				 * return here without enabling traffic +				 * LED blink andsetting rate in ON mode. +				 * In oper mode, enabling LED blink +				 * and setting rate is needed. +				 */ +				if (mode == LED_MODE_ON) +					return rc;  			} -		} else if (SINGLE_MEDIA_DIRECT(params) && -			   (CHIP_IS_E1x(bp) || -			    CHIP_IS_E2(bp))) { +		} else if (SINGLE_MEDIA_DIRECT(params)) {  			/*  			 * This is a work-around for HW issue found when link  			 * is up in CL73  			 */ -			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);  			REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); -		} else { +			if (CHIP_IS_E1x(bp) || +			    CHIP_IS_E2(bp) || +			    (mode == LED_MODE_ON)) +				REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); +			else +				REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, +				       hw_led_mode); +		} else  			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode); -		}  		REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);  		/* Set blinking rate to ~15.9Hz */ @@ -6160,6 +6189,7 @@ static int bnx2x_update_link_down(struct link_params *params,  	/* update shared memory */  	vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |  			       LINK_STATUS_LINK_UP | +			       LINK_STATUS_PHYSICAL_LINK_FLAG |  			       LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |  			       LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |  			       LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | @@ -6197,7 +6227,8 @@ static int bnx2x_update_link_up(struct link_params *params,  	u8 port = params->port;  	int rc = 0; -	vars->link_status |= LINK_STATUS_LINK_UP; +	vars->link_status |= (LINK_STATUS_LINK_UP | +			      LINK_STATUS_PHYSICAL_LINK_FLAG);  	vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;  	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) @@ -7998,6 +8029,9 @@ static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,  	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,  			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); +	/* Restart microcode to re-read the new mode */ +	bnx2x_warpcore_reset_lane(bp, phy, 1); +	bnx2x_warpcore_reset_lane(bp, phy, 0);  } @@ -8116,7 +8150,6 @@ void bnx2x_handle_module_detect_int(struct link_params *params)  				 offsetof(struct shmem_region, dev_info.  					  port_feature_config[params->port].  					  config)); -  		bnx2x_set_gpio_int(bp, gpio_num,  				   MISC_REGISTERS_GPIO_INT_OUTPUT_SET,  				   gpio_port); @@ -8125,8 +8158,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params)  		 * Disable transmit for this module  		 */  		phy->media_type = ETH_PHY_NOT_PRESENT; -		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == -		    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) +		if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == +		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) || +		    CHIP_IS_E3(bp))  			bnx2x_sfp_set_transmitter(params, phy, 0);  	}  } @@ -8228,9 +8262,6 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,  	u16 cnt, val, tmp1;  	struct bnx2x *bp = params->bp; -	/* SPF+ PHY: Set flag to check for Tx error */ -	vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; -  	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,  		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);  	/* HW reset */ @@ -8414,9 +8445,6 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy,  	struct bnx2x *bp = params->bp;  	DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); -	/* SPF+ PHY: Set flag to check for Tx error */ -	vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; -  	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);  	bnx2x_wait_reset_complete(bp, phy, params); @@ -8585,9 +8613,6 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy,  	struct bnx2x *bp = params->bp;  	/* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ -	/* SPF+ PHY: Set flag to check for Tx error */ -	vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; -  	bnx2x_wait_reset_complete(bp, phy, params);  	rx_alarm_ctrl_val = (1<<2) | (1<<5) ;  	/* Should be 0x6 to enable XS on Tx side. */ @@ -9243,7 +9268,13 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,  	if (phy->req_duplex == DUPLEX_FULL)  		autoneg_val |= (1<<8); -	bnx2x_cl45_write(bp, phy, +	/* +	 * Always write this if this is not 84833. +	 * For 84833, write it only when it's a forced speed. +	 */ +	if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) || +		((autoneg_val & (1<<12)) == 0)) +		bnx2x_cl45_write(bp, phy,  			 MDIO_AN_DEVAD,  			 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); @@ -9257,13 +9288,12 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,  			bnx2x_cl45_write(bp, phy,  				 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,  				 0x3200); -	} else if (phy->req_line_speed != SPEED_10 && -		   phy->req_line_speed != SPEED_100) { +	} else  		bnx2x_cl45_write(bp, phy,  				 MDIO_AN_DEVAD,  				 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,  				 1); -	} +  	/* Save spirom version */  	bnx2x_save_848xx_spirom_version(phy, params); @@ -9756,11 +9786,9 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,  		bnx2x_cl45_read(bp, phy,  				MDIO_CTL_DEVAD,  				0x400f, &val16); -		/* Put to low power mode on newer FW */ -		if ((val16 & 0x303f) > 0x1009) -			bnx2x_cl45_write(bp, phy, -					MDIO_PMA_DEVAD, -					MDIO_PMA_REG_CTRL, 0x800); +		bnx2x_cl45_write(bp, phy, +				MDIO_PMA_DEVAD, +				MDIO_PMA_REG_CTRL, 0x800);  	}  } @@ -10191,8 +10219,15 @@ static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,  	u32 cfg_pin;  	u8 port; -	/* This works with E3 only, no need to check the chip -	   before determining the port. */ +	/* +	 * In case of no EPIO routed to reset the GPHY, put it +	 * in low power mode. +	 */ +	bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800); +	/* +	 * This works with E3 only, no need to check the chip +	 * before determining the port. +	 */  	port = params->port;  	cfg_pin = (REG_RD(bp, params->shmem_base +  			offsetof(struct shmem_region, @@ -10603,7 +10638,8 @@ static struct bnx2x_phy phy_warpcore = {  	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,  	.addr		= 0xff,  	.def_md_devad	= 0, -	.flags		= FLAGS_HW_LOCK_REQUIRED, +	.flags		= (FLAGS_HW_LOCK_REQUIRED | +			   FLAGS_TX_ERROR_CHECK),  	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},  	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},  	.mdio_ctrl	= 0, @@ -10729,7 +10765,8 @@ static struct bnx2x_phy phy_8706 = {  	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,  	.addr		= 0xff,  	.def_md_devad	= 0, -	.flags		= FLAGS_INIT_XGXS_FIRST, +	.flags		= (FLAGS_INIT_XGXS_FIRST | +			   FLAGS_TX_ERROR_CHECK),  	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},  	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},  	.mdio_ctrl	= 0, @@ -10760,7 +10797,8 @@ static struct bnx2x_phy phy_8726 = {  	.addr		= 0xff,  	.def_md_devad	= 0,  	.flags		= (FLAGS_HW_LOCK_REQUIRED | -			   FLAGS_INIT_XGXS_FIRST), +			   FLAGS_INIT_XGXS_FIRST | +			   FLAGS_TX_ERROR_CHECK),  	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},  	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},  	.mdio_ctrl	= 0, @@ -10791,7 +10829,8 @@ static struct bnx2x_phy phy_8727 = {  	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,  	.addr		= 0xff,  	.def_md_devad	= 0, -	.flags		= FLAGS_FAN_FAILURE_DET_REQ, +	.flags		= (FLAGS_FAN_FAILURE_DET_REQ | +			   FLAGS_TX_ERROR_CHECK),  	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},  	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},  	.mdio_ctrl	= 0, @@ -11112,6 +11151,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,  		 */  		if (CHIP_REV(bp) == CHIP_REV_Ax)  			phy->flags |= FLAGS_MDC_MDIO_WA; +		else +			phy->flags |= FLAGS_MDC_MDIO_WA_B0;  	} else {  		switch (switch_cfg) {  		case SWITCH_CFG_1G: @@ -11500,13 +11541,12 @@ void bnx2x_init_xmac_loopback(struct link_params *params,  	 * Set WC to loopback mode since link is required to provide clock  	 * to the XMAC in 20G mode  	 */ -	if (vars->line_speed == SPEED_20000) { -		bnx2x_set_aer_mmd(params, ¶ms->phy[0]); -		bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0); -		params->phy[INT_PHY].config_loopback( +	bnx2x_set_aer_mmd(params, ¶ms->phy[0]); +	bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0); +	params->phy[INT_PHY].config_loopback(  			¶ms->phy[INT_PHY],  			params); -	} +  	bnx2x_xmac_enable(params, vars, 1);  	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);  } @@ -11684,12 +11724,16 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,  	bnx2x_set_led(params, vars, LED_MODE_OFF, 0);  	if (reset_ext_phy) { +		bnx2x_set_mdio_clk(bp, params->chip_id, port);  		for (phy_index = EXT_PHY1; phy_index < params->num_phys;  		      phy_index++) { -			if (params->phy[phy_index].link_reset) +			if (params->phy[phy_index].link_reset) { +				bnx2x_set_aer_mmd(params, +						  ¶ms->phy[phy_index]);  				params->phy[phy_index].link_reset(  					¶ms->phy[phy_index],  					params); +			}  			if (params->phy[phy_index].flags &  			    FLAGS_REARM_LATCH_SIGNAL)  				clear_latch_ind = 1; @@ -12178,10 +12222,6 @@ static void bnx2x_analyze_link_error(struct link_params *params,  	u8 led_mode;  	u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0; -	/*DP(NETIF_MSG_LINK, "CHECK LINK: %x half_open:%x-> lss:%x\n", -		       vars->link_up, -		       half_open_conn, lss_status);*/ -  	if ((lss_status ^ half_open_conn) == 0)  		return; @@ -12194,6 +12234,7 @@ static void bnx2x_analyze_link_error(struct link_params *params,  	 * b. Update link_vars->link_up  	 */  	if (lss_status) { +		DP(NETIF_MSG_LINK, "Remote Fault detected !!!\n");  		vars->link_status &= ~LINK_STATUS_LINK_UP;  		vars->link_up = 0;  		vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; @@ -12203,6 +12244,7 @@ static void bnx2x_analyze_link_error(struct link_params *params,  		 */  		led_mode = LED_MODE_OFF;  	} else { +		DP(NETIF_MSG_LINK, "Remote Fault cleared\n");  		vars->link_status |= LINK_STATUS_LINK_UP;  		vars->link_up = 1;  		vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; @@ -12219,6 +12261,15 @@ static void bnx2x_analyze_link_error(struct link_params *params,  	bnx2x_notify_link_changed(bp);  } +/****************************************************************************** +* Description: +*	This function checks for half opened connection change indication. +*	When such change occurs, it calls the bnx2x_analyze_link_error +*	to check if Remote Fault is set or cleared. Reception of remote fault +*	status message in the MAC indicates that the peer's MAC has detected +*	a fault, for example, due to break in the TX side of fiber. +* +******************************************************************************/  static void bnx2x_check_half_open_conn(struct link_params *params,  				       struct link_vars *vars)  { @@ -12229,9 +12280,28 @@ static void bnx2x_check_half_open_conn(struct link_params *params,  	if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)  		return; -	if (!CHIP_IS_E3(bp) && +	if (CHIP_IS_E3(bp) &&  	    (REG_RD(bp, MISC_REG_RESET_REG_2) & -		   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))) { +	      (MISC_REGISTERS_RESET_REG_2_XMAC))) { +		/* Check E3 XMAC */ +		/* +		 * Note that link speed cannot be queried here, since it may be +		 * zero while link is down. In case UMAC is active, LSS will +		 * simply not be set +		 */ +		mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; + +		/* Clear stick bits (Requires rising edge) */ +		REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0); +		REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, +		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS | +		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS); +		if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS)) +			lss_status = 1; + +		bnx2x_analyze_link_error(params, vars, lss_status); +	} else if (REG_RD(bp, MISC_REG_RESET_REG_2) & +		   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {  		/* Check E1X / E2 BMAC */  		u32 lss_status_reg;  		u32 wb_data[2]; @@ -12253,14 +12323,20 @@ static void bnx2x_check_half_open_conn(struct link_params *params,  void bnx2x_period_func(struct link_params *params, struct link_vars *vars)  {  	struct bnx2x *bp = params->bp; +	u16 phy_idx;  	if (!params) { -		DP(NETIF_MSG_LINK, "Ininitliazed params !\n"); +		DP(NETIF_MSG_LINK, "Uninitialized params !\n");  		return;  	} -	/* DP(NETIF_MSG_LINK, "Periodic called vars->phy_flags 0x%x speed 0x%x -	 RESET_REG_2 0x%x\n", vars->phy_flags, vars->line_speed, -	  REG_RD(bp, MISC_REG_RESET_REG_2)); */ -	bnx2x_check_half_open_conn(params, vars); + +	for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { +		if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) { +			bnx2x_set_aer_mmd(params, ¶ms->phy[phy_idx]); +			bnx2x_check_half_open_conn(params, vars); +			break; +		} +	} +  	if (CHIP_IS_E3(bp))  		bnx2x_check_over_curr(params, vars);  } diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 6a7708d5da3..c12db6da213 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -145,6 +145,8 @@ struct bnx2x_phy {  #define FLAGS_SFP_NOT_APPROVED		(1<<7)  #define FLAGS_MDC_MDIO_WA		(1<<8)  #define FLAGS_DUMMY_READ		(1<<9) +#define FLAGS_MDC_MDIO_WA_B0		(1<<10) +#define FLAGS_TX_ERROR_CHECK		(1<<12)  	/* preemphasis values for the rx side */  	u16 rx_preemphasis[4]; @@ -276,7 +278,6 @@ struct link_vars {  #define PHY_PHYSICAL_LINK_FLAG		(1<<2)  #define PHY_HALF_OPEN_CONN_FLAG		(1<<3)  #define PHY_OVER_CURRENT_FLAG		(1<<4) -#define PHY_TX_ERROR_CHECK_FLAG		(1<<5)  	u8 mac_type;  #define MAC_TYPE_NONE		0 diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 15070911154..f74582a22c6 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -5798,6 +5798,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp)  	DP(BNX2X_MSG_MCP, "starting common init  func %d\n", BP_ABS_FUNC(bp)); +	/* +	 * take the UNDI lock to protect undi_unload flow from accessing +	 * registers while we're resetting the chip +	 */ +	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); +  	bnx2x_reset_common(bp);  	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); @@ -5808,6 +5814,8 @@ static int bnx2x_init_hw_common(struct bnx2x *bp)  	}  	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, val); +	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); +  	bnx2x_init_block(bp, BLOCK_MISC, PHASE_COMMON);  	if (!CHIP_IS_E1x(bp)) { @@ -10251,10 +10259,17 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,  	/* clean indirect addresses */  	pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,  			       PCICFG_VENDOR_ID_OFFSET); -	REG_WR(bp, PXP2_REG_PGL_ADDR_88_F0 + BP_PORT(bp)*16, 0); -	REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F0 + BP_PORT(bp)*16, 0); -	REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0 + BP_PORT(bp)*16, 0); -	REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0 + BP_PORT(bp)*16, 0); +	/* Clean the following indirect addresses for all functions since it +	 * is not used by the driver. +	 */ +	REG_WR(bp, PXP2_REG_PGL_ADDR_88_F0, 0); +	REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F0, 0); +	REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0, 0); +	REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0, 0); +	REG_WR(bp, PXP2_REG_PGL_ADDR_88_F1, 0); +	REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F1, 0); +	REG_WR(bp, PXP2_REG_PGL_ADDR_90_F1, 0); +	REG_WR(bp, PXP2_REG_PGL_ADDR_94_F1, 0);  	/*  	 * Enable internal target-read (in case we are probed after PF FLR). diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 02461fef875..40266c14e6d 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -3007,11 +3007,27 @@  /* [R 6] Debug only: Number of used entries in the data FIFO */  #define PXP2_REG_HST_DATA_FIFO_STATUS				 0x12047c  /* [R 7] Debug only: Number of used entries in the header FIFO */ -#define PXP2_REG_HST_HEADER_FIFO_STATUS 			 0x120478 -#define PXP2_REG_PGL_ADDR_88_F0 				 0x120534 -#define PXP2_REG_PGL_ADDR_8C_F0 				 0x120538 -#define PXP2_REG_PGL_ADDR_90_F0 				 0x12053c -#define PXP2_REG_PGL_ADDR_94_F0 				 0x120540 +#define PXP2_REG_HST_HEADER_FIFO_STATUS				 0x120478 +#define PXP2_REG_PGL_ADDR_88_F0					 0x120534 +/* [R 32] GRC address for configuration access to PCIE config address 0x88. + * any write to this PCIE address will cause a GRC write access to the + * address that's in t this register */ +#define PXP2_REG_PGL_ADDR_88_F1					 0x120544 +#define PXP2_REG_PGL_ADDR_8C_F0					 0x120538 +/* [R 32] GRC address for configuration access to PCIE config address 0x8c. + * any write to this PCIE address will cause a GRC write access to the + * address that's in t this register */ +#define PXP2_REG_PGL_ADDR_8C_F1					 0x120548 +#define PXP2_REG_PGL_ADDR_90_F0					 0x12053c +/* [R 32] GRC address for configuration access to PCIE config address 0x90. + * any write to this PCIE address will cause a GRC write access to the + * address that's in t this register */ +#define PXP2_REG_PGL_ADDR_90_F1					 0x12054c +#define PXP2_REG_PGL_ADDR_94_F0					 0x120540 +/* [R 32] GRC address for configuration access to PCIE config address 0x94. + * any write to this PCIE address will cause a GRC write access to the + * address that's in t this register */ +#define PXP2_REG_PGL_ADDR_94_F1					 0x120550  #define PXP2_REG_PGL_CONTROL0					 0x120490  #define PXP2_REG_PGL_CONTROL1					 0x120514  #define PXP2_REG_PGL_DEBUG					 0x120520 @@ -4771,9 +4787,11 @@     The fields are: [4:0] - tail pointer; 10:5] - Link List size; 15:11] -     header pointer. */  #define UCM_REG_XX_TABLE					 0xe0300 +#define UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE			 (0x1<<28)  #define UMAC_COMMAND_CONFIG_REG_LOOP_ENA			 (0x1<<15)  #define UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK			 (0x1<<24)  #define UMAC_COMMAND_CONFIG_REG_PAD_EN				 (0x1<<5) +#define UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE			 (0x1<<8)  #define UMAC_COMMAND_CONFIG_REG_PROMIS_EN			 (0x1<<4)  #define UMAC_COMMAND_CONFIG_REG_RX_ENA				 (0x1<<1)  #define UMAC_COMMAND_CONFIG_REG_SW_RESET			 (0x1<<13) @@ -5622,8 +5640,9 @@  #define EMAC_MDIO_COMM_START_BUSY				 (1L<<29)  #define EMAC_MDIO_MODE_AUTO_POLL				 (1L<<4)  #define EMAC_MDIO_MODE_CLAUSE_45				 (1L<<31) -#define EMAC_MDIO_MODE_CLOCK_CNT				 (0x3fL<<16) +#define EMAC_MDIO_MODE_CLOCK_CNT				 (0x3ffL<<16)  #define EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT			 16 +#define EMAC_MDIO_STATUS_10MB					 (1L<<1)  #define EMAC_MODE_25G_MODE					 (1L<<5)  #define EMAC_MODE_HALF_DUPLEX					 (1L<<1)  #define EMAC_MODE_PORT_GMII					 (2L<<2) @@ -5634,6 +5653,7 @@  #define EMAC_REG_EMAC_MAC_MATCH 				 0x10  #define EMAC_REG_EMAC_MDIO_COMM 				 0xac  #define EMAC_REG_EMAC_MDIO_MODE 				 0xb4 +#define EMAC_REG_EMAC_MDIO_STATUS				 0xb0  #define EMAC_REG_EMAC_MODE					 0x0  #define EMAC_REG_EMAC_RX_MODE					 0xc8  #define EMAC_REG_EMAC_RX_MTU_SIZE				 0x9c diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 02842d05c11..43f2ea54108 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1557,8 +1557,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)  			if (slave_dev->type != ARPHRD_ETHER)  				bond_setup_by_slave(bond_dev, slave_dev); -			else +			else {  				ether_setup(bond_dev); +				bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; +			}  			netdev_bonding_change(bond_dev,  					      NETDEV_POST_TYPE_CHANGE); @@ -3417,9 +3419,27 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)  static int bond_open(struct net_device *bond_dev)  {  	struct bonding *bond = netdev_priv(bond_dev); +	struct slave *slave; +	int i;  	bond->kill_timers = 0; +	/* reset slave->backup and slave->inactive */ +	read_lock(&bond->lock); +	if (bond->slave_cnt > 0) { +		read_lock(&bond->curr_slave_lock); +		bond_for_each_slave(bond, slave, i) { +			if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) +				&& (slave != bond->curr_active_slave)) { +				bond_set_slave_inactive_flags(slave); +			} else { +				bond_set_slave_active_flags(slave); +			} +		} +		read_unlock(&bond->curr_slave_lock); +	} +	read_unlock(&bond->lock); +  	INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed);  	if (bond_is_lb(bond)) { @@ -4330,7 +4350,7 @@ static void bond_setup(struct net_device *bond_dev)  	bond_dev->tx_queue_len = 0;  	bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;  	bond_dev->priv_flags |= IFF_BONDING; -	bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; +	bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);  	/* At first, we block adding VLANs. That's the only way to  	 * prevent problems that occur when adding VLANs over an @@ -4691,7 +4711,7 @@ static int bond_check_params(struct bond_params *params)  		/* miimon and arp_interval not set, we need one so things  		 * work as expected, see bonding.txt for details  		 */ -		pr_warning("Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details.\n"); +		pr_debug("Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details.\n");  	}  	if (primary && !USES_PRIMARY(bond_mode)) { diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index b60835f5865..2dfb4bf9008 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1025,6 +1025,7 @@ static ssize_t bonding_store_primary(struct device *d,  	int i;  	struct slave *slave;  	struct bonding *bond = to_bond(d); +	char ifname[IFNAMSIZ];  	if (!rtnl_trylock())  		return restart_syscall(); @@ -1035,32 +1036,33 @@ static ssize_t bonding_store_primary(struct device *d,  	if (!USES_PRIMARY(bond->params.mode)) {  		pr_info("%s: Unable to set primary slave; %s is in mode %d\n",  			bond->dev->name, bond->dev->name, bond->params.mode); -	} else { -		bond_for_each_slave(bond, slave, i) { -			if (strnicmp -			    (slave->dev->name, buf, -			     strlen(slave->dev->name)) == 0) { -				pr_info("%s: Setting %s as primary slave.\n", -					bond->dev->name, slave->dev->name); -				bond->primary_slave = slave; -				strcpy(bond->params.primary, slave->dev->name); -				bond_select_active_slave(bond); -				goto out; -			} -		} +		goto out; +	} -		/* if we got here, then we didn't match the name of any slave */ +	sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ -		if (strlen(buf) == 0 || buf[0] == '\n') { -			pr_info("%s: Setting primary slave to None.\n", -				bond->dev->name); -			bond->primary_slave = NULL; -				bond_select_active_slave(bond); -		} else { -			pr_info("%s: Unable to set %.*s as primary slave as it is not a slave.\n", -				bond->dev->name, (int)strlen(buf) - 1, buf); +	/* check to see if we are clearing primary */ +	if (!strlen(ifname) || buf[0] == '\n') { +		pr_info("%s: Setting primary slave to None.\n", +			bond->dev->name); +		bond->primary_slave = NULL; +		bond_select_active_slave(bond); +		goto out; +	} + +	bond_for_each_slave(bond, slave, i) { +		if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { +			pr_info("%s: Setting %s as primary slave.\n", +				bond->dev->name, slave->dev->name); +			bond->primary_slave = slave; +			strcpy(bond->params.primary, slave->dev->name); +			bond_select_active_slave(bond); +			goto out;  		}  	} + +	pr_info("%s: Unable to set %.*s as primary slave.\n", +		bond->dev->name, (int)strlen(buf) - 1, buf);  out:  	write_unlock_bh(&bond->curr_slave_lock);  	read_unlock(&bond->lock); @@ -1195,6 +1197,7 @@ static ssize_t bonding_store_active_slave(struct device *d,  	struct slave *old_active = NULL;  	struct slave *new_active = NULL;  	struct bonding *bond = to_bond(d); +	char ifname[IFNAMSIZ];  	if (!rtnl_trylock())  		return restart_syscall(); @@ -1203,56 +1206,62 @@ static ssize_t bonding_store_active_slave(struct device *d,  	read_lock(&bond->lock);  	write_lock_bh(&bond->curr_slave_lock); -	if (!USES_PRIMARY(bond->params.mode)) +	if (!USES_PRIMARY(bond->params.mode)) {  		pr_info("%s: Unable to change active slave; %s is in mode %d\n",  			bond->dev->name, bond->dev->name, bond->params.mode); -	else { -		bond_for_each_slave(bond, slave, i) { -			if (strnicmp -			    (slave->dev->name, buf, -			     strlen(slave->dev->name)) == 0) { -        			old_active = bond->curr_active_slave; -        			new_active = slave; -        			if (new_active == old_active) { -					/* do nothing */ -					pr_info("%s: %s is already the current active slave.\n", +		goto out; +	} + +	sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ + +	/* check to see if we are clearing active */ +	if (!strlen(ifname) || buf[0] == '\n') { +		pr_info("%s: Clearing current active slave.\n", +			bond->dev->name); +		bond->curr_active_slave = NULL; +		bond_select_active_slave(bond); +		goto out; +	} + +	bond_for_each_slave(bond, slave, i) { +		if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { +			old_active = bond->curr_active_slave; +			new_active = slave; +			if (new_active == old_active) { +				/* do nothing */ +				pr_info("%s: %s is already the current" +					" active slave.\n", +					bond->dev->name, +					slave->dev->name); +				goto out; +			} +			else { +				if ((new_active) && +				    (old_active) && +				    (new_active->link == BOND_LINK_UP) && +				    IS_UP(new_active->dev)) { +					pr_info("%s: Setting %s as active" +						" slave.\n",  						bond->dev->name,  						slave->dev->name); -					goto out; +					bond_change_active_slave(bond, +								 new_active);  				}  				else { -        				if ((new_active) && -            				    (old_active) && -				            (new_active->link == BOND_LINK_UP) && -				            IS_UP(new_active->dev)) { -						pr_info("%s: Setting %s as active slave.\n", -							bond->dev->name, -							slave->dev->name); -							bond_change_active_slave(bond, new_active); -        				} -					else { -						pr_info("%s: Could not set %s as active slave; either %s is down or the link is down.\n", -							bond->dev->name, -							slave->dev->name, -							slave->dev->name); -					} -					goto out; +					pr_info("%s: Could not set %s as" +						" active slave; either %s is" +						" down or the link is down.\n", +						bond->dev->name, +						slave->dev->name, +						slave->dev->name);  				} +				goto out;  			}  		} - -		/* if we got here, then we didn't match the name of any slave */ - -		if (strlen(buf) == 0 || buf[0] == '\n') { -			pr_info("%s: Setting active slave to None.\n", -				bond->dev->name); -			bond->primary_slave = NULL; -			bond_select_active_slave(bond); -		} else { -			pr_info("%s: Unable to set %.*s as active slave as it is not a slave.\n", -				bond->dev->name, (int)strlen(buf) - 1, buf); -		}  	} + +	pr_info("%s: Unable to set %.*s as active slave.\n", +		bond->dev->name, (int)strlen(buf) - 1, buf);   out:  	write_unlock_bh(&bond->curr_slave_lock);  	read_unlock(&bond->lock); diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index 231385b8e08..c7f3d4ea116 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -408,7 +408,7 @@ static void plx_pci_del_card(struct pci_dev *pdev)  	struct sja1000_priv *priv;  	int i = 0; -	for (i = 0; i < card->channels; i++) { +	for (i = 0; i < PLX_PCI_MAX_CHAN; i++) {  		dev = card->net_dev[i];  		if (!dev)  			continue; @@ -536,7 +536,6 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev,  			if (err) {  				dev_err(&pdev->dev, "Registering device failed "  					"(err=%d)\n", err); -				free_sja1000dev(dev);  				goto failure_cleanup;  			} @@ -549,6 +548,7 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev,  			dev_err(&pdev->dev, "Channel #%d not detected\n",  				i + 1);  			free_sja1000dev(dev); +			card->net_dev[i] = NULL;  		}  	} diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index f523f1cc514..4b70b7e8bde 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -197,7 +197,7 @@ static void slc_bump(struct slcan *sl)  	skb->ip_summed = CHECKSUM_UNNECESSARY;  	memcpy(skb_put(skb, sizeof(struct can_frame)),  	       &cf, sizeof(struct can_frame)); -	netif_rx(skb); +	netif_rx_ni(skb);  	sl->dev->stats.rx_packets++;  	sl->dev->stats.rx_bytes += cf.can_dlc; diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index f7bbde9eb2c..a81249246ec 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -503,9 +503,9 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)  	spin_unlock_irqrestore(&priv->mbx_lock, flags);  	/* Prepare mailbox for transmission */ +	data = cf->can_dlc | (get_tx_head_prio(priv) << 8);  	if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */  		data |= HECC_CANMCF_RTR; -	data |= get_tx_head_prio(priv) << 8;  	hecc_write_mbx(priv, mbxno, HECC_CANMCF, data);  	if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */ @@ -923,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev)  	priv->can.do_get_state = ti_hecc_get_state;  	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; +	spin_lock_init(&priv->mbx_lock);  	ndev->irq = irq->start;  	ndev->flags |= IFF_ECHO;  	platform_set_drvdata(pdev, ndev); diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index b414f5ae0da..fdb7a175640 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -98,7 +98,7 @@  #include <net/checksum.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/system.h>  #include <asm/io.h>  #include <asm/byteorder.h> @@ -2452,14 +2452,13 @@ static irqreturn_t cas_interruptN(int irq, void *dev_id)  	struct net_device *dev = dev_id;  	struct cas *cp = netdev_priv(dev);  	unsigned long flags; -	int ring; +	int ring = (irq == cp->pci_irq_INTC) ? 2 : 3;  	u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring));  	/* check for shared irq */  	if (status == 0)  		return IRQ_NONE; -	ring = (irq == cp->pci_irq_INTC) ? 2 : 3;  	spin_lock_irqsave(&cp->lock, flags);  	if (status & INTR_RX_DONE_ALT) { /* handle rx separately */  #ifdef USE_NAPI diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 086ce0418b2..e0638cb4b07 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -40,7 +40,7 @@  #include <linux/dma-mapping.h>  #include <linux/clk.h>  #include <linux/gpio.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");  MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)"); diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 32636a1d62a..805076c54f1 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -34,7 +34,7 @@  #include <linux/slab.h>  #include <net/neighbour.h>  #include <linux/notifier.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <linux/proc_fs.h>  #include <linux/if_vlan.h>  #include <net/netevent.h> diff --git a/drivers/net/cxgb3/l2t.h b/drivers/net/cxgb3/l2t.h index fd3eb07e3f4..7a12d52ed4f 100644 --- a/drivers/net/cxgb3/l2t.h +++ b/drivers/net/cxgb3/l2t.h @@ -34,7 +34,7 @@  #include <linux/spinlock.h>  #include "t3cdev.h" -#include <asm/atomic.h> +#include <linux/atomic.h>  enum {  	L2T_STATE_VALID,	/* entry is up to date */ diff --git a/drivers/net/cxgb3/t3cdev.h b/drivers/net/cxgb3/t3cdev.h index be55e9ae74d..705713b5663 100644 --- a/drivers/net/cxgb3/t3cdev.h +++ b/drivers/net/cxgb3/t3cdev.h @@ -33,7 +33,7 @@  #define _T3CDEV_H_  #include <linux/list.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <linux/netdevice.h>  #include <linux/proc_fs.h>  #include <linux/skbuff.h> diff --git a/drivers/net/cxgb4/cxgb4_uld.h b/drivers/net/cxgb4/cxgb4_uld.h index 1b48c017014..b1d39b8d141 100644 --- a/drivers/net/cxgb4/cxgb4_uld.h +++ b/drivers/net/cxgb4/cxgb4_uld.h @@ -38,7 +38,7 @@  #include <linux/cache.h>  #include <linux/spinlock.h>  #include <linux/skbuff.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  /* CPL message priority levels */  enum { diff --git a/drivers/net/cxgb4/l2t.h b/drivers/net/cxgb4/l2t.h index 7bd8f42378f..02b31d0c641 100644 --- a/drivers/net/cxgb4/l2t.h +++ b/drivers/net/cxgb4/l2t.h @@ -37,7 +37,7 @@  #include <linux/spinlock.h>  #include <linux/if_ether.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  struct adapter;  struct l2t_data; diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index c5f0f04219f..5548d464261 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -838,6 +838,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  	/* Disable all the interrupts */  	ew32(IMC, 0xFFFFFFFF); +	E1000_WRITE_FLUSH();  	msleep(10);  	/* Test each interrupt */ @@ -856,6 +857,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  			adapter->test_icr = 0;  			ew32(IMC, mask);  			ew32(ICS, mask); +			E1000_WRITE_FLUSH();  			msleep(10);  			if (adapter->test_icr & mask) { @@ -873,6 +875,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  		adapter->test_icr = 0;  		ew32(IMS, mask);  		ew32(ICS, mask); +		E1000_WRITE_FLUSH();  		msleep(10);  		if (!(adapter->test_icr & mask)) { @@ -890,6 +893,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  			adapter->test_icr = 0;  			ew32(IMC, ~mask & 0x00007FFF);  			ew32(ICS, ~mask & 0x00007FFF); +			E1000_WRITE_FLUSH();  			msleep(10);  			if (adapter->test_icr) { @@ -901,6 +905,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  	/* Disable all the interrupts */  	ew32(IMC, 0xFFFFFFFF); +	E1000_WRITE_FLUSH();  	msleep(10);  	/* Unhook test interrupt handler */ @@ -1394,6 +1399,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)  			if (unlikely(++k == txdr->count)) k = 0;  		}  		ew32(TDT, k); +		E1000_WRITE_FLUSH();  		msleep(200);  		time = jiffies; /* set the start time for the receive */  		good_cnt = 0; diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 1698622af43..8545c7aa93e 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -446,6 +446,7 @@ s32 e1000_reset_hw(struct e1000_hw *hw)  	/* Must reset the PHY before resetting the MAC */  	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {  		ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST)); +		E1000_WRITE_FLUSH();  		msleep(5);  	} @@ -3752,6 +3753,7 @@ static s32 e1000_acquire_eeprom(struct e1000_hw *hw)  		/* Clear SK and CS */  		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);  		ew32(EECD, eecd); +		E1000_WRITE_FLUSH();  		udelay(1);  	} @@ -3824,6 +3826,7 @@ static void e1000_release_eeprom(struct e1000_hw *hw)  		eecd &= ~E1000_EECD_SK;	/* Lower SCK */  		ew32(EECD, eecd); +		E1000_WRITE_FLUSH();  		udelay(hw->eeprom.delay_usec);  	} else if (hw->eeprom.type == e1000_eeprom_microwire) { diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 480f2592f8a..536b3a55c45 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -2085,7 +2085,8 @@ struct e1000_info e1000_82574_info = {  				  | FLAG_HAS_AMT  				  | FLAG_HAS_CTRLEXT_ON_LOAD,  	.flags2			  = FLAG2_CHECK_PHY_HANG -				  | FLAG2_DISABLE_ASPM_L0S, +				  | FLAG2_DISABLE_ASPM_L0S +				  | FLAG2_NO_DISABLE_RX,  	.pba			= 32,  	.max_hw_frame_size	= DEFAULT_JUMBO,  	.get_variants		= e1000_get_variants_82571, @@ -2104,7 +2105,8 @@ struct e1000_info e1000_82583_info = {  				  | FLAG_HAS_AMT  				  | FLAG_HAS_JUMBO_FRAMES  				  | FLAG_HAS_CTRLEXT_ON_LOAD, -	.flags2			= FLAG2_DISABLE_ASPM_L0S, +	.flags2			= FLAG2_DISABLE_ASPM_L0S +				  | FLAG2_NO_DISABLE_RX,  	.pba			= 32,  	.max_hw_frame_size	= DEFAULT_JUMBO,  	.get_variants		= e1000_get_variants_82571, diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 638d175792c..8533ad7f355 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -155,6 +155,9 @@ struct e1000_info;  #define HV_M_STATUS_SPEED_1000            0x0200  #define HV_M_STATUS_LINK_UP               0x0040 +#define E1000_ICH_FWSM_PCIM2PCI		0x01000000 /* ME PCIm-to-PCI active */ +#define E1000_ICH_FWSM_PCIM2PCI_COUNT	2000 +  /* Time to wait before putting the device into D3 if there's no link (in ms). */  #define LINK_TIMEOUT		100 @@ -453,6 +456,8 @@ struct e1000_info {  #define FLAG2_DISABLE_ASPM_L0S            (1 << 7)  #define FLAG2_DISABLE_AIM                 (1 << 8)  #define FLAG2_CHECK_PHY_HANG              (1 << 9) +#define FLAG2_NO_DISABLE_RX               (1 << 10) +#define FLAG2_PCIM2PCI_ARBITER_WA         (1 << 11)  #define E1000_RX_DESC_PS(R, i)	    \  	(&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index c0ecb2d9fdb..e4f42257c24 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -1313,6 +1313,7 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,  	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &  	               E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;  	ew32(KMRNCTRLSTA, kmrnctrlsta); +	e1e_flush();  	udelay(2); @@ -1347,6 +1348,7 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,  	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &  	               E1000_KMRNCTRLSTA_OFFSET) | data;  	ew32(KMRNCTRLSTA, kmrnctrlsta); +	e1e_flush();  	udelay(2); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index cb1a3623253..6a0526a59a8 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -28,8 +28,8 @@  /* ethtool support for e1000 */ -#include <linux/interrupt.h>  #include <linux/netdevice.h> +#include <linux/interrupt.h>  #include <linux/ethtool.h>  #include <linux/pci.h>  #include <linux/slab.h> @@ -964,6 +964,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  	/* Disable all the interrupts */  	ew32(IMC, 0xFFFFFFFF); +	e1e_flush();  	usleep_range(10000, 20000);  	/* Test each interrupt */ @@ -996,6 +997,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  			adapter->test_icr = 0;  			ew32(IMC, mask);  			ew32(ICS, mask); +			e1e_flush();  			usleep_range(10000, 20000);  			if (adapter->test_icr & mask) { @@ -1014,6 +1016,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  		adapter->test_icr = 0;  		ew32(IMS, mask);  		ew32(ICS, mask); +		e1e_flush();  		usleep_range(10000, 20000);  		if (!(adapter->test_icr & mask)) { @@ -1032,6 +1035,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  			adapter->test_icr = 0;  			ew32(IMC, ~mask & 0x00007FFF);  			ew32(ICS, ~mask & 0x00007FFF); +			e1e_flush();  			usleep_range(10000, 20000);  			if (adapter->test_icr) { @@ -1043,6 +1047,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)  	/* Disable all the interrupts */  	ew32(IMC, 0xFFFFFFFF); +	e1e_flush();  	usleep_range(10000, 20000);  	/* Unhook test interrupt handler */ @@ -1201,7 +1206,8 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)  	rx_ring->next_to_clean = 0;  	rctl = er32(RCTL); -	ew32(RCTL, rctl & ~E1000_RCTL_EN); +	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) +		ew32(RCTL, rctl & ~E1000_RCTL_EN);  	ew32(RDBAL, ((u64) rx_ring->dma & 0xFFFFFFFF));  	ew32(RDBAH, ((u64) rx_ring->dma >> 32));  	ew32(RDLEN, rx_ring->size); @@ -1276,6 +1282,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)  			     E1000_CTRL_FD);	 /* Force Duplex to FULL */  		ew32(CTRL, ctrl_reg); +		e1e_flush();  		udelay(500);  		return 0; @@ -1418,6 +1425,7 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter)  	 */  #define E1000_SERDES_LB_ON 0x410  	ew32(SCTL, E1000_SERDES_LB_ON); +	e1e_flush();  	usleep_range(10000, 20000);  	return 0; @@ -1513,6 +1521,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)  		    hw->phy.media_type == e1000_media_type_internal_serdes) {  #define E1000_SERDES_LB_OFF 0x400  			ew32(SCTL, E1000_SERDES_LB_OFF); +			e1e_flush();  			usleep_range(10000, 20000);  			break;  		} @@ -1592,6 +1601,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)  				k = 0;  		}  		ew32(TDT, k); +		e1e_flush();  		msleep(200);  		time = jiffies; /* set the start time for the receive */  		good_cnt = 0; diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index c1752124f3c..54add27c8f7 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -137,8 +137,9 @@  #define HV_PM_CTRL		PHY_REG(770, 17)  /* PHY Low Power Idle Control */ -#define I82579_LPI_CTRL			PHY_REG(772, 20) -#define I82579_LPI_CTRL_ENABLE_MASK	0x6000 +#define I82579_LPI_CTRL				PHY_REG(772, 20) +#define I82579_LPI_CTRL_ENABLE_MASK		0x6000 +#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT	0x80  /* EMI Registers */  #define I82579_EMI_ADDR         0x10 @@ -163,6 +164,11 @@  #define HV_KMRN_MODE_CTRL      PHY_REG(769, 16)  #define HV_KMRN_MDIO_SLOW      0x0400 +/* KMRN FIFO Control and Status */ +#define HV_KMRN_FIFO_CTRLSTA                  PHY_REG(770, 16) +#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK    0x7000 +#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT   12 +  /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */  /* Offset 04h HSFSTS */  union ich8_hws_flash_status { @@ -283,6 +289,7 @@ static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw)  	ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;  	ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;  	ew32(CTRL, ctrl); +	e1e_flush();  	udelay(10);  	ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;  	ew32(CTRL, ctrl); @@ -656,6 +663,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)  	struct e1000_mac_info *mac = &hw->mac;  	s32 ret_val;  	bool link; +	u16 phy_reg;  	/*  	 * We only want to go out to the PHY registers to see if Auto-Neg @@ -688,16 +696,35 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)  	mac->get_link_status = false; -	if (hw->phy.type == e1000_phy_82578) { -		ret_val = e1000_link_stall_workaround_hv(hw); -		if (ret_val) -			goto out; -	} - -	if (hw->mac.type == e1000_pch2lan) { +	switch (hw->mac.type) { +	case e1000_pch2lan:  		ret_val = e1000_k1_workaround_lv(hw);  		if (ret_val)  			goto out; +		/* fall-thru */ +	case e1000_pchlan: +		if (hw->phy.type == e1000_phy_82578) { +			ret_val = e1000_link_stall_workaround_hv(hw); +			if (ret_val) +				goto out; +		} + +		/* +		 * Workaround for PCHx parts in half-duplex: +		 * Set the number of preambles removed from the packet +		 * when it is passed from the PHY to the MAC to prevent +		 * the MAC from misinterpreting the packet type. +		 */ +		e1e_rphy(hw, HV_KMRN_FIFO_CTRLSTA, &phy_reg); +		phy_reg &= ~HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK; + +		if ((er32(STATUS) & E1000_STATUS_FD) != E1000_STATUS_FD) +			phy_reg |= (1 << HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT); + +		e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, phy_reg); +		break; +	default: +		break;  	}  	/* @@ -787,6 +814,11 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)  	    (adapter->hw.phy.type == e1000_phy_igp_3))  		adapter->flags |= FLAG_LSC_GIG_SPEED_DROP; +	/* Enable workaround for 82579 w/ ME enabled */ +	if ((adapter->hw.mac.type == e1000_pch2lan) && +	    (er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) +		adapter->flags2 |= FLAG2_PCIM2PCI_ARBITER_WA; +  	/* Disable EEE by default until IEEE802.3az spec is finalized */  	if (adapter->flags2 & FLAG2_HAS_EEE)  		adapter->hw.dev_spec.ich8lan.eee_disable = true; @@ -1230,9 +1262,11 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)  	ew32(CTRL, reg);  	ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS); +	e1e_flush();  	udelay(20);  	ew32(CTRL, ctrl_reg);  	ew32(CTRL_EXT, ctrl_ext); +	e1e_flush();  	udelay(20);  out: @@ -1352,7 +1386,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)  			return ret_val;  		/* Preamble tuning for SSC */ -		ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204); +		ret_val = e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, 0xA204);  		if (ret_val)  			return ret_val;  	} @@ -1642,6 +1676,7 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)  	s32 ret_val = 0;  	u16 status_reg = 0;  	u32 mac_reg; +	u16 phy_reg;  	if (hw->mac.type != e1000_pch2lan)  		goto out; @@ -1656,12 +1691,19 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)  		mac_reg = er32(FEXTNVM4);  		mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; -		if (status_reg & HV_M_STATUS_SPEED_1000) +		ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg); +		if (ret_val) +			goto out; + +		if (status_reg & HV_M_STATUS_SPEED_1000) {  			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; -		else +			phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; +		} else {  			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; - +			phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; +		}  		ew32(FEXTNVM4, mac_reg); +		ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);  	}  out: @@ -2134,8 +2176,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,  	ret_val = 0;  	for (i = 0; i < words; i++) { -		if ((dev_spec->shadow_ram) && -		    (dev_spec->shadow_ram[offset+i].modified)) { +		if (dev_spec->shadow_ram[offset+i].modified) {  			data[i] = dev_spec->shadow_ram[offset+i].value;  		} else {  			ret_val = e1000_read_flash_word_ich8lan(hw, @@ -3090,6 +3131,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)  	ret_val = e1000_acquire_swflag_ich8lan(hw);  	e_dbg("Issuing a global reset to ich8lan\n");  	ew32(CTRL, (ctrl | E1000_CTRL_RST)); +	/* cannot issue a flush here because it hangs the hardware */  	msleep(20);  	if (!ret_val) diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 65580b40594..0893ab107ad 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -190,7 +190,8 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)  	/* Check for LOM (vs. NIC) or one of two valid mezzanine cards */  	if (!((nvm_data & NVM_COMPAT_LOM) ||  	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || -	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD))) +	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) || +	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES)))  		goto out;  	ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, @@ -200,10 +201,10 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)  		goto out;  	} -	if (nvm_alt_mac_addr_offset == 0xFFFF) { +	if ((nvm_alt_mac_addr_offset == 0xFFFF) || +	    (nvm_alt_mac_addr_offset == 0x0000))  		/* There is no Alternate MAC Address */  		goto out; -	}  	if (hw->bus.func == E1000_FUNC_1)  		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; @@ -1986,6 +1987,7 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)  		/* Clear SK and CS */  		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);  		ew32(EECD, eecd); +		e1e_flush();  		udelay(1);  		/* diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4353ad56cf1..2198e615f24 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -31,12 +31,12 @@  #include <linux/module.h>  #include <linux/types.h>  #include <linux/init.h> -#include <linux/interrupt.h>  #include <linux/pci.h>  #include <linux/vmalloc.h>  #include <linux/pagemap.h>  #include <linux/delay.h>  #include <linux/netdevice.h> +#include <linux/interrupt.h>  #include <linux/tcp.h>  #include <linux/ipv6.h>  #include <linux/slab.h> @@ -56,7 +56,7 @@  #define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "1.3.16" DRV_EXTRAVERSION +#define DRV_VERSION "1.4.4" DRV_EXTRAVERSION  char e1000e_driver_name[] = "e1000e";  const char e1000e_driver_version[] = DRV_VERSION; @@ -519,6 +519,63 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,  }  /** + * e1000e_update_tail_wa - helper function for e1000e_update_[rt]dt_wa() + * @hw: pointer to the HW structure + * @tail: address of tail descriptor register + * @i: value to write to tail descriptor register + * + * When updating the tail register, the ME could be accessing Host CSR + * registers at the same time.  Normally, this is handled in h/w by an + * arbiter but on some parts there is a bug that acknowledges Host accesses + * later than it should which could result in the descriptor register to + * have an incorrect value.  Workaround this by checking the FWSM register + * which has bit 24 set while ME is accessing Host CSR registers, wait + * if it is set and try again a number of times. + **/ +static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail, +					unsigned int i) +{ +	unsigned int j = 0; + +	while ((j++ < E1000_ICH_FWSM_PCIM2PCI_COUNT) && +	       (er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI)) +		udelay(50); + +	writel(i, tail); + +	if ((j == E1000_ICH_FWSM_PCIM2PCI_COUNT) && (i != readl(tail))) +		return E1000_ERR_SWFW_SYNC; + +	return 0; +} + +static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) +{ +	u8 __iomem *tail = (adapter->hw.hw_addr + adapter->rx_ring->tail); +	struct e1000_hw *hw = &adapter->hw; + +	if (e1000e_update_tail_wa(hw, tail, i)) { +		u32 rctl = er32(RCTL); +		ew32(RCTL, rctl & ~E1000_RCTL_EN); +		e_err("ME firmware caused invalid RDT - resetting\n"); +		schedule_work(&adapter->reset_task); +	} +} + +static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) +{ +	u8 __iomem *tail = (adapter->hw.hw_addr + adapter->tx_ring->tail); +	struct e1000_hw *hw = &adapter->hw; + +	if (e1000e_update_tail_wa(hw, tail, i)) { +		u32 tctl = er32(TCTL); +		ew32(TCTL, tctl & ~E1000_TCTL_EN); +		e_err("ME firmware caused invalid TDT - resetting\n"); +		schedule_work(&adapter->reset_task); +	} +} + +/**   * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended   * @adapter: address of board private structure   **/ @@ -573,7 +630,10 @@ map_skb:  			 * such as IA-64).  			 */  			wmb(); -			writel(i, adapter->hw.hw_addr + rx_ring->tail); +			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) +				e1000e_update_rdt_wa(adapter, i); +			else +				writel(i, adapter->hw.hw_addr + rx_ring->tail);  		}  		i++;  		if (i == rx_ring->count) @@ -673,7 +733,11 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,  			 * such as IA-64).  			 */  			wmb(); -			writel(i << 1, adapter->hw.hw_addr + rx_ring->tail); +			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) +				e1000e_update_rdt_wa(adapter, i << 1); +			else +				writel(i << 1, +				       adapter->hw.hw_addr + rx_ring->tail);  		}  		i++; @@ -756,7 +820,10 @@ check_page:  		 * applicable for weak-ordered memory model archs,  		 * such as IA-64). */  		wmb(); -		writel(i, adapter->hw.hw_addr + rx_ring->tail); +		if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) +			e1000e_update_rdt_wa(adapter, i); +		else +			writel(i, adapter->hw.hw_addr + rx_ring->tail);  	}  } @@ -2915,7 +2982,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)  	/* disable receives while setting up the descriptors */  	rctl = er32(RCTL); -	ew32(RCTL, rctl & ~E1000_RCTL_EN); +	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) +		ew32(RCTL, rctl & ~E1000_RCTL_EN);  	e1e_flush();  	usleep_range(10000, 20000); @@ -3394,7 +3462,8 @@ void e1000e_down(struct e1000_adapter *adapter)  	/* disable receives in the hardware */  	rctl = er32(RCTL); -	ew32(RCTL, rctl & ~E1000_RCTL_EN); +	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) +		ew32(RCTL, rctl & ~E1000_RCTL_EN);  	/* flush and sleep below */  	netif_stop_queue(netdev); @@ -3403,6 +3472,7 @@ void e1000e_down(struct e1000_adapter *adapter)  	tctl = er32(TCTL);  	tctl &= ~E1000_TCTL_EN;  	ew32(TCTL, tctl); +  	/* flush both disables and wait for them to finish */  	e1e_flush();  	usleep_range(10000, 20000); @@ -4686,7 +4756,12 @@ static void e1000_tx_queue(struct e1000_adapter *adapter,  	wmb();  	tx_ring->next_to_use = i; -	writel(i, adapter->hw.hw_addr + tx_ring->tail); + +	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) +		e1000e_update_tdt_wa(adapter, i); +	else +		writel(i, adapter->hw.hw_addr + tx_ring->tail); +  	/*  	 * we need this if more than one processor can write to our tail  	 * at a time, it synchronizes IO on IA64/Altix systems diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 2a6ee13285b..8666476cb9b 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -537,6 +537,7 @@ static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,  	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &  		       E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;  	ew32(KMRNCTRLSTA, kmrnctrlsta); +	e1e_flush();  	udelay(2); @@ -609,6 +610,7 @@ static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,  	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &  		       E1000_KMRNCTRLSTA_OFFSET) | data;  	ew32(KMRNCTRLSTA, kmrnctrlsta); +	e1e_flush();  	udelay(2); diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 5b631fe7473..e8266ccf818 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -44,6 +44,10 @@  #include <linux/platform_device.h>  #include <linux/phy.h>  #include <linux/fec.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <linux/of_net.h>  #include <asm/cacheflush.h> @@ -66,17 +70,42 @@  #define FEC_QUIRK_ENET_MAC		(1 << 0)  /* Controller needs driver to swap frame */  #define FEC_QUIRK_SWAP_FRAME		(1 << 1) +/* Controller uses gasket */ +#define FEC_QUIRK_USE_GASKET		(1 << 2)  static struct platform_device_id fec_devtype[] = {  	{ +		/* keep it for coldfire */  		.name = DRIVER_NAME,  		.driver_data = 0,  	}, { +		.name = "imx25-fec", +		.driver_data = FEC_QUIRK_USE_GASKET, +	}, { +		.name = "imx27-fec", +		.driver_data = 0, +	}, {  		.name = "imx28-fec",  		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, -	}, -	{ } +	}, { +		/* sentinel */ +	}  }; +MODULE_DEVICE_TABLE(platform, fec_devtype); + +enum imx_fec_type { +	IMX25_FEC = 1, 	/* runs on i.mx25/50/53 */ +	IMX27_FEC,	/* runs on i.mx27/35/51 */ +	IMX28_FEC, +}; + +static const struct of_device_id fec_dt_ids[] = { +	{ .compatible = "fsl,imx25-fec", .data = &fec_devtype[IMX25_FEC], }, +	{ .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], }, +	{ .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], }, +	{ /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, fec_dt_ids);  static unsigned char macaddr[ETH_ALEN];  module_param_array(macaddr, byte, NULL, 0); @@ -427,7 +456,7 @@ fec_restart(struct net_device *ndev, int duplex)  	} else {  #ifdef FEC_MIIGSK_ENR -		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) { +		if (id_entry->driver_data & FEC_QUIRK_USE_GASKET) {  			/* disable the gasket and wait */  			writel(0, fep->hwp + FEC_MIIGSK_ENR);  			while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4) @@ -436,8 +465,11 @@ fec_restart(struct net_device *ndev, int duplex)  			/*  			 * configure the gasket:  			 *   RMII, 50 MHz, no loopback, no echo +			 *   MII, 25 MHz, no loopback, no echo  			 */ -			writel(1, fep->hwp + FEC_MIIGSK_CFGR); +			writel((fep->phy_interface == PHY_INTERFACE_MODE_RMII) ? +					1 : 0, fep->hwp + FEC_MIIGSK_CFGR); +  			/* re-enable the gasket */  			writel(2, fep->hwp + FEC_MIIGSK_ENR); @@ -734,8 +766,22 @@ static void __inline__ fec_get_mac(struct net_device *ndev)  	 */  	iap = macaddr; +#ifdef CONFIG_OF  	/* -	 * 2) from flash or fuse (via platform data) +	 * 2) from device tree data +	 */ +	if (!is_valid_ether_addr(iap)) { +		struct device_node *np = fep->pdev->dev.of_node; +		if (np) { +			const char *mac = of_get_mac_address(np); +			if (mac) +				iap = (unsigned char *) mac; +		} +	} +#endif + +	/* +	 * 3) from flash or fuse (via platform data)  	 */  	if (!is_valid_ether_addr(iap)) {  #ifdef CONFIG_M5272 @@ -748,7 +794,7 @@ static void __inline__ fec_get_mac(struct net_device *ndev)  	}  	/* -	 * 3) FEC mac registers set by bootloader +	 * 4) FEC mac registers set by bootloader  	 */  	if (!is_valid_ether_addr(iap)) {  		*((unsigned long *) &tmpaddr[0]) = @@ -1354,6 +1400,52 @@ static int fec_enet_init(struct net_device *ndev)  	return 0;  } +#ifdef CONFIG_OF +static int __devinit fec_get_phy_mode_dt(struct platform_device *pdev) +{ +	struct device_node *np = pdev->dev.of_node; + +	if (np) +		return of_get_phy_mode(np); + +	return -ENODEV; +} + +static int __devinit fec_reset_phy(struct platform_device *pdev) +{ +	int err, phy_reset; +	struct device_node *np = pdev->dev.of_node; + +	if (!np) +		return -ENODEV; + +	phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0); +	err = gpio_request_one(phy_reset, GPIOF_OUT_INIT_LOW, "phy-reset"); +	if (err) { +		pr_warn("FEC: failed to get gpio phy-reset: %d\n", err); +		return err; +	} +	msleep(1); +	gpio_set_value(phy_reset, 1); + +	return 0; +} +#else /* CONFIG_OF */ +static inline int fec_get_phy_mode_dt(struct platform_device *pdev) +{ +	return -ENODEV; +} + +static inline int fec_reset_phy(struct platform_device *pdev) +{ +	/* +	 * In case of platform probe, the reset has been done +	 * by machine code. +	 */ +	return 0; +} +#endif /* CONFIG_OF */ +  static int __devinit  fec_probe(struct platform_device *pdev)  { @@ -1362,6 +1454,11 @@ fec_probe(struct platform_device *pdev)  	struct net_device *ndev;  	int i, irq, ret = 0;  	struct resource *r; +	const struct of_device_id *of_id; + +	of_id = of_match_device(fec_dt_ids, &pdev->dev); +	if (of_id) +		pdev->id_entry = of_id->data;  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!r) @@ -1393,9 +1490,18 @@ fec_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, ndev); -	pdata = pdev->dev.platform_data; -	if (pdata) -		fep->phy_interface = pdata->phy; +	ret = fec_get_phy_mode_dt(pdev); +	if (ret < 0) { +		pdata = pdev->dev.platform_data; +		if (pdata) +			fep->phy_interface = pdata->phy; +		else +			fep->phy_interface = PHY_INTERFACE_MODE_MII; +	} else { +		fep->phy_interface = ret; +	} + +	fec_reset_phy(pdev);  	/* This device has up to three irqs on some platforms */  	for (i = 0; i < 3; i++) { @@ -1530,6 +1636,7 @@ static struct platform_driver fec_driver = {  #ifdef CONFIG_PM  		.pm	= &fec_pm_ops,  #endif +		.of_match_table = fec_dt_ids,  	},  	.id_table = fec_devtype,  	.probe	= fec_probe, diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index e64cd9ceac3..6d5fbd4d425 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2764,7 +2764,14 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)  			prefetch(skb->data);  			vlanflags = le32_to_cpu(np->get_rx.ex->buflow); -			if (vlanflags & NV_RX3_VLAN_TAG_PRESENT) { + +			/* +			 * There's need to check for NETIF_F_HW_VLAN_RX here. +			 * Even if vlan rx accel is disabled, +			 * NV_RX3_VLAN_TAG_PRESENT is pseudo randomly set. +			 */ +			if (dev->features & NETIF_F_HW_VLAN_RX && +			    vlanflags & NV_RX3_VLAN_TAG_PRESENT) {  				u16 vid = vlanflags & NV_RX3_VLAN_TAG_MASK;  				__vlan_hwaccel_put_tag(skb, vid); @@ -5331,15 +5338,16 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i  		np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;  		dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG |  			NETIF_F_TSO | NETIF_F_RXCSUM; -		dev->features |= dev->hw_features;  	}  	np->vlanctl_bits = 0;  	if (id->driver_data & DEV_HAS_VLAN) {  		np->vlanctl_bits = NVREG_VLANCONTROL_ENABLE; -		dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX; +		dev->hw_features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;  	} +	dev->features |= dev->hw_features; +  	np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG;  	if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) ||  	    (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) || @@ -5607,6 +5615,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i  		goto out_error;  	} +	if (id->driver_data & DEV_HAS_VLAN) +		nv_vlan_mode(dev, dev->features); +  	netif_carrier_off(dev);  	dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 835cd258814..31d5c574e5a 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -388,12 +388,8 @@ static void gfar_init_mac(struct net_device *ndev)  	if (priv->hwts_rx_en)  		rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE; -	/* keep vlan related bits if it's enabled */ -	if (ndev->features & NETIF_F_HW_VLAN_TX) -		rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT; -  	if (ndev->features & NETIF_F_HW_VLAN_RX) -		tctrl |= TCTRL_VLINS; +		rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;  	/* Init rctrl based on our settings */  	gfar_write(®s->rctrl, rctrl); @@ -2714,8 +2710,13 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,  	/* Tell the skb what kind of packet this is */  	skb->protocol = eth_type_trans(skb, dev); -	/* Set vlan tag */ -	if (fcb->flags & RXFCB_VLN) +	/* +	 * There's need to check for NETIF_F_HW_VLAN_RX here. +	 * Even if vlan rx accel is disabled, on some chips +	 * RXFCB_VLN is pseudo randomly set. +	 */ +	if (dev->features & NETIF_F_HW_VLAN_RX && +	    fcb->flags & RXFCB_VLN)  		__vlan_hwaccel_put_tag(skb, fcb->vlctl);  	/* Send the packet up the stack */ diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 6e350692d11..25a8c2adb00 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -686,10 +686,21 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u  {  	unsigned int last_rule_idx = priv->cur_filer_idx;  	unsigned int cmp_rqfpr; -	unsigned int local_rqfpr[MAX_FILER_IDX + 1]; -	unsigned int local_rqfcr[MAX_FILER_IDX + 1]; +	unsigned int *local_rqfpr; +	unsigned int *local_rqfcr;  	int i = 0x0, k = 0x0;  	int j = MAX_FILER_IDX, l = 0x0; +	int ret = 1; + +	local_rqfpr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1), +		GFP_KERNEL); +	local_rqfcr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1), +		GFP_KERNEL); +	if (!local_rqfpr || !local_rqfcr) { +		pr_err("Out of memory\n"); +		ret = 0; +		goto err; +	}  	switch (class) {  	case TCP_V4_FLOW: @@ -706,7 +717,8 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u  		break;  	default:  		pr_err("Right now this class is not supported\n"); -		return 0; +		ret = 0; +		goto err;  	}  	for (i = 0; i < MAX_FILER_IDX + 1; i++) { @@ -721,7 +733,8 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u  	if (i == MAX_FILER_IDX + 1) {  		pr_err("No parse rule found, can't create hash rules\n"); -		return 0; +		ret = 0; +		goto err;  	}  	/* If a match was found, then it begins the starting of a cluster rule @@ -765,7 +778,10 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u  		priv->cur_filer_idx = priv->cur_filer_idx - 1;  	} -	return 1; +err: +	kfree(local_rqfcr); +	kfree(local_rqfpr); +	return ret;  }  static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd) diff --git a/drivers/net/gianfar_ptp.c b/drivers/net/gianfar_ptp.c index 1c97861596f..f67b8aebc89 100644 --- a/drivers/net/gianfar_ptp.c +++ b/drivers/net/gianfar_ptp.c @@ -193,14 +193,9 @@ static void set_alarm(struct etsects *etsects)  /* Caller must hold etsects->lock. */  static void set_fipers(struct etsects *etsects)  { -	u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl); - -	gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl & (~TE)); -	gfar_write(&etsects->regs->tmr_prsc,   etsects->tmr_prsc); +	set_alarm(etsects);  	gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1);  	gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); -	set_alarm(etsects); -	gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl|TE);  }  /* @@ -511,7 +506,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)  	gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1);  	gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2);  	set_alarm(etsects); -	gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl|FS|RTPE|TE); +	gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl|FS|RTPE|TE|FRD);  	spin_unlock_irqrestore(&etsects->lock, flags); diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 0d283781bc5..2a5a34d2d67 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -36,7 +36,7 @@  #include <linux/tcp.h>  #include <linux/semaphore.h>  #include <linux/compat.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #define SIXPACK_VERSION    "Revision: 0.3.0" diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 52b14256e2c..ce555d9ac02 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -36,7 +36,7 @@  #include <linux/rtnetlink.h>  #include <linux/sockios.h>  #include <linux/workqueue.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/dma.h>  #include <asm/io.h>  #include <asm/irq.h> diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 725399ea069..70cb7d8a3b5 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -39,6 +39,7 @@  #include <linux/bitops.h>  #include <linux/workqueue.h>  #include <linux/of.h> +#include <linux/of_net.h>  #include <linux/slab.h>  #include <asm/processor.h> @@ -2506,18 +2507,6 @@ static int __devinit emac_init_config(struct emac_instance *dev)  {  	struct device_node *np = dev->ofdev->dev.of_node;  	const void *p; -	unsigned int plen; -	const char *pm, *phy_modes[] = { -		[PHY_MODE_NA] = "", -		[PHY_MODE_MII] = "mii", -		[PHY_MODE_RMII] = "rmii", -		[PHY_MODE_SMII] = "smii", -		[PHY_MODE_RGMII] = "rgmii", -		[PHY_MODE_TBI] = "tbi", -		[PHY_MODE_GMII] = "gmii", -		[PHY_MODE_RTBI] = "rtbi", -		[PHY_MODE_SGMII] = "sgmii", -	};  	/* Read config from device-tree */  	if (emac_read_uint_prop(np, "mal-device", &dev->mal_ph, 1)) @@ -2566,23 +2555,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)  		dev->mal_burst_size = 256;  	/* PHY mode needs some decoding */ -	dev->phy_mode = PHY_MODE_NA; -	pm = of_get_property(np, "phy-mode", &plen); -	if (pm != NULL) { -		int i; -		for (i = 0; i < ARRAY_SIZE(phy_modes); i++) -			if (!strcasecmp(pm, phy_modes[i])) { -				dev->phy_mode = i; -				break; -			} -	} - -	/* Backward compat with non-final DT */ -	if (dev->phy_mode == PHY_MODE_NA && pm != NULL && plen == 4) { -		u32 nmode = *(const u32 *)pm; -		if (nmode > PHY_MODE_NA && nmode <= PHY_MODE_SGMII) -			dev->phy_mode = nmode; -	} +	dev->phy_mode = of_get_phy_mode(np); +	if (dev->phy_mode < 0) +		dev->phy_mode = PHY_MODE_NA;  	/* Check EMAC version */  	if (of_device_is_compatible(np, "ibm,emac4sync")) { diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h index 8a61b597a16..1568278d759 100644 --- a/drivers/net/ibm_newemac/emac.h +++ b/drivers/net/ibm_newemac/emac.h @@ -26,6 +26,7 @@  #define __IBM_NEWEMAC_H  #include <linux/types.h> +#include <linux/phy.h>  /* EMAC registers 			Write Access rules */  struct emac_regs { @@ -106,15 +107,15 @@ struct emac_regs {  /*   * PHY mode settings (EMAC <-> ZMII/RGMII bridge <-> PHY)   */ -#define PHY_MODE_NA	0 -#define PHY_MODE_MII	1 -#define PHY_MODE_RMII	2 -#define PHY_MODE_SMII	3 -#define PHY_MODE_RGMII	4 -#define PHY_MODE_TBI	5 -#define PHY_MODE_GMII	6 -#define PHY_MODE_RTBI	7 -#define PHY_MODE_SGMII	8 +#define PHY_MODE_NA	PHY_INTERFACE_MODE_NA +#define PHY_MODE_MII	PHY_INTERFACE_MODE_MII +#define PHY_MODE_RMII	PHY_INTERFACE_MODE_RMII +#define PHY_MODE_SMII	PHY_INTERFACE_MODE_SMII +#define PHY_MODE_RGMII	PHY_INTERFACE_MODE_RGMII +#define PHY_MODE_TBI	PHY_INTERFACE_MODE_TBI +#define PHY_MODE_GMII	PHY_INTERFACE_MODE_GMII +#define PHY_MODE_RTBI	PHY_INTERFACE_MODE_RTBI +#define PHY_MODE_SGMII	PHY_INTERFACE_MODE_SGMII  /* EMACx_MR0 */  #define EMAC_MR0_RXI			0x80000000 diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c index ac9d964e59e..ab4e5969fe6 100644 --- a/drivers/net/ibm_newemac/phy.c +++ b/drivers/net/ibm_newemac/phy.c @@ -28,12 +28,15 @@  #include "emac.h"  #include "phy.h" -static inline int phy_read(struct mii_phy *phy, int reg) +#define phy_read _phy_read +#define phy_write _phy_write + +static inline int _phy_read(struct mii_phy *phy, int reg)  {  	return phy->mdio_read(phy->dev, phy->address, reg);  } -static inline void phy_write(struct mii_phy *phy, int reg, int val) +static inline void _phy_write(struct mii_phy *phy, int reg, int val)  {  	phy->mdio_write(phy->dev, phy->address, reg, val);  } diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 838c5b67376..3e667926940 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -43,7 +43,7 @@  #include <linux/ipv6.h>  #include <linux/slab.h>  #include <asm/hvcall.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/vio.h>  #include <asm/iommu.h>  #include <asm/firmware.h> @@ -395,7 +395,7 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada  }  /* recycle the current buffer on the rx queue */ -static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) +static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)  {  	u32 q_index = adapter->rx_queue.index;  	u64 correlator = adapter->rx_queue.queue_addr[q_index].correlator; @@ -403,6 +403,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)  	unsigned int index = correlator & 0xffffffffUL;  	union ibmveth_buf_desc desc;  	unsigned long lpar_rc; +	int ret = 1;  	BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);  	BUG_ON(index >= adapter->rx_buff_pool[pool].size); @@ -410,7 +411,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)  	if (!adapter->rx_buff_pool[pool].active) {  		ibmveth_rxq_harvest_buffer(adapter);  		ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); -		return; +		goto out;  	}  	desc.fields.flags_len = IBMVETH_BUF_VALID | @@ -423,12 +424,16 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)  		netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed "  			   "during recycle rc=%ld", lpar_rc);  		ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); +		ret = 0;  	}  	if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) {  		adapter->rx_queue.index = 0;  		adapter->rx_queue.toggle = !adapter->rx_queue.toggle;  	} + +out: +	return ret;  }  static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) @@ -1084,8 +1089,9 @@ restart_poll:  				if (rx_flush)  					ibmveth_flush_buffer(skb->data,  						length + offset); +				if (!ibmveth_rxq_recycle_buffer(adapter)) +					kfree_skb(skb);  				skb = new_skb; -				ibmveth_rxq_recycle_buffer(adapter);  			} else {  				ibmveth_rxq_harvest_buffer(adapter);  				skb_reserve(skb, offset); diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 6e82dd32e80..46b5f5fd686 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -183,7 +183,7 @@ static void ifb_setup(struct net_device *dev)  	dev->flags |= IFF_NOARP;  	dev->flags &= ~IFF_MULTICAST; -	dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; +	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);  	random_ether_addr(dev->dev_addr);  } diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c index 7dcd65cede5..40407124e72 100644 --- a/drivers/net/igb/e1000_nvm.c +++ b/drivers/net/igb/e1000_nvm.c @@ -285,6 +285,7 @@ static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw)  		/* Clear SK and CS */  		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);  		wr32(E1000_EECD, eecd); +		wrfl();  		udelay(1);  		timeout = NVM_MAX_RETRY_SPI; diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index ff244ce803c..414b0225be8 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -1225,6 +1225,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)  	/* Disable all the interrupts */  	wr32(E1000_IMC, ~0); +	wrfl();  	msleep(10);  	/* Define all writable bits for ICS */ @@ -1268,6 +1269,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)  			wr32(E1000_IMC, mask);  			wr32(E1000_ICS, mask); +			wrfl();  			msleep(10);  			if (adapter->test_icr & mask) { @@ -1289,6 +1291,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)  		wr32(E1000_IMS, mask);  		wr32(E1000_ICS, mask); +		wrfl();  		msleep(10);  		if (!(adapter->test_icr & mask)) { @@ -1310,6 +1313,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)  			wr32(E1000_IMC, ~mask);  			wr32(E1000_ICS, ~mask); +			wrfl();  			msleep(10);  			if (adapter->test_icr & mask) { @@ -1321,6 +1325,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)  	/* Disable all the interrupts */  	wr32(E1000_IMC, ~0); +	wrfl();  	msleep(10);  	/* Unhook test interrupt handler */ diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index dc599059512..40d4c405fd7 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1052,6 +1052,7 @@ msi_only:  		kfree(adapter->vf_data);  		adapter->vf_data = NULL;  		wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); +		wrfl();  		msleep(100);  		dev_info(&adapter->pdev->dev, "IOV Disabled\n");  	} @@ -2022,7 +2023,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,  	if (hw->bus.func == 0)  		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); -	else if (hw->mac.type == e1000_82580) +	else if (hw->mac.type >= e1000_82580)  		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +  		                 NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,  		                 &eeprom_data); @@ -2198,6 +2199,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)  		kfree(adapter->vf_data);  		adapter->vf_data = NULL;  		wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); +		wrfl();  		msleep(100);  		dev_info(&pdev->dev, "IOV Disabled\n");  	} diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 1330c8e932d..40ed066e3ef 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -1226,6 +1226,7 @@ static void igbvf_configure_tx(struct igbvf_adapter *adapter)  	/* disable transmits */  	txdctl = er32(TXDCTL(0));  	ew32(TXDCTL(0), txdctl & ~E1000_TXDCTL_QUEUE_ENABLE); +	e1e_flush();  	msleep(10);  	/* Setup the HW Tx Head and Tail descriptor pointers */ @@ -1306,6 +1307,7 @@ static void igbvf_configure_rx(struct igbvf_adapter *adapter)  	/* disable receives */  	rxdctl = er32(RXDCTL(0));  	ew32(RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE); +	e1e_flush();  	msleep(10);  	rdlen = rx_ring->count * sizeof(union e1000_adv_rx_desc); diff --git a/drivers/net/irda/sh_irda.c b/drivers/net/irda/sh_irda.c index 4488bd581ec..82660672dcd 100644 --- a/drivers/net/irda/sh_irda.c +++ b/drivers/net/irda/sh_irda.c @@ -22,6 +22,8 @@   *  - DMA transfer support   *  - FIFO mode support   */ +#include <linux/io.h> +#include <linux/interrupt.h>  #include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/clk.h> diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c index 52a7c86af66..ed7d7d62bf6 100644 --- a/drivers/net/irda/sh_sir.c +++ b/drivers/net/irda/sh_sir.c @@ -12,6 +12,8 @@   * published by the Free Software Foundation.   */ +#include <linux/io.h> +#include <linux/interrupt.h>  #include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/slab.h> @@ -511,7 +513,7 @@ static void sh_sir_tx(struct sh_sir_self *self, int phase)  static int sh_sir_read_data(struct sh_sir_self *self)  { -	u16 val; +	u16 val = 0;  	int timeout = 1024;  	while (timeout--) { diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 954f6e938fb..8b1c3484d27 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -2405,8 +2405,6 @@ static int __init smsc_superio_lpc(unsigned short cfg_base)   * addresses making a subsystem device table necessary.   */  #ifdef CONFIG_PCI -#define PCIID_VENDOR_INTEL 0x8086 -#define PCIID_VENDOR_ALI 0x10b9  static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = {  	/*  	 * Subsystems needing entries: @@ -2416,7 +2414,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini  	 */  	{  		/* Guessed entry */ -		.vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ +		.vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */  		.device = 0x24cc,  		.subvendor = 0x103c,  		.subdevice = 0x08bc, @@ -2429,7 +2427,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini  		.name = "HP nx5000 family",  	},  	{ -		.vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ +		.vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */  		.device = 0x24cc,  		.subvendor = 0x103c,  		.subdevice = 0x088c, @@ -2443,7 +2441,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini  		.name = "HP nc8000 family",  	},  	{ -		.vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ +		.vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */  		.device = 0x24cc,  		.subvendor = 0x103c,  		.subdevice = 0x0890, @@ -2456,7 +2454,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini  		.name = "HP nc6000 family",  	},  	{ -		.vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ +		.vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */  		.device = 0x24cc,  		.subvendor = 0x0e11,  		.subdevice = 0x0860, @@ -2471,7 +2469,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini  	},  	{  		/* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ -		.vendor = PCIID_VENDOR_INTEL, +		.vendor = PCI_VENDOR_ID_INTEL,  		.device = 0x24c0,  		.subvendor = 0x1179,  		.subdevice = 0xffff, /* 0xffff is "any" */ @@ -2484,7 +2482,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini  		.name = "Toshiba laptop with Intel 82801DB/DBL LPC bridge",  	},  	{ -		.vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ +		.vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801CAM ISA bridge */  		.device = 0x248c,  		.subvendor = 0x1179,  		.subdevice = 0xffff, /* 0xffff is "any" */ @@ -2498,7 +2496,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini  	},  	{  		/* 82801DBM (ICH4-M) LPC Interface Bridge */ -		.vendor = PCIID_VENDOR_INTEL, +		.vendor = PCI_VENDOR_ID_INTEL,  		.device = 0x24cc,  		.subvendor = 0x1179,  		.subdevice = 0xffff, /* 0xffff is "any" */ @@ -2512,7 +2510,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini  	},  	{  		/* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ -		.vendor = PCIID_VENDOR_ALI, +		.vendor = PCI_VENDOR_ID_AL,  		.device = 0x1533,  		.subvendor = 0x1179,  		.subdevice = 0xffff, /* 0xffff is "any" */ diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c index c982ab9f900..38b362b6785 100644 --- a/drivers/net/ixgb/ixgb_ee.c +++ b/drivers/net/ixgb/ixgb_ee.c @@ -57,6 +57,7 @@ ixgb_raise_clock(struct ixgb_hw *hw,  	 */  	*eecd_reg = *eecd_reg | IXGB_EECD_SK;  	IXGB_WRITE_REG(hw, EECD, *eecd_reg); +	IXGB_WRITE_FLUSH(hw);  	udelay(50);  } @@ -75,6 +76,7 @@ ixgb_lower_clock(struct ixgb_hw *hw,  	 */  	*eecd_reg = *eecd_reg & ~IXGB_EECD_SK;  	IXGB_WRITE_REG(hw, EECD, *eecd_reg); +	IXGB_WRITE_FLUSH(hw);  	udelay(50);  } @@ -112,6 +114,7 @@ ixgb_shift_out_bits(struct ixgb_hw *hw,  			eecd_reg |= IXGB_EECD_DI;  		IXGB_WRITE_REG(hw, EECD, eecd_reg); +		IXGB_WRITE_FLUSH(hw);  		udelay(50); @@ -206,21 +209,25 @@ ixgb_standby_eeprom(struct ixgb_hw *hw)  	/*  Deselect EEPROM  */  	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK);  	IXGB_WRITE_REG(hw, EECD, eecd_reg); +	IXGB_WRITE_FLUSH(hw);  	udelay(50);  	/*  Clock high  */  	eecd_reg |= IXGB_EECD_SK;  	IXGB_WRITE_REG(hw, EECD, eecd_reg); +	IXGB_WRITE_FLUSH(hw);  	udelay(50);  	/*  Select EEPROM  */  	eecd_reg |= IXGB_EECD_CS;  	IXGB_WRITE_REG(hw, EECD, eecd_reg); +	IXGB_WRITE_FLUSH(hw);  	udelay(50);  	/*  Clock low  */  	eecd_reg &= ~IXGB_EECD_SK;  	IXGB_WRITE_REG(hw, EECD, eecd_reg); +	IXGB_WRITE_FLUSH(hw);  	udelay(50);  } @@ -239,11 +246,13 @@ ixgb_clock_eeprom(struct ixgb_hw *hw)  	/*  Rising edge of clock  */  	eecd_reg |= IXGB_EECD_SK;  	IXGB_WRITE_REG(hw, EECD, eecd_reg); +	IXGB_WRITE_FLUSH(hw);  	udelay(50);  	/*  Falling edge of clock  */  	eecd_reg &= ~IXGB_EECD_SK;  	IXGB_WRITE_REG(hw, EECD, eecd_reg); +	IXGB_WRITE_FLUSH(hw);  	udelay(50);  } diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c index 6cb2e42ff4c..3d61a9e4faf 100644 --- a/drivers/net/ixgb/ixgb_hw.c +++ b/drivers/net/ixgb/ixgb_hw.c @@ -149,6 +149,7 @@ ixgb_adapter_stop(struct ixgb_hw *hw)  	 */  	IXGB_WRITE_REG(hw, RCTL, IXGB_READ_REG(hw, RCTL) & ~IXGB_RCTL_RXEN);  	IXGB_WRITE_REG(hw, TCTL, IXGB_READ_REG(hw, TCTL) & ~IXGB_TCTL_TXEN); +	IXGB_WRITE_FLUSH(hw);  	msleep(IXGB_DELAY_BEFORE_RESET);  	/* Issue a global reset to the MAC.  This will reset the chip's @@ -1220,6 +1221,7 @@ ixgb_optics_reset_bcm(struct ixgb_hw *hw)  	ctrl &= ~IXGB_CTRL0_SDP2;  	ctrl |= IXGB_CTRL0_SDP3;  	IXGB_WRITE_REG(hw, CTRL0, ctrl); +	IXGB_WRITE_FLUSH(hw);  	/* SerDes needs extra delay */  	msleep(IXGB_SUN_PHY_RESET_DELAY); diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 3b3dd4df4c5..34f30ec79c2 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -213,6 +213,7 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)  	switch (hw->phy.type) {  	case ixgbe_phy_tn:  		phy->ops.check_link = &ixgbe_check_phy_link_tnx; +		phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;  		phy->ops.get_firmware_version =  		             &ixgbe_get_phy_firmware_version_tnx;  		break; diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 777051f54e5..fc1375f26fe 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -2632,6 +2632,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)  		autoc_reg |= IXGBE_AUTOC_AN_RESTART;  		autoc_reg |= IXGBE_AUTOC_FLU;  		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); +		IXGBE_WRITE_FLUSH(hw);  		usleep_range(10000, 20000);  	} diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index dc649553a0a..82d4244c6e1 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1378,6 +1378,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)  	/* Disable all the interrupts */  	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); +	IXGBE_WRITE_FLUSH(&adapter->hw);  	usleep_range(10000, 20000);  	/* Test each interrupt */ @@ -1398,6 +1399,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)  			                ~mask & 0x00007FFF);  			IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,  			                ~mask & 0x00007FFF); +			IXGBE_WRITE_FLUSH(&adapter->hw);  			usleep_range(10000, 20000);  			if (adapter->test_icr & mask) { @@ -1415,6 +1417,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)  		adapter->test_icr = 0;  		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);  		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); +		IXGBE_WRITE_FLUSH(&adapter->hw);  		usleep_range(10000, 20000);  		if (!(adapter->test_icr &mask)) { @@ -1435,6 +1438,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)  			                ~mask & 0x00007FFF);  			IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,  			                ~mask & 0x00007FFF); +			IXGBE_WRITE_FLUSH(&adapter->hw);  			usleep_range(10000, 20000);  			if (adapter->test_icr) { @@ -1446,6 +1450,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)  	/* Disable all the interrupts */  	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); +	IXGBE_WRITE_FLUSH(&adapter->hw);  	usleep_range(10000, 20000);  	/* Unhook test interrupt handler */ diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1be617545dc..22790394318 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -184,6 +184,7 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)  	vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);  	vmdctl &= ~IXGBE_VT_CTL_POOL_MASK;  	IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl); +	IXGBE_WRITE_FLUSH(hw);  	/* take a breather then clean up driver data */  	msleep(100); @@ -1005,7 +1006,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)  	struct ixgbe_adapter *adapter = dev_get_drvdata(dev);  	unsigned long event = *(unsigned long *)data; -	if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED)) +	if (!(adapter->flags & IXGBE_FLAG_DCA_CAPABLE))  		return 0;  	switch (event) { @@ -1458,8 +1459,10 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,  		if (ixgbe_rx_is_fcoe(adapter, rx_desc)) {  			ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb,  						   staterr); -			if (!ddp_bytes) +			if (!ddp_bytes) { +				dev_kfree_skb_any(skb);  				goto next_desc; +			}  		}  #endif /* IXGBE_FCOE */  		ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc); diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 735f686c3b3..f7ca3511b9f 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -1585,6 +1585,7 @@ static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)  	*i2cctl |= IXGBE_I2C_CLK_OUT;  	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); +	IXGBE_WRITE_FLUSH(hw);  	/* SCL rise time (1000ns) */  	udelay(IXGBE_I2C_T_RISE); @@ -1605,6 +1606,7 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)  	*i2cctl &= ~IXGBE_I2C_CLK_OUT;  	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); +	IXGBE_WRITE_FLUSH(hw);  	/* SCL fall time (300ns) */  	udelay(IXGBE_I2C_T_FALL); @@ -1628,6 +1630,7 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)  		*i2cctl &= ~IXGBE_I2C_DATA_OUT;  	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); +	IXGBE_WRITE_FLUSH(hw);  	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */  	udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA); diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index bec30ed91ad..2696c78e9f4 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -162,6 +162,7 @@ mac_reset_top:  	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);  	ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;  	IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); +	IXGBE_WRITE_FLUSH(hw);  	msleep(50); diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 0fcdc25699d..dc4e305a108 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -322,6 +322,9 @@ static void macb_tx(struct macb *bp)  		for (i = 0; i < TX_RING_SIZE; i++)  			bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); +		/* Add wrap bit */ +		bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); +  		/* free transmit buffer in upper layer*/  		for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {  			struct ring_info *rp = &bp->tx_skb[tail]; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index ba631fcece3..05172c39a0c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -572,7 +572,7 @@ void macvlan_common_setup(struct net_device *dev)  {  	ether_setup(dev); -	dev->priv_flags	       &= ~IFF_XMIT_DST_RELEASE; +	dev->priv_flags	       &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);  	dev->netdev_ops		= &macvlan_netdev_ops;  	dev->destructor		= free_netdev;  	dev->header_ops		= &macvlan_hard_header_ops, diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c index 5e710917806..5ada5b46911 100644 --- a/drivers/net/mlx4/en_port.c +++ b/drivers/net/mlx4/en_port.c @@ -128,7 +128,7 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,  	memset(context, 0, sizeof *context);  	context->base_qpn = cpu_to_be32(base_qpn); -	context->n_mac = 0x7; +	context->n_mac = 0x2;  	context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |  				       base_qpn);  	context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT | diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index c94b3426d35..f0ee35df4dd 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -1117,6 +1117,8 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)  	info->port = port;  	mlx4_init_mac_table(dev, &info->mac_table);  	mlx4_init_vlan_table(dev, &info->vlan_table); +	info->base_qpn = dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] + +			(port - 1) * (1 << log_num_mac);  	sprintf(info->dev_name, "mlx4_port%d", port);  	info->port_attr.attr.name = info->dev_name; diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c index 1f95afda684..609e0ec14ce 100644 --- a/drivers/net/mlx4/port.c +++ b/drivers/net/mlx4/port.c @@ -258,9 +258,12 @@ void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int qpn)  	if (validate_index(dev, table, index))  		goto out; -	table->entries[index] = 0; -	mlx4_set_port_mac_table(dev, port, table->entries); -	--table->total; +	/* Check whether this address has reference count */ +	if (!(--table->refs[index])) { +		table->entries[index] = 0; +		mlx4_set_port_mac_table(dev, port, table->entries); +		--table->total; +	}  out:  	mutex_unlock(&table->mutex);  } diff --git a/drivers/net/niu.c b/drivers/net/niu.c index cd6c2317e29..ed47585a686 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -9201,7 +9201,7 @@ static int __devinit niu_ldg_init(struct niu *np)  	first_chan = 0;  	for (i = 0; i < port; i++) -		first_chan += parent->rxchan_per_port[port]; +		first_chan += parent->rxchan_per_port[i];  	num_chan = parent->rxchan_per_port[port];  	for (i = first_chan; i < (first_chan + num_chan); i++) { @@ -9217,7 +9217,7 @@ static int __devinit niu_ldg_init(struct niu *np)  	first_chan = 0;  	for (i = 0; i < port; i++) -		first_chan += parent->txchan_per_port[port]; +		first_chan += parent->txchan_per_port[i];  	num_chan = parent->txchan_per_port[port];  	for (i = first_chan; i < (first_chan + num_chan); i++) {  		err = niu_ldg_assign_ldn(np, parent, diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 1cd9394c335..cffbc0373fa 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -809,7 +809,7 @@ static int smc91c92_config(struct pcmcia_device *link)      struct net_device *dev = link->priv;      struct smc_private *smc = netdev_priv(dev);      char *name; -    int i, j, rev; +    int i, rev, j = 0;      unsigned int ioaddr;      u_long mir; diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 8b3090dc4bc..80b6f36a807 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -82,7 +82,7 @@ static int cards_found;  /*   * VLB I/O addresses   */ -static unsigned int pcnet32_portlist[] __initdata = +static unsigned int pcnet32_portlist[] =      { 0x300, 0x320, 0x340, 0x360, 0 };  static int pcnet32_debug; diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 2cd8dc5847b..cb6e0b486b1 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -34,8 +34,7 @@  #define PAGESEL		0x13  #define LAYER4		0x02  #define LAYER2		0x01 -#define MAX_RXTS	4 -#define MAX_TXTS	4 +#define MAX_RXTS	64  #define N_EXT_TS	1  #define PSF_PTPVER	2  #define PSF_EVNT	0x4000 @@ -218,7 +217,7 @@ static void phy2rxts(struct phy_rxts *p, struct rxts *rxts)  	rxts->seqid = p->seqid;  	rxts->msgtype = (p->msgtype >> 12) & 0xf;  	rxts->hash = p->msgtype & 0x0fff; -	rxts->tmo = jiffies + HZ; +	rxts->tmo = jiffies + 2;  }  static u64 phy2txts(struct phy_txts *p) diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c index 0620ba96350..04bb8fcc0cb 100644 --- a/drivers/net/phy/national.c +++ b/drivers/net/phy/national.c @@ -25,8 +25,9 @@  /* DP83865 phy identifier values */  #define DP83865_PHY_ID	0x20005c7a -#define DP83865_INT_MASK_REG 0x15 -#define DP83865_INT_MASK_STATUS 0x14 +#define DP83865_INT_STATUS	0x14 +#define DP83865_INT_MASK	0x15 +#define DP83865_INT_CLEAR	0x17  #define DP83865_INT_REMOTE_FAULT 0x0008  #define DP83865_INT_ANE_COMPLETED 0x0010 @@ -68,21 +69,25 @@ static int ns_config_intr(struct phy_device *phydev)  	int err;  	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) -		err = phy_write(phydev, DP83865_INT_MASK_REG, +		err = phy_write(phydev, DP83865_INT_MASK,  				DP83865_INT_MASK_DEFAULT);  	else -		err = phy_write(phydev, DP83865_INT_MASK_REG, 0); +		err = phy_write(phydev, DP83865_INT_MASK, 0);  	return err;  }  static int ns_ack_interrupt(struct phy_device *phydev)  { -	int ret = phy_read(phydev, DP83865_INT_MASK_STATUS); +	int ret = phy_read(phydev, DP83865_INT_STATUS);  	if (ret < 0)  		return ret; -	return 0; +	/* Clear the interrupt status bit by writing a “1” +	 * to the corresponding bit in INT_CLEAR (2:0 are reserved) */ +	ret = phy_write(phydev, DP83865_INT_CLEAR, ret & ~0x7); + +	return ret;  }  static void ns_giga_speed_fallback(struct phy_device *phydev, int mode) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index a4759576075..3cbda0851f8 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -33,7 +33,7 @@  #include <linux/timer.h>  #include <linux/workqueue.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/io.h>  #include <asm/irq.h>  #include <asm/uaccess.h> diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 4609bc0e2f5..10e5d985afa 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -48,7 +48,7 @@  #include <linux/slab.h>  #include <asm/unaligned.h>  #include <net/slhc_vj.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <linux/nsproxy.h>  #include <net/net_namespace.h> diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7d9c650f395..02339b3352e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -239,6 +239,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {  	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_1 },  	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, RTL_CFG_0 },  	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, RTL_CFG_0 }, +	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4302), 0, 0, RTL_CFG_0 },  	{ PCI_DEVICE(PCI_VENDOR_ID_AT,		0xc107), 0, 0, RTL_CFG_0 },  	{ PCI_DEVICE(0x16ec,			0x0116), 0, 0, RTL_CFG_0 },  	{ PCI_VENDOR_ID_LINKSYS,		0x1032, @@ -1091,6 +1092,21 @@ rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type)  	rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type);  } +struct exgmac_reg { +	u16 addr; +	u16 mask; +	u32 val; +}; + +static void rtl_write_exgmac_batch(void __iomem *ioaddr, +				   const struct exgmac_reg *r, int len) +{ +	while (len-- > 0) { +		rtl_eri_write(ioaddr, r->addr, r->mask, r->val, ERIAR_EXGMAC); +		r++; +	} +} +  static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)  {  	u8 value = 0xff; @@ -3116,6 +3132,18 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)  	RTL_W32(MAC0, low);  	RTL_R32(MAC0); +	if (tp->mac_version == RTL_GIGA_MAC_VER_34) { +		const struct exgmac_reg e[] = { +			{ .addr = 0xe0, ERIAR_MASK_1111, .val = low }, +			{ .addr = 0xe4, ERIAR_MASK_1111, .val = high }, +			{ .addr = 0xf0, ERIAR_MASK_1111, .val = low << 16 }, +			{ .addr = 0xf4, ERIAR_MASK_1111, .val = high << 16 | +								low  >> 16 }, +		}; + +		rtl_write_exgmac_batch(ioaddr, e, ARRAY_SIZE(e)); +	} +  	RTL_W8(Cfg9346, Cfg9346_Lock);  	spin_unlock_irq(&tp->lock); diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 86ac38c96bc..3bb13113703 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -80,13 +80,13 @@ static int rionet_capable = 1;   */  static struct rio_dev **rionet_active; -#define is_rionet_capable(pef, src_ops, dst_ops)		\ -			((pef & RIO_PEF_INB_MBOX) &&		\ -			 (pef & RIO_PEF_INB_DOORBELL) &&	\ +#define is_rionet_capable(src_ops, dst_ops)			\ +			((src_ops & RIO_SRC_OPS_DATA_MSG) &&	\ +			 (dst_ops & RIO_DST_OPS_DATA_MSG) &&	\  			 (src_ops & RIO_SRC_OPS_DOORBELL) &&	\  			 (dst_ops & RIO_DST_OPS_DOORBELL))  #define dev_rionet_capable(dev) \ -	is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops) +	is_rionet_capable(dev->src_ops, dev->dst_ops)  #define RIONET_MAC_MATCH(x)	(*(u32 *)x == 0x00010001)  #define RIONET_GET_DESTID(x)	(*(u16 *)(x + 4)) @@ -282,7 +282,6 @@ static int rionet_open(struct net_device *ndev)  {  	int i, rc = 0;  	struct rionet_peer *peer, *tmp; -	u32 pwdcsr;  	struct rionet_private *rnet = netdev_priv(ndev);  	if (netif_msg_ifup(rnet)) @@ -332,13 +331,8 @@ static int rionet_open(struct net_device *ndev)  			continue;  		} -		/* -		 * If device has initialized inbound doorbells, -		 * send a join message -		 */ -		rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr); -		if (pwdcsr & RIO_DOORBELL_AVAIL) -			rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); +		/* Send a join message */ +		rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);  	}        out: @@ -492,7 +486,7 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)  static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)  {  	int rc = -ENODEV; -	u32 lpef, lsrc_ops, ldst_ops; +	u32 lsrc_ops, ldst_ops;  	struct rionet_peer *peer;  	struct net_device *ndev = NULL; @@ -515,12 +509,11 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)  	 * on later probes  	 */  	if (!rionet_check) { -		rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef);  		rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,  					 &lsrc_ops);  		rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,  					 &ldst_ops); -		if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) { +		if (!is_rionet_capable(lsrc_ops, ldst_ops)) {  			printk(KERN_ERR  			       "%s: local device is not network capable\n",  			       DRV_NAME); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index ad35c210b83..1c1666e9910 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -21,6 +21,7 @@   */  #include <linux/init.h> +#include <linux/interrupt.h>  #include <linux/dma-mapping.h>  #include <linux/etherdevice.h>  #include <linux/delay.h> @@ -30,6 +31,7 @@  #include <linux/phy.h>  #include <linux/cache.h>  #include <linux/io.h> +#include <linux/interrupt.h>  #include <linux/pm_runtime.h>  #include <linux/slab.h>  #include <linux/ethtool.h> diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 8ad7bfbaa3a..3c0f1312b39 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1825,6 +1825,16 @@ static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)  		generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL);  } +static int sis190_mac_addr(struct net_device  *dev, void *p) +{ +	int rc; + +	rc = eth_mac_addr(dev, p); +	if (!rc) +		sis190_init_rxfilter(dev); +	return rc; +} +  static const struct net_device_ops sis190_netdev_ops = {  	.ndo_open		= sis190_open,  	.ndo_stop		= sis190_close, @@ -1833,7 +1843,7 @@ static const struct net_device_ops sis190_netdev_ops = {  	.ndo_tx_timeout		= sis190_tx_timeout,  	.ndo_set_multicast_list = sis190_set_rx_mode,  	.ndo_change_mtu		= eth_change_mtu, -	.ndo_set_mac_address 	= eth_mac_addr, +	.ndo_set_mac_address	= sis190_mac_addr,  	.ndo_validate_addr	= eth_validate_addr,  #ifdef CONFIG_NET_POLL_CONTROLLER  	.ndo_poll_controller	 = sis190_netpoll, diff --git a/drivers/net/slip.c b/drivers/net/slip.c index f11b3f3df24..4c617534f93 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -367,7 +367,7 @@ static void sl_bump(struct slip *sl)  	memcpy(skb_put(skb, count), sl->rbuff, count);  	skb_reset_mac_header(skb);  	skb->protocol = htons(ETH_P_IP); -	netif_rx(skb); +	netif_rx_ni(skb);  	dev->stats.rx_packets++;  } diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index be745ae8f4e..ade35dde5b5 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -46,14 +46,15 @@  #include <asm/byteorder.h>  #include <asm/uaccess.h>  #include <asm/irq.h> -#include <asm/prom.h>  #ifdef CONFIG_SPARC  #include <asm/idprom.h> +#include <asm/prom.h>  #endif  #ifdef CONFIG_PPC_PMAC  #include <asm/pci-bridge.h> +#include <asm/prom.h>  #include <asm/machdep.h>  #include <asm/pmac_feature.h>  #endif diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 80357656815..dc3fbf61910 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -190,6 +190,7 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)  /* minimum number of free TX descriptors required to wake up TX process */  #define TG3_TX_WAKEUP_THRESH(tnapi)		((tnapi)->tx_pending / 4) +#define TG3_TX_BD_DMA_MAX		4096  #define TG3_RAW_IP_ALIGN 2 @@ -4824,7 +4825,7 @@ static void tg3_tx(struct tg3_napi *tnapi)  	txq = netdev_get_tx_queue(tp->dev, index);  	while (sw_idx != hw_idx) { -		struct ring_info *ri = &tnapi->tx_buffers[sw_idx]; +		struct tg3_tx_ring_info *ri = &tnapi->tx_buffers[sw_idx];  		struct sk_buff *skb = ri->skb;  		int i, tx_bug = 0; @@ -4840,6 +4841,12 @@ static void tg3_tx(struct tg3_napi *tnapi)  		ri->skb = NULL; +		while (ri->fragmented) { +			ri->fragmented = false; +			sw_idx = NEXT_TX(sw_idx); +			ri = &tnapi->tx_buffers[sw_idx]; +		} +  		sw_idx = NEXT_TX(sw_idx);  		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { @@ -4851,6 +4858,13 @@ static void tg3_tx(struct tg3_napi *tnapi)  				       dma_unmap_addr(ri, mapping),  				       skb_shinfo(skb)->frags[i].size,  				       PCI_DMA_TODEVICE); + +			while (ri->fragmented) { +				ri->fragmented = false; +				sw_idx = NEXT_TX(sw_idx); +				ri = &tnapi->tx_buffers[sw_idx]; +			} +  			sw_idx = NEXT_TX(sw_idx);  		} @@ -5901,40 +5915,100 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,  #endif  } -static void tg3_set_txd(struct tg3_napi *tnapi, int entry, -			dma_addr_t mapping, int len, u32 flags, -			u32 mss_and_is_end) +static inline void tg3_tx_set_bd(struct tg3_tx_buffer_desc *txbd, +				 dma_addr_t mapping, u32 len, u32 flags, +				 u32 mss, u32 vlan)  { -	struct tg3_tx_buffer_desc *txd = &tnapi->tx_ring[entry]; -	int is_end = (mss_and_is_end & 0x1); -	u32 mss = (mss_and_is_end >> 1); -	u32 vlan_tag = 0; +	txbd->addr_hi = ((u64) mapping >> 32); +	txbd->addr_lo = ((u64) mapping & 0xffffffff); +	txbd->len_flags = (len << TXD_LEN_SHIFT) | (flags & 0x0000ffff); +	txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT); +} + +static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, +			    dma_addr_t map, u32 len, u32 flags, +			    u32 mss, u32 vlan) +{ +	struct tg3 *tp = tnapi->tp; +	bool hwbug = false; + +	if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8) +		hwbug = 1; + +	if (tg3_4g_overflow_test(map, len)) +		hwbug = 1; + +	if (tg3_40bit_overflow_test(tp, map, len)) +		hwbug = 1; + +	if (tg3_flag(tp, 4K_FIFO_LIMIT)) { +		u32 tmp_flag = flags & ~TXD_FLAG_END; +		while (len > TG3_TX_BD_DMA_MAX) { +			u32 frag_len = TG3_TX_BD_DMA_MAX; +			len -= TG3_TX_BD_DMA_MAX; + +			if (len) { +				tnapi->tx_buffers[*entry].fragmented = true; +				/* Avoid the 8byte DMA problem */ +				if (len <= 8) { +					len += TG3_TX_BD_DMA_MAX / 2; +					frag_len = TG3_TX_BD_DMA_MAX / 2; +				} +			} else +				tmp_flag = flags; + +			if (*budget) { +				tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, +					      frag_len, tmp_flag, mss, vlan); +				(*budget)--; +				*entry = NEXT_TX(*entry); +			} else { +				hwbug = 1; +				break; +			} + +			map += frag_len; +		} -	if (is_end) -		flags |= TXD_FLAG_END; -	if (flags & TXD_FLAG_VLAN) { -		vlan_tag = flags >> 16; -		flags &= 0xffff; +		if (len) { +			if (*budget) { +				tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, +					      len, flags, mss, vlan); +				(*budget)--; +				*entry = NEXT_TX(*entry); +			} else { +				hwbug = 1; +			} +		} +	} else { +		tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, +			      len, flags, mss, vlan); +		*entry = NEXT_TX(*entry);  	} -	vlan_tag |= (mss << TXD_MSS_SHIFT); -	txd->addr_hi = ((u64) mapping >> 32); -	txd->addr_lo = ((u64) mapping & 0xffffffff); -	txd->len_flags = (len << TXD_LEN_SHIFT) | flags; -	txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT; +	return hwbug;  } -static void tg3_skb_error_unmap(struct tg3_napi *tnapi, -				struct sk_buff *skb, int last) +static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)  {  	int i; -	u32 entry = tnapi->tx_prod; -	struct ring_info *txb = &tnapi->tx_buffers[entry]; +	struct sk_buff *skb; +	struct tg3_tx_ring_info *txb = &tnapi->tx_buffers[entry]; + +	skb = txb->skb; +	txb->skb = NULL;  	pci_unmap_single(tnapi->tp->pdev,  			 dma_unmap_addr(txb, mapping),  			 skb_headlen(skb),  			 PCI_DMA_TODEVICE); + +	while (txb->fragmented) { +		txb->fragmented = false; +		entry = NEXT_TX(entry); +		txb = &tnapi->tx_buffers[entry]; +	} +  	for (i = 0; i < last; i++) {  		skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; @@ -5944,18 +6018,24 @@ static void tg3_skb_error_unmap(struct tg3_napi *tnapi,  		pci_unmap_page(tnapi->tp->pdev,  			       dma_unmap_addr(txb, mapping),  			       frag->size, PCI_DMA_TODEVICE); + +		while (txb->fragmented) { +			txb->fragmented = false; +			entry = NEXT_TX(entry); +			txb = &tnapi->tx_buffers[entry]; +		}  	}  }  /* Workaround 4GB and 40-bit hardware DMA bugs. */  static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,  				       struct sk_buff *skb, -				       u32 base_flags, u32 mss) +				       u32 *entry, u32 *budget, +				       u32 base_flags, u32 mss, u32 vlan)  {  	struct tg3 *tp = tnapi->tp;  	struct sk_buff *new_skb;  	dma_addr_t new_addr = 0; -	u32 entry = tnapi->tx_prod;  	int ret = 0;  	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) @@ -5976,24 +6056,22 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,  					  PCI_DMA_TODEVICE);  		/* Make sure the mapping succeeded */  		if (pci_dma_mapping_error(tp->pdev, new_addr)) { -			ret = -1;  			dev_kfree_skb(new_skb); - -		/* Make sure new skb does not cross any 4G boundaries. -		 * Drop the packet if it does. -		 */ -		} else if (tg3_4g_overflow_test(new_addr, new_skb->len)) { -			pci_unmap_single(tp->pdev, new_addr, new_skb->len, -					 PCI_DMA_TODEVICE);  			ret = -1; -			dev_kfree_skb(new_skb);  		} else { -			tnapi->tx_buffers[entry].skb = new_skb; -			dma_unmap_addr_set(&tnapi->tx_buffers[entry], +			base_flags |= TXD_FLAG_END; + +			tnapi->tx_buffers[*entry].skb = new_skb; +			dma_unmap_addr_set(&tnapi->tx_buffers[*entry],  					   mapping, new_addr); -			tg3_set_txd(tnapi, entry, new_addr, new_skb->len, -				    base_flags, 1 | (mss << 1)); +			if (tg3_tx_frag_set(tnapi, entry, budget, new_addr, +					    new_skb->len, base_flags, +					    mss, vlan)) { +				tg3_tx_skb_unmap(tnapi, *entry, 0); +				dev_kfree_skb(new_skb); +				ret = -1; +			}  		}  	} @@ -6051,7 +6129,8 @@ tg3_tso_bug_end:  static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)  {  	struct tg3 *tp = netdev_priv(dev); -	u32 len, entry, base_flags, mss; +	u32 len, entry, base_flags, mss, vlan = 0; +	u32 budget;  	int i = -1, would_hit_hwbug;  	dma_addr_t mapping;  	struct tg3_napi *tnapi; @@ -6063,12 +6142,14 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)  	if (tg3_flag(tp, ENABLE_TSS))  		tnapi++; +	budget = tg3_tx_avail(tnapi); +  	/* We are running in BH disabled context with netif_tx_lock  	 * and TX reclaim runs via tp->napi.poll inside of a software  	 * interrupt.  Furthermore, IRQ processing runs lockless so we have  	 * no IRQ context deadlocks to worry about either.  Rejoice!  	 */ -	if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) { +	if (unlikely(budget <= (skb_shinfo(skb)->nr_frags + 1))) {  		if (!netif_tx_queue_stopped(txq)) {  			netif_tx_stop_queue(txq); @@ -6153,9 +6234,12 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)  		}  	} -	if (vlan_tx_tag_present(skb)) -		base_flags |= (TXD_FLAG_VLAN | -			       (vlan_tx_tag_get(skb) << 16)); +#ifdef BCM_KERNEL_SUPPORTS_8021Q +	if (vlan_tx_tag_present(skb)) { +		base_flags |= TXD_FLAG_VLAN; +		vlan = vlan_tx_tag_get(skb); +	} +#endif  	if (tg3_flag(tp, USE_JUMBO_BDFLAG) &&  	    !mss && skb->len > VLAN_ETH_FRAME_LEN) @@ -6174,25 +6258,23 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)  	would_hit_hwbug = 0; -	if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8) -		would_hit_hwbug = 1; - -	if (tg3_4g_overflow_test(mapping, len)) -		would_hit_hwbug = 1; - -	if (tg3_40bit_overflow_test(tp, mapping, len)) -		would_hit_hwbug = 1; -  	if (tg3_flag(tp, 5701_DMA_BUG))  		would_hit_hwbug = 1; -	tg3_set_txd(tnapi, entry, mapping, len, base_flags, -		    (skb_shinfo(skb)->nr_frags == 0) | (mss << 1)); - -	entry = NEXT_TX(entry); +	if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags | +			  ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0), +			    mss, vlan)) +		would_hit_hwbug = 1;  	/* Now loop through additional data fragments, and queue them. */  	if (skb_shinfo(skb)->nr_frags > 0) { +		u32 tmp_mss = mss; + +		if (!tg3_flag(tp, HW_TSO_1) && +		    !tg3_flag(tp, HW_TSO_2) && +		    !tg3_flag(tp, HW_TSO_3)) +			tmp_mss = 0; +  		last = skb_shinfo(skb)->nr_frags - 1;  		for (i = 0; i <= last; i++) {  			skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; @@ -6209,39 +6291,25 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)  			if (pci_dma_mapping_error(tp->pdev, mapping))  				goto dma_error; -			if (tg3_flag(tp, SHORT_DMA_BUG) && -			    len <= 8) -				would_hit_hwbug = 1; - -			if (tg3_4g_overflow_test(mapping, len)) -				would_hit_hwbug = 1; - -			if (tg3_40bit_overflow_test(tp, mapping, len)) +			if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, +					    len, base_flags | +					    ((i == last) ? TXD_FLAG_END : 0), +					    tmp_mss, vlan))  				would_hit_hwbug = 1; - -			if (tg3_flag(tp, HW_TSO_1) || -			    tg3_flag(tp, HW_TSO_2) || -			    tg3_flag(tp, HW_TSO_3)) -				tg3_set_txd(tnapi, entry, mapping, len, -					    base_flags, (i == last)|(mss << 1)); -			else -				tg3_set_txd(tnapi, entry, mapping, len, -					    base_flags, (i == last)); - -			entry = NEXT_TX(entry);  		}  	}  	if (would_hit_hwbug) { -		tg3_skb_error_unmap(tnapi, skb, i); +		tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);  		/* If the workaround fails due to memory/mapping  		 * failure, silently drop this packet.  		 */ -		if (tigon3_dma_hwbug_workaround(tnapi, skb, base_flags, mss)) +		entry = tnapi->tx_prod; +		budget = tg3_tx_avail(tnapi); +		if (tigon3_dma_hwbug_workaround(tnapi, skb, &entry, &budget, +						base_flags, mss, vlan))  			goto out_unlock; - -		entry = NEXT_TX(tnapi->tx_prod);  	}  	skb_tx_timestamp(skb); @@ -6269,7 +6337,7 @@ out_unlock:  	return NETDEV_TX_OK;  dma_error: -	tg3_skb_error_unmap(tnapi, skb, i); +	tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);  	dev_kfree_skb(skb);  	tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;  	return NETDEV_TX_OK; @@ -6602,35 +6670,13 @@ static void tg3_free_rings(struct tg3 *tp)  		if (!tnapi->tx_buffers)  			continue; -		for (i = 0; i < TG3_TX_RING_SIZE; ) { -			struct ring_info *txp; -			struct sk_buff *skb; -			unsigned int k; +		for (i = 0; i < TG3_TX_RING_SIZE; i++) { +			struct sk_buff *skb = tnapi->tx_buffers[i].skb; -			txp = &tnapi->tx_buffers[i]; -			skb = txp->skb; - -			if (skb == NULL) { -				i++; +			if (!skb)  				continue; -			} - -			pci_unmap_single(tp->pdev, -					 dma_unmap_addr(txp, mapping), -					 skb_headlen(skb), -					 PCI_DMA_TODEVICE); -			txp->skb = NULL; - -			i++; -			for (k = 0; k < skb_shinfo(skb)->nr_frags; k++) { -				txp = &tnapi->tx_buffers[i & (TG3_TX_RING_SIZE - 1)]; -				pci_unmap_page(tp->pdev, -					       dma_unmap_addr(txp, mapping), -					       skb_shinfo(skb)->frags[k].size, -					       PCI_DMA_TODEVICE); -				i++; -			} +			tg3_tx_skb_unmap(tnapi, i, skb_shinfo(skb)->nr_frags);  			dev_kfree_skb_any(skb);  		} @@ -6762,9 +6808,9 @@ static int tg3_alloc_consistent(struct tg3 *tp)  		 */  		if ((!i && !tg3_flag(tp, ENABLE_TSS)) ||  		    (i && tg3_flag(tp, ENABLE_TSS))) { -			tnapi->tx_buffers = kzalloc(sizeof(struct ring_info) * -						    TG3_TX_RING_SIZE, -						    GFP_KERNEL); +			tnapi->tx_buffers = kzalloc( +					       sizeof(struct tg3_tx_ring_info) * +					       TG3_TX_RING_SIZE, GFP_KERNEL);  			if (!tnapi->tx_buffers)  				goto err_out; @@ -8360,7 +8406,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)  	/* Program the jumbo buffer descriptor ring control  	 * blocks on those devices that have them.  	 */ -	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || +	if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||  	    (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS))) {  		if (tg3_flag(tp, JUMBO_RING_ENABLE)) { @@ -11204,6 +11250,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)  {  	u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key;  	u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val; +	u32 budget;  	struct sk_buff *skb, *rx_skb;  	u8 *tx_data;  	dma_addr_t map; @@ -11363,6 +11410,10 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)  		return -EIO;  	} +	val = tnapi->tx_prod; +	tnapi->tx_buffers[val].skb = skb; +	dma_unmap_addr_set(&tnapi->tx_buffers[val], mapping, map); +  	tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |  	       rnapi->coal_now); @@ -11370,8 +11421,13 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)  	rx_start_idx = rnapi->hw_status->idx[0].rx_producer; -	tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len, -		    base_flags, (mss << 1) | 1); +	budget = tg3_tx_avail(tnapi); +	if (tg3_tx_frag_set(tnapi, &val, &budget, map, tx_len, +			    base_flags | TXD_FLAG_END, mss, 0)) { +		tnapi->tx_buffers[val].skb = NULL; +		dev_kfree_skb(skb); +		return -EIO; +	}  	tnapi->tx_prod++; @@ -11394,7 +11450,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)  			break;  	} -	pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); +	tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, 0);  	dev_kfree_skb(skb);  	if (tx_idx != tnapi->tx_prod) @@ -13817,7 +13873,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)  		tg3_flag_set(tp, 5705_PLUS);  	/* Determine TSO capabilities */ -	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) +	if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0)  		; /* Do nothing. HW bug. */  	else if (tg3_flag(tp, 57765_PLUS))  		tg3_flag_set(tp, HW_TSO_3); @@ -13880,11 +13936,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)  	if (tg3_flag(tp, 5755_PLUS))  		tg3_flag_set(tp, SHORT_DMA_BUG); +	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) +		tg3_flag_set(tp, 4K_FIFO_LIMIT); +  	if (tg3_flag(tp, 5717_PLUS))  		tg3_flag_set(tp, LRG_PROD_RING_CAP);  	if (tg3_flag(tp, 57765_PLUS) && -	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) +	    tp->pci_chip_rev_id != CHIPREV_ID_5719_A0)  		tg3_flag_set(tp, USE_JUMBO_BDFLAG);  	if (!tg3_flag(tp, 5705_PLUS) || diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 691539ba17b..2ea456dd588 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2652,6 +2652,12 @@ struct ring_info {  	DEFINE_DMA_UNMAP_ADDR(mapping);  }; +struct tg3_tx_ring_info { +	struct sk_buff			*skb; +	DEFINE_DMA_UNMAP_ADDR(mapping); +	bool				fragmented; +}; +  struct tg3_link_config {  	/* Describes what we're trying to get. */  	u32				advertising; @@ -2816,7 +2822,7 @@ struct tg3_napi {  	u32				last_tx_cons;  	u32				prodmbox;  	struct tg3_tx_buffer_desc	*tx_ring; -	struct ring_info		*tx_buffers; +	struct tg3_tx_ring_info		*tx_buffers;  	dma_addr_t			status_mapping;  	dma_addr_t			rx_rcb_mapping; @@ -2899,6 +2905,7 @@ enum TG3_FLAGS {  	TG3_FLAG_57765_PLUS,  	TG3_FLAG_APE_HAS_NCSI,  	TG3_FLAG_5717_PLUS, +	TG3_FLAG_4K_FIFO_LIMIT,  	/* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */  	TG3_FLAG_NUMBER_OF_FLAGS,	/* Last entry in enum TG3_FLAGS */ diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 9a6b3824da1..71f3d1a35b7 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -528,6 +528,7 @@ static void tun_net_init(struct net_device *dev)  		dev->netdev_ops = &tap_netdev_ops;  		/* Ethernet TAP Device */  		ether_setup(dev); +		dev->priv_flags &= ~IFF_TX_SKB_SHARING;  		random_ether_addr(dev->dev_addr); diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 52502883523..c5c4b4def7f 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -314,12 +314,11 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)  	skb_pull(skb, 4);  	while (skb->len > 0) { -		if ((short)(header & 0x0000ffff) != -		    ~((short)((header & 0xffff0000) >> 16))) { +		if ((header & 0x07ff) != ((~header >> 16) & 0x07ff))  			netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n"); -		} +  		/* get the packet length */ -		size = (u16) (header & 0x0000ffff); +		size = (u16) (header & 0x000007ff);  		if ((skb->len) - ((size + 1) & 0xfffe) == 0) {  			u8 alignment = (unsigned long)skb->data & 0x3; diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index fd622a66ebb..f06fb78383a 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -53,7 +53,7 @@  #include <linux/usb/usbnet.h>  #include <linux/usb/cdc.h> -#define	DRIVER_VERSION				"01-June-2011" +#define	DRIVER_VERSION				"04-Aug-2011"  /* CDC NCM subclass 3.2.1 */  #define USB_CDC_NCM_NDP16_LENGTH_MIN		0x10 @@ -163,35 +163,8 @@ cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)  	usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));  } -static int -cdc_ncm_do_request(struct cdc_ncm_ctx *ctx, struct usb_cdc_notification *req, -		   void *data, u16 flags, u16 *actlen, u16 timeout) -{ -	int err; - -	err = usb_control_msg(ctx->udev, (req->bmRequestType & USB_DIR_IN) ? -				usb_rcvctrlpipe(ctx->udev, 0) : -				usb_sndctrlpipe(ctx->udev, 0), -				req->bNotificationType, req->bmRequestType, -				req->wValue, -				req->wIndex, data, -				req->wLength, timeout); - -	if (err < 0) { -		if (actlen) -			*actlen = 0; -		return err; -	} - -	if (actlen) -		*actlen = err; - -	return 0; -} -  static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)  { -	struct usb_cdc_notification req;  	u32 val;  	u8 flags;  	u8 iface_no; @@ -200,14 +173,14 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)  	iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; -	req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE; -	req.bNotificationType = USB_CDC_GET_NTB_PARAMETERS; -	req.wValue = 0; -	req.wIndex = cpu_to_le16(iface_no); -	req.wLength = cpu_to_le16(sizeof(ctx->ncm_parm)); - -	err = cdc_ncm_do_request(ctx, &req, &ctx->ncm_parm, 0, NULL, 1000); -	if (err) { +	err = usb_control_msg(ctx->udev, +				usb_rcvctrlpipe(ctx->udev, 0), +				USB_CDC_GET_NTB_PARAMETERS, +				USB_TYPE_CLASS | USB_DIR_IN +				 | USB_RECIP_INTERFACE, +				0, iface_no, &ctx->ncm_parm, +				sizeof(ctx->ncm_parm), 10000); +	if (err < 0) {  		pr_debug("failed GET_NTB_PARAMETERS\n");  		return 1;  	} @@ -253,31 +226,43 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)  	/* inform device about NTB input size changes */  	if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { -		req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | -							USB_RECIP_INTERFACE; -		req.bNotificationType = USB_CDC_SET_NTB_INPUT_SIZE; -		req.wValue = 0; -		req.wIndex = cpu_to_le16(iface_no);  		if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) { -			struct usb_cdc_ncm_ndp_input_size ndp_in_sz; +			struct usb_cdc_ncm_ndp_input_size *ndp_in_sz; -			req.wLength = 8; -			ndp_in_sz.dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); -			ndp_in_sz.wNtbInMaxDatagrams = -					cpu_to_le16(CDC_NCM_DPT_DATAGRAMS_MAX); -			ndp_in_sz.wReserved = 0; -			err = cdc_ncm_do_request(ctx, &req, &ndp_in_sz, 0, NULL, -									1000); +			ndp_in_sz = kzalloc(sizeof(*ndp_in_sz), GFP_KERNEL); +			if (!ndp_in_sz) { +				err = -ENOMEM; +				goto size_err; +			} + +			err = usb_control_msg(ctx->udev, +					usb_sndctrlpipe(ctx->udev, 0), +					USB_CDC_SET_NTB_INPUT_SIZE, +					USB_TYPE_CLASS | USB_DIR_OUT +					 | USB_RECIP_INTERFACE, +					0, iface_no, ndp_in_sz, 8, 1000); +			kfree(ndp_in_sz);  		} else { -			__le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); +			__le32 *dwNtbInMaxSize; +			dwNtbInMaxSize = kzalloc(sizeof(*dwNtbInMaxSize), +					GFP_KERNEL); +			if (!dwNtbInMaxSize) { +				err = -ENOMEM; +				goto size_err; +			} +			*dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); -			req.wLength = 4; -			err = cdc_ncm_do_request(ctx, &req, &dwNtbInMaxSize, 0, -								NULL, 1000); +			err = usb_control_msg(ctx->udev, +					usb_sndctrlpipe(ctx->udev, 0), +					USB_CDC_SET_NTB_INPUT_SIZE, +					USB_TYPE_CLASS | USB_DIR_OUT +					 | USB_RECIP_INTERFACE, +					0, iface_no, dwNtbInMaxSize, 4, 1000); +			kfree(dwNtbInMaxSize);  		} - -		if (err) +size_err: +		if (err < 0)  			pr_debug("Setting NTB Input Size failed\n");  	} @@ -332,29 +317,24 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)  	/* set CRC Mode */  	if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { -		req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | -							USB_RECIP_INTERFACE; -		req.bNotificationType = USB_CDC_SET_CRC_MODE; -		req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); -		req.wIndex = cpu_to_le16(iface_no); -		req.wLength = 0; - -		err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); -		if (err) +		err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), +				USB_CDC_SET_CRC_MODE, +				USB_TYPE_CLASS | USB_DIR_OUT +				 | USB_RECIP_INTERFACE, +				USB_CDC_NCM_CRC_NOT_APPENDED, +				iface_no, NULL, 0, 1000); +		if (err < 0)  			pr_debug("Setting CRC mode off failed\n");  	}  	/* set NTB format, if both formats are supported */  	if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { -		req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | -							USB_RECIP_INTERFACE; -		req.bNotificationType = USB_CDC_SET_NTB_FORMAT; -		req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); -		req.wIndex = cpu_to_le16(iface_no); -		req.wLength = 0; - -		err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); -		if (err) +		err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), +				USB_CDC_SET_NTB_FORMAT, USB_TYPE_CLASS +				 | USB_DIR_OUT | USB_RECIP_INTERFACE, +				USB_CDC_NCM_NTB16_FORMAT, +				iface_no, NULL, 0, 1000); +		if (err < 0)  			pr_debug("Setting NTB format to 16-bit failed\n");  	} @@ -362,23 +342,29 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)  	/* set Max Datagram Size (MTU) */  	if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { -		__le16 max_datagram_size; +		__le16 *max_datagram_size;  		u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); -		req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | -							USB_RECIP_INTERFACE; -		req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; -		req.wValue = 0; -		req.wIndex = cpu_to_le16(iface_no); -		req.wLength = cpu_to_le16(2); +		max_datagram_size = kzalloc(sizeof(*max_datagram_size), +				GFP_KERNEL); +		if (!max_datagram_size) { +			err = -ENOMEM; +			goto max_dgram_err; +		} -		err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, -									1000); -		if (err) { +		err = usb_control_msg(ctx->udev, usb_rcvctrlpipe(ctx->udev, 0), +				USB_CDC_GET_MAX_DATAGRAM_SIZE, +				USB_TYPE_CLASS | USB_DIR_IN +				 | USB_RECIP_INTERFACE, +				0, iface_no, max_datagram_size, +				2, 1000); +		if (err < 0) {  			pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",  						CDC_NCM_MIN_DATAGRAM_SIZE); +			kfree(max_datagram_size);  		} else { -			ctx->max_datagram_size = le16_to_cpu(max_datagram_size); +			ctx->max_datagram_size = +				le16_to_cpu(*max_datagram_size);  			/* Check Eth descriptor value */  			if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) {  				if (ctx->max_datagram_size > eth_max_sz) @@ -395,17 +381,17 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)  					CDC_NCM_MIN_DATAGRAM_SIZE;  			/* if value changed, update device */ -			req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | -							USB_RECIP_INTERFACE; -			req.bNotificationType = USB_CDC_SET_MAX_DATAGRAM_SIZE; -			req.wValue = 0; -			req.wIndex = cpu_to_le16(iface_no); -			req.wLength = 2; -			max_datagram_size = cpu_to_le16(ctx->max_datagram_size); - -			err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, -								0, NULL, 1000); -			if (err) +			err = usb_control_msg(ctx->udev, +						usb_sndctrlpipe(ctx->udev, 0), +						USB_CDC_SET_MAX_DATAGRAM_SIZE, +						USB_TYPE_CLASS | USB_DIR_OUT +						 | USB_RECIP_INTERFACE, +						0, +						iface_no, max_datagram_size, +						2, 1000); +			kfree(max_datagram_size); +max_dgram_err: +			if (err < 0)  				pr_debug("SET_MAX_DATAGRAM_SIZE failed\n");  		} @@ -671,7 +657,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)  	u32 rem;  	u32 offset;  	u32 last_offset; -	u16 n = 0; +	u16 n = 0, index;  	u8 ready2send = 0;  	/* if there is a remaining skb, it gets priority */ @@ -859,8 +845,8 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)  					cpu_to_le16(sizeof(ctx->tx_ncm.nth16));  	ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq);  	ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); -	ctx->tx_ncm.nth16.wNdpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), -							ctx->tx_ndp_modulus); +	index = ALIGN(sizeof(struct usb_cdc_ncm_nth16), ctx->tx_ndp_modulus); +	ctx->tx_ncm.nth16.wNdpIndex = cpu_to_le16(index);  	memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16));  	ctx->tx_seq++; @@ -873,12 +859,11 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)  	ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem);  	ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */ -	memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex, +	memcpy(((u8 *)skb_out->data) + index,  						&(ctx->tx_ncm.ndp16),  						sizeof(ctx->tx_ncm.ndp16)); -	memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex + -					sizeof(ctx->tx_ncm.ndp16), +	memcpy(((u8 *)skb_out->data) + index + sizeof(ctx->tx_ncm.ndp16),  					&(ctx->tx_ncm.dpe16),  					(ctx->tx_curr_frame_num + 1) *  					sizeof(struct usb_cdc_ncm_dpe16)); diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 041fb7d43c4..ef3b236b514 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -977,7 +977,6 @@ static void rtl8150_disconnect(struct usb_interface *intf)  	usb_set_intfdata(intf, NULL);  	if (dev) {  		set_bit(RTL8150_UNPLUG, &dev->flags); -		tasklet_disable(&dev->tl);  		tasklet_kill(&dev->tl);  		unregister_netdev(dev->netdev);  		unlink_all_urbs(dev); diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 7f78db7bd68..5b23767ea81 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -263,6 +263,8 @@ static void veth_setup(struct net_device *dev)  {  	ether_setup(dev); +	dev->priv_flags &= ~IFF_TX_SKB_SHARING; +  	dev->netdev_ops = &veth_netdev_ops;  	dev->ethtool_ops = &veth_ethtool_ops;  	dev->features |= NETIF_F_LLTX; diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index deb1eca13c9..7c5336c5c37 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -515,10 +515,6 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)  	mac_set_cam_mask(regs, vptr->mCAMmask);  	/* Enable VCAMs */ - -	if (test_bit(0, vptr->active_vlans)) -		WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); -  	for_each_set_bit(vid, vptr->active_vlans, VLAN_N_VID) {  		mac_set_vlan_cam(regs, i, (u8 *) &vid);  		vptr->vCAMmask[i / 8] |= 0x1 << (i % 8); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 1cbacb38965..0959583feb2 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1929,14 +1929,17 @@ static void  vmxnet3_vlan_rx_add_vid(struct net_device *netdev, u16 vid)  {  	struct vmxnet3_adapter *adapter = netdev_priv(netdev); -	u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; -	unsigned long flags; -	VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid); -	spin_lock_irqsave(&adapter->cmd_lock, flags); -	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, -			       VMXNET3_CMD_UPDATE_VLAN_FILTERS); -	spin_unlock_irqrestore(&adapter->cmd_lock, flags); +	if (!(netdev->flags & IFF_PROMISC)) { +		u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; +		unsigned long flags; + +		VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid); +		spin_lock_irqsave(&adapter->cmd_lock, flags); +		VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, +				       VMXNET3_CMD_UPDATE_VLAN_FILTERS); +		spin_unlock_irqrestore(&adapter->cmd_lock, flags); +	}  	set_bit(vid, adapter->active_vlans);  } @@ -1946,14 +1949,17 @@ static void  vmxnet3_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)  {  	struct vmxnet3_adapter *adapter = netdev_priv(netdev); -	u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; -	unsigned long flags; -	VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid); -	spin_lock_irqsave(&adapter->cmd_lock, flags); -	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, -			       VMXNET3_CMD_UPDATE_VLAN_FILTERS); -	spin_unlock_irqrestore(&adapter->cmd_lock, flags); +	if (!(netdev->flags & IFF_PROMISC)) { +		u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; +		unsigned long flags; + +		VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid); +		spin_lock_irqsave(&adapter->cmd_lock, flags); +		VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, +				       VMXNET3_CMD_UPDATE_VLAN_FILTERS); +		spin_unlock_irqrestore(&adapter->cmd_lock, flags); +	}  	clear_bit(vid, adapter->active_vlans);  } diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index b25c9229a6a..eb2028187fb 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -1074,9 +1074,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)  	used = pvc_is_used(pvc); -	if (type == ARPHRD_ETHER) +	if (type == ARPHRD_ETHER) {  		dev = alloc_netdev(0, "pvceth%d", ether_setup); -	else +		dev->priv_flags &= ~IFF_TX_SKB_SHARING; +	} else  		dev = alloc_netdev(0, "pvc%d", pvc_setup);  	if (!dev) { diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 5eacc653a94..c421a614185 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -155,7 +155,7 @@  #include <linux/netdevice.h>  #include <linux/completion.h>  #include <linux/rwsem.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <net/wimax.h>  #include <linux/wimax/i2400m.h>  #include <asm/byteorder.h> diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 55cf71fbffe..e1b3e3c134f 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2823,6 +2823,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,  	dev->wireless_data = &ai->wireless_data;  	dev->irq = irq;  	dev->base_addr = port; +	dev->priv_flags &= ~IFF_TX_SKB_SHARING;  	SET_NETDEV_DEV(dev, dmdev); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index f54dff44ed5..c3119a6caac 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1735,6 +1735,8 @@ ath5k_beacon_setup(struct ath5k_hw *ah, struct ath5k_buf *bf)  	if (dma_mapping_error(ah->dev, bf->skbaddr)) {  		ATH5K_ERR(ah, "beacon DMA mapping failed\n"); +		dev_kfree_skb_any(skb); +		bf->skb = NULL;  		return -EIO;  	} @@ -1819,8 +1821,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)  	ath5k_txbuf_free_skb(ah, avf->bbuf);  	avf->bbuf->skb = skb;  	ret = ath5k_beacon_setup(ah, avf->bbuf); -	if (ret) -		avf->bbuf->skb = NULL;  out:  	return ret;  } @@ -1840,6 +1840,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)  	struct ath5k_vif *avf;  	struct ath5k_buf *bf;  	struct sk_buff *skb; +	int err;  	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, "in beacon_send\n"); @@ -1888,11 +1889,6 @@ ath5k_beacon_send(struct ath5k_hw *ah)  	avf = (void *)vif->drv_priv;  	bf = avf->bbuf; -	if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION || -		     ah->opmode == NL80211_IFTYPE_MONITOR)) { -		ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); -		return; -	}  	/*  	 * Stop any current dma and put the new frame on the queue. @@ -1906,8 +1902,17 @@ ath5k_beacon_send(struct ath5k_hw *ah)  	/* refresh the beacon for AP or MESH mode */  	if (ah->opmode == NL80211_IFTYPE_AP || -	    ah->opmode == NL80211_IFTYPE_MESH_POINT) -		ath5k_beacon_update(ah->hw, vif); +	    ah->opmode == NL80211_IFTYPE_MESH_POINT) { +		err = ath5k_beacon_update(ah->hw, vif); +		if (err) +			return; +	} + +	if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION || +		     ah->opmode == NL80211_IFTYPE_MONITOR)) { +		ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf->skb); +		return; +	}  	trace_ath5k_tx(ah, bf->skb, &ah->txqs[ah->bhalq]); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 9ff7c30573b..44d9d8d5649 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -309,11 +309,7 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,  	u8 i;  	u32 val; -	if (ah->is_pciexpress != true) -		return; - -	/* Do not touch SerDes registers */ -	if (ah->config.pcie_powersave_enable == 2) +	if (ah->is_pciexpress != true || ah->aspm_enabled != true)  		return;  	/* Nothing to do on restore for 11N */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index d109c25417f..1b9400371ea 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -69,7 +69,7 @@ static int ar9003_hw_power_interpolate(int32_t x,  static const struct ar9300_eeprom ar9300_default = {  	.eepromVersion = 2,  	.templateVersion = 2, -	.macAddr = {1, 2, 3, 4, 5, 6}, +	.macAddr = {0, 2, 3, 4, 5, 6},  	.custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  		     0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  	.baseEepHeader = { @@ -307,7 +307,7 @@ static const struct ar9300_eeprom ar9300_default = {  		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },  		 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, -		 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, +		 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },  		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },  		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -884,7 +884,7 @@ static const struct ar9300_eeprom ar9300_x113 = {  		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },  		 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, -		 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, +		 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },  		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },  		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -2040,7 +2040,7 @@ static const struct ar9300_eeprom ar9300_x112 = {  		{ { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },  		{ { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, -		{ { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, +		{ { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },  		{ { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },  		{ { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -3734,7 +3734,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)  				}  			} else {  				reg_pmu_set = (5 << 1) | (7 << 4) | -					      (1 << 8) | (2 << 14) | +					      (2 << 8) | (2 << 14) |  					      (6 << 17) | (1 << 20) |  					      (3 << 24) | (1 << 28);  			} diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 8efdec247c0..ad2bb2bf4e8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -519,11 +519,7 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,  					 int restore,  					 int power_off)  { -	if (ah->is_pciexpress != true) -		return; - -	/* Do not touch SerDes registers */ -	if (ah->config.pcie_powersave_enable == 2) +	if (ah->is_pciexpress != true || ah->aspm_enabled != true)  		return;  	/* Nothing to do on restore for 11N */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 6de3f0bc18e..5c590429f12 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -850,7 +850,7 @@  #define AR_PHY_TPC_11_B1         (AR_SM1_BASE + 0x220)  #define AR_PHY_PDADC_TAB_1       (AR_SM1_BASE + 0x240)  #define AR_PHY_TX_IQCAL_STATUS_B1   (AR_SM1_BASE + 0x48c) -#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i)    (AR_SM_BASE + 0x450 + ((_i) << 2)) +#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i)    (AR_SM1_BASE + 0x450 + ((_i) << 2))  /*   * Channel 2 Register Map diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8006ce0c735..8dcefe74f4c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -318,6 +318,14 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)  	REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);  } +static void ath9k_hw_aspm_init(struct ath_hw *ah) +{ +	struct ath_common *common = ath9k_hw_common(ah); + +	if (common->bus_ops->aspm_init) +		common->bus_ops->aspm_init(common); +} +  /* This should work for all families including legacy */  static bool ath9k_hw_chip_test(struct ath_hw *ah)  { @@ -378,7 +386,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)  	ah->config.additional_swba_backoff = 0;  	ah->config.ack_6mb = 0x0;  	ah->config.cwm_ignore_extcca = 0; -	ah->config.pcie_powersave_enable = 0;  	ah->config.pcie_clock_req = 0;  	ah->config.pcie_waen = 0;  	ah->config.analog_shiftreg = 1; @@ -598,7 +605,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)  	if (ah->is_pciexpress) -		ath9k_hw_configpcipowersave(ah, 0, 0); +		ath9k_hw_aspm_init(ah);  	else  		ath9k_hw_disablepcie(ah); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 6acd0f975ae..c79889036ec 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -219,7 +219,6 @@ struct ath9k_ops_config {  	int additional_swba_backoff;  	int ack_6mb;  	u32 cwm_ignore_extcca; -	u8 pcie_powersave_enable;  	bool pcieSerDesWrite;  	u8 pcie_clock_req;  	u32 pcie_waen; @@ -673,6 +672,7 @@ struct ath_hw {  	bool sw_mgmt_crypto;  	bool is_pciexpress; +	bool aspm_enabled;  	bool is_monitoring;  	bool need_an_top2_fixup;  	u16 tx_trig_level; @@ -874,6 +874,7 @@ struct ath_bus_ops {  	bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);  	void (*bt_coex_prep)(struct ath_common *common);  	void (*extn_synch_en)(struct ath_common *common); +	void (*aspm_init)(struct ath_common *common);  };  static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index ac5107172f9..aa0ff7e2c92 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -670,8 +670,10 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)  static void ath9k_init_txpower_limits(struct ath_softc *sc)  {  	struct ath_hw *ah = sc->sc_ah; +	struct ath_common *common = ath9k_hw_common(sc->sc_ah);  	struct ath9k_channel *curchan = ah->curchan; +	ah->txchainmask = common->tx_chainmask;  	if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)  		ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);  	if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9098aaad97a..6530694a59a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2283,7 +2283,11 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)  	mutex_lock(&sc->mutex);  	ah->coverage_class = coverage_class; + +	ath9k_ps_wakeup(sc);  	ath9k_hw_init_global_settings(ah); +	ath9k_ps_restore(sc); +  	mutex_unlock(&sc->mutex);  } diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 3bad0b2cf9a..be4ea132981 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -16,6 +16,7 @@  #include <linux/nl80211.h>  #include <linux/pci.h> +#include <linux/pci-aspm.h>  #include <linux/ath9k_platform.h>  #include "ath9k.h" @@ -115,12 +116,38 @@ static void ath_pci_extn_synch_enable(struct ath_common *common)  	pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);  } +static void ath_pci_aspm_init(struct ath_common *common) +{ +	struct ath_softc *sc = (struct ath_softc *) common->priv; +	struct ath_hw *ah = sc->sc_ah; +	struct pci_dev *pdev = to_pci_dev(sc->dev); +	struct pci_dev *parent; +	int pos; +	u8 aspm; + +	if (!pci_is_pcie(pdev)) +		return; + +	parent = pdev->bus->self; +	if (WARN_ON(!parent)) +		return; + +	pos = pci_pcie_cap(parent); +	pci_read_config_byte(parent, pos +  PCI_EXP_LNKCTL, &aspm); +	if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { +		ah->aspm_enabled = true; +		/* Initialize PCIe PM and SERDES registers. */ +		ath9k_hw_configpcipowersave(ah, 0, 0); +	} +} +  static const struct ath_bus_ops ath_pci_bus_ops = {  	.ath_bus_type = ATH_PCI,  	.read_cachesize = ath_pci_read_cachesize,  	.eeprom_read = ath_pci_eeprom_read,  	.bt_coex_prep = ath_pci_bt_coex_prep,  	.extn_synch_en = ath_pci_extn_synch_enable, +	.aspm_init = ath_pci_aspm_init,  };  static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 0122930b14c..0474e6638d2 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1066,8 +1066,10 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  	 * the high througput speed in 802.11n networks.  	 */ -	if (!is_main_vif(ar, vif)) +	if (!is_main_vif(ar, vif)) { +		mutex_lock(&ar->mutex);  		goto err_softw; +	}  	/*  	 * While the hardware supports *catch-all* key, for offloading diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index d2293dcc117..3cab843afb0 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -28,7 +28,7 @@ config B43  config B43_BCMA  	bool "Support for BCMA bus" -	depends on B43 && BCMA && BROKEN +	depends on B43 && BCMA  	default y  config B43_SSB diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index 64c3f65ff8c..05f6c7bff6a 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -244,10 +244,12 @@ void b43_bus_set_wldev(struct b43_bus_dev *dev, void *wldev)  #ifdef CONFIG_B43_BCMA  	case B43_BUS_BCMA:  		bcma_set_drvdata(dev->bdev, wldev); +		break;  #endif  #ifdef CONFIG_B43_SSB  	case B43_BUS_SSB:  		ssb_set_drvdata(dev->sdev, wldev); +		break;  #endif  	}  } diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 83cba22ac6e..481e534534e 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -795,9 +795,23 @@ static u64 supported_dma_mask(struct b43_wldev *dev)  	u32 tmp;  	u16 mmio_base; -	tmp = b43_read32(dev, SSB_TMSHIGH); -	if (tmp & SSB_TMSHIGH_DMA64) -		return DMA_BIT_MASK(64); +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST); +		if (tmp & BCMA_IOST_DMA64) +			return DMA_BIT_MASK(64); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); +		if (tmp & SSB_TMSHIGH_DMA64) +			return DMA_BIT_MASK(64); +		break; +#endif +	} +  	mmio_base = b43_dmacontroller_base(0, 0);  	b43_write32(dev, mmio_base + B43_DMA32_TXCTL, B43_DMA32_TXADDREXT_MASK);  	tmp = b43_read32(dev, mmio_base + B43_DMA32_TXCTL); diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 032d46674f6..26f1ab840cc 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -5350,6 +5350,7 @@ static void b43_ssb_remove(struct ssb_device *sdev)  {  	struct b43_wl *wl = ssb_get_devtypedata(sdev);  	struct b43_wldev *wldev = ssb_get_drvdata(sdev); +	struct b43_bus_dev *dev = wldev->dev;  	/* We must cancel any work here before unregistering from ieee80211,  	 * as the ieee80211 unreg will destroy the workqueue. */ @@ -5365,14 +5366,14 @@ static void b43_ssb_remove(struct ssb_device *sdev)  		ieee80211_unregister_hw(wl->hw);  	} -	b43_one_core_detach(wldev->dev); +	b43_one_core_detach(dev);  	if (list_empty(&wl->devlist)) {  		b43_leds_unregister(wl);  		/* Last core on the chip unregistered.  		 * We can destroy common struct b43_wl.  		 */ -		b43_wireless_exit(wldev->dev, wl); +		b43_wireless_exit(dev, wl);  	}  } diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 17a130d18dc..a610a352102 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -8,7 +8,7 @@  #include <linux/stringify.h>  #include <linux/netdevice.h>  #include <linux/pci.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <linux/io.h>  #include <linux/ssb/ssb.h> diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h index f89c3422628..686941c242f 100644 --- a/drivers/net/wireless/b43legacy/dma.h +++ b/drivers/net/wireless/b43legacy/dma.h @@ -5,7 +5,7 @@  #include <linux/spinlock.h>  #include <linux/workqueue.h>  #include <linux/linkage.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include "b43legacy.h" diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index c052a0d5cbd..5441ad19511 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -648,6 +648,8 @@ static const struct pcmcia_device_id hostap_cs_ids[] = {  					 0x74c5e40d),  	PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil",  					 0x4b801a17), +	PCMCIA_DEVICE_MANF_CARD_PROD_ID3(0x0156, 0x0002, "Version 01.02", +					 0x4b74baa0),  	PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus",  				    0x7a954bd9, 0x74be00c6),  	PCMCIA_DEVICE_PROD_ID123( diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index d5084829c9e..89a116fba1d 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -855,6 +855,7 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,  	iface = netdev_priv(dev);  	ether_setup(dev); +	dev->priv_flags &= ~IFF_TX_SKB_SHARING;  	/* kernel callbacks */  	if (iface) { diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c index dab67a12d73..73fe3cdf796 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945.c @@ -1746,7 +1746,11 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)  		}  		memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - +		/* +		 * We do not commit tx power settings while channel changing, +		 * do it now if tx power changed. +		 */ +		iwl_legacy_set_tx_power(priv, priv->tx_power_next, false);  		return 0;  	} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index bd4b000733f..ecdc6e55742 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -1235,7 +1235,12 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c  		memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));  		iwl_legacy_print_rx_config_cmd(priv, ctx); -		goto set_tx_power; +		/* +		 * We do not commit tx power settings while channel changing, +		 * do it now if tx power changed. +		 */ +		iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); +		return 0;  	}  	/* If we are currently associated and the new config requires @@ -1315,7 +1320,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c  	iwl4965_init_sensitivity(priv); -set_tx_power:  	/* If we issue a new RXON command which required a tune then we must  	 * send a new TXPOWER command or we won't be able to Tx any frames */  	ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 3eeb12ebe6e..c95cefd529d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -365,6 +365,7 @@ static struct iwl_base_params iwl5000_base_params = {  	.chain_noise_scale = 1000,  	.wd_timeout = IWL_LONG_WD_TIMEOUT,  	.max_event_log_size = 512, +	.no_idle_support = true,  };  static struct iwl_ht_params iwl5000_ht_params = {  	.ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3e6bb734dcb..02817a43855 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -135,6 +135,7 @@ struct iwl_mod_params {   * @temperature_kelvin: temperature report by uCode in kelvin   * @max_event_log_size: size of event log buffer size for ucode event logging   * @shadow_reg_enable: HW shadhow register bit + * @no_idle_support: do not support idle mode   */  struct iwl_base_params {  	int eeprom_size; @@ -156,6 +157,7 @@ struct iwl_base_params {  	bool temperature_kelvin;  	u32 max_event_log_size;  	const bool shadow_reg_enable; +	const bool no_idle_support;  };  /*   * @advanced_bt_coexist: support advanced bt coexist diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index fb7e436b40c..2fdbffa079c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -134,6 +134,7 @@ static void iwl_pci_apm_config(struct iwl_bus *bus)  static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_data)  {  	bus->drv_data = drv_data; +	pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_data);  }  static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], @@ -454,8 +455,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);  	} -	pci_set_drvdata(pdev, bus); -  	bus->dev = &pdev->dev;  	bus->irq = pdev->irq;  	bus->ops = &pci_ops; @@ -479,26 +478,22 @@ out_no_pci:  	return err;  } -static void iwl_pci_down(struct iwl_bus *bus) -{ -	struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus->bus_specific; - -	pci_disable_msi(pci_bus->pci_dev); -	pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base); -	pci_release_regions(pci_bus->pci_dev); -	pci_disable_device(pci_bus->pci_dev); -	pci_set_drvdata(pci_bus->pci_dev, NULL); - -	kfree(bus); -} -  static void __devexit iwl_pci_remove(struct pci_dev *pdev)  { -	struct iwl_bus *bus = pci_get_drvdata(pdev); +	struct iwl_priv *priv = pci_get_drvdata(pdev); +	struct iwl_bus *bus = priv->bus; +	struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); +	struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); -	iwl_remove(bus->drv_data); +	iwl_remove(priv); -	iwl_pci_down(bus); +	pci_disable_msi(pci_dev); +	pci_iounmap(pci_dev, pci_bus->hw_base); +	pci_release_regions(pci_dev); +	pci_disable_device(pci_dev); +	pci_set_drvdata(pci_dev, NULL); + +	kfree(bus);  }  #ifdef CONFIG_PM @@ -506,20 +501,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)  static int iwl_pci_suspend(struct device *device)  {  	struct pci_dev *pdev = to_pci_dev(device); -	struct iwl_bus *bus = pci_get_drvdata(pdev); +	struct iwl_priv *priv = pci_get_drvdata(pdev);  	/* Before you put code here, think about WoWLAN. You cannot check here  	 * whether WoWLAN is enabled or not, and your code will run even if  	 * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx.  	 */ -	return iwl_suspend(bus->drv_data); +	return iwl_suspend(priv);  }  static int iwl_pci_resume(struct device *device)  {  	struct pci_dev *pdev = to_pci_dev(device); -	struct iwl_bus *bus = pci_get_drvdata(pdev); +	struct iwl_priv *priv = pci_get_drvdata(pdev);  	/* Before you put code here, think about WoWLAN. You cannot check here  	 * whether WoWLAN is enabled or not, and your code will run even if @@ -532,7 +527,7 @@ static int iwl_pci_resume(struct device *device)  	 */  	pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); -	return iwl_resume(bus->drv_data); +	return iwl_resume(priv);  }  static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 3ec619c6881..cd64df05f9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -349,7 +349,8 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,  	if (priv->wowlan)  		iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); -	else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) +	else if (!priv->cfg->base_params->no_idle_support && +		 priv->hw->conf.flags & IEEE80211_CONF_IDLE)  		iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);  	else if (iwl_tt_is_low_power_state(priv)) {  		/* in thermal throttling low power state */ diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 3f7fc4a0b43..d7dbc00bcfb 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -239,7 +239,6 @@ static int orinoco_cs_resume(struct pcmcia_device *link)  static const struct pcmcia_device_id orinoco_cs_ids[] = {  	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ -	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */  	PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */  	PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */  	PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ @@ -272,6 +271,7 @@ static const struct pcmcia_device_id orinoco_cs_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),  	PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),  	PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), +	PCMCIA_DEVICE_MANF_CARD_PROD_ID3(0x0156, 0x0002, "Version 01.01", 0xd27deb1a), /* Lucent Orinoco */  #ifdef CONFIG_HERMES_PRISM  	/* Only entries that certainly identify Prism chipset */  	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */ @@ -321,6 +321,9 @@ static const struct pcmcia_device_id orinoco_cs_ids[] = {  	PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),  	PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),  	PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39), + +	/* This may be Agere or Intersil Firmware */ +	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),  #endif  	PCMCIA_DEVICE_NULL,  }; diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 84ab7d1acb6..ef67f6786a8 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -703,8 +703,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)  	/*  	 * Add space for the TXWI in front of the skb.  	 */ -	skb_push(entry->skb, TXWI_DESC_SIZE); -	memset(entry->skb, 0, TXWI_DESC_SIZE); +	memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE);  	/*  	 * Register descriptor details in skb frame descriptor. diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 507559361d8..dbf501ca317 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -464,6 +464,15 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)  	int wcid, ack, pid;  	int tx_wcid, tx_ack, tx_pid; +	if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || +	    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) { +		WARNING(entry->queue->rt2x00dev, +			"Data pending for entry %u in queue %u\n", +			entry->entry_idx, entry->queue->qid); +		cond_resched(); +		return false; +	} +  	wcid	= rt2x00_get_field32(reg, TX_STA_FIFO_WCID);  	ack	= rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);  	pid	= rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); @@ -529,12 +538,11 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)  			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);  			if (rt2800usb_txdone_entry_check(entry, reg))  				break; +			entry = NULL;  		} -		if (!entry || rt2x00queue_empty(queue)) -			break; - -		rt2800_txdone_entry(entry, reg); +		if (entry) +			rt2800_txdone_entry(entry, reg);  	}  } @@ -558,8 +566,10 @@ static void rt2800usb_work_txdone(struct work_struct *work)  		while (!rt2x00queue_empty(queue)) {  			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); -			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) +			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || +			    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))  				break; +  			if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))  				rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);  			else if (rt2x00queue_status_timeout(entry)) @@ -921,6 +931,8 @@ static struct usb_device_id rt2800usb_device_table[] = {  	{ USB_DEVICE(0x07d1, 0x3c16) },  	/* Draytek */  	{ USB_DEVICE(0x07fa, 0x7712) }, +	/* DVICO */ +	{ USB_DEVICE(0x0fe9, 0xb307) },  	/* Edimax */  	{ USB_DEVICE(0x7392, 0x7711) },  	{ USB_DEVICE(0x7392, 0x7717) }, diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 15cdc7e57fc..4cdf247a870 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -355,7 +355,8 @@ static inline enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *  	return CIPHER_NONE;  } -static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, +static inline void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, +						     struct sk_buff *skb,  						     struct txentry_desc *txdesc)  {  } diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 8efab398352..4ccf2380597 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -113,7 +113,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)  	 * due to possible race conditions in mac80211.  	 */  	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) -		goto exit_fail; +		goto exit_free_skb;  	/*  	 * Use the ATIM queue if appropriate and present. @@ -127,7 +127,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)  		ERROR(rt2x00dev,  		      "Attempt to send packet over invalid queue %d.\n"  		      "Please file bug report to %s.\n", qid, DRV_PROJECT); -		goto exit_fail; +		goto exit_free_skb;  	}  	/* @@ -159,6 +159,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)   exit_fail:  	rt2x00queue_pause_queue(queue); + exit_free_skb:  	dev_kfree_skb_any(skb);  }  EXPORT_SYMBOL_GPL(rt2x00mac_tx); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index b6b4542c246..1e31050dafc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -262,23 +262,20 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)  	struct queue_entry *entry = (struct queue_entry *)urb->context;  	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; -	if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) +	if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))  		return; - -	if (rt2x00dev->ops->lib->tx_dma_done) -		rt2x00dev->ops->lib->tx_dma_done(entry); - -	/* -	 * Report the frame as DMA done -	 */ -	rt2x00lib_dmadone(entry); -  	/*  	 * Check if the frame was correctly uploaded  	 */  	if (urb->status)  		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); +	/* +	 * Report the frame as DMA done +	 */ +	rt2x00lib_dmadone(entry); +	if (rt2x00dev->ops->lib->tx_dma_done) +		rt2x00dev->ops->lib->tx_dma_done(entry);  	/*  	 * Schedule the delayed work for reading the TX status  	 * from the device. @@ -874,18 +871,8 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)  {  	struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);  	struct rt2x00_dev *rt2x00dev = hw->priv; -	int retval; - -	retval = rt2x00lib_suspend(rt2x00dev, state); -	if (retval) -		return retval; -	/* -	 * Decrease usbdev refcount. -	 */ -	usb_put_dev(interface_to_usbdev(usb_intf)); - -	return 0; +	return rt2x00lib_suspend(rt2x00dev, state);  }  EXPORT_SYMBOL_GPL(rt2x00usb_suspend); @@ -894,8 +881,6 @@ int rt2x00usb_resume(struct usb_interface *usb_intf)  	struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);  	struct rt2x00_dev *rt2x00dev = hw->priv; -	usb_get_dev(interface_to_usbdev(usb_intf)); -  	return rt2x00lib_resume(rt2x00dev);  }  EXPORT_SYMBOL_GPL(rt2x00usb_resume); diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6a93939f44e..0baeb894f09 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2420,6 +2420,7 @@ static struct usb_device_id rt73usb_device_table[] = {  	/* Buffalo */  	{ USB_DEVICE(0x0411, 0x00d8) },  	{ USB_DEVICE(0x0411, 0x00d9) }, +	{ USB_DEVICE(0x0411, 0x00e6) },  	{ USB_DEVICE(0x0411, 0x00f4) },  	{ USB_DEVICE(0x0411, 0x0116) },  	{ USB_DEVICE(0x0411, 0x0119) }, diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c1ea65e5d03..f8648b7288d 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1696,15 +1696,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,  	pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);  	pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); -	/*find bridge info */ -	pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; -	for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { -		if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { -			pcipriv->ndis_adapter.pcibridge_vendor = tmp; -			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, -				 ("Pci Bridge Vendor is found index: %d\n", -				  tmp)); -			break; +	if (bridge_pdev) { +		/*find bridge info if available */ +		pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; +		for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { +			if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { +				pcipriv->ndis_adapter.pcibridge_vendor = tmp; +				RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +					 ("Pci Bridge Vendor is found index:" +					 " %d\n", tmp)); +				break; +			}  		}  	} diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 942f7a3969a..ef63c0df006 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -281,6 +281,8 @@ static struct usb_device_id rtl8192c_usb_ids[] = {  	{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817d, rtl92cu_hal_cfg)},  	/* 8188CE-VAU USB minCard (b/g mode only) */  	{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, +	/* 8188RU in Alfa AWUS036NHR */ +	{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)},  	/* 8188 Combo for BC4 */  	{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, @@ -303,20 +305,23 @@ static struct usb_device_id rtl8192c_usb_ids[] = {  	{RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/  	/* HP - Lite-On ,8188CUS Slim Combo */  	{RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, +	{RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */  	{RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/  	{RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/  	{RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/  	{RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/  	{RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ -	{RTL_USB_DEVICE(0x3358, 0x13d3, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/ +	{RTL_USB_DEVICE(0x13d3, 0x3358, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/  	/* Russian customer -Azwave (8188CE-VAU  b/g mode only) */ -	{RTL_USB_DEVICE(0x3359, 0x13d3, rtl92cu_hal_cfg)}, +	{RTL_USB_DEVICE(0x13d3, 0x3359, rtl92cu_hal_cfg)}, +	{RTL_USB_DEVICE(0x4855, 0x0090, rtl92cu_hal_cfg)}, /* Feixun */ +	{RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ +	{RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */  	/****** 8192CU ********/  	{RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/  	{RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/  	{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ -	{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Abocom -Abocom*/  	{RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/  	{RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/  	{RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ diff --git a/drivers/net/wireless/wl1251/acx.c b/drivers/net/wireless/wl1251/acx.c index ef8370edace..ad87a1ac646 100644 --- a/drivers/net/wireless/wl1251/acx.c +++ b/drivers/net/wireless/wl1251/acx.c @@ -140,8 +140,6 @@ int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)  	auth->sleep_auth = sleep_auth;  	ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); -	if (ret < 0) -		return ret;  out:  	kfree(auth); @@ -681,10 +679,8 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl)  	ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,  				   detection, sizeof(*detection)); -	if (ret < 0) { +	if (ret < 0)  		wl1251_warning("failed to set cca threshold: %d", ret); -		return ret; -	}  out:  	kfree(detection); diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/wl1251/cmd.c index 81f164bc488..d14d69d733a 100644 --- a/drivers/net/wireless/wl1251/cmd.c +++ b/drivers/net/wireless/wl1251/cmd.c @@ -241,7 +241,7 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)  	if (ret < 0) {  		wl1251_error("tx %s cmd for channel %d failed",  			     enable ? "start" : "stop", channel); -		return ret; +		goto out;  	}  	wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d", diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 7e33f1f4f3d..34f6ab53e51 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -77,8 +77,6 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)  	auth->sleep_auth = sleep_auth;  	ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); -	if (ret < 0) -		return ret;  out:  	kfree(auth); @@ -624,10 +622,8 @@ int wl1271_acx_cca_threshold(struct wl1271 *wl)  	ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,  				   detection, sizeof(*detection)); -	if (ret < 0) { +	if (ret < 0)  		wl1271_warning("failed to set cca threshold: %d", ret); -		return ret; -	}  out:  	kfree(detection); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index e58c22d21e3..b70ae40ad66 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4283,6 +4283,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)  	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |  		BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);  	wl->hw->wiphy->max_scan_ssids = 1; +	wl->hw->wiphy->max_sched_scan_ssids = 1;  	/*  	 * Maximum length of elements in scanning probe request templates  	 * should be the maximum length possible for a template, without diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 5cf18c2c23f..fb1fd5af75e 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -164,7 +164,7 @@ static int wl1271_sdio_power_on(struct wl1271 *wl)  	/* If enabled, tell runtime PM not to power off the card */  	if (pm_runtime_enabled(&func->dev)) {  		ret = pm_runtime_get_sync(&func->dev); -		if (ret) +		if (ret < 0)  			goto out;  	} else {  		/* Runtime PM is disabled: power up the card manually */ diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index 5d5e1ef8720..4ae8effaee2 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c @@ -36,7 +36,6 @@ enum wl1271_tm_commands {  	WL1271_TM_CMD_TEST,  	WL1271_TM_CMD_INTERROGATE,  	WL1271_TM_CMD_CONFIGURE, -	WL1271_TM_CMD_NVS_PUSH,  	WL1271_TM_CMD_SET_PLT_MODE,  	WL1271_TM_CMD_RECOVER, @@ -139,12 +138,15 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])  	if (ret < 0) {  		wl1271_warning("testmode cmd interrogate failed: %d", ret); +		kfree(cmd);  		return ret;  	}  	skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd)); -	if (!skb) +	if (!skb) { +		kfree(cmd);  		return -ENOMEM; +	}  	NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd); @@ -187,48 +189,6 @@ static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])  	return 0;  } -static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) -{ -	int ret = 0; -	size_t len; -	void *buf; - -	wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push"); - -	if (!tb[WL1271_TM_ATTR_DATA]) -		return -EINVAL; - -	buf = nla_data(tb[WL1271_TM_ATTR_DATA]); -	len = nla_len(tb[WL1271_TM_ATTR_DATA]); - -	mutex_lock(&wl->mutex); - -	kfree(wl->nvs); - -	if ((wl->chip.id == CHIP_ID_1283_PG20) && -	    (len != sizeof(struct wl128x_nvs_file))) -		return -EINVAL; -	else if (len != sizeof(struct wl1271_nvs_file)) -		return -EINVAL; - -	wl->nvs = kzalloc(len, GFP_KERNEL); -	if (!wl->nvs) { -		wl1271_error("could not allocate memory for the nvs file"); -		ret = -ENOMEM; -		goto out; -	} - -	memcpy(wl->nvs, buf, len); -	wl->nvs_len = len; - -	wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); - -out: -	mutex_unlock(&wl->mutex); - -	return ret; -} -  static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])  {  	u32 val; @@ -285,8 +245,6 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)  		return wl1271_tm_cmd_interrogate(wl, tb);  	case WL1271_TM_CMD_CONFIGURE:  		return wl1271_tm_cmd_configure(wl, tb); -	case WL1271_TM_CMD_NVS_PUSH: -		return wl1271_tm_cmd_nvs_push(wl, tb);  	case WL1271_TM_CMD_SET_PLT_MODE:  		return wl1271_tm_cmd_set_plt_mode(wl, tb);  	case WL1271_TM_CMD_RECOVER:  |