Forráskód Böngészése

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6

Conflicts:
	drivers/net/wireless/ath/ath9k/init.c
John W. Linville 14 éve
szülő
commit
3e11210d46
35 módosított fájl, 191 hozzáadás és 199 törlés
  1. 0 1
      MAINTAINERS
  2. 20 55
      drivers/bluetooth/ath3k.c
  3. 4 0
      drivers/net/wireless/ath/ath5k/base.c
  4. 2 2
      drivers/net/wireless/ath/ath5k/dma.c
  5. 1 3
      drivers/net/wireless/ath/ath5k/pcu.c
  6. 5 5
      drivers/net/wireless/ath/ath9k/ar9002_calib.c
  7. 1 2
      drivers/net/wireless/ath/ath9k/ar9002_hw.c
  8. 1 1
      drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
  9. 2 2
      drivers/net/wireless/ath/ath9k/ar9003_hw.c
  10. 1 1
      drivers/net/wireless/ath/ath9k/htc.h
  11. 0 3
      drivers/net/wireless/ath/ath9k/htc_drv_init.c
  12. 15 6
      drivers/net/wireless/ath/ath9k/htc_drv_main.c
  13. 5 3
      drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
  14. 5 1
      drivers/net/wireless/ath/ath9k/hw.c
  15. 1 0
      drivers/net/wireless/ath/ath9k/hw.h
  16. 2 5
      drivers/net/wireless/ath/ath9k/init.c
  17. 14 5
      drivers/net/wireless/ath/ath9k/main.c
  18. 0 2
      drivers/net/wireless/ath/ath9k/xmit.c
  19. 1 0
      drivers/net/wireless/iwlwifi/iwl-4965.c
  20. 8 5
      drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
  21. 2 0
      drivers/net/wireless/iwmc3200wifi/netdev.c
  22. 1 0
      drivers/net/wireless/rt2x00/rt2x00firmware.c
  23. 1 0
      drivers/net/wireless/rt2x00/rt73usb.c
  24. 20 20
      drivers/net/wireless/rtlwifi/efuse.c
  25. 9 2
      drivers/net/wireless/rtlwifi/pci.c
  26. 1 1
      include/linux/ieee80211.h
  27. 1 0
      include/net/bluetooth/hci_core.h
  28. 9 7
      net/bluetooth/hci_conn.c
  29. 4 0
      net/bluetooth/hci_core.c
  30. 5 4
      net/bluetooth/hci_event.c
  31. 32 52
      net/bluetooth/l2cap.c
  32. 2 1
      net/bluetooth/rfcomm/core.c
  33. 2 9
      net/mac80211/agg-rx.c
  34. 11 1
      net/mac80211/main.c
  35. 3 0
      net/mac80211/tx.c

+ 0 - 1
MAINTAINERS

@@ -3323,7 +3323,6 @@ F:	drivers/net/wimax/i2400m/
 F:	include/linux/wimax/i2400m.h
 F:	include/linux/wimax/i2400m.h
 
 
 INTEL WIRELESS WIFI LINK (iwlwifi)
 INTEL WIRELESS WIFI LINK (iwlwifi)
-M:	Reinette Chatre <reinette.chatre@intel.com>
 M:	Wey-Yi Guy <wey-yi.w.guy@intel.com>
 M:	Wey-Yi Guy <wey-yi.w.guy@intel.com>
 M:	Intel Linux Wireless <ilw@linux.intel.com>
 M:	Intel Linux Wireless <ilw@linux.intel.com>
 L:	linux-wireless@vger.kernel.org
 L:	linux-wireless@vger.kernel.org

+ 20 - 55
drivers/bluetooth/ath3k.c

@@ -47,46 +47,40 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 #define USB_REQ_DFU_DNLOAD	1
 #define USB_REQ_DFU_DNLOAD	1
 #define BULK_SIZE		4096
 #define BULK_SIZE		4096
 
 
