Browse Source

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

John W. Linville 15 years ago
parent
commit
ae3568adf4
100 changed files with 2651 additions and 2279 deletions
  1. 5 15
      MAINTAINERS
  2. 12 0
      drivers/bluetooth/Kconfig
  3. 1 0
      drivers/bluetooth/Makefile
  4. 1 2
      drivers/bluetooth/bcm203x.c
  5. 1 1
      drivers/bluetooth/bpa10x.c
  6. 1 1
      drivers/bluetooth/btmrvl_debugfs.c
  7. 3 2
      drivers/bluetooth/btmrvl_drv.h
  8. 4 1
      drivers/bluetooth/btmrvl_main.c
  9. 55 56
      drivers/bluetooth/btmrvl_sdio.c
  10. 7 6
      drivers/bluetooth/btusb.c
  11. 1 1
      drivers/bluetooth/dtl1_cs.c
  12. 235 0
      drivers/bluetooth/hci_ath.c
  13. 2 2
      drivers/bluetooth/hci_bcsp.c
  14. 4 103
      drivers/bluetooth/hci_h4.c
  15. 18 2
      drivers/bluetooth/hci_ldisc.c
  16. 3 3
      drivers/bluetooth/hci_ll.c
  17. 13 2
      drivers/bluetooth/hci_uart.h
  18. 24 29
      drivers/net/wireless/adm8211.c
  19. 80 88
      drivers/net/wireless/at76c50x-usb.c
  20. 3 4
      drivers/net/wireless/ath/ar9170/cmd.c
  21. 2 2
      drivers/net/wireless/ath/ar9170/led.c
  22. 99 92
      drivers/net/wireless/ath/ar9170/main.c
  23. 3 5
      drivers/net/wireless/ath/ar9170/phy.c
  24. 18 0
      drivers/net/wireless/ath/ath5k/debug.c
  25. 2 5
      drivers/net/wireless/ath/ath9k/ahb.c
  26. 3 0
      drivers/net/wireless/ath/ath9k/ar5008_phy.c
  27. 4 2
      drivers/net/wireless/ath/ath9k/ar9002_phy.c
  28. 3 0
      drivers/net/wireless/ath/ath9k/ar9003_phy.c
  29. 1 1
      drivers/net/wireless/ath/ath9k/ath9k.h
  30. 2 19
      drivers/net/wireless/ath/ath9k/calib.c
  31. 9 0
      drivers/net/wireless/ath/ath9k/htc_drv_main.c
  32. 2 1
      drivers/net/wireless/ath/ath9k/hw.c
  33. 9 4
      drivers/net/wireless/ath/ath9k/main.c
  34. 2 5
      drivers/net/wireless/ath/ath9k/pci.c
  35. 353 248
      drivers/net/wireless/ath/ath9k/rc.c
  36. 66 23
      drivers/net/wireless/ath/ath9k/rc.h
  37. 5 1
      drivers/net/wireless/ath/ath9k/virtual.c
  38. 10 10
      drivers/net/wireless/ath/ath9k/xmit.c
  39. 0 1
      drivers/net/wireless/ipw2x00/libipw.h
  40. 3 13
      drivers/net/wireless/ipw2x00/libipw_tx.c
  41. 1 1
      drivers/net/wireless/ipw2x00/libipw_wx.c
  42. 1 0
      drivers/net/wireless/iwlwifi/iwl-1000.c
  43. 3 2
      drivers/net/wireless/iwlwifi/iwl-4965.c
  44. 2 1
      drivers/net/wireless/iwlwifi/iwl-5000.c
  45. 7 0
      drivers/net/wireless/iwlwifi/iwl-6000.c
  46. 45 19
      drivers/net/wireless/iwlwifi/iwl-agn-calib.c
  47. 180 45
      drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
  48. 7 0
      drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
  49. 2 2
      drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
  50. 5 2
      drivers/net/wireless/iwlwifi/iwl-agn-lib.c
  51. 117 50
      drivers/net/wireless/iwlwifi/iwl-agn-rx.c
  52. 85 56
      drivers/net/wireless/iwlwifi/iwl-agn.c
  53. 2 4
      drivers/net/wireless/iwlwifi/iwl-calib.h
  54. 50 5
      drivers/net/wireless/iwlwifi/iwl-commands.h
  55. 32 33
      drivers/net/wireless/iwlwifi/iwl-core.c
  56. 3 1
      drivers/net/wireless/iwlwifi/iwl-core.h
  57. 13 0
      drivers/net/wireless/iwlwifi/iwl-debugfs.c
  58. 16 0
      drivers/net/wireless/iwlwifi/iwl-dev.h
  59. 1 0
      drivers/net/wireless/iwlwifi/iwl-eeprom.h
  60. 8 10
      drivers/net/wireless/iwlwifi/iwl-scan.c
  61. 12 10
      drivers/net/wireless/iwlwifi/iwl3945-base.c
  62. 10 187
      drivers/net/wireless/libertas/cfg.c
  63. 0 6
      drivers/net/wireless/libertas/cfg.h
  64. 307 411
      drivers/net/wireless/libertas/cmd.c
  65. 16 9
      drivers/net/wireless/libertas/cmd.h
  66. 8 171
      drivers/net/wireless/libertas/cmdresp.c
  67. 18 49
      drivers/net/wireless/libertas/debugfs.c
  68. 0 5
      drivers/net/wireless/libertas/decl.h
  69. 0 18
      drivers/net/wireless/libertas/defs.h
  70. 0 6
      drivers/net/wireless/libertas/dev.h
  71. 63 79
      drivers/net/wireless/libertas/host.h
  72. 2 2
      drivers/net/wireless/libertas/if_usb.c
  73. 11 24
      drivers/net/wireless/libertas/main.c
  74. 170 46
      drivers/net/wireless/libertas/mesh.c
  75. 10 4
      drivers/net/wireless/libertas/mesh.h
  76. 1 1
      drivers/net/wireless/libertas/tx.c
  77. 3 0
      drivers/net/wireless/libertas_tf/libertas_tf.h
  78. 18 0
      drivers/net/wireless/libertas_tf/main.c
  79. 46 53
      drivers/net/wireless/mac80211_hwsim.c
  80. 79 75
      drivers/net/wireless/mwl8k.c
  81. 2 3
      drivers/net/wireless/orinoco/cfg.c
  82. 35 41
      drivers/net/wireless/p54/eeprom.c
  83. 26 27
      drivers/net/wireless/p54/fwio.c
  84. 4 4
      drivers/net/wireless/p54/led.c
  85. 17 0
      drivers/net/wireless/p54/main.c
  86. 1 2
      drivers/net/wireless/p54/p54pci.c
  87. 19 17
      drivers/net/wireless/p54/txrx.c
  88. 10 1
      drivers/net/wireless/rt2x00/rt2500usb.c
  89. 13 6
      drivers/net/wireless/rt2x00/rt2x00mac.c
  90. 18 17
      drivers/net/wireless/rtl818x/rtl8180_dev.c
  91. 11 1
      drivers/net/wireless/rtl818x/rtl8180_grf5101.c
  92. 18 1
      drivers/net/wireless/rtl818x/rtl8180_max2820.c
  93. 4 1
      drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
  94. 27 1
      drivers/net/wireless/rtl818x/rtl8180_sa2400.c
  95. 5 6
      drivers/net/wireless/rtl818x/rtl8187_dev.c
  96. 4 4
      drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
  97. 1 0
      drivers/net/wireless/rtl818x/rtl818x.h
  98. 3 0
      drivers/net/wireless/wl12xx/wl1251.h
  99. 4 4
      drivers/net/wireless/wl12xx/wl1251_boot.c
  100. 6 6
      drivers/net/wireless/wl12xx/wl1251_cmd.h

+ 5 - 15
MAINTAINERS

@@ -3671,7 +3671,7 @@ F:	include/linux/mv643xx.h
 MARVELL MWL8K WIRELESS DRIVER
 MARVELL MWL8K WIRELESS DRIVER
 M:	Lennert Buytenhek <buytenh@wantstofly.org>
 M:	Lennert Buytenhek <buytenh@wantstofly.org>
 L:	linux-wireless@vger.kernel.org
 L:	linux-wireless@vger.kernel.org
-S:	Maintained
+S:	Odd Fixes
 F:	drivers/net/wireless/mwl8k.c
 F:	drivers/net/wireless/mwl8k.c
 
 
 MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
 MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
@@ -4522,7 +4522,7 @@ PRISM54 WIRELESS DRIVER
 M:	"Luis R. Rodriguez" <mcgrof@gmail.com>
 M:	"Luis R. Rodriguez" <mcgrof@gmail.com>
 L:	linux-wireless@vger.kernel.org
 L:	linux-wireless@vger.kernel.org
 W:	http://prism54.org
 W:	http://prism54.org
-S:	Maintained
+S:	Obsolete
 F:	drivers/net/wireless/prism54/
 F:	drivers/net/wireless/prism54/
 
 
 PROMISE DC4030 CACHING DISK CONTROLLER DRIVER
 PROMISE DC4030 CACHING DISK CONTROLLER DRIVER
@@ -4712,9 +4712,8 @@ S:	Maintained
 F:	drivers/rapidio/
 F:	drivers/rapidio/
 
 
 RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
 RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
-M:	Corey Thomas <coreythomas@charter.net>
 L:	linux-wireless@vger.kernel.org
 L:	linux-wireless@vger.kernel.org
-S:	Maintained
+S:	Orphan
 F:	drivers/net/wireless/ray*
 F:	drivers/net/wireless/ray*
 
 
 RCUTORTURE MODULE
 RCUTORTURE MODULE
@@ -6037,10 +6036,9 @@ F:	Documentation/video4linux/zc0301.txt
 F:	drivers/media/video/zc0301/
 F:	drivers/media/video/zc0301/
 
 
 USB ZD1201 DRIVER
 USB ZD1201 DRIVER
-M:	Jeroen Vreeken <pe1rxq@amsat.org>
-L:	linux-usb@vger.kernel.org
+L:	linux-wireless@vger.kernel.org
 W:	http://linux-lc100020.sourceforge.net
 W:	http://linux-lc100020.sourceforge.net
-S:	Maintained
+S:	Orphan
 F:	drivers/net/wireless/zd1201.*
 F:	drivers/net/wireless/zd1201.*
 
 
 USB ZR364XX DRIVER
 USB ZR364XX DRIVER
@@ -6226,14 +6224,6 @@ F:	Documentation/watchdog/
 F:	drivers/watchdog/
 F:	drivers/watchdog/
 F:	include/linux/watchdog.h
 F:	include/linux/watchdog.h
 
 
-WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS
-M:	Jean Tourrilhes <jt@hpl.hp.com>
-L:	linux-wireless@vger.kernel.org
-W:	http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
-S:	Maintained
-F:	Documentation/networking/wavelan.txt
-F:	drivers/staging/wavelan/
-
 WD7000 SCSI DRIVER
 WD7000 SCSI DRIVER
 M:	Miroslav Zagorac <zaga@fly.cc.fer.hr>
 M:	Miroslav Zagorac <zaga@fly.cc.fer.hr>
 L:	linux-scsi@vger.kernel.org
 L:	linux-scsi@vger.kernel.org

+ 12 - 0
drivers/bluetooth/Kconfig

@@ -58,6 +58,18 @@ config BT_HCIUART_BCSP
 
 
 	  Say Y here to compile support for HCI BCSP protocol.
 	  Say Y here to compile support for HCI BCSP protocol.
 
 
+config BT_HCIUART_ATH3K
+	bool "Atheros AR300x serial support"
+	depends on BT_HCIUART
+	help
+	  HCIATH3K (HCI Atheros AR300x) is a serial protocol for
+	  communication between host and Atheros AR300x Bluetooth devices.
+	  This protocol enables AR300x chips to be enabled with
+	  power management support.
+	  Enable this if you have Atheros AR300x serial Bluetooth device.
+
+	  Say Y here to compile support for HCI UART ATH3K protocol.
+
 config BT_HCIUART_LL
 config BT_HCIUART_LL
 	bool "HCILL protocol support"
 	bool "HCILL protocol support"
 	depends on BT_HCIUART
 	depends on BT_HCIUART

+ 1 - 0
drivers/bluetooth/Makefile

@@ -26,4 +26,5 @@ hci_uart-y				:= hci_ldisc.o
 hci_uart-$(CONFIG_BT_HCIUART_H4)	+= hci_h4.o
 hci_uart-$(CONFIG_BT_HCIUART_H4)	+= hci_h4.o
 hci_uart-$(CONFIG_BT_HCIUART_BCSP)	+= hci_bcsp.o
 hci_uart-$(CONFIG_BT_HCIUART_BCSP)	+= hci_bcsp.o
 hci_uart-$(CONFIG_BT_HCIUART_LL)	+= hci_ll.o
 hci_uart-$(CONFIG_BT_HCIUART_LL)	+= hci_ll.o
+hci_uart-$(CONFIG_BT_HCIUART_ATH3K)	+= hci_ath.o
 hci_uart-objs				:= $(hci_uart-y)
 hci_uart-objs				:= $(hci_uart-y)

+ 1 - 2
drivers/bluetooth/bcm203x.c

@@ -224,7 +224,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
 
 
 	BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);
 	BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);
 
 
-	data->fw_data = kmalloc(firmware->size, GFP_KERNEL);
+	data->fw_data = kmemdup(firmware->data, firmware->size, GFP_KERNEL);
 	if (!data->fw_data) {
 	if (!data->fw_data) {
 		BT_ERR("Can't allocate memory for firmware image");
 		BT_ERR("Can't allocate memory for firmware image");
 		release_firmware(firmware);
 		release_firmware(firmware);
@@ -234,7 +234,6 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	memcpy(data->fw_data, firmware->data, firmware->size);
 	data->fw_size = firmware->size;
 	data->fw_size = firmware->size;
 	data->fw_sent = 0;
 	data->fw_sent = 0;
 
 

+ 1 - 1
drivers/bluetooth/bpa10x.c

@@ -62,7 +62,7 @@ struct hci_vendor_hdr {
 	__u8    type;
 	__u8    type;
 	__le16  snum;
 	__le16  snum;
 	__le16  dlen;
 	__le16  dlen;
-} __attribute__ ((packed));
+} __packed;
 
 
 static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
 static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
 {
 {

+ 1 - 1
drivers/bluetooth/btmrvl_debugfs.c

@@ -216,7 +216,7 @@ static const struct file_operations btmrvl_gpiogap_fops = {
 static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
 static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
 						size_t count, loff_t *ppos)
 						size_t count, loff_t *ppos)
 {
 {
-	struct btmrvl_private *priv = (struct btmrvl_private *) file->private_data;
+	struct btmrvl_private *priv = file->private_data;
 	char buf[16];
 	char buf[16];
 	long result, ret;
 	long result, ret;
 
 

+ 3 - 2
drivers/bluetooth/btmrvl_drv.h

@@ -76,6 +76,7 @@ struct btmrvl_private {
 	int (*hw_host_to_card) (struct btmrvl_private *priv,
 	int (*hw_host_to_card) (struct btmrvl_private *priv,
 				u8 *payload, u16 nb);
 				u8 *payload, u16 nb);
 	int (*hw_wakeup_firmware) (struct btmrvl_private *priv);
 	int (*hw_wakeup_firmware) (struct btmrvl_private *priv);
+	int (*hw_process_int_status) (struct btmrvl_private *priv);
 	spinlock_t driver_lock;		/* spinlock used by driver */
 	spinlock_t driver_lock;		/* spinlock used by driver */
 #ifdef CONFIG_DEBUG_FS
 #ifdef CONFIG_DEBUG_FS
 	void *debugfs_data;
 	void *debugfs_data;
@@ -118,13 +119,13 @@ struct btmrvl_cmd {
 	__le16 ocf_ogf;
 	__le16 ocf_ogf;
 	u8 length;
 	u8 length;
 	u8 data[4];
 	u8 data[4];
-} __attribute__ ((packed));
+} __packed;
 
 
 struct btmrvl_event {
 struct btmrvl_event {
 	u8 ec;		/* event counter */
 	u8 ec;		/* event counter */
 	u8 length;
 	u8 length;
 	u8 data[4];
 	u8 data[4];
-} __attribute__ ((packed));
+} __packed;
 
 
 /* Prototype of global function */
 /* Prototype of global function */
 
 

+ 4 - 1
drivers/bluetooth/btmrvl_main.c

@@ -502,14 +502,17 @@ static int btmrvl_service_main_thread(void *data)
 		spin_lock_irqsave(&priv->driver_lock, flags);
 		spin_lock_irqsave(&priv->driver_lock, flags);
 		if (adapter->int_count) {
 		if (adapter->int_count) {
 			adapter->int_count = 0;
 			adapter->int_count = 0;
+			spin_unlock_irqrestore(&priv->driver_lock, flags);
+			priv->hw_process_int_status(priv);
 		} else if (adapter->ps_state == PS_SLEEP &&
 		} else if (adapter->ps_state == PS_SLEEP &&
 					!skb_queue_empty(&adapter->tx_queue)) {
 					!skb_queue_empty(&adapter->tx_queue)) {
 			spin_unlock_irqrestore(&priv->driver_lock, flags);
 			spin_unlock_irqrestore(&priv->driver_lock, flags);
 			adapter->wakeup_tries++;
 			adapter->wakeup_tries++;
 			priv->hw_wakeup_firmware(priv);
 			priv->hw_wakeup_firmware(priv);
 			continue;
 			continue;
+		} else {
+			spin_unlock_irqrestore(&priv->driver_lock, flags);
 		}
 		}
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 
 		if (adapter->ps_state == PS_SLEEP)
 		if (adapter->ps_state == PS_SLEEP)
 			continue;
 			continue;

+ 55 - 56
drivers/bluetooth/btmrvl_sdio.c

@@ -47,6 +47,7 @@
  * module_exit function is called.
  * module_exit function is called.
  */
  */
 static u8 user_rmmod;
 static u8 user_rmmod;
+static u8 sdio_ireg;
 
 
 static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
 	.helper		= "sd8688_helper.bin",
 	.helper		= "sd8688_helper.bin",
@@ -83,10 +84,10 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
 	*dat = 0;
 	*dat = 0;
 
 
 	fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret);
 	fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret);
+	if (ret)
+		return -EIO;
 
 
-	if (!ret)
-		fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
-
+	fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
 	if (ret)
 	if (ret)
 		return -EIO;
 		return -EIO;
 
 
@@ -216,7 +217,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
 
 
 	tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
 	tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
 
 
-	tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL);
+	tmphlprbuf = kzalloc(tmphlprbufsz, GFP_KERNEL);
 	if (!tmphlprbuf) {
 	if (!tmphlprbuf) {
 		BT_ERR("Unable to allocate buffer for helper."
 		BT_ERR("Unable to allocate buffer for helper."
 			" Terminating download");
 			" Terminating download");
@@ -224,8 +225,6 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
 		goto done;
 		goto done;
 	}
 	}
 
 
-	memset(tmphlprbuf, 0, tmphlprbufsz);
-
 	helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN);
 	helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN);
 
 
 	/* Perform helper data transfer */
 	/* Perform helper data transfer */
@@ -318,7 +317,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
 	BT_DBG("Downloading FW image (%d bytes)", firmwarelen);
 	BT_DBG("Downloading FW image (%d bytes)", firmwarelen);
 
 
 	tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
 	tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
-	tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL);
+	tmpfwbuf = kzalloc(tmpfwbufsz, GFP_KERNEL);
 	if (!tmpfwbuf) {
 	if (!tmpfwbuf) {
 		BT_ERR("Unable to allocate buffer for firmware."
 		BT_ERR("Unable to allocate buffer for firmware."
 		       " Terminating download");
 		       " Terminating download");
@@ -326,8 +325,6 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
 		goto done;
 		goto done;
 	}
 	}
 
 
-	memset(tmpfwbuf, 0, tmpfwbufsz);
-
 	/* Ensure aligned firmware buffer */
 	/* Ensure aligned firmware buffer */
 	fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN);
 	fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN);
 
 
@@ -555,78 +552,79 @@ exit:
 	return ret;
 	return ret;
 }
 }
 
 
-static int btmrvl_sdio_get_int_status(struct btmrvl_private *priv, u8 * ireg)
+static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv)
 {
 {
-	int ret;
-	u8 sdio_ireg = 0;
+	ulong flags;
+	u8 ireg;
 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
 
 
-	*ireg = 0;
-
-	sdio_ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
-	if (ret) {
-		BT_ERR("sdio_readb: read int status register failed");
-		ret = -EIO;
-		goto done;
-	}
-
-	if (sdio_ireg != 0) {
-		/*
-		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
-		 * Clear the interrupt status register and re-enable the
-		 * interrupt.
-		 */
-		BT_DBG("sdio_ireg = 0x%x", sdio_ireg);
-
-		sdio_writeb(card->func, ~(sdio_ireg) & (DN_LD_HOST_INT_STATUS |
-							UP_LD_HOST_INT_STATUS),
-			    HOST_INTSTATUS_REG, &ret);
-		if (ret) {
-			BT_ERR("sdio_writeb: clear int status register "
-				"failed");
-			ret = -EIO;
-			goto done;
-		}
-	}
+	spin_lock_irqsave(&priv->driver_lock, flags);
+	ireg = sdio_ireg;
+	sdio_ireg = 0;
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 
-	if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
+	sdio_claim_host(card->func);
+	if (ireg & DN_LD_HOST_INT_STATUS) {
 		if (priv->btmrvl_dev.tx_dnld_rdy)
 		if (priv->btmrvl_dev.tx_dnld_rdy)
 			BT_DBG("tx_done already received: "
 			BT_DBG("tx_done already received: "
-				" int_status=0x%x", sdio_ireg);
+				" int_status=0x%x", ireg);
 		else
 		else
 			priv->btmrvl_dev.tx_dnld_rdy = true;
 			priv->btmrvl_dev.tx_dnld_rdy = true;
 	}
 	}
 
 
-	if (sdio_ireg & UP_LD_HOST_INT_STATUS)
+	if (ireg & UP_LD_HOST_INT_STATUS)
 		btmrvl_sdio_card_to_host(priv);
 		btmrvl_sdio_card_to_host(priv);
 
 
-	*ireg = sdio_ireg;
-
-	ret = 0;
+	sdio_release_host(card->func);
 
 
-done:
-	return ret;
+	return 0;
 }
 }
 
 
 static void btmrvl_sdio_interrupt(struct sdio_func *func)
 static void btmrvl_sdio_interrupt(struct sdio_func *func)
 {
 {
 	struct btmrvl_private *priv;
 	struct btmrvl_private *priv;
-	struct hci_dev *hcidev;
 	struct btmrvl_sdio_card *card;
 	struct btmrvl_sdio_card *card;
+	ulong flags;
 	u8 ireg = 0;
 	u8 ireg = 0;
+	int ret;
 
 
 	card = sdio_get_drvdata(func);
 	card = sdio_get_drvdata(func);
-	if (card && card->priv) {
-		priv = card->priv;
-		hcidev = priv->btmrvl_dev.hcidev;
+	if (!card || !card->priv) {
+		BT_ERR("sbi_interrupt(%p) card or priv is "
+				"NULL, card=%p\n", func, card);
+		return;
+	}
 
 
-		if (btmrvl_sdio_get_int_status(priv, &ireg))
-			BT_ERR("reading HOST_INT_STATUS_REG failed");
-		else
-			BT_DBG("HOST_INT_STATUS_REG %#x", ireg);
+	priv = card->priv;
+
+	ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
+	if (ret) {
+		BT_ERR("sdio_readb: read int status register failed");
+		return;
+	}
+
+	if (ireg != 0) {
+		/*
+		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+		 * Clear the interrupt status register and re-enable the
+		 * interrupt.
+		 */
+		BT_DBG("ireg = 0x%x", ireg);
 
 
-		btmrvl_interrupt(priv);
+		sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS |
+					UP_LD_HOST_INT_STATUS),
+				HOST_INTSTATUS_REG, &ret);
+		if (ret) {
+			BT_ERR("sdio_writeb: clear int status register failed");
+			return;
+		}
 	}
 	}
+
+	spin_lock_irqsave(&priv->driver_lock, flags);
+	sdio_ireg |= ireg;
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+	btmrvl_interrupt(priv);
 }
 }
 
 
 static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
 static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
@@ -930,6 +928,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
 	/* Initialize the interface specific function pointers */
 	/* Initialize the interface specific function pointers */
 	priv->hw_host_to_card = btmrvl_sdio_host_to_card;
 	priv->hw_host_to_card = btmrvl_sdio_host_to_card;
 	priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
 	priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
+	priv->hw_process_int_status = btmrvl_sdio_process_int_status;
 
 
 	if (btmrvl_register_hdev(priv)) {
 	if (btmrvl_register_hdev(priv)) {
 		BT_ERR("Register hdev failed!");
 		BT_ERR("Register hdev failed!");

+ 7 - 6
drivers/bluetooth/btusb.c

@@ -59,6 +59,9 @@ static struct usb_device_id btusb_table[] = {
 	/* Generic Bluetooth USB device */
 	/* Generic Bluetooth USB device */
 	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 
 
+	/* Apple iMac11,1 */
+	{ USB_DEVICE(0x05ac, 0x8215) },
+
 	/* AVM BlueFRITZ! USB v2.0 */
 	/* AVM BlueFRITZ! USB v2.0 */
 	{ USB_DEVICE(0x057c, 0x3800) },
 	{ USB_DEVICE(0x057c, 0x3800) },
 
 
@@ -146,6 +149,7 @@ static struct usb_device_id blacklist_table[] = {
 #define BTUSB_BULK_RUNNING	1
 #define BTUSB_BULK_RUNNING	1
 #define BTUSB_ISOC_RUNNING	2
 #define BTUSB_ISOC_RUNNING	2
 #define BTUSB_SUSPENDING	3
 #define BTUSB_SUSPENDING	3
+#define BTUSB_DID_ISO_RESUME	4
 
 
 struct btusb_data {
 struct btusb_data {
 	struct hci_dev       *hdev;
 	struct hci_dev       *hdev;
@@ -179,7 +183,6 @@ struct btusb_data {
 	unsigned int sco_num;
 	unsigned int sco_num;
 	int isoc_altsetting;
 	int isoc_altsetting;
 	int suspend_count;
 	int suspend_count;
-	int did_iso_resume:1;
 };
 };
 
 
 static int inc_tx(struct btusb_data *data)
 static int inc_tx(struct btusb_data *data)
@@ -807,7 +810,7 @@ static void btusb_work(struct work_struct *work)
 	int err;
 	int err;
 
 
 	if (hdev->conn_hash.sco_num > 0) {
 	if (hdev->conn_hash.sco_num > 0) {
-		if (!data->did_iso_resume) {
+		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
 			err = usb_autopm_get_interface(data->isoc);
 			err = usb_autopm_get_interface(data->isoc);
 			if (err < 0) {
 			if (err < 0) {
 				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
@@ -815,7 +818,7 @@ static void btusb_work(struct work_struct *work)
 				return;
 				return;
 			}
 			}
 
 
-			data->did_iso_resume = 1;
+			set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
 		}
 		}
 		if (data->isoc_altsetting != 2) {
 		if (data->isoc_altsetting != 2) {
 			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
@@ -836,10 +839,8 @@ static void btusb_work(struct work_struct *work)
 		usb_kill_anchored_urbs(&data->isoc_anchor);
 		usb_kill_anchored_urbs(&data->isoc_anchor);
 
 
 		__set_isoc_interface(hdev, 0);
 		__set_isoc_interface(hdev, 0);
-		if (data->did_iso_resume) {
-			data->did_iso_resume = 0;
+		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
 			usb_autopm_put_interface(data->isoc);
 			usb_autopm_put_interface(data->isoc);
-		}
 	}
 	}
 }
 }
 
 

+ 1 - 1
drivers/bluetooth/dtl1_cs.c

@@ -104,7 +104,7 @@ typedef struct {
 	u8 type;
 	u8 type;
 	u8 zero;
 	u8 zero;
 	u16 len;
 	u16 len;
-} __attribute__ ((packed)) nsh_t;	/* Nokia Specific Header */
+} __packed nsh_t;	/* Nokia Specific Header */
 
 
 #define NSHL  4				/* Nokia Specific Header Length */
 #define NSHL  4				/* Nokia Specific Header Length */
 
 

+ 235 - 0
drivers/bluetooth/hci_ath.c

@@ -0,0 +1,235 @@
+/*
+ *  Atheros Communication Bluetooth HCIATH3K UART protocol
+ *
+ *  HCIATH3K (HCI Atheros AR300x Protocol) is a Atheros Communication's
+ *  power management protocol extension to H4 to support AR300x Bluetooth Chip.
+ *
+ *  Copyright (c) 2009-2010 Atheros Communications Inc.
+ *
+ *  Acknowledgements:
+ *  This file is based on hci_h4.c, which was written
+ *  by Maxim Krasnyansky and Marcel Holtmann.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "hci_uart.h"
+
+struct ath_struct {
+	struct hci_uart *hu;
+	unsigned int cur_sleep;
+
+	struct sk_buff_head txq;
+	struct work_struct ctxtsw;
+};
+
+static int ath_wakeup_ar3k(struct tty_struct *tty)
+{
+	struct termios settings;
+	int status = tty->driver->ops->tiocmget(tty, NULL);
+
+	if (status & TIOCM_CTS)
+		return status;
+
+	/* Disable Automatic RTSCTS */
+	n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings);
+	settings.c_cflag &= ~CRTSCTS;
+	n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings);
+
+	/* Clear RTS first */
+	status = tty->driver->ops->tiocmget(tty, NULL);
+	tty->driver->ops->tiocmset(tty, NULL, 0x00, TIOCM_RTS);
+	mdelay(20);
+
+	/* Set RTS, wake up board */
+	status = tty->driver->ops->tiocmget(tty, NULL);
+	tty->driver->ops->tiocmset(tty, NULL, TIOCM_RTS, 0x00);
+	mdelay(20);
+
+	status = tty->driver->ops->tiocmget(tty, NULL);
+
+	n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings);
+	settings.c_cflag |= CRTSCTS;
+	n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings);
+
+	return status;
+}
+
+static void ath_hci_uart_work(struct work_struct *work)
+{
+	int status;
+	struct ath_struct *ath;
+	struct hci_uart *hu;
+	struct tty_struct *tty;
+
+	ath = container_of(work, struct ath_struct, ctxtsw);
+
+	hu = ath->hu;
+	tty = hu->tty;
+
+	/* verify and wake up controller */
+	if (ath->cur_sleep) {
+		status = ath_wakeup_ar3k(tty);
+		if (!(status & TIOCM_CTS))
+			return;
+	}
+
+	/* Ready to send Data */
+	clear_bit(HCI_UART_SENDING, &hu->tx_state);
+	hci_uart_tx_wakeup(hu);
+}
+
+/* Initialize protocol */
+static int ath_open(struct hci_uart *hu)
+{
+	struct ath_struct *ath;
+
+	BT_DBG("hu %p", hu);
+
+	ath = kzalloc(sizeof(*ath), GFP_ATOMIC);
+	if (!ath)
+		return -ENOMEM;
+
+	skb_queue_head_init(&ath->txq);
+
+	hu->priv = ath;
+	ath->hu = hu;
+
+	INIT_WORK(&ath->ctxtsw, ath_hci_uart_work);
+
+	return 0;
+}
+
+/* Flush protocol data */
+static int ath_flush(struct hci_uart *hu)
+{
+	struct ath_struct *ath = hu->priv;
+
+	BT_DBG("hu %p", hu);
+
+	skb_queue_purge(&ath->txq);
+
+	return 0;
+}
+
+/* Close protocol */
+static int ath_close(struct hci_uart *hu)
+{
+	struct ath_struct *ath = hu->priv;
+
+	BT_DBG("hu %p", hu);
+
+	skb_queue_purge(&ath->txq);
+
+	cancel_work_sync(&ath->ctxtsw);
+
+	hu->priv = NULL;
+	kfree(ath);
+
+	return 0;
+}
+
+#define HCI_OP_ATH_SLEEP 0xFC04
+
+/* Enqueue frame for transmittion */
+static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+{
+	struct ath_struct *ath = hu->priv;
+
+	if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	/*
+	 * Update power management enable flag with parameters of
+	 * HCI sleep enable vendor specific HCI command.
+	 */
+	if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
+		struct hci_command_hdr *hdr = (void *)skb->data;
+
+		if (__le16_to_cpu(hdr->opcode) == HCI_OP_ATH_SLEEP)
+			ath->cur_sleep = skb->data[HCI_COMMAND_HDR_SIZE];
+	}
+
+	BT_DBG("hu %p skb %p", hu, skb);
+
+	/* Prepend skb with frame type */
+	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+
+	skb_queue_tail(&ath->txq, skb);
+	set_bit(HCI_UART_SENDING, &hu->tx_state);
+
+	schedule_work(&ath->ctxtsw);
+
+	return 0;
+}
+
+static struct sk_buff *ath_dequeue(struct hci_uart *hu)
+{
+	struct ath_struct *ath = hu->priv;
+
+	return skb_dequeue(&ath->txq);
+}
+
+/* Recv data */
+static int ath_recv(struct hci_uart *hu, void *data, int count)
+{
+	if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
+		BT_ERR("Frame Reassembly Failed");
+
+	return count;
+}
+
+static struct hci_uart_proto athp = {
+	.id = HCI_UART_ATH3K,
+	.open = ath_open,
+	.close = ath_close,
+	.recv = ath_recv,
+	.enqueue = ath_enqueue,
+	.dequeue = ath_dequeue,
+	.flush = ath_flush,
+};
+
+int __init ath_init(void)
+{
+	int err = hci_uart_register_proto(&athp);
+
+	if (!err)
+		BT_INFO("HCIATH3K protocol initialized");
+	else
+		BT_ERR("HCIATH3K protocol registration failed");
+
+	return err;
+}
+
+int __exit ath_deinit(void)
+{
+	return hci_uart_unregister_proto(&athp);
+}

+ 2 - 2
drivers/bluetooth/hci_bcsp.c

@@ -739,7 +739,7 @@ static struct hci_uart_proto bcsp = {
 	.flush		= bcsp_flush
 	.flush		= bcsp_flush
 };
 };
 
 
-int bcsp_init(void)
+int __init bcsp_init(void)
 {
 {
 	int err = hci_uart_register_proto(&bcsp);
 	int err = hci_uart_register_proto(&bcsp);
 
 
@@ -751,7 +751,7 @@ int bcsp_init(void)
 	return err;
 	return err;
 }
 }
 
 
-int bcsp_deinit(void)
+int __exit bcsp_deinit(void)
 {
 {
 	return hci_uart_unregister_proto(&bcsp);
 	return hci_uart_unregister_proto(&bcsp);
 }
 }

+ 4 - 103
drivers/bluetooth/hci_h4.c

@@ -151,107 +151,8 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
 /* Recv data */
 /* Recv data */
 static int h4_recv(struct hci_uart *hu, void *data, int count)
 static int h4_recv(struct hci_uart *hu, void *data, int count)
 {
 {
-	struct h4_struct *h4 = hu->priv;
-	register char *ptr;
-	struct hci_event_hdr *eh;
-	struct hci_acl_hdr   *ah;
-	struct hci_sco_hdr   *sh;
-	register int len, type, dlen;
-
-	BT_DBG("hu %p count %d rx_state %ld rx_count %ld", 
-			hu, count, h4->rx_state, h4->rx_count);
-
-	ptr = data;
-	while (count) {
-		if (h4->rx_count) {
-			len = min_t(unsigned int, h4->rx_count, count);
-			memcpy(skb_put(h4->rx_skb, len), ptr, len);
-			h4->rx_count -= len; count -= len; ptr += len;
-
-			if (h4->rx_count)
-				continue;
-
-			switch (h4->rx_state) {
-			case H4_W4_DATA:
-				BT_DBG("Complete data");
-
-				hci_recv_frame(h4->rx_skb);
-
-				h4->rx_state = H4_W4_PACKET_TYPE;
-				h4->rx_skb = NULL;
-				continue;
-
-			case H4_W4_EVENT_HDR:
-				eh = hci_event_hdr(h4->rx_skb);
-
-				BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
-
-				h4_check_data_len(h4, eh->plen);
-				continue;
-
-			case H4_W4_ACL_HDR:
-				ah = hci_acl_hdr(h4->rx_skb);
-				dlen = __le16_to_cpu(ah->dlen);
-
-				BT_DBG("ACL header: dlen %d", dlen);
-
-				h4_check_data_len(h4, dlen);
-				continue;
-
-			case H4_W4_SCO_HDR:
-				sh = hci_sco_hdr(h4->rx_skb);
-
-				BT_DBG("SCO header: dlen %d", sh->dlen);
-
-				h4_check_data_len(h4, sh->dlen);
-				continue;
-			}
-		}
-
-		/* H4_W4_PACKET_TYPE */
-		switch (*ptr) {
-		case HCI_EVENT_PKT:
-			BT_DBG("Event packet");
-			h4->rx_state = H4_W4_EVENT_HDR;
-			h4->rx_count = HCI_EVENT_HDR_SIZE;
-			type = HCI_EVENT_PKT;
-			break;
-
-		case HCI_ACLDATA_PKT:
-			BT_DBG("ACL packet");
-			h4->rx_state = H4_W4_ACL_HDR;
-			h4->rx_count = HCI_ACL_HDR_SIZE;
-			type = HCI_ACLDATA_PKT;
-			break;
-
-		case HCI_SCODATA_PKT:
-			BT_DBG("SCO packet");
-			h4->rx_state = H4_W4_SCO_HDR;
-			h4->rx_count = HCI_SCO_HDR_SIZE;
-			type = HCI_SCODATA_PKT;
-			break;
-
-		default:
-			BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-			hu->hdev->stat.err_rx++;
-			ptr++; count--;
-			continue;
-		};
-
-		ptr++; count--;
-
-		/* Allocate packet */
-		h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
-		if (!h4->rx_skb) {
-			BT_ERR("Can't allocate mem for new packet");
-			h4->rx_state = H4_W4_PACKET_TYPE;
-			h4->rx_count = 0;
-			return -ENOMEM;
-		}
-
-		h4->rx_skb->dev = (void *) hu->hdev;
-		bt_cb(h4->rx_skb)->pkt_type = type;
-	}
+	if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
+		BT_ERR("Frame Reassembly Failed");
 
 
 	return count;
 	return count;
 }
 }
@@ -272,7 +173,7 @@ static struct hci_uart_proto h4p = {
 	.flush		= h4_flush,
 	.flush		= h4_flush,
 };
 };
 
 
-int h4_init(void)
+int __init h4_init(void)
 {
 {
 	int err = hci_uart_register_proto(&h4p);
 	int err = hci_uart_register_proto(&h4p);
 
 
@@ -284,7 +185,7 @@ int h4_init(void)
 	return err;
 	return err;
 }
 }
 
 
-int h4_deinit(void)
+int __exit h4_deinit(void)
 {
 {
 	return hci_uart_unregister_proto(&h4p);
 	return hci_uart_unregister_proto(&h4p);
 }
 }

+ 18 - 2
drivers/bluetooth/hci_ldisc.c

@@ -210,7 +210,6 @@ static int hci_uart_close(struct hci_dev *hdev)
 static int hci_uart_send_frame(struct sk_buff *skb)
 static int hci_uart_send_frame(struct sk_buff *skb)
 {
 {
 	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
 	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-	struct tty_struct *tty;
 	struct hci_uart *hu;
 	struct hci_uart *hu;
 
 
 	if (!hdev) {
 	if (!hdev) {
@@ -222,7 +221,6 @@ static int hci_uart_send_frame(struct sk_buff *skb)
 		return -EBUSY;
 		return -EBUSY;
 
 
 	hu = (struct hci_uart *) hdev->driver_data;
 	hu = (struct hci_uart *) hdev->driver_data;
-	tty = hu->tty;
 
 
 	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
 	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
 
 
@@ -397,6 +395,9 @@ static int hci_uart_register_dev(struct hci_uart *hu)
 	if (!reset)
 	if (!reset)
 		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
 		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
 
 
+	if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
+		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+
 	if (hci_register_dev(hdev) < 0) {
 	if (hci_register_dev(hdev) < 0) {
 		BT_ERR("Can't register HCI device");
 		BT_ERR("Can't register HCI device");
 		hci_free_dev(hdev);
 		hci_free_dev(hdev);
@@ -477,6 +478,15 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
 			return hu->hdev->id;
 			return hu->hdev->id;
 		return -EUNATCH;
 		return -EUNATCH;
 
 
+	case HCIUARTSETFLAGS:
+		if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
+			return -EBUSY;
+		hu->hdev_flags = arg;
+		break;
+
+	case HCIUARTGETFLAGS:
+		return hu->hdev_flags;
+
 	default:
 	default:
 		err = n_tty_ioctl_helper(tty, file, cmd, arg);
 		err = n_tty_ioctl_helper(tty, file, cmd, arg);
 		break;
 		break;
@@ -542,6 +552,9 @@ static int __init hci_uart_init(void)
 #ifdef CONFIG_BT_HCIUART_LL
 #ifdef CONFIG_BT_HCIUART_LL
 	ll_init();
 	ll_init();
 #endif
 #endif
+#ifdef CONFIG_BT_HCIUART_ATH3K
+	ath_init();
+#endif
 
 
 	return 0;
 	return 0;
 }
 }
@@ -559,6 +572,9 @@ static void __exit hci_uart_exit(void)
 #ifdef CONFIG_BT_HCIUART_LL
 #ifdef CONFIG_BT_HCIUART_LL
 	ll_deinit();
 	ll_deinit();
 #endif
 #endif
+#ifdef CONFIG_BT_HCIUART_ATH3K
+	ath_deinit();
+#endif
 
 
 	/* Release tty registration of line discipline */
 	/* Release tty registration of line discipline */
 	if ((err = tty_unregister_ldisc(N_HCI)))
 	if ((err = tty_unregister_ldisc(N_HCI)))

+ 3 - 3
drivers/bluetooth/hci_ll.c

@@ -74,7 +74,7 @@ enum hcill_states_e {
 
 
 struct hcill_cmd {
 struct hcill_cmd {
 	u8 cmd;
 	u8 cmd;
-} __attribute__((packed));
+} __packed;
 
 
 struct ll_struct {
 struct ll_struct {
 	unsigned long rx_state;
 	unsigned long rx_state;
@@ -517,7 +517,7 @@ static struct hci_uart_proto llp = {
 	.flush		= ll_flush,
 	.flush		= ll_flush,
 };
 };
 
 
-int ll_init(void)
+int __init ll_init(void)
 {
 {
 	int err = hci_uart_register_proto(&llp);
 	int err = hci_uart_register_proto(&llp);
 
 
@@ -529,7 +529,7 @@ int ll_init(void)
 	return err;
 	return err;
 }
 }
 
 
-int ll_deinit(void)
+int __exit ll_deinit(void)
 {
 {
 	return hci_uart_unregister_proto(&llp);
 	return hci_uart_unregister_proto(&llp);
 }
 }

+ 13 - 2
drivers/bluetooth/hci_uart.h

@@ -31,15 +31,20 @@
 #define HCIUARTSETPROTO		_IOW('U', 200, int)
 #define HCIUARTSETPROTO		_IOW('U', 200, int)
 #define HCIUARTGETPROTO		_IOR('U', 201, int)
 #define HCIUARTGETPROTO		_IOR('U', 201, int)
 #define HCIUARTGETDEVICE	_IOR('U', 202, int)
 #define HCIUARTGETDEVICE	_IOR('U', 202, int)
+#define HCIUARTSETFLAGS		_IOW('U', 203, int)
+#define HCIUARTGETFLAGS		_IOR('U', 204, int)
 
 
 /* UART protocols */
 /* UART protocols */
-#define HCI_UART_MAX_PROTO	5
+#define HCI_UART_MAX_PROTO	6
 
 
 #define HCI_UART_H4	0
 #define HCI_UART_H4	0
 #define HCI_UART_BCSP	1
 #define HCI_UART_BCSP	1
 #define HCI_UART_3WIRE	2
 #define HCI_UART_3WIRE	2
 #define HCI_UART_H4DS	3
 #define HCI_UART_H4DS	3
 #define HCI_UART_LL	4
 #define HCI_UART_LL	4
+#define HCI_UART_ATH3K	5
+
+#define HCI_UART_RAW_DEVICE	0
 
 
 struct hci_uart;
 struct hci_uart;
 
 
@@ -57,6 +62,7 @@ struct hci_uart {
 	struct tty_struct	*tty;
 	struct tty_struct	*tty;
 	struct hci_dev		*hdev;
 	struct hci_dev		*hdev;
 	unsigned long		flags;
 	unsigned long		flags;
+	unsigned long		hdev_flags;
 
 
 	struct hci_uart_proto	*proto;
 	struct hci_uart_proto	*proto;
 	void			*priv;
 	void			*priv;
@@ -66,7 +72,7 @@ struct hci_uart {
 	spinlock_t		rx_lock;
 	spinlock_t		rx_lock;
 };
 };
 
 
-/* HCI_UART flag bits */
+/* HCI_UART proto flag bits */
 #define HCI_UART_PROTO_SET	0
 #define HCI_UART_PROTO_SET	0
 
 
 /* TX states  */
 /* TX states  */
@@ -91,3 +97,8 @@ int bcsp_deinit(void);
 int ll_init(void);
 int ll_init(void);
 int ll_deinit(void);
 int ll_deinit(void);
 #endif
 #endif
+
+#ifdef CONFIG_BT_HCIUART_ATH3K
+int ath_init(void);
+int ath_deinit(void);
+#endif

+ 24 - 29
drivers/net/wireless/adm8211.c

@@ -373,8 +373,8 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
 		pktlen = status & RDES0_STATUS_FL;
 		pktlen = status & RDES0_STATUS_FL;
 		if (pktlen > RX_PKT_SIZE) {
 		if (pktlen > RX_PKT_SIZE) {
 			if (net_ratelimit())
 			if (net_ratelimit())
-				printk(KERN_DEBUG "%s: frame too long (%d)\n",
-				       wiphy_name(dev->wiphy), pktlen);
+				wiphy_debug(dev->wiphy, "frame too long (%d)\n",
+					    pktlen);
 			pktlen = RX_PKT_SIZE;
 			pktlen = RX_PKT_SIZE;
 		}
 		}
 
 
@@ -454,10 +454,10 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
 
 
 static irqreturn_t adm8211_interrupt(int irq, void *dev_id)
 static irqreturn_t adm8211_interrupt(int irq, void *dev_id)
 {
 {
-#define ADM8211_INT(x)							   \
-do {									   \
-	if (unlikely(stsr & ADM8211_STSR_ ## x))			   \
-		printk(KERN_DEBUG "%s: " #x "\n", wiphy_name(dev->wiphy)); \
+#define ADM8211_INT(x)						\
+do {								\
+	if (unlikely(stsr & ADM8211_STSR_ ## x))		\
+		wiphy_debug(dev->wiphy, "%s\n", #x);		\
 } while (0)
 } while (0)
 
 
 	struct ieee80211_hw *dev = dev_id;
 	struct ieee80211_hw *dev = dev_id;
@@ -570,9 +570,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data)
 	}
 	}
 
 
 	if (timeout == 0) {
 	if (timeout == 0) {
-		printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed"
-		       " prewrite (reg=0x%08x)\n",
-		       wiphy_name(dev->wiphy), addr, data, reg);
+		wiphy_debug(dev->wiphy,
+			    "adm8211_write_bbp(%d,%d) failed prewrite (reg=0x%08x)\n",
+			    addr, data, reg);
 		return -ETIMEDOUT;
 		return -ETIMEDOUT;
 	}
 	}
 
 
@@ -605,9 +605,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data)
 	if (timeout == 0) {
 	if (timeout == 0) {
 		ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) &
 		ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) &
 				  ~ADM8211_BBPCTL_WR);
 				  ~ADM8211_BBPCTL_WR);
-		printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed"
-		       " postwrite (reg=0x%08x)\n",
-		       wiphy_name(dev->wiphy), addr, data, reg);
+		wiphy_debug(dev->wiphy,
+			    "adm8211_write_bbp(%d,%d) failed postwrite (reg=0x%08x)\n",
+			    addr, data, reg);
 		return -ETIMEDOUT;
 		return -ETIMEDOUT;
 	}
 	}
 
 
@@ -675,8 +675,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
 		break;
 		break;
 
 
 	default:
 	default:
-		printk(KERN_DEBUG "%s: unsupported transceiver type %d\n",
-		       wiphy_name(dev->wiphy), priv->transceiver_type);
+		wiphy_debug(dev->wiphy, "unsupported transceiver type %d\n",
+			    priv->transceiver_type);
 		break;
 		break;
 	}
 	}
 
 
@@ -732,8 +732,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
 
 
 	/* Nothing to do for ADMtek BBP */
 	/* Nothing to do for ADMtek BBP */
 	} else if (priv->bbp_type != ADM8211_TYPE_ADMTEK)
 	} else if (priv->bbp_type != ADM8211_TYPE_ADMTEK)
-		printk(KERN_DEBUG "%s: unsupported BBP type %d\n",
-		       wiphy_name(dev->wiphy), priv->bbp_type);
+		wiphy_debug(dev->wiphy, "unsupported bbp type %d\n",
+			    priv->bbp_type);
 
 
 	ADM8211_RESTORE();
 	ADM8211_RESTORE();
 
 
@@ -1027,13 +1027,12 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev)
 			break;
 			break;
 
 
 		default:
 		default:
-			printk(KERN_DEBUG "%s: unsupported transceiver %d\n",
-			       wiphy_name(dev->wiphy), priv->transceiver_type);
+			wiphy_debug(dev->wiphy, "unsupported transceiver %d\n",
+				    priv->transceiver_type);
 			break;
 			break;
 		}
 		}
 	} else
 	} else
-		printk(KERN_DEBUG "%s: unsupported BBP %d\n",
-		       wiphy_name(dev->wiphy), priv->bbp_type);
+		wiphy_debug(dev->wiphy, "unsupported bbp %d\n", priv->bbp_type);
 
 
 	ADM8211_CSR_WRITE(SYNRF, 0);
 	ADM8211_CSR_WRITE(SYNRF, 0);
 
 
@@ -1509,15 +1508,13 @@ static int adm8211_start(struct ieee80211_hw *dev)
 	/* Power up MAC and RF chips */
 	/* Power up MAC and RF chips */
 	retval = adm8211_hw_reset(dev);
 	retval = adm8211_hw_reset(dev);
 	if (retval) {
 	if (retval) {
-		printk(KERN_ERR "%s: hardware reset failed\n",
-		       wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "hardware reset failed\n");
 		goto fail;
 		goto fail;
 	}
 	}
 
 
 	retval = adm8211_init_rings(dev);
 	retval = adm8211_init_rings(dev);
 	if (retval) {
 	if (retval) {
-		printk(KERN_ERR "%s: failed to initialize rings\n",
-		       wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "failed to initialize rings\n");
 		goto fail;
 		goto fail;
 	}
 	}
 
 
@@ -1528,8 +1525,7 @@ static int adm8211_start(struct ieee80211_hw *dev)
 	retval = request_irq(priv->pdev->irq, adm8211_interrupt,
 	retval = request_irq(priv->pdev->irq, adm8211_interrupt,
 			     IRQF_SHARED, "adm8211", dev);
 			     IRQF_SHARED, "adm8211", dev);
 	if (retval) {
 	if (retval) {
-		printk(KERN_ERR "%s: failed to register IRQ handler\n",
-		       wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "failed to register irq handler\n");
 		goto fail;
 		goto fail;
 	}
 	}
 
 
@@ -1906,9 +1902,8 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
 		goto err_free_eeprom;
 		goto err_free_eeprom;
 	}
 	}
 
 
-	printk(KERN_INFO "%s: hwaddr %pM, Rev 0x%02x\n",
-	       wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
-	       pdev->revision);
+	wiphy_info(dev->wiphy, "hwaddr %pm, rev 0x%02x\n",
+		   dev->wiphy->perm_addr, pdev->revision);
 
 
 	return 0;
 	return 0;
 
 

+ 80 - 88
drivers/net/wireless/at76c50x-usb.c

@@ -89,22 +89,19 @@
 #define DBG_DEFAULTS		0
 #define DBG_DEFAULTS		0
 
 
 /* Use our own dbg macro */
 /* Use our own dbg macro */
-#define at76_dbg(bits, format, arg...) \
-	do { \
-		if (at76_debug & (bits))				 \
-			printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
-			       ## arg);					 \
-	} while (0)
-
-#define at76_dbg_dump(bits, buf, len, format, arg...)	\
-	do { \
-		if (at76_debug & (bits)) { \
-			printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
-			       ## arg);					 \
-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,     \
-					     buf, len);			 \
-		}							 \
-	} while (0)
+#define at76_dbg(bits, format, arg...)					\
+do {									\
+	if (at76_debug & (bits))					\
+		printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg);	\
+} while (0)
+
+#define at76_dbg_dump(bits, buf, len, format, arg...)			\
+do {									\
+	if (at76_debug & (bits)) {					\
+		printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg);	\
+		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);	\
+	}								\
+} while (0)
 
 
 static uint at76_debug = DBG_DEFAULTS;
 static uint at76_debug = DBG_DEFAULTS;
 
 
@@ -658,8 +655,8 @@ static int at76_get_hw_config(struct at76_priv *priv)
 exit:
 exit:
 	kfree(hwcfg);
 	kfree(hwcfg);
 	if (ret < 0)
 	if (ret < 0)
-		printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "cannot get hw config (error %d)\n",
+			  ret);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -794,8 +791,9 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
 	do {
 	do {
 		status = at76_get_cmd_status(priv->udev, cmd);
 		status = at76_get_cmd_status(priv->udev, cmd);
 		if (status < 0) {
 		if (status < 0) {
-			printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
-			       wiphy_name(priv->hw->wiphy), status);
+			wiphy_err(priv->hw->wiphy,
+				  "at76_get_cmd_status failed: %d\n",
+				  status);
 			break;
 			break;
 		}
 		}
 
 
@@ -810,9 +808,8 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
 
 
 		schedule_timeout_interruptible(HZ / 10);	/* 100 ms */
 		schedule_timeout_interruptible(HZ / 10);	/* 100 ms */
 		if (time_after(jiffies, timeout)) {
 		if (time_after(jiffies, timeout)) {
-			printk(KERN_ERR
-			       "%s: completion timeout for command %d\n",
-			       wiphy_name(priv->hw->wiphy), cmd);
+			wiphy_err(priv->hw->wiphy,
+				  "completion timeout for command %d\n", cmd);
 			status = -ETIMEDOUT;
 			status = -ETIMEDOUT;
 			break;
 			break;
 		}
 		}
@@ -833,9 +830,9 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
 
 
 	ret = at76_wait_completion(priv, CMD_SET_MIB);
 	ret = at76_wait_completion(priv, CMD_SET_MIB);
 	if (ret != CMD_STATUS_COMPLETE) {
 	if (ret != CMD_STATUS_COMPLETE) {
-		printk(KERN_INFO
-		       "%s: set_mib: at76_wait_completion failed "
-		       "with %d\n", wiphy_name(priv->hw->wiphy), ret);
+		wiphy_info(priv->hw->wiphy,
+			   "set_mib: at76_wait_completion failed with %d\n",
+			   ret);
 		ret = -EIO;
 		ret = -EIO;
 	}
 	}
 
 
@@ -855,8 +852,8 @@ static int at76_set_radio(struct at76_priv *priv, int enable)
 
 
 	ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
 	ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
 	if (ret < 0)
 	if (ret < 0)
-		printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), cmd, ret);
+		wiphy_err(priv->hw->wiphy,
+			  "at76_set_card_command(%d) failed: %d\n", cmd, ret);
 	else
 	else
 		ret = 1;
 		ret = 1;
 
 
@@ -876,8 +873,8 @@ static int at76_set_pm_mode(struct at76_priv *priv)
 
 
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	if (ret < 0)
 	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "set_mib (pm_mode) failed: %d\n",
+			  ret);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -893,8 +890,8 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type)
 
 
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	if (ret < 0)
 	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "set_mib (preamble) failed: %d\n",
+			  ret);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -910,8 +907,8 @@ static int at76_set_frag(struct at76_priv *priv, u16 size)
 
 
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	if (ret < 0)
 	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "set_mib (frag threshold) failed: %d\n", ret);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -927,8 +924,7 @@ static int at76_set_rts(struct at76_priv *priv, u16 size)
 
 
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	if (ret < 0)
 	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "set_mib (rts) failed: %d\n", ret);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -944,8 +940,8 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
 
 
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	if (ret < 0)
 	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "set_mib (autorate fallback) failed: %d\n", ret);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -963,8 +959,8 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv)
 	ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
 	ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
 			   sizeof(struct mib_mac_addr));
 			   sizeof(struct mib_mac_addr));
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "at76_get_mib (mac_addr) failed: %d\n", ret);
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -992,8 +988,8 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
 	ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
 	ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
 			   sizeof(struct mib_mac_wep));
 			   sizeof(struct mib_mac_wep));
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "at76_get_mib (mac_wep) failed: %d\n", ret);
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -1029,8 +1025,8 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
 	ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
 	ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
 			   sizeof(struct mib_mac_mgmt));
 			   sizeof(struct mib_mac_mgmt));
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "at76_get_mib (mac_mgmt) failed: %d\n", ret);
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -1065,8 +1061,8 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
 
 
 	ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
 	ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "at76_get_mib (mac) failed: %d\n", ret);
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -1102,8 +1098,8 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
 
 
 	ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
 	ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "at76_get_mib (phy) failed: %d\n", ret);
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -1135,8 +1131,8 @@ static void at76_dump_mib_local(struct at76_priv *priv)
 
 
 	ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
 	ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "at76_get_mib (local) failed: %d\n", ret);
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -1161,8 +1157,8 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv)
 	ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
 	ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
 			   sizeof(struct mib_mdomain));
 			   sizeof(struct mib_mdomain));
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "at76_get_mib (mdomain) failed: %d\n", ret);
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -1233,16 +1229,16 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
 	struct sk_buff *skb = priv->rx_skb;
 	struct sk_buff *skb = priv->rx_skb;
 
 
 	if (!priv->rx_urb) {
 	if (!priv->rx_urb) {
-		printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
-		       wiphy_name(priv->hw->wiphy), __func__);
+		wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is null\n",
+			  __func__);
 		return -EFAULT;
 		return -EFAULT;
 	}
 	}
 
 
 	if (!skb) {
 	if (!skb) {
 		skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
 		skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
 		if (!skb) {
 		if (!skb) {
-			printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
-			       wiphy_name(priv->hw->wiphy));
+			wiphy_err(priv->hw->wiphy,
+				  "cannot allocate rx skbuff\n");
 			ret = -ENOMEM;
 			ret = -ENOMEM;
 			goto exit;
 			goto exit;
 		}
 		}
@@ -1261,15 +1257,14 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
 			at76_dbg(DBG_DEVSTART,
 			at76_dbg(DBG_DEVSTART,
 				 "usb_submit_urb returned -ENODEV");
 				 "usb_submit_urb returned -ENODEV");
 		else
 		else
-			printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
-			       wiphy_name(priv->hw->wiphy), ret);
+			wiphy_err(priv->hw->wiphy,
+				  "rx, usb_submit_urb failed: %d\n", ret);
 	}
 	}
 
 
 exit:
 exit:
 	if (ret < 0 && ret != -ENODEV)
 	if (ret < 0 && ret != -ENODEV)
-		printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
-		       "driver and/or power cycle the device\n",
-		       wiphy_name(priv->hw->wiphy));
+		wiphy_err(priv->hw->wiphy,
+			  "cannot submit rx urb - please unload the driver and/or power cycle the device\n");
 
 
 	return ret;
 	return ret;
 }
 }
@@ -1438,8 +1433,8 @@ static int at76_startup_device(struct at76_priv *priv)
 	ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
 	ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
 				    sizeof(struct at76_card_config));
 				    sizeof(struct at76_card_config));
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n",
+			  ret);
 		return ret;
 		return ret;
 	}
 	}
 
 
@@ -1504,8 +1499,8 @@ static void at76_work_set_promisc(struct work_struct *work)
 
 
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	ret = at76_set_mib(priv, &priv->mib_buf);
 	if (ret < 0)
 	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy,
+			  "set_mib (promiscuous_mode) failed: %d\n", ret);
 
 
 	mutex_unlock(&priv->mtx);
 	mutex_unlock(&priv->mtx);
 }
 }
@@ -1668,16 +1663,16 @@ static int at76_join(struct at76_priv *priv)
 				    sizeof(struct at76_req_join));
 				    sizeof(struct at76_req_join));
 
 
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n",
+			  ret);
 		return 0;
 		return 0;
 	}
 	}
 
 
 	ret = at76_wait_completion(priv, CMD_JOIN);
 	ret = at76_wait_completion(priv, CMD_JOIN);
 	at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
 	at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
 	if (ret != CMD_STATUS_COMPLETE) {
 	if (ret != CMD_STATUS_COMPLETE) {
-		printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "at76_wait_completion failed: %d\n",
+			  ret);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1745,8 +1740,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 	at76_dbg(DBG_MAC80211, "%s()", __func__);
 	at76_dbg(DBG_MAC80211, "%s()", __func__);
 
 
 	if (priv->tx_urb->status == -EINPROGRESS) {
 	if (priv->tx_urb->status == -EINPROGRESS) {
-		printk(KERN_ERR "%s: %s called while tx urb is pending\n",
-		       wiphy_name(priv->hw->wiphy), __func__);
+		wiphy_err(priv->hw->wiphy,
+			  "%s called while tx urb is pending\n", __func__);
 		return NETDEV_TX_BUSY;
 		return NETDEV_TX_BUSY;
 	}
 	}
 
 
@@ -1794,13 +1789,12 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 			  submit_len, at76_mac80211_tx_callback, priv);
 			  submit_len, at76_mac80211_tx_callback, priv);
 	ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
 	ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
 	if (ret) {
 	if (ret) {
-		printk(KERN_ERR "%s: error in tx submit urb: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret);
 		if (ret == -EINVAL)
 		if (ret == -EINVAL)
-			printk(KERN_ERR
-			       "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
-			       wiphy_name(priv->hw->wiphy), priv->tx_urb,
-			       priv->tx_urb->hcpriv, priv->tx_urb->complete);
+			wiphy_err(priv->hw->wiphy,
+				  "-einval: tx urb %p hcpriv %p complete %p\n",
+				  priv->tx_urb,
+				  priv->tx_urb->hcpriv, priv->tx_urb->complete);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -1817,8 +1811,8 @@ static int at76_mac80211_start(struct ieee80211_hw *hw)
 
 
 	ret = at76_submit_rx_urb(priv);
 	ret = at76_submit_rx_urb(priv);
 	if (ret < 0) {
 	if (ret < 0) {
-		printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
-		       wiphy_name(priv->hw->wiphy), ret);
+		wiphy_err(priv->hw->wiphy, "open: submit_rx_urb failed: %d\n",
+			  ret);
 		goto error;
 		goto error;
 	}
 	}
 
 
@@ -2316,14 +2310,12 @@ static int at76_init_new_device(struct at76_priv *priv,
 
 
 	priv->mac80211_registered = 1;
 	priv->mac80211_registered = 1;
 
 
-	printk(KERN_INFO "%s: USB %s, MAC %pM, firmware %d.%d.%d-%d\n",
-	       wiphy_name(priv->hw->wiphy),
-	       dev_name(&interface->dev), priv->mac_addr,
-	       priv->fw_version.major, priv->fw_version.minor,
-	       priv->fw_version.patch, priv->fw_version.build);
-	printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n",
-	       wiphy_name(priv->hw->wiphy),
-	       priv->regulatory_domain, priv->domain->name);
+	wiphy_info(priv->hw->wiphy, "usb %s, mac %pm, firmware %d.%d.%d-%d\n",
+		   dev_name(&interface->dev), priv->mac_addr,
+		   priv->fw_version.major, priv->fw_version.minor,
+		   priv->fw_version.patch, priv->fw_version.build);
+	wiphy_info(priv->hw->wiphy, "regulatory domain 0x%02x: %s\n",
+		   priv->regulatory_domain, priv->domain->name);
 
 
 exit:
 exit:
 	return ret;
 	return ret;
@@ -2485,7 +2477,7 @@ static void at76_disconnect(struct usb_interface *interface)
 	if (!priv)
 	if (!priv)
 		return;
 		return;
 
 
-	printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
+	wiphy_info(priv->hw->wiphy, "disconnecting\n");
 	at76_delete_device(priv);
 	at76_delete_device(priv);
 	dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
 	dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
 }
 }

+ 3 - 4
drivers/net/wireless/ath/ar9170/cmd.c

@@ -48,8 +48,7 @@ int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
 
 
 	err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
 	err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
 	if (err)
 	if (err)
-		printk(KERN_DEBUG "%s: writing memory failed\n",
-		       wiphy_name(ar->hw->wiphy));
+		wiphy_debug(ar->hw->wiphy, "writing memory failed\n");
 	return err;
 	return err;
 }
 }
 
 
@@ -67,8 +66,8 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
 	err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
 	err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
 			   (u8 *) buf, 0, NULL);
 			   (u8 *) buf, 0, NULL);
 	if (err)
 	if (err)
-		printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
-		       wiphy_name(ar->hw->wiphy), reg, val);
+		wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n",
+			    reg, val);
 	return err;
 	return err;
 }
 }
 
 

+ 2 - 2
drivers/net/wireless/ath/ar9170/led.c

@@ -133,8 +133,8 @@ static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
 	err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
 	err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
 				    &ar->leds[i].l);
 				    &ar->leds[i].l);
 	if (err)
 	if (err)
-		printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
-		       wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
+		wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n",
+			  ar->leds[i].name, err);
 	else
 	else
 		ar->leds[i].registered = true;
 		ar->leds[i].registered = true;
 
 

+ 99 - 92
drivers/net/wireless/ath/ar9170/main.c

@@ -198,12 +198,13 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
 	struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
 	struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
 	struct ieee80211_hdr *hdr = (void *) txc->frame_data;
 	struct ieee80211_hdr *hdr = (void *) txc->frame_data;
 
 
-	printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
-			  "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
-	       wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
-	       ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
-	       le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
-	       jiffies_to_msecs(arinfo->timeout - jiffies));
+	wiphy_debug(ar->hw->wiphy,
+		    "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
+		    "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
+		    skb, skb_get_queue_mapping(skb),
+		    ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
+		    le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
+		    jiffies_to_msecs(arinfo->timeout - jiffies));
 }
 }
 
 
 static void __ar9170_dump_txqueue(struct ar9170 *ar,
 static void __ar9170_dump_txqueue(struct ar9170 *ar,
@@ -213,8 +214,8 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar,
 	int i = 0;
 	int i = 0;
 
 
 	printk(KERN_DEBUG "---[ cut here ]---\n");
 	printk(KERN_DEBUG "---[ cut here ]---\n");
-	printk(KERN_DEBUG "%s: %d entries in queue.\n",
-	       wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
+	wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n",
+		    skb_queue_len(queue));
 
 
 	skb_queue_walk(queue, skb) {
 	skb_queue_walk(queue, skb) {
 		printk(KERN_DEBUG "index:%d =>\n", i++);
 		printk(KERN_DEBUG "index:%d =>\n", i++);
@@ -244,15 +245,14 @@ static void __ar9170_dump_txstats(struct ar9170 *ar)
 {
 {
 	int i;
 	int i;
 
 
-	printk(KERN_DEBUG "%s: QoS queue stats\n",
-	       wiphy_name(ar->hw->wiphy));
+	wiphy_debug(ar->hw->wiphy, "qos queue stats\n");
 
 
 	for (i = 0; i < __AR9170_NUM_TXQ; i++)
 	for (i = 0; i < __AR9170_NUM_TXQ; i++)
-		printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d "
-		       " stopped:%d\n", wiphy_name(ar->hw->wiphy), i,
-		       ar->tx_stats[i].limit, ar->tx_stats[i].len,
-		       skb_queue_len(&ar->tx_status[i]),
-		       ieee80211_queue_stopped(ar->hw, i));
+		wiphy_debug(ar->hw->wiphy,
+			    "queue:%d limit:%d len:%d waitack:%d stopped:%d\n",
+			    i, ar->tx_stats[i].limit, ar->tx_stats[i].len,
+			    skb_queue_len(&ar->tx_status[i]),
+			    ieee80211_queue_stopped(ar->hw, i));
 }
 }
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 
 
@@ -274,9 +274,9 @@ static void ar9170_recycle_expired(struct ar9170 *ar,
 
 
 		if (time_is_before_jiffies(arinfo->timeout)) {
 		if (time_is_before_jiffies(arinfo->timeout)) {
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
-			       "recycle\n", wiphy_name(ar->hw->wiphy),
-			       jiffies, arinfo->timeout);
+			wiphy_debug(ar->hw->wiphy,
+				    "[%ld > %ld] frame expired => recycle\n",
+				    jiffies, arinfo->timeout);
 			ar9170_print_txheader(ar, skb);
 			ar9170_print_txheader(ar, skb);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 			__skb_unlink(skb, queue);
 			__skb_unlink(skb, queue);
@@ -317,8 +317,8 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
 		break;
 		break;
 
 
 	default:
 	default:
-		printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
-		       wiphy_name(ar->hw->wiphy), tx_status);
+		wiphy_err(ar->hw->wiphy,
+			  "invalid tx_status response (%x)\n", tx_status);
 		break;
 		break;
 	}
 	}
 
 
@@ -339,8 +339,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
 
 
 	if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
 	if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
 #ifdef AR9170_QUEUE_STOP_DEBUG
 #ifdef AR9170_QUEUE_STOP_DEBUG
-		printk(KERN_DEBUG "%s: wake queue %d\n",
-		       wiphy_name(ar->hw->wiphy), queue);
+		wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue);
 		__ar9170_dump_txstats(ar);
 		__ar9170_dump_txstats(ar);
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 		ieee80211_wake_queue(ar->hw, queue);
 		ieee80211_wake_queue(ar->hw, queue);
@@ -387,9 +386,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
 
 
 		if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
 		if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
-			       wiphy_name(ar->hw->wiphy), mac,
-			       ieee80211_get_DA(hdr));
+			wiphy_debug(ar->hw->wiphy,
+				    "skip frame => da %pm != %pm\n",
+				    mac, ieee80211_get_DA(hdr));
 			ar9170_print_txheader(ar, skb);
 			ar9170_print_txheader(ar, skb);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 			continue;
 			continue;
@@ -400,8 +399,8 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
 
 
 		if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
 		if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
-			       wiphy_name(ar->hw->wiphy), rate, r);
+			wiphy_debug(ar->hw->wiphy,
+				    "skip frame => rate %d != %d\n", rate, r);
 			ar9170_print_txheader(ar, skb);
 			ar9170_print_txheader(ar, skb);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 			continue;
 			continue;
@@ -413,9 +412,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
 	}
 	}
 
 
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-	printk(KERN_ERR "%s: ESS:[%pM] does not have any "
-			"outstanding frames in queue.\n",
-			wiphy_name(ar->hw->wiphy), mac);
+	wiphy_err(ar->hw->wiphy,
+		  "ESS:[%pM] does not have any outstanding frames in queue.\n",
+		  mac);
 	__ar9170_dump_txqueue(ar, queue);
 	__ar9170_dump_txqueue(ar, queue);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 	spin_unlock_irqrestore(&queue->lock, flags);
 	spin_unlock_irqrestore(&queue->lock, flags);
@@ -444,8 +443,8 @@ static void ar9170_tx_janitor(struct work_struct *work)
 
 
 	for (i = 0; i < __AR9170_NUM_TXQ; i++) {
 	for (i = 0; i < __AR9170_NUM_TXQ; i++) {
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-		printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
-		       wiphy_name(ar->hw->wiphy), i);
+		wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n",
+			    i);
 		ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
 		ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
 		ar9170_dump_txqueue(ar, &ar->tx_status[i]);
 		ar9170_dump_txqueue(ar, &ar->tx_status[i]);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
@@ -495,8 +494,9 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
 		u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
 		u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
 			AR9170_TX_PHY_QOS_SHIFT;
 			AR9170_TX_PHY_QOS_SHIFT;
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-		printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
-		       wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
+		wiphy_debug(ar->hw->wiphy,
+			    "recv tx_status for %pm, p:%08x, q:%d\n",
+			    cmd->tx_status.dst, phy, q);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 
 
 		skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
 		skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
@@ -582,7 +582,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
 		break;
 		break;
 
 
 	default:
 	default:
-		printk(KERN_INFO "received unhandled event %x\n", cmd->type);
+		pr_info("received unhandled event %x\n", cmd->type);
 		print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
 		print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
 		break;
 		break;
 	}
 	}
@@ -675,9 +675,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar,
 		/* TODO: update netdevice's RX dropped/errors statistics */
 		/* TODO: update netdevice's RX dropped/errors statistics */
 
 
 		if (ar9170_nag_limiter(ar))
 		if (ar9170_nag_limiter(ar))
-			printk(KERN_DEBUG "%s: received frame with "
-			       "suspicious error code (%#x).\n",
-			       wiphy_name(ar->hw->wiphy), error);
+			wiphy_debug(ar->hw->wiphy,
+				    "received frame with suspicious error code (%#x).\n",
+				    error);
 
 
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -704,9 +704,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar,
 			break;
 			break;
 		default:
 		default:
 			if (ar9170_nag_limiter(ar))
 			if (ar9170_nag_limiter(ar))
-				printk(KERN_ERR "%s: invalid plcp cck rate "
-				       "(%x).\n", wiphy_name(ar->hw->wiphy),
-				       head->plcp[0]);
+				wiphy_err(ar->hw->wiphy,
+					  "invalid plcp cck rate (%x).\n",
+					  head->plcp[0]);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		break;
 		break;
@@ -740,9 +740,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar,
 			break;
 			break;
 		default:
 		default:
 			if (ar9170_nag_limiter(ar))
 			if (ar9170_nag_limiter(ar))
-				printk(KERN_ERR "%s: invalid plcp ofdm rate "
-				       "(%x).\n", wiphy_name(ar->hw->wiphy),
-				       head->plcp[0]);
+				wiphy_err(ar->hw->wiphy,
+					  "invalid plcp ofdm rate (%x).\n",
+					  head->plcp[0]);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		if (status->band == IEEE80211_BAND_2GHZ)
 		if (status->band == IEEE80211_BAND_2GHZ)
@@ -761,8 +761,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar,
 
 
 	default:
 	default:
 		if (ar9170_nag_limiter(ar))
 		if (ar9170_nag_limiter(ar))
-			printk(KERN_ERR "%s: invalid modulation\n",
-			       wiphy_name(ar->hw->wiphy));
+			wiphy_err(ar->hw->wiphy, "invalid modulation\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -863,8 +862,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 			ar->rx_mpdu.has_plcp = true;
 			ar->rx_mpdu.has_plcp = true;
 		} else {
 		} else {
 			if (ar9170_nag_limiter(ar))
 			if (ar9170_nag_limiter(ar))
-				printk(KERN_ERR "%s: plcp info is clipped.\n",
-				       wiphy_name(ar->hw->wiphy));
+				wiphy_err(ar->hw->wiphy,
+					  "plcp info is clipped.\n");
 			return ;
 			return ;
 		}
 		}
 		break;
 		break;
@@ -877,8 +876,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 			phy = (void *)(buf + mpdu_len);
 			phy = (void *)(buf + mpdu_len);
 		} else {
 		} else {
 			if (ar9170_nag_limiter(ar))
 			if (ar9170_nag_limiter(ar))
-				printk(KERN_ERR "%s: frame tail is clipped.\n",
-				       wiphy_name(ar->hw->wiphy));
+				wiphy_err(ar->hw->wiphy,
+					  "frame tail is clipped.\n");
 			return ;
 			return ;
 		}
 		}
 
 
@@ -888,9 +887,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 			if (!ar9170_nag_limiter(ar))
 			if (!ar9170_nag_limiter(ar))
 				return ;
 				return ;
 
 
-			printk(KERN_ERR "%s: rx stream did not start "
-					"with a first_mpdu frame tag.\n",
-			       wiphy_name(ar->hw->wiphy));
+			wiphy_err(ar->hw->wiphy,
+				  "rx stream did not start with a first_mpdu frame tag.\n");
 
 
 			return ;
 			return ;
 		}
 		}
@@ -954,8 +952,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
 			if (!ar->rx_failover_missing) {
 			if (!ar->rx_failover_missing) {
 				/* this is no "short read". */
 				/* this is no "short read". */
 				if (ar9170_nag_limiter(ar)) {
 				if (ar9170_nag_limiter(ar)) {
-					printk(KERN_ERR "%s: missing tag!\n",
-					       wiphy_name(ar->hw->wiphy));
+					wiphy_err(ar->hw->wiphy,
+						  "missing tag!\n");
 					goto err_telluser;
 					goto err_telluser;
 				} else
 				} else
 					goto err_silent;
 					goto err_silent;
@@ -963,9 +961,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
 
 
 			if (ar->rx_failover_missing > tlen) {
 			if (ar->rx_failover_missing > tlen) {
 				if (ar9170_nag_limiter(ar)) {
 				if (ar9170_nag_limiter(ar)) {
-					printk(KERN_ERR "%s: possible multi "
-					       "stream corruption!\n",
-					       wiphy_name(ar->hw->wiphy));
+					wiphy_err(ar->hw->wiphy,
+						  "possible multi stream corruption!\n");
 					goto err_telluser;
 					goto err_telluser;
 				} else
 				} else
 					goto err_silent;
 					goto err_silent;
@@ -997,9 +994,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
 			if (ar->rx_failover_missing) {
 			if (ar->rx_failover_missing) {
 				/* TODO: handle double stream corruption. */
 				/* TODO: handle double stream corruption. */
 				if (ar9170_nag_limiter(ar)) {
 				if (ar9170_nag_limiter(ar)) {
-					printk(KERN_ERR "%s: double rx stream "
-					       "corruption!\n",
-						wiphy_name(ar->hw->wiphy));
+					wiphy_err(ar->hw->wiphy,
+						  "double rx stream corruption!\n");
 					goto err_telluser;
 					goto err_telluser;
 				} else
 				} else
 					goto err_silent;
 					goto err_silent;
@@ -1042,9 +1038,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
 
 
 	if (tlen) {
 	if (tlen) {
 		if (net_ratelimit())
 		if (net_ratelimit())
-			printk(KERN_ERR "%s: %d bytes of unprocessed "
-					"data left in rx stream!\n",
-			       wiphy_name(ar->hw->wiphy), tlen);
+			wiphy_err(ar->hw->wiphy,
+				  "%d bytes of unprocessed data left in rx stream!\n",
+				  tlen);
 
 
 		goto err_telluser;
 		goto err_telluser;
 	}
 	}
@@ -1052,10 +1048,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
 	return ;
 	return ;
 
 
 err_telluser:
 err_telluser:
-	printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
-			"data:%d, rx:%d, pending:%d ]\n",
-	       wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
-	       ar->rx_failover_missing);
+	wiphy_err(ar->hw->wiphy,
+		  "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n",
+		  clen, wlen, tlen, ar->rx_failover_missing);
 
 
 	if (ar->rx_failover_missing)
 	if (ar->rx_failover_missing)
 		print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
 		print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
@@ -1065,9 +1060,8 @@ err_telluser:
 	print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
 	print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
 			     skb->data, skb->len);
 			     skb->data, skb->len);
 
 
-	printk(KERN_ERR "%s: please check your hardware and cables, if "
-			"you see this message frequently.\n",
-	       wiphy_name(ar->hw->wiphy));
+	wiphy_err(ar->hw->wiphy,
+		  "If you see this message frequently, please check your hardware and cables.\n");
 
 
 err_silent:
 err_silent:
 	if (ar->rx_failover_missing) {
 	if (ar->rx_failover_missing) {
@@ -1384,10 +1378,10 @@ static void ar9170_tx(struct ar9170 *ar)
 
 
 		if (remaining_space < frames) {
 		if (remaining_space < frames) {
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
-			       "remaining slots:%d, needed:%d\n",
-			       wiphy_name(ar->hw->wiphy), i, remaining_space,
-			       frames);
+			wiphy_debug(ar->hw->wiphy,
+				    "tx quota reached queue:%d, "
+				    "remaining slots:%d, needed:%d\n",
+				    i, remaining_space, frames);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 			frames = remaining_space;
 			frames = remaining_space;
 		}
 		}
@@ -1396,18 +1390,14 @@ static void ar9170_tx(struct ar9170 *ar)
 		ar->tx_stats[i].count += frames;
 		ar->tx_stats[i].count += frames;
 		if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
 		if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: queue %d full\n",
-			       wiphy_name(ar->hw->wiphy), i);
-
-			printk(KERN_DEBUG "%s: stuck frames: ===>\n",
-			       wiphy_name(ar->hw->wiphy));
+			wiphy_debug(ar->hw->wiphy, "queue %d full\n", i);
+			wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n");
 			ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
 			ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
 			ar9170_dump_txqueue(ar, &ar->tx_status[i]);
 			ar9170_dump_txqueue(ar, &ar->tx_status[i]);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 
 
 #ifdef AR9170_QUEUE_STOP_DEBUG
 #ifdef AR9170_QUEUE_STOP_DEBUG
-			printk(KERN_DEBUG "%s: stop queue %d\n",
-			       wiphy_name(ar->hw->wiphy), i);
+			wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i);
 			__ar9170_dump_txstats(ar);
 			__ar9170_dump_txstats(ar);
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 			ieee80211_stop_queue(ar->hw, i);
 			ieee80211_stop_queue(ar->hw, i);
@@ -1435,8 +1425,7 @@ static void ar9170_tx(struct ar9170 *ar)
 					  msecs_to_jiffies(AR9170_TX_TIMEOUT);
 					  msecs_to_jiffies(AR9170_TX_TIMEOUT);
 
 
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: send frame q:%d =>\n",
-			       wiphy_name(ar->hw->wiphy), i);
+			wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i);
 			ar9170_print_txheader(ar, skb);
 			ar9170_print_txheader(ar, skb);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 
 
@@ -1453,26 +1442,25 @@ static void ar9170_tx(struct ar9170 *ar)
 		}
 		}
 
 
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-		printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
-		       wiphy_name(ar->hw->wiphy), i);
+		wiphy_debug(ar->hw->wiphy,
+			    "ar9170_tx report for queue %d\n", i);
 
 
-		printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
-		       wiphy_name(ar->hw->wiphy));
+		wiphy_debug(ar->hw->wiphy,
+			    "unprocessed pending frames left:\n");
 		ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
 		ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 
 
 		if (unlikely(frames_failed)) {
 		if (unlikely(frames_failed)) {
 #ifdef AR9170_QUEUE_DEBUG
 #ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: frames failed %d =>\n",
-			       wiphy_name(ar->hw->wiphy), frames_failed);
+			wiphy_debug(ar->hw->wiphy,
+				    "frames failed %d =>\n", frames_failed);
 #endif /* AR9170_QUEUE_DEBUG */
 #endif /* AR9170_QUEUE_DEBUG */
 
 
 			spin_lock_irqsave(&ar->tx_stats_lock, flags);
 			spin_lock_irqsave(&ar->tx_stats_lock, flags);
 			ar->tx_stats[i].len -= frames_failed;
 			ar->tx_stats[i].len -= frames_failed;
 			ar->tx_stats[i].count -= frames_failed;
 			ar->tx_stats[i].count -= frames_failed;
 #ifdef AR9170_QUEUE_STOP_DEBUG
 #ifdef AR9170_QUEUE_STOP_DEBUG
-			printk(KERN_DEBUG "%s: wake queue %d\n",
-			       wiphy_name(ar->hw->wiphy), i);
+			wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i);
 			__ar9170_dump_txstats(ar);
 			__ar9170_dump_txstats(ar);
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 			ieee80211_wake_queue(ar->hw, i);
 			ieee80211_wake_queue(ar->hw, i);
@@ -1917,6 +1905,24 @@ static int ar9170_get_stats(struct ieee80211_hw *hw,
 	return 0;
 	return 0;
 }
 }
 
 
+static int ar9170_get_survey(struct ieee80211_hw *hw, int idx,
+				struct survey_info *survey)
+{
+	struct ar9170 *ar = hw->priv;
+	struct ieee80211_conf *conf = &hw->conf;
+
+	if (idx != 0)
+		return -ENOENT;
+
+	/* TODO: update noise value, e.g. call ar9170_set_channel */
+
+	survey->channel = conf->channel;
+	survey->filled = SURVEY_INFO_NOISE_DBM;
+	survey->noise = ar->noise[0];
+
+	return 0;
+}
+
 static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
 static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
 			  const struct ieee80211_tx_queue_params *param)
 			  const struct ieee80211_tx_queue_params *param)
 {
 {
@@ -1969,6 +1975,7 @@ static const struct ieee80211_ops ar9170_ops = {
 	.get_tsf		= ar9170_op_get_tsf,
 	.get_tsf		= ar9170_op_get_tsf,
 	.set_key		= ar9170_set_key,
 	.set_key		= ar9170_set_key,
 	.get_stats		= ar9170_get_stats,
 	.get_stats		= ar9170_get_stats,
+	.get_survey		= ar9170_get_survey,
 	.ampdu_action		= ar9170_ampdu_action,
 	.ampdu_action		= ar9170_ampdu_action,
 };
 };
 
 

+ 3 - 5
drivers/net/wireless/ath/ar9170/phy.c

@@ -670,8 +670,7 @@ static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
 	ar9170_regwrite_finish();
 	ar9170_regwrite_finish();
 	err = ar9170_regwrite_result();
 	err = ar9170_regwrite_result();
 	if (err)
 	if (err)
-		printk(KERN_ERR "%s: rf init failed\n",
-		       wiphy_name(ar->hw->wiphy));
+		wiphy_err(ar->hw->wiphy, "rf init failed\n");
 	return err;
 	return err;
 }
 }
 
 
@@ -1702,9 +1701,8 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
 				       0x200 | ar->phy_heavy_clip);
 				       0x200 | ar->phy_heavy_clip);
 		if (err) {
 		if (err) {
 			if (ar9170_nag_limiter(ar))
 			if (ar9170_nag_limiter(ar))
-				printk(KERN_ERR "%s: failed to set "
-				       "heavy clip\n",
-				       wiphy_name(ar->hw->wiphy));
+				wiphy_err(ar->hw->wiphy,
+					  "failed to set heavy clip\n");
 		}
 		}
 	}
 	}
 
 

+ 18 - 0
drivers/net/wireless/ath/ath5k/debug.c

@@ -239,6 +239,9 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
 		"TSF\t\t0x%016llx\tTU: %08x\n",
 		"TSF\t\t0x%016llx\tTU: %08x\n",
 		(unsigned long long)tsf, TSF_TO_TU(tsf));
 		(unsigned long long)tsf, TSF_TO_TU(tsf));
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 
@@ -334,6 +337,9 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf,
 		sc->debug.level == dbg_info[i].level ? '+' : ' ',
 		sc->debug.level == dbg_info[i].level ? '+' : ' ',
 		dbg_info[i].level, dbg_info[i].desc);
 		dbg_info[i].level, dbg_info[i].desc);
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 
@@ -433,6 +439,9 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
 	len += snprintf(buf+len, sizeof(buf)-len,
 	len += snprintf(buf+len, sizeof(buf)-len,
 			"AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
 			"AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 
@@ -542,6 +551,9 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
 	len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
 	len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
 			st->tx_all_count);
 			st->tx_all_count);
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 
@@ -681,6 +693,9 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
 			ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
 			ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
 			ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2)));
 			ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2)));
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 
@@ -766,6 +781,9 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
 		len += snprintf(buf+len, sizeof(buf)-len, "  len: %d\n", n);
 		len += snprintf(buf+len, sizeof(buf)-len, "  len: %d\n", n);
 	}
 	}
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 

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

@@ -131,11 +131,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
 
 
 	ah = sc->sc_ah;
 	ah = sc->sc_ah;
 	ath9k_hw_name(ah, hw_name, sizeof(hw_name));
 	ath9k_hw_name(ah, hw_name, sizeof(hw_name));
-	printk(KERN_INFO
-	       "%s: %s mem=0x%lx, irq=%d\n",
-	       wiphy_name(hw->wiphy),
-	       hw_name,
-	       (unsigned long)mem, irq);
+	wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
+		   hw_name, (unsigned long)mem, irq);
 
 
 	return 0;
 	return 0;
 
 

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

@@ -1506,6 +1506,9 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
 	nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
 	nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
 	nfarray[2] = sign_extend(nf, 9);
 	nfarray[2] = sign_extend(nf, 9);
 
 
+	if (!IS_CHAN_HT40(ah->curchan))
+		return;
+
 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
 	nfarray[3] = sign_extend(nf, 9);
 	nfarray[3] = sign_extend(nf, 9);
 
 

+ 4 - 2
drivers/net/wireless/ath/ath9k/ar9002_phy.c

@@ -477,7 +477,8 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah,
 	nfarray[0] = sign_extend(nf, 9);
 	nfarray[0] = sign_extend(nf, 9);
 
 
 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
-	nfarray[3] = sign_extend(nf, 9);
+	if (IS_CHAN_HT40(ah->curchan))
+		nfarray[3] = sign_extend(nf, 9);
 
 
 	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
 	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
 		return;
 		return;
@@ -486,7 +487,8 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah,
 	nfarray[1] = sign_extend(nf, 9);
 	nfarray[1] = sign_extend(nf, 9);
 
 
 	nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
 	nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
-	nfarray[4] = sign_extend(nf, 9);
+	if (IS_CHAN_HT40(ah->curchan))
+		nfarray[4] = sign_extend(nf, 9);
 }
 }
 
 
 static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
 static void ar9002_hw_set_nf_limits(struct ath_hw *ah)

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

@@ -1029,6 +1029,9 @@ static void ar9003_hw_do_getnf(struct ath_hw *ah,
 	nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
 	nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
 	nfarray[2] = sign_extend(nf, 9);
 	nfarray[2] = sign_extend(nf, 9);
 
 
+	if (!IS_CHAN_HT40(ah->curchan))
+		return;
+
 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
 	nfarray[3] = sign_extend(nf, 9);
 	nfarray[3] = sign_extend(nf, 9);
 
 

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

@@ -687,7 +687,7 @@ bool ath9k_all_wiphys_idle(struct ath_softc *sc);
 void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 
 
 void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
 void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
-void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
+bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
 
 
 void ath_start_rfkill_poll(struct ath_softc *sc);
 void ath_start_rfkill_poll(struct ath_softc *sc);
 extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
 extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);

+ 2 - 19
drivers/net/wireless/ath/ath9k/calib.c

@@ -172,26 +172,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 	struct ath9k_nfcal_hist *h;
 	struct ath9k_nfcal_hist *h;
 	unsigned i, j;
 	unsigned i, j;
 	int32_t val;
 	int32_t val;
-	u8 chainmask;
+	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_common *common = ath9k_hw_common(ah);
 
 
-	if (AR_SREV_9300_20_OR_LATER(ah))
-		chainmask = 0x3F;
-	else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-		chainmask = 0x9;
-	else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
-		if ((ah->rxchainmask & 0x2) || (ah->rxchainmask & 0x4))
-			chainmask = 0x1B;
-		else
-			chainmask = 0x09;
-	} else {
-		if (ah->rxchainmask & 0x4)
-			chainmask = 0x3F;
-		else if (ah->rxchainmask & 0x2)
-			chainmask = 0x1B;
-		else
-			chainmask = 0x09;
-	}
 	h = ah->nfCalHist;
 	h = ah->nfCalHist;
 
 
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 	for (i = 0; i < NUM_NF_READINGS; i++) {
@@ -278,7 +261,7 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
 
 
 		ath_print(common, ATH_DBG_CALIBRATE,
 		ath_print(common, ATH_DBG_CALIBRATE,
 			  "NF calibrated [%s] [chain %d] is %d\n",
 			  "NF calibrated [%s] [chain %d] is %d\n",
-			  (i > 3 ? "ext" : "ctl"), i % 3, nf[i]);
+			  (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
 
 
 		if (nf[i] > limit->max) {
 		if (nf[i] > limit->max) {
 			ath_print(common, ATH_DBG_CALIBRATE,
 			ath_print(common, ATH_DBG_CALIBRATE,

+ 9 - 0
drivers/net/wireless/ath/ath9k/htc_drv_main.c

@@ -524,6 +524,9 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
 	len += snprintf(buf + len, sizeof(buf) - len,
 	len += snprintf(buf + len, sizeof(buf) - len,
 			"%19s : %10u\n", "TX Rate", priv->debug.txrate);
 			"%19s : %10u\n", "TX Rate", priv->debug.txrate);
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 
@@ -569,6 +572,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
 			"%20s : %10u\n", "VO queued",
 			"%20s : %10u\n", "VO queued",
 			priv->debug.tx_stats.queue_stats[WME_AC_VO]);
 			priv->debug.tx_stats.queue_stats[WME_AC_VO]);
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 
@@ -595,6 +601,9 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
 			"%20s : %10u\n", "SKBs Dropped",
 			"%20s : %10u\n", "SKBs Dropped",
 			priv->debug.rx_stats.skb_dropped);
 			priv->debug.rx_stats.skb_dropped);
 
 
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 }
 
 

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

@@ -532,7 +532,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 
 
 	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
 	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
 		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
 		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
-		    (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
+		    ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
+		     !ah->is_pciexpress)) {
 			ah->config.serialize_regmode =
 			ah->config.serialize_regmode =
 				SER_REG_MODE_ON;
 				SER_REG_MODE_ON;
 		} else {
 		} else {

+ 9 - 4
drivers/net/wireless/ath/ath9k/main.c

@@ -1994,11 +1994,12 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
 
 
 	mutex_lock(&sc->mutex);
 	mutex_lock(&sc->mutex);
 	if (ath9k_wiphy_scanning(sc)) {
 	if (ath9k_wiphy_scanning(sc)) {
-		printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
-		       "same time\n");
 		/*
 		/*
-		 * Do not allow the concurrent scanning state for now. This
-		 * could be improved with scanning control moved into ath9k.
+		 * There is a race here in mac80211 but fixing it requires
+		 * we revisit how we handle the scan complete callback.
+		 * After mac80211 fixes we will not have configured hardware
+		 * to the home channel nor would we have configured the RX
+		 * filter yet.
 		 */
 		 */
 		mutex_unlock(&sc->mutex);
 		mutex_unlock(&sc->mutex);
 		return;
 		return;
@@ -2014,6 +2015,10 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
 	mutex_unlock(&sc->mutex);
 	mutex_unlock(&sc->mutex);
 }
 }
 
 
+/*
+ * XXX: this requires a revisit after the driver
+ * scan_complete gets moved to another place/removed in mac80211.
+ */
 static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
 static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
 {
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_wiphy *aphy = hw->priv;

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

@@ -209,11 +209,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	}
 	}
 
 
 	ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
 	ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
-	printk(KERN_INFO
-	       "%s: %s mem=0x%lx, irq=%d\n",
-	       wiphy_name(hw->wiphy),
-	       hw_name,
-	       (unsigned long)mem, pdev->irq);
+	wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
+		   hw_name, (unsigned long)mem, pdev->irq);
 
 
 	return 0;
 	return 0;
 
 

+ 353 - 248
drivers/net/wireless/ath/ath9k/rc.c

@@ -20,95 +20,145 @@
 #include "ath9k.h"
 #include "ath9k.h"
 
 
 static const struct ath_rate_table ar5416_11na_ratetable = {
 static const struct ath_rate_table ar5416_11na_ratetable = {
-	43,
+	68,
 	8, /* MCS start */
 	8, /* MCS start */
 	{
 	{
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 0, 12, 0, 0, 0, 0, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800,  1, 18, 0, 1, 1, 1, 1 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10000, 2, 24, 2, 2, 2, 2, 2 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			13900, 3, 36, 2, 3, 3, 3, 3 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17300, 4, 48, 4, 4, 4, 4, 4 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23000, 5, 72, 4, 5, 5, 5, 5 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 6, 96, 4, 6, 6, 6, 6 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			29300, 7, 108, 4, 7, 7, 7, 7 },
-		{ VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
-			6400, 0, 0, 0, 8, 25, 8, 25 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
-			12700, 1, 1, 2, 9, 26, 9, 26 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
-			18800, 2, 2, 2, 10, 27, 10, 27 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
-			25000, 3, 3, 4, 11, 28, 11, 28 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
-			36700, 4, 4, 4, 12, 29, 12, 29 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
-			48100, 5, 5, 4, 13, 30, 13, 30 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
-			53500, 6, 6, 4, 14, 31, 14, 31 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
-			59000, 7, 7, 4, 15, 32, 15, 33 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
-			12700, 8, 8, 3, 16, 34, 16, 34 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
-			24800, 9, 9, 2, 17, 35, 17, 35 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
-			36600, 10, 10, 2, 18, 36, 18, 36 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
-			48100, 11, 11, 4, 19, 37, 19, 37 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
-			69500, 12, 12, 4, 20, 38, 20, 38 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
-			89500, 13, 13, 4, 21, 39, 21, 39 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
-			98900, 14, 14, 4, 22, 40, 22, 40 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
-			108300, 15, 15, 4, 23, 41, 24, 42 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 144.4 Mb */
-			12000, 15, 15, 4, 23, 41, 24, 42 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
-			13200, 0, 0, 0, 8, 25, 25, 25 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
-			25900, 1, 1, 2, 9, 26, 26, 26 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
-			38600, 2, 2, 2, 10, 27, 27, 27 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
-			49800, 3, 3, 4, 11, 28, 28, 28 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
-			72200, 4, 4, 4, 12, 29, 29, 29 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
-			92900, 5, 5, 4, 13, 30, 30, 30 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
-			102700, 6, 6, 4, 14, 31, 31, 31 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
-			112000, 7, 7, 4, 15, 32, 33, 33 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
-			122000, 7, 7, 4, 15, 32, 33, 33 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
-			25800, 8, 8, 0, 16, 34, 34, 34 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
-			49800, 9, 9, 2, 17, 35, 35, 35 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
-			71900, 10, 10, 2, 18, 36, 36, 36 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
-			92500, 11, 11, 4, 19, 37, 37, 37 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
-			130300, 12, 12, 4, 20, 38, 38, 38 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
-			162800, 13, 13, 4, 21, 39, 39, 39 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
-			178200, 14, 14, 4, 22, 40, 40, 40 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
-			192100, 15, 15, 4, 23, 41, 42, 42 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
-			207000, 15, 15, 4, 23, 41, 42, 42 },
+		[0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000,
+			5400, 0, 12, 0, 0, 0, 0 }, /* 6 Mb */
+		[1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000,
+			7800,  1, 18, 0, 1, 1, 1 }, /* 9 Mb */
+		[2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
+			10000, 2, 24, 2, 2, 2, 2 }, /* 12 Mb */
+		[3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
+			13900, 3, 36, 2, 3, 3, 3 }, /* 18 Mb */
+		[4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
+			17300, 4, 48, 4, 4, 4, 4 }, /* 24 Mb */
+		[5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
+			23000, 5, 72, 4, 5, 5, 5 }, /* 36 Mb */
+		[6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
+			27400, 6, 96, 4, 6, 6, 6 }, /* 48 Mb */
+		[7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
+			29300, 7, 108, 4, 7, 7, 7 }, /* 54 Mb */
+		[8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500,
+			6400, 0, 0, 0, 38, 8, 38 }, /* 6.5 Mb */
+		[9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
+			12700, 1, 1, 2, 39, 9, 39 }, /* 13 Mb */
+		[10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
+			18800, 2, 2, 2, 40, 10, 40 }, /* 19.5 Mb */
+		[11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
+			25000, 3, 3, 4, 41, 11, 41 }, /* 26 Mb */
+		[12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
+			36700, 4, 4, 4, 42, 12, 42 }, /* 39 Mb */
+		[13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
+			48100, 5, 5, 4, 43, 13, 43 }, /* 52 Mb */
+		[14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
+			53500, 6, 6, 4, 44, 14, 44 }, /* 58.5 Mb */
+		[15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
+			59000, 7, 7, 4, 45, 16, 46 }, /* 65 Mb */
+		[16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
+			65400, 7, 7, 4, 45, 16, 46 }, /* 75 Mb */
+		[17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
+			12700, 8, 8, 0, 47, 17, 47 }, /* 13 Mb */
+		[18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
+			24800, 9, 9, 2, 48, 18, 48 }, /* 26 Mb */
+		[19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
+			36600, 10, 10, 2, 49, 19, 49 }, /* 39 Mb */
+		[20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
+			48100, 11, 11, 4, 50, 20, 50 }, /* 52 Mb */
+		[21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
+			69500, 12, 12, 4, 51, 21, 51 }, /* 78 Mb */
+		[22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
+			89500, 13, 13, 4, 52, 22, 52 }, /* 104 Mb */
+		[23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
+			98900, 14, 14, 4, 53, 23, 53 }, /* 117 Mb */
+		[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
+			108300, 15, 15, 4, 54, 25, 55 }, /* 130 Mb */
+		[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
+			120000, 15, 15, 4, 54, 25, 55 }, /* 144.4 Mb */
+		[26] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
+			17400, 16, 16, 0, 56, 26, 56 }, /* 19.5 Mb */
+		[27] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
+			35100, 17, 17, 2, 57, 27, 57 }, /* 39 Mb */
+		[28] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
+			52600, 18, 18, 2, 58, 28, 58 }, /* 58.5 Mb */
+		[29] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
+			70400, 19, 19, 4, 59, 29, 59 }, /* 78 Mb */
+		[30] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
+			104900, 20, 20, 4, 60, 31, 61 }, /* 117 Mb */
+		[31] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
+			115800, 20, 20, 4, 60, 31, 61 }, /* 130 Mb*/
+		[32] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
+			137200, 21, 21, 4, 62, 33, 63 }, /* 156 Mb */
+		[33] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
+			151100, 21, 21, 4, 62, 33, 63 }, /* 173.3 Mb */
+		[34] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
+			152800, 22, 22, 4, 64, 35, 65 }, /* 175.5 Mb */
+		[35] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
+			168400, 22, 22, 4, 64, 35, 65 }, /* 195 Mb*/
+		[36] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
+			168400, 23, 23, 4, 66, 37, 67 }, /* 195 Mb */
+		[37] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
+			185000, 23, 23, 4, 66, 37, 67 }, /* 216.7 Mb */
+		[38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
+			13200, 0, 0, 0, 38, 38, 38 }, /* 13.5 Mb*/
+		[39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
+			25900, 1, 1, 2, 39, 39, 39 }, /* 27.0 Mb*/
+		[40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
+			38600, 2, 2, 2, 40, 40, 40 }, /* 40.5 Mb*/
+		[41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
+			49800, 3, 3, 4, 41, 41, 41 }, /* 54 Mb */
+		[42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
+			72200, 4, 4, 4, 42, 42, 42 }, /* 81 Mb */
+		[43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000,
+			92900, 5, 5, 4, 43, 43, 43 }, /* 108 Mb */
+		[44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
+			102700, 6, 6, 4, 44, 44, 44 }, /* 121.5 Mb*/
+		[45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
+			112000, 7, 7, 4, 45, 46, 46 }, /* 135 Mb */
+		[46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
+			122000, 7, 7, 4, 45, 46, 46 }, /* 150 Mb */
+		[47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
+			25800, 8, 8, 0, 47, 47, 47 }, /* 27 Mb */
+		[48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
+			49800, 9, 9, 2, 48, 48, 48 }, /* 54 Mb */
+		[49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
+			71900, 10, 10, 2, 49, 49, 49 }, /* 81 Mb */
+		[50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
+			92500, 11, 11, 4, 50, 50, 50 }, /* 108 Mb */
+		[51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
+			130300, 12, 12, 4, 51, 51, 51 }, /* 162 Mb */
+		[52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
+			162800, 13, 13, 4, 52, 52, 52 }, /* 216 Mb */
+		[53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
+			178200, 14, 14, 4, 53, 53, 53 }, /* 243 Mb */
+		[54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
+			192100, 15, 15, 4, 54, 55, 55 }, /* 270 Mb */
+		[55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
+			207000, 15, 15, 4, 54, 55, 55 }, /* 300 Mb */
+		[56] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
+			36100, 16, 16, 0, 56, 56, 56 }, /* 40.5 Mb */
+		[57] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
+			72900, 17, 17, 2, 57, 57, 57 }, /* 81 Mb */
+		[58] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
+			108300, 18, 18, 2, 58, 58, 58 }, /* 121.5 Mb */
+		[59] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
+			142000, 19, 19, 4, 59, 59, 59 }, /*  162 Mb */
+		[60] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
+			205100, 20, 20, 4, 60, 61, 61 }, /*  243 Mb */
+		[61] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
+			224700, 20, 20, 4, 60, 61, 61 }, /*  270 Mb */
+		[62] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
+			263100, 21, 21, 4, 62, 63, 63 }, /*  324 Mb */
+		[63] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
+			288000, 21, 21, 4, 62, 63, 63 }, /*  360 Mb */
+		[64] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
+			290700, 22, 22, 4, 64, 65, 65 }, /* 364.5 Mb */
+		[65] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
+			317200, 22, 22, 4, 64, 65, 65 }, /* 405 Mb */
+		[66] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
+			317200, 23, 23, 4, 66, 67, 67 }, /* 405 Mb */
+		[67] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
+			346400, 23, 23, 4, 66, 67, 67 }, /* 450 Mb */
 	},
 	},
 	50,  /* probe interval */
 	50,  /* probe interval */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
@@ -118,103 +168,153 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
  * for HT are the 64K max aggregate limit */
  * for HT are the 64K max aggregate limit */
 
 
 static const struct ath_rate_table ar5416_11ng_ratetable = {
 static const struct ath_rate_table ar5416_11ng_ratetable = {
-	47,
+	72,
 	12, /* MCS start */
 	12, /* MCS start */
 	{
 	{
-		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-			900, 0, 2, 0, 0, 0, 0, 0 },
-		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-			1900, 1, 4, 1, 1, 1, 1, 1 },
-		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-			4900, 2, 11, 2, 2, 2, 2, 2 },
-		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-			8100, 3, 22, 3, 3, 3, 3, 3 },
-		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 4, 12, 4, 4, 4, 4, 4 },
-		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800, 5, 18, 4, 5, 5, 5, 5 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10100, 6, 24, 6, 6, 6, 6, 6 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			14100, 7, 36, 6, 7, 7, 7, 7 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17700, 8, 48, 8, 8, 8, 8, 8 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23700, 9, 72, 8, 9, 9, 9, 9 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 10, 96, 8, 10, 10, 10, 10 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			30900, 11, 108, 8, 11, 11, 11, 11 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
-			6400, 0, 0, 4, 12, 29, 12, 29 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
-			12700, 1, 1, 6, 13, 30, 13, 30 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
-			18800, 2, 2, 6, 14, 31, 14, 31 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
-			25000, 3, 3, 8, 15, 32, 15, 32 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
-			36700, 4, 4, 8, 16, 33, 16, 33 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
-			48100, 5, 5, 8, 17, 34, 17, 34 },
-		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
-			53500, 6, 6, 8, 18, 35, 18, 35 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
-			59000, 7, 7, 8, 19, 36, 19, 37 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
-			12700, 8, 8, 4, 20, 38, 20, 38 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
-			24800, 9, 9, 6, 21, 39, 21, 39 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
-			36600, 10, 10, 6, 22, 40, 22, 40 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
-			48100, 11, 11, 8, 23, 41, 23, 41 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
-			69500, 12, 12, 8, 24, 42, 24, 42 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
-			89500, 13, 13, 8, 25, 43, 25, 43 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
-			98900, 14, 14, 8, 26, 44, 26, 44 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
-			108300, 15, 15, 8, 27, 45, 28, 46 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 130 Mb */
-			120000, 15, 15, 8, 27, 45, 28, 46 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
-			13200, 0, 0, 8, 12, 29, 29, 29 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
-			25900, 1, 1, 8, 13, 30, 30, 30 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
-			38600, 2, 2, 8, 14, 31, 31, 31 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
-			49800, 3, 3, 8,  15, 32, 32, 32 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
-			72200, 4, 4, 8, 16, 33, 33, 33 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
-			92900, 5, 5, 8, 17, 34, 34, 34 },
-		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
-			102700, 6, 6, 8, 18, 35, 35, 35 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
-			112000, 7, 7, 8, 19, 36, 37, 37 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
-			122000, 7, 7, 8, 19, 36, 37, 37 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
-			25800, 8, 8, 8, 20, 38, 38, 38 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
-			49800, 9, 9, 8, 21, 39, 39, 39 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
-			71900, 10, 10, 8, 22, 40, 40, 40 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
-			92500, 11, 11, 8, 23, 41, 41, 41 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
-			130300, 12, 12, 8, 24, 42, 42, 42 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
-			162800, 13, 13, 8, 25, 43, 43, 43 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
-			178200, 14, 14, 8, 26, 44, 44, 44 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
-			192100, 15, 15, 8, 27, 45, 46, 46 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
-			207000, 15, 15, 8, 27, 45, 46, 46 },
+		[0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000,
+			900, 0, 2, 0, 0, 0, 0 }, /* 1 Mb */
+		[1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000,
+			1900, 1, 4, 1, 1, 1, 1 }, /* 2 Mb */
+		[2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500,
+			4900, 2, 11, 2, 2, 2, 2 }, /* 5.5 Mb */
+		[3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000,
+			8100, 3, 22, 3, 3, 3, 3 }, /* 11 Mb */
+		[4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000,
+			5400, 4, 12, 4, 4, 4, 4 }, /* 6 Mb */
+		[5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000,
+			7800, 5, 18, 4, 5, 5, 5 }, /* 9 Mb */
+		[6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
+			10100, 6, 24, 6, 6, 6, 6 }, /* 12 Mb */
+		[7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
+			14100, 7, 36, 6, 7, 7, 7 }, /* 18 Mb */
+		[8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
+			17700, 8, 48, 8, 8, 8, 8 }, /* 24 Mb */
+		[9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
+			23700, 9, 72, 8, 9, 9, 9 }, /* 36 Mb */
+		[10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
+			27400, 10, 96, 8, 10, 10, 10 }, /* 48 Mb */
+		[11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
+			30900, 11, 108, 8, 11, 11, 11 }, /* 54 Mb */
+		[12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500,
+			6400, 0, 0, 4, 42, 12, 42 }, /* 6.5 Mb */
+		[13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
+			12700, 1, 1, 6, 43, 13, 43 }, /* 13 Mb */
+		[14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
+			18800, 2, 2, 6, 44, 14, 44 }, /* 19.5 Mb*/
+		[15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
+			25000, 3, 3, 8, 45, 15, 45 }, /* 26 Mb */
+		[16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
+			36700, 4, 4, 8, 46, 16, 46 }, /* 39 Mb */
+		[17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
+			48100, 5, 5, 8, 47, 17, 47 }, /* 52 Mb */
+		[18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
+			53500, 6, 6, 8, 48, 18, 48 }, /* 58.5 Mb */
+		[19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
+			59000, 7, 7, 8, 49, 20, 50 }, /* 65 Mb */
+		[20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
+			65400, 7, 7, 8, 49, 20, 50 }, /* 65 Mb*/
+		[21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
+			12700, 8, 8, 4, 51, 21, 51 }, /* 13 Mb */
+		[22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
+			24800, 9, 9, 6, 52, 22, 52 }, /* 26 Mb */
+		[23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
+			36600, 10, 10, 6, 53, 23, 53 }, /* 39 Mb */
+		[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
+			48100, 11, 11, 8, 54, 24, 54 }, /* 52 Mb */
+		[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
+			69500, 12, 12, 8, 55, 25, 55 }, /* 78 Mb */
+		[26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
+			89500, 13, 13, 8, 56, 26, 56 }, /* 104 Mb */
+		[27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
+			98900, 14, 14, 8, 57, 27, 57 }, /* 117 Mb */
+		[28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
+			108300, 15, 15, 8, 58, 29, 59 }, /* 130 Mb */
+		[29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
+			120000, 15, 15, 8, 58, 29, 59 }, /* 144.4 Mb */
+		[30] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
+			17400, 16, 16, 4, 60, 30, 60 }, /* 19.5 Mb */
+		[31] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
+			35100, 17, 17, 6, 61, 31, 61 }, /* 39 Mb */
+		[32] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
+			52600, 18, 18, 6, 62, 32, 62 }, /* 58.5 Mb */
+		[33] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
+			70400, 19, 19, 8, 63, 33, 63 }, /* 78 Mb */
+		[34] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
+			104900, 20, 20, 8, 64, 35, 65 }, /* 117 Mb */
+		[35] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
+			115800, 20, 20, 8, 64, 35, 65 }, /* 130 Mb */
+		[36] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
+			137200, 21, 21, 8, 66, 37, 67 }, /* 156 Mb */
+		[37] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
+			151100, 21, 21, 8, 66, 37, 67 }, /* 173.3 Mb */
+		[38] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
+			152800, 22, 22, 8, 68, 39, 69 }, /* 175.5 Mb */
+		[39] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
+			168400, 22, 22, 8, 68, 39, 69 }, /* 195 Mb */
+		[40] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
+			168400, 23, 23, 8, 70, 41, 71 }, /* 195 Mb */
+		[41] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
+			185000, 23, 23, 8, 70, 41, 71 }, /* 216.7 Mb */
+		[42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
+			13200, 0, 0, 8, 42, 42, 42 }, /* 13.5 Mb */
+		[43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
+			25900, 1, 1, 8, 43, 43, 43 }, /* 27.0 Mb */
+		[44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
+			38600, 2, 2, 8, 44, 44, 44 }, /* 40.5 Mb */
+		[45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
+			49800, 3, 3, 8, 45, 45, 45 }, /* 54 Mb */
+		[46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
+			72200, 4, 4, 8, 46, 46, 46 }, /* 81 Mb */
+		[47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000,
+			92900, 5, 5, 8, 47, 47, 47 }, /* 108 Mb */
+		[48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
+			102700, 6, 6, 8, 48, 48, 48 }, /* 121.5 Mb */
+		[49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
+			112000, 7, 7, 8, 49, 50, 50 }, /* 135 Mb */
+		[50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
+			122000, 7, 7, 8, 49, 50, 50 }, /* 150 Mb */
+		[51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
+			25800, 8, 8, 8, 51, 51, 51 }, /* 27 Mb */
+		[52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
+			49800, 9, 9, 8, 52, 52, 52 }, /* 54 Mb */
+		[53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
+			71900, 10, 10, 8, 53, 53, 53 }, /* 81 Mb */
+		[54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
+			92500, 11, 11, 8, 54, 54, 54 }, /* 108 Mb */
+		[55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
+			130300, 12, 12, 8, 55, 55, 55 }, /* 162 Mb */
+		[56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
+			162800, 13, 13, 8, 56, 56, 56 }, /* 216 Mb */
+		[57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
+			178200, 14, 14, 8, 57, 57, 57 }, /* 243 Mb */
+		[58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
+			192100, 15, 15, 8, 58, 59, 59 }, /* 270 Mb */
+		[59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
+			207000, 15, 15, 8, 58, 59, 59 }, /* 300 Mb */
+		[60] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
+			36100, 16, 16, 8, 60, 60, 60 }, /* 40.5 Mb */
+		[61] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
+			72900, 17, 17, 8, 61, 61, 61 }, /* 81 Mb */
+		[62] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
+			108300, 18, 18, 8, 62, 62, 62 }, /* 121.5 Mb */
+		[63] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
+			142000, 19, 19, 8, 63, 63, 63 }, /* 162 Mb */
+		[64] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
+			205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */
+		[65] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
+			224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */
+		[66] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
+			263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */
+		[67] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
+			288000, 21, 21, 8, 66, 67, 67 }, /* 360 Mb */
+		[68] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
+			290700, 22, 22, 8, 68, 69, 69 }, /* 364.5 Mb */
+		[69] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
+			317200, 22, 22, 8, 68, 69, 69 }, /* 405 Mb */
+		[70] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
+			317200, 23, 23, 8, 70, 71, 71 }, /* 405 Mb */
+		[71] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
+			346400, 23, 23, 8, 70, 71, 71 }, /* 450 Mb */
 	},
 	},
 	50,  /* probe interval */
 	50,  /* probe interval */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
@@ -224,22 +324,22 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
 	8,
 	8,
 	0,
 	0,
 	{
 	{
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 0, 12, 0, 0, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800,  1, 18, 0, 1, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10000, 2, 24, 2, 2, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			13900, 3, 36, 2, 3, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17300, 4, 48, 4, 4, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23000, 5, 72, 4, 5, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 6, 96, 4, 6, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			29300, 7, 108, 4, 7, 0 },
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+			5400, 0, 12, 0},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+			7800,  1, 18, 0},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+			10000, 2, 24, 2},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+			13900, 3, 36, 2},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+			17300, 4, 48, 4},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+			23000, 5, 72, 4},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+			27400, 6, 96, 4},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+			29300, 7, 108, 4},
 	},
 	},
 	50,  /* probe interval */
 	50,  /* probe interval */
 	0,   /* Phy rates allowed initially */
 	0,   /* Phy rates allowed initially */
@@ -249,30 +349,30 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
 	12,
 	12,
 	0,
 	0,
 	{
 	{
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-			900, 0, 2, 0, 0, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-			1900, 1, 4, 1, 1, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-			4900, 2, 11, 2, 2, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-			8100, 3, 22, 3, 3, 0 },
-		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 4, 12, 4, 4, 0 },
-		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800, 5, 18, 4, 5, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10000, 6, 24, 6, 6, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			13900, 7, 36, 6, 7, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17300, 8, 48, 8, 8, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23000, 9, 72, 8, 9, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 10, 96, 8, 10, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			29300, 11, 108, 8, 11, 0 },
+		{ RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+			900, 0, 2, 0},
+		{ RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+			1900, 1, 4, 1},
+		{ RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+			4900, 2, 11, 2},
+		{ RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+			8100, 3, 22, 3},
+		{ RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+			5400, 4, 12, 4},
+		{ RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+			7800, 5, 18, 4},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+			10000, 6, 24, 6},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+			13900, 7, 36, 6},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+			17300, 8, 48, 8},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+			23000, 9, 72, 8},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+			27400, 10, 96, 8},
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+			29300, 11, 108, 8},
 	},
 	},
 	50,  /* probe interval */
 	50,  /* probe interval */
 	0,   /* Phy rates allowed initially */
 	0,   /* Phy rates allowed initially */
@@ -342,7 +442,7 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
 					   u8 index, int valid_tx_rate)
 					   u8 index, int valid_tx_rate)
 {
 {
 	BUG_ON(index > ath_rc_priv->rate_table_size);
 	BUG_ON(index > ath_rc_priv->rate_table_size);
-	ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
+	ath_rc_priv->valid_rate_index[index] = !!valid_tx_rate;
 }
 }
 
 
 static inline
 static inline
@@ -374,6 +474,8 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
 		return 0;
 		return 0;
 	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
 	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
 		return 0;
 		return 0;
+	if (WLAN_RC_PHY_TS(phy) && !(capflag & WLAN_RC_TS_FLAG))
+		return 0;
 	if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
 	if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
 		return 0;
 		return 0;
 	if (!ignore_cw && WLAN_RC_PHY_HT(phy))
 	if (!ignore_cw && WLAN_RC_PHY_HT(phy))
@@ -404,13 +506,9 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
 				 u32 capflag)
 				 u32 capflag)
 {
 {
 	u8 i, hi = 0;
 	u8 i, hi = 0;
-	u32 valid;
 
 
 	for (i = 0; i < rate_table->rate_cnt; i++) {
 	for (i = 0; i < rate_table->rate_cnt; i++) {
-		valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-			 rate_table->info[i].valid_single_stream :
-			 rate_table->info[i].valid);
-		if (valid == 1) {
+		if (rate_table->info[i].rate_flags & RC_LEGACY) {
 			u32 phy = rate_table->info[i].phy;
 			u32 phy = rate_table->info[i].phy;
 			u8 valid_rate_count = 0;
 			u8 valid_rate_count = 0;
 
 
@@ -422,7 +520,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
 			ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
 			ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
 			ath_rc_priv->valid_phy_ratecnt[phy] += 1;
 			ath_rc_priv->valid_phy_ratecnt[phy] += 1;
 			ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
 			ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
-			hi = A_MAX(hi, i);
+			hi = i;
 		}
 		}
 	}
 	}
 
 
@@ -440,9 +538,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
 	for (i = 0; i < rateset->rs_nrates; i++) {
 	for (i = 0; i < rateset->rs_nrates; i++) {
 		for (j = 0; j < rate_table->rate_cnt; j++) {
 		for (j = 0; j < rate_table->rate_cnt; j++) {
 			u32 phy = rate_table->info[j].phy;
 			u32 phy = rate_table->info[j].phy;
-			u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-				     rate_table->info[j].valid_single_stream :
-				     rate_table->info[j].valid);
+			u16 rate_flags = rate_table->info[i].rate_flags;
 			u8 rate = rateset->rs_rates[i];
 			u8 rate = rateset->rs_rates[i];
 			u8 dot11rate = rate_table->info[j].dot11rate;
 			u8 dot11rate = rate_table->info[j].dot11rate;
 
 
@@ -451,8 +547,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
 			 * (VALID/VALID_20/VALID_40) flags */
 			 * (VALID/VALID_20/VALID_40) flags */
 
 
 			if ((rate == dot11rate) &&
 			if ((rate == dot11rate) &&
-			    ((valid & WLAN_RC_CAP_MODE(capflag)) ==
-			     WLAN_RC_CAP_MODE(capflag)) &&
+			    (rate_flags & WLAN_RC_CAP_MODE(capflag)) ==
+			    WLAN_RC_CAP_MODE(capflag) &&
+			    (rate_flags & WLAN_RC_CAP_STREAM(capflag)) &&
 			    !WLAN_RC_PHY_HT(phy)) {
 			    !WLAN_RC_PHY_HT(phy)) {
 				u8 valid_rate_count = 0;
 				u8 valid_rate_count = 0;
 
 
@@ -486,14 +583,13 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
 	for (i = 0; i < rateset->rs_nrates; i++) {
 	for (i = 0; i < rateset->rs_nrates; i++) {
 		for (j = 0; j < rate_table->rate_cnt; j++) {
 		for (j = 0; j < rate_table->rate_cnt; j++) {
 			u32 phy = rate_table->info[j].phy;
 			u32 phy = rate_table->info[j].phy;
-			u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-				     rate_table->info[j].valid_single_stream :
-				     rate_table->info[j].valid);
+			u16 rate_flags = rate_table->info[j].rate_flags;
 			u8 rate = rateset->rs_rates[i];
 			u8 rate = rateset->rs_rates[i];
 			u8 dot11rate = rate_table->info[j].dot11rate;
 			u8 dot11rate = rate_table->info[j].dot11rate;
 
 
 			if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) ||
 			if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) ||
-			    !WLAN_RC_PHY_HT_VALID(valid, capflag))
+			    !(rate_flags & WLAN_RC_CAP_STREAM(capflag)) ||
+			    !WLAN_RC_PHY_HT_VALID(rate_flags, capflag))
 				continue;
 				continue;
 
 
 			if (!ath_rc_valid_phyrate(phy, capflag, 0))
 			if (!ath_rc_valid_phyrate(phy, capflag, 0))
@@ -589,12 +685,15 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
 	if (rate > (ath_rc_priv->rate_table_size - 1))
 	if (rate > (ath_rc_priv->rate_table_size - 1))
 		rate = ath_rc_priv->rate_table_size - 1;
 		rate = ath_rc_priv->rate_table_size - 1;
 
 
-	if (rate_table->info[rate].valid &&
-	    (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
+	if (RC_TS_ONLY(rate_table->info[rate].rate_flags) &&
+	    (ath_rc_priv->ht_cap & WLAN_RC_TS_FLAG))
+		return rate;
+
+	if (RC_DS_OR_LATER(rate_table->info[rate].rate_flags) &&
+	    (ath_rc_priv->ht_cap & (WLAN_RC_DS_FLAG | WLAN_RC_TS_FLAG)))
 		return rate;
 		return rate;
 
 
-	if (rate_table->info[rate].valid_single_stream &&
-	    !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
+	if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags))
 		return rate;
 		return rate;
 
 
 	/* This should not happen */
 	/* This should not happen */
@@ -1007,12 +1106,19 @@ static void ath_rc_update_ht(struct ath_softc *sc,
 static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
 static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
 				struct ieee80211_tx_rate *rate)
 				struct ieee80211_tx_rate *rate)
 {
 {
-	int rix;
+	int rix = 0, i = 0;
+	int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
 
 
 	if (!(rate->flags & IEEE80211_TX_RC_MCS))
 	if (!(rate->flags & IEEE80211_TX_RC_MCS))
 		return rate->idx;
 		return rate->idx;
 
 
-	rix = rate->idx + rate_table->mcs_start;
+	while (rate->idx > mcs_rix_off[i] &&
+	      i < sizeof(mcs_rix_off)/sizeof(int)) {
+		rix++; i++;
+	}
+
+	rix += rate->idx + rate_table->mcs_start;
+
 	if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
 	if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
 	    (rate->flags & IEEE80211_TX_RC_SHORT_GI))
 	    (rate->flags & IEEE80211_TX_RC_SHORT_GI))
 		rix = rate_table->info[rix].ht_index;
 		rix = rate_table->info[rix].ht_index;
@@ -1020,8 +1126,6 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
 		rix = rate_table->info[rix].sgi_index;
 		rix = rate_table->info[rix].sgi_index;
 	else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
 	else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
 		rix = rate_table->info[rix].cw40index;
 		rix = rate_table->info[rix].cw40index;
-	else
-		rix = rate_table->info[rix].base_index;
 
 
 	return rix;
 	return rix;
 }
 }
@@ -1203,13 +1307,14 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
 
 
 	if (sta->ht_cap.ht_supported) {
 	if (sta->ht_cap.ht_supported) {
 		caps = WLAN_RC_HT_FLAG;
 		caps = WLAN_RC_HT_FLAG;
-		if (sta->ht_cap.mcs.rx_mask[1])
+		if (sta->ht_cap.mcs.rx_mask[1] && sta->ht_cap.mcs.rx_mask[2])
+			caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG;
+		else if (sta->ht_cap.mcs.rx_mask[1])
 			caps |= WLAN_RC_DS_FLAG;
 			caps |= WLAN_RC_DS_FLAG;
 		if (is_cw40)
 		if (is_cw40)
 			caps |= WLAN_RC_40_FLAG;
 			caps |= WLAN_RC_40_FLAG;
 		if (is_sgi)
 		if (is_sgi)
 			caps |= WLAN_RC_SGI_FLAG;
 			caps |= WLAN_RC_SGI_FLAG;
-
 	}
 	}
 
 
 	return caps;
 	return caps;

+ 66 - 23
drivers/net/wireless/ath/ath9k/rc.h

@@ -24,32 +24,63 @@
 struct ath_softc;
 struct ath_softc;
 
 
 #define ATH_RATE_MAX     30
 #define ATH_RATE_MAX     30
-#define RATE_TABLE_SIZE  64
+#define RATE_TABLE_SIZE  72
 #define MAX_TX_RATE_PHY  48
 #define MAX_TX_RATE_PHY  48
 
 
-/* VALID_ALL - valid for 20/40/Legacy,
- * VALID - Legacy only,
- * VALID_20 - HT 20 only,
- * VALID_40 - HT 40 only */
 
 
-#define INVALID    0x0
-#define VALID      0x1
-#define VALID_20   0x2
-#define VALID_40   0x4
-#define VALID_2040 (VALID_20|VALID_40)
-#define VALID_ALL  (VALID_2040|VALID)
+#define RC_INVALID	0x0000
+#define RC_LEGACY	0x0001
+#define RC_SS		0x0002
+#define RC_DS		0x0004
+#define RC_TS		0x0008
+#define RC_HT_20	0x0010
+#define RC_HT_40	0x0020
+
+#define RC_STREAM_MASK	0xe
+#define RC_DS_OR_LATER(f)	((((f) & RC_STREAM_MASK) == RC_DS) || \
+				(((f) & RC_STREAM_MASK) == (RC_DS | RC_TS)))
+#define RC_TS_ONLY(f)		(((f) & RC_STREAM_MASK) == RC_TS)
+#define RC_SS_OR_LEGACY(f)	((f) & (RC_SS | RC_LEGACY))
+
+#define RC_HT_2040		(RC_HT_20 | RC_HT_40)
+#define RC_ALL_STREAM		(RC_SS | RC_DS | RC_TS)
+#define RC_L_SD			(RC_LEGACY | RC_SS | RC_DS)
+#define RC_L_SDT		(RC_LEGACY | RC_SS | RC_DS | RC_TS)
+#define RC_HT_S_20		(RC_HT_20 | RC_SS)
+#define RC_HT_D_20		(RC_HT_20 | RC_DS)
+#define RC_HT_T_20		(RC_HT_20 | RC_TS)
+#define RC_HT_S_40		(RC_HT_40 | RC_SS)
+#define RC_HT_D_40		(RC_HT_40 | RC_DS)
+#define RC_HT_T_40		(RC_HT_40 | RC_TS)
+
+#define RC_HT_SD_20		(RC_HT_20 | RC_SS | RC_DS)
+#define RC_HT_DT_20		(RC_HT_20 | RC_DS | RC_TS)
+#define RC_HT_SD_40		(RC_HT_40 | RC_SS | RC_DS)
+#define RC_HT_DT_40		(RC_HT_40 | RC_DS | RC_TS)
+
+#define RC_HT_SD_2040		(RC_HT_2040 | RC_SS | RC_DS)
+#define RC_HT_SDT_2040		(RC_HT_2040 | RC_SS | RC_DS | RC_TS)
+
+#define RC_HT_SDT_20		(RC_HT_20 | RC_SS | RC_DS | RC_TS)
+#define RC_HT_SDT_40		(RC_HT_40 | RC_SS | RC_DS | RC_TS)
+
+#define RC_ALL			(RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM)
 
 
 enum {
 enum {
 	WLAN_RC_PHY_OFDM,
 	WLAN_RC_PHY_OFDM,
 	WLAN_RC_PHY_CCK,
 	WLAN_RC_PHY_CCK,
 	WLAN_RC_PHY_HT_20_SS,
 	WLAN_RC_PHY_HT_20_SS,
 	WLAN_RC_PHY_HT_20_DS,
 	WLAN_RC_PHY_HT_20_DS,
+	WLAN_RC_PHY_HT_20_TS,
 	WLAN_RC_PHY_HT_40_SS,
 	WLAN_RC_PHY_HT_40_SS,
 	WLAN_RC_PHY_HT_40_DS,
 	WLAN_RC_PHY_HT_40_DS,
+	WLAN_RC_PHY_HT_40_TS,
 	WLAN_RC_PHY_HT_20_SS_HGI,
 	WLAN_RC_PHY_HT_20_SS_HGI,
 	WLAN_RC_PHY_HT_20_DS_HGI,
 	WLAN_RC_PHY_HT_20_DS_HGI,
+	WLAN_RC_PHY_HT_20_TS_HGI,
 	WLAN_RC_PHY_HT_40_SS_HGI,
 	WLAN_RC_PHY_HT_40_SS_HGI,
 	WLAN_RC_PHY_HT_40_DS_HGI,
 	WLAN_RC_PHY_HT_40_DS_HGI,
+	WLAN_RC_PHY_HT_40_TS_HGI,
 	WLAN_RC_PHY_MAX
 	WLAN_RC_PHY_MAX
 };
 };
 
 
@@ -57,36 +88,50 @@ enum {
 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\
 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\
 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)	\
 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)	\
 				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
 				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+#define WLAN_RC_PHY_TS(_phy)   ((_phy == WLAN_RC_PHY_HT_20_TS)		\
+				|| (_phy == WLAN_RC_PHY_HT_40_TS)	\
+				|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI)	\
+				|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
 #define WLAN_RC_PHY_20(_phy)   ((_phy == WLAN_RC_PHY_HT_20_SS)		\
 #define WLAN_RC_PHY_20(_phy)   ((_phy == WLAN_RC_PHY_HT_20_SS)		\
 				|| (_phy == WLAN_RC_PHY_HT_20_DS)	\
 				|| (_phy == WLAN_RC_PHY_HT_20_DS)	\
+				|| (_phy == WLAN_RC_PHY_HT_20_TS)	\
 				|| (_phy == WLAN_RC_PHY_HT_20_SS_HGI)	\
 				|| (_phy == WLAN_RC_PHY_HT_20_SS_HGI)	\
-				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI))
+				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)	\
+				|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI))
 #define WLAN_RC_PHY_40(_phy)   ((_phy == WLAN_RC_PHY_HT_40_SS)		\
 #define WLAN_RC_PHY_40(_phy)   ((_phy == WLAN_RC_PHY_HT_40_SS)		\
 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\
 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\
+				|| (_phy == WLAN_RC_PHY_HT_40_TS)	\
 				|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI)	\
 				|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI)	\
-				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)	\
+				|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
 #define WLAN_RC_PHY_SGI(_phy)  ((_phy == WLAN_RC_PHY_HT_20_SS_HGI)      \
 #define WLAN_RC_PHY_SGI(_phy)  ((_phy == WLAN_RC_PHY_HT_20_SS_HGI)      \
 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)   \
 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)   \
+				|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI)   \
 				|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI)   \
 				|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI)   \
-				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)   \
+				|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
 
 
 #define WLAN_RC_PHY_HT(_phy)    (_phy >= WLAN_RC_PHY_HT_20_SS)
 #define WLAN_RC_PHY_HT(_phy)    (_phy >= WLAN_RC_PHY_HT_20_SS)
 
 
 #define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ?	\
 #define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ?	\
-		(capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID))
+	((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY))
+
+#define WLAN_RC_CAP_STREAM(capflag) (((capflag & WLAN_RC_TS_FLAG) ?	\
+	(RC_TS) : ((capflag & WLAN_RC_DS_FLAG) ? RC_DS : RC_SS)))
 
 
 /* Return TRUE if flag supports HT20 && client supports HT20 or
 /* Return TRUE if flag supports HT20 && client supports HT20 or
  * return TRUE if flag supports HT40 && client supports HT40.
  * return TRUE if flag supports HT40 && client supports HT40.
  * This is used becos some rates overlap between HT20/HT40.
  * This is used becos some rates overlap between HT20/HT40.
  */
  */
 #define WLAN_RC_PHY_HT_VALID(flag, capflag)			\
 #define WLAN_RC_PHY_HT_VALID(flag, capflag)			\
-	(((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \
-	 ((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG)))
+	(((flag & RC_HT_20) && !(capflag & WLAN_RC_40_FLAG)) || \
+	 ((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG)))
 
 
 #define WLAN_RC_DS_FLAG         (0x01)
 #define WLAN_RC_DS_FLAG         (0x01)
-#define WLAN_RC_40_FLAG         (0x02)
-#define WLAN_RC_SGI_FLAG        (0x04)
-#define WLAN_RC_HT_FLAG         (0x08)
+#define WLAN_RC_TS_FLAG         (0x02)
+#define WLAN_RC_40_FLAG         (0x04)
+#define WLAN_RC_SGI_FLAG        (0x08)
+#define WLAN_RC_HT_FLAG         (0x10)
 
 
 /**
 /**
  * struct ath_rate_table - Rate Control table
  * struct ath_rate_table - Rate Control table
@@ -110,15 +155,13 @@ struct ath_rate_table {
 	int rate_cnt;
 	int rate_cnt;
 	int mcs_start;
 	int mcs_start;
 	struct {
 	struct {
-		u8 valid;
-		u8 valid_single_stream;
+		u16 rate_flags;
 		u8 phy;
 		u8 phy;
 		u32 ratekbps;
 		u32 ratekbps;
 		u32 user_ratekbps;
 		u32 user_ratekbps;
 		u8 ratecode;
 		u8 ratecode;
 		u8 dot11rate;
 		u8 dot11rate;
 		u8 ctrl_rate;
 		u8 ctrl_rate;
-		u8 base_index;
 		u8 cw40index;
 		u8 cw40index;
 		u8 sgi_index;
 		u8 sgi_index;
 		u8 ht_index;
 		u8 ht_index;

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

@@ -695,16 +695,18 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
 		  idle ? "idle" : "not-idle");
 		  idle ? "idle" : "not-idle");
 }
 }
 /* Only bother starting a queue on an active virtual wiphy */
 /* Only bother starting a queue on an active virtual wiphy */
-void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
+bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
 {
 {
 	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
 	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
 	unsigned int i;
 	unsigned int i;
+	bool txq_started = false;
 
 
 	spin_lock_bh(&sc->wiphy_lock);
 	spin_lock_bh(&sc->wiphy_lock);
 
 
 	/* Start the primary wiphy */
 	/* Start the primary wiphy */
 	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
 	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
 		ieee80211_wake_queue(hw, skb_queue);
 		ieee80211_wake_queue(hw, skb_queue);
+		txq_started = true;
 		goto unlock;
 		goto unlock;
 	}
 	}
 
 
@@ -718,11 +720,13 @@ void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
 
 
 		hw = aphy->hw;
 		hw = aphy->hw;
 		ieee80211_wake_queue(hw, skb_queue);
 		ieee80211_wake_queue(hw, skb_queue);
+		txq_started = true;
 		break;
 		break;
 	}
 	}
 
 
 unlock:
 unlock:
 	spin_unlock_bh(&sc->wiphy_lock);
 	spin_unlock_bh(&sc->wiphy_lock);
+	return txq_started;
 }
 }
 
 
 /* Go ahead and propagate information to all virtual wiphys, it won't hurt */
 /* Go ahead and propagate information to all virtual wiphys, it won't hurt */

+ 10 - 10
drivers/net/wireless/ath/ath9k/xmit.c

@@ -518,6 +518,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 		bf = bf_next;
 		bf = bf_next;
 	}
 	}
 
 
+	/* prepend un-acked frames to the beginning of the pending frame queue */
+	if (!list_empty(&bf_pending)) {
+		spin_lock_bh(&txq->axq_lock);
+		list_splice(&bf_pending, &tid->buf_q);
+		ath_tx_queue_tid(txq, tid);
+		spin_unlock_bh(&txq->axq_lock);
+	}
+
 	if (tid->state & AGGR_CLEANUP) {
 	if (tid->state & AGGR_CLEANUP) {
 		if (tid->baw_head == tid->baw_tail) {
 		if (tid->baw_head == tid->baw_tail) {
 			tid->state &= ~AGGR_ADDBA_COMPLETE;
 			tid->state &= ~AGGR_ADDBA_COMPLETE;
@@ -530,14 +538,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 		return;
 		return;
 	}
 	}
 
 
-	/* prepend un-acked frames to the beginning of the pending frame queue */
-	if (!list_empty(&bf_pending)) {
-		spin_lock_bh(&txq->axq_lock);
-		list_splice(&bf_pending, &tid->buf_q);
-		ath_tx_queue_tid(txq, tid);
-		spin_unlock_bh(&txq->axq_lock);
-	}
-
 	rcu_read_unlock();
 	rcu_read_unlock();
 
 
 	if (needreset)
 	if (needreset)
@@ -2077,8 +2077,8 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
 
 
 	spin_lock_bh(&txq->axq_lock);
 	spin_lock_bh(&txq->axq_lock);
 	if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
 	if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
-		ath_mac80211_start_queue(sc, qnum);
-		txq->stopped = 0;
+		if (ath_mac80211_start_queue(sc, qnum))
+			txq->stopped = 0;
 	}
 	}
 	spin_unlock_bh(&txq->axq_lock);
 	spin_unlock_bh(&txq->axq_lock);
 }
 }

+ 0 - 1
drivers/net/wireless/ipw2x00/libipw.h

@@ -828,7 +828,6 @@ struct libipw_device {
 	int host_strip_iv_icv;
 	int host_strip_iv_icv;
 
 
 	int host_open_frag;
 	int host_open_frag;
-	int host_build_iv;
 	int ieee802_1x;		/* is IEEE 802.1X used */
 	int ieee802_1x;		/* is IEEE 802.1X used */
 
 
 	/* WPA data */
 	/* WPA data */

+ 3 - 13
drivers/net/wireless/ipw2x00/libipw_tx.c

@@ -260,7 +260,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
 	    rts_required;
 	    rts_required;
 	unsigned long flags;
 	unsigned long flags;
-	int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
+	int encrypt, host_encrypt, host_encrypt_msdu;
 	__be16 ether_type;
 	__be16 ether_type;
 	int bytes, fc, hdr_len;
 	int bytes, fc, hdr_len;
 	struct sk_buff *skb_frag;
 	struct sk_buff *skb_frag;
@@ -301,7 +301,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
 
 
 	host_encrypt = ieee->host_encrypt && encrypt && crypt;
 	host_encrypt = ieee->host_encrypt && encrypt && crypt;
 	host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
 	host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
-	host_build_iv = ieee->host_build_iv && encrypt && crypt;
 
 
 	if (!encrypt && ieee->ieee802_1x &&
 	if (!encrypt && ieee->ieee802_1x &&
 	    ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
 	    ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
@@ -313,7 +312,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
 	skb_copy_from_linear_data(skb, dest, ETH_ALEN);
 	skb_copy_from_linear_data(skb, dest, ETH_ALEN);
 	skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN);
 	skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN);
 
 
-	if (host_encrypt || host_build_iv)
+	if (host_encrypt)
 		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
 		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
 		    IEEE80211_FCTL_PROTECTED;
 		    IEEE80211_FCTL_PROTECTED;
 	else
 	else
@@ -467,7 +466,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
 	for (; i < nr_frags; i++) {
 	for (; i < nr_frags; i++) {
 		skb_frag = txb->fragments[i];
 		skb_frag = txb->fragments[i];
 
 
-		if (host_encrypt || host_build_iv)
+		if (host_encrypt)
 			skb_reserve(skb_frag,
 			skb_reserve(skb_frag,
 				    crypt->ops->extra_mpdu_prefix_len);
 				    crypt->ops->extra_mpdu_prefix_len);
 
 
@@ -502,15 +501,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
 		 * to insert the IV between the header and the payload */
 		 * to insert the IV between the header and the payload */
 		if (host_encrypt)
 		if (host_encrypt)
 			libipw_encrypt_fragment(ieee, skb_frag, hdr_len);
 			libipw_encrypt_fragment(ieee, skb_frag, hdr_len);
-		else if (host_build_iv) {
-			atomic_inc(&crypt->refcnt);
-			if (crypt->ops->build_iv)
-				crypt->ops->build_iv(skb_frag, hdr_len,
-				      ieee->sec.keys[ieee->sec.active_key],
-				      ieee->sec.key_sizes[ieee->sec.active_key],
-				      crypt->priv);
-			atomic_dec(&crypt->refcnt);
-		}
 
 
 		if (ieee->config &
 		if (ieee->config &
 		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
 		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))

+ 1 - 1
drivers/net/wireless/ipw2x00/libipw_wx.c

@@ -320,7 +320,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
 	};
 	};
 	int i, key, key_provided, len;
 	int i, key, key_provided, len;
 	struct lib80211_crypt_data **crypt;
 	struct lib80211_crypt_data **crypt;
-	int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
+	int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
 	DECLARE_SSID_BUF(ssid);
 	DECLARE_SSID_BUF(ssid);
 
 
 	LIBIPW_DEBUG_WX("SET_ENCODE\n");
 	LIBIPW_DEBUG_WX("SET_ENCODE\n");

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

@@ -222,6 +222,7 @@ static struct iwl_lib_ops iwl1000_lib = {
 		.rx_stats_read = iwl_ucode_rx_stats_read,
 		.rx_stats_read = iwl_ucode_rx_stats_read,
 		.tx_stats_read = iwl_ucode_tx_stats_read,
 		.tx_stats_read = iwl_ucode_tx_stats_read,
 		.general_stats_read = iwl_ucode_general_stats_read,
 		.general_stats_read = iwl_ucode_general_stats_read,
+		.bt_stats_read = iwl_ucode_bt_stats_read,
 	},
 	},
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_plcp_health = iwl_good_plcp_health,

+ 3 - 2
drivers/net/wireless/iwlwifi/iwl-4965.c

@@ -1605,8 +1605,8 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
 	if (!test_bit(STATUS_TEMPERATURE, &priv->status))
 	if (!test_bit(STATUS_TEMPERATURE, &priv->status))
 		vt = sign_extend(R4, 23);
 		vt = sign_extend(R4, 23);
 	else
 	else
-		vt = sign_extend(le32_to_cpu(
-				priv->_agn.statistics.general.temperature), 23);
+		vt = sign_extend(le32_to_cpu(priv->_agn.statistics.
+				 general.common.temperature), 23);
 
 
 	IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
 	IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
 
 
@@ -2285,6 +2285,7 @@ static struct iwl_lib_ops iwl4965_lib = {
 		.rx_stats_read = iwl_ucode_rx_stats_read,
 		.rx_stats_read = iwl_ucode_rx_stats_read,
 		.tx_stats_read = iwl_ucode_tx_stats_read,
 		.tx_stats_read = iwl_ucode_tx_stats_read,
 		.general_stats_read = iwl_ucode_general_stats_read,
 		.general_stats_read = iwl_ucode_general_stats_read,
+		.bt_stats_read = iwl_ucode_bt_stats_read,
 	},
 	},
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_plcp_health = iwl_good_plcp_health,

+ 2 - 1
drivers/net/wireless/iwlwifi/iwl-5000.c

@@ -265,7 +265,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
 	u32 vt = 0;
 	u32 vt = 0;
 	s32 offset =  iwl_temp_calib_to_offset(priv);
 	s32 offset =  iwl_temp_calib_to_offset(priv);
 
 
-	vt = le32_to_cpu(priv->_agn.statistics.general.temperature);
+	vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature);
 	vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
 	vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
 	/* now vt hold the temperature in Kelvin */
 	/* now vt hold the temperature in Kelvin */
 	priv->temperature = KELVIN_TO_CELSIUS(vt);
 	priv->temperature = KELVIN_TO_CELSIUS(vt);
@@ -398,6 +398,7 @@ static struct iwl_lib_ops iwl5000_lib = {
 		.rx_stats_read = iwl_ucode_rx_stats_read,
 		.rx_stats_read = iwl_ucode_rx_stats_read,
 		.tx_stats_read = iwl_ucode_tx_stats_read,
 		.tx_stats_read = iwl_ucode_tx_stats_read,
 		.general_stats_read = iwl_ucode_general_stats_read,
 		.general_stats_read = iwl_ucode_general_stats_read,
+		.bt_stats_read = iwl_ucode_bt_stats_read,
 	},
 	},
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_plcp_health = iwl_good_plcp_health,

+ 7 - 0
drivers/net/wireless/iwlwifi/iwl-6000.c

@@ -323,6 +323,7 @@ static struct iwl_lib_ops iwl6000_lib = {
 		.rx_stats_read = iwl_ucode_rx_stats_read,
 		.rx_stats_read = iwl_ucode_rx_stats_read,
 		.tx_stats_read = iwl_ucode_tx_stats_read,
 		.tx_stats_read = iwl_ucode_tx_stats_read,
 		.general_stats_read = iwl_ucode_general_stats_read,
 		.general_stats_read = iwl_ucode_general_stats_read,
+		.bt_stats_read = iwl_ucode_bt_stats_read,
 	},
 	},
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_plcp_health = iwl_good_plcp_health,
@@ -500,6 +501,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
 	.sensitivity_calib_by_driver = true,
 	.sensitivity_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.need_dc_calib = true,
 	.need_dc_calib = true,
+	.bt_statistics = true,
 };
 };
 
 
 struct iwl_cfg iwl6000g2b_2abg_cfg = {
 struct iwl_cfg iwl6000g2b_2abg_cfg = {
@@ -535,6 +537,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
 	.sensitivity_calib_by_driver = true,
 	.sensitivity_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.need_dc_calib = true,
 	.need_dc_calib = true,
+	.bt_statistics = true,
 };
 };
 
 
 struct iwl_cfg iwl6000g2b_2bgn_cfg = {
 struct iwl_cfg iwl6000g2b_2bgn_cfg = {
@@ -572,6 +575,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
 	.sensitivity_calib_by_driver = true,
 	.sensitivity_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.need_dc_calib = true,
 	.need_dc_calib = true,
+	.bt_statistics = true,
 };
 };
 
 
 struct iwl_cfg iwl6000g2b_2bg_cfg = {
 struct iwl_cfg iwl6000g2b_2bg_cfg = {
@@ -607,6 +611,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
 	.sensitivity_calib_by_driver = true,
 	.sensitivity_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.need_dc_calib = true,
 	.need_dc_calib = true,
+	.bt_statistics = true,
 };
 };
 
 
 struct iwl_cfg iwl6000g2b_bgn_cfg = {
 struct iwl_cfg iwl6000g2b_bgn_cfg = {
@@ -644,6 +649,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
 	.sensitivity_calib_by_driver = true,
 	.sensitivity_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.need_dc_calib = true,
 	.need_dc_calib = true,
+	.bt_statistics = true,
 };
 };
 
 
 struct iwl_cfg iwl6000g2b_bg_cfg = {
 struct iwl_cfg iwl6000g2b_bg_cfg = {
@@ -679,6 +685,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
 	.sensitivity_calib_by_driver = true,
 	.sensitivity_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 	.need_dc_calib = true,
 	.need_dc_calib = true,
+	.bt_statistics = true,
 };
 };
 
 
 /*
 /*

+ 45 - 19
drivers/net/wireless/iwlwifi/iwl-agn-calib.c

@@ -605,8 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
 	IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
 	IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
 }
 }
 
 
-void iwl_sensitivity_calibration(struct iwl_priv *priv,
-				    struct iwl_notif_statistics *resp)
+void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
 {
 {
 	u32 rx_enable_time;
 	u32 rx_enable_time;
 	u32 fa_cck;
 	u32 fa_cck;
@@ -616,8 +615,8 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
 	u32 norm_fa_ofdm;
 	u32 norm_fa_ofdm;
 	u32 norm_fa_cck;
 	u32 norm_fa_cck;
 	struct iwl_sensitivity_data *data = NULL;
 	struct iwl_sensitivity_data *data = NULL;
-	struct statistics_rx_non_phy *rx_info = &(resp->rx.general);
-	struct statistics_rx *statistics = &(resp->rx);
+	struct statistics_rx_non_phy *rx_info;
+	struct statistics_rx_phy *ofdm, *cck;
 	unsigned long flags;
 	unsigned long flags;
 	struct statistics_general_data statis;
 	struct statistics_general_data statis;
 
 
@@ -632,6 +631,16 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
 	}
 	}
 
 
 	spin_lock_irqsave(&priv->lock, flags);
 	spin_lock_irqsave(&priv->lock, flags);
+	if (priv->cfg->bt_statistics) {
+		rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
+			      rx.general.common);
+		ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
+		cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck);
+	} else {
+		rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general);
+		ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm);
+		cck = &(((struct iwl_notif_statistics *)resp)->rx.cck);
+	}
 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
 		IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
 		IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
 		spin_unlock_irqrestore(&priv->lock, flags);
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -640,23 +649,23 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
 
 
 	/* Extract Statistics: */
 	/* Extract Statistics: */
 	rx_enable_time = le32_to_cpu(rx_info->channel_load);
 	rx_enable_time = le32_to_cpu(rx_info->channel_load);
-	fa_cck = le32_to_cpu(statistics->cck.false_alarm_cnt);
-	fa_ofdm = le32_to_cpu(statistics->ofdm.false_alarm_cnt);
-	bad_plcp_cck = le32_to_cpu(statistics->cck.plcp_err);
-	bad_plcp_ofdm = le32_to_cpu(statistics->ofdm.plcp_err);
+	fa_cck = le32_to_cpu(cck->false_alarm_cnt);
+	fa_ofdm = le32_to_cpu(ofdm->false_alarm_cnt);
+	bad_plcp_cck = le32_to_cpu(cck->plcp_err);
+	bad_plcp_ofdm = le32_to_cpu(ofdm->plcp_err);
 
 
 	statis.beacon_silence_rssi_a =
 	statis.beacon_silence_rssi_a =
-			le32_to_cpu(statistics->general.beacon_silence_rssi_a);
+			le32_to_cpu(rx_info->beacon_silence_rssi_a);
 	statis.beacon_silence_rssi_b =
 	statis.beacon_silence_rssi_b =
-			le32_to_cpu(statistics->general.beacon_silence_rssi_b);
+			le32_to_cpu(rx_info->beacon_silence_rssi_b);
 	statis.beacon_silence_rssi_c =
 	statis.beacon_silence_rssi_c =
-			le32_to_cpu(statistics->general.beacon_silence_rssi_c);
+			le32_to_cpu(rx_info->beacon_silence_rssi_c);
 	statis.beacon_energy_a =
 	statis.beacon_energy_a =
-			le32_to_cpu(statistics->general.beacon_energy_a);
+			le32_to_cpu(rx_info->beacon_energy_a);
 	statis.beacon_energy_b =
 	statis.beacon_energy_b =
-			le32_to_cpu(statistics->general.beacon_energy_b);
+			le32_to_cpu(rx_info->beacon_energy_b);
 	statis.beacon_energy_c =
 	statis.beacon_energy_c =
-			le32_to_cpu(statistics->general.beacon_energy_c);
+			le32_to_cpu(rx_info->beacon_energy_c);
 
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 
@@ -728,8 +737,7 @@ static inline u8 find_first_chain(u8 mask)
  * 1)  Which antennas are connected.
  * 1)  Which antennas are connected.
  * 2)  Differential rx gain settings to balance the 3 receivers.
  * 2)  Differential rx gain settings to balance the 3 receivers.
  */
  */
-void iwl_chain_noise_calibration(struct iwl_priv *priv,
-				 struct iwl_notif_statistics *stat_resp)
+void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
 {
 {
 	struct iwl_chain_noise_data *data = NULL;
 	struct iwl_chain_noise_data *data = NULL;
 
 
@@ -753,7 +761,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
 	u32 active_chains = 0;
 	u32 active_chains = 0;
 	u8 num_tx_chains;
 	u8 num_tx_chains;
 	unsigned long flags;
 	unsigned long flags;
-	struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general);
+	struct statistics_rx_non_phy *rx_info;
 	u8 first_chain;
 	u8 first_chain;
 
 
 	if (priv->disable_chain_noise_cal)
 	if (priv->disable_chain_noise_cal)
@@ -772,6 +780,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
 	}
 	}
 
 
 	spin_lock_irqsave(&priv->lock, flags);
 	spin_lock_irqsave(&priv->lock, flags);
+	if (priv->cfg->bt_statistics) {
+		rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
+			      rx.general.common);
+	} else {
+		rx_info = &(((struct iwl_notif_statistics *)stat_resp)->
+			      rx.general);
+	}
 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
 		IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
 		IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
 		spin_unlock_irqrestore(&priv->lock, flags);
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -780,8 +795,19 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
 
 
 	rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK);
 	rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK);
 	rxon_chnum = le16_to_cpu(priv->staging_rxon.channel);
 	rxon_chnum = le16_to_cpu(priv->staging_rxon.channel);
-	stat_band24 = !!(stat_resp->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK);
-	stat_chnum = le32_to_cpu(stat_resp->flag) >> 16;
+	if (priv->cfg->bt_statistics) {
+		stat_band24 = !!(((struct iwl_bt_notif_statistics *)
+				 stat_resp)->flag &
+				 STATISTICS_REPLY_FLG_BAND_24G_MSK);
+		stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *)
+					 stat_resp)->flag) >> 16;
+	} else {
+		stat_band24 = !!(((struct iwl_notif_statistics *)
+				 stat_resp)->flag &
+				 STATISTICS_REPLY_FLG_BAND_24G_MSK);
+		stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *)
+					 stat_resp)->flag) >> 16;
+	}
 
 
 	/* Make sure we accumulate data for just the associated channel
 	/* Make sure we accumulate data for just the associated channel
 	 *   (even if scanning). */
 	 *   (even if scanning). */

+ 180 - 45
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c

@@ -31,21 +31,24 @@
 static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
 static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
 {
 {
 	int p = 0;
 	int p = 0;
+	u32 flag;
 
 
-	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
-		       le32_to_cpu(priv->_agn.statistics.flag));
-	if (le32_to_cpu(priv->_agn.statistics.flag) &
-			UCODE_STATISTICS_CLEAR_MSK)
+	if (priv->cfg->bt_statistics)
+		flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
+	else
+		flag = le32_to_cpu(priv->_agn.statistics.flag);
+
+	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
+	if (flag & UCODE_STATISTICS_CLEAR_MSK)
 		p += scnprintf(buf + p, bufsz - p,
 		p += scnprintf(buf + p, bufsz - p,
-			       "\tStatistics have been cleared\n");
+		"\tStatistics have been cleared\n");
 	p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
 	p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
-		       (le32_to_cpu(priv->_agn.statistics.flag) &
-			UCODE_STATISTICS_FREQUENCY_MSK)
-			? "2.4 GHz" : "5.2 GHz");
+		(flag & UCODE_STATISTICS_FREQUENCY_MSK)
+		? "2.4 GHz" : "5.2 GHz");
 	p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
 	p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
-		       (le32_to_cpu(priv->_agn.statistics.flag) &
-			UCODE_STATISTICS_NARROW_BAND_MSK)
-			? "enabled" : "disabled");
+		(flag & UCODE_STATISTICS_NARROW_BAND_MSK)
+		 ? "enabled" : "disabled");
+
 	return p;
 	return p;
 }
 }
 
 
@@ -79,22 +82,43 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
 	 * the last statistics notification from uCode
 	 * the last statistics notification from uCode
 	 * might not reflect the current uCode activity
 	 * might not reflect the current uCode activity
 	 */
 	 */
-	ofdm = &priv->_agn.statistics.rx.ofdm;
-	cck = &priv->_agn.statistics.rx.cck;
-	general = &priv->_agn.statistics.rx.general;
-	ht = &priv->_agn.statistics.rx.ofdm_ht;
-	accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
-	accum_cck = &priv->_agn.accum_statistics.rx.cck;
-	accum_general = &priv->_agn.accum_statistics.rx.general;
-	accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
-	delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
-	delta_cck = &priv->_agn.delta_statistics.rx.cck;
-	delta_general = &priv->_agn.delta_statistics.rx.general;
-	delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
-	max_ofdm = &priv->_agn.max_delta.rx.ofdm;
-	max_cck = &priv->_agn.max_delta.rx.cck;
-	max_general = &priv->_agn.max_delta.rx.general;
-	max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
+	if (priv->cfg->bt_statistics) {
+		ofdm = &priv->_agn.statistics_bt.rx.ofdm;
+		cck = &priv->_agn.statistics_bt.rx.cck;
+		general = &priv->_agn.statistics_bt.rx.general.common;
+		ht = &priv->_agn.statistics_bt.rx.ofdm_ht;
+		accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm;
+		accum_cck = &priv->_agn.accum_statistics_bt.rx.cck;
+		accum_general =
+			&priv->_agn.accum_statistics_bt.rx.general.common;
+		accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht;
+		delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm;
+		delta_cck = &priv->_agn.delta_statistics_bt.rx.cck;
+		delta_general =
+			&priv->_agn.delta_statistics_bt.rx.general.common;
+		delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht;
+		max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm;
+		max_cck = &priv->_agn.max_delta_bt.rx.cck;
+		max_general = &priv->_agn.max_delta_bt.rx.general.common;
+		max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht;
+	} else {
+		ofdm = &priv->_agn.statistics.rx.ofdm;
+		cck = &priv->_agn.statistics.rx.cck;
+		general = &priv->_agn.statistics.rx.general;
+		ht = &priv->_agn.statistics.rx.ofdm_ht;
+		accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
+		accum_cck = &priv->_agn.accum_statistics.rx.cck;
+		accum_general = &priv->_agn.accum_statistics.rx.general;
+		accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
+		delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
+		delta_cck = &priv->_agn.delta_statistics.rx.cck;
+		delta_general = &priv->_agn.delta_statistics.rx.general;
+		delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
+		max_ofdm = &priv->_agn.max_delta.rx.ofdm;
+		max_cck = &priv->_agn.max_delta.rx.cck;
+		max_general = &priv->_agn.max_delta.rx.general;
+		max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
+	}
 
 
 	pos += iwl_statistics_flag(priv, buf, bufsz);
 	pos += iwl_statistics_flag(priv, buf, bufsz);
 	pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
 	pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
@@ -560,10 +584,18 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
 	  * the last statistics notification from uCode
 	  * the last statistics notification from uCode
 	  * might not reflect the current uCode activity
 	  * might not reflect the current uCode activity
 	  */
 	  */
-	tx = &priv->_agn.statistics.tx;
-	accum_tx = &priv->_agn.accum_statistics.tx;
-	delta_tx = &priv->_agn.delta_statistics.tx;
-	max_tx = &priv->_agn.max_delta.tx;
+	if (priv->cfg->bt_statistics) {
+		tx = &priv->_agn.statistics_bt.tx;
+		accum_tx = &priv->_agn.accum_statistics_bt.tx;
+		delta_tx = &priv->_agn.delta_statistics_bt.tx;
+		max_tx = &priv->_agn.max_delta_bt.tx;
+	} else {
+		tx = &priv->_agn.statistics.tx;
+		accum_tx = &priv->_agn.accum_statistics.tx;
+		delta_tx = &priv->_agn.delta_statistics.tx;
+		max_tx = &priv->_agn.max_delta.tx;
+	}
+
 	pos += iwl_statistics_flag(priv, buf, bufsz);
 	pos += iwl_statistics_flag(priv, buf, bufsz);
 	pos += scnprintf(buf + pos, bufsz - pos,  "%-32s     current"
 	pos += scnprintf(buf + pos, bufsz - pos,  "%-32s     current"
 			 "acumulative       delta         max\n",
 			 "acumulative       delta         max\n",
@@ -759,8 +791,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
 	char *buf;
 	char *buf;
 	int bufsz = sizeof(struct statistics_general) * 10 + 300;
 	int bufsz = sizeof(struct statistics_general) * 10 + 300;
 	ssize_t ret;
 	ssize_t ret;
-	struct statistics_general *general, *accum_general;
-	struct statistics_general *delta_general, *max_general;
+	struct statistics_general_common *general, *accum_general;
+	struct statistics_general_common *delta_general, *max_general;
 	struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
 	struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
 	struct statistics_div *div, *accum_div, *delta_div, *max_div;
 	struct statistics_div *div, *accum_div, *delta_div, *max_div;
 
 
@@ -777,18 +809,34 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
 	  * the last statistics notification from uCode
 	  * the last statistics notification from uCode
 	  * might not reflect the current uCode activity
 	  * might not reflect the current uCode activity
 	  */
 	  */
-	general = &priv->_agn.statistics.general;
-	dbg = &priv->_agn.statistics.general.dbg;
-	div = &priv->_agn.statistics.general.div;
-	accum_general = &priv->_agn.accum_statistics.general;
-	delta_general = &priv->_agn.delta_statistics.general;
-	max_general = &priv->_agn.max_delta.general;
-	accum_dbg = &priv->_agn.accum_statistics.general.dbg;
-	delta_dbg = &priv->_agn.delta_statistics.general.dbg;
-	max_dbg = &priv->_agn.max_delta.general.dbg;
-	accum_div = &priv->_agn.accum_statistics.general.div;
-	delta_div = &priv->_agn.delta_statistics.general.div;
-	max_div = &priv->_agn.max_delta.general.div;
+	if (priv->cfg->bt_statistics) {
+		general = &priv->_agn.statistics_bt.general.common;
+		dbg = &priv->_agn.statistics_bt.general.common.dbg;
+		div = &priv->_agn.statistics_bt.general.common.div;
+		accum_general = &priv->_agn.accum_statistics_bt.general.common;
+		accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg;
+		accum_div = &priv->_agn.accum_statistics_bt.general.common.div;
+		delta_general = &priv->_agn.delta_statistics_bt.general.common;
+		max_general = &priv->_agn.max_delta_bt.general.common;
+		delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg;
+		max_dbg = &priv->_agn.max_delta_bt.general.common.dbg;
+		delta_div = &priv->_agn.delta_statistics_bt.general.common.div;
+		max_div = &priv->_agn.max_delta_bt.general.common.div;
+	} else {
+		general = &priv->_agn.statistics.general.common;
+		dbg = &priv->_agn.statistics.general.common.dbg;
+		div = &priv->_agn.statistics.general.common.div;
+		accum_general = &priv->_agn.accum_statistics.general.common;
+		accum_dbg = &priv->_agn.accum_statistics.general.common.dbg;
+		accum_div = &priv->_agn.accum_statistics.general.common.div;
+		delta_general = &priv->_agn.delta_statistics.general.common;
+		max_general = &priv->_agn.max_delta.general.common;
+		delta_dbg = &priv->_agn.delta_statistics.general.common.dbg;
+		max_dbg = &priv->_agn.max_delta.general.common.dbg;
+		delta_div = &priv->_agn.delta_statistics.general.common.div;
+		max_div = &priv->_agn.max_delta.general.common.div;
+	}
+
 	pos += iwl_statistics_flag(priv, buf, bufsz);
 	pos += iwl_statistics_flag(priv, buf, bufsz);
 	pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
 	pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
 			 "acumulative       delta         max\n",
 			 "acumulative       delta         max\n",
@@ -876,3 +924,90 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
 	kfree(buf);
 	kfree(buf);
 	return ret;
 	return ret;
 }
 }
+
+ssize_t iwl_ucode_bt_stats_read(struct file *file,
+				char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	char *buf;
+	int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
+	ssize_t ret;
+	struct statistics_bt_activity *bt, *accum_bt;
+
+	if (!iwl_is_alive(priv))
+		return -EAGAIN;
+
+	/* make request to uCode to retrieve statistics information */
+	mutex_lock(&priv->mutex);
+	ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
+	mutex_unlock(&priv->mutex);
+
+	if (ret) {
+		IWL_ERR(priv,
+			"Error sending statistics request: %zd\n", ret);
+		return -EAGAIN;
+	}
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * the statistic information display here is based on
+	 * the last statistics notification from uCode
+	 * might not reflect the current uCode activity
+	 */
+	bt = &priv->_agn.statistics_bt.general.activity;
+	accum_bt = &priv->_agn.accum_statistics_bt.general.activity;
+
+	pos += iwl_statistics_flag(priv, buf, bufsz);
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"\t\t\tcurrent\t\t\taccumulative\n");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->hi_priority_tx_req_cnt),
+			 accum_bt->hi_priority_tx_req_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->hi_priority_tx_denied_cnt),
+			 accum_bt->hi_priority_tx_denied_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->lo_priority_tx_req_cnt),
+			 accum_bt->lo_priority_tx_req_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->lo_priority_tx_denied_cnt),
+			 accum_bt->lo_priority_tx_denied_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->hi_priority_rx_req_cnt),
+			 accum_bt->hi_priority_rx_req_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->hi_priority_rx_denied_cnt),
+			 accum_bt->hi_priority_rx_denied_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->lo_priority_rx_req_cnt),
+			 accum_bt->lo_priority_rx_req_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->lo_priority_rx_denied_cnt),
+			 accum_bt->lo_priority_rx_denied_cnt);
+
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(priv->_agn.statistics_bt.rx.
+				general.num_bt_kills),
+			 priv->_agn.accum_statistics_bt.rx.
+				general.num_bt_kills);
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}

+ 7 - 0
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h

@@ -37,6 +37,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
 				size_t count, loff_t *ppos);
 				size_t count, loff_t *ppos);
 ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
 ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
 				     size_t count, loff_t *ppos);
 				     size_t count, loff_t *ppos);
+ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
+				size_t count, loff_t *ppos);
 #else
 #else
 static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
 static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
 				       size_t count, loff_t *ppos)
 				       size_t count, loff_t *ppos)
@@ -53,4 +55,9 @@ static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user
 {
 {
 	return 0;
 	return 0;
 }
 }
+static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
+				       size_t count, loff_t *ppos)
+{
+	return 0;
+}
 #endif
 #endif

+ 2 - 2
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c

@@ -164,7 +164,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
 
 
 		memset(&cmd, 0, sizeof(cmd));
 		memset(&cmd, 0, sizeof(cmd));
 
 
-		cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
+		cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_gain_cmd;
 		cmd.hdr.first_group = 0;
 		cmd.hdr.first_group = 0;
 		cmd.hdr.groups_num = 1;
 		cmd.hdr.groups_num = 1;
 		cmd.hdr.data_valid = 1;
 		cmd.hdr.data_valid = 1;
@@ -197,7 +197,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
 		data->beacon_count = 0;
 		data->beacon_count = 0;
 
 
 		memset(&cmd, 0, sizeof(cmd));
 		memset(&cmd, 0, sizeof(cmd));
-		cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
+		cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_reset_cmd;
 		cmd.hdr.first_group = 0;
 		cmd.hdr.first_group = 0;
 		cmd.hdr.groups_num = 1;
 		cmd.hdr.groups_num = 1;
 		cmd.hdr.data_valid = 1;
 		cmd.hdr.data_valid = 1;

+ 5 - 2
drivers/net/wireless/iwlwifi/iwl-agn-lib.c

@@ -364,7 +364,7 @@ void iwlagn_temperature(struct iwl_priv *priv)
 {
 {
 	/* store temperature from statistics (in Celsius) */
 	/* store temperature from statistics (in Celsius) */
 	priv->temperature =
 	priv->temperature =
-		le32_to_cpu(priv->_agn.statistics.general.temperature);
+		le32_to_cpu(priv->_agn.statistics.general.common.temperature);
 	iwl_tt_handler(priv);
 	iwl_tt_handler(priv);
 }
 }
 
 
@@ -1234,7 +1234,10 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 
 
 		IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
 		IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
 		spin_lock_irqsave(&priv->lock, flags);
 		spin_lock_irqsave(&priv->lock, flags);
-		interval = vif ? vif->bss_conf.beacon_int : 0;
+		if (priv->is_internal_short_scan)
+			interval = 0;
+		else
+			interval = vif->bss_conf.beacon_int;
 		spin_unlock_irqrestore(&priv->lock, flags);
 		spin_unlock_irqrestore(&priv->lock, flags);
 
 
 		scan->suspend_time = 0;
 		scan->suspend_time = 0;

+ 117 - 50
drivers/net/wireless/iwlwifi/iwl-agn-rx.c

@@ -67,17 +67,22 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
  *   exactly when to expect beacons, therefore only when we're associated. */
  *   exactly when to expect beacons, therefore only when we're associated. */
 static void iwl_rx_calc_noise(struct iwl_priv *priv)
 static void iwl_rx_calc_noise(struct iwl_priv *priv)
 {
 {
-	struct statistics_rx_non_phy *rx_info
-				= &(priv->_agn.statistics.rx.general);
+	struct statistics_rx_non_phy *rx_info;
 	int num_active_rx = 0;
 	int num_active_rx = 0;
 	int total_silence = 0;
 	int total_silence = 0;
-	int bcn_silence_a =
+	int bcn_silence_a, bcn_silence_b, bcn_silence_c;
+	int last_rx_noise;
+
+	if (priv->cfg->bt_statistics)
+		rx_info = &(priv->_agn.statistics_bt.rx.general.common);
+	else
+		rx_info = &(priv->_agn.statistics.rx.general);
+	bcn_silence_a =
 		le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
 		le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
-	int bcn_silence_b =
+	bcn_silence_b =
 		le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
 		le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
-	int bcn_silence_c =
+	bcn_silence_c =
 		le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
 		le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
-	int last_rx_noise;
 
 
 	if (bcn_silence_a) {
 	if (bcn_silence_a) {
 		total_silence += bcn_silence_a;
 		total_silence += bcn_silence_a;
@@ -112,17 +117,35 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
 static void iwl_accumulative_statistics(struct iwl_priv *priv,
 static void iwl_accumulative_statistics(struct iwl_priv *priv,
 					__le32 *stats)
 					__le32 *stats)
 {
 {
-	int i;
+	int i, size;
 	__le32 *prev_stats;
 	__le32 *prev_stats;
 	u32 *accum_stats;
 	u32 *accum_stats;
 	u32 *delta, *max_delta;
 	u32 *delta, *max_delta;
+	struct statistics_general_common *general, *accum_general;
+	struct statistics_tx *tx, *accum_tx;
 
 
-	prev_stats = (__le32 *)&priv->_agn.statistics;
-	accum_stats = (u32 *)&priv->_agn.accum_statistics;
-	delta = (u32 *)&priv->_agn.delta_statistics;
-	max_delta = (u32 *)&priv->_agn.max_delta;
-
-	for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
+	if (priv->cfg->bt_statistics) {
+		prev_stats = (__le32 *)&priv->_agn.statistics_bt;
+		accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
+		size = sizeof(struct iwl_bt_notif_statistics);
+		general = &priv->_agn.statistics_bt.general.common;
+		accum_general = &priv->_agn.accum_statistics_bt.general.common;
+		tx = &priv->_agn.statistics_bt.tx;
+		accum_tx = &priv->_agn.accum_statistics_bt.tx;
+		delta = (u32 *)&priv->_agn.delta_statistics_bt;
+		max_delta = (u32 *)&priv->_agn.max_delta_bt;
+	} else {
+		prev_stats = (__le32 *)&priv->_agn.statistics;
+		accum_stats = (u32 *)&priv->_agn.accum_statistics;
+		size = sizeof(struct iwl_notif_statistics);
+		general = &priv->_agn.statistics.general.common;
+		accum_general = &priv->_agn.accum_statistics.general.common;
+		tx = &priv->_agn.statistics.tx;
+		accum_tx = &priv->_agn.accum_statistics.tx;
+		delta = (u32 *)&priv->_agn.delta_statistics;
+		max_delta = (u32 *)&priv->_agn.max_delta;
+	}
+	for (i = sizeof(__le32); i < size;
 	     i += sizeof(__le32), stats++, prev_stats++, delta++,
 	     i += sizeof(__le32), stats++, prev_stats++, delta++,
 	     max_delta++, accum_stats++) {
 	     max_delta++, accum_stats++) {
 		if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
 		if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
@@ -135,18 +158,12 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
 	}
 	}
 
 
 	/* reset accumulative statistics for "no-counter" type statistics */
 	/* reset accumulative statistics for "no-counter" type statistics */
-	priv->_agn.accum_statistics.general.temperature =
-		priv->_agn.statistics.general.temperature;
-	priv->_agn.accum_statistics.general.temperature_m =
-		priv->_agn.statistics.general.temperature_m;
-	priv->_agn.accum_statistics.general.ttl_timestamp =
-		priv->_agn.statistics.general.ttl_timestamp;
-	priv->_agn.accum_statistics.tx.tx_power.ant_a =
-		priv->_agn.statistics.tx.tx_power.ant_a;
-	priv->_agn.accum_statistics.tx.tx_power.ant_b =
-		priv->_agn.statistics.tx.tx_power.ant_b;
-	priv->_agn.accum_statistics.tx.tx_power.ant_c =
-		priv->_agn.statistics.tx.tx_power.ant_c;
+	accum_general->temperature = general->temperature;
+	accum_general->temperature_m = general->temperature_m;
+	accum_general->ttl_timestamp = general->ttl_timestamp;
+	accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
+	accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
+	accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
 }
 }
 #endif
 #endif
 
 
@@ -185,11 +202,30 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
 	 * by zero.
 	 * by zero.
 	 */
 	 */
 	if (plcp_msec) {
 	if (plcp_msec) {
-		combined_plcp_delta =
-			(le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
-			le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) +
-			(le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
-			le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err));
+		struct statistics_rx_phy *ofdm;
+		struct statistics_rx_ht_phy *ofdm_ht;
+
+		if (priv->cfg->bt_statistics) {
+			ofdm = &pkt->u.stats_bt.rx.ofdm;
+			ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
+			combined_plcp_delta =
+			   (le32_to_cpu(ofdm->plcp_err) -
+			   le32_to_cpu(priv->_agn.statistics_bt.
+				       rx.ofdm.plcp_err)) +
+			   (le32_to_cpu(ofdm_ht->plcp_err) -
+			   le32_to_cpu(priv->_agn.statistics_bt.
+				       rx.ofdm_ht.plcp_err));
+		} else {
+			ofdm = &pkt->u.stats.rx.ofdm;
+			ofdm_ht = &pkt->u.stats.rx.ofdm_ht;
+			combined_plcp_delta =
+			    (le32_to_cpu(ofdm->plcp_err) -
+			    le32_to_cpu(priv->_agn.statistics.
+					rx.ofdm.plcp_err)) +
+			    (le32_to_cpu(ofdm_ht->plcp_err) -
+			    le32_to_cpu(priv->_agn.statistics.
+					rx.ofdm_ht.plcp_err));
+		}
 
 
 		if ((combined_plcp_delta > 0) &&
 		if ((combined_plcp_delta > 0) &&
 		    ((combined_plcp_delta * 100) / plcp_msec) >
 		    ((combined_plcp_delta * 100) / plcp_msec) >
@@ -206,15 +242,14 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
 			 *    plcp_msec
 			 *    plcp_msec
 			 */
 			 */
 			IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
 			IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
-				"%u, %u, %u, %u, %d, %u mSecs\n",
-				priv->cfg->plcp_delta_threshold,
-				le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
-				le32_to_cpu(
-				       priv->_agn.statistics.rx.ofdm.plcp_err),
-				le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
-				le32_to_cpu(
-				  priv->_agn.statistics.rx.ofdm_ht.plcp_err),
-				combined_plcp_delta, plcp_msec);
+				    "%u, %u, %u, %u, %d, %u mSecs\n",
+				    priv->cfg->plcp_delta_threshold,
+				    le32_to_cpu(ofdm->plcp_err),
+				    le32_to_cpu(ofdm->plcp_err),
+				    le32_to_cpu(ofdm_ht->plcp_err),
+				    le32_to_cpu(ofdm_ht->plcp_err),
+				    combined_plcp_delta, plcp_msec);
+
 			rc = false;
 			rc = false;
 		}
 		}
 	}
 	}
@@ -227,24 +262,50 @@ void iwl_rx_statistics(struct iwl_priv *priv,
 	int change;
 	int change;
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
 
+	if (priv->cfg->bt_statistics) {
+		IWL_DEBUG_RX(priv,
+			     "Statistics notification received (%d vs %d).\n",
+			     (int)sizeof(struct iwl_bt_notif_statistics),
+			     le32_to_cpu(pkt->len_n_flags) &
+			     FH_RSCSR_FRAME_SIZE_MSK);
 
 
-	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
-		     (int)sizeof(priv->_agn.statistics),
-		     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
+		change = ((priv->_agn.statistics_bt.general.common.temperature !=
+			   pkt->u.stats_bt.general.common.temperature) ||
+			   ((priv->_agn.statistics_bt.flag &
+			   STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+			   (pkt->u.stats_bt.flag &
+			   STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+		iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
+#endif
 
 
-	change = ((priv->_agn.statistics.general.temperature !=
-		   pkt->u.stats.general.temperature) ||
-		  ((priv->_agn.statistics.flag &
-		    STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
-		   (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
+	} else {
+		IWL_DEBUG_RX(priv,
+			     "Statistics notification received (%d vs %d).\n",
+			     (int)sizeof(struct iwl_notif_statistics),
+			     le32_to_cpu(pkt->len_n_flags) &
+			     FH_RSCSR_FRAME_SIZE_MSK);
 
 
+		change = ((priv->_agn.statistics.general.common.temperature !=
+			   pkt->u.stats.general.common.temperature) ||
+			   ((priv->_agn.statistics.flag &
+			   STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+			   (pkt->u.stats.flag &
+			   STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-	iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
+		iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
 #endif
 #endif
+
+	}
+
 	iwl_recover_from_statistics(priv, pkt);
 	iwl_recover_from_statistics(priv, pkt);
 
 
-	memcpy(&priv->_agn.statistics, &pkt->u.stats,
-	       sizeof(priv->_agn.statistics));
+	if (priv->cfg->bt_statistics)
+		memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
+			sizeof(priv->_agn.statistics_bt));
+	else
+		memcpy(&priv->_agn.statistics, &pkt->u.stats,
+			sizeof(priv->_agn.statistics));
 
 
 	set_bit(STATUS_STATISTICS, &priv->status);
 	set_bit(STATUS_STATISTICS, &priv->status);
 
 
@@ -277,6 +338,12 @@ void iwl_reply_statistics(struct iwl_priv *priv,
 			sizeof(struct iwl_notif_statistics));
 			sizeof(struct iwl_notif_statistics));
 		memset(&priv->_agn.max_delta, 0,
 		memset(&priv->_agn.max_delta, 0,
 			sizeof(struct iwl_notif_statistics));
 			sizeof(struct iwl_notif_statistics));
+		memset(&priv->_agn.accum_statistics_bt, 0,
+			sizeof(struct iwl_bt_notif_statistics));
+		memset(&priv->_agn.delta_statistics_bt, 0,
+			sizeof(struct iwl_bt_notif_statistics));
+		memset(&priv->_agn.max_delta_bt, 0,
+			sizeof(struct iwl_bt_notif_statistics));
 #endif
 #endif
 		IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
 		IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
 	}
 	}

+ 85 - 56
drivers/net/wireless/iwlwifi/iwl-agn.c

@@ -27,6 +27,8 @@
  *
  *
  *****************************************************************************/
  *****************************************************************************/
 
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/init.h>
@@ -292,9 +294,7 @@ static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
 					  struct ieee80211_hdr *hdr,
 					  struct ieee80211_hdr *hdr,
 					  int left)
 					  int left)
 {
 {
-	if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
-	    ((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
-	     (priv->iw_mode != NL80211_IFTYPE_AP)))
+	if (!priv->ibss_beacon)
 		return 0;
 		return 0;
 
 
 	if (priv->ibss_beacon->len > left)
 	if (priv->ibss_beacon->len > left)
@@ -1692,6 +1692,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
 
 
 struct iwlagn_ucode_capabilities {
 struct iwlagn_ucode_capabilities {
 	u32 max_probe_length;
 	u32 max_probe_length;
+	u32 standard_phy_calibration_size;
 };
 };
 
 
 static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
 static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
@@ -1827,7 +1828,6 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 	u32 tlv_len;
 	u32 tlv_len;
 	enum iwl_ucode_tlv_type tlv_type;
 	enum iwl_ucode_tlv_type tlv_type;
 	const u8 *tlv_data;
 	const u8 *tlv_data;
-	int ret = 0;
 
 
 	if (len < sizeof(*ucode)) {
 	if (len < sizeof(*ucode)) {
 		IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
 		IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
@@ -1863,9 +1863,8 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 
 
 	len -= sizeof(*ucode);
 	len -= sizeof(*ucode);
 
 
-	while (len >= sizeof(*tlv) && !ret) {
+	while (len >= sizeof(*tlv)) {
 		u16 tlv_alt;
 		u16 tlv_alt;
-		u32 fixed_tlv_size = 4;
 
 
 		len -= sizeof(*tlv);
 		len -= sizeof(*tlv);
 		tlv = (void *)data;
 		tlv = (void *)data;
@@ -1913,59 +1912,57 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 			pieces->boot_size = tlv_len;
 			pieces->boot_size = tlv_len;
 			break;
 			break;
 		case IWL_UCODE_TLV_PROBE_MAX_LEN:
 		case IWL_UCODE_TLV_PROBE_MAX_LEN:
-			if (tlv_len != fixed_tlv_size)
-				ret = -EINVAL;
-			else
-				capa->max_probe_length =
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			capa->max_probe_length =
 					le32_to_cpup((__le32 *)tlv_data);
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
 			break;
 		case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
 		case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
-			if (tlv_len != fixed_tlv_size)
-				ret = -EINVAL;
-			else
-				pieces->init_evtlog_ptr =
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->init_evtlog_ptr =
 					le32_to_cpup((__le32 *)tlv_data);
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
 			break;
 		case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
 		case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
-			if (tlv_len != fixed_tlv_size)
-				ret = -EINVAL;
-			else
-				pieces->init_evtlog_size =
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->init_evtlog_size =
 					le32_to_cpup((__le32 *)tlv_data);
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
 			break;
 		case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
 		case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
-			if (tlv_len != fixed_tlv_size)
-				ret = -EINVAL;
-			else
-				pieces->init_errlog_ptr =
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->init_errlog_ptr =
 					le32_to_cpup((__le32 *)tlv_data);
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
 			break;
 		case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
 		case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
-			if (tlv_len != fixed_tlv_size)
-				ret = -EINVAL;
-			else
-				pieces->inst_evtlog_ptr =
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->inst_evtlog_ptr =
 					le32_to_cpup((__le32 *)tlv_data);
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
 			break;
 		case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
 		case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
-			if (tlv_len != fixed_tlv_size)
-				ret = -EINVAL;
-			else
-				pieces->inst_evtlog_size =
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->inst_evtlog_size =
 					le32_to_cpup((__le32 *)tlv_data);
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
 			break;
 		case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
 		case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
-			if (tlv_len != fixed_tlv_size)
-				ret = -EINVAL;
-			else
-				pieces->inst_errlog_ptr =
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->inst_errlog_ptr =
 					le32_to_cpup((__le32 *)tlv_data);
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
 			break;
 		case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
 		case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
 			if (tlv_len)
 			if (tlv_len)
-				ret = -EINVAL;
-			else
-				priv->enhance_sensitivity_table = true;
+				goto invalid_tlv_len;
+			priv->enhance_sensitivity_table = true;
+			break;
+		case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			capa->standard_phy_calibration_size =
+					le32_to_cpup((__le32 *)tlv_data);
 			break;
 			break;
 		default:
 		default:
 			IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
 			IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
@@ -1976,14 +1973,16 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 	if (len) {
 	if (len) {
 		IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
 		IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
 		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
 		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
-		ret = -EINVAL;
-	} else if (ret) {
-		IWL_ERR(priv, "TLV %d has invalid size: %u\n",
-			tlv_type, tlv_len);
-		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len);
+		return -EINVAL;
 	}
 	}
 
 
-	return ret;
+	return 0;
+
+ invalid_tlv_len:
+	IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
+	iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len);
+
+	return -EINVAL;
 }
 }
 
 
 /**
 /**
@@ -2005,6 +2004,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 	u32 build;
 	u32 build;
 	struct iwlagn_ucode_capabilities ucode_capa = {
 	struct iwlagn_ucode_capabilities ucode_capa = {
 		.max_probe_length = 200,
 		.max_probe_length = 200,
+		.standard_phy_calibration_size =
+			IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE,
 	};
 	};
 
 
 	memset(&pieces, 0, sizeof(pieces));
 	memset(&pieces, 0, sizeof(pieces));
@@ -2226,6 +2227,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 			pieces.boot_size);
 			pieces.boot_size);
 	memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
 	memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
 
 
+	/*
+	 * figure out the offset of chain noise reset and gain commands
+	 * base on the size of standard phy calibration commands table size
+	 */
+	if (ucode_capa.standard_phy_calibration_size >
+	    IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
+		ucode_capa.standard_phy_calibration_size =
+			IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
+
+	priv->_agn.phy_calib_chain_noise_reset_cmd =
+		ucode_capa.standard_phy_calibration_size;
+	priv->_agn.phy_calib_chain_noise_gain_cmd =
+		ucode_capa.standard_phy_calibration_size + 1;
+
 	/**************************************************
 	/**************************************************
 	 * This is still part of probe() in a sense...
 	 * This is still part of probe() in a sense...
 	 *
 	 *
@@ -3008,9 +3023,17 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
 	}
 	}
 
 
 	if (priv->start_calib) {
 	if (priv->start_calib) {
-		iwl_chain_noise_calibration(priv, &priv->_agn.statistics);
-
-		iwl_sensitivity_calibration(priv, &priv->_agn.statistics);
+		if (priv->cfg->bt_statistics) {
+			iwl_chain_noise_calibration(priv,
+					(void *)&priv->_agn.statistics_bt);
+			iwl_sensitivity_calibration(priv,
+					(void *)&priv->_agn.statistics_bt);
+		} else {
+			iwl_chain_noise_calibration(priv,
+					(void *)&priv->_agn.statistics);
+			iwl_sensitivity_calibration(priv,
+					(void *)&priv->_agn.statistics);
+		}
 	}
 	}
 
 
 	mutex_unlock(&priv->mutex);
 	mutex_unlock(&priv->mutex);
@@ -3909,8 +3932,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct ieee80211_hw *hw;
 	struct ieee80211_hw *hw;
 	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
 	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
 	unsigned long flags;
 	unsigned long flags;
-	u16 pci_cmd;
-	u8 perm_addr[ETH_ALEN];
+	u16 pci_cmd, num_mac;
 
 
 	/************************
 	/************************
 	 * 1. Allocating HW data
 	 * 1. Allocating HW data
@@ -4028,9 +4050,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto out_free_eeprom;
 		goto out_free_eeprom;
 
 
 	/* extract MAC Address */
 	/* extract MAC Address */
-	iwl_eeprom_get_mac(priv, perm_addr);
-	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", perm_addr);
-	SET_IEEE80211_PERM_ADDR(priv->hw, perm_addr);
+	iwl_eeprom_get_mac(priv, priv->addresses[0].addr);
+	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
+	priv->hw->wiphy->addresses = priv->addresses;
+	priv->hw->wiphy->n_addresses = 1;
+	num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS);
+	if (num_mac > 1) {
+		memcpy(priv->addresses[1].addr, priv->addresses[0].addr,
+		       ETH_ALEN);
+		priv->addresses[1].addr[5]++;
+		priv->hw->wiphy->n_addresses++;
+	}
 
 
 	/************************
 	/************************
 	 * 5. Setup HW constants
 	 * 5. Setup HW constants
@@ -4389,19 +4419,18 @@ static int __init iwl_init(void)
 {
 {
 
 
 	int ret;
 	int ret;
-	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
-	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
+	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
+	pr_info(DRV_COPYRIGHT "\n");
 
 
 	ret = iwlagn_rate_control_register();
 	ret = iwlagn_rate_control_register();
 	if (ret) {
 	if (ret) {
-		printk(KERN_ERR DRV_NAME
-		       "Unable to register rate control algorithm: %d\n", ret);
+		pr_err("Unable to register rate control algorithm: %d\n", ret);
 		return ret;
 		return ret;
 	}
 	}
 
 
 	ret = pci_register_driver(&iwl_driver);
 	ret = pci_register_driver(&iwl_driver);
 	if (ret) {
 	if (ret) {
-		printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
+		pr_err("Unable to initialize PCI module\n");
 		goto error_register;
 		goto error_register;
 	}
 	}
 
 

+ 2 - 4
drivers/net/wireless/iwlwifi/iwl-calib.h

@@ -66,10 +66,8 @@
 #include "iwl-core.h"
 #include "iwl-core.h"
 #include "iwl-commands.h"
 #include "iwl-commands.h"
 
 
-void iwl_chain_noise_calibration(struct iwl_priv *priv,
-				struct iwl_notif_statistics *stat_resp);
-void iwl_sensitivity_calibration(struct iwl_priv *priv,
-				struct iwl_notif_statistics *resp);
+void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
+void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
 
 
 void iwl_init_sensitivity(struct iwl_priv *priv);
 void iwl_init_sensitivity(struct iwl_priv *priv);
 void iwl_reset_run_time_calib(struct iwl_priv *priv);
 void iwl_reset_run_time_calib(struct iwl_priv *priv);

+ 50 - 5
drivers/net/wireless/iwlwifi/iwl-commands.h

@@ -964,8 +964,8 @@ struct iwl_qosparam_cmd {
 #define	IWL_STATION_COUNT	32 	/* MAX(3945,4965)*/
 #define	IWL_STATION_COUNT	32 	/* MAX(3945,4965)*/
 #define	IWL_INVALID_STATION 	255
 #define	IWL_INVALID_STATION 	255
 
 
-#define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2);
-#define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8);
+#define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2)
+#define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8)
 #define STA_FLG_RTS_MIMO_PROT_MSK	cpu_to_le32(1 << 17)
 #define STA_FLG_RTS_MIMO_PROT_MSK	cpu_to_le32(1 << 17)
 #define STA_FLG_AGG_MPDU_8US_MSK	cpu_to_le32(1 << 18)
 #define STA_FLG_AGG_MPDU_8US_MSK	cpu_to_le32(1 << 18)
 #define STA_FLG_MAX_AGG_SIZE_POS	(19)
 #define STA_FLG_MAX_AGG_SIZE_POS	(19)
@@ -3127,6 +3127,13 @@ struct statistics_rx_non_phy {
 	__le32 beacon_energy_c;
 	__le32 beacon_energy_c;
 } __packed;
 } __packed;
 
 
+struct statistics_rx_non_phy_bt {
+	struct statistics_rx_non_phy common;
+	/* additional stats for bt */
+	__le32 num_bt_kills;
+	__le32 reserved[2];
+} __packed;
+
 struct statistics_rx {
 struct statistics_rx {
 	struct statistics_rx_phy ofdm;
 	struct statistics_rx_phy ofdm;
 	struct statistics_rx_phy cck;
 	struct statistics_rx_phy cck;
@@ -3134,6 +3141,13 @@ struct statistics_rx {
 	struct statistics_rx_ht_phy ofdm_ht;
 	struct statistics_rx_ht_phy ofdm_ht;
 } __packed;
 } __packed;
 
 
+struct statistics_rx_bt {
+	struct statistics_rx_phy ofdm;
+	struct statistics_rx_phy cck;
+	struct statistics_rx_non_phy_bt general;
+	struct statistics_rx_ht_phy ofdm_ht;
+} __packed;
+
 /**
 /**
  * struct statistics_tx_power - current tx power
  * struct statistics_tx_power - current tx power
  *
  *
@@ -3196,7 +3210,7 @@ struct statistics_div {
 	__le32 reserved2;
 	__le32 reserved2;
 } __packed;
 } __packed;
 
 
-struct statistics_general {
+struct statistics_general_common {
 	__le32 temperature;   /* radio temperature */
 	__le32 temperature;   /* radio temperature */
 	__le32 temperature_m; /* for 5000 and up, this is radio voltage */
 	__le32 temperature_m; /* for 5000 and up, this is radio voltage */
 	struct statistics_dbg dbg;
 	struct statistics_dbg dbg;
@@ -3212,6 +3226,30 @@ struct statistics_general {
 	 *  in order to get out of bad PHY status
 	 *  in order to get out of bad PHY status
 	 */
 	 */
 	__le32 num_of_sos_states;
 	__le32 num_of_sos_states;
+} __packed;
+
+struct statistics_bt_activity {
+	/* Tx statistics */
+	__le32 hi_priority_tx_req_cnt;
+	__le32 hi_priority_tx_denied_cnt;
+	__le32 lo_priority_tx_req_cnt;
+	__le32 lo_priority_tx_denied_cnt;
+	/* Rx statistics */
+	__le32 hi_priority_rx_req_cnt;
+	__le32 hi_priority_rx_denied_cnt;
+	__le32 lo_priority_rx_req_cnt;
+	__le32 lo_priority_rx_denied_cnt;
+} __packed;
+
+struct statistics_general {
+	struct statistics_general_common common;
+	__le32 reserved2;
+	__le32 reserved3;
+} __packed;
+
+struct statistics_general_bt {
+	struct statistics_general_common common;
+	struct statistics_bt_activity activity;
 	__le32 reserved2;
 	__le32 reserved2;
 	__le32 reserved3;
 	__le32 reserved3;
 } __packed;
 } __packed;
@@ -3273,6 +3311,12 @@ struct iwl_notif_statistics {
 	struct statistics_general general;
 	struct statistics_general general;
 } __packed;
 } __packed;
 
 
+struct iwl_bt_notif_statistics {
+	__le32 flag;
+	struct statistics_rx_bt rx;
+	struct statistics_tx tx;
+	struct statistics_general_bt general;
+} __packed;
 
 
 /*
 /*
  * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
  * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
@@ -3616,10 +3660,10 @@ enum {
 	IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD	= 15,
 	IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD	= 15,
 	IWL_PHY_CALIBRATE_BASE_BAND_CMD		= 16,
 	IWL_PHY_CALIBRATE_BASE_BAND_CMD		= 16,
 	IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD	= 17,
 	IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD	= 17,
-	IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD	= 18,
-	IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD	= 19,
+	IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE	= 18,
 };
 };
 
 
+#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE		(253)
 
 
 #define IWL_CALIB_INIT_CFG_ALL	cpu_to_le32(0xffffffff)
 #define IWL_CALIB_INIT_CFG_ALL	cpu_to_le32(0xffffffff)
 
 
@@ -3944,6 +3988,7 @@ struct iwl_rx_packet {
 		struct iwl_sleep_notification sleep_notif;
 		struct iwl_sleep_notification sleep_notif;
 		struct iwl_spectrum_resp spectrum;
 		struct iwl_spectrum_resp spectrum;
 		struct iwl_notif_statistics stats;
 		struct iwl_notif_statistics stats;
+		struct iwl_bt_notif_statistics stats_bt;
 		struct iwl_compressed_ba_resp compressed_ba;
 		struct iwl_compressed_ba_resp compressed_ba;
 		struct iwl_missed_beacon_notif missed_beacon;
 		struct iwl_missed_beacon_notif missed_beacon;
 		struct iwl_coex_medium_notification coex_medium_notif;
 		struct iwl_coex_medium_notification coex_medium_notif;

+ 32 - 33
drivers/net/wireless/iwlwifi/iwl-core.c

@@ -170,7 +170,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
 	struct ieee80211_hw *hw =
 	struct ieee80211_hw *hw =
 		ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
 		ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
 	if (hw == NULL) {
 	if (hw == NULL) {
-		printk(KERN_ERR "%s: Can not allocate network device\n",
+		pr_err("%s: Can not allocate network device\n",
 		       cfg->name);
 		       cfg->name);
 		goto out;
 		goto out;
 	}
 	}
@@ -1748,6 +1748,37 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv)
 	iwlcore_commit_rxon(priv);
 	iwlcore_commit_rxon(priv);
 }
 }
 
 
+static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+	struct iwl_priv *priv = hw->priv;
+	unsigned long flags;
+	__le64 timestamp;
+
+	IWL_DEBUG_MAC80211(priv, "enter\n");
+
+	if (!iwl_is_ready_rf(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+		return -EIO;
+	}
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (priv->ibss_beacon)
+		dev_kfree_skb(priv->ibss_beacon);
+
+	priv->ibss_beacon = skb;
+
+	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+	priv->timestamp = le64_to_cpu(timestamp);
+
+	IWL_DEBUG_MAC80211(priv, "leave\n");
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	priv->cfg->ops->lib->post_associate(priv, priv->vif);
+
+	return 0;
+}
+
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
 			  struct ieee80211_vif *vif,
 			  struct ieee80211_vif *vif,
 			  struct ieee80211_bss_conf *bss_conf,
 			  struct ieee80211_bss_conf *bss_conf,
@@ -1914,38 +1945,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
 }
 }
 EXPORT_SYMBOL(iwl_bss_info_changed);
 EXPORT_SYMBOL(iwl_bss_info_changed);
 
 
-int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-	struct iwl_priv *priv = hw->priv;
-	unsigned long flags;
-	__le64 timestamp;
-
-	IWL_DEBUG_MAC80211(priv, "enter\n");
-
-	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-		return -EIO;
-	}
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
-
-	priv->ibss_beacon = skb;
-
-	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
-	priv->timestamp = le64_to_cpu(timestamp);
-
-	IWL_DEBUG_MAC80211(priv, "leave\n");
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	priv->cfg->ops->lib->post_associate(priv, priv->vif);
-
-	return 0;
-}
-EXPORT_SYMBOL(iwl_mac_beacon_update);
-
 static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
 static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
 {
 {
 	iwl_connection_init_rx_config(priv, vif);
 	iwl_connection_init_rx_config(priv, vif);

+ 3 - 1
drivers/net/wireless/iwlwifi/iwl-core.h

@@ -125,6 +125,8 @@ struct iwl_debugfs_ops {
 				 size_t count, loff_t *ppos);
 				 size_t count, loff_t *ppos);
 	ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
 	ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
 				      size_t count, loff_t *ppos);
 				      size_t count, loff_t *ppos);
+	ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf,
+				 size_t count, loff_t *ppos);
 };
 };
 
 
 struct iwl_temp_ops {
 struct iwl_temp_ops {
@@ -335,6 +337,7 @@ struct iwl_cfg {
 	u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
 	u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
 	u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
 	u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
 	const bool need_dc_calib;
 	const bool need_dc_calib;
+	const bool bt_statistics;
 };
 };
 
 
 /***************************
 /***************************
@@ -377,7 +380,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
 				     struct ieee80211_vif *vif,
 				     struct ieee80211_vif *vif,
 				     struct ieee80211_bss_conf *bss_conf,
 				     struct ieee80211_bss_conf *bss_conf,
 				     u32 changes);
 				     u32 changes);
-int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
 int iwl_commit_rxon(struct iwl_priv *priv);
 int iwl_commit_rxon(struct iwl_priv *priv);
 int iwl_mac_add_interface(struct ieee80211_hw *hw,
 int iwl_mac_add_interface(struct ieee80211_hw *hw,
 			  struct ieee80211_vif *vif);
 			  struct ieee80211_vif *vif);

+ 13 - 0
drivers/net/wireless/iwlwifi/iwl-debugfs.c

@@ -1519,6 +1519,16 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
 	return count;
 	return count;
 }
 }
 
 
+static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+
+	return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
+			user_buf, count, ppos);
+}
+
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1541,6 +1551,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
 DEBUGFS_READ_FILE_OPS(rxon_flags);
 DEBUGFS_READ_FILE_OPS(rxon_flags);
 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
 DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
 DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
+DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
 
 
 /*
 /*
  * Create the debugfs files and directories
  * Create the debugfs files and directories
@@ -1608,6 +1619,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 		DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
 		DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
 	if (priv->cfg->ucode_tracing)
 	if (priv->cfg->ucode_tracing)
 		DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
 		DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
+	if (priv->cfg->bt_statistics)
+		DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
 	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
 	if (priv->cfg->sensitivity_calib_by_driver)
 	if (priv->cfg->sensitivity_calib_by_driver)

+ 16 - 0
drivers/net/wireless/iwlwifi/iwl-dev.h

@@ -571,6 +571,7 @@ enum iwl_ucode_tlv_type {
 	IWL_UCODE_TLV_INIT_EVTLOG_SIZE	= 12,
 	IWL_UCODE_TLV_INIT_EVTLOG_SIZE	= 12,
 	IWL_UCODE_TLV_INIT_ERRLOG_PTR	= 13,
 	IWL_UCODE_TLV_INIT_ERRLOG_PTR	= 13,
 	IWL_UCODE_TLV_ENHANCE_SENS_TBL	= 14,
 	IWL_UCODE_TLV_ENHANCE_SENS_TBL	= 14,
+	IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
 };
 };
 
 
 struct iwl_ucode_tlv {
 struct iwl_ucode_tlv {
@@ -1153,6 +1154,9 @@ struct iwl_priv {
 	u32  hw_wa_rev;
 	u32  hw_wa_rev;
 	u8   rev_id;
 	u8   rev_id;
 
 
+	/* EEPROM MAC addresses */
+	struct mac_address addresses[2];
+
 	/* uCode images, save to reload in case of failure */
 	/* uCode images, save to reload in case of failure */
 	int fw_index;			/* firmware we're trying to load */
 	int fw_index;			/* firmware we're trying to load */
 	u32 ucode_ver;			/* version of ucode, copy of
 	u32 ucode_ver;			/* version of ucode, copy of
@@ -1321,11 +1325,23 @@ struct iwl_priv {
 			u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
 			u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
 			u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
 			u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
 
 
+			/*
+			 * chain noise reset and gain commands are the
+			 * two extra calibration commands follows the standard
+			 * phy calibration commands
+			 */
+			u8 phy_calib_chain_noise_reset_cmd;
+			u8 phy_calib_chain_noise_gain_cmd;
+
 			struct iwl_notif_statistics statistics;
 			struct iwl_notif_statistics statistics;
+			struct iwl_bt_notif_statistics statistics_bt;
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 			struct iwl_notif_statistics accum_statistics;
 			struct iwl_notif_statistics accum_statistics;
 			struct iwl_notif_statistics delta_statistics;
 			struct iwl_notif_statistics delta_statistics;
 			struct iwl_notif_statistics max_delta;
 			struct iwl_notif_statistics max_delta;
+			struct iwl_bt_notif_statistics accum_statistics_bt;
+			struct iwl_bt_notif_statistics delta_statistics_bt;
+			struct iwl_bt_notif_statistics max_delta_bt;
 #endif
 #endif
 		} _agn;
 		} _agn;
 #endif
 #endif

+ 1 - 0
drivers/net/wireless/iwlwifi/iwl-eeprom.h

@@ -402,6 +402,7 @@ struct iwl_eeprom_calib_info {
 #define EEPROM_WOWLAN_MODE                  (2*0x47)	/* 2  bytes */
 #define EEPROM_WOWLAN_MODE                  (2*0x47)	/* 2  bytes */
 #define EEPROM_RADIO_CONFIG                 (2*0x48)	/* 2  bytes */
 #define EEPROM_RADIO_CONFIG                 (2*0x48)	/* 2  bytes */
 #define EEPROM_3945_M_VERSION               (2*0x4A)	/* 1  bytes */
 #define EEPROM_3945_M_VERSION               (2*0x4A)	/* 1  bytes */
+#define EEPROM_NUM_MAC_ADDRESS              (2*0x4C)	/* 2  bytes */
 
 
 /* The following masks are to be applied on EEPROM_RADIO_CONFIG */
 /* The following masks are to be applied on EEPROM_RADIO_CONFIG */
 #define EEPROM_RF_CFG_TYPE_MSK(x)   (x & 0x3)         /* bits 0-1   */
 #define EEPROM_RF_CFG_TYPE_MSK(x)   (x & 0x3)         /* bits 0-1   */

+ 8 - 10
drivers/net/wireless/iwlwifi/iwl-scan.c

@@ -429,11 +429,10 @@ void iwl_bg_scan_check(struct work_struct *data)
 		return;
 		return;
 
 
 	mutex_lock(&priv->mutex);
 	mutex_lock(&priv->mutex);
-	if (test_bit(STATUS_SCANNING, &priv->status) ||
-	    test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting "
-			"adapter (%dms)\n",
-			jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
+	if (test_bit(STATUS_SCANNING, &priv->status) &&
+	    !test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n",
+			       jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
 
 
 		if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
 		if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
 			iwl_send_scan_abort(priv);
 			iwl_send_scan_abort(priv);
@@ -498,12 +497,11 @@ void iwl_bg_abort_scan(struct work_struct *work)
 	    !test_bit(STATUS_GEO_CONFIGURED, &priv->status))
 	    !test_bit(STATUS_GEO_CONFIGURED, &priv->status))
 		return;
 		return;
 
 
-	mutex_lock(&priv->mutex);
-
-	cancel_delayed_work_sync(&priv->scan_check);
-	set_bit(STATUS_SCAN_ABORTING, &priv->status);
-	iwl_send_scan_abort(priv);
+	cancel_delayed_work(&priv->scan_check);
 
 
+	mutex_lock(&priv->mutex);
+	if (test_bit(STATUS_SCAN_ABORTING, &priv->status))
+		iwl_send_scan_abort(priv);
 	mutex_unlock(&priv->mutex);
 	mutex_unlock(&priv->mutex);
 }
 }
 EXPORT_SYMBOL(iwl_bg_abort_scan);
 EXPORT_SYMBOL(iwl_bg_abort_scan);

+ 12 - 10
drivers/net/wireless/iwlwifi/iwl3945-base.c

@@ -27,6 +27,8 @@
  *
  *
  *****************************************************************************/
  *****************************************************************************/
 
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/init.h>
@@ -311,9 +313,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
 				int left)
 				int left)
 {
 {
 
 
-	if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
-	    ((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
-	     (priv->iw_mode != NL80211_IFTYPE_AP)))
+	if (!iwl_is_associated(priv) || !priv->ibss_beacon)
 		return 0;
 		return 0;
 
 
 	if (priv->ibss_beacon->len > left)
 	if (priv->ibss_beacon->len > left)
@@ -2883,7 +2883,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 		IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
 		IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
 
 
 		spin_lock_irqsave(&priv->lock, flags);
 		spin_lock_irqsave(&priv->lock, flags);
-		interval = vif ? vif->bss_conf.beacon_int : 0;
+		if (priv->is_internal_short_scan)
+			interval = 0;
+		else
+			interval = vif->bss_conf.beacon_int;
 		spin_unlock_irqrestore(&priv->lock, flags);
 		spin_unlock_irqrestore(&priv->lock, flags);
 
 
 		scan->suspend_time = 0;
 		scan->suspend_time = 0;
@@ -3932,7 +3935,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 	 *   space for this driver's private structure */
 	 *   space for this driver's private structure */
 	hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
 	hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
 	if (hw == NULL) {
 	if (hw == NULL) {
-		printk(KERN_ERR DRV_NAME "Can not allocate network device\n");
+		pr_err("Can not allocate network device\n");
 		err = -ENOMEM;
 		err = -ENOMEM;
 		goto out;
 		goto out;
 	}
 	}
@@ -4224,19 +4227,18 @@ static int __init iwl3945_init(void)
 {
 {
 
 
 	int ret;
 	int ret;
-	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
-	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
+	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
+	pr_info(DRV_COPYRIGHT "\n");
 
 
 	ret = iwl3945_rate_control_register();
 	ret = iwl3945_rate_control_register();
 	if (ret) {
 	if (ret) {
-		printk(KERN_ERR DRV_NAME
-		       "Unable to register rate control algorithm: %d\n", ret);
+		pr_err("Unable to register rate control algorithm: %d\n", ret);
 		return ret;
 		return ret;
 	}
 	}
 
 
 	ret = pci_register_driver(&iwl3945_driver);
 	ret = pci_register_driver(&iwl3945_driver);
 	if (ret) {
 	if (ret) {
-		printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
+		pr_err("Unable to initialize PCI module\n");
 		goto error_register;
 		goto error_register;
 	}
 	}
 
 

+ 10 - 187
drivers/net/wireless/libertas/cfg.c

@@ -7,7 +7,6 @@
  */
  */
 
 
 #include <linux/slab.h>
 #include <linux/slab.h>
-#include <linux/if_arp.h>
 #include <linux/ieee80211.h>
 #include <linux/ieee80211.h>
 #include <net/cfg80211.h>
 #include <net/cfg80211.h>
 #include <asm/unaligned.h>
 #include <asm/unaligned.h>
@@ -1383,93 +1382,10 @@ static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
 }
 }
 
 
 
 
-
-/***************************************************************************
- * Monitor mode
- */
-
-/* like "struct cmd_ds_802_11_monitor_mode", but with cmd_header. Once we
- * get rid of WEXT, this should go into host.h */
-struct cmd_monitor_mode {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 mode;
-} __packed;
-
-static int lbs_enable_monitor_mode(struct lbs_private *priv, int mode)
-{
-	struct cmd_monitor_mode cmd;
-	int ret;
-
-	lbs_deb_enter(LBS_DEB_CFG80211);
-
-	/*
-	 * cmd       98 00
-	 * size      0c 00
-	 * sequence  xx xx
-	 * result    00 00
-	 * action    01 00    ACT_SET
-	 * enable    01 00
-	 */
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-	cmd.action = cpu_to_le16(CMD_ACT_SET);
-	cmd.mode = cpu_to_le16(mode);
-
-	ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
-
-	if (ret == 0)
-		priv->dev->type = ARPHRD_IEEE80211_RADIOTAP;
-	else
-		priv->dev->type = ARPHRD_ETHER;
-
-	lbs_deb_leave(LBS_DEB_CFG80211);
-	return ret;
-}
-
-
-
-
-
-
 /***************************************************************************
 /***************************************************************************
  * Get station
  * Get station
  */
  */
 
 
-/*
- * Returns the signal or 0 in case of an error.
- */
-
-/* like "struct cmd_ds_802_11_rssi", but with cmd_header. Once we get rid
- * of WEXT, this should go into host.h */
-struct cmd_rssi {
-	struct cmd_header hdr;
-
-	__le16 n_or_snr;
-	__le16 nf;
-	__le16 avg_snr;
-	__le16 avg_nf;
-} __packed;
-
-static int lbs_get_signal(struct lbs_private *priv, s8 *signal, s8 *noise)
-{
-	struct cmd_rssi cmd;
-	int ret;
-
-	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-	cmd.n_or_snr = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
-	ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
-
-	if (ret == 0) {
-		*signal = CAL_RSSI(le16_to_cpu(cmd.n_or_snr),
-				le16_to_cpu(cmd.nf));
-		*noise  = CAL_NF(le16_to_cpu(cmd.nf));
-	}
-	return ret;
-}
-
-
 static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
 static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
 			      u8 *mac, struct station_info *sinfo)
 			      u8 *mac, struct station_info *sinfo)
 {
 {
@@ -1490,7 +1406,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
 	sinfo->rx_packets = priv->dev->stats.rx_packets;
 	sinfo->rx_packets = priv->dev->stats.rx_packets;
 
 
 	/* Get current RSSI */
 	/* Get current RSSI */
-	ret = lbs_get_signal(priv, &signal, &noise);
+	ret = lbs_get_rssi(priv, &signal, &noise);
 	if (ret == 0) {
 	if (ret == 0) {
 		sinfo->signal = signal;
 		sinfo->signal = signal;
 		sinfo->filled |= STATION_INFO_SIGNAL;
 		sinfo->filled |= STATION_INFO_SIGNAL;
@@ -1530,7 +1446,7 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
 	survey->channel = ieee80211_get_channel(wiphy,
 	survey->channel = ieee80211_get_channel(wiphy,
 		ieee80211_channel_to_frequency(priv->channel));
 		ieee80211_channel_to_frequency(priv->channel));
 
 
-	ret = lbs_get_signal(priv, &signal, &noise);
+	ret = lbs_get_rssi(priv, &signal, &noise);
 	if (ret == 0) {
 	if (ret == 0) {
 		survey->filled = SURVEY_INFO_NOISE_DBM;
 		survey->filled = SURVEY_INFO_NOISE_DBM;
 		survey->noise = noise;
 		survey->noise = noise;
@@ -1558,17 +1474,17 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
 
 
 	switch (type) {
 	switch (type) {
 	case NL80211_IFTYPE_MONITOR:
 	case NL80211_IFTYPE_MONITOR:
-		ret = lbs_enable_monitor_mode(priv, 1);
+		ret = lbs_set_monitor_mode(priv, 1);
 		break;
 		break;
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_STATION:
 		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
 		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
-			ret = lbs_enable_monitor_mode(priv, 0);
+			ret = lbs_set_monitor_mode(priv, 0);
 		if (!ret)
 		if (!ret)
 			ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1);
 			ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1);
 		break;
 		break;
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_ADHOC:
 		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
 		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
-			ret = lbs_enable_monitor_mode(priv, 0);
+			ret = lbs_set_monitor_mode(priv, 0);
 		if (!ret)
 		if (!ret)
 			ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2);
 			ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2);
 		break;
 		break;
@@ -2063,113 +1979,20 @@ int lbs_cfg_register(struct lbs_private *priv)
 	return ret;
 	return ret;
 }
 }
 
 
-/**
- *  @brief This function sets DOMAIN INFO to FW
- *  @param priv       pointer to struct lbs_private
- *  @return          0; -1
-*/
-static int lbs_11d_set_domain_info(struct lbs_private *priv)
-{
-	int ret;
-
-	ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
-			CMD_ACT_SET,
-			CMD_OPTION_WAITFORRSP, 0, NULL);
-	if (ret)
-		lbs_deb_11d("fail to dnld domain info\n");
-
-	return ret;
-}
-
-static void lbs_send_domain_info_cmd_fw(struct wiphy *wiphy,
-					struct regulatory_request *request)
-{
-	u8   no_of_triplet = 0;
-	u8   no_of_parsed_chan = 0;
-	u8   first_channel = 0, next_chan = 0, max_pwr = 0;
-	u8   i, flag = 0;
-	enum ieee80211_band band;
-	struct ieee80211_supported_band *sband;
-	struct ieee80211_channel *ch;
-	struct lbs_private *priv = wiphy_priv(wiphy);
-	struct lbs_802_11d_domain_reg *domain_info = &priv->domain_reg;
-	int ret = 0;
-
-	lbs_deb_enter(LBS_DEB_CFG80211);
-
-	/* Set country code */
-	domain_info->country_code[0] = request->alpha2[0];
-	domain_info->country_code[1] = request->alpha2[1];
-	domain_info->country_code[2] = ' ';
-
-	for (band = 0; band < IEEE80211_NUM_BANDS ; band++) {
-
-		if (!wiphy->bands[band])
-			continue;
-
-		sband = wiphy->bands[band];
-
-		for (i = 0; i < sband->n_channels ; i++) {
-			ch = &sband->channels[i];
-			if (ch->flags & IEEE80211_CHAN_DISABLED)
-				continue;
-
-			if (!flag) {
-				flag = 1;
-				next_chan = first_channel = (u32) ch->hw_value;
-				max_pwr = ch->max_power;
-				no_of_parsed_chan = 1;
-				continue;
-			}
-
-			if (ch->hw_value == next_chan + 1 &&
-					ch->max_power == max_pwr) {
-				next_chan++;
-				no_of_parsed_chan++;
-			} else {
-				domain_info->triplet[no_of_triplet]
-					.chans.first_channel = first_channel;
-				domain_info->triplet[no_of_triplet]
-					.chans.num_channels = no_of_parsed_chan;
-				domain_info->triplet[no_of_triplet]
-					.chans.max_power = max_pwr;
-				no_of_triplet++;
-				flag = 0;
-			}
-		}
-		if (flag) {
-			domain_info->triplet[no_of_triplet]
-				.chans.first_channel = first_channel;
-			domain_info->triplet[no_of_triplet]
-				.chans.num_channels = no_of_parsed_chan;
-			domain_info->triplet[no_of_triplet]
-				.chans.max_power = max_pwr;
-			no_of_triplet++;
-		}
-	}
-
-	domain_info->no_triplet = no_of_triplet;
-
-	/* Set domain info */
-	ret = lbs_11d_set_domain_info(priv);
-	if (ret)
-		lbs_pr_err("11D: error setting domain info in FW\n");
-
-	lbs_deb_leave(LBS_DEB_CFG80211);
-}
-
 int lbs_reg_notifier(struct wiphy *wiphy,
 int lbs_reg_notifier(struct wiphy *wiphy,
 		struct regulatory_request *request)
 		struct regulatory_request *request)
 {
 {
+	struct lbs_private *priv = wiphy_priv(wiphy);
+	int ret;
+
 	lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
 	lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
 			"callback for domain %c%c\n", request->alpha2[0],
 			"callback for domain %c%c\n", request->alpha2[0],
 			request->alpha2[1]);
 			request->alpha2[1]);
 
 
-	lbs_send_domain_info_cmd_fw(wiphy, request);
+	ret = lbs_set_11d_domain_info(priv, request, wiphy->bands);
 
 
 	lbs_deb_leave(LBS_DEB_CFG80211);
 	lbs_deb_leave(LBS_DEB_CFG80211);
-
-	return 0;
+	return ret;
 }
 }
 
 
 void lbs_scan_deinit(struct lbs_private *priv)
 void lbs_scan_deinit(struct lbs_private *priv)

+ 0 - 6
drivers/net/wireless/libertas/cfg.h

@@ -13,12 +13,6 @@ void lbs_cfg_free(struct lbs_private *priv);
 int lbs_reg_notifier(struct wiphy *wiphy,
 int lbs_reg_notifier(struct wiphy *wiphy,
 		struct regulatory_request *request);
 		struct regulatory_request *request);
 
 
-/* All of those are TODOs: */
-#define lbs_cmd_802_11_rssi(priv, cmdptr) (0)
-#define lbs_ret_802_11_rssi(priv, resp) (0)
-#define lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action) (0)
-#define lbs_ret_802_11_bcn_ctrl(priv, resp) (0)
-
 void lbs_send_disconnect_notification(struct lbs_private *priv);
 void lbs_send_disconnect_notification(struct lbs_private *priv);
 void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
 void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
 
 

+ 307 - 411
drivers/net/wireless/libertas/cmd.c

@@ -6,13 +6,14 @@
 #include <linux/kfifo.h>
 #include <linux/kfifo.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
+#include <linux/if_arp.h>
 
 
 #include "decl.h"
 #include "decl.h"
 #include "cfg.h"
 #include "cfg.h"
 #include "cmd.h"
 #include "cmd.h"
 
 
-
-static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
+#define CAL_NF(nf)		((s32)(-(s32)(nf)))
+#define CAL_RSSI(snr, nf)	((s32)((s32)(snr) + CAL_NF(nf)))
 
 
 /**
 /**
  *  @brief Simple callback that copies response back into command
  *  @brief Simple callback that copies response back into command
@@ -73,30 +74,6 @@ static u8 is_command_allowed_in_ps(u16 cmd)
 	return 0;
 	return 0;
 }
 }
 
 
-/**
- *  @brief This function checks if the command is allowed.
- *
- *  @param priv         A pointer to lbs_private structure
- *  @return             allowed or not allowed.
- */
-
-static int lbs_is_cmd_allowed(struct lbs_private *priv)
-{
-	int ret = 1;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	if (!priv->is_auto_deep_sleep_enabled) {
-		if (priv->is_deep_sleep) {
-			lbs_deb_cmd("command not allowed in deep sleep\n");
-			ret = 0;
-		}
-	}
-
-	lbs_deb_leave(LBS_DEB_CMD);
-	return ret;
-}
-
 /**
 /**
  *  @brief Updates the hardware details like MAC address and regulatory region
  *  @brief Updates the hardware details like MAC address and regulatory region
  *
  *
@@ -227,42 +204,49 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
 }
 }
 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
 
 
-static int lbs_cmd_802_11_ps_mode(struct cmd_ds_command *cmd,
-				   u16 cmd_action)
+/**
+ *  @brief Sets the Power Save mode
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param cmd_action	The Power Save operation (PS_MODE_ACTION_ENTER_PS or
+ *                         PS_MODE_ACTION_EXIT_PS)
+ *  @param block	Whether to block on a response or not
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
 {
 {
-	struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
+	struct cmd_ds_802_11_ps_mode cmd;
+	int ret = 0;
 
 
 	lbs_deb_enter(LBS_DEB_CMD);
 	lbs_deb_enter(LBS_DEB_CMD);
 
 
-	cmd->command = cpu_to_le16(CMD_802_11_PS_MODE);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
-				sizeof(struct cmd_header));
-	psm->action = cpu_to_le16(cmd_action);
-	psm->multipledtim = 0;
-	switch (cmd_action) {
-	case CMD_SUBCMD_ENTER_PS:
-		lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");
-
-		psm->locallisteninterval = 0;
-		psm->nullpktinterval = 0;
-		psm->multipledtim =
-		    cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM);
-		break;
-
-	case CMD_SUBCMD_EXIT_PS:
-		lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
-		break;
-
-	case CMD_SUBCMD_SLEEP_CONFIRMED:
-		lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
-		break;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(cmd_action);
 
 
-	default:
-		break;
+	if (cmd_action == PS_MODE_ACTION_ENTER_PS) {
+		lbs_deb_cmd("PS_MODE: action ENTER_PS\n");
+		cmd.multipledtim = cpu_to_le16(1);  /* Default DTIM multiple */
+	} else if (cmd_action == PS_MODE_ACTION_EXIT_PS) {
+		lbs_deb_cmd("PS_MODE: action EXIT_PS\n");
+	} else {
+		/* We don't handle CONFIRM_SLEEP here because it needs to
+		 * be fastpathed to the firmware.
+		 */
+		lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action);
+		ret = -EOPNOTSUPP;
+		goto out;
 	}
 	}
 
 
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
+	if (block)
+		ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd);
+	else
+		lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd));
+
+out:
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
 }
 }
 
 
 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
@@ -576,23 +560,35 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
 	return ret;
 	return ret;
 }
 }
 
 
-static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd,
-				      u16 cmd_action, void *pdata_buf)
+/**
+ *  @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW)
+ *
+ *  @param priv        A pointer to struct lbs_private structure
+ *  @param enable      1 to enable monitor mode, 0 to disable
+ *
+ *  @return            0 on success, error on failure
+ */
+int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
 {
 {
-	struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor;
+	struct cmd_ds_802_11_monitor_mode cmd;
+	int ret;
 
 
-	cmd->command = cpu_to_le16(CMD_802_11_MONITOR_MODE);
-	cmd->size =
-	    cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) +
-			     sizeof(struct cmd_header));
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_SET);
+	if (enable)
+		cmd.mode = cpu_to_le16(0x1);
+
+	lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable);
 
 
-	monitor->action = cpu_to_le16(cmd_action);
-	if (cmd_action == CMD_ACT_SET) {
-		monitor->mode =
-		    cpu_to_le16((u16) (*(u32 *) pdata_buf));
+	ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
+	if (ret == 0) {
+		priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP :
+						ARPHRD_ETHER;
 	}
 	}
 
 
-	return 0;
+	lbs_deb_leave(LBS_DEB_CMD);
+	return ret;
 }
 }
 
 
 /**
 /**
@@ -677,78 +673,242 @@ out:
 	return ret;
 	return ret;
 }
 }
 
 
-static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr,
-			       u8 cmd_action, void *pdata_buf)
+/**
+ *  @brief Get current RSSI and noise floor
+ *
+ *  @param priv		A pointer to struct lbs_private structure
+ *  @param rssi		On successful return, signal level in mBm
+ *
+ *  @return 	   	The channel on success, error on failure
+ */
+int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
 {
 {
-	struct lbs_offset_value *offval;
+	struct cmd_ds_802_11_rssi cmd;
+	int ret = 0;
 
 
 	lbs_deb_enter(LBS_DEB_CMD);
 	lbs_deb_enter(LBS_DEB_CMD);
 
 
-	offval = (struct lbs_offset_value *)pdata_buf;
+	BUG_ON(rssi == NULL);
+	BUG_ON(nf == NULL);
 
 
-	switch (le16_to_cpu(cmdptr->command)) {
-	case CMD_MAC_REG_ACCESS:
-		{
-			struct cmd_ds_mac_reg_access *macreg;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	/* Average SNR over last 8 beacons */
+	cmd.n_or_snr = cpu_to_le16(8);
 
 
-			cmdptr->size =
-			    cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access)
-					+ sizeof(struct cmd_header));
-			macreg =
-			    (struct cmd_ds_mac_reg_access *)&cmdptr->params.
-			    macreg;
+	ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
+	if (ret == 0) {
+		*nf = CAL_NF(le16_to_cpu(cmd.nf));
+		*rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf));
+	}
 
 
-			macreg->action = cpu_to_le16(cmd_action);
-			macreg->offset = cpu_to_le16((u16) offval->offset);
-			macreg->value = cpu_to_le32(offval->value);
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
 
 
-			break;
-		}
+/**
+ *  @brief Send regulatory and 802.11d domain information to the firmware
+ *
+ *  @param priv		pointer to struct lbs_private
+ *  @param request	cfg80211 regulatory request structure
+ *  @param bands	the device's supported bands and channels
+ *
+ *  @return		0 on success, error code on failure
+*/
+int lbs_set_11d_domain_info(struct lbs_private *priv,
+			    struct regulatory_request *request,
+			    struct ieee80211_supported_band **bands)
+{
+	struct cmd_ds_802_11d_domain_info cmd;
+	struct mrvl_ie_domain_param_set *domain = &cmd.domain;
+	struct ieee80211_country_ie_triplet *t;
+	enum ieee80211_band band;
+	struct ieee80211_channel *ch;
+	u8 num_triplet = 0;
+	u8 num_parsed_chan = 0;
+	u8 first_channel = 0, next_chan = 0, max_pwr = 0;
+	u8 i, flag = 0;
+	size_t triplet_size;
+	int ret;
 
 
-	case CMD_BBP_REG_ACCESS:
-		{
-			struct cmd_ds_bbp_reg_access *bbpreg;
+	lbs_deb_enter(LBS_DEB_11D);
 
 
-			cmdptr->size =
-			    cpu_to_le16(sizeof
-					     (struct cmd_ds_bbp_reg_access)
-					     + sizeof(struct cmd_header));
-			bbpreg =
-			    (struct cmd_ds_bbp_reg_access *)&cmdptr->params.
-			    bbpreg;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_SET);
 
 
-			bbpreg->action = cpu_to_le16(cmd_action);
-			bbpreg->offset = cpu_to_le16((u16) offval->offset);
-			bbpreg->value = (u8) offval->value;
+	lbs_deb_11d("Setting country code '%c%c'\n",
+		    request->alpha2[0], request->alpha2[1]);
 
 
-			break;
+	domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
+
+	/* Set country code */
+	domain->country_code[0] = request->alpha2[0];
+	domain->country_code[1] = request->alpha2[1];
+	domain->country_code[2] = ' ';
+
+	/* Now set up the channel triplets; firmware is somewhat picky here
+	 * and doesn't validate channel numbers and spans; hence it would
+	 * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39.  Since
+	 * the last 3 aren't valid channels, the driver is responsible for
+	 * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20)
+	 * etc.
+	 */
+	for (band = 0;
+	     (band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS);
+	     band++) {
+
+		if (!bands[band])
+			continue;
+
+		for (i = 0;
+		     (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS);
+		     i++) {
+			ch = &bands[band]->channels[i];
+			if (ch->flags & IEEE80211_CHAN_DISABLED)
+				continue;
+
+			if (!flag) {
+				flag = 1;
+				next_chan = first_channel = (u32) ch->hw_value;
+				max_pwr = ch->max_power;
+				num_parsed_chan = 1;
+				continue;
+			}
+
+			if ((ch->hw_value == next_chan + 1) &&
+					(ch->max_power == max_pwr)) {
+				/* Consolidate adjacent channels */
+				next_chan++;
+				num_parsed_chan++;
+			} else {
+				/* Add this triplet */
+				lbs_deb_11d("11D triplet (%d, %d, %d)\n",
+					first_channel, num_parsed_chan,
+					max_pwr);
+				t = &domain->triplet[num_triplet];
+				t->chans.first_channel = first_channel;
+				t->chans.num_channels = num_parsed_chan;
+				t->chans.max_power = max_pwr;
+				num_triplet++;
+				flag = 0;
+			}
 		}
 		}
 
 
-	case CMD_RF_REG_ACCESS:
-		{
-			struct cmd_ds_rf_reg_access *rfreg;
+		if (flag) {
+			/* Add last triplet */
+			lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel,
+				num_parsed_chan, max_pwr);
+			t = &domain->triplet[num_triplet];
+			t->chans.first_channel = first_channel;
+			t->chans.num_channels = num_parsed_chan;
+			t->chans.max_power = max_pwr;
+			num_triplet++;
+		}
+	}
 
 
-			cmdptr->size =
-			    cpu_to_le16(sizeof
-					     (struct cmd_ds_rf_reg_access) +
-					     sizeof(struct cmd_header));
-			rfreg =
-			    (struct cmd_ds_rf_reg_access *)&cmdptr->params.
-			    rfreg;
+	lbs_deb_11d("# triplets %d\n", num_triplet);
 
 
-			rfreg->action = cpu_to_le16(cmd_action);
-			rfreg->offset = cpu_to_le16((u16) offval->offset);
-			rfreg->value = (u8) offval->value;
+	/* Set command header sizes */
+	triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet);
+	domain->header.len = cpu_to_le16(sizeof(domain->country_code) +
+					triplet_size);
 
 
-			break;
-		}
+	lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set",
+			(u8 *) &cmd.domain.country_code,
+			le16_to_cpu(domain->header.len));
 
 
-	default:
-		break;
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) +
+				   sizeof(cmd.action) +
+				   sizeof(cmd.domain.header) +
+				   sizeof(cmd.domain.country_code) +
+				   triplet_size);
+
+	ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd);
+
+	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
+	return ret;
+}
+
+/**
+ *  @brief Read a MAC, Baseband, or RF register
+ *
+ *  @param priv		pointer to struct lbs_private
+ *  @param cmd		register command, one of CMD_MAC_REG_ACCESS,
+ *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
+ *  @param offset       byte offset of the register to get
+ *  @param value        on success, the value of the register at 'offset'
+ *
+ *  @return		0 on success, error code on failure
+*/
+int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
+{
+	struct cmd_ds_reg_access cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	BUG_ON(value == NULL);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_GET);
+
+	if (reg != CMD_MAC_REG_ACCESS &&
+	    reg != CMD_BBP_REG_ACCESS &&
+	    reg != CMD_RF_REG_ACCESS) {
+		ret = -EINVAL;
+		goto out;
 	}
 	}
 
 
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
+	ret = lbs_cmd_with_response(priv, reg, &cmd);
+	if (ret) {
+		if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
+			*value = cmd.value.bbp_rf;
+		else if (reg == CMD_MAC_REG_ACCESS)
+			*value = le32_to_cpu(cmd.value.mac);
+	}
+
+out:
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+/**
+ *  @brief Write a MAC, Baseband, or RF register
+ *
+ *  @param priv		pointer to struct lbs_private
+ *  @param cmd		register command, one of CMD_MAC_REG_ACCESS,
+ *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
+ *  @param offset       byte offset of the register to set
+ *  @param value        the value to write to the register at 'offset'
+ *
+ *  @return		0 on success, error code on failure
+*/
+int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
+{
+	struct cmd_ds_reg_access cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_SET);
+
+	if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
+		cmd.value.bbp_rf = (u8) (value & 0xFF);
+	else if (reg == CMD_MAC_REG_ACCESS)
+		cmd.value.mac = cpu_to_le32(value);
+	else {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = lbs_cmd_with_response(priv, reg, &cmd);
+
+out:
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
 }
 }
 
 
 static void lbs_queue_cmd(struct lbs_private *priv,
 static void lbs_queue_cmd(struct lbs_private *priv,
@@ -771,16 +931,15 @@ static void lbs_queue_cmd(struct lbs_private *priv,
 
 
 	/* Exit_PS command needs to be queued in the header always. */
 	/* Exit_PS command needs to be queued in the header always. */
 	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
 	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
-		struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1];
+		struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf;
 
 
-		if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
+		if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
 			if (priv->psstate != PS_STATE_FULL_POWER)
 			if (priv->psstate != PS_STATE_FULL_POWER)
 				addtail = 0;
 				addtail = 0;
 		}
 		}
 	}
 	}
 
 
-	if (le16_to_cpu(cmdnode->cmdbuf->command) ==
-			CMD_802_11_WAKEUP_CONFIRM)
+	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM)
 		addtail = 0;
 		addtail = 0;
 
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	spin_lock_irqsave(&priv->driver_lock, flags);
@@ -815,7 +974,6 @@ static void lbs_submit_command(struct lbs_private *priv,
 
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	priv->cur_cmd = cmdnode;
 	priv->cur_cmd = cmdnode;
-	priv->cur_cmd_retcode = 0;
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 
 	cmdsize = le16_to_cpu(cmd->size);
 	cmdsize = le16_to_cpu(cmd->size);
@@ -888,9 +1046,6 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
 			  int result)
 			  int result)
 {
 {
-	if (cmd == priv->cur_cmd)
-		priv->cur_cmd_retcode = result;
-
 	cmd->result = result;
 	cmd->result = result;
 	cmd->cmdwaitqwoken = 1;
 	cmd->cmdwaitqwoken = 1;
 	wake_up_interruptible(&cmd->cmdwait_q);
 	wake_up_interruptible(&cmd->cmdwait_q);
@@ -957,240 +1112,6 @@ void lbs_set_mac_control(struct lbs_private *priv)
 	lbs_deb_leave(LBS_DEB_CMD);
 	lbs_deb_leave(LBS_DEB_CMD);
 }
 }
 
 
-/**
- *  @brief This function implements command CMD_802_11D_DOMAIN_INFO
- *  @param priv       pointer to struct lbs_private
- *  @param cmd        pointer to cmd buffer
- *  @param cmdno      cmd ID
- *  @param cmdOption  cmd action
- *  @return           0
-*/
-int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
-				 struct cmd_ds_command *cmd,
-				 u16 cmdoption)
-{
-	struct cmd_ds_802_11d_domain_info *pdomaininfo =
-	    &cmd->params.domaininfo;
-	struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
-	u8 nr_triplet = priv->domain_reg.no_triplet;
-
-	lbs_deb_enter(LBS_DEB_11D);
-
-	lbs_deb_11d("nr_triplet=%x\n", nr_triplet);
-
-	pdomaininfo->action = cpu_to_le16(cmdoption);
-	if (cmdoption == CMD_ACT_GET) {
-		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
-					sizeof(struct cmd_header));
-		lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
-			le16_to_cpu(cmd->size));
-		goto done;
-	}
-
-	domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
-	memcpy(domain->countrycode, priv->domain_reg.country_code,
-	       sizeof(domain->countrycode));
-
-	domain->header.len = cpu_to_le16(nr_triplet
-				* sizeof(struct ieee80211_country_ie_triplet)
-				+ sizeof(domain->countrycode));
-
-	if (nr_triplet) {
-		memcpy(domain->triplet, priv->domain_reg.triplet,
-				nr_triplet *
-				sizeof(struct ieee80211_country_ie_triplet));
-
-		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
-					     le16_to_cpu(domain->header.len) +
-					     sizeof(struct mrvl_ie_header) +
-					     sizeof(struct cmd_header));
-	} else {
-		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
-					sizeof(struct cmd_header));
-	}
-
-	lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
-			le16_to_cpu(cmd->size));
-
-done:
-	lbs_deb_enter(LBS_DEB_11D);
-	return 0;
-}
-
-/**
- *  @brief This function prepare the command before send to firmware.
- *
- *  @param priv		A pointer to struct lbs_private structure
- *  @param cmd_no	command number
- *  @param cmd_action	command action: GET or SET
- *  @param wait_option	wait option: wait response or not
- *  @param cmd_oid	cmd oid: treated as sub command
- *  @param pdata_buf	A pointer to informaion buffer
- *  @return 		0 or -1
- */
-int lbs_prepare_and_send_command(struct lbs_private *priv,
-			  u16 cmd_no,
-			  u16 cmd_action,
-			  u16 wait_option, u32 cmd_oid, void *pdata_buf)
-{
-	int ret = 0;
-	struct cmd_ctrl_node *cmdnode;
-	struct cmd_ds_command *cmdptr;
-	unsigned long flags;
-
-	lbs_deb_enter(LBS_DEB_HOST);
-
-	if (!priv) {
-		lbs_deb_host("PREP_CMD: priv is NULL\n");
-		ret = -1;
-		goto done;
-	}
-
-	if (priv->surpriseremoved) {
-		lbs_deb_host("PREP_CMD: card removed\n");
-		ret = -1;
-		goto done;
-	}
-
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto done;
-	}
-
-	cmdnode = lbs_get_cmd_ctrl_node(priv);
-
-	if (cmdnode == NULL) {
-		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
-
-		/* Wake up main thread to execute next command */
-		wake_up_interruptible(&priv->waitq);
-		ret = -1;
-		goto done;
-	}
-
-	cmdnode->callback = NULL;
-	cmdnode->callback_arg = (unsigned long)pdata_buf;
-
-	cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
-
-	lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no);
-
-	/* Set sequence number, command and INT option */
-	priv->seqnum++;
-	cmdptr->seqnum = cpu_to_le16(priv->seqnum);
-
-	cmdptr->command = cpu_to_le16(cmd_no);
-	cmdptr->result = 0;
-
-	switch (cmd_no) {
-	case CMD_802_11_PS_MODE:
-		ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
-		break;
-
-	case CMD_MAC_REG_ACCESS:
-	case CMD_BBP_REG_ACCESS:
-	case CMD_RF_REG_ACCESS:
-		ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf);
-		break;
-
-	case CMD_802_11_MONITOR_MODE:
-		ret = lbs_cmd_802_11_monitor_mode(cmdptr,
-				          cmd_action, pdata_buf);
-		break;
-
-	case CMD_802_11_RSSI:
-		ret = lbs_cmd_802_11_rssi(priv, cmdptr);
-		break;
-
-	case CMD_802_11_SET_AFC:
-	case CMD_802_11_GET_AFC:
-
-		cmdptr->command = cpu_to_le16(cmd_no);
-		cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
-					   sizeof(struct cmd_header));
-
-		memmove(&cmdptr->params.afc,
-			pdata_buf, sizeof(struct cmd_ds_802_11_afc));
-
-		ret = 0;
-		goto done;
-
-	case CMD_802_11D_DOMAIN_INFO:
-		cmdptr->command = cpu_to_le16(cmd_no);
-		ret = lbs_cmd_802_11d_domain_info(priv, cmdptr, cmd_action);
-		break;
-
-	case CMD_802_11_TPC_CFG:
-		cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG);
-		cmdptr->size =
-		    cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) +
-				     sizeof(struct cmd_header));
-
-		memmove(&cmdptr->params.tpccfg,
-			pdata_buf, sizeof(struct cmd_ds_802_11_tpc_cfg));
-
-		ret = 0;
-		break;
-
-#ifdef CONFIG_LIBERTAS_MESH
-
-	case CMD_BT_ACCESS:
-		ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf);
-		break;
-
-	case CMD_FWT_ACCESS:
-		ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf);
-		break;
-
-#endif
-
-	case CMD_802_11_BEACON_CTRL:
-		ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
-		break;
-	case CMD_802_11_DEEP_SLEEP:
-		cmdptr->command = cpu_to_le16(CMD_802_11_DEEP_SLEEP);
-		cmdptr->size = cpu_to_le16(sizeof(struct cmd_header));
-		break;
-	default:
-		lbs_pr_err("PREP_CMD: unknown command 0x%04x\n", cmd_no);
-		ret = -1;
-		break;
-	}
-
-	/* return error, since the command preparation failed */
-	if (ret != 0) {
-		lbs_deb_host("PREP_CMD: command preparation failed\n");
-		lbs_cleanup_and_insert_cmd(priv, cmdnode);
-		ret = -1;
-		goto done;
-	}
-
-	cmdnode->cmdwaitqwoken = 0;
-
-	lbs_queue_cmd(priv, cmdnode);
-	wake_up_interruptible(&priv->waitq);
-
-	if (wait_option & CMD_OPTION_WAITFORRSP) {
-		lbs_deb_host("PREP_CMD: wait for response\n");
-		might_sleep();
-		wait_event_interruptible(cmdnode->cmdwait_q,
-					 cmdnode->cmdwaitqwoken);
-	}
-
-	spin_lock_irqsave(&priv->driver_lock, flags);
-	if (priv->cur_cmd_retcode) {
-		lbs_deb_host("PREP_CMD: command failed with return code %d\n",
-		       priv->cur_cmd_retcode);
-		priv->cur_cmd_retcode = 0;
-		ret = -1;
-	}
-	spin_unlock_irqrestore(&priv->driver_lock, flags);
-
-done:
-	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
-	return ret;
-}
-
 /**
 /**
  *  @brief This function allocates the command buffer and link
  *  @brief This function allocates the command buffer and link
  *  it to command free queue.
  *  it to command free queue.
@@ -1284,7 +1205,7 @@ done:
  *  @param priv		A pointer to struct lbs_private structure
  *  @param priv		A pointer to struct lbs_private structure
  *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
  *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
  */
  */
-static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
+static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
 {
 {
 	struct cmd_ctrl_node *tempnode;
 	struct cmd_ctrl_node *tempnode;
 	unsigned long flags;
 	unsigned long flags;
@@ -1367,10 +1288,10 @@ int lbs_execute_next_command(struct lbs_private *priv)
 			/*
 			/*
 			 * 1. Non-PS command:
 			 * 1. Non-PS command:
 			 * Queue it. set needtowakeup to TRUE if current state
 			 * Queue it. set needtowakeup to TRUE if current state
-			 * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS.
-			 * 2. PS command but not Exit_PS:
+			 * is SLEEP, otherwise call send EXIT_PS.
+			 * 2. PS command but not EXIT_PS:
 			 * Ignore it.
 			 * Ignore it.
-			 * 3. PS command Exit_PS:
+			 * 3. PS command EXIT_PS:
 			 * Set needtowakeup to TRUE if current state is SLEEP,
 			 * Set needtowakeup to TRUE if current state is SLEEP,
 			 * otherwise send this command down to firmware
 			 * otherwise send this command down to firmware
 			 * immediately.
 			 * immediately.
@@ -1384,8 +1305,11 @@ int lbs_execute_next_command(struct lbs_private *priv)
 					/* w/ new scheme, it will not reach here.
 					/* w/ new scheme, it will not reach here.
 					   since it is blocked in main_thread. */
 					   since it is blocked in main_thread. */
 					priv->needtowakeup = 1;
 					priv->needtowakeup = 1;
-				} else
-					lbs_ps_wakeup(priv, 0);
+				} else {
+					lbs_set_ps_mode(priv,
+							PS_MODE_ACTION_EXIT_PS,
+							false);
+				}
 
 
 				ret = 0;
 				ret = 0;
 				goto done;
 				goto done;
@@ -1400,7 +1324,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 				       "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
 				       "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
 				       psm->action);
 				       psm->action);
 				if (psm->action !=
 				if (psm->action !=
-				    cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
+				    cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
 					lbs_deb_host(
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
 					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
 					list_del(&cmdnode->list);
 					list_del(&cmdnode->list);
@@ -1460,13 +1384,16 @@ int lbs_execute_next_command(struct lbs_private *priv)
 					lbs_deb_host(
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
 					       "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
 					       " go back to PS_SLEEP");
 					       " go back to PS_SLEEP");
-					lbs_ps_sleep(priv, 0);
+					lbs_set_ps_mode(priv,
+							PS_MODE_ACTION_ENTER_PS,
+							false);
 				}
 				}
 			} else {
 			} else {
 				lbs_deb_host(
 				lbs_deb_host(
 				       "EXEC_NEXT_CMD: cmdpendingq empty, "
 				       "EXEC_NEXT_CMD: cmdpendingq empty, "
 				       "go back to PS_SLEEP");
 				       "go back to PS_SLEEP");
-				lbs_ps_sleep(priv, 0);
+				lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS,
+						false);
 			}
 			}
 		}
 		}
 #endif
 #endif
@@ -1514,43 +1441,6 @@ out:
 	lbs_deb_leave(LBS_DEB_HOST);
 	lbs_deb_leave(LBS_DEB_HOST);
 }
 }
 
 
-void lbs_ps_sleep(struct lbs_private *priv, int wait_option)
-{
-	lbs_deb_enter(LBS_DEB_HOST);
-
-	/*
-	 * PS is currently supported only in Infrastructure mode
-	 * Remove this check if it is to be supported in IBSS mode also
-	 */
-
-	lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
-			      CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL);
-
-	lbs_deb_leave(LBS_DEB_HOST);
-}
-
-/**
- *  @brief This function sends Exit_PS command to firmware.
- *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param wait_option	wait response or not
- *  @return 	   	n/a
- */
-void lbs_ps_wakeup(struct lbs_private *priv, int wait_option)
-{
-	__le32 Localpsmode;
-
-	lbs_deb_enter(LBS_DEB_HOST);
-
-	Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
-
-	lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
-			      CMD_SUBCMD_EXIT_PS,
-			      wait_option, 0, &Localpsmode);
-
-	lbs_deb_leave(LBS_DEB_HOST);
-}
-
 /**
 /**
  *  @brief This function checks condition and prepares to
  *  @brief This function checks condition and prepares to
  *  send sleep confirm command to firmware if ok.
  *  send sleep confirm command to firmware if ok.
@@ -1675,12 +1565,18 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
 		goto done;
 		goto done;
 	}
 	}
 
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		cmdnode = ERR_PTR(-EBUSY);
-		goto done;
+	/* No commands are allowed in Deep Sleep until we toggle the GPIO
+	 * to wake up the card and it has signaled that it's ready.
+	 */
+	if (!priv->is_auto_deep_sleep_enabled) {
+		if (priv->is_deep_sleep) {
+			lbs_deb_cmd("command not allowed in deep sleep\n");
+			cmdnode = ERR_PTR(-EBUSY);
+			goto done;
+		}
 	}
 	}
 
 
-	cmdnode = lbs_get_cmd_ctrl_node(priv);
+	cmdnode = lbs_get_free_cmd_node(priv);
 	if (cmdnode == NULL) {
 	if (cmdnode == NULL) {
 		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
 		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
 
 

+ 16 - 9
drivers/net/wireless/libertas/cmd.h

@@ -3,6 +3,8 @@
 #ifndef _LBS_CMD_H_
 #ifndef _LBS_CMD_H_
 #define _LBS_CMD_H_
 #define _LBS_CMD_H_
 
 
+#include <net/cfg80211.h>
+
 #include "host.h"
 #include "host.h"
 #include "dev.h"
 #include "dev.h"
 
 
@@ -37,11 +39,6 @@ struct cmd_ctrl_node {
 #define lbs_cmd_with_response(priv, cmdnr, cmd)	\
 #define lbs_cmd_with_response(priv, cmdnr, cmd)	\
 	lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
 	lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
 
 
-int lbs_prepare_and_send_command(struct lbs_private *priv,
-	u16 cmd_no,
-	u16 cmd_action,
-	u16 wait_option, u32 cmd_oid, void *pdata_buf);
-
 void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
 void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
 	struct cmd_header *in_cmd, int in_cmd_size);
 	struct cmd_header *in_cmd, int in_cmd_size);
 
 
@@ -92,10 +89,6 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
 				struct sleep_params *sp);
 				struct sleep_params *sp);
 
 
-void lbs_ps_sleep(struct lbs_private *priv, int wait_option);
-
-void lbs_ps_wakeup(struct lbs_private *priv, int wait_option);
-
 void lbs_ps_confirm_sleep(struct lbs_private *priv);
 void lbs_ps_confirm_sleep(struct lbs_private *priv);
 
 
 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);
 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);
@@ -129,4 +122,18 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep);
 
 
 int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep);
 int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep);
 
 
+int lbs_set_monitor_mode(struct lbs_private *priv, int enable);
+
+int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf);
+
+int lbs_set_11d_domain_info(struct lbs_private *priv,
+			    struct regulatory_request *request,
+			    struct ieee80211_supported_band **bands);
+
+int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value);
+
+int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value);
+
+int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block);
+
 #endif /* _LBS_CMD_H */
 #endif /* _LBS_CMD_H */

+ 8 - 171
drivers/net/wireless/libertas/cmdresp.c

@@ -49,171 +49,11 @@ void lbs_mac_event_disconnected(struct lbs_private *priv)
 	if (priv->psstate != PS_STATE_FULL_POWER) {
 	if (priv->psstate != PS_STATE_FULL_POWER) {
 		/* make firmware to exit PS mode */
 		/* make firmware to exit PS mode */
 		lbs_deb_cmd("disconnected, so exit PS mode\n");
 		lbs_deb_cmd("disconnected, so exit PS mode\n");
-		lbs_ps_wakeup(priv, 0);
+		lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
 	}
 	}
 	lbs_deb_leave(LBS_DEB_ASSOC);
 	lbs_deb_leave(LBS_DEB_ASSOC);
 }
 }
 
 
-static int lbs_ret_reg_access(struct lbs_private *priv,
-			       u16 type, struct cmd_ds_command *resp)
-{
-	int ret = 0;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	switch (type) {
-	case CMD_RET(CMD_MAC_REG_ACCESS):
-		{
-			struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;
-
-			priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
-			priv->offsetvalue.value = le32_to_cpu(reg->value);
-			break;
-		}
-
-	case CMD_RET(CMD_BBP_REG_ACCESS):
-		{
-			struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;
-
-			priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
-			priv->offsetvalue.value = reg->value;
-			break;
-		}
-
-	case CMD_RET(CMD_RF_REG_ACCESS):
-		{
-			struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;
-
-			priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
-			priv->offsetvalue.value = reg->value;
-			break;
-		}
-
-	default:
-		ret = -1;
-	}
-
-	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-	return ret;
-}
-
-/**
- *  @brief This function parses countryinfo from AP and download country info to FW
- *  @param priv    pointer to struct lbs_private
- *  @param resp    pointer to command response buffer
- *  @return        0; -1
- */
-static int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
-{
-	struct cmd_ds_802_11d_domain_info *domaininfo =
-			&resp->params.domaininforesp;
-	struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
-	u16 action = le16_to_cpu(domaininfo->action);
-	s16 ret = 0;
-	u8 nr_triplet = 0;
-
-	lbs_deb_enter(LBS_DEB_11D);
-
-	lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp,
-			(int)le16_to_cpu(resp->size));
-
-	nr_triplet = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
-		sizeof(struct ieee80211_country_ie_triplet);
-
-	lbs_deb_11d("domain info resp: nr_triplet %d\n", nr_triplet);
-
-	if (nr_triplet > MRVDRV_MAX_TRIPLET_802_11D) {
-		lbs_deb_11d("invalid number of triplets returned!!\n");
-		return -1;
-	}
-
-	switch (action) {
-	case CMD_ACT_SET:	/*Proc set action */
-		break;
-
-	case CMD_ACT_GET:
-		break;
-	default:
-		lbs_deb_11d("invalid action:%d\n", domaininfo->action);
-		ret = -1;
-		break;
-	}
-
-	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
-	return ret;
-}
-
-static inline int handle_cmd_response(struct lbs_private *priv,
-				      struct cmd_header *cmd_response)
-{
-	struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response;
-	int ret = 0;
-	unsigned long flags;
-	uint16_t respcmd = le16_to_cpu(resp->command);
-
-	lbs_deb_enter(LBS_DEB_HOST);
-
-	switch (respcmd) {
-	case CMD_RET(CMD_MAC_REG_ACCESS):
-	case CMD_RET(CMD_BBP_REG_ACCESS):
-	case CMD_RET(CMD_RF_REG_ACCESS):
-		ret = lbs_ret_reg_access(priv, respcmd, resp);
-		break;
-
-	case CMD_RET(CMD_802_11_SET_AFC):
-	case CMD_RET(CMD_802_11_GET_AFC):
-		spin_lock_irqsave(&priv->driver_lock, flags);
-		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.afc,
-			sizeof(struct cmd_ds_802_11_afc));
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
-
-		break;
-
-	case CMD_RET(CMD_802_11_BEACON_STOP):
-		break;
-
-	case CMD_RET(CMD_802_11_RSSI):
-		ret = lbs_ret_802_11_rssi(priv, resp);
-		break;
-
-	case CMD_RET(CMD_802_11D_DOMAIN_INFO):
-		ret = lbs_ret_802_11d_domain_info(resp);
-		break;
-
-	case CMD_RET(CMD_802_11_TPC_CFG):
-		spin_lock_irqsave(&priv->driver_lock, flags);
-		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg,
-			sizeof(struct cmd_ds_802_11_tpc_cfg));
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
-		break;
-
-	case CMD_RET(CMD_BT_ACCESS):
-		spin_lock_irqsave(&priv->driver_lock, flags);
-		if (priv->cur_cmd->callback_arg)
-			memcpy((void *)priv->cur_cmd->callback_arg,
-			       &resp->params.bt.addr1, 2 * ETH_ALEN);
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
-		break;
-	case CMD_RET(CMD_FWT_ACCESS):
-		spin_lock_irqsave(&priv->driver_lock, flags);
-		if (priv->cur_cmd->callback_arg)
-			memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt,
-			       sizeof(resp->params.fwt));
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
-		break;
-	case CMD_RET(CMD_802_11_BEACON_CTRL):
-		ret = lbs_ret_802_11_bcn_ctrl(priv, resp);
-		break;
-
-	default:
-		lbs_pr_err("CMD_RESP: unknown cmd response 0x%04x\n",
-			   le16_to_cpu(resp->command));
-		break;
-	}
-	lbs_deb_leave(LBS_DEB_HOST);
-	return ret;
-}
-
 int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 {
 {
 	uint16_t respcmd, curcmd;
 	uint16_t respcmd, curcmd;
@@ -272,9 +112,6 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 	del_timer(&priv->command_timer);
 	del_timer(&priv->command_timer);
 	priv->cmd_timed_out = 0;
 	priv->cmd_timed_out = 0;
 
 
-	/* Store the response code to cur_cmd_retcode. */
-	priv->cur_cmd_retcode = result;
-
 	if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
 	if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
 		struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1];
 		struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1];
 		u16 action = le16_to_cpu(psmode->action);
 		u16 action = le16_to_cpu(psmode->action);
@@ -292,9 +129,9 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 			 * lbs_execute_next_command().
 			 * lbs_execute_next_command().
 			 */
 			 */
 			if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR &&
 			if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR &&
-			    action == CMD_SUBCMD_ENTER_PS)
+			    action == PS_MODE_ACTION_ENTER_PS)
 				priv->psmode = LBS802_11POWERMODECAM;
 				priv->psmode = LBS802_11POWERMODECAM;
-		} else if (action == CMD_SUBCMD_ENTER_PS) {
+		} else if (action == PS_MODE_ACTION_ENTER_PS) {
 			priv->needtowakeup = 0;
 			priv->needtowakeup = 0;
 			priv->psstate = PS_STATE_AWAKE;
 			priv->psstate = PS_STATE_AWAKE;
 
 
@@ -309,11 +146,12 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 
 
 				spin_unlock_irqrestore(&priv->driver_lock, flags);
 				spin_unlock_irqrestore(&priv->driver_lock, flags);
 				mutex_unlock(&priv->lock);
 				mutex_unlock(&priv->lock);
-				lbs_ps_wakeup(priv, 0);
+				lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS,
+						false);
 				mutex_lock(&priv->lock);
 				mutex_lock(&priv->lock);
 				spin_lock_irqsave(&priv->driver_lock, flags);
 				spin_lock_irqsave(&priv->driver_lock, flags);
 			}
 			}
-		} else if (action == CMD_SUBCMD_EXIT_PS) {
+		} else if (action == PS_MODE_ACTION_EXIT_PS) {
 			priv->needtowakeup = 0;
 			priv->needtowakeup = 0;
 			priv->psstate = PS_STATE_FULL_POWER;
 			priv->psstate = PS_STATE_FULL_POWER;
 			lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
 			lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
@@ -354,8 +192,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 	if (priv->cur_cmd && priv->cur_cmd->callback) {
 	if (priv->cur_cmd && priv->cur_cmd->callback) {
 		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
 		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
 				resp);
 				resp);
-	} else
-		ret = handle_cmd_response(priv, resp);
+	}
 
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	spin_lock_irqsave(&priv->driver_lock, flags);
 
 
@@ -452,7 +289,7 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
 			 * in lbs_ps_wakeup()
 			 * in lbs_ps_wakeup()
 			 */
 			 */
 			lbs_deb_cmd("waking up ...\n");
 			lbs_deb_cmd("waking up ...\n");
-			lbs_ps_wakeup(priv, 0);
+			lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
 		}
 		}
 		break;
 		break;
 
 

+ 18 - 49
drivers/net/wireless/libertas/debugfs.c

@@ -446,30 +446,24 @@ static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf,
 }
 }
 
 
 
 
-
 static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
 static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
 				  size_t count, loff_t *ppos)
 				  size_t count, loff_t *ppos)
 {
 {
 	struct lbs_private *priv = file->private_data;
 	struct lbs_private *priv = file->private_data;
-	struct lbs_offset_value offval;
 	ssize_t pos = 0;
 	ssize_t pos = 0;
 	int ret;
 	int ret;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
 	char *buf = (char *)addr;
+	u32 val = 0;
+
 	if (!buf)
 	if (!buf)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	offval.offset = priv->mac_offset;
-	offval.value = 0;
-
-	ret = lbs_prepare_and_send_command(priv,
-				CMD_MAC_REG_ACCESS, 0,
-				CMD_OPTION_WAITFORRSP, 0, &offval);
+	ret = lbs_get_reg(priv, CMD_MAC_REG_ACCESS, priv->mac_offset, &val);
 	mdelay(10);
 	mdelay(10);
 	if (!ret) {
 	if (!ret) {
-		pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
-				priv->mac_offset, priv->offsetvalue.value);
-
+		pos = snprintf(buf, len, "MAC[0x%x] = 0x%08x\n",
+				priv->mac_offset, val);
 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 	}
 	}
 	free_page(addr);
 	free_page(addr);
@@ -507,7 +501,6 @@ static ssize_t lbs_wrmac_write(struct file *file,
 	struct lbs_private *priv = file->private_data;
 	struct lbs_private *priv = file->private_data;
 	ssize_t res, buf_size;
 	ssize_t res, buf_size;
 	u32 offset, value;
 	u32 offset, value;
-	struct lbs_offset_value offval;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
 	char *buf = (char *)addr;
 	if (!buf)
 	if (!buf)
@@ -524,11 +517,7 @@ static ssize_t lbs_wrmac_write(struct file *file,
 		goto out_unlock;
 		goto out_unlock;
 	}
 	}
 
 
-	offval.offset = offset;
-	offval.value = value;
-	res = lbs_prepare_and_send_command(priv,
-				CMD_MAC_REG_ACCESS, 1,
-				CMD_OPTION_WAITFORRSP, 0, &offval);
+	res = lbs_set_reg(priv, CMD_MAC_REG_ACCESS, offset, value);
 	mdelay(10);
 	mdelay(10);
 
 
 	if (!res)
 	if (!res)
@@ -542,25 +531,20 @@ static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf,
 				  size_t count, loff_t *ppos)
 				  size_t count, loff_t *ppos)
 {
 {
 	struct lbs_private *priv = file->private_data;
 	struct lbs_private *priv = file->private_data;
-	struct lbs_offset_value offval;
 	ssize_t pos = 0;
 	ssize_t pos = 0;
 	int ret;
 	int ret;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
 	char *buf = (char *)addr;
+	u32 val;
+
 	if (!buf)
 	if (!buf)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	offval.offset = priv->bbp_offset;
-	offval.value = 0;
-
-	ret = lbs_prepare_and_send_command(priv,
-				CMD_BBP_REG_ACCESS, 0,
-				CMD_OPTION_WAITFORRSP, 0, &offval);
+	ret = lbs_get_reg(priv, CMD_BBP_REG_ACCESS, priv->bbp_offset, &val);
 	mdelay(10);
 	mdelay(10);
 	if (!ret) {
 	if (!ret) {
-		pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
-				priv->bbp_offset, priv->offsetvalue.value);
-
+		pos = snprintf(buf, len, "BBP[0x%x] = 0x%08x\n",
+				priv->bbp_offset, val);
 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 	}
 	}
 	free_page(addr);
 	free_page(addr);
@@ -599,7 +583,6 @@ static ssize_t lbs_wrbbp_write(struct file *file,
 	struct lbs_private *priv = file->private_data;
 	struct lbs_private *priv = file->private_data;
 	ssize_t res, buf_size;
 	ssize_t res, buf_size;
 	u32 offset, value;
 	u32 offset, value;
-	struct lbs_offset_value offval;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
 	char *buf = (char *)addr;
 	if (!buf)
 	if (!buf)
@@ -616,11 +599,7 @@ static ssize_t lbs_wrbbp_write(struct file *file,
 		goto out_unlock;
 		goto out_unlock;
 	}
 	}
 
 
-	offval.offset = offset;
-	offval.value = value;
-	res = lbs_prepare_and_send_command(priv,
-				CMD_BBP_REG_ACCESS, 1,
-				CMD_OPTION_WAITFORRSP, 0, &offval);
+	res = lbs_set_reg(priv, CMD_BBP_REG_ACCESS, offset, value);
 	mdelay(10);
 	mdelay(10);
 
 
 	if (!res)
 	if (!res)
@@ -634,25 +613,20 @@ static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf,
 				  size_t count, loff_t *ppos)
 				  size_t count, loff_t *ppos)
 {
 {
 	struct lbs_private *priv = file->private_data;
 	struct lbs_private *priv = file->private_data;
-	struct lbs_offset_value offval;
 	ssize_t pos = 0;
 	ssize_t pos = 0;
 	int ret;
 	int ret;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
 	char *buf = (char *)addr;
+	u32 val;
+
 	if (!buf)
 	if (!buf)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	offval.offset = priv->rf_offset;
-	offval.value = 0;
-
-	ret = lbs_prepare_and_send_command(priv,
-				CMD_RF_REG_ACCESS, 0,
-				CMD_OPTION_WAITFORRSP, 0, &offval);
+	ret = lbs_get_reg(priv, CMD_RF_REG_ACCESS, priv->rf_offset, &val);
 	mdelay(10);
 	mdelay(10);
 	if (!ret) {
 	if (!ret) {
-		pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
-				priv->rf_offset, priv->offsetvalue.value);
-
+		pos = snprintf(buf, len, "RF[0x%x] = 0x%08x\n",
+				priv->rf_offset, val);
 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 	}
 	}
 	free_page(addr);
 	free_page(addr);
@@ -691,7 +665,6 @@ static ssize_t lbs_wrrf_write(struct file *file,
 	struct lbs_private *priv = file->private_data;
 	struct lbs_private *priv = file->private_data;
 	ssize_t res, buf_size;
 	ssize_t res, buf_size;
 	u32 offset, value;
 	u32 offset, value;
-	struct lbs_offset_value offval;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
 	char *buf = (char *)addr;
 	if (!buf)
 	if (!buf)
@@ -708,11 +681,7 @@ static ssize_t lbs_wrrf_write(struct file *file,
 		goto out_unlock;
 		goto out_unlock;
 	}
 	}
 
 
-	offval.offset = offset;
-	offval.value = value;
-	res = lbs_prepare_and_send_command(priv,
-				CMD_RF_REG_ACCESS, 1,
-				CMD_OPTION_WAITFORRSP, 0, &offval);
+	res = lbs_set_reg(priv, CMD_RF_REG_ACCESS, offset, value);
 	mdelay(10);
 	mdelay(10);
 
 
 	if (!res)
 	if (!res)

+ 0 - 5
drivers/net/wireless/libertas/decl.h

@@ -53,9 +53,4 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
 u32 lbs_fw_index_to_data_rate(u8 index);
 u32 lbs_fw_index_to_data_rate(u8 index);
 u8 lbs_data_rate_to_fw_index(u32 rate);
 u8 lbs_data_rate_to_fw_index(u32 rate);
 
 
-int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
-		struct cmd_ds_command *cmd, u16 cmdoption);
-
-int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp);
-
 #endif
 #endif

+ 0 - 18
drivers/net/wireless/libertas/defs.h

@@ -172,11 +172,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 #define MRVDRV_MAX_BSS_DESCRIPTS		16
 #define MRVDRV_MAX_BSS_DESCRIPTS		16
 #define MRVDRV_MAX_REGION_CODE			6
 #define MRVDRV_MAX_REGION_CODE			6
 
 
-#define MRVDRV_IGNORE_MULTIPLE_DTIM		0xfffe
-#define MRVDRV_MIN_MULTIPLE_DTIM		1
-#define MRVDRV_MAX_MULTIPLE_DTIM		5
-#define MRVDRV_DEFAULT_MULTIPLE_DTIM		1
-
 #define MRVDRV_DEFAULT_LISTEN_INTERVAL		10
 #define MRVDRV_DEFAULT_LISTEN_INTERVAL		10
 
 
 #define	MRVDRV_CHANNELS_PER_SCAN		4
 #define	MRVDRV_CHANNELS_PER_SCAN		4
@@ -301,19 +296,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 #define	BAND_G			(0x02)
 #define	BAND_G			(0x02)
 #define ALL_802_11_BANDS	(BAND_B | BAND_G)
 #define ALL_802_11_BANDS	(BAND_B | BAND_G)
 
 
-/** MACRO DEFINITIONS */
-#define CAL_NF(NF)			((s32)(-(s32)(NF)))
-#define CAL_RSSI(SNR, NF) 		((s32)((s32)(SNR) + CAL_NF(NF)))
-#define SCAN_RSSI(RSSI)			(0x100 - ((u8)(RSSI)))
-
-#define DEFAULT_BCN_AVG_FACTOR		8
-#define DEFAULT_DATA_AVG_FACTOR		8
-#define AVG_SCALE			100
-#define CAL_AVG_SNR_NF(AVG, SNRNF, N)         \
-                        (((AVG) == 0) ? ((u16)(SNRNF) * AVG_SCALE) : \
-                        ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \
-                        AVG_SCALE))  / N))
-
 #define MAX_RATES			14
 #define MAX_RATES			14
 
 
 #define	MAX_LEDS			8
 #define	MAX_LEDS			8

+ 0 - 6
drivers/net/wireless/libertas/dev.h

@@ -60,14 +60,10 @@ struct lbs_private {
 	struct dentry *regs_dir;
 	struct dentry *regs_dir;
 	struct dentry *debugfs_regs_files[6];
 	struct dentry *debugfs_regs_files[6];
 
 
-	/** 11D and domain regulatory data */
-	struct lbs_802_11d_domain_reg domain_reg;
-
 	/* Hardware debugging */
 	/* Hardware debugging */
 	u32 mac_offset;
 	u32 mac_offset;
 	u32 bbp_offset;
 	u32 bbp_offset;
 	u32 rf_offset;
 	u32 rf_offset;
-	struct lbs_offset_value offsetvalue;
 
 
 	/* Power management */
 	/* Power management */
 	u16 psmode;
 	u16 psmode;
@@ -115,12 +111,10 @@ struct lbs_private {
 	struct cmd_ctrl_node *cur_cmd;
 	struct cmd_ctrl_node *cur_cmd;
 	struct list_head cmdfreeq;    /* free command buffers */
 	struct list_head cmdfreeq;    /* free command buffers */
 	struct list_head cmdpendingq; /* pending command buffers */
 	struct list_head cmdpendingq; /* pending command buffers */
-	wait_queue_head_t cmd_pending;
 	struct timer_list command_timer;
 	struct timer_list command_timer;
 	int cmd_timed_out;
 	int cmd_timed_out;
 
 
 	/* Command responses sent from the hardware to the driver */
 	/* Command responses sent from the hardware to the driver */
-	int cur_cmd_retcode;
 	u8 resp_idx;
 	u8 resp_idx;
 	u8 resp_buf[2][LBS_UPLD_SIZE];
 	u8 resp_buf[2][LBS_UPLD_SIZE];
 	u32 resp_len[2];
 	u32 resp_len[2];

+ 63 - 79
drivers/net/wireless/libertas/host.h

@@ -94,11 +94,9 @@
 #define CMD_802_11_BEACON_CTRL                  0x00b0
 #define CMD_802_11_BEACON_CTRL                  0x00b0
 
 
 /* For the IEEE Power Save */
 /* For the IEEE Power Save */
-#define CMD_SUBCMD_ENTER_PS                     0x0030
-#define CMD_SUBCMD_EXIT_PS                      0x0031
-#define CMD_SUBCMD_SLEEP_CONFIRMED              0x0034
-#define CMD_SUBCMD_FULL_POWERDOWN               0x0035
-#define CMD_SUBCMD_FULL_POWERUP                 0x0036
+#define PS_MODE_ACTION_ENTER_PS                 0x0030
+#define PS_MODE_ACTION_EXIT_PS                  0x0031
+#define PS_MODE_ACTION_SLEEP_CONFIRMED          0x0034
 
 
 #define CMD_ENABLE_RSN                          0x0001
 #define CMD_ENABLE_RSN                          0x0001
 #define CMD_DISABLE_RSN                         0x0000
 #define CMD_DISABLE_RSN                         0x0000
@@ -163,11 +161,6 @@
 #define CMD_ACT_SET_TX_FIX_RATE                 0x0001
 #define CMD_ACT_SET_TX_FIX_RATE                 0x0001
 #define CMD_ACT_GET_TX_RATE                     0x0002
 #define CMD_ACT_GET_TX_RATE                     0x0002
 
 
-/* Define action or option for CMD_802_11_PS_MODE */
-#define CMD_TYPE_CAM                            0x0000
-#define CMD_TYPE_MAX_PSP                        0x0001
-#define CMD_TYPE_FAST_PSP                       0x0002
-
 /* Options for CMD_802_11_FW_WAKE_METHOD */
 /* Options for CMD_802_11_FW_WAKE_METHOD */
 #define CMD_WAKE_METHOD_UNCHANGED               0x0000
 #define CMD_WAKE_METHOD_UNCHANGED               0x0000
 #define CMD_WAKE_METHOD_COMMAND_INT             0x0001
 #define CMD_WAKE_METHOD_COMMAND_INT             0x0001
@@ -389,30 +382,22 @@ struct lbs_offset_value {
 	u32 value;
 	u32 value;
 } __packed;
 } __packed;
 
 
-#define MRVDRV_MAX_TRIPLET_802_11D              83
-
-#define COUNTRY_CODE_LEN                        3
+#define MAX_11D_TRIPLETS	83
 
 
 struct mrvl_ie_domain_param_set {
 struct mrvl_ie_domain_param_set {
 	struct mrvl_ie_header header;
 	struct mrvl_ie_header header;
 
 
-	u8 countrycode[COUNTRY_CODE_LEN];
-	struct ieee80211_country_ie_triplet triplet[1];
+	u8 country_code[3];
+	struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS];
 } __packed;
 } __packed;
 
 
 struct cmd_ds_802_11d_domain_info {
 struct cmd_ds_802_11d_domain_info {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 action;
 	struct mrvl_ie_domain_param_set domain;
 	struct mrvl_ie_domain_param_set domain;
 } __packed;
 } __packed;
 
 
-struct lbs_802_11d_domain_reg {
-	/** Country code*/
-	u8 country_code[COUNTRY_CODE_LEN];
-	/** No. of triplet*/
-	u8 no_triplet;
-	struct ieee80211_country_ie_triplet triplet[MRVDRV_MAX_TRIPLET_802_11D];
-} __packed;
-
 /*
 /*
  * Define data structure for CMD_GET_HW_SPEC
  * Define data structure for CMD_GET_HW_SPEC
  * This structure defines the response for the GET_HW_SPEC command
  * This structure defines the response for the GET_HW_SPEC command
@@ -575,24 +560,15 @@ struct cmd_ds_802_11_snmp_mib {
 	u8 value[128];
 	u8 value[128];
 } __packed;
 } __packed;
 
 
-struct cmd_ds_mac_reg_access {
-	__le16 action;
-	__le16 offset;
-	__le32 value;
-} __packed;
-
-struct cmd_ds_bbp_reg_access {
-	__le16 action;
-	__le16 offset;
-	u8 value;
-	u8 reserved[3];
-} __packed;
+struct cmd_ds_reg_access {
+	struct cmd_header hdr;
 
 
-struct cmd_ds_rf_reg_access {
 	__le16 action;
 	__le16 action;
 	__le16 offset;
 	__le16 offset;
-	u8 value;
-	u8 reserved[3];
+	union {
+		u8 bbp_rf;  /* for BBP and RF registers */
+		__le32 mac; /* for MAC registers */
+	} value;
 } __packed;
 } __packed;
 
 
 struct cmd_ds_802_11_radio_control {
 struct cmd_ds_802_11_radio_control {
@@ -603,6 +579,8 @@ struct cmd_ds_802_11_radio_control {
 } __packed;
 } __packed;
 
 
 struct cmd_ds_802_11_beacon_control {
 struct cmd_ds_802_11_beacon_control {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 action;
 	__le16 beacon_enable;
 	__le16 beacon_enable;
 	__le16 beacon_period;
 	__le16 beacon_period;
@@ -644,19 +622,19 @@ struct cmd_ds_802_11_rf_channel {
 } __packed;
 } __packed;
 
 
 struct cmd_ds_802_11_rssi {
 struct cmd_ds_802_11_rssi {
-	/* weighting factor */
-	__le16 N;
+	struct cmd_header hdr;
 
 
-	__le16 reserved_0;
-	__le16 reserved_1;
-	__le16 reserved_2;
-} __packed;
+	/* request:  number of beacons (N) to average the SNR and NF over
+	 * response: SNR of most recent beacon
+	 */
+	__le16 n_or_snr;
 
 
-struct cmd_ds_802_11_rssi_rsp {
-	__le16 SNR;
-	__le16 noisefloor;
-	__le16 avgSNR;
-	__le16 avgnoisefloor;
+	/* The following fields are only set in the response.
+	 * In the request these are reserved and should be set to 0.
+	 */
+	__le16 nf;       /* most recent beacon noise floor */
+	__le16 avg_snr;  /* average SNR weighted by N from request */
+	__le16 avg_nf;   /* average noise floor weighted by N from request */
 } __packed;
 } __packed;
 
 
 struct cmd_ds_802_11_mac_address {
 struct cmd_ds_802_11_mac_address {
@@ -675,7 +653,10 @@ struct cmd_ds_802_11_rf_tx_power {
 	s8 minlevel;
 	s8 minlevel;
 } __packed;
 } __packed;
 
 
+/* MONITOR_MODE only exists in OLPC v5 firmware */
 struct cmd_ds_802_11_monitor_mode {
 struct cmd_ds_802_11_monitor_mode {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 action;
 	__le16 mode;
 	__le16 mode;
 } __packed;
 } __packed;
@@ -695,11 +676,35 @@ struct cmd_ds_802_11_fw_wake_method {
 } __packed;
 } __packed;
 
 
 struct cmd_ds_802_11_ps_mode {
 struct cmd_ds_802_11_ps_mode {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 action;
+
+	/* Interval for keepalive in PS mode:
+	 * 0x0000 = don't change
+	 * 0x001E = firmware default
+	 * 0xFFFF = disable
+	 */
 	__le16 nullpktinterval;
 	__le16 nullpktinterval;
+
+	/* Number of DTIM intervals to wake up for:
+	 * 0 = don't change
+	 * 1 = firmware default
+	 * 5 = max
+	 */
 	__le16 multipledtim;
 	__le16 multipledtim;
+
 	__le16 reserved;
 	__le16 reserved;
 	__le16 locallisteninterval;
 	__le16 locallisteninterval;
+
+	/* AdHoc awake period (FW v9+ only):
+	 * 0 = don't change
+	 * 1 = always awake (IEEE standard behavior)
+	 * 2 - 31 = sleep for (n - 1) periods and awake for 1 period
+	 * 32 - 254 = invalid
+	 * 255 = sleep at each ATIM
+	 */
+	__le16 adhoc_awake_period;
 } __packed;
 } __packed;
 
 
 struct cmd_confirm_sleep {
 struct cmd_confirm_sleep {
@@ -882,12 +887,17 @@ struct cmd_ds_802_11_pa_cfg {
 
 
 
 
 struct cmd_ds_802_11_led_ctrl {
 struct cmd_ds_802_11_led_ctrl {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 action;
 	__le16 numled;
 	__le16 numled;
 	u8 data[256];
 	u8 data[256];
 } __packed;
 } __packed;
 
 
+/* Automatic Frequency Control */
 struct cmd_ds_802_11_afc {
 struct cmd_ds_802_11_afc {
+	struct cmd_header hdr;
+
 	__le16 afc_auto;
 	__le16 afc_auto;
 	union {
 	union {
 		struct {
 		struct {
@@ -910,6 +920,8 @@ struct cmd_ds_get_tsf {
 } __packed;
 } __packed;
 
 
 struct cmd_ds_bt_access {
 struct cmd_ds_bt_access {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 action;
 	__le32 id;
 	__le32 id;
 	u8 addr1[ETH_ALEN];
 	u8 addr1[ETH_ALEN];
@@ -917,6 +929,8 @@ struct cmd_ds_bt_access {
 } __packed;
 } __packed;
 
 
 struct cmd_ds_fwt_access {
 struct cmd_ds_fwt_access {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 action;
 	__le32 id;
 	__le32 id;
 	u8 valid;
 	u8 valid;
@@ -955,34 +969,4 @@ struct cmd_ds_mesh_access {
 
 
 /* Number of stats counters returned by the firmware */
 /* Number of stats counters returned by the firmware */
 #define MESH_STATS_NUM 8
 #define MESH_STATS_NUM 8
-
-struct cmd_ds_command {
-	/* command header */
-	__le16 command;
-	__le16 size;
-	__le16 seqnum;
-	__le16 result;
-
-	/* command Body */
-	union {
-		struct cmd_ds_802_11_ps_mode psmode;
-		struct cmd_ds_802_11_monitor_mode monitor;
-		struct cmd_ds_802_11_rssi rssi;
-		struct cmd_ds_802_11_rssi_rsp rssirsp;
-		struct cmd_ds_mac_reg_access macreg;
-		struct cmd_ds_bbp_reg_access bbpreg;
-		struct cmd_ds_rf_reg_access rfreg;
-
-		struct cmd_ds_802_11d_domain_info domaininfo;
-		struct cmd_ds_802_11d_domain_info domaininforesp;
-
-		struct cmd_ds_802_11_tpc_cfg tpccfg;
-		struct cmd_ds_802_11_afc afc;
-		struct cmd_ds_802_11_led_ctrl ledgpio;
-
-		struct cmd_ds_bt_access bt;
-		struct cmd_ds_fwt_access fwt;
-		struct cmd_ds_802_11_beacon_control bcn_ctrl;
-	} params;
-} __packed;
 #endif
 #endif

+ 2 - 2
drivers/net/wireless/libertas/if_usb.c

@@ -433,7 +433,7 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
 
 
 static int if_usb_reset_device(struct if_usb_card *cardp)
 static int if_usb_reset_device(struct if_usb_card *cardp)
 {
 {
-	struct cmd_ds_command *cmd = cardp->ep_out_buf + 4;
+	struct cmd_header *cmd = cardp->ep_out_buf + 4;
 	int ret;
 	int ret;
 
 
 	lbs_deb_enter(LBS_DEB_USB);
 	lbs_deb_enter(LBS_DEB_USB);
@@ -441,7 +441,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
 	*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
 	*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
 
 
 	cmd->command = cpu_to_le16(CMD_802_11_RESET);
 	cmd->command = cpu_to_le16(CMD_802_11_RESET);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_header));
+	cmd->size = cpu_to_le16(sizeof(cmd));
 	cmd->result = cpu_to_le16(0);
 	cmd->result = cpu_to_le16(0);
 	cmd->seqnum = cpu_to_le16(0x5a5a);
 	cmd->seqnum = cpu_to_le16(0x5a5a);
 	usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header));
 	usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header));

+ 11 - 24
drivers/net/wireless/libertas/main.c

@@ -157,12 +157,7 @@ static void lbs_tx_timeout(struct net_device *dev)
 	   to kick it somehow? */
 	   to kick it somehow? */
 	lbs_host_to_card_done(priv);
 	lbs_host_to_card_done(priv);
 
 
-	/* More often than not, this actually happens because the
-	   firmware has crapped itself -- rather than just a very
-	   busy medium. So send a harmless command, and if/when
-	   _that_ times out, we'll kick it in the head. */
-	lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
-				     0, 0, NULL);
+	/* FIXME: reset the card */
 
 
 	lbs_deb_leave(LBS_DEB_TX);
 	lbs_deb_leave(LBS_DEB_TX);
 }
 }
@@ -507,12 +502,6 @@ static int lbs_thread(void *data)
 		if (!priv->dnld_sent && !priv->cur_cmd)
 		if (!priv->dnld_sent && !priv->cur_cmd)
 			lbs_execute_next_command(priv);
 			lbs_execute_next_command(priv);
 
 
-		/* Wake-up command waiters which can't sleep in
-		 * lbs_prepare_and_send_command
-		 */
-		if (!list_empty(&priv->cmdpendingq))
-			wake_up_all(&priv->cmd_pending);
-
 		spin_lock_irq(&priv->driver_lock);
 		spin_lock_irq(&priv->driver_lock);
 		if (!priv->dnld_sent && priv->tx_pending_len > 0) {
 		if (!priv->dnld_sent && priv->tx_pending_len > 0) {
 			int ret = priv->hw_host_to_card(priv, MVMS_DAT,
 			int ret = priv->hw_host_to_card(priv, MVMS_DAT,
@@ -538,7 +527,6 @@ static int lbs_thread(void *data)
 
 
 	del_timer(&priv->command_timer);
 	del_timer(&priv->command_timer);
 	del_timer(&priv->auto_deepsleep_timer);
 	del_timer(&priv->auto_deepsleep_timer);
-	wake_up_all(&priv->cmd_pending);
 
 
 	lbs_deb_leave(LBS_DEB_THREAD);
 	lbs_deb_leave(LBS_DEB_THREAD);
 	return 0;
 	return 0;
@@ -663,7 +651,6 @@ out:
 static void auto_deepsleep_timer_fn(unsigned long data)
 static void auto_deepsleep_timer_fn(unsigned long data)
 {
 {
 	struct lbs_private *priv = (struct lbs_private *)data;
 	struct lbs_private *priv = (struct lbs_private *)data;
-	int ret;
 
 
 	lbs_deb_enter(LBS_DEB_CMD);
 	lbs_deb_enter(LBS_DEB_CMD);
 
 
@@ -671,14 +658,15 @@ static void auto_deepsleep_timer_fn(unsigned long data)
 		priv->is_activity_detected = 0;
 		priv->is_activity_detected = 0;
 	} else {
 	} else {
 		if (priv->is_auto_deep_sleep_enabled &&
 		if (priv->is_auto_deep_sleep_enabled &&
-				(!priv->wakeup_dev_required) &&
-				(priv->connect_status != LBS_CONNECTED)) {
+		    (!priv->wakeup_dev_required) &&
+		    (priv->connect_status != LBS_CONNECTED)) {
+			struct cmd_header cmd;
+
 			lbs_deb_main("Entering auto deep sleep mode...\n");
 			lbs_deb_main("Entering auto deep sleep mode...\n");
-			ret = lbs_prepare_and_send_command(priv,
-					CMD_802_11_DEEP_SLEEP, 0,
-					0, 0, NULL);
-			if (ret)
-				lbs_pr_err("Enter Deep Sleep command failed\n");
+			memset(&cmd, 0, sizeof(cmd));
+			cmd.size = cpu_to_le16(sizeof(cmd));
+			lbs_cmd_async(priv, CMD_802_11_DEEP_SLEEP, &cmd,
+					sizeof(cmd));
 		}
 		}
 	}
 	}
 	mod_timer(&priv->auto_deepsleep_timer , jiffies +
 	mod_timer(&priv->auto_deepsleep_timer , jiffies +
@@ -746,7 +734,6 @@ static int lbs_init_adapter(struct lbs_private *priv)
 	INIT_LIST_HEAD(&priv->cmdpendingq);
 	INIT_LIST_HEAD(&priv->cmdpendingq);
 
 
 	spin_lock_init(&priv->driver_lock);
 	spin_lock_init(&priv->driver_lock);
-	init_waitqueue_head(&priv->cmd_pending);
 
 
 	/* Allocate the command buffers */
 	/* Allocate the command buffers */
 	if (lbs_allocate_cmd_buffer(priv)) {
 	if (lbs_allocate_cmd_buffer(priv)) {
@@ -902,7 +889,7 @@ void lbs_remove_card(struct lbs_private *priv)
 
 
 	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
 	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
 		priv->psmode = LBS802_11POWERMODECAM;
 		priv->psmode = LBS802_11POWERMODECAM;
-		lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
+		lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true);
 	}
 	}
 
 
 	if (priv->is_deep_sleep) {
 	if (priv->is_deep_sleep) {
@@ -1065,7 +1052,7 @@ static int __init lbs_init_module(void)
 	memset(&confirm_sleep, 0, sizeof(confirm_sleep));
 	memset(&confirm_sleep, 0, sizeof(confirm_sleep));
 	confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE);
 	confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE);
 	confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep));
 	confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep));
-	confirm_sleep.action = cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
+	confirm_sleep.action = cpu_to_le16(PS_MODE_ACTION_SLEEP_CONFIRMED);
 	lbs_debugfs_init();
 	lbs_debugfs_init();
 	lbs_deb_leave(LBS_DEB_MAIN);
 	lbs_deb_leave(LBS_DEB_MAIN);
 	return 0;
 	return 0;

+ 170 - 46
drivers/net/wireless/libertas/mesh.c

@@ -455,65 +455,189 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
  * Mesh command handling
  * Mesh command handling
  */
  */
 
 
-int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
-			       u16 cmd_action, void *pdata_buf)
+/**
+ *  @brief Add or delete Mesh Blinding Table entries
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param add  	TRUE to add the entry, FALSE to delete it
+ *  @param addr1        Destination address to blind or unblind
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)
 {
 {
-	struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
-	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+	struct cmd_ds_bt_access cmd;
+	int ret = 0;
 
 
-	cmd->command = cpu_to_le16(CMD_BT_ACCESS);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) +
-		sizeof(struct cmd_header));
-	cmd->result = 0;
-	bt_access->action = cpu_to_le16(cmd_action);
+	lbs_deb_enter(LBS_DEB_CMD);
 
 
-	switch (cmd_action) {
-	case CMD_ACT_BT_ACCESS_ADD:
-		memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
+	BUG_ON(addr1 == NULL);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	memcpy(cmd.addr1, addr1, ETH_ALEN);
+	if (add) {
+		cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_ADD);
 		lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr",
 		lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr",
-			bt_access->addr1, 6);
-		break;
-	case CMD_ACT_BT_ACCESS_DEL:
-		memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
+			addr1, ETH_ALEN);
+	} else {
+		cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_DEL);
 		lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr",
 		lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr",
-			bt_access->addr1, 6);
-		break;
-	case CMD_ACT_BT_ACCESS_LIST:
-		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
-		break;
-	case CMD_ACT_BT_ACCESS_RESET:
-		break;
-	case CMD_ACT_BT_ACCESS_SET_INVERT:
-		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
-		break;
-	case CMD_ACT_BT_ACCESS_GET_INVERT:
-		break;
-	default:
-		break;
+			addr1, ETH_ALEN);
 	}
 	}
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
+
+	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
+
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
 }
 }
 
 
-int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
-			       u16 cmd_action, void *pdata_buf)
+/**
+ *  @brief Reset/clear the mesh blinding table
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_mesh_bt_reset(struct lbs_private *priv)
 {
 {
-	struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
-	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+	struct cmd_ds_bt_access cmd;
+	int ret = 0;
 
 
-	cmd->command = cpu_to_le16(CMD_FWT_ACCESS);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) +
-		sizeof(struct cmd_header));
-	cmd->result = 0;
+	lbs_deb_enter(LBS_DEB_CMD);
 
 
-	if (pdata_buf)
-		memcpy(fwt_access, pdata_buf, sizeof(*fwt_access));
-	else
-		memset(fwt_access, 0, sizeof(*fwt_access));
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_RESET);
 
 
-	fwt_access->action = cpu_to_le16(cmd_action);
+	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
 
 
-	lbs_deb_leave(LBS_DEB_CMD);
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+/**
+ *  @brief Gets the inverted status of the mesh blinding table
+ *
+ *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the
+ *  table, but an inverted table allows *only* traffic from nodes listed in
+ *  the table.
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param invert  	On success, TRUE if the blinding table is inverted,
+ *                        FALSE if it is not inverted
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted)
+{
+	struct cmd_ds_bt_access cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	BUG_ON(inverted == NULL);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_GET_INVERT);
+
+	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
+	if (ret == 0)
+		*inverted = !!cmd.id;
+
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+/**
+ *  @brief Sets the inverted status of the mesh blinding table
+ *
+ *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the
+ *  table, but an inverted table allows *only* traffic from nodes listed in
+ *  the table.
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param invert  	TRUE to invert the blinding table (only traffic from
+ *                         listed nodes allowed), FALSE to return it
+ *                         to normal state (listed nodes ignored)
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
+{
+	struct cmd_ds_bt_access cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT);
+	cmd.id = !!inverted;
+
+	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
+
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+/**
+ *  @brief List an entry in the mesh blinding table
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param id		The ID of the entry to list
+ *  @param addr1	MAC address associated with the table entry
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1)
+{
+	struct cmd_ds_bt_access cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	BUG_ON(addr1 == NULL);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT);
+	cmd.id = cpu_to_le32(id);
+
+	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
+	if (ret == 0)
+		memcpy(addr1, cmd.addr1, sizeof(cmd.addr1));
+
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+/**
+ *  @brief Access the mesh forwarding table
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param cmd_action	The forwarding table action to perform
+ *  @param cmd		The pre-filled FWT_ACCESS command
+ *
+ *  @return 	   	0 on success and 'cmd' will be filled with the
+ *                        firmware's response
+ */
+int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
+			struct cmd_ds_fwt_access *cmd)
+{
+	int ret;
+
+	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+
+	cmd->hdr.command = cpu_to_le16(CMD_FWT_ACCESS);
+	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access));
+	cmd->hdr.result = 0;
+	cmd->action = cpu_to_le16(cmd_action);
+
+	ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd);
+
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
 	return 0;
 	return 0;
 }
 }
 
 

+ 10 - 4
drivers/net/wireless/libertas/mesh.h

@@ -8,6 +8,7 @@
 #include <net/iw_handler.h>
 #include <net/iw_handler.h>
 #include <net/lib80211.h>
 #include <net/lib80211.h>
 
 
+#include "host.h"
 
 
 #ifdef CONFIG_LIBERTAS_MESH
 #ifdef CONFIG_LIBERTAS_MESH
 
 
@@ -51,10 +52,15 @@ struct cmd_ds_command;
 struct cmd_ds_mesh_access;
 struct cmd_ds_mesh_access;
 struct cmd_ds_mesh_config;
 struct cmd_ds_mesh_config;
 
 
-int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
-	u16 cmd_action, void *pdata_buf);
-int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
-	u16 cmd_action, void *pdata_buf);
+int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1);
+int lbs_mesh_bt_reset(struct lbs_private *priv);
+int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted);
+int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted);
+int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1);
+
+int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
+			struct cmd_ds_fwt_access *cmd);
+
 int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
 int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
 		    struct cmd_ds_mesh_access *cmd);
 		    struct cmd_ds_mesh_access *cmd);
 int lbs_mesh_config_send(struct lbs_private *priv,
 int lbs_mesh_config_send(struct lbs_private *priv,

+ 1 - 1
drivers/net/wireless/libertas/tx.c

@@ -180,7 +180,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
 {
 {
 	struct tx_radiotap_hdr *radiotap_hdr;
 	struct tx_radiotap_hdr *radiotap_hdr;
 
 
-	if (!priv->wdev->iftype == NL80211_IFTYPE_MONITOR ||
+	if (priv->wdev->iftype != NL80211_IFTYPE_MONITOR ||
 	    priv->currenttxskb == NULL)
 	    priv->currenttxskb == NULL)
 		return;
 		return;
 
 

+ 3 - 0
drivers/net/wireless/libertas_tf/libertas_tf.h

@@ -253,6 +253,9 @@ struct lbtf_private {
 	u8 fw_ready;
 	u8 fw_ready;
 	u8 surpriseremoved;
 	u8 surpriseremoved;
 	struct sk_buff_head bc_ps_buf;
 	struct sk_buff_head bc_ps_buf;
+
+	/* Most recently reported noise in dBm */
+	s8 noise;
 };
 };
 
 
 /* 802.11-related definitions */
 /* 802.11-related definitions */

+ 18 - 0
drivers/net/wireless/libertas_tf/main.c

@@ -525,6 +525,22 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
 	lbtf_deb_leave(LBTF_DEB_MACOPS);
 	lbtf_deb_leave(LBTF_DEB_MACOPS);
 }
 }
 
 
+static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx,
+				struct survey_info *survey)
+{
+	struct lbtf_private *priv = hw->priv;
+	struct ieee80211_conf *conf = &hw->conf;
+
+	if (idx != 0)
+		return -ENOENT;
+
+	survey->channel = conf->channel;
+	survey->filled = SURVEY_INFO_NOISE_DBM;
+	survey->noise = priv->noise;
+
+	return 0;
+}
+
 static const struct ieee80211_ops lbtf_ops = {
 static const struct ieee80211_ops lbtf_ops = {
 	.tx			= lbtf_op_tx,
 	.tx			= lbtf_op_tx,
 	.start			= lbtf_op_start,
 	.start			= lbtf_op_start,
@@ -535,6 +551,7 @@ static const struct ieee80211_ops lbtf_ops = {
 	.prepare_multicast	= lbtf_op_prepare_multicast,
 	.prepare_multicast	= lbtf_op_prepare_multicast,
 	.configure_filter	= lbtf_op_configure_filter,
 	.configure_filter	= lbtf_op_configure_filter,
 	.bss_info_changed	= lbtf_op_bss_info_changed,
 	.bss_info_changed	= lbtf_op_bss_info_changed,
+	.get_survey		= lbtf_op_get_survey,
 };
 };
 
 
 int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
 int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
@@ -555,6 +572,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
 	stats.freq = priv->cur_freq;
 	stats.freq = priv->cur_freq;
 	stats.band = IEEE80211_BAND_2GHZ;
 	stats.band = IEEE80211_BAND_2GHZ;
 	stats.signal = prxpd->snr;
 	stats.signal = prxpd->snr;
+	priv->noise = prxpd->nf;
 	/* Marvell rate index has a hole at value 4 */
 	/* Marvell rate index has a hole at value 4 */
 	if (prxpd->rx_rate > 4)
 	if (prxpd->rx_rate > 4)
 		--prxpd->rx_rate;
 		--prxpd->rx_rate;

+ 46 - 53
drivers/net/wireless/mac80211_hwsim.c

@@ -486,8 +486,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
 	struct ieee80211_rx_status rx_status;
 	struct ieee80211_rx_status rx_status;
 
 
 	if (data->idle) {
 	if (data->idle) {
-		printk(KERN_DEBUG "%s: Trying to TX when idle - reject\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_debug(hw->wiphy, "trying to tx when idle - reject\n");
 		return false;
 		return false;
 	}
 	}
 
 
@@ -576,7 +575,7 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 static int mac80211_hwsim_start(struct ieee80211_hw *hw)
 static int mac80211_hwsim_start(struct ieee80211_hw *hw)
 {
 {
 	struct mac80211_hwsim_data *data = hw->priv;
 	struct mac80211_hwsim_data *data = hw->priv;
-	printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
+	wiphy_debug(hw->wiphy, "%s\n", __func__);
 	data->started = 1;
 	data->started = 1;
 	return 0;
 	return 0;
 }
 }
@@ -587,16 +586,15 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
 	struct mac80211_hwsim_data *data = hw->priv;
 	struct mac80211_hwsim_data *data = hw->priv;
 	data->started = 0;
 	data->started = 0;
 	del_timer(&data->beacon_timer);
 	del_timer(&data->beacon_timer);
-	printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
+	wiphy_debug(hw->wiphy, "%s\n", __func__);
 }
 }
 
 
 
 
 static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
 static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
 					struct ieee80211_vif *vif)
 					struct ieee80211_vif *vif)
 {
 {
-	printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
-	       wiphy_name(hw->wiphy), __func__, vif->type,
-	       vif->addr);
+	wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
+		    __func__, vif->type, vif->addr);
 	hwsim_set_magic(vif);
 	hwsim_set_magic(vif);
 	return 0;
 	return 0;
 }
 }
@@ -605,9 +603,8 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
 static void mac80211_hwsim_remove_interface(
 static void mac80211_hwsim_remove_interface(
 	struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
 {
-	printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
-	       wiphy_name(hw->wiphy), __func__, vif->type,
-	       vif->addr);
+	wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
+		    __func__, vif->type, vif->addr);
 	hwsim_check_magic(vif);
 	hwsim_check_magic(vif);
 	hwsim_clear_magic(vif);
 	hwsim_clear_magic(vif);
 }
 }
@@ -670,13 +667,14 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
 		[IEEE80211_SMPS_DYNAMIC] = "dynamic",
 		[IEEE80211_SMPS_DYNAMIC] = "dynamic",
 	};
 	};
 
 
-	printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
-	       wiphy_name(hw->wiphy), __func__,
-	       conf->channel->center_freq,
-	       hwsim_chantypes[conf->channel_type],
-	       !!(conf->flags & IEEE80211_CONF_IDLE),
-	       !!(conf->flags & IEEE80211_CONF_PS),
-	       smps_modes[conf->smps_mode]);
+	wiphy_debug(hw->wiphy,
+		    "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
+		    __func__,
+		    conf->channel->center_freq,
+		    hwsim_chantypes[conf->channel_type],
+		    !!(conf->flags & IEEE80211_CONF_IDLE),
+		    !!(conf->flags & IEEE80211_CONF_PS),
+		    smps_modes[conf->smps_mode]);
 
 
 	data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
 	data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
 
 
@@ -696,7 +694,7 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
 {
 {
 	struct mac80211_hwsim_data *data = hw->priv;
 	struct mac80211_hwsim_data *data = hw->priv;
 
 
-	printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
+	wiphy_debug(hw->wiphy, "%s\n", __func__);
 
 
 	data->rx_filter = 0;
 	data->rx_filter = 0;
 	if (*total_flags & FIF_PROMISC_IN_BSS)
 	if (*total_flags & FIF_PROMISC_IN_BSS)
@@ -717,26 +715,23 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
 
 
 	hwsim_check_magic(vif);
 	hwsim_check_magic(vif);
 
 
-	printk(KERN_DEBUG "%s:%s(changed=0x%x)\n",
-	       wiphy_name(hw->wiphy), __func__, changed);
+	wiphy_debug(hw->wiphy, "%s(changed=0x%x)\n", __func__, changed);
 
 
 	if (changed & BSS_CHANGED_BSSID) {
 	if (changed & BSS_CHANGED_BSSID) {
-		printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
-		       wiphy_name(hw->wiphy), __func__,
-		       info->bssid);
+		wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n",
+			    __func__, info->bssid);
 		memcpy(vp->bssid, info->bssid, ETH_ALEN);
 		memcpy(vp->bssid, info->bssid, ETH_ALEN);
 	}
 	}
 
 
 	if (changed & BSS_CHANGED_ASSOC) {
 	if (changed & BSS_CHANGED_ASSOC) {
-		printk(KERN_DEBUG "  %s: ASSOC: assoc=%d aid=%d\n",
-		       wiphy_name(hw->wiphy), info->assoc, info->aid);
+		wiphy_debug(hw->wiphy, "  ASSOC: assoc=%d aid=%d\n",
+			    info->assoc, info->aid);
 		vp->assoc = info->assoc;
 		vp->assoc = info->assoc;
 		vp->aid = info->aid;
 		vp->aid = info->aid;
 	}
 	}
 
 
 	if (changed & BSS_CHANGED_BEACON_INT) {
 	if (changed & BSS_CHANGED_BEACON_INT) {
-		printk(KERN_DEBUG "  %s: BCNINT: %d\n",
-		       wiphy_name(hw->wiphy), info->beacon_int);
+		wiphy_debug(hw->wiphy, "  BCNINT: %d\n", info->beacon_int);
 		data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
 		data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
 		if (WARN_ON(!data->beacon_int))
 		if (WARN_ON(!data->beacon_int))
 			data->beacon_int = 1;
 			data->beacon_int = 1;
@@ -746,31 +741,28 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
 	}
 	}
 
 
 	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
 	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-		printk(KERN_DEBUG "  %s: ERP_CTS_PROT: %d\n",
-		       wiphy_name(hw->wiphy), info->use_cts_prot);
+		wiphy_debug(hw->wiphy, "  ERP_CTS_PROT: %d\n",
+			    info->use_cts_prot);
 	}
 	}
 
 
 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-		printk(KERN_DEBUG "  %s: ERP_PREAMBLE: %d\n",
-		       wiphy_name(hw->wiphy), info->use_short_preamble);
+		wiphy_debug(hw->wiphy, "  ERP_PREAMBLE: %d\n",
+			    info->use_short_preamble);
 	}
 	}
 
 
 	if (changed & BSS_CHANGED_ERP_SLOT) {
 	if (changed & BSS_CHANGED_ERP_SLOT) {
-		printk(KERN_DEBUG "  %s: ERP_SLOT: %d\n",
-		       wiphy_name(hw->wiphy), info->use_short_slot);
+		wiphy_debug(hw->wiphy, "  ERP_SLOT: %d\n", info->use_short_slot);
 	}
 	}
 
 
 	if (changed & BSS_CHANGED_HT) {
 	if (changed & BSS_CHANGED_HT) {
-		printk(KERN_DEBUG "  %s: HT: op_mode=0x%x, chantype=%s\n",
-		       wiphy_name(hw->wiphy),
-		       info->ht_operation_mode,
-		       hwsim_chantypes[info->channel_type]);
+		wiphy_debug(hw->wiphy, "  HT: op_mode=0x%x, chantype=%s\n",
+			    info->ht_operation_mode,
+			    hwsim_chantypes[info->channel_type]);
 	}
 	}
 
 
 	if (changed & BSS_CHANGED_BASIC_RATES) {
 	if (changed & BSS_CHANGED_BASIC_RATES) {
-		printk(KERN_DEBUG "  %s: BASIC_RATES: 0x%llx\n",
-		       wiphy_name(hw->wiphy),
-		       (unsigned long long) info->basic_rates);
+		wiphy_debug(hw->wiphy, "  BASIC_RATES: 0x%llx\n",
+			    (unsigned long long) info->basic_rates);
 	}
 	}
 }
 }
 
 
@@ -824,10 +816,11 @@ static int mac80211_hwsim_conf_tx(
 	struct ieee80211_hw *hw, u16 queue,
 	struct ieee80211_hw *hw, u16 queue,
 	const struct ieee80211_tx_queue_params *params)
 	const struct ieee80211_tx_queue_params *params)
 {
 {
-	printk(KERN_DEBUG "%s:%s (queue=%d txop=%d cw_min=%d cw_max=%d "
-	       "aifs=%d)\n",
-	       wiphy_name(hw->wiphy), __func__, queue,
-	       params->txop, params->cw_min, params->cw_max, params->aifs);
+	wiphy_debug(hw->wiphy,
+		    "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n",
+		    __func__, queue,
+		    params->txop, params->cw_min,
+		    params->cw_max, params->aifs);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -837,8 +830,7 @@ static int mac80211_hwsim_get_survey(
 {
 {
 	struct ieee80211_conf *conf = &hw->conf;
 	struct ieee80211_conf *conf = &hw->conf;
 
 
-	printk(KERN_DEBUG "%s:%s (idx=%d)\n",
-	       wiphy_name(hw->wiphy), __func__, idx);
+	wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx);
 
 
 	if (idx != 0)
 	if (idx != 0)
 		return -ENOENT;
 		return -ENOENT;
@@ -1108,8 +1100,9 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
 	if (!vp->assoc)
 	if (!vp->assoc)
 		return;
 		return;
 
 
-	printk(KERN_DEBUG "%s:%s: send PS-Poll to %pM for aid %d\n",
-	       wiphy_name(data->hw->wiphy), __func__, vp->bssid, vp->aid);
+	wiphy_debug(data->hw->wiphy,
+		    "%s: send PS-Poll to %pM for aid %d\n",
+		    __func__, vp->bssid, vp->aid);
 
 
 	skb = dev_alloc_skb(sizeof(*pspoll));
 	skb = dev_alloc_skb(sizeof(*pspoll));
 	if (!skb)
 	if (!skb)
@@ -1137,8 +1130,9 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
 	if (!vp->assoc)
 	if (!vp->assoc)
 		return;
 		return;
 
 
-	printk(KERN_DEBUG "%s:%s: send data::nullfunc to %pM ps=%d\n",
-	       wiphy_name(data->hw->wiphy), __func__, vp->bssid, ps);
+	wiphy_debug(data->hw->wiphy,
+		    "%s: send data::nullfunc to %pM ps=%d\n",
+		    __func__, vp->bssid, ps);
 
 
 	skb = dev_alloc_skb(sizeof(*hdr));
 	skb = dev_alloc_skb(sizeof(*hdr));
 	if (!skb)
 	if (!skb)
@@ -1473,9 +1467,8 @@ static int __init init_mac80211_hwsim(void)
 			break;
 			break;
 		}
 		}
 
 
-		printk(KERN_DEBUG "%s: hwaddr %pM registered\n",
-		       wiphy_name(hw->wiphy),
-		       hw->wiphy->perm_addr);
+		wiphy_debug(hw->wiphy, "hwaddr %pm registered\n",
+			    hw->wiphy->perm_addr);
 
 
 		data->debugfs = debugfs_create_dir("hwsim",
 		data->debugfs = debugfs_create_dir("hwsim",
 						   hw->wiphy->debugfsdir);
 						   hw->wiphy->debugfsdir);

+ 79 - 75
drivers/net/wireless/mwl8k.c

@@ -86,7 +86,7 @@ struct rxd_ops {
 	void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
 	void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
 	void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
 	void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
 	int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
 	int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
-			   __le16 *qos);
+			   __le16 *qos, s8 *noise);
 };
 };
 
 
 struct mwl8k_device_info {
 struct mwl8k_device_info {
@@ -207,6 +207,9 @@ struct mwl8k_priv {
 
 
 	/* Tasklet to perform RX.  */
 	/* Tasklet to perform RX.  */
 	struct tasklet_struct poll_rx_task;
 	struct tasklet_struct poll_rx_task;
+
+	/* Most recently reported noise in dBm */
+	s8 noise;
 };
 };
 
 
 /* Per interface specific private data */
 /* Per interface specific private data */
@@ -741,7 +744,7 @@ static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len)
 
 
 static int
 static int
 mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
 mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
-			  __le16 *qos)
+			  __le16 *qos, s8 *noise)
 {
 {
 	struct mwl8k_rxd_8366_ap *rxd = _rxd;
 	struct mwl8k_rxd_8366_ap *rxd = _rxd;
 
 
@@ -752,6 +755,7 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
 	memset(status, 0, sizeof(*status));
 	memset(status, 0, sizeof(*status));
 
 
 	status->signal = -rxd->rssi;
 	status->signal = -rxd->rssi;
+	*noise = -rxd->noise_floor;
 
 
 	if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
 	if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
 		status->flag |= RX_FLAG_HT;
 		status->flag |= RX_FLAG_HT;
@@ -839,7 +843,7 @@ static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
 
 
 static int
 static int
 mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
 mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
-		       __le16 *qos)
+		       __le16 *qos, s8 *noise)
 {
 {
 	struct mwl8k_rxd_sta *rxd = _rxd;
 	struct mwl8k_rxd_sta *rxd = _rxd;
 	u16 rate_info;
 	u16 rate_info;
@@ -853,6 +857,7 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
 	memset(status, 0, sizeof(*status));
 	memset(status, 0, sizeof(*status));
 
 
 	status->signal = -rxd->rssi;
 	status->signal = -rxd->rssi;
+	*noise = -rxd->noise_level;
 	status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
 	status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
 	status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
 	status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
 
 
@@ -905,16 +910,14 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
 
 
 	rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
 	rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
 	if (rxq->rxd == NULL) {
 	if (rxq->rxd == NULL) {
-		printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 	memset(rxq->rxd, 0, size);
 	memset(rxq->rxd, 0, size);
 
 
 	rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL);
 	rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL);
 	if (rxq->buf == NULL) {
 	if (rxq->buf == NULL) {
-		printk(KERN_ERR "%s: failed to alloc RX skbuff list\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n");
 		pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
 		pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
@@ -1055,7 +1058,8 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
 
 
 		rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
 		rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
 
 
-		pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos);
+		pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos,
+							&priv->noise);
 		if (pkt_len < 0)
 		if (pkt_len < 0)
 			break;
 			break;
 
 
@@ -1141,16 +1145,14 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
 
 
 	txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma);
 	txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma);
 	if (txq->txd == NULL) {
 	if (txq->txd == NULL) {
-		printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 	memset(txq->txd, 0, size);
 	memset(txq->txd, 0, size);
 
 
 	txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL);
 	txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL);
 	if (txq->skb == NULL) {
 	if (txq->skb == NULL) {
-		printk(KERN_ERR "%s: failed to alloc TX skbuff list\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n");
 		pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
 		pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
@@ -1206,11 +1208,12 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
 				unused++;
 				unused++;
 		}
 		}
 
 
-		printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d "
-		       "fw_owned=%d drv_owned=%d unused=%d\n",
-		       wiphy_name(hw->wiphy), i,
-		       txq->len, txq->head, txq->tail,
-		       fw_owned, drv_owned, unused);
+		wiphy_err(hw->wiphy,
+			  "txq[%d] len=%d head=%d tail=%d "
+			  "fw_owned=%d drv_owned=%d unused=%d\n",
+			  i,
+			  txq->len, txq->head, txq->tail,
+			  fw_owned, drv_owned, unused);
 	}
 	}
 }
 }
 
 
@@ -1254,25 +1257,23 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
 		if (timeout) {
 		if (timeout) {
 			WARN_ON(priv->pending_tx_pkts);
 			WARN_ON(priv->pending_tx_pkts);
 			if (retry) {
 			if (retry) {
-				printk(KERN_NOTICE "%s: tx rings drained\n",
-				       wiphy_name(hw->wiphy));
+				wiphy_notice(hw->wiphy, "tx rings drained\n");
 			}
 			}
 			break;
 			break;
 		}
 		}
 
 
 		if (priv->pending_tx_pkts < oldcount) {
 		if (priv->pending_tx_pkts < oldcount) {
-			printk(KERN_NOTICE "%s: waiting for tx rings "
-			       "to drain (%d -> %d pkts)\n",
-			       wiphy_name(hw->wiphy), oldcount,
-			       priv->pending_tx_pkts);
+			wiphy_notice(hw->wiphy,
+				     "waiting for tx rings to drain (%d -> %d pkts)\n",
+				     oldcount, priv->pending_tx_pkts);
 			retry = 1;
 			retry = 1;
 			continue;
 			continue;
 		}
 		}
 
 
 		priv->tx_wait = NULL;
 		priv->tx_wait = NULL;
 
 
-		printk(KERN_ERR "%s: tx rings stuck for %d ms\n",
-		       wiphy_name(hw->wiphy), MWL8K_TX_WAIT_TIMEOUT_MS);
+		wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n",
+			  MWL8K_TX_WAIT_TIMEOUT_MS);
 		mwl8k_dump_tx_rings(hw);
 		mwl8k_dump_tx_rings(hw);
 
 
 		rc = -ETIMEDOUT;
 		rc = -ETIMEDOUT;
@@ -1423,8 +1424,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 				skb->len, PCI_DMA_TODEVICE);
 				skb->len, PCI_DMA_TODEVICE);
 
 
 	if (pci_dma_mapping_error(priv->pdev, dma)) {
 	if (pci_dma_mapping_error(priv->pdev, dma)) {
-		printk(KERN_DEBUG "%s: failed to dma map skb, "
-		       "dropping TX frame.\n", wiphy_name(hw->wiphy));
+		wiphy_debug(hw->wiphy,
+			    "failed to dma map skb, dropping TX frame.\n");
 		dev_kfree_skb(skb);
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 		return NETDEV_TX_OK;
 	}
 	}
@@ -1572,10 +1573,9 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
 					PCI_DMA_BIDIRECTIONAL);
 					PCI_DMA_BIDIRECTIONAL);
 
 
 	if (!timeout) {
 	if (!timeout) {
-		printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
-		       wiphy_name(hw->wiphy),
-		       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
-		       MWL8K_CMD_TIMEOUT_MS);
+		wiphy_err(hw->wiphy, "command %s timeout after %u ms\n",
+			  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+			  MWL8K_CMD_TIMEOUT_MS);
 		rc = -ETIMEDOUT;
 		rc = -ETIMEDOUT;
 	} else {
 	} else {
 		int ms;
 		int ms;
@@ -1584,15 +1584,14 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
 
 
 		rc = cmd->result ? -EINVAL : 0;
 		rc = cmd->result ? -EINVAL : 0;
 		if (rc)
 		if (rc)
-			printk(KERN_ERR "%s: Command %s error 0x%x\n",
-			       wiphy_name(hw->wiphy),
-			       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
-			       le16_to_cpu(cmd->result));
+			wiphy_err(hw->wiphy, "command %s error 0x%x\n",
+				  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+				  le16_to_cpu(cmd->result));
 		else if (ms > 2000)
 		else if (ms > 2000)
-			printk(KERN_NOTICE "%s: Command %s took %d ms\n",
-			       wiphy_name(hw->wiphy),
-			       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
-			       ms);
+			wiphy_notice(hw->wiphy, "command %s took %d ms\n",
+				     mwl8k_cmd_name(cmd->code,
+						    buf, sizeof(buf)),
+				     ms);
 	}
 	}
 
 
 	return rc;
 	return rc;
@@ -3192,8 +3191,8 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 	int rc;
 	int rc;
 
 
 	if (!priv->radio_on) {
 	if (!priv->radio_on) {
-		printk(KERN_DEBUG "%s: dropped TX frame since radio "
-		       "disabled\n", wiphy_name(hw->wiphy));
+		wiphy_debug(hw->wiphy,
+			    "dropped TX frame since radio disabled\n");
 		dev_kfree_skb(skb);
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 		return NETDEV_TX_OK;
 	}
 	}
@@ -3211,8 +3210,7 @@ static int mwl8k_start(struct ieee80211_hw *hw)
 	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
 	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
 			 IRQF_SHARED, MWL8K_NAME, hw);
 			 IRQF_SHARED, MWL8K_NAME, hw);
 	if (rc) {
 	if (rc) {
-		printk(KERN_ERR "%s: failed to register IRQ handler\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "failed to register irq handler\n");
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
@@ -3299,9 +3297,8 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
 	 * mode.  (Sniffer mode is only used on STA firmware.)
 	 * mode.  (Sniffer mode is only used on STA firmware.)
 	 */
 	 */
 	if (priv->sniffer_enabled) {
 	if (priv->sniffer_enabled) {
-		printk(KERN_INFO "%s: unable to create STA "
-		       "interface due to sniffer mode being enabled\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_info(hw->wiphy,
+			   "unable to create STA interface because sniffer mode is enabled\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -3583,9 +3580,8 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
 	 */
 	 */
 	if (!list_empty(&priv->vif_list)) {
 	if (!list_empty(&priv->vif_list)) {
 		if (net_ratelimit())
 		if (net_ratelimit())
-			printk(KERN_INFO "%s: not enabling sniffer "
-			       "mode because STA interface is active\n",
-			       wiphy_name(hw->wiphy));
+			wiphy_info(hw->wiphy,
+				   "not enabling sniffer mode because STA interface is active\n");
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -3765,6 +3761,22 @@ static int mwl8k_get_stats(struct ieee80211_hw *hw,
 	return mwl8k_cmd_get_stat(hw, stats);
 	return mwl8k_cmd_get_stat(hw, stats);
 }
 }
 
 
+static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
+				struct survey_info *survey)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct ieee80211_conf *conf = &hw->conf;
+
+	if (idx != 0)
+		return -ENOENT;
+
+	survey->channel = conf->channel;
+	survey->filled = SURVEY_INFO_NOISE_DBM;
+	survey->noise = priv->noise;
+
+	return 0;
+}
+
 static int
 static int
 mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		   enum ieee80211_ampdu_mlme_action action,
 		   enum ieee80211_ampdu_mlme_action action,
@@ -3796,6 +3808,7 @@ static const struct ieee80211_ops mwl8k_ops = {
 	.sta_remove		= mwl8k_sta_remove,
 	.sta_remove		= mwl8k_sta_remove,
 	.conf_tx		= mwl8k_conf_tx,
 	.conf_tx		= mwl8k_conf_tx,
 	.get_stats		= mwl8k_get_stats,
 	.get_stats		= mwl8k_get_stats,
+	.get_survey		= mwl8k_get_survey,
 	.ampdu_action		= mwl8k_ampdu_action,
 	.ampdu_action		= mwl8k_ampdu_action,
 };
 };
 
 
@@ -3913,8 +3926,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 
 
 	priv->sram = pci_iomap(pdev, 0, 0x10000);
 	priv->sram = pci_iomap(pdev, 0, 0x10000);
 	if (priv->sram == NULL) {
 	if (priv->sram == NULL) {
-		printk(KERN_ERR "%s: Cannot map device SRAM\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "cannot map device sram\n");
 		goto err_iounmap;
 		goto err_iounmap;
 	}
 	}
 
 
@@ -3926,8 +3938,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	if (priv->regs == NULL) {
 	if (priv->regs == NULL) {
 		priv->regs = pci_iomap(pdev, 2, 0x10000);
 		priv->regs = pci_iomap(pdev, 2, 0x10000);
 		if (priv->regs == NULL) {
 		if (priv->regs == NULL) {
-			printk(KERN_ERR "%s: Cannot map device registers\n",
-			       wiphy_name(hw->wiphy));
+			wiphy_err(hw->wiphy, "cannot map device registers\n");
 			goto err_iounmap;
 			goto err_iounmap;
 		}
 		}
 	}
 	}
@@ -3939,16 +3950,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	/* Ask userland hotplug daemon for the device firmware */
 	/* Ask userland hotplug daemon for the device firmware */
 	rc = mwl8k_request_firmware(priv);
 	rc = mwl8k_request_firmware(priv);
 	if (rc) {
 	if (rc) {
-		printk(KERN_ERR "%s: Firmware files not found\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "firmware files not found\n");
 		goto err_stop_firmware;
 		goto err_stop_firmware;
 	}
 	}
 
 
 	/* Load firmware into hardware */
 	/* Load firmware into hardware */
 	rc = mwl8k_load_firmware(hw);
 	rc = mwl8k_load_firmware(hw);
 	if (rc) {
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot start firmware\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "cannot start firmware\n");
 		goto err_stop_firmware;
 		goto err_stop_firmware;
 	}
 	}
 
 
@@ -3959,9 +3968,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	if (priv->ap_fw) {
 	if (priv->ap_fw) {
 		priv->rxd_ops = priv->device_info->ap_rxd_ops;
 		priv->rxd_ops = priv->device_info->ap_rxd_ops;
 		if (priv->rxd_ops == NULL) {
 		if (priv->rxd_ops == NULL) {
-			printk(KERN_ERR "%s: Driver does not have AP "
-			       "firmware image support for this hardware\n",
-			       wiphy_name(hw->wiphy));
+			wiphy_err(hw->wiphy,
+				  "Driver does not have AP firmware image support for this hardware\n");
 			goto err_stop_firmware;
 			goto err_stop_firmware;
 		}
 		}
 	} else {
 	} else {
@@ -4039,8 +4047,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
 	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
 			 IRQF_SHARED, MWL8K_NAME, hw);
 			 IRQF_SHARED, MWL8K_NAME, hw);
 	if (rc) {
 	if (rc) {
-		printk(KERN_ERR "%s: failed to register IRQ handler\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "failed to register irq handler\n");
 		goto err_free_queues;
 		goto err_free_queues;
 	}
 	}
 
 
@@ -4060,8 +4067,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 		rc = mwl8k_cmd_get_hw_spec_sta(hw);
 		rc = mwl8k_cmd_get_hw_spec_sta(hw);
 	}
 	}
 	if (rc) {
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot initialise firmware\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "cannot initialise firmware\n");
 		goto err_free_irq;
 		goto err_free_irq;
 	}
 	}
 
 
@@ -4075,15 +4081,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	/* Turn radio off */
 	/* Turn radio off */
 	rc = mwl8k_cmd_radio_disable(hw);
 	rc = mwl8k_cmd_radio_disable(hw);
 	if (rc) {
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "cannot disable\n");
 		goto err_free_irq;
 		goto err_free_irq;
 	}
 	}
 
 
 	/* Clear MAC address */
 	/* Clear MAC address */
 	rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
 	rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
 	if (rc) {
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot clear MAC address\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "cannot clear mac address\n");
 		goto err_free_irq;
 		goto err_free_irq;
 	}
 	}
 
 
@@ -4093,17 +4098,16 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 
 
 	rc = ieee80211_register_hw(hw);
 	rc = ieee80211_register_hw(hw);
 	if (rc) {
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot register device\n",
-		       wiphy_name(hw->wiphy));
+		wiphy_err(hw->wiphy, "cannot register device\n");
 		goto err_free_queues;
 		goto err_free_queues;
 	}
 	}
 
 
-	printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
-	       wiphy_name(hw->wiphy), priv->device_info->part_name,
-	       priv->hw_rev, hw->wiphy->perm_addr,
-	       priv->ap_fw ? "AP" : "STA",
-	       (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
-	       (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
+	wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n",
+		   priv->device_info->part_name,
+		   priv->hw_rev, hw->wiphy->perm_addr,
+		   priv->ap_fw ? "AP" : "STA",
+		   (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
+		   (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
 
 
 	return 0;
 	return 0;
 
 

+ 2 - 3
drivers/net/wireless/orinoco/cfg.c

@@ -117,9 +117,8 @@ static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev,
 
 
 	case NL80211_IFTYPE_MONITOR:
 	case NL80211_IFTYPE_MONITOR:
 		if (priv->broken_monitor && !force_monitor) {
 		if (priv->broken_monitor && !force_monitor) {
-			printk(KERN_WARNING "%s: Monitor mode support is "
-			       "buggy in this firmware, not enabling\n",
-			       wiphy_name(wiphy));
+			wiphy_warn(wiphy,
+				   "Monitor mode support is buggy in this firmware, not enabling\n");
 			err = -EINVAL;
 			err = -EINVAL;
 		}
 		}
 		break;
 		break;

+ 35 - 41
drivers/net/wireless/p54/eeprom.c

@@ -149,16 +149,15 @@ static int p54_generate_band(struct ieee80211_hw *dev,
 			continue;
 			continue;
 
 
 		if (list->channels[i].data != CHAN_HAS_ALL) {
 		if (list->channels[i].data != CHAN_HAS_ALL) {
-			printk(KERN_ERR "%s:%s%s%s is/are missing for "
-					"channel:%d [%d MHz].\n",
-			       wiphy_name(dev->wiphy),
-			       (list->channels[i].data & CHAN_HAS_CAL ? "" :
-				" [iqauto calibration data]"),
-			       (list->channels[i].data & CHAN_HAS_LIMIT ? "" :
-				" [output power limits]"),
-			       (list->channels[i].data & CHAN_HAS_CURVE ? "" :
-				" [curve data]"),
-			       list->channels[i].index, list->channels[i].freq);
+			wiphy_err(dev->wiphy,
+				  "%s%s%s is/are missing for channel:%d [%d MHz].\n",
+				  (list->channels[i].data & CHAN_HAS_CAL ? "" :
+				   " [iqauto calibration data]"),
+				  (list->channels[i].data & CHAN_HAS_LIMIT ? "" :
+				   " [output power limits]"),
+				  (list->channels[i].data & CHAN_HAS_CURVE ? "" :
+				   " [curve data]"),
+				  list->channels[i].index, list->channels[i].freq);
 			continue;
 			continue;
 		}
 		}
 
 
@@ -168,9 +167,8 @@ static int p54_generate_band(struct ieee80211_hw *dev,
 	}
 	}
 
 
 	if (j == 0) {
 	if (j == 0) {
-		printk(KERN_ERR "%s: Disabling totally damaged %s band.\n",
-		       wiphy_name(dev->wiphy), (band == IEEE80211_BAND_2GHZ) ?
-		       "2 GHz" : "5 GHz");
+		wiphy_err(dev->wiphy, "disabling totally damaged %d GHz band\n",
+			  (band == IEEE80211_BAND_2GHZ) ? 2 : 5);
 
 
 		ret = -ENODATA;
 		ret = -ENODATA;
 		goto err_out;
 		goto err_out;
@@ -244,9 +242,9 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
 
 
 	if ((priv->iq_autocal_len != priv->curve_data->entries) ||
 	if ((priv->iq_autocal_len != priv->curve_data->entries) ||
 	    (priv->iq_autocal_len != priv->output_limit->entries))
 	    (priv->iq_autocal_len != priv->output_limit->entries))
-		printk(KERN_ERR "%s: Unsupported or damaged EEPROM detected. "
-				"You may not be able to use all channels.\n",
-				wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy,
+			  "Unsupported or damaged EEPROM detected. "
+			  "You may not be able to use all channels.\n");
 
 
 	max_channel_num = max_t(unsigned int, priv->output_limit->entries,
 	max_channel_num = max_t(unsigned int, priv->output_limit->entries,
 				priv->iq_autocal_len);
 				priv->iq_autocal_len);
@@ -419,15 +417,14 @@ static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
 	int i;
 	int i;
 
 
 	if (len != (entry_size * num_entries)) {
 	if (len != (entry_size * num_entries)) {
-		printk(KERN_ERR "%s: unknown rssi calibration data packing "
-				 " type:(%x) len:%d.\n",
-		       wiphy_name(dev->wiphy), type, len);
+		wiphy_err(dev->wiphy,
+			  "unknown rssi calibration data packing type:(%x) len:%d.\n",
+			  type, len);
 
 
 		print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
 		print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
 				     data, len);
 				     data, len);
 
 
-		printk(KERN_ERR "%s: please report this issue.\n",
-			wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "please report this issue.\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -445,15 +442,14 @@ static void p54_parse_default_country(struct ieee80211_hw *dev,
 	struct pda_country *country;
 	struct pda_country *country;
 
 
 	if (len != sizeof(*country)) {
 	if (len != sizeof(*country)) {
-		printk(KERN_ERR "%s: found possible invalid default country "
-				"eeprom entry. (entry size: %d)\n",
-		       wiphy_name(dev->wiphy), len);
+		wiphy_err(dev->wiphy,
+			  "found possible invalid default country eeprom entry. (entry size: %d)\n",
+			  len);
 
 
 		print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
 		print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
 				     data, len);
 				     data, len);
 
 
-		printk(KERN_ERR "%s: please report this issue.\n",
-			wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "please report this issue.\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -478,8 +474,8 @@ static int p54_convert_output_limits(struct ieee80211_hw *dev,
 		return -EINVAL;
 		return -EINVAL;
 
 
 	if (data[0] != 0) {
 	if (data[0] != 0) {
-		printk(KERN_ERR "%s: unknown output power db revision:%x\n",
-		       wiphy_name(dev->wiphy), data[0]);
+		wiphy_err(dev->wiphy, "unknown output power db revision:%x\n",
+			  data[0]);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -587,10 +583,9 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 				err = p54_convert_rev1(dev, curve_data);
 				err = p54_convert_rev1(dev, curve_data);
 				break;
 				break;
 			default:
 			default:
-				printk(KERN_ERR "%s: unknown curve data "
-						"revision %d\n",
-						wiphy_name(dev->wiphy),
-						curve_data->cal_method_rev);
+				wiphy_err(dev->wiphy,
+					  "unknown curve data revision %d\n",
+					  curve_data->cal_method_rev);
 				err = -ENODEV;
 				err = -ENODEV;
 				break;
 				break;
 			}
 			}
@@ -672,8 +667,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 
 
 	if (!synth || !priv->iq_autocal || !priv->output_limit ||
 	if (!synth || !priv->iq_autocal || !priv->output_limit ||
 	    !priv->curve_data) {
 	    !priv->curve_data) {
-		printk(KERN_ERR "%s: not all required entries found in eeprom!\n",
-			wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy,
+			  "not all required entries found in eeprom!\n");
 		err = -EINVAL;
 		err = -EINVAL;
 		goto err;
 		goto err;
 	}
 	}
@@ -699,15 +694,15 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
 	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
 		u8 perm_addr[ETH_ALEN];
 		u8 perm_addr[ETH_ALEN];
 
 
-		printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n",
-			wiphy_name(dev->wiphy));
+		wiphy_warn(dev->wiphy,
+			   "invalid hwaddr! using randomly generated mac addr\n");
 		random_ether_addr(perm_addr);
 		random_ether_addr(perm_addr);
 		SET_IEEE80211_PERM_ADDR(dev, perm_addr);
 		SET_IEEE80211_PERM_ADDR(dev, perm_addr);
 	}
 	}
 
 
-	printk(KERN_INFO "%s: hwaddr %pM, MAC:isl38%02x RF:%s\n",
-		wiphy_name(dev->wiphy),	dev->wiphy->perm_addr, priv->version,
-		p54_rf_chips[priv->rxhw]);
+	wiphy_info(dev->wiphy, "hwaddr %pm, mac:isl38%02x rf:%s\n",
+		   dev->wiphy->perm_addr, priv->version,
+		   p54_rf_chips[priv->rxhw]);
 
 
 	return 0;
 	return 0;
 
 
@@ -719,8 +714,7 @@ err:
 	priv->output_limit = NULL;
 	priv->output_limit = NULL;
 	priv->curve_data = NULL;
 	priv->curve_data = NULL;
 
 
-	printk(KERN_ERR "%s: eeprom parse failed!\n",
-		wiphy_name(dev->wiphy));
+	wiphy_err(dev->wiphy, "eeprom parse failed!\n");
 	return err;
 	return err;
 }
 }
 EXPORT_SYMBOL_GPL(p54_parse_eeprom);
 EXPORT_SYMBOL_GPL(p54_parse_eeprom);

+ 26 - 27
drivers/net/wireless/p54/fwio.c

@@ -62,16 +62,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
 			case FW_LM20:
 			case FW_LM20:
 			case FW_LM87: {
 			case FW_LM87: {
 				char *iftype = (char *)bootrec->data;
 				char *iftype = (char *)bootrec->data;
-				printk(KERN_INFO "%s: p54 detected a LM%c%c "
-						 "firmware\n",
-					wiphy_name(priv->hw->wiphy),
-					iftype[2], iftype[3]);
+				wiphy_info(priv->hw->wiphy,
+					   "p54 detected a LM%c%c firmware\n",
+					   iftype[2], iftype[3]);
 				break;
 				break;
 				}
 				}
 			case FW_FMAC:
 			case FW_FMAC:
 			default:
 			default:
-				printk(KERN_ERR "%s: unsupported firmware\n",
-					wiphy_name(priv->hw->wiphy));
+				wiphy_err(priv->hw->wiphy,
+					  "unsupported firmware\n");
 				return -ENODEV;
 				return -ENODEV;
 			}
 			}
 			break;
 			break;
@@ -125,15 +124,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
 	}
 	}
 
 
 	if (fw_version)
 	if (fw_version)
-		printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n",
-			wiphy_name(priv->hw->wiphy), fw_version,
-			priv->fw_var >> 8, priv->fw_var & 0xff);
+		wiphy_info(priv->hw->wiphy,
+			   "fw rev %s - softmac protocol %x.%x\n",
+			   fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
 
 
 	if (priv->fw_var < 0x500)
 	if (priv->fw_var < 0x500)
-		printk(KERN_INFO "%s: you are using an obsolete firmware. "
-		       "visit http://wireless.kernel.org/en/users/Drivers/p54 "
-		       "and grab one for \"kernel >= 2.6.28\"!\n",
-			wiphy_name(priv->hw->wiphy));
+		wiphy_info(priv->hw->wiphy,
+			   "you are using an obsolete firmware. "
+			   "visit http://wireless.kernel.org/en/users/Drivers/p54 "
+			   "and grab one for \"kernel >= 2.6.28\"!\n");
 
 
 	if (priv->fw_var >= 0x300) {
 	if (priv->fw_var >= 0x300) {
 		/* Firmware supports QoS, use it! */
 		/* Firmware supports QoS, use it! */
@@ -152,13 +151,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
 		priv->hw->queues = P54_QUEUE_AC_NUM;
 		priv->hw->queues = P54_QUEUE_AC_NUM;
 	}
 	}
 
 
-	printk(KERN_INFO "%s: cryptographic accelerator "
-	       "WEP:%s, TKIP:%s, CCMP:%s\n", wiphy_name(priv->hw->wiphy),
-		(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" :
-		"no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP |
-		BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no",
-		(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ?
-		"YES" : "no");
+	wiphy_info(priv->hw->wiphy,
+		   "cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n",
+		   (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no",
+		   (priv->privacy_caps &
+		    (BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL))
+		   ? "YES" : "no",
+		   (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)
+		   ? "YES" : "no");
 
 
 	if (priv->rx_keycache_size) {
 	if (priv->rx_keycache_size) {
 		/*
 		/*
@@ -247,8 +247,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf,
 
 
 	if (!wait_for_completion_interruptible_timeout(
 	if (!wait_for_completion_interruptible_timeout(
 	     &priv->eeprom_comp, HZ)) {
 	     &priv->eeprom_comp, HZ)) {
-		printk(KERN_ERR "%s: device does not respond!\n",
-		       wiphy_name(priv->hw->wiphy));
+		wiphy_err(priv->hw->wiphy, "device does not respond!\n");
 		ret = -EBUSY;
 		ret = -EBUSY;
 	}
 	}
 	priv->eeprom = NULL;
 	priv->eeprom = NULL;
@@ -523,9 +522,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
 	return 0;
 	return 0;
 
 
 err:
 err:
-	printk(KERN_ERR "%s: frequency change to channel %d failed.\n",
-	       wiphy_name(priv->hw->wiphy), ieee80211_frequency_to_channel(
-	       priv->hw->conf.channel->center_freq));
+	wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n",
+		  ieee80211_frequency_to_channel(
+			  priv->hw->conf.channel->center_freq));
 
 
 	dev_kfree_skb_any(skb);
 	dev_kfree_skb_any(skb);
 	return -EINVAL;
 	return -EINVAL;
@@ -676,8 +675,8 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len,
 		break;
 		break;
 
 
 	default:
 	default:
-		printk(KERN_ERR "%s: invalid cryptographic algorithm: %d\n",
-		       wiphy_name(priv->hw->wiphy), algo);
+		wiphy_err(priv->hw->wiphy,
+			  "invalid cryptographic algorithm: %d\n", algo);
 		dev_kfree_skb(skb);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}

+ 4 - 4
drivers/net/wireless/p54/led.c

@@ -57,8 +57,8 @@ static void p54_update_leds(struct work_struct *work)
 
 
 	err = p54_set_leds(priv);
 	err = p54_set_leds(priv);
 	if (err && net_ratelimit())
 	if (err && net_ratelimit())
-		printk(KERN_ERR "%s: failed to update LEDs (%d).\n",
-			wiphy_name(priv->hw->wiphy), err);
+		wiphy_err(priv->hw->wiphy,
+			  "failed to update leds (%d).\n", err);
 
 
 	if (rerun)
 	if (rerun)
 		ieee80211_queue_delayed_work(priv->hw, &priv->led_work,
 		ieee80211_queue_delayed_work(priv->hw, &priv->led_work,
@@ -102,8 +102,8 @@ static int p54_register_led(struct p54_common *priv,
 
 
 	err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev);
 	err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev);
 	if (err)
 	if (err)
-		printk(KERN_ERR "%s: Failed to register %s LED.\n",
-			wiphy_name(priv->hw->wiphy), name);
+		wiphy_err(priv->hw->wiphy,
+			  "failed to register %s led.\n", name);
 	else
 	else
 		led->registered = 1;
 		led->registered = 1;
 
 

+ 17 - 0
drivers/net/wireless/p54/main.c

@@ -507,6 +507,22 @@ out_unlock:
 	return ret;
 	return ret;
 }
 }
 
 
+static int p54_get_survey(struct ieee80211_hw *dev, int idx,
+				struct survey_info *survey)
+{
+	struct p54_common *priv = dev->priv;
+	struct ieee80211_conf *conf = &dev->conf;
+
+	if (idx != 0)
+		return -ENOENT;
+
+	survey->channel = conf->channel;
+	survey->filled = SURVEY_INFO_NOISE_DBM;
+	survey->noise = clamp_t(s8, priv->noise, -128, 127);
+
+	return 0;
+}
+
 static const struct ieee80211_ops p54_ops = {
 static const struct ieee80211_ops p54_ops = {
 	.tx			= p54_tx_80211,
 	.tx			= p54_tx_80211,
 	.start			= p54_start,
 	.start			= p54_start,
@@ -523,6 +539,7 @@ static const struct ieee80211_ops p54_ops = {
 	.configure_filter	= p54_configure_filter,
 	.configure_filter	= p54_configure_filter,
 	.conf_tx		= p54_conf_tx,
 	.conf_tx		= p54_conf_tx,
 	.get_stats		= p54_get_stats,
 	.get_stats		= p54_get_stats,
+	.get_survey		= p54_get_survey,
 };
 };
 
 
 struct ieee80211_hw *p54_init_common(size_t priv_data_len)
 struct ieee80211_hw *p54_init_common(size_t priv_data_len)

+ 1 - 2
drivers/net/wireless/p54/p54pci.c

@@ -466,8 +466,7 @@ static int p54p_open(struct ieee80211_hw *dev)
 	P54P_READ(dev_int);
 	P54P_READ(dev_int);
 
 
 	if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
 	if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
-		printk(KERN_ERR "%s: Cannot boot firmware!\n",
-		       wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "cannot boot firmware!\n");
 		p54p_stop(dev);
 		p54p_stop(dev);
 		return -ETIMEDOUT;
 		return -ETIMEDOUT;
 	}
 	}

+ 19 - 17
drivers/net/wireless/p54/txrx.c

@@ -38,8 +38,8 @@ static void p54_dump_tx_queue(struct p54_common *priv)
 	u32 largest_hole = 0, free;
 	u32 largest_hole = 0, free;
 
 
 	spin_lock_irqsave(&priv->tx_queue.lock, flags);
 	spin_lock_irqsave(&priv->tx_queue.lock, flags);
-	printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) ---\n",
-	       wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue));
+	wiphy_debug(priv->hw->wiphy, "/ --- tx queue dump (%d entries) ---\n",
+		    skb_queue_len(&priv->tx_queue));
 
 
 	prev_addr = priv->rx_start;
 	prev_addr = priv->rx_start;
 	skb_queue_walk(&priv->tx_queue, skb) {
 	skb_queue_walk(&priv->tx_queue, skb) {
@@ -48,21 +48,23 @@ static void p54_dump_tx_queue(struct p54_common *priv)
 		hdr = (void *) skb->data;
 		hdr = (void *) skb->data;
 
 
 		free = range->start_addr - prev_addr;
 		free = range->start_addr - prev_addr;
-		printk(KERN_DEBUG "%s: | [%02d] => [skb:%p skb_len:0x%04x "
-		       "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} "
-		       "mem:{start:%04x end:%04x, free:%d}]\n",
-		       wiphy_name(priv->hw->wiphy), i++, skb, skb->len,
-		       le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len),
-		       le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type),
-		       range->start_addr, range->end_addr, free);
+		wiphy_debug(priv->hw->wiphy,
+			    "| [%02d] => [skb:%p skb_len:0x%04x "
+			    "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} "
+			    "mem:{start:%04x end:%04x, free:%d}]\n",
+			    i++, skb, skb->len,
+			    le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len),
+			    le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type),
+			    range->start_addr, range->end_addr, free);
 
 
 		prev_addr = range->end_addr;
 		prev_addr = range->end_addr;
 		largest_hole = max(largest_hole, free);
 		largest_hole = max(largest_hole, free);
 	}
 	}
 	free = priv->rx_end - prev_addr;
 	free = priv->rx_end - prev_addr;
 	largest_hole = max(largest_hole, free);
 	largest_hole = max(largest_hole, free);
-	printk(KERN_DEBUG "%s: \\ --- [free: %d], largest free block: %d ---\n",
-	       wiphy_name(priv->hw->wiphy), free, largest_hole);
+	wiphy_debug(priv->hw->wiphy,
+		    "\\ --- [free: %d], largest free block: %d ---\n",
+		    free, largest_hole);
 	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 }
 }
 #endif /* P54_MM_DEBUG */
 #endif /* P54_MM_DEBUG */
@@ -538,8 +540,7 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
 	case P54_TRAP_BEACON_TX:
 	case P54_TRAP_BEACON_TX:
 		break;
 		break;
 	case P54_TRAP_RADAR:
 	case P54_TRAP_RADAR:
-		printk(KERN_INFO "%s: radar (freq:%d MHz)\n",
-			wiphy_name(priv->hw->wiphy), freq);
+		wiphy_info(priv->hw->wiphy, "radar (freq:%d mhz)\n", freq);
 		break;
 		break;
 	case P54_TRAP_NO_BEACON:
 	case P54_TRAP_NO_BEACON:
 		if (priv->vif)
 		if (priv->vif)
@@ -558,8 +559,8 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
 		wiphy_rfkill_set_hw_state(priv->hw->wiphy, false);
 		wiphy_rfkill_set_hw_state(priv->hw->wiphy, false);
 		break;
 		break;
 	default:
 	default:
-		printk(KERN_INFO "%s: received event:%x freq:%d\n",
-		       wiphy_name(priv->hw->wiphy), event, freq);
+		wiphy_info(priv->hw->wiphy, "received event:%x freq:%d\n",
+			   event, freq);
 		break;
 		break;
 	}
 	}
 }
 }
@@ -584,8 +585,9 @@ static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb)
 		p54_rx_eeprom_readback(priv, skb);
 		p54_rx_eeprom_readback(priv, skb);
 		break;
 		break;
 	default:
 	default:
-		printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n",
-		       wiphy_name(priv->hw->wiphy), le16_to_cpu(hdr->type));
+		wiphy_debug(priv->hw->wiphy,
+			    "not handling 0x%02x type control frame\n",
+			    le16_to_cpu(hdr->type));
 		break;
 		break;
 	}
 	}
 	return 0;
 	return 0;

+ 10 - 1
drivers/net/wireless/rt2x00/rt2500usb.c

@@ -350,6 +350,14 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
 	enum cipher curr_cipher;
 	enum cipher curr_cipher;
 
 
 	if (crypto->cmd == SET_KEY) {
 	if (crypto->cmd == SET_KEY) {
+		/*
+		 * Disallow to set WEP key other than with index 0,
+		 * it is known that not work at least on some hardware.
+		 * SW crypto will be used in that case.
+		 */
+		if (key->alg == ALG_WEP && key->keyidx != 0)
+			return -EOPNOTSUPP;
+
 		/*
 		/*
 		 * Pairwise key will always be entry 0, but this
 		 * Pairwise key will always be entry 0, but this
 		 * could collide with a shared key on the same
 		 * could collide with a shared key on the same
@@ -376,7 +384,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
 		if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher)
 		if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher)
 			return -EOPNOTSUPP;
 			return -EOPNOTSUPP;
 
 
-		rt2500usb_register_multiwrite(rt2x00dev, reg,
+		rt2500usb_register_multiwrite(rt2x00dev, KEY_ENTRY(key->hw_key_idx),
 					      crypto->key, sizeof(crypto->key));
 					      crypto->key, sizeof(crypto->key));
 
 
 		/*
 		/*
@@ -817,6 +825,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2500usb_register_write(rt2x00dev, MAC_CSR8, reg);
 	rt2500usb_register_write(rt2x00dev, MAC_CSR8, reg);
 
 
 	rt2500usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
 	rt2500usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+	rt2x00_set_field16(&reg, TXRX_CSR0_ALGORITHM, CIPHER_NONE);
 	rt2x00_set_field16(&reg, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER);
 	rt2x00_set_field16(&reg, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER);
 	rt2x00_set_field16(&reg, TXRX_CSR0_KEY_ID, 0);
 	rt2x00_set_field16(&reg, TXRX_CSR0_KEY_ID, 0);
 	rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 	rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg);

+ 13 - 6
drivers/net/wireless/rt2x00/rt2x00mac.c

@@ -273,17 +273,24 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 	mutex_init(&intf->beacon_skb_mutex);
 	mutex_init(&intf->beacon_skb_mutex);
 	intf->beacon = entry;
 	intf->beacon = entry;
 
 
-	if (vif->type == NL80211_IFTYPE_AP)
-		memcpy(&intf->bssid, vif->addr, ETH_ALEN);
-	memcpy(&intf->mac, vif->addr, ETH_ALEN);
-
 	/*
 	/*
 	 * The MAC adddress must be configured after the device
 	 * The MAC adddress must be configured after the device
 	 * has been initialized. Otherwise the device can reset
 	 * has been initialized. Otherwise the device can reset
 	 * the MAC registers.
 	 * the MAC registers.
+	 * The BSSID address must only be configured in AP mode,
+	 * however we should not send an empty BSSID address for
+	 * STA interfaces at this time, since this can cause
+	 * invalid behavior in the device.
 	 */
 	 */
-	rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
-			      intf->mac, intf->bssid);
+	memcpy(&intf->mac, vif->addr, ETH_ALEN);
+	if (vif->type == NL80211_IFTYPE_AP) {
+		memcpy(&intf->bssid, vif->addr, ETH_ALEN);
+		rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
+				      intf->mac, intf->bssid);
+	} else {
+		rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
+				      intf->mac, NULL);
+	}
 
 
 	/*
 	/*
 	 * Some filters depend on the current working mode. We can force
 	 * Some filters depend on the current working mode. We can force

+ 18 - 17
drivers/net/wireless/rtl818x/rtl8180_dev.c

@@ -103,7 +103,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
 {
 {
 	struct rtl8180_priv *priv = dev->priv;
 	struct rtl8180_priv *priv = dev->priv;
 	unsigned int count = 32;
 	unsigned int count = 32;
-	u8 signal;
+	u8 signal, agc, sq;
 
 
 	while (count--) {
 	while (count--) {
 		struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
 		struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
@@ -132,12 +132,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
 
 
 			rx_status.antenna = (flags2 >> 15) & 1;
 			rx_status.antenna = (flags2 >> 15) & 1;
 			rx_status.rate_idx = (flags >> 20) & 0xF;
 			rx_status.rate_idx = (flags >> 20) & 0xF;
-			/* TODO: improve signal/rssi reporting for !rtl8185 */
-			signal = (flags2 >> 17) & 0x7F;
-			if (rx_status.rate_idx > 3)
-				signal = 90 - clamp_t(u8, signal, 25, 90);
-			else
-				signal = 95 - clamp_t(u8, signal, 30, 95);
+			agc = (flags2 >> 17) & 0x7F;
+			if (priv->r8185) {
+				if (rx_status.rate_idx > 3)
+					signal = 90 - clamp_t(u8, agc, 25, 90);
+				else
+					signal = 95 - clamp_t(u8, agc, 30, 95);
+			} else {
+				sq = flags2 & 0xff;
+				signal = priv->rf->calc_rssi(agc, sq);
+			}
 			rx_status.signal = signal;
 			rx_status.signal = signal;
 			rx_status.freq = dev->conf.channel->center_freq;
 			rx_status.freq = dev->conf.channel->center_freq;
 			rx_status.band = dev->conf.channel->band;
 			rx_status.band = dev->conf.channel->band;
@@ -357,7 +361,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
 
 
 	/* check success of reset */
 	/* check success of reset */
 	if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
 	if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
-		printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "reset timeout!\n");
 		return -ETIMEDOUT;
 		return -ETIMEDOUT;
 	}
 	}
 
 
@@ -441,8 +445,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
 					     &priv->rx_ring_dma);
 					     &priv->rx_ring_dma);
 
 
 	if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
 	if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
-		printk(KERN_ERR "%s: Cannot allocate RX ring\n",
-		       wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "cannot allocate rx ring\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
@@ -499,8 +502,8 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev,
 
 
 	ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
 	ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
 	if (!ring || (unsigned long)ring & 0xFF) {
 	if (!ring || (unsigned long)ring & 0xFF) {
-		printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n",
-		       wiphy_name(dev->wiphy), prio);
+		wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n",
+			  prio);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
@@ -565,8 +568,7 @@ static int rtl8180_start(struct ieee80211_hw *dev)
 	ret = request_irq(priv->pdev->irq, rtl8180_interrupt,
 	ret = request_irq(priv->pdev->irq, rtl8180_interrupt,
 			  IRQF_SHARED, KBUILD_MODNAME, dev);
 			  IRQF_SHARED, KBUILD_MODNAME, dev);
 	if (ret) {
 	if (ret) {
-		printk(KERN_ERR "%s: failed to register IRQ handler\n",
-		       wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "failed to register irq handler\n");
 		goto err_free_rings;
 		goto err_free_rings;
 	}
 	}
 
 
@@ -1103,9 +1105,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
 		goto err_iounmap;
 		goto err_iounmap;
 	}
 	}
 
 
-	printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n",
-	       wiphy_name(dev->wiphy), mac_addr,
-	       chip_name, priv->rf->name);
+	wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n",
+		   mac_addr, chip_name, priv->rf->name);
 
 
 	return 0;
 	return 0;
 
 

+ 11 - 1
drivers/net/wireless/rtl818x/rtl8180_grf5101.c

@@ -69,6 +69,15 @@ static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan)
 	rtl8180_write_phy(dev, 0x10, ant);
 	rtl8180_write_phy(dev, 0x10, ant);
 }
 }
 
 
+static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq)
+{
+	if (agc > 60)
+		return 65;
+
+	/* TODO(?): just return agc (or agc + 5) to avoid mult / div */
+	return 65 * agc / 60;
+}
+
 static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
 static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
 				   struct ieee80211_conf *conf)
 				   struct ieee80211_conf *conf)
 {
 {
@@ -176,5 +185,6 @@ const struct rtl818x_rf_ops grf5101_rf_ops = {
 	.name		= "GCT",
 	.name		= "GCT",
 	.init		= grf5101_rf_init,
 	.init		= grf5101_rf_init,
 	.stop		= grf5101_rf_stop,
 	.stop		= grf5101_rf_stop,
-	.set_chan	= grf5101_rf_set_channel
+	.set_chan	= grf5101_rf_set_channel,
+	.calc_rssi	= grf5101_rf_calc_rssi,
 };
 };

+ 18 - 1
drivers/net/wireless/rtl818x/rtl8180_max2820.c

@@ -74,6 +74,22 @@ static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
 	rtl8180_write_phy(dev, 0x10, ant);
 	rtl8180_write_phy(dev, 0x10, ant);
 }
 }
 
 
+static u8 max2820_rf_calc_rssi(u8 agc, u8 sq)
+{
+	bool odd;
+
+	odd = !!(agc & 1);
+
+	agc >>= 1;
+	if (odd)
+		agc += 76;
+	else
+		agc += 66;
+
+	/* TODO: change addends above to avoid mult / div below */
+	return 65 * agc / 100;
+}
+
 static void max2820_rf_set_channel(struct ieee80211_hw *dev,
 static void max2820_rf_set_channel(struct ieee80211_hw *dev,
 				   struct ieee80211_conf *conf)
 				   struct ieee80211_conf *conf)
 {
 {
@@ -148,5 +164,6 @@ const struct rtl818x_rf_ops max2820_rf_ops = {
 	.name		= "Maxim",
 	.name		= "Maxim",
 	.init		= max2820_rf_init,
 	.init		= max2820_rf_init,
 	.stop		= max2820_rf_stop,
 	.stop		= max2820_rf_stop,
-	.set_chan	= max2820_rf_set_channel
+	.set_chan	= max2820_rf_set_channel,
+	.calc_rssi	= max2820_rf_calc_rssi,
 };
 };

+ 4 - 1
drivers/net/wireless/rtl818x/rtl8180_rtl8225.c

@@ -50,7 +50,10 @@ static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
 	udelay(10);
 	udelay(10);
 
 
 	for (i = 15; i >= 0; i--) {
 	for (i = 15; i >= 0; i--) {
-		u16 reg = reg80 | !!(bangdata & (1 << i));
+		u16 reg = reg80;
+
+		if (bangdata & (1 << i))
+			reg |= 1;
 
 
 		if (i & 1)
 		if (i & 1)
 			rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
 			rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);

+ 27 - 1
drivers/net/wireless/rtl818x/rtl8180_sa2400.c

@@ -76,6 +76,31 @@ static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
 
 
 }
 }
 
 
+static u8 sa2400_rf_rssi_map[] = {
+	0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
+	0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50,
+	0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f,
+	0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b,
+	0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17,
+	0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13,
+	0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f,
+	0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
+	0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
+	0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02,
+};
+
+static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq)
+{
+	if (sq == 0x80)
+		return 1;
+
+	if (sq > 78)
+		return 32;
+
+	/* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */
+	return 65 * sa2400_rf_rssi_map[sq] / 100;
+}
+
 static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
 static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
 				  struct ieee80211_conf *conf)
 				  struct ieee80211_conf *conf)
 {
 {
@@ -198,5 +223,6 @@ const struct rtl818x_rf_ops sa2400_rf_ops = {
 	.name		= "Philips",
 	.name		= "Philips",
 	.init		= sa2400_rf_init,
 	.init		= sa2400_rf_init,
 	.stop		= sa2400_rf_stop,
 	.stop		= sa2400_rf_stop,
-	.set_chan	= sa2400_rf_set_channel
+	.set_chan	= sa2400_rf_set_channel,
+	.calc_rssi	= sa2400_rf_calc_rssi,
 };
 };

+ 5 - 6
drivers/net/wireless/rtl818x/rtl8187_dev.c

@@ -573,7 +573,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
 	} while (--i);
 	} while (--i);
 
 
 	if (!i) {
 	if (!i) {
-		printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "reset timeout!\n");
 		return -ETIMEDOUT;
 		return -ETIMEDOUT;
 	}
 	}
 
 
@@ -589,8 +589,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
 	} while (--i);
 	} while (--i);
 
 
 	if (!i) {
 	if (!i) {
-		printk(KERN_ERR "%s: eeprom reset timeout!\n",
-		       wiphy_name(dev->wiphy));
+		wiphy_err(dev->wiphy, "eeprom reset timeout!\n");
 		return -ETIMEDOUT;
 		return -ETIMEDOUT;
 	}
 	}
 
 
@@ -1527,9 +1526,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
 	mutex_init(&priv->conf_mutex);
 	mutex_init(&priv->conf_mutex);
 	skb_queue_head_init(&priv->b_tx_status.queue);
 	skb_queue_head_init(&priv->b_tx_status.queue);
 
 
-	printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
-	       wiphy_name(dev->wiphy), mac_addr,
-	       chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask);
+	wiphy_info(dev->wiphy, "hwaddr %pm, %s v%d + %s, rfkill mask %d\n",
+		   mac_addr, chip_name, priv->asic_rev, priv->rf->name,
+		   priv->rfkill_mask);
 
 
 #ifdef CONFIG_RTL8187_LEDS
 #ifdef CONFIG_RTL8187_LEDS
 	eeprom_93cx6_read(&eeprom, 0x3F, &reg);
 	eeprom_93cx6_read(&eeprom, 0x3F, &reg);

+ 4 - 4
drivers/net/wireless/rtl818x/rtl8187_rtl8225.c

@@ -366,8 +366,8 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
 		rtl8225_write(dev, 0x02, 0x044d);
 		rtl8225_write(dev, 0x02, 0x044d);
 		msleep(100);
 		msleep(100);
 		if (!(rtl8225_read(dev, 6) & (1 << 7)))
 		if (!(rtl8225_read(dev, 6) & (1 << 7)))
-			printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
-			       wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
+			wiphy_warn(dev->wiphy, "rf calibration failed! %x\n",
+				   rtl8225_read(dev, 6));
 	}
 	}
 
 
 	rtl8225_write(dev, 0x0, 0x127);
 	rtl8225_write(dev, 0x0, 0x127);
@@ -735,8 +735,8 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
 		rtl8225_write(dev, 0x02, 0x044D);
 		rtl8225_write(dev, 0x02, 0x044D);
 		msleep(100);
 		msleep(100);
 		if (!(rtl8225_read(dev, 6) & (1 << 7)))
 		if (!(rtl8225_read(dev, 6) & (1 << 7)))
-			printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
-			       wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
+			wiphy_warn(dev->wiphy, "rf calibration failed! %x\n",
+				   rtl8225_read(dev, 6));
 	}
 	}
 
 
 	msleep(200);
 	msleep(200);

+ 1 - 0
drivers/net/wireless/rtl818x/rtl818x.h

@@ -193,6 +193,7 @@ struct rtl818x_rf_ops {
 	void (*stop)(struct ieee80211_hw *);
 	void (*stop)(struct ieee80211_hw *);
 	void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
 	void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
 	void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *);
 	void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *);
+	u8 (*calc_rssi)(u8 agc, u8 sq);
 };
 };
 
 
 /**
 /**

+ 3 - 0
drivers/net/wireless/wl12xx/wl1251.h

@@ -381,6 +381,9 @@ struct wl1251 {
 
 
 	u32 chip_id;
 	u32 chip_id;
 	char fw_ver[21];
 	char fw_ver[21];
+
+	/* Most recently reported noise in dBm */
+	s8 noise;
 };
 };
 
 
 int wl1251_plt_start(struct wl1251 *wl);
 int wl1251_plt_start(struct wl1251 *wl);

+ 4 - 4
drivers/net/wireless/wl12xx/wl1251_boot.c

@@ -225,7 +225,7 @@ static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag)
 int wl1251_boot_run_firmware(struct wl1251 *wl)
 int wl1251_boot_run_firmware(struct wl1251 *wl)
 {
 {
 	int loop, ret;
 	int loop, ret;
-	u32 chip_id, interrupt;
+	u32 chip_id, acx_intr;
 
 
 	wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
 	wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
 
 
@@ -242,15 +242,15 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
 	loop = 0;
 	loop = 0;
 	while (loop++ < INIT_LOOP) {
 	while (loop++ < INIT_LOOP) {
 		udelay(INIT_LOOP_DELAY);
 		udelay(INIT_LOOP_DELAY);
-		interrupt = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+		acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
 
 
-		if (interrupt == 0xffffffff) {
+		if (acx_intr == 0xffffffff) {
 			wl1251_error("error reading hardware complete "
 			wl1251_error("error reading hardware complete "
 				     "init indication");
 				     "init indication");
 			return -EIO;
 			return -EIO;
 		}
 		}
 		/* check that ACX_INTR_INIT_COMPLETE is enabled */
 		/* check that ACX_INTR_INIT_COMPLETE is enabled */
-		else if (interrupt & WL1251_ACX_INTR_INIT_COMPLETE) {
+		else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) {
 			wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
 			wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
 					   WL1251_ACX_INTR_INIT_COMPLETE);
 					   WL1251_ACX_INTR_INIT_COMPLETE);
 			break;
 			break;

+ 6 - 6
drivers/net/wireless/wl12xx/wl1251_cmd.h

@@ -175,8 +175,8 @@ struct cmd_read_write_memory {
 #define WL1251_SCAN_NUM_PROBES 3
 #define WL1251_SCAN_NUM_PROBES 3
 
 
 struct wl1251_scan_parameters {
 struct wl1251_scan_parameters {
-	u32 rx_config_options;
-	u32 rx_filter_options;
+	__le32 rx_config_options;
+	__le32 rx_filter_options;
 
 
 	/*
 	/*
 	 * Scan options:
 	 * Scan options:
@@ -186,7 +186,7 @@ struct wl1251_scan_parameters {
 	 * bit 2: voice mode, 0 for normal scan.
 	 * bit 2: voice mode, 0 for normal scan.
 	 * bit 3: scan priority, 1 for high priority.
 	 * bit 3: scan priority, 1 for high priority.
 	 */
 	 */
-	u16 scan_options;
+	__le16 scan_options;
 
 
 	/* Number of channels to scan */
 	/* Number of channels to scan */
 	u8 num_channels;
 	u8 num_channels;
@@ -195,7 +195,7 @@ struct wl1251_scan_parameters {
 	u8 num_probe_requests;
 	u8 num_probe_requests;
 
 
 	/* Rate and modulation for probe requests */
 	/* Rate and modulation for probe requests */
-	u16 tx_rate;
+	__le16 tx_rate;
 
 
 	u8 tid_trigger;
 	u8 tid_trigger;
 	u8 ssid_len;
 	u8 ssid_len;
@@ -204,8 +204,8 @@ struct wl1251_scan_parameters {
 } __packed;
 } __packed;
 
 
 struct wl1251_scan_ch_parameters {
 struct wl1251_scan_ch_parameters {
-	u32 min_duration; /* in TU */
-	u32 max_duration; /* in TU */
+	__le32 min_duration; /* in TU */
+	__le32 max_duration; /* in TU */
 	u32 bssid_lsb;
 	u32 bssid_lsb;
 	u16 bssid_msb;
 	u16 bssid_msb;
 
 

Some files were not shown because too many files changed in this diff