diff options
Diffstat (limited to 'drivers/net')
74 files changed, 609 insertions, 394 deletions
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 25197b698dd..b8b4c7ba884 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev)  	BUGLVL(D_NORMAL) printk(VERSION);  	BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n"); -	BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n", +	BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n",  	       dev->dev_addr[0], dev->mem_start, dev->irq);  	if (dev->mem_start <= 0 || dev->irq <= 0) { -		BUGMSG(D_NORMAL, "No autoprobe for RIM I; you " +		BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you "  		       "must specify the shmem and irq!\n");  		return -ENODEV;  	}  	if (dev->dev_addr[0] == 0) { -		BUGMSG(D_NORMAL, "You need to specify your card's station " +		BUGLVL(D_NORMAL) printk("You need to specify your card's station "  		       "ID!\n");  		return -ENODEV;  	} @@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev)  	 * will be taken.  	 */  	if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { -		BUGMSG(D_NORMAL, "Card memory already allocated\n"); +		BUGLVL(D_NORMAL) printk("Card memory already allocated\n");  		return -ENODEV;  	}  	return arcrimi_found(dev); diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 9a66e2a910a..9c1c8cd5223 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -744,14 +744,14 @@ static void cfhsi_wake_up(struct work_struct *work)  		size_t fifo_occupancy = 0;  		/* Wakeup timeout */ -		dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", +		dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n",  			__func__);  		/* Check FIFO to check if modem has sent something. */  		WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,  					&fifo_occupancy)); -		dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", +		dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",  				__func__, (unsigned) fifo_occupancy);  		/* Check if we misssed the interrupt. */ @@ -1210,7 +1210,7 @@ int cfhsi_probe(struct platform_device *pdev)  static void cfhsi_shutdown(struct cfhsi *cfhsi)  { -	u8 *tx_buf, *rx_buf; +	u8 *tx_buf, *rx_buf, *flip_buf;  	/* Stop TXing */  	netif_tx_stop_all_queues(cfhsi->ndev); @@ -1234,7 +1234,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)  	/* Store bufferes: will be freed later. */  	tx_buf = cfhsi->tx_buf;  	rx_buf = cfhsi->rx_buf; - +	flip_buf = cfhsi->rx_flip_buf;  	/* Flush transmit queues. */  	cfhsi_abort_tx(cfhsi); @@ -1247,6 +1247,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)  	/* Free buffers. */  	kfree(tx_buf);  	kfree(rx_buf); +	kfree(flip_buf);  }  int cfhsi_remove(struct platform_device *pdev) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 5234586dff1..629c4ba5d49 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -875,6 +875,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)  					    PCAN_USBPRO_INFO_FW,  					    &fi, sizeof(fi));  		if (err) { +			kfree(usb_if);  			dev_err(dev->netdev->dev.parent,  				"unable to read %s firmware info (err %d)\n",  				pcan_usb_pro.name, err); @@ -885,6 +886,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)  					    PCAN_USBPRO_INFO_BL,  					    &bi, sizeof(bi));  		if (err) { +			kfree(usb_if);  			dev_err(dev->netdev->dev.parent,  				"unable to read %s bootloader info (err %d)\n",  				pcan_usb_pro.name, err); diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index d5c6d92f1ee..442d91a2747 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -107,14 +107,14 @@ static int dummy_dev_init(struct net_device *dev)  	return 0;  } -static void dummy_dev_free(struct net_device *dev) +static void dummy_dev_uninit(struct net_device *dev)  {  	free_percpu(dev->dstats); -	free_netdev(dev);  }  static const struct net_device_ops dummy_netdev_ops = {  	.ndo_init		= dummy_dev_init, +	.ndo_uninit		= dummy_dev_uninit,  	.ndo_start_xmit		= dummy_xmit,  	.ndo_validate_addr	= eth_validate_addr,  	.ndo_set_rx_mode	= set_multicast_list, @@ -128,7 +128,7 @@ static void dummy_setup(struct net_device *dev)  	/* Initialize the device structure. */  	dev->netdev_ops = &dummy_netdev_ops; -	dev->destructor = dummy_dev_free; +	dev->destructor = free_netdev;  	/* Fill in device structure with ethernet-generic values. */  	dev->tx_queue_len = 0; diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 40ac4143654..c926857e820 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data)  					"pcie phy link down %x\n", status);  			if (netif_running(adapter->netdev)) {	/* reset MAC */  				iowrite32(0, adapter->hw.hw_addr + REG_IMR); -				schedule_work(&adapter->pcie_dma_to_rst_task); +				schedule_work(&adapter->reset_dev_task);  				return IRQ_HANDLED;  			}  		} @@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data)  					"pcie DMA r/w error (status = 0x%x)\n",  					status);  			iowrite32(0, adapter->hw.hw_addr + REG_IMR); -			schedule_work(&adapter->pcie_dma_to_rst_task); +			schedule_work(&adapter->reset_dev_task);  			return IRQ_HANDLED;  		} @@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter)  	atl1_clean_rx_ring(adapter);  } -static void atl1_tx_timeout_task(struct work_struct *work) +static void atl1_reset_dev_task(struct work_struct *work)  {  	struct atl1_adapter *adapter = -		container_of(work, struct atl1_adapter, tx_timeout_task); +		container_of(work, struct atl1_adapter, reset_dev_task);  	struct net_device *netdev = adapter->netdev;  	netif_device_detach(netdev); @@ -3038,12 +3038,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,  		    (unsigned long)adapter);  	adapter->phy_timer_pending = false; -	INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); +	INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);  	INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task); -	INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); -  	err = register_netdev(netdev);  	if (err)  		goto err_common; diff --git a/drivers/net/ethernet/atheros/atlx/atl1.h b/drivers/net/ethernet/atheros/atlx/atl1.h index 109d6da8be9..e04bf4d71e4 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.h +++ b/drivers/net/ethernet/atheros/atlx/atl1.h @@ -758,9 +758,8 @@ struct atl1_adapter {  	u16 link_speed;  	u16 link_duplex;  	spinlock_t lock; -	struct work_struct tx_timeout_task; +	struct work_struct reset_dev_task;  	struct work_struct link_chg_task; -	struct work_struct pcie_dma_to_rst_task;  	struct timer_list phy_config_timer;  	bool phy_timer_pending; diff --git a/drivers/net/ethernet/atheros/atlx/atlx.c b/drivers/net/ethernet/atheros/atlx/atlx.c index 3cd8837236d..c9e9dc57986 100644 --- a/drivers/net/ethernet/atheros/atlx/atlx.c +++ b/drivers/net/ethernet/atheros/atlx/atlx.c @@ -194,7 +194,7 @@ static void atlx_tx_timeout(struct net_device *netdev)  {  	struct atlx_adapter *adapter = netdev_priv(netdev);  	/* Do the reset outside of interrupt context */ -	schedule_work(&adapter->tx_timeout_task); +	schedule_work(&adapter->reset_dev_task);  }  /* diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index ad95324dc04..64392ec410a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -942,6 +942,12 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,  	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :  		DCBX_E3B0_MAX_NUM_COS_PORT0; +	if (pri >= max_num_of_cos) { +		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " +		   "parameter Illegal strict priority\n"); +	    return -EINVAL; +	} +  	if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {  		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "  				   "parameter There can't be two COS's with " @@ -949,12 +955,6 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,  		return -EINVAL;  	} -	if (pri > max_num_of_cos) { -		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " -		   "parameter Illegal strict priority\n"); -	    return -EINVAL; -	} -  	sp_pri_to_cos[pri] = cos_entry;  	return 0; diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 062ac333fde..ceeab8e852e 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -879,8 +879,13 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)  		if (sblk->status & SD_STATUS_LINK_CHG)  			work_exists = 1;  	} -	/* check for RX/TX work to do */ -	if (sblk->idx[0].tx_consumer != tnapi->tx_cons || + +	/* check for TX work to do */ +	if (sblk->idx[0].tx_consumer != tnapi->tx_cons) +		work_exists = 1; + +	/* check for RX work to do */ +	if (tnapi->rx_rcb_prod_idx &&  	    *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)  		work_exists = 1; @@ -6124,6 +6129,9 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)  			return work_done;  	} +	if (!tnapi->rx_rcb_prod_idx) +		return work_done; +  	/* run RX thread, within the bounds set by NAPI.  	 * All RX "locking" is done by ensuring outside  	 * code synchronizes with tg3->napi.poll() @@ -7567,6 +7575,12 @@ static int tg3_alloc_consistent(struct tg3 *tp)  		 */  		switch (i) {  		default: +			if (tg3_flag(tp, ENABLE_RSS)) { +				tnapi->rx_rcb_prod_idx = NULL; +				break; +			} +			/* Fall through */ +		case 1:  			tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;  			break;  		case 2: diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 63bfdd10bd6..abb6ce7c1b7 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -1150,6 +1150,48 @@ release_tpsram:  }  /** + * t3_synchronize_rx - wait for current Rx processing on a port to complete + * @adap: the adapter + * @p: the port + * + * Ensures that current Rx processing on any of the queues associated with + * the given port completes before returning.  We do this by acquiring and + * releasing the locks of the response queues associated with the port. + */ +static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) +{ +	int i; + +	for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { +		struct sge_rspq *q = &adap->sge.qs[i].rspq; + +		spin_lock_irq(&q->lock); +		spin_unlock_irq(&q->lock); +	} +} + +static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) +{ +	struct port_info *pi = netdev_priv(dev); +	struct adapter *adapter = pi->adapter; + +	if (adapter->params.rev > 0) { +		t3_set_vlan_accel(adapter, 1 << pi->port_id, +				  features & NETIF_F_HW_VLAN_RX); +	} else { +		/* single control for all ports */ +		unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; + +		for_each_port(adapter, i) +			have_vlans |= +				adapter->port[i]->features & NETIF_F_HW_VLAN_RX; + +		t3_set_vlan_accel(adapter, 1, have_vlans); +	} +	t3_synchronize_rx(adapter, pi); +} + +/**   *	cxgb_up - enable the adapter   *	@adapter: adapter being enabled   * @@ -1161,7 +1203,7 @@ release_tpsram:   */  static int cxgb_up(struct adapter *adap)  { -	int err; +	int i, err;  	if (!(adap->flags & FULL_INIT_DONE)) {  		err = t3_check_fw_version(adap); @@ -1198,6 +1240,9 @@ static int cxgb_up(struct adapter *adap)  		if (err)  			goto out; +		for_each_port(adap, i) +			cxgb_vlan_mode(adap->port[i], adap->port[i]->features); +  		setup_rss(adap);  		if (!(adap->flags & NAPI_INIT))  			init_napi(adap); @@ -2508,48 +2553,6 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p)  	return 0;  } -/** - * t3_synchronize_rx - wait for current Rx processing on a port to complete - * @adap: the adapter - * @p: the port - * - * Ensures that current Rx processing on any of the queues associated with - * the given port completes before returning.  We do this by acquiring and - * releasing the locks of the response queues associated with the port. - */ -static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) -{ -	int i; - -	for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { -		struct sge_rspq *q = &adap->sge.qs[i].rspq; - -		spin_lock_irq(&q->lock); -		spin_unlock_irq(&q->lock); -	} -} - -static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) -{ -	struct port_info *pi = netdev_priv(dev); -	struct adapter *adapter = pi->adapter; - -	if (adapter->params.rev > 0) { -		t3_set_vlan_accel(adapter, 1 << pi->port_id, -				  features & NETIF_F_HW_VLAN_RX); -	} else { -		/* single control for all ports */ -		unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; - -		for_each_port(adapter, i) -			have_vlans |= -				adapter->port[i]->features & NETIF_F_HW_VLAN_RX; - -		t3_set_vlan_accel(adapter, 1, have_vlans); -	} -	t3_synchronize_rx(adapter, pi); -} -  static netdev_features_t cxgb_fix_features(struct net_device *dev,  	netdev_features_t features)  { @@ -3353,9 +3356,6 @@ static int __devinit init_one(struct pci_dev *pdev,  	err = sysfs_create_group(&adapter->port[0]->dev.kobj,  				 &cxgb3_attr_group); -	for_each_port(adapter, i) -		cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); -  	print_port_info(adapter, ai);  	return 0; diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c index b2dc2c81a14..2e09edb9cdf 100644 --- a/drivers/net/ethernet/dlink/dl2k.c +++ b/drivers/net/ethernet/dlink/dl2k.c @@ -1259,55 +1259,21 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)  {  	int phy_addr;  	struct netdev_private *np = netdev_priv(dev); -	struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru; - -	struct netdev_desc *desc; -	int i; +	struct mii_ioctl_data *miidata = if_mii(rq);  	phy_addr = np->phy_addr;  	switch (cmd) { -	case SIOCDEVPRIVATE: -		break; - -	case SIOCDEVPRIVATE + 1: -		miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num); +	case SIOCGMIIPHY: +		miidata->phy_id = phy_addr;  		break; -	case SIOCDEVPRIVATE + 2: -		mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value); +	case SIOCGMIIREG: +		miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);  		break; -	case SIOCDEVPRIVATE + 3: -		break; -	case SIOCDEVPRIVATE + 4: -		break; -	case SIOCDEVPRIVATE + 5: -		netif_stop_queue (dev); +	case SIOCSMIIREG: +		if (!capable(CAP_NET_ADMIN)) +			return -EPERM; +		mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);  		break; -	case SIOCDEVPRIVATE + 6: -		netif_wake_queue (dev); -		break; -	case SIOCDEVPRIVATE + 7: -		printk -		    ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n", -		     netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx, -		     np->old_rx); -		break; -	case SIOCDEVPRIVATE + 8: -		printk("TX ring:\n"); -		for (i = 0; i < TX_RING_SIZE; i++) { -			desc = &np->tx_ring[i]; -			printk -			    ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x", -			     i, -			     (u32) (np->tx_ring_dma + i * sizeof (*desc)), -			     (u32)le64_to_cpu(desc->next_desc), -			     (u32)le64_to_cpu(desc->status), -			     (u32)(le64_to_cpu(desc->fraginfo) >> 32), -			     (u32)le64_to_cpu(desc->fraginfo)); -			printk ("\n"); -		} -		printk ("\n"); -		break; -  	default:  		return -EOPNOTSUPP;  	} diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h index ba0adcafa55..30c2da3de54 100644 --- a/drivers/net/ethernet/dlink/dl2k.h +++ b/drivers/net/ethernet/dlink/dl2k.h @@ -365,13 +365,6 @@ struct ioctl_data {  	char *data;  }; -struct mii_data { -	__u16 reserved; -	__u16 reg_num; -	__u16 in_value; -	__u16 out_value; -}; -  /* The Rx and Tx buffer descriptors. */  struct netdev_desc {  	__le64 next_desc; diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 17a46e76123..9ac14f80485 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -116,10 +116,10 @@ static struct ucc_geth_info ugeth_primary_info = {  	.maxGroupAddrInHash = 4,  	.maxIndAddrInHash = 4,  	.prel = 7, -	.maxFrameLength = 1518, +	.maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */  	.minFrameLength = 64, -	.maxD1Length = 1520, -	.maxD2Length = 1520, +	.maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */ +	.maxD2Length = 1520+16, /* Add extra bytes for VLANs etc. */  	.vlantype = 0x8100,  	.ecamptr = ((uint32_t) NULL),  	.eventRegMask = UCCE_OTHER, diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h index 2e395a2566b..f71b3e7b12d 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.h +++ b/drivers/net/ethernet/freescale/ucc_geth.h @@ -877,7 +877,7 @@ struct ucc_geth_hardware_statistics {  /* Driver definitions */  #define TX_BD_RING_LEN                          0x10 -#define RX_BD_RING_LEN                          0x10 +#define RX_BD_RING_LEN                          0x20  #define TX_RING_MOD_MASK(size)                  (size-1)  #define RX_RING_MOD_MASK(size)                  (size-1) diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 3516e17a399..c9069a28832 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -290,16 +290,18 @@ static void ehea_update_bcmc_registrations(void)  				arr[i].adh = adapter->handle;  				arr[i].port_id = port->logical_port_id; -				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | -						  EHEA_BCMC_MULTICAST | +				arr[i].reg_type = EHEA_BCMC_MULTICAST |  						  EHEA_BCMC_UNTAGGED; +				if (mc_entry->macaddr == 0) +					arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;  				arr[i++].macaddr = mc_entry->macaddr;  				arr[i].adh = adapter->handle;  				arr[i].port_id = port->logical_port_id; -				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | -						  EHEA_BCMC_MULTICAST | +				arr[i].reg_type = EHEA_BCMC_MULTICAST |  						  EHEA_BCMC_VLANID_ALL; +				if (mc_entry->macaddr == 0) +					arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;  				arr[i++].macaddr = mc_entry->macaddr;  				num_registrations -= 2;  			} @@ -1838,8 +1840,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,  	u64 hret;  	u8 reg_type; -	reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST -		 | EHEA_BCMC_UNTAGGED; +	reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED; +	if (mc_mac_addr == 0) +		reg_type |= EHEA_BCMC_SCOPE_ALL;  	hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,  				     port->logical_port_id, @@ -1847,8 +1850,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,  	if (hret)  		goto out; -	reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST -		 | EHEA_BCMC_VLANID_ALL; +	reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL; +	if (mc_mac_addr == 0) +		reg_type |= EHEA_BCMC_SCOPE_ALL;  	hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,  				     port->logical_port_id, @@ -1898,7 +1902,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)  				netdev_err(dev,  					   "failed enabling IFF_ALLMULTI\n");  		} -	} else +	} else {  		if (!enable) {  			/* Disable ALLMULTI */  			hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC); @@ -1908,6 +1912,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)  				netdev_err(dev,  					   "failed disabling IFF_ALLMULTI\n");  		} +	}  }  static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) @@ -1941,11 +1946,7 @@ static void ehea_set_multicast_list(struct net_device *dev)  	struct netdev_hw_addr *ha;  	int ret; -	if (port->promisc) { -		ehea_promiscuous(dev, 1); -		return; -	} -	ehea_promiscuous(dev, 0); +	ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC));  	if (dev->flags & IFF_ALLMULTI) {  		ehea_allmulti(dev, 1); @@ -2463,6 +2464,7 @@ static int ehea_down(struct net_device *dev)  		return 0;  	ehea_drop_multicast_list(dev); +	ehea_allmulti(dev, 0);  	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);  	ehea_free_interrupts(dev); @@ -3261,6 +3263,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,  	struct ehea_adapter *adapter;  	const u64 *adapter_handle;  	int ret; +	int i;  	if (!dev || !dev->dev.of_node) {  		pr_err("Invalid ibmebus device probed\n"); @@ -3314,17 +3317,9 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,  	tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,  		     (unsigned long)adapter); -	ret = ibmebus_request_irq(adapter->neq->attr.ist1, -				  ehea_interrupt_neq, IRQF_DISABLED, -				  "ehea_neq", adapter); -	if (ret) { -		dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); -		goto out_kill_eq; -	} -  	ret = ehea_create_device_sysfs(dev);  	if (ret) -		goto out_free_irq; +		goto out_kill_eq;  	ret = ehea_setup_ports(adapter);  	if (ret) { @@ -3332,15 +3327,28 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,  		goto out_rem_dev_sysfs;  	} +	ret = ibmebus_request_irq(adapter->neq->attr.ist1, +				  ehea_interrupt_neq, IRQF_DISABLED, +				  "ehea_neq", adapter); +	if (ret) { +		dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); +		goto out_shutdown_ports; +	} + +  	ret = 0;  	goto out; +out_shutdown_ports: +	for (i = 0; i < EHEA_MAX_PORTS; i++) +		if (adapter->port[i]) { +			ehea_shutdown_single_port(adapter->port[i]); +			adapter->port[i] = NULL; +		} +  out_rem_dev_sysfs:  	ehea_remove_device_sysfs(dev); -out_free_irq: -	ibmebus_free_irq(adapter->neq->attr.ist1, adapter); -  out_kill_eq:  	ehea_destroy_eq(adapter->neq); diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h index 52c456ec4d6..8364815c32f 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h +++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h @@ -450,7 +450,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,  			    void *cb_addr);  #define H_REGBCMC_PN            EHEA_BMASK_IBM(48, 63) -#define H_REGBCMC_REGTYPE       EHEA_BMASK_IBM(61, 63) +#define H_REGBCMC_REGTYPE       EHEA_BMASK_IBM(60, 63)  #define H_REGBCMC_MACADDR       EHEA_BMASK_IBM(16, 63)  #define H_REGBCMC_VLANID        EHEA_BMASK_IBM(52, 63) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 64c76443a7a..b461c24945e 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1310,10 +1310,6 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)  		if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)  			oem_reg |= HV_OEM_BITS_LPLU; - -		/* Set Restart auto-neg to activate the bits */ -		if (!hw->phy.ops.check_reset_block(hw)) -			oem_reg |= HV_OEM_BITS_RESTART_AN;  	} else {  		if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE |  			       E1000_PHY_CTRL_NOND0A_GBE_DISABLE)) @@ -1324,6 +1320,11 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)  			oem_reg |= HV_OEM_BITS_LPLU;  	} +	/* Set Restart auto-neg to activate the bits */ +	if ((d0_state || (hw->mac.type != e1000_pchlan)) && +	    !hw->phy.ops.check_reset_block(hw)) +		oem_reg |= HV_OEM_BITS_RESTART_AN; +  	ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);  release: @@ -3682,7 +3683,11 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)  	if (hw->mac.type >= e1000_pchlan) {  		e1000_oem_bits_config_ich8lan(hw, false); -		e1000_phy_hw_reset_ich8lan(hw); + +		/* Reset PHY to activate OEM bits on 82577/8 */ +		if (hw->mac.type == e1000_pchlan) +			e1000e_phy_hw_reset_generic(hw); +  		ret_val = hw->phy.ops.acquire(hw);  		if (ret_val)  			return; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 19ab2154802..9520a6ac1f3 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3799,7 +3799,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)  	/* fire an unusual interrupt on the test handler */  	ew32(ICS, E1000_ICS_RXSEQ);  	e1e_flush(); -	msleep(50); +	msleep(100);  	e1000_irq_disable(adapter); diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index ff796e42c3e..16adeb9418a 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -106,7 +106,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");  /*   * Interrupt Throttle Rate (interrupts/sec)   * - * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) + * Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative   */  E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");  #define DEFAULT_ITR 3 @@ -344,53 +344,60 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)  		if (num_InterruptThrottleRate > bd) {  			adapter->itr = InterruptThrottleRate[bd]; -			switch (adapter->itr) { -			case 0: -				e_info("%s turned off\n", opt.name); -				break; -			case 1: -				e_info("%s set to dynamic mode\n", opt.name); -				adapter->itr_setting = adapter->itr; -				adapter->itr = 20000; -				break; -			case 3: -				e_info("%s set to dynamic conservative mode\n", -					opt.name); -				adapter->itr_setting = adapter->itr; -				adapter->itr = 20000; -				break; -			case 4: -				e_info("%s set to simplified (2000-8000 ints) " -				       "mode\n", opt.name); -				adapter->itr_setting = 4; -				break; -			default: -				/* -				 * Save the setting, because the dynamic bits -				 * change itr. -				 */ -				if (e1000_validate_option(&adapter->itr, &opt, -							  adapter) && -				    (adapter->itr == 3)) { -					/* -					 * In case of invalid user value, -					 * default to conservative mode. -					 */ -					adapter->itr_setting = adapter->itr; -					adapter->itr = 20000; -				} else { -					/* -					 * Clear the lower two bits because -					 * they are used as control. -					 */ -					adapter->itr_setting = -						adapter->itr & ~3; -				} -				break; -			} + +			/* +			 * Make sure a message is printed for non-special +			 * values.  And in case of an invalid option, display +			 * warning, use default and got through itr/itr_setting +			 * adjustment logic below +			 */ +			if ((adapter->itr > 4) && +			    e1000_validate_option(&adapter->itr, &opt, adapter)) +				adapter->itr = opt.def;  		} else { -			adapter->itr_setting = opt.def; +			/* +			 * If no option specified, use default value and go +			 * through the logic below to adjust itr/itr_setting +			 */ +			adapter->itr = opt.def; + +			/* +			 * Make sure a message is printed for non-special +			 * default values +			 */ +			if (adapter->itr > 40) +				e_info("%s set to default %d\n", opt.name, +				       adapter->itr); +		} + +		adapter->itr_setting = adapter->itr; +		switch (adapter->itr) { +		case 0: +			e_info("%s turned off\n", opt.name); +			break; +		case 1: +			e_info("%s set to dynamic mode\n", opt.name); +			adapter->itr = 20000; +			break; +		case 3: +			e_info("%s set to dynamic conservative mode\n", +			       opt.name);  			adapter->itr = 20000; +			break; +		case 4: +			e_info("%s set to simplified (2000-8000 ints) mode\n", +			       opt.name); +			break; +		default: +			/* +			 * Save the setting, because the dynamic bits +			 * change itr. +			 * +			 * Clear the lower two bits because +			 * they are used as control. +			 */ +			adapter->itr_setting &= ~3; +			break;  		}  	}  	{ /* Interrupt Mode */ diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index d61ca2a732f..8ec74b07f94 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -2731,14 +2731,14 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,  			netdev->addr_len);  	} -	if (!is_valid_ether_addr(netdev->perm_addr)) { +	if (!is_valid_ether_addr(netdev->dev_addr)) {  		dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",  		        netdev->dev_addr);  		err = -EIO;  		goto err_hw_init;  	} -	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); +	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);  	setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,  	            (unsigned long) adapter); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c index 77ea4b71653..bc07933d67d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c @@ -437,6 +437,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,  	 */  	if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&  	    (fctl & FC_FC_END_SEQ)) { +		skb_linearize(skb);  		crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));  		crc->fcoe_eof = FC_EOF_T;  	} diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index 027d7a75be3..ed1b47dc083 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -622,6 +622,16 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, int v_idx,  		if (adapter->hw.mac.type == ixgbe_mac_82599EB)  			set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state); +#ifdef IXGBE_FCOE +		if (adapter->netdev->features & NETIF_F_FCOE_MTU) { +			struct ixgbe_ring_feature *f; +			f = &adapter->ring_feature[RING_F_FCOE]; +			if ((rxr_idx >= f->mask) && +			    (rxr_idx < f->mask + f->indices)) +				set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); +		} + +#endif /* IXGBE_FCOE */  		/* apply Rx specific ring traits */  		ring->count = adapter->rx_ring_count;  		ring->queue_index = rxr_idx; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 3e26b1f9ac7..88f6b2e9b72 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3154,14 +3154,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)  			set_ring_rsc_enabled(rx_ring);  		else  			clear_ring_rsc_enabled(rx_ring); -#ifdef IXGBE_FCOE -		if (netdev->features & NETIF_F_FCOE_MTU) { -			struct ixgbe_ring_feature *f; -			f = &adapter->ring_feature[RING_F_FCOE]; -			if ((i >= f->mask) && (i < f->mask + f->indices)) -				set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state); -		} -#endif /* IXGBE_FCOE */  	}  } @@ -4836,7 +4828,9 @@ static int ixgbe_resume(struct pci_dev *pdev)  	pci_wake_from_d3(pdev, false); +	rtnl_lock();  	err = ixgbe_init_interrupt_scheme(adapter); +	rtnl_unlock();  	if (err) {  		e_dev_err("Cannot initialize interrupts for device\n");  		return err; @@ -4879,10 +4873,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)  	}  	ixgbe_clear_interrupt_scheme(adapter); -#ifdef CONFIG_DCB -	kfree(adapter->ixgbe_ieee_pfc); -	kfree(adapter->ixgbe_ieee_ets); -#endif  #ifdef CONFIG_PM  	retval = pci_save_state(pdev); @@ -4893,6 +4883,16 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)  	if (wufc) {  		ixgbe_set_rx_mode(netdev); +		/* +		 * enable the optics for both mult-speed fiber and +		 * 82599 SFP+ fiber as we can WoL. +		 */ +		if (hw->mac.ops.enable_tx_laser && +		    (hw->phy.multispeed_fiber || +		    (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber && +		     hw->mac.type == ixgbe_mac_82599EB))) +			hw->mac.ops.enable_tx_laser(hw); +  		/* turn on all-multi mode if wake on multicast is enabled */  		if (wufc & IXGBE_WUFC_MC) {  			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); @@ -7220,6 +7220,11 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)  	ixgbe_release_hw_control(adapter); +#ifdef CONFIG_DCB +	kfree(adapter->ixgbe_ieee_pfc); +	kfree(adapter->ixgbe_ieee_ets); + +#endif  	iounmap(adapter->hw.hw_addr);  	pci_release_selected_regions(pdev, pci_select_bars(pdev,  				     IORESOURCE_MEM)); diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index c9b504e2dfc..487a6c8bd4e 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -2494,8 +2494,13 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,  		skb_copy_from_linear_data(re->skb, skb->data, length);  		skb->ip_summed = re->skb->ip_summed;  		skb->csum = re->skb->csum; +		skb->rxhash = re->skb->rxhash; +		skb->vlan_tci = re->skb->vlan_tci; +  		pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,  					       length, PCI_DMA_FROMDEVICE); +		re->skb->vlan_tci = 0; +		re->skb->rxhash = 0;  		re->skb->ip_summed = CHECKSUM_NONE;  		skb_put(skb, length);  	} @@ -2580,9 +2585,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev,  	struct sk_buff *skb = NULL;  	u16 count = (status & GMR_FS_LEN) >> 16; -	if (status & GMR_FS_VLAN) -		count -= VLAN_HLEN;	/* Account for vlan tag */ -  	netif_printk(sky2, rx_status, KERN_DEBUG, dev,  		     "rx slot %u status 0x%x len %d\n",  		     sky2->rx_next, status, length); @@ -2590,6 +2592,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,  	sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;  	prefetch(sky2->rx_ring + sky2->rx_next); +	if (vlan_tx_tag_present(re->skb)) +		count -= VLAN_HLEN;	/* Account for vlan tag */ +  	/* This chip has hardware problems that generates bogus status.  	 * So do only marginal checking and expect higher level protocols  	 * to handle crap frames. @@ -2647,11 +2652,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)  }  static inline void sky2_skb_rx(const struct sky2_port *sky2, -			       u32 status, struct sk_buff *skb) +			       struct sk_buff *skb)  { -	if (status & GMR_FS_VLAN) -		__vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag)); -  	if (skb->ip_summed == CHECKSUM_NONE)  		netif_receive_skb(skb);  	else @@ -2705,6 +2707,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)  	}  } +static void sky2_rx_tag(struct sky2_port *sky2, u16 length) +{ +	struct sk_buff *skb; + +	skb = sky2->rx_ring[sky2->rx_next].skb; +	__vlan_hwaccel_put_tag(skb, be16_to_cpu(length)); +} +  static void sky2_rx_hash(struct sky2_port *sky2, u32 status)  {  	struct sk_buff *skb; @@ -2763,8 +2773,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)  			}  			skb->protocol = eth_type_trans(skb, dev); - -			sky2_skb_rx(sky2, status, skb); +			sky2_skb_rx(sky2, skb);  			/* Stop after net poll weight */  			if (++work_done >= to_do) @@ -2772,11 +2781,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)  			break;  		case OP_RXVLAN: -			sky2->rx_tag = length; +			sky2_rx_tag(sky2, length);  			break;  		case OP_RXCHKSVLAN: -			sky2->rx_tag = length; +			sky2_rx_tag(sky2, length);  			/* fall through */  		case OP_RXCHKS:  			if (likely(dev->features & NETIF_F_RXCSUM)) diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h index ff6f58bf822..3c896ce80b7 100644 --- a/drivers/net/ethernet/marvell/sky2.h +++ b/drivers/net/ethernet/marvell/sky2.h @@ -2241,7 +2241,6 @@ struct sky2_port {  	u16		     rx_pending;  	u16		     rx_data_size;  	u16		     rx_nfrags; -	u16		     rx_tag;  	struct {  		unsigned long last; diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index c722aa607d0..f8dda009d3c 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -889,16 +889,17 @@ static int ks8851_net_stop(struct net_device *dev)  	netif_stop_queue(dev);  	mutex_lock(&ks->lock); +	/* turn off the IRQs and ack any outstanding */ +	ks8851_wrreg16(ks, KS_IER, 0x0000); +	ks8851_wrreg16(ks, KS_ISR, 0xffff); +	mutex_unlock(&ks->lock);  	/* stop any outstanding work */  	flush_work(&ks->irq_work);  	flush_work(&ks->tx_work);  	flush_work(&ks->rxctrl_work); -	/* turn off the IRQs and ack any outstanding */ -	ks8851_wrreg16(ks, KS_IER, 0x0000); -	ks8851_wrreg16(ks, KS_ISR, 0xffff); - +	mutex_lock(&ks->lock);  	/* shutdown RX process */  	ks8851_wrreg16(ks, KS_RXCR1, 0x0000); @@ -907,6 +908,7 @@ static int ks8851_net_stop(struct net_device *dev)  	/* set powermode to soft power down to save power */  	ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); +	mutex_unlock(&ks->lock);  	/* ensure any queued tx buffers are dumped */  	while (!skb_queue_empty(&ks->txq)) { @@ -918,7 +920,6 @@ static int ks8851_net_stop(struct net_device *dev)  		dev_kfree_skb(txb);  	} -	mutex_unlock(&ks->lock);  	return 0;  } @@ -1418,6 +1419,7 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	struct net_device *ndev;  	struct ks8851_net *ks;  	int ret; +	unsigned cider;  	ndev = alloc_etherdev(sizeof(struct ks8851_net));  	if (!ndev) @@ -1484,8 +1486,8 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	ks8851_soft_reset(ks, GRR_GSR);  	/* simple check for a valid chip being connected to the bus */ - -	if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { +	cider = ks8851_rdreg16(ks, KS_CIDER); +	if ((cider & ~CIDER_REV_MASK) != CIDER_ID) {  		dev_err(&spi->dev, "failed to read device ID\n");  		ret = -ENODEV;  		goto err_id; @@ -1516,15 +1518,14 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	}  	netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n", -		    CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), -		    ndev->dev_addr, ndev->irq, +		    CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq,  		    ks->rc_ccr & CCR_EEPROM ? "has" : "no");  	return 0;  err_netdev: -	free_irq(ndev->irq, ndev); +	free_irq(ndev->irq, ks);  err_id:  err_irq: diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index b8104d9f408..5ffde23ac8f 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -40,7 +40,7 @@  #define	DRV_NAME	"ks8851_mll"  static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 }; -#define MAX_RECV_FRAMES			32 +#define MAX_RECV_FRAMES			255  #define MAX_BUF_SIZE			2048  #define TX_BUF_SIZE			2000  #define RX_BUF_SIZE			2000 diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index ef723b185d8..eaf9ff0262a 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -5675,7 +5675,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr)  		memcpy(hw->override_addr, mac->sa_data, ETH_ALEN);  	} -	memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); +	memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);  	interrupt = hw_block_intr(hw); diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index abc79076f86..b3287c0fe27 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -958,6 +958,11 @@ static inline void cp_start_hw (struct cp_private *cp)  	cpw8(Cmd, RxOn | TxOn);  } +static void cp_enable_irq(struct cp_private *cp) +{ +	cpw16_f(IntrMask, cp_intr_mask); +} +  static void cp_init_hw (struct cp_private *cp)  {  	struct net_device *dev = cp->dev; @@ -997,8 +1002,6 @@ static void cp_init_hw (struct cp_private *cp)  	cpw16(MultiIntr, 0); -	cpw16_f(IntrMask, cp_intr_mask); -  	cpw8_f(Cfg9346, Cfg9346_Lock);  } @@ -1130,6 +1133,8 @@ static int cp_open (struct net_device *dev)  	if (rc)  		goto err_out_hw; +	cp_enable_irq(cp); +  	netif_carrier_off(dev);  	mii_check_media(&cp->mii_if, netif_msg_link(cp), true);  	netif_start_queue(dev); @@ -2031,6 +2036,7 @@ static int cp_resume (struct pci_dev *pdev)  	/* FIXME: sh*t may happen if the Rx ring buffer is depleted */  	cp_init_rings_index (cp);  	cp_init_hw (cp); +	cp_enable_irq(cp);  	netif_start_queue (dev);  	spin_lock_irqsave (&cp->lock, flags); diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 4a697102707..cd3defb11ff 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1166,10 +1166,8 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)  /* Quickly dumps bad packets */  static void -smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) +smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords)  { -	unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2; -  	if (likely(pktwords >= 4)) {  		unsigned int timeout = 500;  		unsigned int val; @@ -1233,7 +1231,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)  			continue;  		} -		skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN); +		skb = netdev_alloc_skb(dev, pktwords << 2);  		if (unlikely(!skb)) {  			SMSC_WARN(pdata, rx_err,  				  "Unable to allocate skb for rx packet"); @@ -1243,14 +1241,12 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)  			break;  		} -		skb->data = skb->head; -		skb_reset_tail_pointer(skb); +		pdata->ops->rx_readfifo(pdata, +				 (unsigned int *)skb->data, pktwords);  		/* Align IP on 16B boundary */  		skb_reserve(skb, NET_IP_ALIGN);  		skb_put(skb, pktlength - 4); -		pdata->ops->rx_readfifo(pdata, -				 (unsigned int *)skb->head, pktwords);  		skb->protocol = eth_type_trans(skb, dev);  		skb_checksum_none_assert(skb);  		netif_receive_skb(skb); @@ -1565,7 +1561,7 @@ static int smsc911x_open(struct net_device *dev)  	smsc911x_reg_write(pdata, FIFO_INT, temp);  	/* set RX Data offset to 2 bytes for alignment */ -	smsc911x_reg_write(pdata, RX_CFG, (2 << 8)); +	smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8));  	/* enable NAPI polling before enabling RX interrupts */  	napi_enable(&pdata->napi); @@ -2382,7 +2378,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)  	SET_NETDEV_DEV(dev, &pdev->dev);  	pdata = netdev_priv(dev); -  	dev->irq = irq_res->start;  	irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;  	pdata->ioaddr = ioremap_nocache(res->start, res_size); @@ -2446,7 +2441,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)  	if (retval) {  		SMSC_WARN(pdata, probe,  			  "Unable to claim requested irq: %d", dev->irq); -		goto out_free_irq; +		goto out_disable_resources;  	}  	retval = register_netdev(dev); diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index 558409ff405..4ba96909671 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)  	netif_device_detach(dev);  	/* Switch off chip, remember WOL setting */ -	gp->asleep_wol = gp->wake_on_lan; +	gp->asleep_wol = !!gp->wake_on_lan;  	gem_do_stop(dev, gp->asleep_wol);  	/* Unlock the network stack */ diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 174a3348f67..08aff1a2087 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1511,7 +1511,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)  static int match_first_device(struct device *dev, void *data)  { -	return 1; +	return !strncmp(dev_name(dev), "davinci_mdio", 12);  }  /** diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index 2757c7d6e63..e4e47088e26 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -181,6 +181,11 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)  		__davinci_mdio_reset(data);  		return -EAGAIN;  	} + +	reg = __raw_readl(®s->user[0].access); +	if ((reg & USERACCESS_GO) == 0) +		return 0; +  	dev_err(data->dev, "timed out waiting for user access\n");  	return -ETIMEDOUT;  } diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 817ad3bc495..efd36691ce5 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -228,7 +228,7 @@ tlan_get_skb(const struct tlan_list *tag)  	unsigned long addr;  	addr = tag->buffer[9].address; -	addr |= (tag->buffer[8].address << 16) << 16; +	addr |= ((unsigned long) tag->buffer[8].address << 16) << 16;  	return (struct sk_buff *) addr;  } diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h index cc83af083fd..44b8d2bad8c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -2,9 +2,7 @@   * Definitions for Xilinx Axi Ethernet device driver.   *   * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   */  #ifndef XILINX_AXIENET_H diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 2fcbeba6814..9c365e192a3 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -4,9 +4,9 @@   * Copyright (c) 2008 Nissin Systems Co., Ltd.,  Yoshio Kashiwagi   * Copyright (c) 2005-2008 DLA Systems,  David H. Lynch Jr. <dhlii@dlasys.net>   * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu> + * Copyright (c) 2010 - 2011 PetaLogix + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   *   * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6   * and Spartan6. diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index d70b6e79f6c..e90e1f46121 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -2,9 +2,9 @@   * MDIO bus driver for the Xilinx Axi Ethernet device   *   * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu> + * Copyright (c) 2010 - 2011 PetaLogix + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   */  #include <linux/of_address.h> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index dd294783b5c..2d59138db7f 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -44,6 +44,7 @@ struct net_device_context {  	/* point back to our device context */  	struct hv_device *device_ctx;  	struct delayed_work dwork; +	struct work_struct work;  }; @@ -51,30 +52,22 @@ static int ring_size = 128;  module_param(ring_size, int, S_IRUGO);  MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); -struct set_multicast_work { -	struct work_struct work; -	struct net_device *net; -}; -  static void do_set_multicast(struct work_struct *w)  { -	struct set_multicast_work *swk = -		container_of(w, struct set_multicast_work, work); -	struct net_device *net = swk->net; - -	struct net_device_context *ndevctx = netdev_priv(net); +	struct net_device_context *ndevctx = +		container_of(w, struct net_device_context, work);  	struct netvsc_device *nvdev;  	struct rndis_device *rdev;  	nvdev = hv_get_drvdata(ndevctx->device_ctx); -	if (nvdev == NULL) -		goto out; +	if (nvdev == NULL || nvdev->ndev == NULL) +		return;  	rdev = nvdev->extension;  	if (rdev == NULL) -		goto out; +		return; -	if (net->flags & IFF_PROMISC) +	if (nvdev->ndev->flags & IFF_PROMISC)  		rndis_filter_set_packet_filter(rdev,  			NDIS_PACKET_TYPE_PROMISCUOUS);  	else @@ -82,21 +75,13 @@ static void do_set_multicast(struct work_struct *w)  			NDIS_PACKET_TYPE_BROADCAST |  			NDIS_PACKET_TYPE_ALL_MULTICAST |  			NDIS_PACKET_TYPE_DIRECTED); - -out: -	kfree(w);  }  static void netvsc_set_multicast_list(struct net_device *net)  { -	struct set_multicast_work *swk = -		kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC); -	if (swk == NULL) -		return; +	struct net_device_context *net_device_ctx = netdev_priv(net); -	swk->net = net; -	INIT_WORK(&swk->work, do_set_multicast); -	schedule_work(&swk->work); +	schedule_work(&net_device_ctx->work);  }  static int netvsc_open(struct net_device *net) @@ -125,6 +110,8 @@ static int netvsc_close(struct net_device *net)  	netif_tx_disable(net); +	/* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ +	cancel_work_sync(&net_device_ctx->work);  	ret = rndis_filter_close(device_obj);  	if (ret != 0)  		netdev_err(net, "unable to close device (ret %d).\n", ret); @@ -335,6 +322,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)  	nvdev->start_remove = true;  	cancel_delayed_work_sync(&ndevctx->dwork); +	cancel_work_sync(&ndevctx->work);  	netif_tx_disable(ndev);  	rndis_filter_device_remove(hdev); @@ -403,6 +391,7 @@ static int netvsc_probe(struct hv_device *dev,  	net_device_ctx->device_ctx = dev;  	hv_set_drvdata(dev, net);  	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); +	INIT_WORK(&net_device_ctx->work, do_set_multicast);  	net->netdev_ops = &device_ops; @@ -456,6 +445,7 @@ static int netvsc_remove(struct hv_device *dev)  	ndev_ctx = netdev_priv(net);  	cancel_delayed_work_sync(&ndev_ctx->dwork); +	cancel_work_sync(&ndev_ctx->work);  	/* Stop outbound asap */  	netif_tx_disable(net); diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index f08c85acf76..5ac46f5226f 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -40,6 +40,7 @@ MODULE_LICENSE("GPL");  #define IP1001_PHASE_SEL_MASK		3	/* IP1001 RX/TXPHASE_SEL */  #define IP1001_APS_ON			11	/* IP1001 APS Mode  bit */  #define IP101A_G_APS_ON			2	/* IP101A/G APS Mode bit */ +#define IP101A_G_IRQ_CONF_STATUS	0x11	/* Conf Info IRQ & Status Reg */  static int ip175c_config_init(struct phy_device *phydev)  { @@ -185,6 +186,15 @@ static int ip175c_config_aneg(struct phy_device *phydev)  	return 0;  } +static int ip101a_g_ack_interrupt(struct phy_device *phydev) +{ +	int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); +	if (err < 0) +		return err; + +	return 0; +} +  static struct phy_driver ip175c_driver = {  	.phy_id		= 0x02430d80,  	.name		= "ICPlus IP175C", @@ -204,7 +214,6 @@ static struct phy_driver ip1001_driver = {  	.phy_id_mask	= 0x0ffffff0,  	.features	= PHY_GBIT_FEATURES | SUPPORTED_Pause |  			  SUPPORTED_Asym_Pause, -	.flags		= PHY_HAS_INTERRUPT,  	.config_init	= &ip1001_config_init,  	.config_aneg	= &genphy_config_aneg,  	.read_status	= &genphy_read_status, @@ -220,6 +229,7 @@ static struct phy_driver ip101a_g_driver = {  	.features	= PHY_BASIC_FEATURES | SUPPORTED_Pause |  			  SUPPORTED_Asym_Pause,  	.flags		= PHY_HAS_INTERRUPT, +	.ack_interrupt	= ip101a_g_ack_interrupt,  	.config_init	= &ip101a_g_config_init,  	.config_aneg	= &genphy_config_aneg,  	.read_status	= &genphy_read_status, diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 33f8c51968b..21d7151fb0a 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -235,7 +235,7 @@ struct ppp_net {  /* Prototypes. */  static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,  			struct file *file, unsigned int cmd, unsigned long arg); -static int ppp_xmit_process(struct ppp *ppp); +static void ppp_xmit_process(struct ppp *ppp);  static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);  static void ppp_push(struct ppp *ppp);  static void ppp_channel_push(struct channel *pch); @@ -969,8 +969,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)  	put_unaligned_be16(proto, pp);  	skb_queue_tail(&ppp->file.xq, skb); -	if (!ppp_xmit_process(ppp)) -		netif_stop_queue(dev); +	ppp_xmit_process(ppp);  	return NETDEV_TX_OK;   outf: @@ -1048,11 +1047,10 @@ static void ppp_setup(struct net_device *dev)   * Called to do any work queued up on the transmit side   * that can now be done.   */ -static int +static void  ppp_xmit_process(struct ppp *ppp)  {  	struct sk_buff *skb; -	int ret = 0;  	ppp_xmit_lock(ppp);  	if (!ppp->closing) { @@ -1062,13 +1060,12 @@ ppp_xmit_process(struct ppp *ppp)  			ppp_send_frame(ppp, skb);  		/* If there's no work left to do, tell the core net  		   code that we can accept some more. */ -		if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq)) { +		if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))  			netif_wake_queue(ppp->dev); -			ret = 1; -		} +		else +			netif_stop_queue(ppp->dev);  	}  	ppp_xmit_unlock(ppp); -	return ret;  }  static inline struct sk_buff * diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 5ee032cafad..42b5151aa78 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -355,7 +355,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,  	u32 packet_len;  	u32 padbytes = 0xffff0000; -	padlen = ((skb->len + 4) % 512) ? 0 : 4; +	padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;  	if ((!skb_cloned(skb)) &&  	    ((headroom + tailroom) >= (4 + padlen))) { @@ -377,7 +377,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,  	cpu_to_le32s(&packet_len);  	skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); -	if ((skb->len % 512) == 0) { +	if (padlen) {  		cpu_to_le32s(&padbytes);  		memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));  		skb_put(skb, sizeof(padbytes)); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 552d24bf862..d316503b35d 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -365,6 +365,27 @@ static const struct driver_info	qmi_wwan_force_int4 = {  	.data		= BIT(4), /* interface whitelist bitmap */  }; +/* Sierra Wireless provide equally useless interface descriptors + * Devices in QMI mode can be switched between two different + * configurations: + *   a) USB interface #8 is QMI/wwan + *   b) USB interfaces #8, #19 and #20 are QMI/wwan + * + * Both configurations provide a number of other interfaces (serial++), + * some of which have the same endpoint configuration as we expect, so + * a whitelist or blacklist is necessary. + * + * FIXME: The below whitelist should include BIT(20).  It does not + * because I cannot get it to work... + */ +static const struct driver_info	qmi_wwan_sierra = { +	.description	= "Sierra Wireless wwan/QMI device", +	.flags		= FLAG_WWAN, +	.bind		= qmi_wwan_bind_gobi, +	.unbind		= qmi_wwan_unbind_shared, +	.manage_power	= qmi_wwan_manage_power, +	.data		= BIT(8) | BIT(19), /* interface whitelist bitmap */ +};  #define HUAWEI_VENDOR_ID	0x12D1  #define QMI_GOBI_DEVICE(vend, prod) \ @@ -445,6 +466,15 @@ static const struct usb_device_id products[] = {  		.bInterfaceProtocol = 0xff,  		.driver_info        = (unsigned long)&qmi_wwan_force_int4,  	}, +	{	/* Sierra Wireless MC77xx in QMI mode */ +		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, +		.idVendor           = 0x1199, +		.idProduct          = 0x68a2, +		.bInterfaceClass    = 0xff, +		.bInterfaceSubClass = 0xff, +		.bInterfaceProtocol = 0xff, +		.driver_info        = (unsigned long)&qmi_wwan_sierra, +	},  	{QMI_GOBI_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */  	{QMI_GOBI_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */  	{QMI_GOBI_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */ diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 187d01ccb97..00103a8c5e0 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -98,7 +98,7 @@ static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,  	if (unlikely(ret < 0))  		netdev_warn(dev->net, -			"Failed to read register index 0x%08x", index); +			"Failed to read reg index 0x%08x: %d", index, ret);  	le32_to_cpus(buf);  	*data = *buf; @@ -128,7 +128,7 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,  	if (unlikely(ret < 0))  		netdev_warn(dev->net, -			"Failed to write register index 0x%08x", index); +			"Failed to write reg index 0x%08x: %d", index, ret);  	kfree(buf); @@ -171,7 +171,7 @@ static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)  	idx &= dev->mii.reg_num_mask;  	addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)  		| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) -		| MII_ACCESS_READ; +		| MII_ACCESS_READ | MII_ACCESS_BUSY;  	ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);  	check_warn_goto_done(ret, "Error writing MII_ACCESS"); @@ -210,7 +210,7 @@ static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,  	idx &= dev->mii.reg_num_mask;  	addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)  		| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) -		| MII_ACCESS_WRITE; +		| MII_ACCESS_WRITE | MII_ACCESS_BUSY;  	ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);  	check_warn_goto_done(ret, "Error writing MII_ACCESS"); @@ -508,9 +508,10 @@ static int smsc75xx_link_reset(struct usbnet *dev)  	u16 lcladv, rmtadv;  	int ret; -	/* clear interrupt status */ +	/* read and write to clear phy interrupt status */  	ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);  	check_warn_return(ret, "Error reading PHY_INT_SRC"); +	smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff);  	ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);  	check_warn_return(ret, "Error writing INT_STS"); @@ -643,7 +644,7 @@ static int smsc75xx_set_mac_address(struct usbnet *dev)  static int smsc75xx_phy_initialize(struct usbnet *dev)  { -	int bmcr, timeout = 0; +	int bmcr, ret, timeout = 0;  	/* Initialize MII structure */  	dev->mii.dev = dev->net; @@ -651,6 +652,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)  	dev->mii.mdio_write = smsc75xx_mdio_write;  	dev->mii.phy_id_mask = 0x1f;  	dev->mii.reg_num_mask = 0x1f; +	dev->mii.supports_gmii = 1;  	dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;  	/* reset phy and wait for reset to complete */ @@ -661,7 +663,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)  		bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);  		check_warn_return(bmcr, "Error reading MII_BMCR");  		timeout++; -	} while ((bmcr & MII_BMCR) && (timeout < 100)); +	} while ((bmcr & BMCR_RESET) && (timeout < 100));  	if (timeout >= 100) {  		netdev_warn(dev->net, "timeout on PHY Reset"); @@ -671,10 +673,13 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)  	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,  		ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |  		ADVERTISE_PAUSE_ASYM); +	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, +		ADVERTISE_1000FULL); -	/* read to clear */ -	smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); -	check_warn_return(bmcr, "Error reading PHY_INT_SRC"); +	/* read and write to clear phy interrupt status */ +	ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); +	check_warn_return(ret, "Error reading PHY_INT_SRC"); +	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff);  	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,  		PHY_INT_MASK_DEFAULT); @@ -946,6 +951,14 @@ static int smsc75xx_reset(struct usbnet *dev)  	ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);  	check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret); +	/* allow mac to detect speed and duplex from phy */ +	ret = smsc75xx_read_reg(dev, MAC_CR, &buf); +	check_warn_return(ret, "Failed to read MAC_CR: %d", ret); + +	buf |= (MAC_CR_ADD | MAC_CR_ASD); +	ret = smsc75xx_write_reg(dev, MAC_CR, buf); +	check_warn_return(ret, "Failed to write MAC_CR: %d", ret); +  	ret = smsc75xx_read_reg(dev, MAC_TX, &buf);  	check_warn_return(ret, "Failed to read MAC_TX: %d", ret); @@ -1051,6 +1064,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->net->ethtool_ops = &smsc75xx_ethtool_ops;  	dev->net->flags |= IFF_MULTICAST;  	dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; +	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;  	return 0;  } @@ -1211,7 +1225,7 @@ static const struct driver_info smsc75xx_info = {  	.rx_fixup	= smsc75xx_rx_fixup,  	.tx_fixup	= smsc75xx_tx_fixup,  	.status		= smsc75xx_status, -	.flags		= FLAG_ETHER | FLAG_SEND_ZLP, +	.flags		= FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,  };  static const struct usb_device_id products[] = { diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 5f19f84d349..94ae66999f5 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1017,6 +1017,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->net->ethtool_ops = &smsc95xx_ethtool_ops;  	dev->net->flags |= IFF_MULTICAST;  	dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM; +	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;  	return 0;  } @@ -1191,7 +1192,7 @@ static const struct driver_info smsc95xx_info = {  	.rx_fixup	= smsc95xx_rx_fixup,  	.tx_fixup	= smsc95xx_tx_fixup,  	.status		= smsc95xx_status, -	.flags		= FLAG_ETHER | FLAG_SEND_ZLP, +	.flags		= FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,  };  static const struct usb_device_id products[] = { diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index b7b3f5b0d40..2d927fb4adf 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -210,6 +210,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)  		} else {  			usb_fill_int_urb(dev->interrupt, dev->udev, pipe,  				buf, maxp, intr_complete, dev, period); +			dev->interrupt->transfer_flags |= URB_FREE_BUFFER;  			dev_dbg(&intf->dev,  				"status ep%din, %d bytes period %d\n",  				usb_pipeendpoint(pipe), maxp, period); @@ -1443,7 +1444,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)  	status = register_netdev (net);  	if (status) -		goto out3; +		goto out4;  	netif_info(dev, probe, dev->net,  		   "register '%s' at usb-%s-%s, %s, %pM\n",  		   udev->dev.driver->name, @@ -1461,6 +1462,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)  	return 0; +out4: +	usb_free_urb(dev->interrupt);  out3:  	if (info->unbind)  		info->unbind (dev, udev); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 4de2760c593..af8acc85f4b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -626,16 +626,15 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)  	/* This can happen with OOM and indirect buffers. */  	if (unlikely(capacity < 0)) {  		if (likely(capacity == -ENOMEM)) { -			if (net_ratelimit()) { +			if (net_ratelimit())  				dev_warn(&dev->dev,  					 "TX queue failure: out of memory\n"); -			} else { +		} else {  			dev->stats.tx_fifo_errors++;  			if (net_ratelimit())  				dev_warn(&dev->dev,  					 "Unexpected TX queue failure: %d\n",  					 capacity); -			}  		}  		dev->stats.tx_dropped++;  		kfree_skb(skb); diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index ebb9f24eefb..1a623183cbe 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2483,6 +2483,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)  		pr_err("Control memory remap failed\n");  		pci_release_regions(pdev);  		pci_disable_device(pdev); +		iounmap(card->mem);  		kfree(card);  		return -ENODEV;  	} diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 8faa129da5a..aec33cc207f 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -19,6 +19,7 @@  #include <linux/nl80211.h>  #include <linux/platform_device.h>  #include <linux/etherdevice.h> +#include <linux/export.h>  #include <ar231x_platform.h>  #include "ath5k.h"  #include "debug.h" @@ -119,7 +120,7 @@ static int ath_ahb_probe(struct platform_device *pdev)  	if (res == NULL) {  		dev_err(&pdev->dev, "no IRQ resource found\n");  		ret = -ENXIO; -		goto err_out; +		goto err_iounmap;  	}  	irq = res->start; @@ -128,7 +129,7 @@ static int ath_ahb_probe(struct platform_device *pdev)  	if (hw == NULL) {  		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");  		ret = -ENOMEM; -		goto err_out; +		goto err_iounmap;  	}  	ah = hw->priv; @@ -185,6 +186,8 @@ static int ath_ahb_probe(struct platform_device *pdev)   err_free_hw:  	ieee80211_free_hw(hw);  	platform_set_drvdata(pdev, NULL); + err_iounmap: +        iounmap(mem);   err_out:  	return ret;  } @@ -217,6 +220,7 @@ static int ath_ahb_remove(struct platform_device *pdev)  	}  	ath5k_deinit_ah(ah); +	iounmap(ah->iobase);  	platform_set_drvdata(pdev, NULL);  	ieee80211_free_hw(hw); diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index d7d8e919914..aba088005b2 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -869,7 +869,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,  	ar5008_hw_set_channel_regs(ah, chan);  	ar5008_hw_init_chain_masks(ah);  	ath9k_olc_init(ah); -	ath9k_hw_apply_txpower(ah, chan); +	ath9k_hw_apply_txpower(ah, chan, false);  	/* Write analog registers */  	if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 59647a3ceb7..3d400e8d653 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -54,7 +54,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)  	if (val) {  		ah->paprd_table_write_done = true; -		ath9k_hw_apply_txpower(ah, chan); +		ath9k_hw_apply_txpower(ah, chan, false);  	}  	REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index bc992b237ae..deb6cfb2959 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -694,7 +694,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,  	ar9003_hw_override_ini(ah);  	ar9003_hw_set_channel_regs(ah, chan);  	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); -	ath9k_hw_apply_txpower(ah, chan); +	ath9k_hw_apply_txpower(ah, chan, false);  	if (AR_SREV_9462(ah)) {  		if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index f272236d805..b34e8b2990b 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -824,6 +824,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,  			regulatory->max_power_level = ratesArray[i];  	} +	ath9k_hw_update_regulatory_maxpower(ah); +  	if (test)  		return; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6c69e4e8b1c..fa84e37bf09 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1454,7 +1454,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,  		return false;  	}  	ath9k_hw_set_clockrate(ah); -	ath9k_hw_apply_txpower(ah, chan); +	ath9k_hw_apply_txpower(ah, chan, false);  	ath9k_hw_rfbus_done(ah);  	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) @@ -2652,7 +2652,8 @@ static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)  	return ah->eep_ops->get_eeprom(ah, gain_param);  } -void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan) +void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, +			    bool test)  {  	struct ath_regulatory *reg = ath9k_hw_regulatory(ah);  	struct ieee80211_channel *channel; @@ -2673,7 +2674,7 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)  	ah->eep_ops->set_txpower(ah, chan,  				 ath9k_regd_get_ctl(reg, chan), -				 ant_reduction, new_pwr, false); +				 ant_reduction, new_pwr, test);  }  void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) @@ -2686,7 +2687,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)  	if (test)  		channel->max_power = MAX_RATE_POWER / 2; -	ath9k_hw_apply_txpower(ah, chan); +	ath9k_hw_apply_txpower(ah, chan, test);  	if (test)  		channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index aa1680a0c7f..e88f182ff45 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -985,7 +985,8 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);  /* PHY */  void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,  				   u32 *coef_mantissa, u32 *coef_exponent); -void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); +void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, +			    bool test);  /*   * Code Specific to AR5008, AR9001 or AR9002, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2504ab00558..798ea57252b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1548,6 +1548,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  	struct ath_hw *ah = sc->sc_ah;  	struct ath_common *common = ath9k_hw_common(ah);  	struct ieee80211_conf *conf = &hw->conf; +	bool reset_channel = false;  	ath9k_ps_wakeup(sc);  	mutex_lock(&sc->mutex); @@ -1556,6 +1557,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  		sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);  		if (sc->ps_idle)  			ath_cancel_work(sc); +		else +			/* +			 * The chip needs a reset to properly wake up from +			 * full sleep +			 */ +			reset_channel = ah->chip_fullsleep;  	}  	/* @@ -1584,7 +1591,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  		}  	} -	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { +	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {  		struct ieee80211_channel *curchan = hw->conf.channel;  		int pos = curchan->hw_value;  		int old_pos = -1; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 834e6bc45e8..23eaa1b26eb 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1820,6 +1820,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,  	struct ath_frame_info *fi = get_frame_info(skb);  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;  	struct ath_buf *bf; +	int fragno;  	u16 seqno;  	bf = ath_tx_get_buffer(sc); @@ -1831,9 +1832,16 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,  	ATH_TXBUF_RESET(bf);  	if (tid) { +		fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;  		seqno = tid->seq_next;  		hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); -		INCR(tid->seq_next, IEEE80211_SEQ_MAX); + +		if (fragno) +			hdr->seq_ctrl |= cpu_to_le16(fragno); + +		if (!ieee80211_has_morefrags(hdr->frame_control)) +			INCR(tid->seq_next, IEEE80211_SEQ_MAX); +  		bf->bf_state.seqno = seqno;  	} diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c79e6638c88..e4d6dc2e37d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4827,8 +4827,14 @@ static int b43_op_start(struct ieee80211_hw *hw)   out_mutex_unlock:  	mutex_unlock(&wl->mutex); -	/* reload configuration */ -	b43_op_config(hw, ~0); +	/* +	 * Configuration may have been overwritten during initialization. +	 * Reload the configuration, but only if initialization was +	 * successful. Reloading the configuration after a failed init +	 * may hang the system. +	 */ +	if (!err) +		b43_op_config(hw, ~0);  	return err;  } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 4688904908e..758c115b556 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -108,9 +108,15 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,  			sdio_release_host(sdfunc);  		}  	} else if (regaddr == SDIO_CCCR_ABORT) { +		sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), +				 GFP_KERNEL); +		if (!sdfunc) +			return -ENOMEM; +		sdfunc->num = 0;  		sdio_claim_host(sdfunc);  		sdio_writeb(sdfunc, *byte, regaddr, &err_ret);  		sdio_release_host(sdfunc); +		kfree(sdfunc);  	} else if (regaddr < 0xF0) {  		brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);  		err_ret = -EPERM; @@ -486,7 +492,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,  			kfree(bus_if);  			return -ENOMEM;  		} -		sdiodev->func[0] = func->card->sdio_func[0]; +		sdiodev->func[0] = func;  		sdiodev->func[1] = func;  		sdiodev->bus_if = bus_if;  		bus_if->bus_priv.sdio = sdiodev; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 2bf5dda2929..eb3829b03cd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -574,6 +574,8 @@ struct brcmf_sdio {  	struct task_struct *dpc_tsk;  	struct completion dpc_wait; +	struct list_head dpc_tsklst; +	spinlock_t dpc_tl_lock;  	struct semaphore sdsem; @@ -2594,29 +2596,58 @@ clkwait:  	return resched;  } +static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus) +{ +	struct list_head *new_hd; +	unsigned long flags; + +	if (in_interrupt()) +		new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC); +	else +		new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL); +	if (new_hd == NULL) +		return; + +	spin_lock_irqsave(&bus->dpc_tl_lock, flags); +	list_add_tail(new_hd, &bus->dpc_tsklst); +	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); +} +  static int brcmf_sdbrcm_dpc_thread(void *data)  {  	struct brcmf_sdio *bus = (struct brcmf_sdio *) data; +	struct list_head *cur_hd, *tmp_hd; +	unsigned long flags;  	allow_signal(SIGTERM);  	/* Run until signal received */  	while (1) {  		if (kthread_should_stop())  			break; -		if (!wait_for_completion_interruptible(&bus->dpc_wait)) { -			/* Call bus dpc unless it indicated down -			(then clean stop) */ -			if (bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN) { -				if (brcmf_sdbrcm_dpc(bus)) -					complete(&bus->dpc_wait); -			} else { + +		if (list_empty(&bus->dpc_tsklst)) +			if (wait_for_completion_interruptible(&bus->dpc_wait)) +				break; + +		spin_lock_irqsave(&bus->dpc_tl_lock, flags); +		list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) { +			spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); + +			if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {  				/* after stopping the bus, exit thread */  				brcmf_sdbrcm_bus_stop(bus->sdiodev->dev);  				bus->dpc_tsk = NULL;  				break;  			} -		} else -			break; + +			if (brcmf_sdbrcm_dpc(bus)) +				brcmf_sdbrcm_adddpctsk(bus); + +			spin_lock_irqsave(&bus->dpc_tl_lock, flags); +			list_del(cur_hd); +			kfree(cur_hd); +		} +		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);  	}  	return 0;  } @@ -2669,8 +2700,10 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)  	/* Schedule DPC if needed to send queued packet(s) */  	if (!bus->dpc_sched) {  		bus->dpc_sched = true; -		if (bus->dpc_tsk) +		if (bus->dpc_tsk) { +			brcmf_sdbrcm_adddpctsk(bus);  			complete(&bus->dpc_wait); +		}  	}  	return ret; @@ -3514,8 +3547,10 @@ void brcmf_sdbrcm_isr(void *arg)  		brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");  	bus->dpc_sched = true; -	if (bus->dpc_tsk) +	if (bus->dpc_tsk) { +		brcmf_sdbrcm_adddpctsk(bus);  		complete(&bus->dpc_wait); +	}  }  static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) @@ -3559,8 +3594,10 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)  				bus->ipend = true;  				bus->dpc_sched = true; -				if (bus->dpc_tsk) +				if (bus->dpc_tsk) { +					brcmf_sdbrcm_adddpctsk(bus);  					complete(&bus->dpc_wait); +				}  			}  		} @@ -3897,6 +3934,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)  	}  	/* Initialize DPC thread */  	init_completion(&bus->dpc_wait); +	INIT_LIST_HEAD(&bus->dpc_tsklst); +	spin_lock_init(&bus->dpc_tl_lock);  	bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,  				   bus, "brcmf_dpc");  	if (IS_ERR(bus->dpc_tsk)) { diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 231ddf4a674..b4d92792c50 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -847,8 +847,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)  	 */  	if (!(txs->status & TX_STATUS_AMPDU)  	    && (txs->status & TX_STATUS_INTERMEDIATE)) { -		wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n", -			  __func__); +		BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");  		return false;  	} @@ -7614,6 +7613,7 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,  {  	int len_mpdu;  	struct ieee80211_rx_status rx_status; +	struct ieee80211_hdr *hdr;  	memset(&rx_status, 0, sizeof(rx_status));  	prep_mac80211_status(wlc, rxh, p, &rx_status); @@ -7623,6 +7623,13 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,  	skb_pull(p, D11_PHY_HDR_LEN);  	__skb_trim(p, len_mpdu); +	/* unmute transmit */ +	if (wlc->hw->suspended_fifos) { +		hdr = (struct ieee80211_hdr *)p->data; +		if (ieee80211_is_beacon(hdr->frame_control)) +			brcms_b_mute(wlc->hw, false); +	} +  	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));  	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);  } diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 2b022571a85..1779db3aa2b 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -2191,6 +2191,7 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)  {  	int rc = 0;  	unsigned long flags; +	unsigned long now, end;  	spin_lock_irqsave(&priv->lock, flags);  	if (priv->status & STATUS_HCMD_ACTIVE) { @@ -2232,10 +2233,20 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)  	}  	spin_unlock_irqrestore(&priv->lock, flags); +	now = jiffies; +	end = now + HOST_COMPLETE_TIMEOUT; +again:  	rc = wait_event_interruptible_timeout(priv->wait_command_queue,  					      !(priv->  						status & STATUS_HCMD_ACTIVE), -					      HOST_COMPLETE_TIMEOUT); +					      end - now); +	if (rc < 0) { +		now = jiffies; +		if (time_before(now, end)) +			goto again; +		rc = 0; +	} +  	if (rc == 0) {  		spin_lock_irqsave(&priv->lock, flags);  		if (priv->status & STATUS_HCMD_ACTIVE) { diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5b0d888f746..8d80e233bc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -46,8 +46,8 @@  #include "iwl-prph.h"  /* Highest firmware API version supported */ -#define IWL1000_UCODE_API_MAX 6 -#define IWL100_UCODE_API_MAX 6 +#define IWL1000_UCODE_API_MAX 5 +#define IWL100_UCODE_API_MAX 5  /* Oldest version we won't warn about */  #define IWL1000_UCODE_API_OK 5 @@ -226,5 +226,5 @@ const struct iwl_cfg iwl100_bg_cfg = {  	IWL_DEVICE_100,  }; -MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 5635b9e2c69..ea108622e0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -51,10 +51,10 @@  #define IWL135_UCODE_API_MAX 6  /* Oldest version we won't warn about */ -#define IWL2030_UCODE_API_OK 5 -#define IWL2000_UCODE_API_OK 5 -#define IWL105_UCODE_API_OK 5 -#define IWL135_UCODE_API_OK 5 +#define IWL2030_UCODE_API_OK 6 +#define IWL2000_UCODE_API_OK 6 +#define IWL105_UCODE_API_OK 6 +#define IWL135_UCODE_API_OK 6  /* Lowest firmware API version supported */  #define IWL2030_UCODE_API_MIN 5 @@ -328,7 +328,7 @@ const struct iwl_cfg iwl135_bgn_cfg = {  	.ht_params = &iwl2000_ht_params,  }; -MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK)); +MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK)); +MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index a805e97b89a..de0920c74cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -51,6 +51,10 @@  #define IWL5000_UCODE_API_MAX 5  #define IWL5150_UCODE_API_MAX 2 +/* Oldest version we won't warn about */ +#define IWL5000_UCODE_API_OK 5 +#define IWL5150_UCODE_API_OK 2 +  /* Lowest firmware API version supported */  #define IWL5000_UCODE_API_MIN 1  #define IWL5150_UCODE_API_MIN 1 @@ -326,6 +330,7 @@ static const struct iwl_ht_params iwl5000_ht_params = {  #define IWL_DEVICE_5000						\  	.fw_name_pre = IWL5000_FW_PRE,				\  	.ucode_api_max = IWL5000_UCODE_API_MAX,			\ +	.ucode_api_ok = IWL5000_UCODE_API_OK,			\  	.ucode_api_min = IWL5000_UCODE_API_MIN,			\  	.max_inst_size = IWLAGN_RTC_INST_SIZE,			\  	.max_data_size = IWLAGN_RTC_DATA_SIZE,			\ @@ -371,6 +376,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {  	.name = "Intel(R) WiMAX/WiFi Link 5350 AGN",  	.fw_name_pre = IWL5000_FW_PRE,  	.ucode_api_max = IWL5000_UCODE_API_MAX, +	.ucode_api_ok = IWL5000_UCODE_API_OK,  	.ucode_api_min = IWL5000_UCODE_API_MIN,  	.max_inst_size = IWLAGN_RTC_INST_SIZE,  	.max_data_size = IWLAGN_RTC_DATA_SIZE, @@ -386,6 +392,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {  #define IWL_DEVICE_5150						\  	.fw_name_pre = IWL5150_FW_PRE,				\  	.ucode_api_max = IWL5150_UCODE_API_MAX,			\ +	.ucode_api_ok = IWL5150_UCODE_API_OK,			\  	.ucode_api_min = IWL5150_UCODE_API_MIN,			\  	.max_inst_size = IWLAGN_RTC_INST_SIZE,			\  	.max_data_size = IWLAGN_RTC_DATA_SIZE,			\ @@ -409,5 +416,5 @@ const struct iwl_cfg iwl5150_abg_cfg = {  	IWL_DEVICE_5150,  }; -MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 64060cd738b..f0c91505a7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -53,6 +53,8 @@  /* Oldest version we won't warn about */  #define IWL6000_UCODE_API_OK 4  #define IWL6000G2_UCODE_API_OK 5 +#define IWL6050_UCODE_API_OK 5 +#define IWL6000G2B_UCODE_API_OK 6  /* Lowest firmware API version supported */  #define IWL6000_UCODE_API_MIN 4 @@ -388,7 +390,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {  #define IWL_DEVICE_6030						\  	.fw_name_pre = IWL6030_FW_PRE,				\  	.ucode_api_max = IWL6000G2_UCODE_API_MAX,		\ -	.ucode_api_ok = IWL6000G2_UCODE_API_OK,			\ +	.ucode_api_ok = IWL6000G2B_UCODE_API_OK,		\  	.ucode_api_min = IWL6000G2_UCODE_API_MIN,		\  	.max_inst_size = IWL60_RTC_INST_SIZE,			\  	.max_data_size = IWL60_RTC_DATA_SIZE,			\ @@ -557,6 +559,6 @@ const struct iwl_cfg iwl6000_3agn_cfg = {  };  MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f1226dbf789..2a9a16f901c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -863,7 +863,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)  void iwlagn_prepare_restart(struct iwl_priv *priv)  { -	struct iwl_rxon_context *ctx;  	bool bt_full_concurrent;  	u8 bt_ci_compliance;  	u8 bt_load; @@ -872,8 +871,6 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)  	lockdep_assert_held(&priv->mutex); -	for_each_context(priv, ctx) -		ctx->vif = NULL;  	priv->is_open = 0;  	/* diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 90208094b8e..74bce97a860 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -104,15 +104,29 @@   * (see struct iwl_tfd_frame).  These 16 pointer registers are offset by 0x04   * bytes from one another.  Each TFD circular buffer in DRAM must be 256-byte   * aligned (address bits 0-7 must be 0). + * Later devices have 20 (5000 series) or 30 (higher) queues, but the registers + * for them are in different places.   *   * Bit fields in each pointer register:   *  27-0: TFD CB physical base address [35:8], must be 256-byte aligned   */ -#define FH_MEM_CBBC_LOWER_BOUND          (FH_MEM_LOWER_BOUND + 0x9D0) -#define FH_MEM_CBBC_UPPER_BOUND          (FH_MEM_LOWER_BOUND + 0xA10) +#define FH_MEM_CBBC_0_15_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0x9D0) +#define FH_MEM_CBBC_0_15_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xA10) +#define FH_MEM_CBBC_16_19_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0xBF0) +#define FH_MEM_CBBC_16_19_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xC00) +#define FH_MEM_CBBC_20_31_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0xB20) +#define FH_MEM_CBBC_20_31_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xB80) -/* Find TFD CB base pointer for given queue (range 0-15). */ -#define FH_MEM_CBBC_QUEUE(x)  (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4) +/* Find TFD CB base pointer for given queue */ +static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) +{ +	if (chnl < 16) +		return FH_MEM_CBBC_0_15_LOWER_BOUND + 4 * chnl; +	if (chnl < 20) +		return FH_MEM_CBBC_16_19_LOWER_BOUND + 4 * (chnl - 16); +	WARN_ON_ONCE(chnl >= 32); +	return FH_MEM_CBBC_20_31_LOWER_BOUND + 4 * (chnl - 20); +}  /** diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index b6805f8e9a0..c24a7134a6f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -1244,6 +1244,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,  	struct iwl_rxon_context *tmp, *ctx = NULL;  	int err;  	enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); +	bool reset = false;  	IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",  			   viftype, vif->addr); @@ -1265,6 +1266,13 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,  			tmp->interface_modes | tmp->exclusive_interface_modes;  		if (tmp->vif) { +			/* On reset we need to add the same interface again */ +			if (tmp->vif == vif) { +				reset = true; +				ctx = tmp; +				break; +			} +  			/* check if this busy context is exclusive */  			if (tmp->exclusive_interface_modes &  						BIT(tmp->vif->type)) { @@ -1291,7 +1299,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,  	ctx->vif = vif;  	err = iwl_setup_interface(priv, ctx); -	if (!err) +	if (!err || reset)  		goto out;  	ctx->vif = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 75dc20bd965..3b1069290fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -223,12 +223,33 @@  #define SCD_AIT			(SCD_BASE + 0x0c)  #define SCD_TXFACT		(SCD_BASE + 0x10)  #define SCD_ACTIVE		(SCD_BASE + 0x14) -#define SCD_QUEUE_WRPTR(x)	(SCD_BASE + 0x18 + (x) * 4) -#define SCD_QUEUE_RDPTR(x)	(SCD_BASE + 0x68 + (x) * 4)  #define SCD_QUEUECHAIN_SEL	(SCD_BASE + 0xe8)  #define SCD_AGGR_SEL		(SCD_BASE + 0x248)  #define SCD_INTERRUPT_MASK	(SCD_BASE + 0x108) -#define SCD_QUEUE_STATUS_BITS(x)	(SCD_BASE + 0x10c + (x) * 4) + +static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) +{ +	if (chnl < 20) +		return SCD_BASE + 0x18 + chnl * 4; +	WARN_ON_ONCE(chnl >= 32); +	return SCD_BASE + 0x284 + (chnl - 20) * 4; +} + +static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl) +{ +	if (chnl < 20) +		return SCD_BASE + 0x68 + chnl * 4; +	WARN_ON_ONCE(chnl >= 32); +	return SCD_BASE + 0x2B4 + (chnl - 20) * 4; +} + +static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl) +{ +	if (chnl < 20) +		return SCD_BASE + 0x10c + chnl * 4; +	WARN_ON_ONCE(chnl >= 32); +	return SCD_BASE + 0x384 + (chnl - 20) * 4; +}  /*********************** END TX SCHEDULER *************************************/ diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 3fa1ecebadf..2fa879b015b 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -103,7 +103,7 @@ static const u32 cipher_suites[] = {   * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1   * in the firmware spec   */ -static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) +static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type)  {  	int ret = -ENOTSUPP; @@ -1411,7 +1411,12 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,  		goto done;  	} -	lbs_set_authtype(priv, sme); +	ret = lbs_set_authtype(priv, sme); +	if (ret == -ENOTSUPP) { +		wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type); +		goto done; +	} +  	lbs_set_radio(priv, preamble, 1);  	/* Do the actual association */ diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 445ff21772e..2f218f9a3fd 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h @@ -48,15 +48,15 @@  #define PCIE_HOST_INT_STATUS_MASK			0xC3C  #define PCIE_SCRATCH_2_REG				0xC40  #define PCIE_SCRATCH_3_REG				0xC44 -#define PCIE_SCRATCH_4_REG				0xCC0 -#define PCIE_SCRATCH_5_REG				0xCC4 -#define PCIE_SCRATCH_6_REG				0xCC8 -#define PCIE_SCRATCH_7_REG				0xCCC -#define PCIE_SCRATCH_8_REG				0xCD0 -#define PCIE_SCRATCH_9_REG				0xCD4 -#define PCIE_SCRATCH_10_REG				0xCD8 -#define PCIE_SCRATCH_11_REG				0xCDC -#define PCIE_SCRATCH_12_REG				0xCE0 +#define PCIE_SCRATCH_4_REG				0xCD0 +#define PCIE_SCRATCH_5_REG				0xCD4 +#define PCIE_SCRATCH_6_REG				0xCD8 +#define PCIE_SCRATCH_7_REG				0xCDC +#define PCIE_SCRATCH_8_REG				0xCE0 +#define PCIE_SCRATCH_9_REG				0xCE4 +#define PCIE_SCRATCH_10_REG				0xCE8 +#define PCIE_SCRATCH_11_REG				0xCEC +#define PCIE_SCRATCH_12_REG				0xCF0  #define CPU_INTR_DNLD_RDY				BIT(0)  #define CPU_INTR_DOOR_BELL				BIT(1) diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 288b035a357..cc15fdb3606 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1941,6 +1941,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)  		rtl_deinit_deferred_work(hw);  		rtlpriv->intf_ops->adapter_stop(hw);  	} +	rtlpriv->cfg->ops->disable_interrupt(hw);  	/*deinit rfkill */  	rtl_deinit_rfkill(hw); diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 41302c7b1ad..d1afb8e3b2e 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -479,6 +479,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)  	cancel_work_sync(&wl->irq_work);  	cancel_work_sync(&wl->tx_work);  	cancel_work_sync(&wl->filter_work); +	cancel_delayed_work_sync(&wl->elp_work);  	mutex_lock(&wl->mutex); diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index f78694295c3..1b851f650e0 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -315,8 +315,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)  	if (wl->irq)  		free_irq(wl->irq, wl); -	kfree(wl_sdio);  	wl1251_free_hw(wl); +	kfree(wl_sdio);  	sdio_claim_host(func);  	sdio_release_irq(func);  |