-struct ath3k_data {
-	struct usb_device *udev;
-	u8 *fw_data;
-	u32 fw_size;
-	u32 fw_sent;
-};
-
-static int ath3k_load_firmware(struct ath3k_data *data,
-				unsigned char *firmware,
-				int count)
+static int ath3k_load_firmware(struct usb_device *udev,
+				const struct firmware *firmware)
 {
 {
 	u8 *send_buf;
 	u8 *send_buf;
 	int err, pipe, len, size, sent = 0;
 	int err, pipe, len, size, sent = 0;
+	int count = firmware->size;
 
 
-	BT_DBG("ath3k %p udev %p", data, data->udev);
+	BT_DBG("udev %p", udev);
 
 
-	pipe = usb_sndctrlpipe(data->udev, 0);
+	pipe = usb_sndctrlpipe(udev, 0);
 
 
-	if ((usb_control_msg(data->udev, pipe,
+	send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+	if (!send_buf) {
+		BT_ERR("Can't allocate memory chunk for firmware");
+		return -ENOMEM;
+	}
+
+	memcpy(send_buf, firmware->data, 20);
+	if ((err = usb_control_msg(udev, pipe,
 				USB_REQ_DFU_DNLOAD,
 				USB_REQ_DFU_DNLOAD,
 				USB_TYPE_VENDOR, 0, 0,
 				USB_TYPE_VENDOR, 0, 0,
-				firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
+				send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
 		BT_ERR("Can't change to loading configuration err");
 		BT_ERR("Can't change to loading configuration err");
-		return -EBUSY;
+		goto error;
 	}
 	}
 	sent += 20;
 	sent += 20;
 	count -= 20;
 	count -= 20;
 
 
-	send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
-	if (!send_buf) {
-		BT_ERR("Can't allocate memory chunk for firmware");
-		return -ENOMEM;
-	}
-
 	while (count) {
 	while (count) {
 		size = min_t(uint, count, BULK_SIZE);
 		size = min_t(uint, count, BULK_SIZE);
-		pipe = usb_sndbulkpipe(data->udev, 0x02);
-		memcpy(send_buf, firmware + sent, size);
+		pipe = usb_sndbulkpipe(udev, 0x02);
+		memcpy(send_buf, firmware->data + sent, size);
 
 
-		err = usb_bulk_msg(data->udev, pipe, send_buf, size,
+		err = usb_bulk_msg(udev, pipe, send_buf, size,
 					&len, 3000);
 					&len, 3000);
 
 
 		if (err || (len != size)) {
 		if (err || (len != size)) {
@@ -112,57 +106,28 @@ static int ath3k_probe(struct usb_interface *intf,
 {
 {
 	const struct firmware *firmware;
 	const struct firmware *firmware;
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_device *udev = interface_to_usbdev(intf);
-	struct ath3k_data *data;
-	int size;
 
 
 	BT_DBG("intf %p id %p", intf, id);
 	BT_DBG("intf %p id %p", intf, id);
 
 
 	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
 	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	data->udev = udev;
-
 	if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
 	if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
-		kfree(data);
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
-	size = max_t(uint, firmware->size, 4096);
-	data->fw_data = kmalloc(size, GFP_KERNEL);
-	if (!data->fw_data) {
+	if (ath3k_load_firmware(udev, firmware)) {
 		release_firmware(firmware);
 		release_firmware(firmware);
-		kfree(data);
-		return -ENOMEM;
-	}
-
-	memcpy(data->fw_data, firmware->data, firmware->size);
-	data->fw_size = firmware->size;
-	data->fw_sent = 0;
-	release_firmware(firmware);
-
-	usb_set_intfdata(intf, data);
-	if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) {
-		usb_set_intfdata(intf, NULL);
-		kfree(data->fw_data);
-		kfree(data);
 		return -EIO;
 		return -EIO;
 	}
 	}
+	release_firmware(firmware);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 static void ath3k_disconnect(struct usb_interface *intf)
 static void ath3k_disconnect(struct usb_interface *intf)
 {
 {
-	struct ath3k_data *data = usb_get_intfdata(intf);
-
 	BT_DBG("ath3k_disconnect intf %p", intf);
 	BT_DBG("ath3k_disconnect intf %p", intf);
-
-	kfree(data->fw_data);
-	kfree(data);
 }
 }
 
 
 static struct usb_driver ath3k_driver = {
 static struct usb_driver ath3k_driver = {

+ 4 - 0
drivers/net/wireless/ath/ath5k/base.c

@@ -2280,6 +2280,8 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
 	int i;
 	int i;
 	bool needreset = false;
 	bool needreset = false;
 
 
+	mutex_lock(&sc->lock);
+
 	for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
 	for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
 		if (sc->txqs[i].setup) {
 		if (sc->txqs[i].setup) {
 			txq = &sc->txqs[i];
 			txq = &sc->txqs[i];
@@ -2307,6 +2309,8 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
 		ath5k_reset(sc, NULL, true);
 		ath5k_reset(sc, NULL, true);
 	}
 	}
 
 
+	mutex_unlock(&sc->lock);
+
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
 		msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
 		msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
 }
 }

+ 2 - 2
drivers/net/wireless/ath/ath5k/dma.c

@@ -838,9 +838,9 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah)
 	for (i = 0; i < qmax; i++) {
 	for (i = 0; i < qmax; i++) {
 		err = ath5k_hw_stop_tx_dma(ah, i);
 		err = ath5k_hw_stop_tx_dma(ah, i);
 		/* -EINVAL -> queue inactive */
 		/* -EINVAL -> queue inactive */
-		if (err != -EINVAL)
+		if (err && err != -EINVAL)
 			return err;
 			return err;
 	}
 	}
 
 
-	return err;
+	return 0;
 }
 }

+ 1 - 3
drivers/net/wireless/ath/ath5k/pcu.c

@@ -86,7 +86,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
 	if (!ah->ah_bwmode) {
 	if (!ah->ah_bwmode) {
 		dur = ieee80211_generic_frame_duration(sc->hw,
 		dur = ieee80211_generic_frame_duration(sc->hw,
 						NULL, len, rate);
 						NULL, len, rate);
-		return dur;
+		return le16_to_cpu(dur);
 	}
 	}
 
 
 	bitrate = rate->bitrate;
 	bitrate = rate->bitrate;
@@ -265,8 +265,6 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
 		 * what rate we should choose to TX ACKs. */
 		 * what rate we should choose to TX ACKs. */
 		tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
 		tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
 
 
-		tx_time = le16_to_cpu(tx_time);
-
 		ath5k_hw_reg_write(ah, tx_time, reg);
 		ath5k_hw_reg_write(ah, tx_time, reg);
 
 
 		if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
 		if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))

+ 5 - 5
drivers/net/wireless/ath/ath9k/ar9002_calib.c

@@ -679,10 +679,6 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
 
 
 	/* Do NF cal only at longer intervals */
 	/* Do NF cal only at longer intervals */
 	if (longcal || nfcal_pending) {
 	if (longcal || nfcal_pending) {
-		/* Do periodic PAOffset Cal */
-		ar9002_hw_pa_cal(ah, false);
-		ar9002_hw_olc_temp_compensation(ah);
-
 		/*
 		/*
 		 * Get the value from the previous NF cal and update
 		 * Get the value from the previous NF cal and update
 		 * history buffer.
 		 * history buffer.
@@ -697,8 +693,12 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
 			ath9k_hw_loadnf(ah, ah->curchan);
 			ath9k_hw_loadnf(ah, ah->curchan);
 		}
 		}
 
 
-		if (longcal)
+		if (longcal) {
 			ath9k_hw_start_nfcal(ah, false);
 			ath9k_hw_start_nfcal(ah, false);
+			/* Do periodic PAOffset Cal */
+			ar9002_hw_pa_cal(ah, false);
+			ar9002_hw_olc_temp_compensation(ah);
+		}
 	}
 	}
 
 
 	return iscaldone;
 	return iscaldone;

+ 1 - 2
drivers/net/wireless/ath/ath9k/ar9002_hw.c

@@ -426,9 +426,8 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
 		}
 		}
 
 
 		/* WAR for ASPM system hang */
 		/* WAR for ASPM system hang */
-		if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
+		if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
 			val |= (AR_WA_BIT6 | AR_WA_BIT7);
 			val |= (AR_WA_BIT6 | AR_WA_BIT7);
-		}
 
 
 		if (AR_SREV_9285E_20(ah))
 		if (AR_SREV_9285E_20(ah))
 			val |= AR_WA_BIT23;
 			val |= AR_WA_BIT23;

+ 1 - 1
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h

@@ -1842,7 +1842,7 @@ static const u32 ar9300_2p2_soc_preamble[][2] = {
 
 
 static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
 static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
 	/* Addr      allmodes  */
 	/* Addr      allmodes  */
-	{0x00004040, 0x08212e5e},
+	{0x00004040, 0x0821265e},
 	{0x00004040, 0x0008003b},
 	{0x00004040, 0x0008003b},
 	{0x00004044, 0x00000000},
 	{0x00004044, 0x00000000},
 };
 };

+ 2 - 2
drivers/net/wireless/ath/ath9k/ar9003_hw.c

@@ -146,8 +146,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 		/* Sleep Setting */
 		/* Sleep Setting */
 
 
 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-				ar9300PciePhy_clkreq_enable_L1_2p2,
-				ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
+				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
+				ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
 				2);
 				2);
 
 
 		/* Fast clock modal settings */
 		/* Fast clock modal settings */

