diff options
Diffstat (limited to 'drivers/net')
90 files changed, 972 insertions, 621 deletions
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 9c149750e2b..284a5f4a63a 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -598,8 +598,8 @@ rx_next:  			goto rx_status_loop;  		spin_lock_irqsave(&cp->lock, flags); -		cpw16_f(IntrMask, cp_intr_mask);  		__napi_complete(napi); +		cpw16_f(IntrMask, cp_intr_mask);  		spin_unlock_irqrestore(&cp->lock, flags);  	} diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 4ba72933f0d..97d8068b372 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -860,6 +860,7 @@ retry:  		}  	/* if unknown chip, assume array element #0, original RTL-8139 in this case */ +	i = 0;  	dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n");  	dev_dbg(&pdev->dev, "TxConfig = 0x%lx\n", RTL_R32 (TxConfig));  	tp->chipset = 0; @@ -2088,8 +2089,8 @@ static int rtl8139_poll(struct napi_struct *napi, int budget)  		 * again when we think we are done.  		 */  		spin_lock_irqsave(&tp->lock, flags); -		RTL_W16_F(IntrMask, rtl8139_intr_mask);  		__napi_complete(napi); +		RTL_W16_F(IntrMask, rtl8139_intr_mask);  		spin_unlock_irqrestore(&tp->lock, flags);  	}  	spin_unlock(&tp->rx_lock); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2decc597bda..ce2fcdd4ab9 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2754,6 +2754,7 @@ config MYRI10GE_DCA  config NETXEN_NIC  	tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"  	depends on PCI +	select FW_LOADER  	help  	  This enables the support for NetXen's Gigabit Ethernet card. @@ -2819,6 +2820,7 @@ config BNX2X  config QLCNIC  	tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"  	depends on PCI +	select FW_LOADER  	help  	  This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet  	  devices. diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 9d11dbf5e4d..b9ad799c719 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1429,7 +1429,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,  	wrb = wrb_from_mccq(adapter);  	if (!wrb) {  		status = -EBUSY; -		goto err; +		goto err_unlock;  	}  	req = cmd->va;  	sge = nonembedded_sgl(wrb); @@ -1457,7 +1457,10 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,  	else  		status = adapter->flash_status; -err: +	return status; + +err_unlock: +	spin_unlock_bh(&adapter->mcc_lock);  	return status;  } @@ -1497,7 +1500,7 @@ err:  	return status;  } -extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, +int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,  				struct be_dma_mem *nonemb_cmd)  {  	struct be_mcc_wrb *wrb; @@ -1590,7 +1593,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,  	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,  			OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); -	req->hdr.timeout = 4; +	req->hdr.timeout = cpu_to_le32(4);  	req->pattern = cpu_to_le64(pattern);  	req->src_port = cpu_to_le32(port_num); @@ -1662,7 +1665,7 @@ err:  	return status;  } -extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, +int be_cmd_get_seeprom_data(struct be_adapter *adapter,  				struct be_dma_mem *nonemb_cmd)  {  	struct be_mcc_wrb *wrb; diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 39250b2ca88..959add2410b 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1654,8 +1654,11 @@ MODULE_DEVICE_TABLE (of, bmac_match);  static struct macio_driver bmac_driver =  { -	.name 		= "bmac", -	.match_table	= bmac_match, +	.driver = { +		.name 		= "bmac", +		.owner		= THIS_MODULE, +		.of_match_table	= bmac_match, +	},  	.probe		= bmac_probe,  	.remove		= bmac_remove,  #ifdef CONFIG_PM diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 188e356c30a..117432222a0 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -247,6 +247,7 @@ static const struct flash_spec flash_5709 = {  MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);  static void bnx2_init_napi(struct bnx2 *bp); +static void bnx2_del_napi(struct bnx2 *bp);  static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)  { @@ -3072,7 +3073,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)  	u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;  	struct l2_fhdr *rx_hdr;  	int rx_pkt = 0, pg_ring_used = 0; -	struct pci_dev *pdev = bp->pdev;  	hw_cons = bnx2_get_hw_rx_cons(bnapi);  	sw_cons = rxr->rx_cons; @@ -3098,12 +3098,10 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)  		skb = rx_buf->skb;  		prefetchw(skb); -		if (!get_dma_ops(&pdev->dev)->sync_single_for_cpu) { -			next_rx_buf = -				&rxr->rx_buf_ring[ -					RX_RING_IDX(NEXT_RX_BD(sw_cons))]; -			prefetch(next_rx_buf->desc); -		} +		next_rx_buf = +			&rxr->rx_buf_ring[RX_RING_IDX(NEXT_RX_BD(sw_cons))]; +		prefetch(next_rx_buf->desc); +  		rx_buf->skb = NULL;  		dma_addr = dma_unmap_addr(rx_buf, mapping); @@ -6270,6 +6268,7 @@ open_err:  	bnx2_free_skbs(bp);  	bnx2_free_irq(bp);  	bnx2_free_mem(bp); +	bnx2_del_napi(bp);  	return rc;  } @@ -6537,6 +6536,7 @@ bnx2_close(struct net_device *dev)  	bnx2_free_irq(bp);  	bnx2_free_skbs(bp);  	bnx2_free_mem(bp); +	bnx2_del_napi(bp);  	bp->link_up = 0;  	netif_carrier_off(bp->dev);  	bnx2_set_power_state(bp, PCI_D3hot); @@ -8227,7 +8227,16 @@ bnx2_bus_string(struct bnx2 *bp, char *str)  	return str;  } -static void __devinit +static void +bnx2_del_napi(struct bnx2 *bp) +{ +	int i; + +	for (i = 0; i < bp->irq_nvecs; i++) +		netif_napi_del(&bp->bnx2_napi[i].napi); +} + +static void  bnx2_init_napi(struct bnx2 *bp)  {  	int i; diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 40fdc41446c..df483076eda 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -340,7 +340,8 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)  	if ((client_info->assigned) &&  	    (client_info->ip_src == arp->ip_dst) && -	    (client_info->ip_dst == arp->ip_src)) { +	    (client_info->ip_dst == arp->ip_src) && +	    (compare_ether_addr_64bits(client_info->mac_dst, arp->mac_src))) {  		/* update the clients MAC address */  		memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);  		client_info->ntt = 1; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5e12462a9d5..c3d98dde2f8 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -168,7 +168,7 @@ static int arp_ip_count;  static int bond_mode	= BOND_MODE_ROUNDROBIN;  static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;  static int lacp_fast; - +static int disable_netpoll = 1;  const struct bond_parm_tbl bond_lacp_tbl[] = {  {	"slow",		AD_LACP_SLOW}, @@ -1742,15 +1742,23 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)  	bond_set_carrier(bond);  #ifdef CONFIG_NET_POLL_CONTROLLER -	if (slaves_support_netpoll(bond_dev)) { -		bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; -		if (bond_dev->npinfo) -			slave_dev->npinfo = bond_dev->npinfo; -	} else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { +	/* +	 * Netpoll and bonding is broken, make sure it is not initialized +	 * until it is fixed. +	 */ +	if (disable_netpoll) {  		bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; -		pr_info("New slave device %s does not support netpoll\n", -			slave_dev->name); -		pr_info("Disabling netpoll support for %s\n", bond_dev->name); +	} else { +		if (slaves_support_netpoll(bond_dev)) { +			bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; +			if (bond_dev->npinfo) +				slave_dev->npinfo = bond_dev->npinfo; +		} else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { +			bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; +			pr_info("New slave device %s does not support netpoll\n", +				slave_dev->name); +			pr_info("Disabling netpoll support for %s\n", bond_dev->name); +		}  	}  #endif  	read_unlock(&bond->lock); @@ -1950,8 +1958,11 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)  #ifdef CONFIG_NET_POLL_CONTROLLER  	read_lock_bh(&bond->lock); -	if (slaves_support_netpoll(bond_dev)) -		bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; + +	 /* Make sure netpoll over stays disabled until fixed. */ +	if (!disable_netpoll) +		if (slaves_support_netpoll(bond_dev)) +				bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;  	read_unlock_bh(&bond->lock);  	if (slave_dev->netdev_ops->ndo_netpoll_cleanup)  		slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev); diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 8af8442c694..af753936e83 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -73,7 +73,7 @@ static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev,  	else  		*mscan_clksrc = MSCAN_CLKSRC_XTAL; -	freq = mpc5xxx_get_bus_frequency(ofdev->node); +	freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);  	if (!freq)  		return 0; @@ -152,7 +152,7 @@ static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,  	}  	/* Determine the MSCAN device index from the physical address */ -	pval = of_get_property(ofdev->node, "reg", &plen); +	pval = of_get_property(ofdev->dev.of_node, "reg", &plen);  	BUG_ON(!pval || plen < sizeof(*pval));  	clockidx = (*pval & 0x80) ? 1 : 0;  	if (*pval & 0x2000) @@ -168,11 +168,11 @@ static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,  	 */  	if (clock_name && !strcmp(clock_name, "ip")) {  		*mscan_clksrc = MSCAN_CLKSRC_IPS; -		freq = mpc5xxx_get_bus_frequency(ofdev->node); +		freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);  	} else {  		*mscan_clksrc = MSCAN_CLKSRC_BUS; -		pval = of_get_property(ofdev->node, +		pval = of_get_property(ofdev->dev.of_node,  				       "fsl,mscan-clock-divider", &plen);  		if (pval && plen == sizeof(*pval))  			clockdiv = *pval; @@ -251,7 +251,7 @@ static int __devinit mpc5xxx_can_probe(struct of_device *ofdev,  				       const struct of_device_id *id)  {  	struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data; -	struct device_node *np = ofdev->node; +	struct device_node *np = ofdev->dev.of_node;  	struct net_device *dev;  	struct mscan_priv *priv;  	void __iomem *base; diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index fe925663d39..80471269977 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3919,8 +3919,9 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)  		HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS;  	context->cstorm_st_context.status_block_id = BNX2X_DEF_SB_ID; -	context->xstorm_st_context.statistics_data = (cli | -				XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE); +	if (cli < MAX_X_STAT_COUNTER_ID) +		context->xstorm_st_context.statistics_data = cli | +				XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE;  	context->xstorm_ag_context.cdu_reserved =  		CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func), @@ -3928,10 +3929,12 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)  					ETH_CONNECTION_TYPE);  	/* reset xstorm per client statistics */ -	val = BAR_XSTRORM_INTMEM + -	      XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); -	for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) -		CNIC_WR(dev, val + i * 4, 0); +	if (cli < MAX_X_STAT_COUNTER_ID) { +		val = BAR_XSTRORM_INTMEM + +		      XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); +		for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) +			CNIC_WR(dev, val + i * 4, 0); +	}  	cp->tx_cons_ptr =  		&cp->bnx2x_def_status_blk->c_def_status_block.index_values[ @@ -3978,9 +3981,11 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)  						BNX2X_ISCSI_RX_SB_INDEX_NUM;  	context->ustorm_st_context.common.clientId = cli;  	context->ustorm_st_context.common.status_block_id = BNX2X_DEF_SB_ID; -	context->ustorm_st_context.common.flags = -		USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS; -	context->ustorm_st_context.common.statistics_counter_id = cli; +	if (cli < MAX_U_STAT_COUNTER_ID) { +		context->ustorm_st_context.common.flags = +			USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS; +		context->ustorm_st_context.common.statistics_counter_id = cli; +	}  	context->ustorm_st_context.common.mc_alignment_log_size = 0;  	context->ustorm_st_context.common.bd_buff_size =  						cp->l2_single_buf_size; @@ -4011,10 +4016,13 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)  	/* client tstorm info */  	tstorm_client.mtu = cp->l2_single_buf_size - 14; -	tstorm_client.config_flags = -			(TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE | -			TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE); -	tstorm_client.statistics_counter_id = cli; +	tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE; + +	if (cli < MAX_T_STAT_COUNTER_ID) { +		tstorm_client.config_flags |= +				TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; +		tstorm_client.statistics_counter_id = cli; +	}  	CNIC_WR(dev, BAR_TSTRORM_INTMEM +  		   TSTORM_CLIENT_CONFIG_OFFSET(port, cli), @@ -4024,16 +4032,21 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)  		   ((u32 *)&tstorm_client)[1]);  	/* reset tstorm per client statistics */ -	val = BAR_TSTRORM_INTMEM + -	      TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); -	for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) -		CNIC_WR(dev, val + i * 4, 0); +	if (cli < MAX_T_STAT_COUNTER_ID) { + +		val = BAR_TSTRORM_INTMEM + +		      TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); +		for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) +			CNIC_WR(dev, val + i * 4, 0); +	}  	/* reset ustorm per client statistics */ -	val = BAR_USTRORM_INTMEM + -	      USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); -	for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++) -		CNIC_WR(dev, val + i * 4, 0); +	if (cli < MAX_U_STAT_COUNTER_ID) { +		val = BAR_USTRORM_INTMEM + +		      USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); +		for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++) +			CNIC_WR(dev, val + i * 4, 0); +	}  	cp->rx_cons_ptr =  		&cp->bnx2x_def_status_blk->u_def_status_block.index_values[ diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 3c58db59528..23786ee34be 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1181,7 +1181,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)  		if (netif_msg_drv(priv))  			printk(KERN_ERR "%s: Could not attach to PHY\n",  			       dev->name); -		return PTR_ERR(priv->phy); +		rc = PTR_ERR(priv->phy); +		goto fail;  	}  	if ((rc = register_netdev(dev))) { diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ebdea089166..68a80893dce 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1047,15 +1047,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  		goto err_register;  	/* print bus type/speed/width info */ -	e_info("(PCI%s:%s:%s) ", -		((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""), -		((hw->bus_speed == e1000_bus_speed_133) ? "133MHz" : -		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" : -		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" : -		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"), -		((hw->bus_width == e1000_bus_width_64) ? "64-bit" : "32-bit")); - -	e_info("%pM\n", netdev->dev_addr); +	e_info("(PCI%s:%dMHz:%d-bit) %pM\n", +	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""), +	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 : +		(hw->bus_speed == e1000_bus_speed_120) ? 120 : +		(hw->bus_speed == e1000_bus_speed_100) ? 100 : +		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33), +	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32), +	       netdev->dev_addr);  	/* carrier off reporting is important to ethtool even BEFORE open */  	netif_carrier_off(netdev); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 24507f3b8b1..57a7e41da69 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2554,7 +2554,7 @@ static void e1000_init_manageability_pt(struct e1000_adapter *adapter)  			mdef = er32(MDEF(i));  			/* Ignore filters with anything other than IPMI ports */ -			if (mdef & !(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664)) +			if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))  				continue;  			/* Enable this decision filter in MANC2H */ diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 0630980a272..0060e422f17 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@  #include <asm/io.h>  #define DRV_NAME	"ehea" -#define DRV_VERSION	"EHEA_0103" +#define DRV_VERSION	"EHEA_0105"  /* eHEA capability flags */  #define DLPAR_PORT_ADD_REM 1 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index f547894ff48..8b92acb448c 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -867,6 +867,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)  		ehea_reset_cq_ep(pr->send_cq);  		ehea_reset_cq_n1(pr->recv_cq);  		ehea_reset_cq_n1(pr->send_cq); +		rmb();  		cqe = ehea_poll_rq1(pr->qp, &wqe_index);  		cqe_skb = ehea_poll_cq(pr->send_cq); @@ -2859,6 +2860,7 @@ static void ehea_reset_port(struct work_struct *work)  		container_of(work, struct ehea_port, reset_task);  	struct net_device *dev = port->netdev; +	mutex_lock(&dlpar_mem_lock);  	port->resets++;  	mutex_lock(&port->port_lock);  	netif_stop_queue(dev); @@ -2881,6 +2883,7 @@ static void ehea_reset_port(struct work_struct *work)  	netif_wake_queue(dev);  out:  	mutex_unlock(&port->port_lock); +	mutex_unlock(&dlpar_mem_lock);  }  static void ehea_rereg_mrs(struct work_struct *work) @@ -3542,10 +3545,7 @@ static int ehea_mem_notifier(struct notifier_block *nb,  	int ret = NOTIFY_BAD;  	struct memory_notify *arg = data; -	if (!mutex_trylock(&dlpar_mem_lock)) { -		ehea_info("ehea_mem_notifier must not be called parallelized"); -		goto out; -	} +	mutex_lock(&dlpar_mem_lock);  	switch (action) {  	case MEM_CANCEL_OFFLINE: @@ -3574,7 +3574,6 @@ static int ehea_mem_notifier(struct notifier_block *nb,  out_unlock:  	mutex_unlock(&dlpar_mem_lock); -out:  	return ret;  } diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 85f2a2e7030..45e86d1e5b1 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -74,7 +74,14 @@ struct enic_msix_entry {  	void *devid;  }; +#define ENIC_SET_APPLIED		(1 << 0) +#define ENIC_SET_REQUEST		(1 << 1) +#define ENIC_SET_NAME			(1 << 2) +#define ENIC_SET_INSTANCE		(1 << 3) +#define ENIC_SET_HOST			(1 << 4) +  struct enic_port_profile { +	u32 set;  	u8 request;  	char name[PORT_PROFILE_MAX];  	u8 instance_uuid[PORT_UUID_MAX]; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 6586b5c7e4b..bc7d6b96de3 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1029,8 +1029,7 @@ static int enic_dev_init_done(struct enic *enic, int *done, int *error)  	return err;  } -static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, -	char *name, u8 *instance_uuid, u8 *host_uuid) +static int enic_set_port_profile(struct enic *enic, u8 *mac)  {  	struct vic_provinfo *vp;  	u8 oui[3] = VIC_PROVINFO_CISCO_OUI; @@ -1040,97 +1039,112 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac,  		"%02X%02X-%02X%02X%02X%02X%0X%02X";  	int err; -	if (!name) -		return -EINVAL; +	err = enic_vnic_dev_deinit(enic); +	if (err) +		return err; -	if (!is_valid_ether_addr(mac)) -		return -EADDRNOTAVAIL; +	switch (enic->pp.request) { -	vp = vic_provinfo_alloc(GFP_KERNEL, oui, VIC_PROVINFO_LINUX_TYPE); -	if (!vp) -		return -ENOMEM; +	case PORT_REQUEST_ASSOCIATE: + +		if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name)) +			return -EINVAL; -	vic_provinfo_add_tlv(vp, -		VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, -		strlen(name) + 1, name); +		if (!is_valid_ether_addr(mac)) +			return -EADDRNOTAVAIL; -	vic_provinfo_add_tlv(vp, -		VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, -		ETH_ALEN, mac); +		vp = vic_provinfo_alloc(GFP_KERNEL, oui, +			VIC_PROVINFO_LINUX_TYPE); +		if (!vp) +			return -ENOMEM; -	if (instance_uuid) { -		uuid = instance_uuid; -		sprintf(uuid_str, uuid_fmt, -			uuid[0],  uuid[1],  uuid[2],  uuid[3], -			uuid[4],  uuid[5],  uuid[6],  uuid[7], -			uuid[8],  uuid[9],  uuid[10], uuid[11], -			uuid[12], uuid[13], uuid[14], uuid[15]);  		vic_provinfo_add_tlv(vp, -			VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, -			sizeof(uuid_str), uuid_str); -	} +			VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, +			strlen(enic->pp.name) + 1, enic->pp.name); -	if (host_uuid) { -		uuid = host_uuid; -		sprintf(uuid_str, uuid_fmt, -			uuid[0],  uuid[1],  uuid[2],  uuid[3], -			uuid[4],  uuid[5],  uuid[6],  uuid[7], -			uuid[8],  uuid[9],  uuid[10], uuid[11], -			uuid[12], uuid[13], uuid[14], uuid[15]);  		vic_provinfo_add_tlv(vp, -			VIC_LINUX_PROV_TLV_HOST_UUID_STR, -			sizeof(uuid_str), uuid_str); -	} - -	err = enic_vnic_dev_deinit(enic); -	if (err) -		goto err_out; +			VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, +			ETH_ALEN, mac); -	memset(&enic->pp, 0, sizeof(enic->pp)); +		if (enic->pp.set & ENIC_SET_INSTANCE) { +			uuid = enic->pp.instance_uuid; +			sprintf(uuid_str, uuid_fmt, +				uuid[0],  uuid[1],  uuid[2],  uuid[3], +				uuid[4],  uuid[5],  uuid[6],  uuid[7], +				uuid[8],  uuid[9],  uuid[10], uuid[11], +				uuid[12], uuid[13], uuid[14], uuid[15]); +			vic_provinfo_add_tlv(vp, +				VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, +				sizeof(uuid_str), uuid_str); +		} -	err = enic_dev_init_prov(enic, vp); -	if (err) -		goto err_out; +		if (enic->pp.set & ENIC_SET_HOST) { +			uuid = enic->pp.host_uuid; +			sprintf(uuid_str, uuid_fmt, +				uuid[0],  uuid[1],  uuid[2],  uuid[3], +				uuid[4],  uuid[5],  uuid[6],  uuid[7], +				uuid[8],  uuid[9],  uuid[10], uuid[11], +				uuid[12], uuid[13], uuid[14], uuid[15]); +			vic_provinfo_add_tlv(vp, +				VIC_LINUX_PROV_TLV_HOST_UUID_STR, +				sizeof(uuid_str), uuid_str); +		} -	enic->pp.request = request; -	memcpy(enic->pp.name, name, PORT_PROFILE_MAX); -	if (instance_uuid) -		memcpy(enic->pp.instance_uuid, -			instance_uuid, PORT_UUID_MAX); -	if (host_uuid) -		memcpy(enic->pp.host_uuid, -			host_uuid, PORT_UUID_MAX); +		err = enic_dev_init_prov(enic, vp); +		vic_provinfo_free(vp); +		if (err) +			return err; +		break; -err_out: -	vic_provinfo_free(vp); +	case PORT_REQUEST_DISASSOCIATE: +		break; -	return err; -} +	default: +		return -EINVAL; +	} -static int enic_unset_port_profile(struct enic *enic) -{ -	memset(&enic->pp, 0, sizeof(enic->pp)); -	return enic_vnic_dev_deinit(enic); +	enic->pp.set |= ENIC_SET_APPLIED; +	return 0;  }  static int enic_set_vf_port(struct net_device *netdev, int vf,  	struct nlattr *port[])  {  	struct enic *enic = netdev_priv(netdev); -	char *name = NULL; -	u8 *instance_uuid = NULL; -	u8 *host_uuid = NULL; -	u8 request = PORT_REQUEST_DISASSOCIATE; + +	memset(&enic->pp, 0, sizeof(enic->pp)); + +	if (port[IFLA_PORT_REQUEST]) { +		enic->pp.set |= ENIC_SET_REQUEST; +		enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); +	} + +	if (port[IFLA_PORT_PROFILE]) { +		enic->pp.set |= ENIC_SET_NAME; +		memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]), +			PORT_PROFILE_MAX); +	} + +	if (port[IFLA_PORT_INSTANCE_UUID]) { +		enic->pp.set |= ENIC_SET_INSTANCE; +		memcpy(enic->pp.instance_uuid, +			nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); +	} + +	if (port[IFLA_PORT_HOST_UUID]) { +		enic->pp.set |= ENIC_SET_HOST; +		memcpy(enic->pp.host_uuid, +			nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); +	}  	/* don't support VFs, yet */  	if (vf != PORT_SELF_VF)  		return -EOPNOTSUPP; -	if (port[IFLA_PORT_REQUEST]) -		request = nla_get_u8(port[IFLA_PORT_REQUEST]); +	if (!(enic->pp.set & ENIC_SET_REQUEST)) +		return -EOPNOTSUPP; -	switch (request) { -	case PORT_REQUEST_ASSOCIATE: +	if (enic->pp.request == PORT_REQUEST_ASSOCIATE) {  		/* If the interface mac addr hasn't been assigned,  		 * assign a random mac addr before setting port- @@ -1139,30 +1153,9 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,  		if (is_zero_ether_addr(netdev->dev_addr))  			random_ether_addr(netdev->dev_addr); - -		if (port[IFLA_PORT_PROFILE]) -			name = nla_data(port[IFLA_PORT_PROFILE]); - -		if (port[IFLA_PORT_INSTANCE_UUID]) -			instance_uuid = -				nla_data(port[IFLA_PORT_INSTANCE_UUID]); - -		if (port[IFLA_PORT_HOST_UUID]) -			host_uuid = nla_data(port[IFLA_PORT_HOST_UUID]); - -		return enic_set_port_profile(enic, request, -			netdev->dev_addr, name, -			instance_uuid, host_uuid); - -	case PORT_REQUEST_DISASSOCIATE: - -		return enic_unset_port_profile(enic); - -	default: -		break;  	} -	return -EOPNOTSUPP; +	return enic_set_port_profile(enic, netdev->dev_addr);  }  static int enic_get_vf_port(struct net_device *netdev, int vf, @@ -1172,14 +1165,12 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,  	int err, error, done;  	u16 response = PORT_PROFILE_RESPONSE_SUCCESS; -	/* don't support VFs, yet */ -	if (vf != PORT_SELF_VF) -		return -EOPNOTSUPP; +	if (!(enic->pp.set & ENIC_SET_APPLIED)) +		return -ENODATA;  	err = enic_dev_init_done(enic, &done, &error); -  	if (err) -		return err; +		error = err;  	switch (error) {  	case ERR_SUCCESS: @@ -1202,12 +1193,15 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,  	NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);  	NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response); -	NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, -		enic->pp.name); -	NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX, -		enic->pp.instance_uuid); -	NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, -		enic->pp.host_uuid); +	if (enic->pp.set & ENIC_SET_NAME) +		NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, +			enic->pp.name); +	if (enic->pp.set & ENIC_SET_INSTANCE) +		NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX, +			enic->pp.instance_uuid); +	if (enic->pp.set & ENIC_SET_HOST) +		NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, +			enic->pp.host_uuid);  	return 0; diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 2b3e16db5c8..e0d33281ec9 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -709,7 +709,7 @@ int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len)  {  	u64 a0, a1 = len;  	int wait = 1000; -	u64 prov_pa; +	dma_addr_t prov_pa;  	void *prov_buf;  	int ret; diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 6838dfc9ef2..4c274657283 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -87,6 +87,7 @@ static int rx_copybreak;  #include <linux/bitops.h>  #include <asm/io.h>  #include <asm/uaccess.h> +#include <asm/byteorder.h>  /* These identify the driver base version and may not be removed. */  static char version[] __devinitdata = @@ -230,7 +231,7 @@ static const u16 media2miictl[16] = {   * The EPIC100 Rx and Tx buffer descriptors.  Note that these   * really ARE host-endian; it's not a misannotation.  We tell   * the card to byteswap them internally on big-endian hosts - - * look for #ifdef CONFIG_BIG_ENDIAN in epic_open(). + * look for #ifdef __BIG_ENDIAN in epic_open().   */  struct epic_tx_desc { @@ -690,7 +691,7 @@ static int epic_open(struct net_device *dev)  		outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);  	/* Tell the chip to byteswap descriptors on big-endian hosts */ -#ifdef CONFIG_BIG_ENDIAN +#ifdef __BIG_ENDIAN  	outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);  	inl(ioaddr + GENCTL);  	outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); @@ -806,7 +807,7 @@ static void epic_restart(struct net_device *dev)  	for (i = 16; i > 0; i--)  		outl(0x0008, ioaddr + TEST1); -#ifdef CONFIG_BIG_ENDIAN +#ifdef __BIG_ENDIAN  	outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);  #else  	outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); diff --git a/drivers/net/fec.c b/drivers/net/fec.c index ddf7a86cd46..edfff92a6d8 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1373,10 +1373,9 @@ fec_suspend(struct platform_device *dev, pm_message_t state)  	if (ndev) {  		fep = netdev_priv(ndev); -		if (netif_running(ndev)) { -			netif_device_detach(ndev); -			fec_stop(ndev); -		} +		if (netif_running(ndev)) +			fec_enet_close(ndev); +		clk_disable(fep->clk);  	}  	return 0;  } @@ -1385,12 +1384,13 @@ static int  fec_resume(struct platform_device *dev)  {  	struct net_device *ndev = platform_get_drvdata(dev); +	struct fec_enet_private *fep;  	if (ndev) { -		if (netif_running(ndev)) { -			fec_enet_init(ndev, 0); -			netif_device_attach(ndev); -		} +		fep = netdev_priv(ndev); +		clk_enable(fep->clk); +		if (netif_running(ndev)) +			fec_enet_open(ndev);  	}  	return 0;  } diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 5d45084b287..48e91b6242c 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -504,17 +504,54 @@ static int get_regs_len(struct net_device *dev)  }  /* Some transmit errors cause the transmitter to shut - * down.  We now issue a restart transmit.  Since the - * errors close the BD and update the pointers, the restart - * _should_ pick up without having to reset any of our - * pointers either.  Also, To workaround 8260 device erratum - * CPM37, we must disable and then re-enable the transmitter - * following a Late Collision, Underrun, or Retry Limit error. + * down.  We now issue a restart transmit. + * Also, to workaround 8260 device erratum CPM37, we must + * disable and then re-enable the transmitterfollowing a + * Late Collision, Underrun, or Retry Limit error. + * In addition, tbptr may point beyond BDs beyond still marked + * as ready due to internal pipelining, so we need to look back + * through the BDs and adjust tbptr to point to the last BD + * marked as ready.  This may result in some buffers being + * retransmitted.   */  static void tx_restart(struct net_device *dev)  {  	struct fs_enet_private *fep = netdev_priv(dev);  	fcc_t __iomem *fccp = fep->fcc.fccp; +	const struct fs_platform_info *fpi = fep->fpi; +	fcc_enet_t __iomem *ep = fep->fcc.ep; +	cbd_t __iomem *curr_tbptr; +	cbd_t __iomem *recheck_bd; +	cbd_t __iomem *prev_bd; +	cbd_t __iomem *last_tx_bd; + +	last_tx_bd = fep->tx_bd_base + (fpi->tx_ring * sizeof(cbd_t)); + +	/* get the current bd held in TBPTR  and scan back from this point */ +	recheck_bd = curr_tbptr = (cbd_t __iomem *) +		((R32(ep, fen_genfcc.fcc_tbptr) - fep->ring_mem_addr) + +		fep->ring_base); + +	prev_bd = (recheck_bd == fep->tx_bd_base) ? last_tx_bd : recheck_bd - 1; + +	/* Move through the bds in reverse, look for the earliest buffer +	 * that is not ready.  Adjust TBPTR to the following buffer */ +	while ((CBDR_SC(prev_bd) & BD_ENET_TX_READY) != 0) { +		/* Go back one buffer */ +		recheck_bd = prev_bd; + +		/* update the previous buffer */ +		prev_bd = (prev_bd == fep->tx_bd_base) ? last_tx_bd : prev_bd - 1; + +		/* We should never see all bds marked as ready, check anyway */ +		if (recheck_bd == curr_tbptr) +			break; +	} +	/* Now update the TBPTR and dirty flag to the current buffer */ +	W32(ep, fen_genfcc.fcc_tbptr, +		(uint) (((void *)recheck_bd - fep->ring_base) + +		fep->ring_mem_addr)); +	fep->dirty_tx = recheck_bd;  	C32(fccp, fcc_gfmr, FCC_GFMR_ENT);  	udelay(10); diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 0f90685d3d1..3607340f3da 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -169,7 +169,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,  	new_bus->name = "CPM2 Bitbanged MII", -	ret = fs_mii_bitbang_init(new_bus, ofdev->node); +	ret = fs_mii_bitbang_init(new_bus, ofdev->dev.of_node);  	if (ret)  		goto out_free_bus; @@ -181,7 +181,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,  	new_bus->parent = &ofdev->dev;  	dev_set_drvdata(&ofdev->dev, new_bus); -	ret = of_mdiobus_register(new_bus, ofdev->node); +	ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);  	if (ret)  		goto out_free_irqs; diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 1830f3199cb..28b53d1cd4f 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -381,10 +381,14 @@ static void gfar_init_mac(struct net_device *ndev)  	/* Insert receive time stamps into padding alignment bytes */  	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) {  		rctrl &= ~RCTRL_PAL_MASK; -		rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE | RCTRL_PADDING(8); +		rctrl |= RCTRL_PADDING(8);  		priv->padding = 8;  	} +	/* Enable HW time stamping if requested from user space */ +	if (priv->hwts_rx_en) +		rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE; +  	/* keep vlan related bits if it's enabled */  	if (priv->vlgrp) {  		rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT; @@ -806,12 +810,20 @@ static int gfar_hwtstamp_ioctl(struct net_device *netdev,  	switch (config.rx_filter) {  	case HWTSTAMP_FILTER_NONE: -		priv->hwts_rx_en = 0; +		if (priv->hwts_rx_en) { +			stop_gfar(netdev); +			priv->hwts_rx_en = 0; +			startup_gfar(netdev); +		}  		break;  	default:  		if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER))  			return -ERANGE; -		priv->hwts_rx_en = 1; +		if (!priv->hwts_rx_en) { +			stop_gfar(netdev); +			priv->hwts_rx_en = 1; +			startup_gfar(netdev); +		}  		config.rx_filter = HWTSTAMP_FILTER_ALL;  		break;  	} @@ -2643,6 +2655,10 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)  		dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,  				priv->rx_buffer_size, DMA_FROM_DEVICE); +		if (unlikely(!(bdp->status & RXBD_ERR) && +				bdp->length > priv->rx_buffer_size)) +			bdp->status = RXBD_LARGE; +  		/* We drop the frame if we failed to allocate a new buffer */  		if (unlikely(!newskb || !(bdp->status & RXBD_LAST) ||  				 bdp->status & RXBD_ERR)) { diff --git a/drivers/net/greth.c b/drivers/net/greth.c index f37a4c143dd..3a029d02c2b 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -1607,14 +1607,13 @@ static struct of_device_id greth_of_match[] = {  MODULE_DEVICE_TABLE(of, greth_of_match);  static struct of_platform_driver greth_of_driver = { -	.name = "grlib-greth", -	.match_table = greth_of_match, +	.driver = { +		.name = "grlib-greth", +		.owner = THIS_MODULE, +		.of_match_table = greth_of_match, +	},  	.probe = greth_of_probe,  	.remove = __devexit_p(greth_of_remove), -	.driver = { -		   .owner = THIS_MODULE, -		   .name = "grlib-greth", -		   },  };  static int __init greth_init(void) diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 1159d9138f0..9595b1bfb8d 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1188,6 +1188,7 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,  		IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);  	} else {  		hw_dbg(hw, "RAR index %d is out of range.\n", index); +		return IXGBE_ERR_RAR_INDEX;  	}  	return 0; @@ -1219,6 +1220,7 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)  		IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);  	} else {  		hw_dbg(hw, "RAR index %d is out of range.\n", index); +		return IXGBE_ERR_RAR_INDEX;  	}  	/* clear VMDq pool/queue selection for this RAR */ diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index c50a7541ffe..3a93a81872b 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2077,25 +2077,6 @@ static int ixgbe_get_coalesce(struct net_device *netdev,  	return 0;  } -/* - * this function must be called before setting the new value of - * rx_itr_setting - */ -static bool ixgbe_reenable_rsc(struct ixgbe_adapter *adapter, -                               struct ethtool_coalesce *ec) -{ -	/* check the old value and enable RSC if necessary */ -	if ((adapter->rx_itr_setting == 0) && -	    (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) { -		adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; -		adapter->netdev->features |= NETIF_F_LRO; -		DPRINTK(PROBE, INFO, "rx-usecs set to %d, re-enabling RSC\n", -		        ec->rx_coalesce_usecs); -		return true; -	} -	return false; -} -  static int ixgbe_set_coalesce(struct net_device *netdev,                                struct ethtool_coalesce *ec)  { @@ -2124,9 +2105,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev,  		    (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE))  			return -EINVAL; -		/* check the old value and enable RSC if necessary */ -		need_reset = ixgbe_reenable_rsc(adapter, ec); -  		/* store the value in ints/second */  		adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs; @@ -2135,9 +2113,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev,  		/* clear the lower bit as its used for dynamic state */  		adapter->rx_itr_setting &= ~1;  	} else if (ec->rx_coalesce_usecs == 1) { -		/* check the old value and enable RSC if necessary */ -		need_reset = ixgbe_reenable_rsc(adapter, ec); -  		/* 1 means dynamic mode */  		adapter->rx_eitr_param = 20000;  		adapter->rx_itr_setting = 1; @@ -2157,10 +2132,11 @@ static int ixgbe_set_coalesce(struct net_device *netdev,  		 */  		if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {  			adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; -			netdev->features &= ~NETIF_F_LRO; -			DPRINTK(PROBE, INFO, -			        "rx-usecs set to 0, disabling RSC\n"); - +			if (netdev->features & NETIF_F_LRO) { +				netdev->features &= ~NETIF_F_LRO; +				DPRINTK(PROBE, INFO, "rx-usecs set to 0, " +					"disabling LRO/RSC\n"); +			}  			need_reset = true;  		}  	} @@ -2255,6 +2231,9 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)  			}  		} else if (!adapter->rx_itr_setting) {  			netdev->features &= ~ETH_FLAG_LRO; +			if (data & ETH_FLAG_LRO) +				DPRINTK(PROBE, INFO, "rx-usecs set to 0, " +					"LRO/RSC cannot be enabled.\n");  		}  	} diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d571d101de0..7b5d9764f31 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -642,7 +642,7 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter,  	u32 txoff = IXGBE_TFCS_TXOFF;  #ifdef CONFIG_IXGBE_DCB -	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { +	if (adapter->dcb_cfg.pfc_mode_enable) {  		int tc;  		int reg_idx = tx_ring->reg_idx;  		int dcb_i = adapter->ring_feature[RING_F_DCB].indices; @@ -3684,10 +3684,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)  	/* signal that we are down to the interrupt handler */  	set_bit(__IXGBE_DOWN, &adapter->state); -	/* power down the optics */ -	if (hw->phy.multispeed_fiber) -		hw->mac.ops.disable_tx_laser(hw); -  	/* disable receive for all VFs and wait one second */  	if (adapter->num_vfs) {  		/* ping all the active vfs to let them know we are going down */ @@ -3742,6 +3738,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)  		                (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &  		                 ~IXGBE_DMATXCTL_TE)); +	/* power down the optics */ +	if (hw->phy.multispeed_fiber) +		hw->mac.ops.disable_tx_laser(hw); +  	/* clear n-tuple filters that are cached */  	ethtool_ntuple_flush(netdev); @@ -4001,7 +4001,7 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)  done:  	/* Notify the stack of the (possibly) reduced Tx Queue count. */ -	adapter->netdev->real_num_tx_queues = adapter->num_tx_queues; +	netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);  }  static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, @@ -5195,7 +5195,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)  		ixgbe_free_all_tx_resources(adapter);  		ixgbe_free_all_rx_resources(adapter);  	} -	ixgbe_clear_interrupt_scheme(adapter);  #ifdef CONFIG_PM  	retval = pci_save_state(pdev); @@ -5230,6 +5229,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)  	*enable_wake = !!wufc; +	ixgbe_clear_interrupt_scheme(adapter); +  	ixgbe_release_hw_control(adapter);  	pci_disable_device(pdev); @@ -5282,6 +5283,10 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)  	u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;  	u64 non_eop_descs = 0, restart_queue = 0; +	if (test_bit(__IXGBE_DOWN, &adapter->state) || +	    test_bit(__IXGBE_RESETTING, &adapter->state)) +		return; +  	if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {  		u64 rsc_count = 0;  		u64 rsc_flush = 0; @@ -6019,7 +6024,6 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,  static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,  	              int queue, u32 tx_flags)  { -	/* Right now, we support IPv4 only */  	struct ixgbe_atr_input atr_input;  	struct tcphdr *th;  	struct iphdr *iph = ip_hdr(skb); @@ -6028,6 +6032,9 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,  	u32 src_ipv4_addr, dst_ipv4_addr;  	u8 l4type = 0; +	/* Right now, we support IPv4 only */ +	if (skb->protocol != htons(ETH_P_IP)) +		return;  	/* check if we're UDP or TCP */  	if (iph->protocol == IPPROTO_TCP) {  		th = tcp_hdr(skb); diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 09e1911ff51..48325a5beff 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -575,6 +575,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)  		 * 4    SFP_DA_CORE1 - 82599-specific  		 * 5    SFP_SR/LR_CORE0 - 82599-specific  		 * 6    SFP_SR/LR_CORE1 - 82599-specific +		 * 7    SFP_act_lmt_DA_CORE0 - 82599-specific +		 * 8    SFP_act_lmt_DA_CORE1 - 82599-specific  		 */  		if (hw->mac.type == ixgbe_mac_82598EB) {  			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 2eb6e151016..cdd1998f18c 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2609,6 +2609,7 @@ struct ixgbe_info {  #define IXGBE_ERR_EEPROM_VERSION                -24  #define IXGBE_ERR_NO_SPACE                      -25  #define IXGBE_ERR_OVERTEMP                      -26 +#define IXGBE_ERR_RAR_INDEX                     -27  #define IXGBE_NOT_IMPLEMENTED                   0x7FFFFFFF  #endif /* _IXGBE_TYPE_H_ */ diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 26bf1b76b99..c7a9bef4dfb 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -135,6 +135,7 @@ struct korina_private {  	struct napi_struct napi;  	struct timer_list media_check_timer;  	struct mii_if_info mii_if; +	struct work_struct restart_task;  	struct net_device *dev;  	int phy_addr;  }; @@ -375,7 +376,7 @@ static int korina_rx(struct net_device *dev, int limit)  		if (devcs & ETH_RX_LE)  			dev->stats.rx_length_errors++;  		if (devcs & ETH_RX_OVR) -			dev->stats.rx_over_errors++; +			dev->stats.rx_fifo_errors++;  		if (devcs & ETH_RX_CV)  			dev->stats.rx_frame_errors++;  		if (devcs & ETH_RX_CES) @@ -764,10 +765,9 @@ static int korina_alloc_ring(struct net_device *dev)  	/* Initialize the receive descriptors */  	for (i = 0; i < KORINA_NUM_RDS; i++) { -		skb = dev_alloc_skb(KORINA_RBSIZE + 2); +		skb = netdev_alloc_skb_ip_align(dev, KORINA_RBSIZE);  		if (!skb)  			return -ENOMEM; -		skb_reserve(skb, 2);  		lp->rx_skb[i] = skb;  		lp->rd_ring[i].control = DMA_DESC_IOD |  				DMA_COUNT(KORINA_RBSIZE); @@ -890,12 +890,12 @@ static int korina_init(struct net_device *dev)  /*   * Restart the RC32434 ethernet controller. - * FIXME: check the return status where we call it   */ -static int korina_restart(struct net_device *dev) +static void korina_restart_task(struct work_struct *work)  { -	struct korina_private *lp = netdev_priv(dev); -	int ret; +	struct korina_private *lp = container_of(work, +			struct korina_private, restart_task); +	struct net_device *dev = lp->dev;  	/*  	 * Disable interrupts @@ -916,10 +916,9 @@ static int korina_restart(struct net_device *dev)  	napi_disable(&lp->napi); -	ret = korina_init(dev); -	if (ret < 0) { +	if (korina_init(dev) < 0) {  		printk(KERN_ERR "%s: cannot restart device\n", dev->name); -		return ret; +		return;  	}  	korina_multicast_list(dev); @@ -927,8 +926,6 @@ static int korina_restart(struct net_device *dev)  	enable_irq(lp->ovr_irq);  	enable_irq(lp->tx_irq);  	enable_irq(lp->rx_irq); - -	return ret;  }  static void korina_clear_and_restart(struct net_device *dev, u32 value) @@ -937,7 +934,7 @@ static void korina_clear_and_restart(struct net_device *dev, u32 value)  	netif_stop_queue(dev);  	writel(value, &lp->eth_regs->ethintfc); -	korina_restart(dev); +	schedule_work(&lp->restart_task);  }  /* Ethernet Tx Underflow interrupt */ @@ -962,11 +959,8 @@ static irqreturn_t korina_und_interrupt(int irq, void *dev_id)  static void korina_tx_timeout(struct net_device *dev)  {  	struct korina_private *lp = netdev_priv(dev); -	unsigned long flags; -	spin_lock_irqsave(&lp->lock, flags); -	korina_restart(dev); -	spin_unlock_irqrestore(&lp->lock, flags); +	schedule_work(&lp->restart_task);  }  /* Ethernet Rx Overflow interrupt */ @@ -1086,6 +1080,8 @@ static int korina_close(struct net_device *dev)  	napi_disable(&lp->napi); +	cancel_work_sync(&lp->restart_task); +  	free_irq(lp->rx_irq, dev);  	free_irq(lp->tx_irq, dev);  	free_irq(lp->ovr_irq, dev); @@ -1198,6 +1194,8 @@ static int korina_probe(struct platform_device *pdev)  	}  	setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev); +	INIT_WORK(&lp->restart_task, korina_restart_task); +  	printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",  			dev->name);  out: diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index c80ca64277b..7805bbf1d53 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -4854,7 +4854,7 @@ static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb)   *   * Return 0 if successful; otherwise an error code indicating failure.   */ -static int netdev_tx(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)  {  	struct dev_priv *priv = netdev_priv(dev);  	struct dev_info *hw_priv = priv->adapter; @@ -6863,6 +6863,7 @@ static const struct net_device_ops netdev_ops = {  	.ndo_tx_timeout		= netdev_tx_timeout,  	.ndo_change_mtu		= netdev_change_mtu,  	.ndo_set_mac_address	= netdev_set_mac_address, +	.ndo_validate_addr	= eth_validate_addr,  	.ndo_do_ioctl		= netdev_ioctl,  	.ndo_set_rx_mode	= netdev_set_rx_mode,  #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c index ce5d6e90921..c27f4291b35 100644 --- a/drivers/net/lib82596.c +++ b/drivers/net/lib82596.c @@ -1343,7 +1343,7 @@ static void set_multicast_list(struct net_device *dev)  	DEB(DEB_MULTI,  	    printk(KERN_DEBUG  		   "%s: set multicast list, %d entries, promisc %s, allmulti %s\n", -		   dev->name, dev->mc_count, +		   dev->name, netdev_mc_count(dev),  		   dev->flags & IFF_PROMISC ? "ON" : "OFF",  		   dev->flags & IFF_ALLMULTI ? "ON" : "OFF")); diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 52dcc849564..6474c4973d3 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -964,7 +964,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)  	np = of_parse_phandle(op->dev.of_node, "llink-connected", 0);  	if (!np) {  		dev_err(&op->dev, "could not find DMA node\n"); -		goto nodev; +		goto err_iounmap;  	}  	/* Setup the DMA register accesses, could be DCR or memory mapped */ @@ -978,7 +978,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)  			dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs);  		} else {  			dev_err(&op->dev, "unable to map DMA registers\n"); -			goto nodev; +			goto err_iounmap;  		}  	} @@ -987,7 +987,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)  	if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) {  		dev_err(&op->dev, "could not determine irqs\n");  		rc = -ENOMEM; -		goto nodev; +		goto err_iounmap_2;  	}  	of_node_put(np); /* Finished with the DMA node; drop the reference */ @@ -997,7 +997,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)  	if ((!addr) || (size != 6)) {  		dev_err(&op->dev, "could not find MAC address\n");  		rc = -ENODEV; -		goto nodev; +		goto err_iounmap_2;  	}  	temac_set_mac_address(ndev, (void *)addr); @@ -1013,7 +1013,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)  	rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group);  	if (rc) {  		dev_err(lp->dev, "Error creating sysfs files\n"); -		goto nodev; +		goto err_iounmap_2;  	}  	rc = register_netdev(lp->ndev); @@ -1026,6 +1026,11 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)   err_register_ndev:  	sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); + err_iounmap_2: +	if (lp->sdma_regs) +		iounmap(lp->sdma_regs); + err_iounmap: +	iounmap(lp->regs);   nodev:  	free_netdev(ndev);  	ndev = NULL; @@ -1044,6 +1049,9 @@ static int __devexit temac_of_remove(struct of_device *op)  		of_node_put(lp->phy_node);  	lp->phy_node = NULL;  	dev_set_drvdata(&op->dev, NULL); +	iounmap(lp->regs); +	if (lp->sdma_regs) +		iounmap(lp->sdma_regs);  	free_netdev(ndev);  	return 0;  } diff --git a/drivers/net/mace.c b/drivers/net/mace.c index b6855a6476f..1c5221f79d6 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -997,8 +997,11 @@ MODULE_DEVICE_TABLE (of, mace_match);  static struct macio_driver mace_driver =  { -	.name 		= "mace", -	.match_table	= mace_match, +	.driver = { +		.name 		= "mace", +		.owner		= THIS_MODULE, +		.of_match_table	= mace_match, +	},  	.probe		= mace_probe,  	.remove		= mace_remove,  }; diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index 8e9704f5c12..869f0ea43a5 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c @@ -247,7 +247,7 @@ static const struct net_device_ops mipsnet_netdev_ops = {  	.ndo_set_mac_address	= eth_mac_addr,  }; -static int __init mipsnet_probe(struct platform_device *dev) +static int __devinit mipsnet_probe(struct platform_device *dev)  {  	struct net_device *netdev;  	int err; diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index e345ec8cb47..73bb8ea6f54 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -289,6 +289,7 @@ struct mv643xx_eth_shared_private {  	unsigned int t_clk;  	int extended_rx_coal_limit;  	int tx_bw_control; +	int tx_csum_limit;  };  #define TX_BW_CONTROL_ABSENT		0 @@ -776,13 +777,16 @@ static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)  	l4i_chk = 0;  	if (skb->ip_summed == CHECKSUM_PARTIAL) { +		int hdr_len;  		int tag_bytes;  		BUG_ON(skb->protocol != htons(ETH_P_IP) &&  		       skb->protocol != htons(ETH_P_8021Q)); -		tag_bytes = (void *)ip_hdr(skb) - (void *)skb->data - ETH_HLEN; -		if (unlikely(tag_bytes & ~12)) { +		hdr_len = (void *)ip_hdr(skb) - (void *)skb->data; +		tag_bytes = hdr_len - ETH_HLEN; +		if (skb->len - hdr_len > mp->shared->tx_csum_limit || +		    unlikely(tag_bytes & ~12)) {  			if (skb_checksum_help(skb) == 0)  				goto no_csum;  			kfree_skb(skb); @@ -2666,6 +2670,7 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)  	 * Detect hardware parameters.  	 */  	msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; +	msp->tx_csum_limit = pd->tx_csum_limit ? pd->tx_csum_limit : 9 * 1024;  	infer_hw_params(msp);  	platform_set_drvdata(pdev, msp); diff --git a/drivers/net/ne.c b/drivers/net/ne.c index b8e2923a1d6..1063093b3af 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -806,8 +806,10 @@ static int __init ne_drv_probe(struct platform_device *pdev)  		dev->base_addr = res->start;  		dev->irq = platform_get_irq(pdev, 0);  	} else { -		if (this_dev < 0 || this_dev >= MAX_NE_CARDS) +		if (this_dev < 0 || this_dev >= MAX_NE_CARDS) { +			free_netdev(dev);  			return -EINVAL; +		}  		dev->base_addr = io[this_dev];  		dev->irq = irq[this_dev];  		dev->mem_end = bad[this_dev]; diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index f26e54716c8..3a41b6a84a6 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -629,7 +629,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)  	if (addr == NULL) {  		dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",  				netdev->name); -		return -ENOMEM; +		err = -ENOMEM; +		goto err_out_free;  	}  	tx_ring->desc_head = (struct cmd_desc_type0 *)addr; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 5c496f8d7c4..29d7b93d049 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -1159,9 +1159,6 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off)  	window = CRB_HI(off); -	if (adapter->ahw.crb_win == window) -		return; -  	writel(window, addr);  	if (readl(addr) != window) {  		if (printk_ratelimit()) @@ -1169,7 +1166,6 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off)  				"failed to set CRB window to %d off 0x%lx\n",  				window, off);  	} -	adapter->ahw.crb_win = window;  }  static void __iomem * diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 045a7c8f5bd..c865dda2adf 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -218,7 +218,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)  	if (cmd_buf_arr == NULL) {  		dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n",  		       netdev->name); -		return -ENOMEM; +		goto err_out;  	}  	memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));  	tx_ring->cmd_buf_arr = cmd_buf_arr; @@ -230,7 +230,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)  	if (rds_ring == NULL) {  		dev_err(&pdev->dev, "%s: failed to allocate rds ring struct\n",  		       netdev->name); -		return -ENOMEM; +		goto err_out;  	}  	recv_ctx->rds_rings = rds_ring; @@ -1805,9 +1805,10 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,  	netxen_ctx_msg msg = 0;  	struct list_head *head; +	spin_lock(&rds_ring->lock); +  	producer = rds_ring->producer; -	spin_lock(&rds_ring->lock);  	head = &rds_ring->free_list;  	while (!list_empty(head)) { @@ -1829,7 +1830,6 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,  		producer = get_next_index(producer, rds_ring->num_desc);  	} -	spin_unlock(&rds_ring->lock);  	if (count) {  		rds_ring->producer = producer; @@ -1853,6 +1853,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,  					NETXEN_RCV_PRODUCER_OFFSET), msg);  		}  	} + +	spin_unlock(&rds_ring->lock);  }  static void @@ -1864,10 +1866,11 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,  	int producer, count = 0;  	struct list_head *head; -	producer = rds_ring->producer;  	if (!spin_trylock(&rds_ring->lock))  		return; +	producer = rds_ring->producer; +  	head = &rds_ring->free_list;  	while (!list_empty(head)) { diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 6f77a768ba8..bfdef72c5d5 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1727,6 +1727,7 @@ static struct pcmcia_device_id pcnet_ids[] = {  	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),  	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),  	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), +	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"),  	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),  	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),  	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 7b6fe89f9db..307cd1721e9 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -322,6 +322,7 @@ static int smc91c92_probe(struct pcmcia_device *link)  	return -ENOMEM;      smc = netdev_priv(dev);      smc->p_dev = link; +    link->priv = dev;      spin_lock_init(&smc->lock);      link->io.NumPorts1 = 16; @@ -1504,12 +1505,20 @@ irq_done:  	writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_LAN + CISREG_COR);  	writeb(cor, smc->base + MOT_LAN + CISREG_COR);      } -#ifdef DOES_NOT_WORK -    if (smc->base != NULL) { /* Megahertz MFC's */ -	readb(smc->base+MEGAHERTZ_ISR); -	readb(smc->base+MEGAHERTZ_ISR); + +    if ((smc->base != NULL) &&  /* Megahertz MFC's */ +	(smc->manfid == MANFID_MEGAHERTZ) && +	(smc->cardid == PRODID_MEGAHERTZ_EM3288)) { + +	u_char tmp; +	tmp = readb(smc->base+MEGAHERTZ_ISR); +	tmp = readb(smc->base+MEGAHERTZ_ISR); + +	/* Retrigger interrupt if needed */ +	writeb(tmp, smc->base + MEGAHERTZ_ISR); +	writeb(tmp, smc->base + MEGAHERTZ_ISR);      } -#endif +      spin_unlock(&smc->lock);      return IRQ_RETVAL(handled);  } diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index 8ee929b796d..29c39ff85de 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c @@ -53,6 +53,9 @@  #define MII_LXT971_ISR		19  /* Interrupt Status Register */ +/* register definitions for the 973 */ +#define MII_LXT973_PCR 16 /* Port Configuration Register */ +#define PCR_FIBER_SELECT 1  MODULE_DESCRIPTION("Intel LXT PHY driver");  MODULE_AUTHOR("Andy Fleming"); @@ -119,6 +122,33 @@ static int lxt971_config_intr(struct phy_device *phydev)  	return err;  } +static int lxt973_probe(struct phy_device *phydev) +{ +	int val = phy_read(phydev, MII_LXT973_PCR); + +	if (val & PCR_FIBER_SELECT) { +		/* +		 * If fiber is selected, then the only correct setting +		 * is 100Mbps, full duplex, and auto negotiation off. +		 */ +		val = phy_read(phydev, MII_BMCR); +		val |= (BMCR_SPEED100 | BMCR_FULLDPLX); +		val &= ~BMCR_ANENABLE; +		phy_write(phydev, MII_BMCR, val); +		/* Remember that the port is in fiber mode. */ +		phydev->priv = lxt973_probe; +	} else { +		phydev->priv = NULL; +	} +	return 0; +} + +static int lxt973_config_aneg(struct phy_device *phydev) +{ +	/* Do nothing if port is in fiber mode. */ +	return phydev->priv ? 0 : genphy_config_aneg(phydev); +} +  static struct phy_driver lxt970_driver = {  	.phy_id		= 0x78100000,  	.name		= "LXT970", @@ -146,6 +176,18 @@ static struct phy_driver lxt971_driver = {  	.driver 	= { .owner = THIS_MODULE,},  }; +static struct phy_driver lxt973_driver = { +	.phy_id		= 0x00137a10, +	.name		= "LXT973", +	.phy_id_mask	= 0xfffffff0, +	.features	= PHY_BASIC_FEATURES, +	.flags		= 0, +	.probe		= lxt973_probe, +	.config_aneg	= lxt973_config_aneg, +	.read_status	= genphy_read_status, +	.driver 	= { .owner = THIS_MODULE,}, +}; +  static int __init lxt_init(void)  {  	int ret; @@ -157,9 +199,15 @@ static int __init lxt_init(void)  	ret = phy_driver_register(&lxt971_driver);  	if (ret)  		goto err2; + +	ret = phy_driver_register(&lxt973_driver); +	if (ret) +		goto err3;  	return 0; - err2:	 + err3: +	phy_driver_unregister(&lxt971_driver); + err2:  	phy_driver_unregister(&lxt970_driver);   err1:  	return ret; @@ -169,6 +217,7 @@ static void __exit lxt_exit(void)  {  	phy_driver_unregister(&lxt970_driver);  	phy_driver_unregister(&lxt971_driver); +	phy_driver_unregister(&lxt973_driver);  }  module_init(lxt_init); @@ -177,6 +226,7 @@ module_exit(lxt_exit);  static struct mdio_device_id lxt_tbl[] = {  	{ 0x78100000, 0xfffffff0 },  	{ 0x001378e0, 0xfffffff0 }, +	{ 0x00137a10, 0xfffffff0 },  	{ }  }; diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index c5f8eb102bf..1b2c2915020 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1422,7 +1422,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)  		flen = len;  		if (nfree > 0) {  			if (pch->speed == 0) { -				flen = totlen/nfree; +				flen = len/nfree;  				if (nbigger > 0) {  					flen++;  					nbigger--; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index fa4b24c49f4..d10bcefc0e4 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -4611,8 +4611,7 @@ static void ql_timer(unsigned long data)  		return;  	} -	qdev->timer.expires = jiffies + (5*HZ); -	add_timer(&qdev->timer); +	mod_timer(&qdev->timer, jiffies + (5*HZ));  }  static int __devinit qlge_probe(struct pci_dev *pdev, @@ -4713,6 +4712,8 @@ static void ql_eeh_close(struct net_device *ndev)  		netif_stop_queue(ndev);  	} +	/* Disabling the timer */ +	del_timer_sync(&qdev->timer);  	if (test_bit(QL_ADAPTER_UP, &qdev->flags))  		cancel_delayed_work_sync(&qdev->asic_reset_work);  	cancel_delayed_work_sync(&qdev->mpi_reset_work); @@ -4808,8 +4809,7 @@ static void qlge_io_resume(struct pci_dev *pdev)  		netif_err(qdev, ifup, qdev->ndev,  			  "Device was not running prior to EEH.\n");  	} -	qdev->timer.expires = jiffies + (5*HZ); -	add_timer(&qdev->timer); +	mod_timer(&qdev->timer, jiffies + (5*HZ));  	netif_device_attach(ndev);  } @@ -4871,8 +4871,7 @@ static int qlge_resume(struct pci_dev *pdev)  			return err;  	} -	qdev->timer.expires = jiffies + (5*HZ); -	add_timer(&qdev->timer); +	mod_timer(&qdev->timer, jiffies + (5*HZ));  	netif_device_attach(ndev);  	return 0; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 217e709bda3..96b6cfbf0a3 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -559,6 +559,11 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)  			break;  		udelay(25);  	} +	/* +	 * According to hardware specs a 20us delay is required after write +	 * complete indication, but before sending next command. +	 */ +	udelay(20);  }  static int mdio_read(void __iomem *ioaddr, int reg_addr) @@ -578,6 +583,12 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)  		}  		udelay(25);  	} +	/* +	 * According to hardware specs a 20us delay is required after read +	 * complete indication, but before sending next command. +	 */ +	udelay(20); +  	return value;  } diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 668327ccd8d..1d37f0c310c 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -3130,7 +3130,6 @@ static void tx_intr_handler(struct fifo_info *fifo_data)  		pkt_cnt++;  		/* Updating the statistics block */ -		nic->dev->stats.tx_bytes += skb->len;  		swstats->mem_freed += skb->truesize;  		dev_kfree_skb_irq(skb); @@ -4901,48 +4900,81 @@ static void s2io_updt_stats(struct s2io_nic *sp)   *  Return value:   *  pointer to the updated net_device_stats structure.   */ -  static struct net_device_stats *s2io_get_stats(struct net_device *dev)  {  	struct s2io_nic *sp = netdev_priv(dev); -	struct config_param *config = &sp->config;  	struct mac_info *mac_control = &sp->mac_control;  	struct stat_block *stats = mac_control->stats_info; -	int i; +	u64 delta;  	/* Configure Stats for immediate updt */  	s2io_updt_stats(sp); -	/* Using sp->stats as a staging area, because reset (due to mtu -	   change, for example) will clear some hardware counters */ -	dev->stats.tx_packets += le32_to_cpu(stats->tmac_frms) - -		sp->stats.tx_packets; -	sp->stats.tx_packets = le32_to_cpu(stats->tmac_frms); +	/* A device reset will cause the on-adapter statistics to be zero'ed. +	 * This can be done while running by changing the MTU.  To prevent the +	 * system from having the stats zero'ed, the driver keeps a copy of the +	 * last update to the system (which is also zero'ed on reset).  This +	 * enables the driver to accurately know the delta between the last +	 * update and the current update. +	 */ +	delta = ((u64) le32_to_cpu(stats->rmac_vld_frms_oflow) << 32 | +		le32_to_cpu(stats->rmac_vld_frms)) - sp->stats.rx_packets; +	sp->stats.rx_packets += delta; +	dev->stats.rx_packets += delta; -	dev->stats.tx_errors += le32_to_cpu(stats->tmac_any_err_frms) - -		sp->stats.tx_errors; -	sp->stats.tx_errors = le32_to_cpu(stats->tmac_any_err_frms); +	delta = ((u64) le32_to_cpu(stats->tmac_frms_oflow) << 32 | +		le32_to_cpu(stats->tmac_frms)) - sp->stats.tx_packets; +	sp->stats.tx_packets += delta; +	dev->stats.tx_packets += delta; -	dev->stats.rx_errors += le64_to_cpu(stats->rmac_drop_frms) - -		sp->stats.rx_errors; -	sp->stats.rx_errors = le64_to_cpu(stats->rmac_drop_frms); +	delta = ((u64) le32_to_cpu(stats->rmac_data_octets_oflow) << 32 | +		le32_to_cpu(stats->rmac_data_octets)) - sp->stats.rx_bytes; +	sp->stats.rx_bytes += delta; +	dev->stats.rx_bytes += delta; -	dev->stats.multicast = le32_to_cpu(stats->rmac_vld_mcst_frms) - -		sp->stats.multicast; -	sp->stats.multicast = le32_to_cpu(stats->rmac_vld_mcst_frms); +	delta = ((u64) le32_to_cpu(stats->tmac_data_octets_oflow) << 32 | +		le32_to_cpu(stats->tmac_data_octets)) - sp->stats.tx_bytes; +	sp->stats.tx_bytes += delta; +	dev->stats.tx_bytes += delta; -	dev->stats.rx_length_errors = le64_to_cpu(stats->rmac_long_frms) - -		sp->stats.rx_length_errors; -	sp->stats.rx_length_errors = le64_to_cpu(stats->rmac_long_frms); +	delta = le64_to_cpu(stats->rmac_drop_frms) - sp->stats.rx_errors; +	sp->stats.rx_errors += delta; +	dev->stats.rx_errors += delta; -	/* collect per-ring rx_packets and rx_bytes */ -	dev->stats.rx_packets = dev->stats.rx_bytes = 0; -	for (i = 0; i < config->rx_ring_num; i++) { -		struct ring_info *ring = &mac_control->rings[i]; +	delta = ((u64) le32_to_cpu(stats->tmac_any_err_frms_oflow) << 32 | +		le32_to_cpu(stats->tmac_any_err_frms)) - sp->stats.tx_errors; +	sp->stats.tx_errors += delta; +	dev->stats.tx_errors += delta; -		dev->stats.rx_packets += ring->rx_packets; -		dev->stats.rx_bytes += ring->rx_bytes; -	} +	delta = le64_to_cpu(stats->rmac_drop_frms) - sp->stats.rx_dropped; +	sp->stats.rx_dropped += delta; +	dev->stats.rx_dropped += delta; + +	delta = le64_to_cpu(stats->tmac_drop_frms) - sp->stats.tx_dropped; +	sp->stats.tx_dropped += delta; +	dev->stats.tx_dropped += delta; + +	/* The adapter MAC interprets pause frames as multicast packets, but +	 * does not pass them up.  This erroneously increases the multicast +	 * packet count and needs to be deducted when the multicast frame count +	 * is queried. +	 */ +	delta = (u64) le32_to_cpu(stats->rmac_vld_mcst_frms_oflow) << 32 | +		le32_to_cpu(stats->rmac_vld_mcst_frms); +	delta -= le64_to_cpu(stats->rmac_pause_ctrl_frms); +	delta -= sp->stats.multicast; +	sp->stats.multicast += delta; +	dev->stats.multicast += delta; + +	delta = ((u64) le32_to_cpu(stats->rmac_usized_frms_oflow) << 32 | +		le32_to_cpu(stats->rmac_usized_frms)) + +		le64_to_cpu(stats->rmac_long_frms) - sp->stats.rx_length_errors; +	sp->stats.rx_length_errors += delta; +	dev->stats.rx_length_errors += delta; + +	delta = le64_to_cpu(stats->rmac_fcs_err_frms) - sp->stats.rx_crc_errors; +	sp->stats.rx_crc_errors += delta; +	dev->stats.rx_crc_errors += delta;  	return &dev->stats;  } @@ -7455,15 +7487,11 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)  		}  	} -	/* Updating statistics */ -	ring_data->rx_packets++;  	rxdp->Host_Control = 0;  	if (sp->rxd_mode == RXD_MODE_1) {  		int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2); -		ring_data->rx_bytes += len;  		skb_put(skb, len); -  	} else if (sp->rxd_mode == RXD_MODE_3B) {  		int get_block = ring_data->rx_curr_get_info.block_index;  		int get_off = ring_data->rx_curr_get_info.offset; @@ -7472,7 +7500,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)  		unsigned char *buff = skb_push(skb, buf0_len);  		struct buffAdd *ba = &ring_data->ba[get_block][get_off]; -		ring_data->rx_bytes += buf0_len + buf2_len;  		memcpy(buff, ba->ba_0, buf0_len);  		skb_put(skb, buf2_len);  	} diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 47c36e0994f..5e52c75892d 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -745,10 +745,6 @@ struct ring_info {  	/* Buffer Address store. */  	struct buffAdd **ba; - -	/* per-Ring statistics */ -	unsigned long rx_packets; -	unsigned long rx_bytes;  } ____cacheline_aligned;  /* Fifo specific structure */ diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 1f3acc3a5df..79eee306208 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -2671,6 +2671,7 @@ static struct platform_driver sbmac_driver = {  	.remove = __exit_p(sbmac_remove),  	.driver = {  		.name = sbmac_string, +		.owner  = THIS_MODULE,  	},  }; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 2e6fd89f2a7..4762c91cb58 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -830,7 +830,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx)  static inline unsigned int efx_port_num(struct efx_nic *efx)  { -	return PCI_FUNC(efx->pci_dev->devfn); +	return efx->net_dev->dev_id;  }  /** diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 727b4228e08..f2b1e618075 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -206,6 +206,7 @@ static int siena_probe_nic(struct efx_nic *efx)  {  	struct siena_nic_data *nic_data;  	bool already_attached = 0; +	efx_oword_t reg;  	int rc;  	/* Allocate storage for hardware specific data */ @@ -220,6 +221,9 @@ static int siena_probe_nic(struct efx_nic *efx)  		goto fail1;  	} +	efx_reado(efx, ®, FR_AZ_CS_DEBUG); +	efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; +  	efx_mcdi_init(efx);  	/* Recover from a failed assertion before probing */ diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2111c7bbf57..7985165e84f 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -717,11 +717,24 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)  	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);  } +/* Enable Rx/Tx */ +static void sky2_enable_rx_tx(struct sky2_port *sky2) +{ +	struct sky2_hw *hw = sky2->hw; +	unsigned port = sky2->port; +	u16 reg; + +	reg = gma_read16(hw, port, GM_GP_CTRL); +	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; +	gma_write16(hw, port, GM_GP_CTRL, reg); +} +  /* Force a renegotiation */  static void sky2_phy_reinit(struct sky2_port *sky2)  {  	spin_lock_bh(&sky2->phy_lock);  	sky2_phy_init(sky2->hw, sky2->port); +	sky2_enable_rx_tx(sky2);  	spin_unlock_bh(&sky2->phy_lock);  } @@ -2040,7 +2053,6 @@ static void sky2_link_up(struct sky2_port *sky2)  {  	struct sky2_hw *hw = sky2->hw;  	unsigned port = sky2->port; -	u16 reg;  	static const char *fc_name[] = {  		[FC_NONE]	= "none",  		[FC_TX]		= "tx", @@ -2048,10 +2060,7 @@ static void sky2_link_up(struct sky2_port *sky2)  		[FC_BOTH]	= "both",  	}; -	/* enable Rx/Tx */ -	reg = gma_read16(hw, port, GM_GP_CTRL); -	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; -	gma_write16(hw, port, GM_GP_CTRL, reg); +	sky2_enable_rx_tx(sky2);  	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 20ab1619232..737df6032bb 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -646,7 +646,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)  		error = copy_from_user(data, ifr->ifr_data, sizeof(data));  		if (error) {  			pr_err("cant copy from user\n"); -			RET(error); +			RET(-EFAULT);  		}  		DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);  	} @@ -665,7 +665,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)  		    data[2]);  		error = copy_to_user(ifr->ifr_data, data, sizeof(data));  		if (error) -			RET(error); +			RET(-EFAULT);  		break;  	case BDX_OP_WRITE: diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index c0e70006374..06b552fca63 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -367,8 +367,8 @@ static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, };  static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; -#define dr32(reg)		readl(de->regs + (reg)) -#define dw32(reg,val)		writel((val), de->regs + (reg)) +#define dr32(reg)	ioread32(de->regs + (reg)) +#define dw32(reg, val)	iowrite32((val), de->regs + (reg))  static void de_rx_err_acct (struct de_private *de, unsigned rx_tail, @@ -1706,6 +1706,7 @@ static void __devinit de21040_get_mac_address (struct de_private *de)  		int value, boguscnt = 100000;  		do {  			value = dr32(ROMCmd); +			rmb();  		} while (value < 0 && --boguscnt > 0);  		de->dev->dev_addr[i] = value;  		udelay(1); diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 4a34833b85d..807470e156a 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3215,6 +3215,8 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit  					   __func__, __LINE__, (u32) skb);  			if (skb) {  				skb->data = skb->head + NET_SKB_PAD; +				skb->len = 0; +				skb_reset_tail_pointer(skb);  				__skb_queue_head(&ugeth->rx_recycle, skb);  			} diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 1f802e90474..9516f382a6b 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -344,7 +344,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)  			return 2;  		} -		if (size > ETH_FRAME_LEN) { +		if (size > dev->net->mtu + ETH_HLEN) {  			netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n",  				   size);  			return 0; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 0a3c41faea9..4dd23513c5a 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1334,7 +1334,6 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)  	/* check for port already opened, if not set the termios */  	serial->open_count++;  	if (serial->open_count == 1) { -		tty->low_latency = 1;  		serial->rx_state = RX_IDLE;  		/* Force default termio settings */  		_hso_serial_set_termios(tty, NULL); diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 28d3ee175e7..dd8a4adf48c 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -104,10 +104,8 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,  int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)  {  	struct cdc_state	*info = (void *) &dev->data; -	struct usb_cdc_notification notification;  	int			master_ifnum;  	int			retval; -	int			partial;  	unsigned		count;  	__le32			rsp;  	u32			xid = 0, msg_len, request_id; @@ -135,17 +133,13 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)  	if (unlikely(retval < 0 || xid == 0))  		return retval; -	/* Some devices don't respond on the control channel until -	 * polled on the status channel, so do that first. */ -	retval = usb_interrupt_msg( -		dev->udev, -		usb_rcvintpipe(dev->udev, dev->status->desc.bEndpointAddress), -		¬ification, sizeof(notification), &partial, -		RNDIS_CONTROL_TIMEOUT_MS); -	if (unlikely(retval < 0)) -		return retval; +	// FIXME Seems like some devices discard responses when +	// we time out and cancel our "get response" requests... +	// so, this is fragile.  Probably need to poll for status. -	/* Poll the control channel; the request probably completed immediately */ +	/* ignore status endpoint, just poll the control channel; +	 * the request probably completed immediately +	 */  	rsp = buf->msg_type | RNDIS_MSG_COMPLETION;  	for (count = 0; count < 10; count++) {  		memset(buf, 0, CONTROL_BUFFER_SIZE); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index a95c73de582..81c76ada8e5 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1293,6 +1293,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)  		goto out;  	} +	/* netdev_printk() needs this so do it as early as possible */ +	SET_NETDEV_DEV(net, &udev->dev); +  	dev = netdev_priv(net);  	dev->udev = xdev;  	dev->intf = udev; @@ -1377,8 +1380,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)  		dev->rx_urb_size = dev->hard_mtu;  	dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); -	SET_NETDEV_DEV(net, &udev->dev); -  	if ((dev->driver_info->flags & FLAG_WLAN) != 0)  		SET_NETDEV_DEVTYPE(net, &wlan_type);  	if ((dev->driver_info->flags & FLAG_WWAN) != 0) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 78eb3190b9b..bb6b67f6b0c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -340,7 +340,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)  	skb_to_sgvec(skb, vi->rx_sg + 1, 0, skb->len); -	err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, 2, skb); +	err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, 2, skb, gfp);  	if (err < 0)  		dev_kfree_skb(skb); @@ -385,8 +385,8 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)  	/* chain first in list head */  	first->private = (unsigned long)list; -	err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2, -				       first); +	err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2, +				    first, gfp);  	if (err < 0)  		give_pages(vi, first); @@ -404,7 +404,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)  	sg_init_one(vi->rx_sg, page_address(page), PAGE_SIZE); -	err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, 1, page); +	err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, 1, page, gfp);  	if (err < 0)  		give_pages(vi, page); @@ -415,7 +415,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)  static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)  {  	int err; -	bool oom = false; +	bool oom;  	do {  		if (vi->mergeable_rx_bufs) @@ -425,10 +425,9 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)  		else  			err = add_recvbuf_small(vi, gfp); -		if (err < 0) { -			oom = true; +		oom = err == -ENOMEM; +		if (err < 0)  			break; -		}  		++vi->num;  	} while (err > 0);  	if (unlikely(vi->num > vi->max)) @@ -563,7 +562,6 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)  	struct virtnet_info *vi = netdev_priv(dev);  	int capacity; -again:  	/* Free up any pending old buffers before queueing new ones. */  	free_old_xmit_skbs(vi); @@ -572,14 +570,20 @@ again:  	/* This can happen with OOM and indirect buffers. */  	if (unlikely(capacity < 0)) { -		netif_stop_queue(dev); -		dev_warn(&dev->dev, "Unexpected full queue\n"); -		if (unlikely(!virtqueue_enable_cb(vi->svq))) { -			virtqueue_disable_cb(vi->svq); -			netif_start_queue(dev); -			goto again; +		if (net_ratelimit()) { +			if (likely(capacity == -ENOMEM)) { +				dev_warn(&dev->dev, +					 "TX queue failure: out of memory\n"); +			} else { +				dev->stats.tx_fifo_errors++; +				dev_warn(&dev->dev, +					 "Unexpected TX queue failure: %d\n", +					 capacity); +			}  		} -		return NETDEV_TX_BUSY; +		dev->stats.tx_dropped++; +		kfree_skb(skb); +		return NETDEV_TX_OK;  	}  	virtqueue_kick(vi->svq); diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index b504bd56136..fc8b2d7a091 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -2262,7 +2262,8 @@ start:  		vxge_debug_init(VXGE_ERR,  			"%s: memory allocation failed",  			VXGE_DRIVER_NAME); -		return  -ENOMEM; +		ret = -ENOMEM; +		goto alloc_entries_failed;  	}  	vdev->vxge_entries = @@ -2271,8 +2272,8 @@ start:  	if (!vdev->vxge_entries) {  		vxge_debug_init(VXGE_ERR, "%s: memory allocation failed",  			VXGE_DRIVER_NAME); -		kfree(vdev->entries); -		return -ENOMEM; +		ret = -ENOMEM; +		goto alloc_vxge_entries_failed;  	}  	for (i = 0, j = 0; i < vdev->no_of_vpath; i++) { @@ -2303,22 +2304,32 @@ start:  		vxge_debug_init(VXGE_ERR,  			"%s: MSI-X enable failed for %d vectors, ret: %d",  			VXGE_DRIVER_NAME, vdev->intr_cnt, ret); +		if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) { +			ret = -ENODEV; +			goto enable_msix_failed; +		} +  		kfree(vdev->entries);  		kfree(vdev->vxge_entries);  		vdev->entries = NULL;  		vdev->vxge_entries = NULL; - -		if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) -			return -ENODEV;  		/* Try with less no of vector by reducing no of vpaths count */  		temp = (ret - 1)/2;  		vxge_close_vpaths(vdev, temp);  		vdev->no_of_vpath = temp;  		goto start; -	} else if (ret < 0) -		return -ENODEV; - +	} else if (ret < 0) { +		ret = -ENODEV; +		goto enable_msix_failed; +	}  	return 0; + +enable_msix_failed: +	kfree(vdev->vxge_entries); +alloc_vxge_entries_failed: +	kfree(vdev->entries); +alloc_entries_failed: +	return ret;  }  static int vxge_enable_msix(struct vxgedev *vdev) @@ -4506,9 +4517,9 @@ vxge_starter(void)  	char version[32];  	snprintf(version, 32, "%s", DRV_VERSION); -	printk(KERN_CRIT "%s: Copyright(c) 2002-2009 Neterion Inc\n", +	printk(KERN_INFO "%s: Copyright(c) 2002-2009 Neterion Inc\n",  		VXGE_DRIVER_NAME); -	printk(KERN_CRIT "%s: Driver version: %s\n", +	printk(KERN_INFO "%s: Driver version: %s\n",  			VXGE_DRIVER_NAME, version);  	verify_bandwidth(); diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 166e77dfffd..e47f5a986b1 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -37,8 +37,6 @@  #include <net/x25device.h>  #include "x25_asy.h" -#include <net/x25device.h> -  static struct net_device **x25_asy_devs;  static int x25_asy_maxdev = SL_NRUNIT; diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 3f283bff0ff..11491354e5b 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c @@ -1192,7 +1192,7 @@ int i2400m_fw_hdr_check(struct i2400m *i2400m,  	unsigned module_type, header_len, major_version, minor_version,  		module_id, module_vendor, date, size; -	module_type = bcf_hdr->module_type; +	module_type = le32_to_cpu(bcf_hdr->module_type);  	header_len = sizeof(u32) * le32_to_cpu(bcf_hdr->header_len);  	major_version = (le32_to_cpu(bcf_hdr->header_version) & 0xffff0000)  		>> 16; diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 82ab532a492..a93dc18a45c 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -739,17 +739,27 @@ err_out:  static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)  {  	struct device *parent = aru->udev->dev.parent; +	struct usb_device *udev; + +	/* +	 * Store a copy of the usb_device pointer locally. +	 * This is because device_release_driver initiates +	 * ar9170_usb_disconnect, which in turn frees our +	 * driver context (aru). +	 */ +	udev = aru->udev;  	complete(&aru->firmware_loading_complete);  	/* unbind anything failed */  	if (parent)  		device_lock(parent); -	device_release_driver(&aru->udev->dev); + +	device_release_driver(&udev->dev);  	if (parent)  		device_unlock(parent); -	usb_put_dev(aru->udev); +	usb_put_dev(udev);  }  static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index e0c244b02f0..31c008042bf 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -126,6 +126,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)  	ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;  	ah->ah_noise_floor = -95;	/* until first NF calibration is run */  	sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; +	ah->ah_current_channel = &sc->channels[0];  	/*  	 * Find the mac version diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index cc6d41dec33..648972df369 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -195,7 +195,7 @@ static const struct ieee80211_rate ath5k_rates[] = {  static int __devinit	ath5k_pci_probe(struct pci_dev *pdev,  				const struct pci_device_id *id);  static void __devexit	ath5k_pci_remove(struct pci_dev *pdev); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int		ath5k_pci_suspend(struct device *dev);  static int		ath5k_pci_resume(struct device *dev); @@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);  #define ATH5K_PM_OPS	(&ath5k_pm_ops)  #else  #define ATH5K_PM_OPS	NULL -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */  static struct pci_driver ath5k_pci_driver = {  	.name		= KBUILD_MODNAME, @@ -222,7 +222,6 @@ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);  static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,  		struct ath5k_txq *txq);  static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); -static int ath5k_reset_wake(struct ath5k_softc *sc);  static int ath5k_start(struct ieee80211_hw *hw);  static void ath5k_stop(struct ieee80211_hw *hw);  static int ath5k_add_interface(struct ieee80211_hw *hw, @@ -709,7 +708,7 @@ ath5k_pci_remove(struct pci_dev *pdev)  	ieee80211_free_hw(hw);  } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int ath5k_pci_suspend(struct device *dev)  {  	struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); @@ -735,7 +734,7 @@ static int ath5k_pci_resume(struct device *dev)  	ath5k_led_enable(sc);  	return 0;  } -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */  /***********************\ @@ -2770,7 +2769,7 @@ ath5k_tasklet_reset(unsigned long data)  {  	struct ath5k_softc *sc = (void *)data; -	ath5k_reset_wake(sc); +	ath5k_reset(sc, sc->curchan);  }  /* @@ -2941,23 +2940,13 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)  	ath5k_beacon_config(sc);  	/* intrs are enabled by ath5k_beacon_config */ +	ieee80211_wake_queues(sc->hw); +  	return 0;  err:  	return ret;  } -static int -ath5k_reset_wake(struct ath5k_softc *sc) -{ -	int ret; - -	ret = ath5k_reset(sc, sc->curchan); -	if (!ret) -		ieee80211_wake_queues(sc->hw); - -	return ret; -} -  static int ath5k_start(struct ieee80211_hw *hw)  {  	return ath5k_init(hw->priv); @@ -3151,13 +3140,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,  	if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {  		if (*new_flags & FIF_PROMISC_IN_BSS) { -			rfilt |= AR5K_RX_FILTER_PROM;  			__set_bit(ATH_STAT_PROMISC, sc->status);  		} else {  			__clear_bit(ATH_STAT_PROMISC, sc->status);  		}  	} +	if (test_bit(ATH_STAT_PROMISC, sc->status)) +		rfilt |= AR5K_RX_FILTER_PROM; +  	/* Note, AR5K_RX_FILTER_MCAST is already enabled */  	if (*new_flags & FIF_ALLMULTI) {  		mfilt[0] =  ~0; diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 1b81c477880..492cbb15720 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1814,6 +1814,13 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)  	u8 def_ant, tx_ant, ee_mode;  	u32 sta_id1 = 0; +	/* if channel is not initialized yet we can't set the antennas +	 * so just store the mode. it will be set on the next reset */ +	if (channel == NULL) { +		ah->ah_ant_mode = ant_mode; +		return; +	} +  	def_ant = ah->ah_def_ant;  	ATH5K_TRACE(ah->ah_sc); diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index fbb7dec6dde..5ea87736a6a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -445,6 +445,7 @@ void ath_deinit_leds(struct ath_softc *sc);  #define SC_OP_TSF_RESET              BIT(11)  #define SC_OP_BT_PRIORITY_DETECTED   BIT(12)  #define SC_OP_BT_SCAN		     BIT(13) +#define SC_OP_ANI_RUN		     BIT(14)  /* Powersave flags */  #define PS_WAIT_FOR_BEACON        BIT(0) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index abfa0493236..1e2a68ea935 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -336,6 +336,10 @@ set_timer:  static void ath_start_ani(struct ath_common *common)  {  	unsigned long timestamp = jiffies_to_msecs(jiffies); +	struct ath_softc *sc = (struct ath_softc *) common->priv; + +	if (!(sc->sc_flags & SC_OP_ANI_RUN)) +		return;  	common->ani.longcal_timer = timestamp;  	common->ani.shortcal_timer = timestamp; @@ -872,11 +876,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,  		/* Reset rssi stats */  		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; +		sc->sc_flags |= SC_OP_ANI_RUN;  		ath_start_ani(common);  	} else {  		ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");  		common->curaid = 0;  		/* Stop ANI */ +		sc->sc_flags &= ~SC_OP_ANI_RUN;  		del_timer_sync(&common->ani.timer);  	}  } @@ -1478,8 +1484,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,  	if (vif->type == NL80211_IFTYPE_AP    ||  	    vif->type == NL80211_IFTYPE_ADHOC || -	    vif->type == NL80211_IFTYPE_MONITOR) +	    vif->type == NL80211_IFTYPE_MONITOR) { +		sc->sc_flags |= SC_OP_ANI_RUN;  		ath_start_ani(common); +	}  out:  	mutex_unlock(&sc->mutex); @@ -1500,6 +1508,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,  	mutex_lock(&sc->mutex);  	/* Stop ANI */ +	sc->sc_flags &= ~SC_OP_ANI_RUN;  	del_timer_sync(&common->ani.timer);  	/* Reclaim beacon resources */ diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3db19172b43..859aa4ab076 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1198,7 +1198,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)  		int r;  		ath_print(common, ATH_DBG_FATAL, -			  "Unable to stop TxDMA. Reset HAL!\n"); +			  "Failed to stop TX DMA. Resetting hardware!\n");  		spin_lock_bh(&sc->sc_resetlock);  		r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); @@ -1728,6 +1728,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,  	} else  		bf->bf_isnullfunc = false; +	bf->bf_tx_aborted = false; +  	return 0;  } @@ -1989,7 +1991,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,  	int nbad = 0;  	int isaggr = 0; -	if (bf->bf_tx_aborted) +	if (bf->bf_lastbf->bf_tx_aborted)  		return 0;  	isaggr = bf_isaggr(bf); diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index db72461c486..29b31a694b5 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -594,6 +594,7 @@ static int prism2_config(struct pcmcia_device *link)  	local_info_t *local;  	int ret = 1;  	struct hostap_cs_priv *hw_priv; +	unsigned long flags;  	PDEBUG(DEBUG_FLOW, "prism2_config()\n"); @@ -625,9 +626,15 @@ static int prism2_config(struct pcmcia_device *link)  	local->hw_priv = hw_priv;  	hw_priv->link = link; +	/* +	 * Make sure the IRQ handler cannot proceed until at least +	 * dev->base_addr is initialized. +	 */ +	spin_lock_irqsave(&local->irq_init_lock, flags); +  	ret = pcmcia_request_irq(link, prism2_interrupt);  	if (ret) -		goto failed; +		goto failed_unlock;  	/*  	 * This actually configures the PCMCIA socket -- setting up @@ -636,11 +643,13 @@ static int prism2_config(struct pcmcia_device *link)  	 */  	ret = pcmcia_request_configuration(link, &link->conf);  	if (ret) -		goto failed; +		goto failed_unlock;  	dev->irq = link->irq;  	dev->base_addr = link->io.BasePort1; +	spin_unlock_irqrestore(&local->irq_init_lock, flags); +  	/* Finally, report what we've done */  	printk(KERN_INFO "%s: index 0x%02x: ",  	       dev_info, link->conf.ConfigIndex); @@ -667,6 +676,8 @@ static int prism2_config(struct pcmcia_device *link)  	return ret; + failed_unlock: +	 spin_unlock_irqrestore(&local->irq_init_lock, flags);   failed:  	kfree(hw_priv);  	prism2_release((u_long)link); diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index d7073281942..2f999fc94f6 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -2618,17 +2618,20 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id)  	int events = 0;  	u16 ev; +	iface = netdev_priv(dev); +	local = iface->local; +  	/* Detect early interrupt before driver is fully configued */ +	spin_lock(&local->irq_init_lock);  	if (!dev->base_addr) {  		if (net_ratelimit()) {  			printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n",  			       dev->name);  		} +		spin_unlock(&local->irq_init_lock);  		return IRQ_HANDLED;  	} - -	iface = netdev_priv(dev); -	local = iface->local; +	spin_unlock(&local->irq_init_lock);  	prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0); @@ -3147,6 +3150,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,  	spin_lock_init(&local->cmdlock);  	spin_lock_init(&local->baplock);  	spin_lock_init(&local->lock); +	spin_lock_init(&local->irq_init_lock);  	mutex_init(&local->rid_bap_mtx);  	if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES) diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 3d238917af0..1ba33be98b2 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -654,7 +654,7 @@ struct local_info {  	rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock  			      * when removing entries from the list.  			      * TX and RX paths can use read lock. */ -	spinlock_t cmdlock, baplock, lock; +	spinlock_t cmdlock, baplock, lock, irq_init_lock;  	struct mutex rid_bap_mtx;  	u16 infofid; /* MAC buffer id for info frame */  	/* txfid, intransmitfid, next_txtid, and next_alloc are protected by diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 068f7f8435c..c44a303e62e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2852,6 +2852,7 @@ static struct iwl_lib_ops iwl3945_lib = {  	.isr = iwl_isr_legacy,  	.config_ap = iwl3945_config_ap,  	.manage_ibss_station = iwl3945_manage_ibss_station, +	.recover_from_tx_stall = iwl_bg_monitor_recover,  	.check_plcp_health = iwl3945_good_plcp_health,  	.debugfs_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 44ef5d93bef..01658cf82d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -212,11 +212,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)  static void iwlagn_rts_tx_cmd_flag(struct ieee80211_tx_info *info,  			__le32 *tx_flags)  { -	if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || -	    (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) -		*tx_flags |= TX_CMD_FLG_RTS_CTS_MSK; -	else -		*tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK; +	*tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;  }  /* Calc max signal level (dBm) among 3 possible receivers */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 1004cfc403b..0f292a210ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1119,10 +1119,9 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,  					   struct iwl_scan_channel *scan_ch)  {  	const struct ieee80211_supported_band *sband; -	const struct iwl_channel_info *ch_info;  	u16 passive_dwell = 0;  	u16 active_dwell = 0; -	int i, added = 0; +	int added = 0;  	u16 channel = 0;  	sband = iwl_get_hw_mode(priv, band); @@ -1137,32 +1136,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,  	if (passive_dwell <= active_dwell)  		passive_dwell = active_dwell + 1; -	/* only scan single channel, good enough to reset the RF */ -	/* pick the first valid not in-use channel */ -	if (band == IEEE80211_BAND_5GHZ) { -		for (i = 14; i < priv->channel_count; i++) { -			if (priv->channel_info[i].channel != -			    le16_to_cpu(priv->staging_rxon.channel)) { -				channel = priv->channel_info[i].channel; -				ch_info = iwl_get_channel_info(priv, -					band, channel); -				if (is_channel_valid(ch_info)) -					break; -			} -		} -	} else { -		for (i = 0; i < 14; i++) { -			if (priv->channel_info[i].channel != -			    le16_to_cpu(priv->staging_rxon.channel)) { -					channel = -						priv->channel_info[i].channel; -					ch_info = iwl_get_channel_info(priv, -						band, channel); -					if (is_channel_valid(ch_info)) -						break; -			} -		} -	} +	channel = iwl_get_single_channel_number(priv, band);  	if (channel) {  		scan_ch->channel = cpu_to_le16(channel);  		scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c402bfc83f3..7d614c4d3c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1125,6 +1125,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)  	struct ieee80211_sta *sta;  	struct iwl_station_priv *sta_priv; +	rcu_read_lock();  	sta = ieee80211_find_sta(priv->vif, hdr->addr1);  	if (sta) {  		sta_priv = (void *)sta->drv_priv; @@ -1133,6 +1134,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)  		    atomic_dec_return(&sta_priv->pending_frames) == 0)  			ieee80211_sta_block_awake(priv->hw, sta, false);  	} +	rcu_read_unlock();  	ieee80211_tx_status_irqsafe(priv->hw, skb);  } @@ -1297,6 +1299,11 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,  	sta_id = ba_resp->sta_id;  	tid = ba_resp->tid;  	agg = &priv->stations[sta_id].tid[tid].agg; +	if (unlikely(agg->txq_id != scd_flow)) { +		IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n", +			scd_flow, agg->txq_id); +		return; +	}  	/* Find index just before block-ack window */  	index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index aef4f71f198..24aff654fa9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1484,6 +1484,156 @@ bool iwl_good_ack_health(struct iwl_priv *priv,  } +/***************************************************************************** + * + * sysfs attributes + * + *****************************************************************************/ + +#ifdef CONFIG_IWLWIFI_DEBUG + +/* + * The following adds a new attribute to the sysfs representation + * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/) + * used for controlling the debug level. + * + * See the level definitions in iwl for details. + * + * The debug_level being managed using sysfs below is a per device debug + * level that is used instead of the global debug level if it (the per + * device debug level) is set. + */ +static ssize_t show_debug_level(struct device *d, +				struct device_attribute *attr, char *buf) +{ +	struct iwl_priv *priv = dev_get_drvdata(d); +	return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); +} +static ssize_t store_debug_level(struct device *d, +				struct device_attribute *attr, +				 const char *buf, size_t count) +{ +	struct iwl_priv *priv = dev_get_drvdata(d); +	unsigned long val; +	int ret; + +	ret = strict_strtoul(buf, 0, &val); +	if (ret) +		IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); +	else { +		priv->debug_level = val; +		if (iwl_alloc_traffic_mem(priv)) +			IWL_ERR(priv, +				"Not enough memory to generate traffic log\n"); +	} +	return strnlen(buf, count); +} + +static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, +			show_debug_level, store_debug_level); + + +#endif /* CONFIG_IWLWIFI_DEBUG */ + + +static ssize_t show_temperature(struct device *d, +				struct device_attribute *attr, char *buf) +{ +	struct iwl_priv *priv = dev_get_drvdata(d); + +	if (!iwl_is_alive(priv)) +		return -EAGAIN; + +	return sprintf(buf, "%d\n", priv->temperature); +} + +static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); + +static ssize_t show_tx_power(struct device *d, +			     struct device_attribute *attr, char *buf) +{ +	struct iwl_priv *priv = dev_get_drvdata(d); + +	if (!iwl_is_ready_rf(priv)) +		return sprintf(buf, "off\n"); +	else +		return sprintf(buf, "%d\n", priv->tx_power_user_lmt); +} + +static ssize_t store_tx_power(struct device *d, +			      struct device_attribute *attr, +			      const char *buf, size_t count) +{ +	struct iwl_priv *priv = dev_get_drvdata(d); +	unsigned long val; +	int ret; + +	ret = strict_strtoul(buf, 10, &val); +	if (ret) +		IWL_INFO(priv, "%s is not in decimal form.\n", buf); +	else { +		ret = iwl_set_tx_power(priv, val, false); +		if (ret) +			IWL_ERR(priv, "failed setting tx power (0x%d).\n", +				ret); +		else +			ret = count; +	} +	return ret; +} + +static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); + +static ssize_t show_rts_ht_protection(struct device *d, +			     struct device_attribute *attr, char *buf) +{ +	struct iwl_priv *priv = dev_get_drvdata(d); + +	return sprintf(buf, "%s\n", +		priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self"); +} + +static ssize_t store_rts_ht_protection(struct device *d, +			      struct device_attribute *attr, +			      const char *buf, size_t count) +{ +	struct iwl_priv *priv = dev_get_drvdata(d); +	unsigned long val; +	int ret; + +	ret = strict_strtoul(buf, 10, &val); +	if (ret) +		IWL_INFO(priv, "Input is not in decimal form.\n"); +	else { +		if (!iwl_is_associated(priv)) +			priv->cfg->use_rts_for_ht = val ? true : false; +		else +			IWL_ERR(priv, "Sta associated with AP - " +				"Change protection mechanism is not allowed\n"); +		ret = count; +	} +	return ret; +} + +static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO, +			show_rts_ht_protection, store_rts_ht_protection); + + +static struct attribute *iwl_sysfs_entries[] = { +	&dev_attr_temperature.attr, +	&dev_attr_tx_power.attr, +	&dev_attr_rts_ht_protection.attr, +#ifdef CONFIG_IWLWIFI_DEBUG +	&dev_attr_debug_level.attr, +#endif +	NULL +}; + +static struct attribute_group iwl_attribute_group = { +	.name = NULL,		/* put in device directory */ +	.attrs = iwl_sysfs_entries, +}; +  /******************************************************************************   *   * uCode download functions @@ -1965,6 +2115,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)  	if (err)  		IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); +	err = sysfs_create_group(&priv->pci_dev->dev.kobj, +					&iwl_attribute_group); +	if (err) { +		IWL_ERR(priv, "failed to create sysfs device attributes\n"); +		goto out_unbind; +	} +  	/* We have our copies now, allow OS release its copies */  	release_firmware(ucode_raw);  	complete(&priv->_agn.firmware_loading_complete); @@ -3234,10 +3391,12 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,  	int ret;  	u8 sta_id; -	sta_priv->common.sta_id = IWL_INVALID_STATION; -  	IWL_DEBUG_INFO(priv, "received request to add station %pM\n",  			sta->addr); +	mutex_lock(&priv->mutex); +	IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", +			sta->addr); +	sta_priv->common.sta_id = IWL_INVALID_STATION;  	atomic_set(&sta_priv->pending_frames, 0);  	if (vif->type == NL80211_IFTYPE_AP) @@ -3249,6 +3408,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,  		IWL_ERR(priv, "Unable to add station %pM (%d)\n",  			sta->addr, ret);  		/* Should we return success if return code is EEXIST ? */ +		mutex_unlock(&priv->mutex);  		return ret;  	} @@ -3258,147 +3418,13 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,  	IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",  		       sta->addr);  	iwl_rs_rate_init(priv, sta, sta_id); +	mutex_unlock(&priv->mutex);  	return 0;  }  /*****************************************************************************   * - * sysfs attributes - * - *****************************************************************************/ - -#ifdef CONFIG_IWLWIFI_DEBUG - -/* - * The following adds a new attribute to the sysfs representation - * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/) - * used for controlling the debug level. - * - * See the level definitions in iwl for details. - * - * The debug_level being managed using sysfs below is a per device debug - * level that is used instead of the global debug level if it (the per - * device debug level) is set. - */ -static ssize_t show_debug_level(struct device *d, -				struct device_attribute *attr, char *buf) -{ -	struct iwl_priv *priv = dev_get_drvdata(d); -	return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); -} -static ssize_t store_debug_level(struct device *d, -				struct device_attribute *attr, -				 const char *buf, size_t count) -{ -	struct iwl_priv *priv = dev_get_drvdata(d); -	unsigned long val; -	int ret; - -	ret = strict_strtoul(buf, 0, &val); -	if (ret) -		IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); -	else { -		priv->debug_level = val; -		if (iwl_alloc_traffic_mem(priv)) -			IWL_ERR(priv, -				"Not enough memory to generate traffic log\n"); -	} -	return strnlen(buf, count); -} - -static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, -			show_debug_level, store_debug_level); - - -#endif /* CONFIG_IWLWIFI_DEBUG */ - - -static ssize_t show_temperature(struct device *d, -				struct device_attribute *attr, char *buf) -{ -	struct iwl_priv *priv = dev_get_drvdata(d); - -	if (!iwl_is_alive(priv)) -		return -EAGAIN; - -	return sprintf(buf, "%d\n", priv->temperature); -} - -static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); - -static ssize_t show_tx_power(struct device *d, -			     struct device_attribute *attr, char *buf) -{ -	struct iwl_priv *priv = dev_get_drvdata(d); - -	if (!iwl_is_ready_rf(priv)) -		return sprintf(buf, "off\n"); -	else -		return sprintf(buf, "%d\n", priv->tx_power_user_lmt); -} - -static ssize_t store_tx_power(struct device *d, -			      struct device_attribute *attr, -			      const char *buf, size_t count) -{ -	struct iwl_priv *priv = dev_get_drvdata(d); -	unsigned long val; -	int ret; - -	ret = strict_strtoul(buf, 10, &val); -	if (ret) -		IWL_INFO(priv, "%s is not in decimal form.\n", buf); -	else { -		ret = iwl_set_tx_power(priv, val, false); -		if (ret) -			IWL_ERR(priv, "failed setting tx power (0x%d).\n", -				ret); -		else -			ret = count; -	} -	return ret; -} - -static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); - -static ssize_t show_rts_ht_protection(struct device *d, -			     struct device_attribute *attr, char *buf) -{ -	struct iwl_priv *priv = dev_get_drvdata(d); - -	return sprintf(buf, "%s\n", -		priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self"); -} - -static ssize_t store_rts_ht_protection(struct device *d, -			      struct device_attribute *attr, -			      const char *buf, size_t count) -{ -	struct iwl_priv *priv = dev_get_drvdata(d); -	unsigned long val; -	int ret; - -	ret = strict_strtoul(buf, 10, &val); -	if (ret) -		IWL_INFO(priv, "Input is not in decimal form.\n"); -	else { -		if (!iwl_is_associated(priv)) -			priv->cfg->use_rts_for_ht = val ? true : false; -		else -			IWL_ERR(priv, "Sta associated with AP - " -				"Change protection mechanism is not allowed\n"); -		ret = count; -	} -	return ret; -} - -static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO, -			show_rts_ht_protection, store_rts_ht_protection); - - -/***************************************************************************** - *   * driver setup and teardown   *   *****************************************************************************/ @@ -3550,21 +3576,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv)  	kfree(priv->scan_cmd);  } -static struct attribute *iwl_sysfs_entries[] = { -	&dev_attr_temperature.attr, -	&dev_attr_tx_power.attr, -	&dev_attr_rts_ht_protection.attr, -#ifdef CONFIG_IWLWIFI_DEBUG -	&dev_attr_debug_level.attr, -#endif -	NULL -}; - -static struct attribute_group iwl_attribute_group = { -	.name = NULL,		/* put in device directory */ -	.attrs = iwl_sysfs_entries, -}; -  static struct ieee80211_ops iwl_hw_ops = {  	.tx = iwl_mac_tx,  	.start = iwl_mac_start, @@ -3750,11 +3761,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);  		goto out_disable_msi;  	} -	err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group); -	if (err) { -		IWL_ERR(priv, "failed to create sysfs device attributes\n"); -		goto out_free_irq; -	}  	iwl_setup_deferred_work(priv);  	iwl_setup_rx_handlers(priv); @@ -3788,15 +3794,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	err = iwl_request_firmware(priv, true);  	if (err) -		goto out_remove_sysfs; +		goto out_destroy_workqueue;  	return 0; - out_remove_sysfs: + out_destroy_workqueue:  	destroy_workqueue(priv->workqueue);  	priv->workqueue = NULL; -	sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); - out_free_irq:  	free_irq(priv->pci_dev->irq, priv);  	iwl_free_isr_ict(priv);   out_disable_msi: diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5a7eca8fb78..5bbc5298ef9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -854,6 +854,45 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)  }  EXPORT_SYMBOL(iwl_set_rxon_chain); +/* Return valid channel */ +u8 iwl_get_single_channel_number(struct iwl_priv *priv, +				  enum ieee80211_band band) +{ +	const struct iwl_channel_info *ch_info; +	int i; +	u8 channel = 0; + +	/* only scan single channel, good enough to reset the RF */ +	/* pick the first valid not in-use channel */ +	if (band == IEEE80211_BAND_5GHZ) { +		for (i = 14; i < priv->channel_count; i++) { +			if (priv->channel_info[i].channel != +			    le16_to_cpu(priv->staging_rxon.channel)) { +				channel = priv->channel_info[i].channel; +				ch_info = iwl_get_channel_info(priv, +					band, channel); +				if (is_channel_valid(ch_info)) +					break; +			} +		} +	} else { +		for (i = 0; i < 14; i++) { +			if (priv->channel_info[i].channel != +			    le16_to_cpu(priv->staging_rxon.channel)) { +					channel = +						priv->channel_info[i].channel; +					ch_info = iwl_get_channel_info(priv, +						band, channel); +					if (is_channel_valid(ch_info)) +						break; +			} +		} +	} + +	return channel; +} +EXPORT_SYMBOL(iwl_get_single_channel_number); +  /**   * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON   * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz @@ -1275,7 +1314,6 @@ void iwl_configure_filter(struct ieee80211_hw *hw,  			changed_flags, *total_flags);  	CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); -	CHK(FIF_ALLMULTI, RXON_FILTER_ACCEPT_GRP_MSK);  	CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);  	CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); @@ -1290,6 +1328,12 @@ void iwl_configure_filter(struct ieee80211_hw *hw,  	mutex_unlock(&priv->mutex); +	/* +	 * Receiving all multicast frames is always enabled by the +	 * default flags setup in iwl_connection_init_rx_config() +	 * since we currently do not support programming multicast +	 * filters into the device. +	 */  	*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |  			FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;  } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7e5a5ba41fd..31775bd9c36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -343,6 +343,8 @@ int iwl_check_rxon_cmd(struct iwl_priv *priv);  int iwl_full_rxon_required(struct iwl_priv *priv);  void iwl_set_rxon_chain(struct iwl_priv *priv);  int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); +u8 iwl_get_single_channel_number(struct iwl_priv *priv, +				  enum ieee80211_band band);  void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);  u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,  			 struct ieee80211_sta_ht_cap *sta_ht_inf); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 5d3f51ff2f0..386c5f96eff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -491,6 +491,7 @@ void iwl_bg_abort_scan(struct work_struct *work)  	mutex_lock(&priv->mutex); +	cancel_delayed_work_sync(&priv->scan_check);  	set_bit(STATUS_SCAN_ABORTING, &priv->status);  	iwl_send_scan_abort(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 83a26361a9b..c27c13fbb1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1373,10 +1373,14 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,  	IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",  			sta->addr); +	mutex_lock(&priv->mutex); +	IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", +			sta->addr);  	ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);  	if (ret)  		IWL_ERR(priv, "Error removing station %pM\n",  			sta->addr); +	mutex_unlock(&priv->mutex);  	return ret;  }  EXPORT_SYMBOL(iwl_mac_sta_remove); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 3e5bffb6034..a27872de410 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1844,6 +1844,49 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)  #endif  } +static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, +					       struct ieee80211_vif *vif, +					       enum ieee80211_band band, +					       struct iwl3945_scan_channel *scan_ch) +{ +	const struct ieee80211_supported_band *sband; +	u16 passive_dwell = 0; +	u16 active_dwell = 0; +	int added = 0; +	u8 channel = 0; + +	sband = iwl_get_hw_mode(priv, band); +	if (!sband) { +		IWL_ERR(priv, "invalid band\n"); +		return added; +	} + +	active_dwell = iwl_get_active_dwell_time(priv, band, 0); +	passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); + +	if (passive_dwell <= active_dwell) +		passive_dwell = active_dwell + 1; + + +	channel = iwl_get_single_channel_number(priv, band); + +	if (channel) { +		scan_ch->channel = channel; +		scan_ch->type = 0;	/* passive */ +		scan_ch->active_dwell = cpu_to_le16(active_dwell); +		scan_ch->passive_dwell = cpu_to_le16(passive_dwell); +		/* Set txpower levels to defaults */ +		scan_ch->tpc.dsp_atten = 110; +		if (band == IEEE80211_BAND_5GHZ) +			scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; +		else +			scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); +		added++; +	} else +		IWL_ERR(priv, "no valid channel found\n"); +	return added; +} +  static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,  					 enum ieee80211_band band,  				     u8 is_active, u8 n_probes, @@ -2992,9 +3035,16 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)  	/* select Rx antennas */  	scan->flags |= iwl3945_get_antenna_flags(priv); -	scan->channel_count = -		iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, -			(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); +	if (priv->is_internal_short_scan) { +		scan->channel_count = +			iwl3945_get_single_channel_for_scan(priv, vif, band, +				(void *)&scan->data[le16_to_cpu( +				scan->tx_cmd.len)]); +	} else { +		scan->channel_count = +			iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, +				(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); +	}  	if (scan->channel_count == 0) {  		IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); @@ -3387,10 +3437,13 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,  	bool is_ap = vif->type == NL80211_IFTYPE_STATION;  	u8 sta_id; -	sta_priv->common.sta_id = IWL_INVALID_STATION; -  	IWL_DEBUG_INFO(priv, "received request to add station %pM\n",  			sta->addr); +	mutex_lock(&priv->mutex); +	IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", +			sta->addr); +	sta_priv->common.sta_id = IWL_INVALID_STATION; +  	ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,  				     &sta_id); @@ -3398,6 +3451,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,  		IWL_ERR(priv, "Unable to add station %pM (%d)\n",  			sta->addr, ret);  		/* Should we return success if return code is EEXIST ? */ +		mutex_unlock(&priv->mutex);  		return ret;  	} @@ -3407,6 +3461,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,  	IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",  		       sta->addr);  	iwl3945_rs_rate_init(priv, sta, sta_id); +	mutex_unlock(&priv->mutex);  	return 0;  } diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index a115bfa9513..7a377f5b766 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -329,9 +329,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,  	/* create the exported radio header */  	/* radiotap header */ -	radiotap_hdr.hdr.it_version = 0; -	/* XXX must check this value for pad */ -	radiotap_hdr.hdr.it_pad = 0; +	memset(&radiotap_hdr, 0, sizeof(radiotap_hdr)); +	/* XXX must check radiotap_hdr.hdr.it_pad for pad */  	radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));  	radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);  	radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate); diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 6a04c2157f7..817fffc0de4 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -549,7 +549,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)  	prxpd = (struct rxpd *) skb->data; -	stats.flag = 0; +	memset(&stats, 0, sizeof(stats));  	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))  		stats.flag |= RX_FLAG_FAILED_FCS_CRC;  	stats.freq = priv->cur_freq; diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c index 9bcee10c930..4a0a0e5265c 100644 --- a/drivers/net/wireless/orinoco/airport.c +++ b/drivers/net/wireless/orinoco/airport.c @@ -239,8 +239,11 @@ static struct of_device_id airport_match[] =  MODULE_DEVICE_TABLE(of, airport_match);  static struct macio_driver airport_driver = { -	.name 		= DRIVER_NAME, -	.match_table	= airport_match, +	.driver = { +		.name 		= DRIVER_NAME, +		.owner		= THIS_MODULE, +		.of_match_table	= airport_match, +	},  	.probe		= airport_attach,  	.remove		= airport_detach,  	.suspend	= airport_suspend, diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 07c4528f6e6..a5ea89cde8c 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -41,6 +41,8 @@ static DEFINE_PCI_DEVICE_TABLE(p54p_table) = {  	{ PCI_DEVICE(0x1260, 0x3877) },  	/* Intersil PRISM Javelin/Xbow Wireless LAN adapter */  	{ PCI_DEVICE(0x1260, 0x3886) }, +	/* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */ +	{ PCI_DEVICE(0x1260, 0xffff) },  	{ },  }; diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index d5b197b4d5b..73073259f50 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -80,6 +80,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {  	{USB_DEVICE(0x1413, 0x5400)},   /* Telsey 802.11g USB2.0 Adapter */  	{USB_DEVICE(0x1435, 0x0427)},	/* Inventel UR054G */  	{USB_DEVICE(0x2001, 0x3704)},	/* DLink DWL-G122 rev A2 */ +	{USB_DEVICE(0x413c, 0x5513)},	/* Dell WLA3310 USB Wireless Adapter */  	{USB_DEVICE(0x413c, 0x8102)},	/* Spinnaker DUT */  	{USB_DEVICE(0x413c, 0x8104)},	/* Cohiba Proto board */  	{} diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 699161327d6..0f8b84b7224 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -413,7 +413,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,  	 */  	rt2x00_desc_read(txi, 0, &word);  	rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, -			   skb->len - TXINFO_DESC_SIZE); +			   skb->len + TXWI_DESC_SIZE);  	rt2x00_set_field32(&word, TXINFO_W0_WIV,  			   !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));  	rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index d234285c2c8..c561332e700 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c @@ -259,6 +259,7 @@ disable:  	sdio_disable_func(func);  release:  	sdio_release_host(func); +	wl1251_free_hw(wl);  	return ret;  }  |