+ 1 - 1
drivers/net/wireless/ath/ath9k/htc.h

@@ -78,7 +78,7 @@ struct tx_frame_hdr {
 	u8 node_idx;
 	u8 node_idx;
 	u8 vif_idx;
 	u8 vif_idx;
 	u8 tidno;
 	u8 tidno;
-	u32 flags; /* ATH9K_HTC_TX_* */
+	__be32 flags; /* ATH9K_HTC_TX_* */
 	u8 key_type;
 	u8 key_type;
 	u8 keyix;
 	u8 keyix;
 	u8 reserved[26];
 	u8 reserved[26];

+ 0 - 3
drivers/net/wireless/ath/ath9k/htc_drv_init.c

@@ -142,9 +142,6 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
 {
 {
 	ath9k_htc_exit_debug(priv->ah);
 	ath9k_htc_exit_debug(priv->ah);
 	ath9k_hw_deinit(priv->ah);
 	ath9k_hw_deinit(priv->ah);
-	tasklet_kill(&priv->swba_tasklet);
-	tasklet_kill(&priv->rx_tasklet);
-	tasklet_kill(&priv->tx_tasklet);
 	kfree(priv->ah);
 	kfree(priv->ah);
 	priv->ah = NULL;
 	priv->ah = NULL;
 }
 }

+ 15 - 6
drivers/net/wireless/ath/ath9k/htc_drv_main.c

@@ -1026,12 +1026,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
 	int ret = 0;
 	int ret = 0;
 	u8 cmd_rsp;
 	u8 cmd_rsp;
 
 
-	/* Cancel all the running timers/work .. */
-	cancel_work_sync(&priv->fatal_work);
-	cancel_work_sync(&priv->ps_work);
-	cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
-	ath9k_led_stop_brightness(priv);
-
 	mutex_lock(&priv->mutex);
 	mutex_lock(&priv->mutex);
 
 
 	if (priv->op_flags & OP_INVALID) {
 	if (priv->op_flags & OP_INVALID) {
@@ -1045,8 +1039,23 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
 	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 	WMI_CMD(WMI_STOP_RECV_CMDID);
 	WMI_CMD(WMI_STOP_RECV_CMDID);
+
+	tasklet_kill(&priv->swba_tasklet);
+	tasklet_kill(&priv->rx_tasklet);
+	tasklet_kill(&priv->tx_tasklet);
+
 	skb_queue_purge(&priv->tx_queue);
 	skb_queue_purge(&priv->tx_queue);
 
 
+	mutex_unlock(&priv->mutex);
+
+	/* Cancel all the running timers/work .. */
+	cancel_work_sync(&priv->fatal_work);
+	cancel_work_sync(&priv->ps_work);
+	cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
+	ath9k_led_stop_brightness(priv);
+
+	mutex_lock(&priv->mutex);
+
 	/* Remove monitor interface here */
 	/* Remove monitor interface here */
 	if (ah->opmode == NL80211_IFTYPE_MONITOR) {
 	if (ah->opmode == NL80211_IFTYPE_MONITOR) {
 		if (ath9k_htc_remove_monitor_interface(priv))
 		if (ath9k_htc_remove_monitor_interface(priv))

+ 5 - 3
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c

@@ -113,6 +113,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
 
 
 	if (ieee80211_is_data(fc)) {
 	if (ieee80211_is_data(fc)) {
 		struct tx_frame_hdr tx_hdr;
 		struct tx_frame_hdr tx_hdr;
+		u32 flags = 0;
 		u8 *qc;
 		u8 *qc;
 
 
 		memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
 		memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
@@ -136,13 +137,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
 		/* Check for RTS protection */
 		/* Check for RTS protection */
 		if (priv->hw->wiphy->rts_threshold != (u32) -1)
 		if (priv->hw->wiphy->rts_threshold != (u32) -1)
 			if (skb->len > priv->hw->wiphy->rts_threshold)
 			if (skb->len > priv->hw->wiphy->rts_threshold)
-				tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS;
+				flags |= ATH9K_HTC_TX_RTSCTS;
 
 
 		/* CTS-to-self */
 		/* CTS-to-self */
-		if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) &&
+		if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
 		    (priv->op_flags & OP_PROTECT_ENABLE))
 		    (priv->op_flags & OP_PROTECT_ENABLE))
-			tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY;
+			flags |= ATH9K_HTC_TX_CTSONLY;
 
 
+		tx_hdr.flags = cpu_to_be32(flags);
 		tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
 		tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
 		if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
 		if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
 			tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
 			tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;

+ 5 - 1
drivers/net/wireless/ath/ath9k/hw.c

@@ -369,6 +369,9 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
 	else
 	else
 		ah->config.ht_enable = 0;
 		ah->config.ht_enable = 0;
 
 
+	/* PAPRD needs some more work to be enabled */
+	ah->config.paprd_disable = 1;
+
 	ah->config.rx_intr_mitigation = true;
 	ah->config.rx_intr_mitigation = true;
 	ah->config.pcieSerDesWrite = true;
 	ah->config.pcieSerDesWrite = true;
 
 
@@ -1971,7 +1974,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 		pCap->rx_status_len = sizeof(struct ar9003_rxs);
 		pCap->rx_status_len = sizeof(struct ar9003_rxs);
 		pCap->tx_desc_len = sizeof(struct ar9003_txc);
 		pCap->tx_desc_len = sizeof(struct ar9003_txc);
 		pCap->txs_len = sizeof(struct ar9003_txs);
 		pCap->txs_len = sizeof(struct ar9003_txs);
-		if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
+		if (!ah->config.paprd_disable &&
+		    ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
 			pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
 			pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
 	} else {
 	} else {
 		pCap->tx_desc_len = sizeof(struct ath_desc);
 		pCap->tx_desc_len = sizeof(struct ath_desc);

+ 1 - 0
drivers/net/wireless/ath/ath9k/hw.h

@@ -228,6 +228,7 @@ struct ath9k_ops_config {
 	u32 pcie_waen;
 	u32 pcie_waen;
 	u8 analog_shiftreg;
 	u8 analog_shiftreg;
 	u8 ht_enable;
 	u8 ht_enable;
+	u8 paprd_disable;
 	u32 ofdm_trig_low;
 	u32 ofdm_trig_low;
 	u32 ofdm_trig_high;
 	u32 ofdm_trig_high;
 	u32 cck_trig_high;
 	u32 cck_trig_high;

+ 2 - 5
drivers/net/wireless/ath/ath9k/init.c

@@ -600,8 +600,6 @@ err_btcoex:
 err_queues:
 err_queues:
 	ath9k_hw_deinit(ah);
 	ath9k_hw_deinit(ah);
 err_hw:
 err_hw:
-	tasklet_kill(&sc->intr_tq);
-	tasklet_kill(&sc->bcon_tasklet);
 
 
 	kfree(ah);
 	kfree(ah);
 	sc->sc_ah = NULL;
 	sc->sc_ah = NULL;
@@ -805,9 +803,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
 
 
 	ath9k_hw_deinit(sc->sc_ah);
 	ath9k_hw_deinit(sc->sc_ah);
 
 
-	tasklet_kill(&sc->intr_tq);
-	tasklet_kill(&sc->bcon_tasklet);
-
 	kfree(sc->sc_ah);
 	kfree(sc->sc_ah);
 	sc->sc_ah = NULL;
 	sc->sc_ah = NULL;
 }
 }
@@ -821,6 +816,8 @@ void ath9k_deinit_device(struct ath_softc *sc)
 	wiphy_rfkill_stop_polling(sc->hw->wiphy);
 	wiphy_rfkill_stop_polling(sc->hw->wiphy);
 	ath_deinit_leds(sc);
 	ath_deinit_leds(sc);
 
 
+	ath9k_ps_restore(sc);
+
 	ieee80211_unregister_hw(hw);
 	ieee80211_unregister_hw(hw);
 	pm_qos_remove_request(&sc->pm_qos_req);
 	pm_qos_remove_request(&sc->pm_qos_req);
 	ath_rx_cleanup(sc);
 	ath_rx_cleanup(sc);

+ 14 - 5
drivers/net/wireless/ath/ath9k/main.c

@@ -611,14 +611,12 @@ void ath9k_tasklet(unsigned long data)
 	u32 status = sc->intrstatus;
 	u32 status = sc->intrstatus;
 	u32 rxmask;
 	u32 rxmask;
 
 
-	ath9k_ps_wakeup(sc);
-
 	if (status & ATH9K_INT_FATAL) {
 	if (status & ATH9K_INT_FATAL) {
 		ath_reset(sc, true);
 		ath_reset(sc, true);
-		ath9k_ps_restore(sc);
 		return;
 		return;
 	}
 	}
 
 
+	ath9k_ps_wakeup(sc);
 	spin_lock(&sc->sc_pcu_lock);
 	spin_lock(&sc->sc_pcu_lock);
 
 
 	/*
 	/*
@@ -939,8 +937,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
 
 
 	spin_unlock_bh(&sc->sc_pcu_lock);
 	spin_unlock_bh(&sc->sc_pcu_lock);
 	ath9k_ps_restore(sc);
 	ath9k_ps_restore(sc);
-
-	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
 }
 }
 
 
 int ath_reset(struct ath_softc *sc, bool retry_tx)
 int ath_reset(struct ath_softc *sc, bool retry_tx)
@@ -953,6 +949,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
 	/* Stop ANI */
 	/* Stop ANI */
 	del_timer_sync(&common->ani.timer);
 	del_timer_sync(&common->ani.timer);
 
 
+	ath9k_ps_wakeup(sc);
 	spin_lock_bh(&sc->sc_pcu_lock);
 	spin_lock_bh(&sc->sc_pcu_lock);
 
 
 	ieee80211_stop_queues(hw);
 	ieee80211_stop_queues(hw);
@@ -999,6 +996,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
 
 
 	/* Start ANI */
 	/* Start ANI */
 	ath_start_ani(common);
 	ath_start_ani(common);
+	ath9k_ps_restore(sc);
 
 
 	return r;
 	return r;
 }
 }
@@ -1220,6 +1218,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
 
 	spin_lock_bh(&sc->sc_pcu_lock);
 	spin_lock_bh(&sc->sc_pcu_lock);
 
 
+	/* prevent tasklets to enable interrupts once we disable them */
+	ah->imask &= ~ATH9K_INT_GLOBAL;
+
 	/* make sure h/w will not generate any interrupt
 	/* make sure h/w will not generate any interrupt
 	 * before setting the invalid flag. */
 	 * before setting the invalid flag. */
 	ath9k_hw_disable_interrupts(ah);
 	ath9k_hw_disable_interrupts(ah);
@@ -1242,6 +1243,12 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
 
 	spin_unlock_bh(&sc->sc_pcu_lock);
 	spin_unlock_bh(&sc->sc_pcu_lock);
 
 
+	/* we can now sync irq and kill any running tasklets, since we already
+	 * disabled interrupts and not holding a spin lock */
+	synchronize_irq(sc->irq);
+	tasklet_kill(&sc->intr_tq);
+	tasklet_kill(&sc->bcon_tasklet);
+
 	ath9k_ps_restore(sc);
 	ath9k_ps_restore(sc);
 
 
 	sc->ps_idle = true;
 	sc->ps_idle = true;
@@ -1706,7 +1713,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 
 
 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
 		sc->config.txpowlimit = 2 * conf->power_level;
 		sc->config.txpowlimit = 2 * conf->power_level;
+		ath9k_ps_wakeup(sc);
 		ath_update_txpow(sc);
 		ath_update_txpow(sc);
+		ath9k_ps_restore(sc);
 	}
 	}
 
 
 	if (disable_radio) {
 	if (disable_radio) {

+ 0 - 2
drivers/net/wireless/ath/ath9k/xmit.c

@@ -2173,9 +2173,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
 	if (needreset) {
 	if (needreset) {
 		ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
 		ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
 			"tx hung, resetting the chip\n");
 			"tx hung, resetting the chip\n");
-		ath9k_ps_wakeup(sc);
 		ath_reset(sc, true);
 		ath_reset(sc, true);
-		ath9k_ps_restore(sc);
 	}
 	}
 
 
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,

+ 1 - 0
drivers/net/wireless/iwlwifi/iwl-4965.c

@@ -2629,6 +2629,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
 	.fw_name_pre = IWL4965_FW_PRE,
 	.fw_name_pre = IWL4965_FW_PRE,
 	.ucode_api_max = IWL4965_UCODE_API_MAX,
 	.ucode_api_max = IWL4965_UCODE_API_MAX,
 	.ucode_api_min = IWL4965_UCODE_API_MIN,
 	.ucode_api_min = IWL4965_UCODE_API_MIN,
+	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.valid_tx_ant = ANT_AB,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
 	.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
 	.eeprom_ver = EEPROM_4965_EEPROM_VERSION,

+ 8 - 5
drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c

@@ -152,11 +152,14 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
 
 
 	eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
 	eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
 
 
-	priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
+	if (!priv->cfg->sku) {
+		/* not using sku overwrite */
+		priv->cfg->sku =
+			((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
 			EEPROM_SKU_CAP_BAND_POS);
 			EEPROM_SKU_CAP_BAND_POS);
-	if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
-		priv->cfg->sku |= IWL_SKU_N;
-
+		if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
+			priv->cfg->sku |= IWL_SKU_N;
+	}
 	if (!priv->cfg->sku) {
 	if (!priv->cfg->sku) {
 		IWL_ERR(priv, "Invalid device sku\n");
 		IWL_ERR(priv, "Invalid device sku\n");
 		return -EINVAL;
 		return -EINVAL;
@@ -168,7 +171,7 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
 		/* not using .cfg overwrite */
 		/* not using .cfg overwrite */
 		radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 		radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 		priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
 		priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
-		priv->cfg->valid_rx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
+		priv->cfg->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
 		if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
 		if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
 			IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n",
 			IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n",
 				priv->cfg->valid_tx_ant,
 				priv->cfg->valid_tx_ant,

+ 2 - 0
drivers/net/wireless/iwmc3200wifi/netdev.c

@@ -126,6 +126,7 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
 	ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
 	ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
 	if (!ndev) {
 	if (!ndev) {
 		dev_err(dev, "no memory for network device instance\n");
 		dev_err(dev, "no memory for network device instance\n");
+		ret = -ENOMEM;
 		goto out_priv;
 		goto out_priv;
 	}
 	}
 
 
@@ -138,6 +139,7 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
 				    GFP_KERNEL);
 				    GFP_KERNEL);
 	if (!iwm->umac_profile) {
 	if (!iwm->umac_profile) {
 		dev_err(dev, "Couldn't alloc memory for profile\n");
 		dev_err(dev, "Couldn't alloc memory for profile\n");
+		ret = -ENOMEM;
 		goto out_profile;
 		goto out_profile;
 	}
 	}
 
 

+ 1 - 0
drivers/net/wireless/rt2x00/rt2x00firmware.c

@@ -58,6 +58,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
 
 
 	if (!fw || !fw->size || !fw->data) {
 	if (!fw || !fw->size || !fw->data) {
 		ERROR(rt2x00dev, "Failed to read Firmware.\n");
 		ERROR(rt2x00dev, "Failed to read Firmware.\n");
+		release_firmware(fw);
 		return -ENOENT;
 		return -ENOENT;
 	}
 	}
 
 

+ 1 - 0
drivers/net/wireless/rt2x00/rt73usb.c

@@ -2446,6 +2446,7 @@ static struct usb_device_id rt73usb_device_table[] = {
 	{ USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Qcom */
 	/* Qcom */
 	{ USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },

+ 20 - 20
drivers/net/wireless/rtlwifi/efuse.c

@@ -726,9 +726,9 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
 }
 }
 
 
 static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
 static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
-				u8 efuse_data, u8 offset, int *bcontinual,
-				u8 *write_state, struct pgpkt_struct target_pkt,
-				int *repeat_times, int *bresult, u8 word_en)
+			u8 efuse_data, u8 offset, int *bcontinual,
+			u8 *write_state, struct pgpkt_struct *target_pkt,
+			int *repeat_times, int *bresult, u8 word_en)
 {
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct pgpkt_struct tmp_pkt;
 	struct pgpkt_struct tmp_pkt;
@@ -744,8 +744,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
 	tmp_pkt.word_en = tmp_header & 0x0F;
 	tmp_pkt.word_en = tmp_header & 0x0F;
 	tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
 	tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
 
 
-	if (tmp_pkt.offset != target_pkt.offset) {
-		efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1;
+	if (tmp_pkt.offset != target_pkt->offset) {
+		*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
 		*write_state = PG_STATE_HEADER;
 		*write_state = PG_STATE_HEADER;
 	} else {
 	} else {
 		for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
 		for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
@@ -756,23 +756,23 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
 		}
 		}
 
 
 		if (bdataempty == false) {
 		if (bdataempty == false) {
-			efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1;
+			*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
 			*write_state = PG_STATE_HEADER;
 			*write_state = PG_STATE_HEADER;
 		} else {
 		} else {
 			match_word_en = 0x0F;
 			match_word_en = 0x0F;
-			if (!((target_pkt.word_en & BIT(0)) |
+			if (!((target_pkt->word_en & BIT(0)) |
 			     (tmp_pkt.word_en & BIT(0))))
 			     (tmp_pkt.word_en & BIT(0))))
 				match_word_en &= (~BIT(0));
 				match_word_en &= (~BIT(0));
 
 
-			if (!((target_pkt.word_en & BIT(1)) |
+			if (!((target_pkt->word_en & BIT(1)) |
 			     (tmp_pkt.word_en & BIT(1))))
 			     (tmp_pkt.word_en & BIT(1))))
 				match_word_en &= (~BIT(1));
 				match_word_en &= (~BIT(1));
 
 
-			if (!((target_pkt.word_en & BIT(2)) |
+			if (!((target_pkt->word_en & BIT(2)) |
 			     (tmp_pkt.word_en & BIT(2))))
 			     (tmp_pkt.word_en & BIT(2))))
 				match_word_en &= (~BIT(2));
 				match_word_en &= (~BIT(2));
 
 
-			if (!((target_pkt.word_en & BIT(3)) |
+			if (!((target_pkt->word_en & BIT(3)) |
 			     (tmp_pkt.word_en & BIT(3))))
 			     (tmp_pkt.word_en & BIT(3))))
 				match_word_en &= (~BIT(3));
 				match_word_en &= (~BIT(3));
 
 
@@ -780,7 +780,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
 				badworden = efuse_word_enable_data_write(
 				badworden = efuse_word_enable_data_write(
 							    hw, *efuse_addr + 1,
 							    hw, *efuse_addr + 1,
 							    tmp_pkt.word_en,
 							    tmp_pkt.word_en,
-							    target_pkt.data);
+							    target_pkt->data);
 
 
 				if (0x0F != (badworden & 0x0F)) {
 				if (0x0F != (badworden & 0x0F)) {
 					u8 reorg_offset = offset;
 					u8 reorg_offset = offset;
@@ -791,26 +791,26 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
 				}
 				}
 
 
 				tmp_word_en = 0x0F;
 				tmp_word_en = 0x0F;
-				if ((target_pkt.word_en & BIT(0)) ^
+				if ((target_pkt->word_en & BIT(0)) ^
 				    (match_word_en & BIT(0)))
 				    (match_word_en & BIT(0)))
 					tmp_word_en &= (~BIT(0));
 					tmp_word_en &= (~BIT(0));
 
 
-				if ((target_pkt.word_en & BIT(1)) ^
+				if ((target_pkt->word_en & BIT(1)) ^
 				    (match_word_en & BIT(1)))
 				    (match_word_en & BIT(1)))
 					tmp_word_en &= (~BIT(1));
 					tmp_word_en &= (~BIT(1));
 
 
-				if ((target_pkt.word_en & BIT(2)) ^
+				if ((target_pkt->word_en & BIT(2)) ^
 					(match_word_en & BIT(2)))
 					(match_word_en & BIT(2)))
 					tmp_word_en &= (~BIT(2));
 					tmp_word_en &= (~BIT(2));
 
 
-				if ((target_pkt.word_en & BIT(3)) ^
+				if ((target_pkt->word_en & BIT(3)) ^
 				    (match_word_en & BIT(3)))
 				    (match_word_en & BIT(3)))
 					tmp_word_en &= (~BIT(3));
 					tmp_word_en &= (~BIT(3));
 
 
 				if ((tmp_word_en & 0x0F) != 0x0F) {
 				if ((tmp_word_en & 0x0F) != 0x0F) {
 					*efuse_addr = efuse_get_current_size(hw);
 					*efuse_addr = efuse_get_current_size(hw);
-					target_pkt.offset = offset;
-					target_pkt.word_en = tmp_word_en;
+					target_pkt->offset = offset;
+					target_pkt->word_en = tmp_word_en;
 				} else
 				} else
 					*bcontinual = false;
 					*bcontinual = false;
 				*write_state = PG_STATE_HEADER;
 				*write_state = PG_STATE_HEADER;
@@ -821,8 +821,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
 				}
 				}
 			} else {
 			} else {
 				*efuse_addr += (2 * tmp_word_cnts) + 1;
 				*efuse_addr += (2 * tmp_word_cnts) + 1;
-				target_pkt.offset = offset;
-				target_pkt.word_en = word_en;
+				target_pkt->offset = offset;
+				target_pkt->word_en = word_en;
 				*write_state = PG_STATE_HEADER;
 				*write_state = PG_STATE_HEADER;
 			}
 			}
 		}
 		}
@@ -938,7 +938,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
 				efuse_write_data_case1(hw, &efuse_addr,
 				efuse_write_data_case1(hw, &efuse_addr,
 						       efuse_data, offset,
 						       efuse_data, offset,
 						       &bcontinual,
 						       &bcontinual,
-						       &write_state, target_pkt,
+						       &write_state, &target_pkt,
 						       &repeat_times, &bresult,
 						       &repeat_times, &bresult,
 						       word_en);
 						       word_en);
 			else
 			else

+ 9 - 2
drivers/net/wireless/rtlwifi/pci.c

@@ -619,6 +619,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
 					struct sk_buff *uskb = NULL;
 					struct sk_buff *uskb = NULL;
 					u8 *pdata;
 					u8 *pdata;
 					uskb = dev_alloc_skb(skb->len + 128);
 					uskb = dev_alloc_skb(skb->len + 128);
+					if (!uskb) {
+						RT_TRACE(rtlpriv,
+							(COMP_INTR | COMP_RECV),
+							DBG_EMERG,
+							("can't alloc rx skb\n"));
+						goto done;
+					}
 					memcpy(IEEE80211_SKB_RXCB(uskb),
 					memcpy(IEEE80211_SKB_RXCB(uskb),
 							&rx_status,
 							&rx_status,
 							sizeof(rx_status));
 							sizeof(rx_status));
@@ -641,7 +648,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
 			new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
 			new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
 			if (unlikely(!new_skb)) {
 			if (unlikely(!new_skb)) {
 				RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
 				RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
-					 DBG_DMESG,
+					 DBG_EMERG,
 					 ("can't alloc skb for rx\n"));
 					 ("can't alloc skb for rx\n"));
 				goto done;
 				goto done;
 			}
 			}
@@ -1066,9 +1073,9 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
 			struct sk_buff *skb =
 			struct sk_buff *skb =
 			    dev_alloc_skb(rtlpci->rxbuffersize);
 			    dev_alloc_skb(rtlpci->rxbuffersize);
 			u32 bufferaddress;
 			u32 bufferaddress;
-			entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
 			if (!skb)
 			if (!skb)
 				return 0;
 				return 0;
+			entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
 
 
 			/*skb->dev = dev; */
 			/*skb->dev = dev; */
 
 

+ 1 - 1
include/linux/ieee80211.h

@@ -959,7 +959,7 @@ struct ieee80211_ht_info {
 /* block-ack parameters */
 /* block-ack parameters */
 #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
 #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
 #define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
 #define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
-#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
 #define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
 #define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
 #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
 #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
 
 

+ 1 - 0
include/net/bluetooth/hci_core.h

@@ -184,6 +184,7 @@ struct hci_conn {
 	__u32		 link_mode;
 	__u32		 link_mode;
 	__u8             auth_type;
 	__u8             auth_type;
 	__u8             sec_level;
 	__u8             sec_level;
+	__u8		 pending_sec_level;
 	__u8             power_save;
 	__u8             power_save;
 	__u16            disc_timeout;
 	__u16            disc_timeout;
 	unsigned long	 pend;
 	unsigned long	 pend;

+ 9 - 7
net/bluetooth/hci_conn.c

@@ -379,14 +379,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
 	hci_conn_hold(acl);
 	hci_conn_hold(acl);
 
 
 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
-		acl->sec_level = sec_level;
+		acl->sec_level = BT_SECURITY_LOW;
+		acl->pending_sec_level = sec_level;
 		acl->auth_type = auth_type;
 		acl->auth_type = auth_type;
 		hci_acl_connect(acl);
 		hci_acl_connect(acl);
-	} else {
-		if (acl->sec_level < sec_level)
-			acl->sec_level = sec_level;
-		if (acl->auth_type < auth_type)
-			acl->auth_type = auth_type;
 	}
 	}
 
 
 	if (type == ACL_LINK)
 	if (type == ACL_LINK)
@@ -442,11 +438,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 {
 {
 	BT_DBG("conn %p", conn);
 	BT_DBG("conn %p", conn);
 
 
+	if (conn->pending_sec_level > sec_level)
+		sec_level = conn->pending_sec_level;
+
 	if (sec_level > conn->sec_level)
 	if (sec_level > conn->sec_level)
-		conn->sec_level = sec_level;
+		conn->pending_sec_level = sec_level;
 	else if (conn->link_mode & HCI_LM_AUTH)
 	else if (conn->link_mode & HCI_LM_AUTH)
 		return 1;
 		return 1;
 
 
+	/* Make sure we preserve an existing MITM requirement*/
+	auth_type |= (conn->auth_type & 0x01);
+
 	conn->auth_type = auth_type;
 	conn->auth_type = auth_type;
 
 
 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {

+ 4 - 0
net/bluetooth/hci_core.c

@@ -1011,6 +1011,10 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
 
 	destroy_workqueue(hdev->workqueue);
 	destroy_workqueue(hdev->workqueue);
 
 
+	hci_dev_lock_bh(hdev);
+	hci_blacklist_clear(hdev);
+	hci_dev_unlock_bh(hdev);
+
 	__hci_dev_put(hdev);
 	__hci_dev_put(hdev);
 
 
 	return 0;
 	return 0;

+ 5 - 4
net/bluetooth/hci_event.c

@@ -692,13 +692,13 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
 	if (conn->state != BT_CONFIG || !conn->out)
 	if (conn->state != BT_CONFIG || !conn->out)
 		return 0;
 		return 0;
 
 
-	if (conn->sec_level == BT_SECURITY_SDP)
+	if (conn->pending_sec_level == BT_SECURITY_SDP)
 		return 0;
 		return 0;
 
 
 	/* Only request authentication for SSP connections or non-SSP
 	/* Only request authentication for SSP connections or non-SSP
 	 * devices with sec_level HIGH */
 	 * devices with sec_level HIGH */
 	if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
 	if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
-					conn->sec_level != BT_SECURITY_HIGH)
+				conn->pending_sec_level != BT_SECURITY_HIGH)
 		return 0;
 		return 0;
 
 
 	return 1;
 	return 1;
@@ -1095,9 +1095,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 
 
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
 	if (conn) {
 	if (conn) {
-		if (!ev->status)
+		if (!ev->status) {
 			conn->link_mode |= HCI_LM_AUTH;
 			conn->link_mode |= HCI_LM_AUTH;
-		else
+			conn->sec_level = conn->pending_sec_level;
+		} else
 			conn->sec_level = BT_SECURITY_LOW;
 			conn->sec_level = BT_SECURITY_LOW;
 
 
 		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
 		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);

+ 32 - 52
net/bluetooth/l2cap.c

@@ -305,33 +305,44 @@ static void l2cap_chan_del(struct sock *sk, int err)
 	}
 	}
 }
 }
 
 
-/* Service level security */
-static inline int l2cap_check_security(struct sock *sk)
+static inline u8 l2cap_get_auth_type(struct sock *sk)
 {
 {
-	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-	__u8 auth_type;
+	if (sk->sk_type == SOCK_RAW) {
+		switch (l2cap_pi(sk)->sec_level) {
+		case BT_SECURITY_HIGH:
+			return HCI_AT_DEDICATED_BONDING_MITM;
+		case BT_SECURITY_MEDIUM:
+			return HCI_AT_DEDICATED_BONDING;
+		default:
+			return HCI_AT_NO_BONDING;
+		}
+	} else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
+		if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
+			l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
 
 
-	if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
 		if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
 		if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
-			auth_type = HCI_AT_NO_BONDING_MITM;
+			return HCI_AT_NO_BONDING_MITM;
 		else
 		else
-			auth_type = HCI_AT_NO_BONDING;
-
-		if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
-			l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
+			return HCI_AT_NO_BONDING;
 	} else {
 	} else {
 		switch (l2cap_pi(sk)->sec_level) {
 		switch (l2cap_pi(sk)->sec_level) {
 		case BT_SECURITY_HIGH:
 		case BT_SECURITY_HIGH:
-			auth_type = HCI_AT_GENERAL_BONDING_MITM;
-			break;
+			return HCI_AT_GENERAL_BONDING_MITM;
 		case BT_SECURITY_MEDIUM:
 		case BT_SECURITY_MEDIUM:
-			auth_type = HCI_AT_GENERAL_BONDING;
-			break;
+			return HCI_AT_GENERAL_BONDING;
 		default:
 		default:
-			auth_type = HCI_AT_NO_BONDING;
-			break;
+			return HCI_AT_NO_BONDING;
 		}
 		}
 	}
 	}
+}
+
+/* Service level security */
+static inline int l2cap_check_security(struct sock *sk)
+{
+	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+	__u8 auth_type;
+
+	auth_type = l2cap_get_auth_type(sk);
 
 
 	return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
 	return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
 								auth_type);
 								auth_type);
@@ -1068,39 +1079,7 @@ static int l2cap_do_connect(struct sock *sk)
 
 
 	err = -ENOMEM;
 	err = -ENOMEM;
 
 
-	if (sk->sk_type == SOCK_RAW) {
-		switch (l2cap_pi(sk)->sec_level) {
-		case BT_SECURITY_HIGH:
-			auth_type = HCI_AT_DEDICATED_BONDING_MITM;
-			break;
-		case BT_SECURITY_MEDIUM:
-			auth_type = HCI_AT_DEDICATED_BONDING;
-			break;
-		default:
-			auth_type = HCI_AT_NO_BONDING;
-			break;
-		}
-	} else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
-		if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
-			auth_type = HCI_AT_NO_BONDING_MITM;
-		else
-			auth_type = HCI_AT_NO_BONDING;
-
-		if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
-			l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
-	} else {
-		switch (l2cap_pi(sk)->sec_level) {
-		case BT_SECURITY_HIGH:
-			auth_type = HCI_AT_GENERAL_BONDING_MITM;
-			break;
-		case BT_SECURITY_MEDIUM:
-			auth_type = HCI_AT_GENERAL_BONDING;
-			break;
-		default:
-			auth_type = HCI_AT_NO_BONDING;
-			break;
-		}
-	}
+	auth_type = l2cap_get_auth_type(sk);
 
 
 	hcon = hci_connect(hdev, ACL_LINK, dst,
 	hcon = hci_connect(hdev, ACL_LINK, dst,
 					l2cap_pi(sk)->sec_level, auth_type);
 					l2cap_pi(sk)->sec_level, auth_type);
@@ -1127,7 +1106,8 @@ static int l2cap_do_connect(struct sock *sk)
 		if (sk->sk_type != SOCK_SEQPACKET &&
 		if (sk->sk_type != SOCK_SEQPACKET &&
 				sk->sk_type != SOCK_STREAM) {
 				sk->sk_type != SOCK_STREAM) {
 			l2cap_sock_clear_timer(sk);
 			l2cap_sock_clear_timer(sk);
-			sk->sk_state = BT_CONNECTED;
+			if (l2cap_check_security(sk))
+				sk->sk_state = BT_CONNECTED;
 		} else
 		} else
 			l2cap_do_start(sk);
 			l2cap_do_start(sk);
 	}
 	}
@@ -1893,8 +1873,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
 		if (pi->mode == L2CAP_MODE_STREAMING) {
 		if (pi->mode == L2CAP_MODE_STREAMING) {
 			l2cap_streaming_send(sk);
 			l2cap_streaming_send(sk);
 		} else {
 		} else {
-			if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
-					pi->conn_state && L2CAP_CONN_WAIT_F) {
+			if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+					(pi->conn_state & L2CAP_CONN_WAIT_F)) {
 				err = len;
 				err = len;
 				break;
 				break;
 			}
 			}

+ 2 - 1
net/bluetooth/rfcomm/core.c

@@ -1164,7 +1164,8 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
 			 * initiator rfcomm_process_rx already calls
 			 * initiator rfcomm_process_rx already calls
 			 * rfcomm_session_put() */
 			 * rfcomm_session_put() */
 			if (s->sock->sk->sk_state != BT_CLOSED)
 			if (s->sock->sk->sk_state != BT_CLOSED)
-				rfcomm_session_put(s);
+				if (list_empty(&s->dlcs))
+					rfcomm_session_put(s);
 			break;
 			break;
 		}
 		}
 	}
 	}

+ 2 - 9
net/mac80211/agg-rx.c

@@ -185,8 +185,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 				     struct ieee80211_mgmt *mgmt,
 				     struct ieee80211_mgmt *mgmt,
 				     size_t len)
 				     size_t len)
 {
 {
-	struct ieee80211_hw *hw = &local->hw;
-	struct ieee80211_conf *conf = &hw->conf;
 	struct tid_ampdu_rx *tid_agg_rx;
 	struct tid_ampdu_rx *tid_agg_rx;
 	u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
 	u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
 	u8 dialog_token;
 	u8 dialog_token;
@@ -231,13 +229,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 		goto end_no_lock;
 		goto end_no_lock;
 	}
 	}
 	/* determine default buffer size */
 	/* determine default buffer size */
-	if (buf_size == 0) {
-		struct ieee80211_supported_band *sband;
-
-		sband = local->hw.wiphy->bands[conf->channel->band];
-		buf_size = IEEE80211_MIN_AMPDU_BUF;
-		buf_size = buf_size << sband->ht_cap.ampdu_factor;
-	}
+	if (buf_size == 0)
+		buf_size = IEEE80211_MAX_AMPDU_BUF;
 
 
 	/* make sure the size doesn't exceed the maximum supported by the hw */
 	/* make sure the size doesn't exceed the maximum supported by the hw */
 	if (buf_size > local->hw.max_rx_aggregation_subframes)
 	if (buf_size > local->hw.max_rx_aggregation_subframes)

+ 11 - 1
net/mac80211/main.c

@@ -39,6 +39,8 @@ module_param(ieee80211_disable_40mhz_24ghz, bool, 0644);
 MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
 MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
 		 "Disable 40MHz support in the 2.4GHz band");
 		 "Disable 40MHz support in the 2.4GHz band");
 
 
+static struct lock_class_key ieee80211_rx_skb_queue_class;
+
 void ieee80211_configure_filter(struct ieee80211_local *local)
 void ieee80211_configure_filter(struct ieee80211_local *local)
 {
 {
 	u64 mc;
 	u64 mc;
@@ -570,7 +572,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 	spin_lock_init(&local->filter_lock);
 	spin_lock_init(&local->filter_lock);
 	spin_lock_init(&local->queue_stop_reason_lock);
 	spin_lock_init(&local->queue_stop_reason_lock);
 
 
-	skb_queue_head_init(&local->rx_skb_queue);
+	/*
+	 * The rx_skb_queue is only accessed from tasklets,
+	 * but other SKB queues are used from within IRQ
+	 * context. Therefore, this one needs a different
+	 * locking class so our direct, non-irq-safe use of
+	 * the queue's lock doesn't throw lockdep warnings.
+	 */
+	skb_queue_head_init_class(&local->rx_skb_queue,
+				  &ieee80211_rx_skb_queue_class);
 
 
 	INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
 	INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
 
 

+ 3 - 0
net/mac80211/tx.c

@@ -2230,6 +2230,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 
 
 	sdata = vif_to_sdata(vif);
 	sdata = vif_to_sdata(vif);
 
 
+	if (!ieee80211_sdata_running(sdata))
+		goto out;
+
 	if (tim_offset)
 	if (tim_offset)
 		*tim_offset = 0;
 		*tim_offset = 0;
 	if (tim_length)
 	if (tim_length)