瀏覽代碼

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

David S. Miller 14 年之前
父節點
當前提交
25009a1ae1
共有 100 個文件被更改,包括 2142 次插入1281 次删除
  1. 3 2
      Documentation/DocBook/80211.tmpl
  2. 3 1
      drivers/bcma/main.c
  3. 3 0
      drivers/bcma/sprom.c
  4. 5 0
      drivers/bluetooth/ath3k.c
  5. 11 1
      drivers/bluetooth/btusb.c
  6. 2 2
      drivers/net/wireless/ath/ath5k/ahb.c
  7. 7 2
      drivers/net/wireless/ath/ath5k/ani.c
  8. 85 82
      drivers/net/wireless/ath/ath5k/ath5k.h
  9. 12 12
      drivers/net/wireless/ath/ath5k/attach.c
  10. 37 34
      drivers/net/wireless/ath/ath5k/base.c
  11. 5 6
      drivers/net/wireless/ath/ath5k/base.h
  12. 2 2
      drivers/net/wireless/ath/ath5k/caps.c
  13. 107 100
      drivers/net/wireless/ath/ath5k/debug.c
  14. 2 2
      drivers/net/wireless/ath/ath5k/desc.h
  15. 4 4
      drivers/net/wireless/ath/ath5k/dma.c
  16. 24 22
      drivers/net/wireless/ath/ath5k/eeprom.c
  17. 6 6
      drivers/net/wireless/ath/ath5k/eeprom.h
  18. 7 7
      drivers/net/wireless/ath/ath5k/initvals.c
  19. 4 4
      drivers/net/wireless/ath/ath5k/led.c
  20. 2 2
      drivers/net/wireless/ath/ath5k/mac80211-ops.c
  21. 7 7
      drivers/net/wireless/ath/ath5k/pci.c
  22. 8 8
      drivers/net/wireless/ath/ath5k/pcu.c
  23. 53 47
      drivers/net/wireless/ath/ath5k/phy.c
  24. 45 44
      drivers/net/wireless/ath/ath5k/reg.h
  25. 30 15
      drivers/net/wireless/ath/ath5k/reset.c
  26. 2 2
      drivers/net/wireless/ath/ath5k/rfbuffer.h
  27. 4 4
      drivers/net/wireless/ath/ath5k/rfgain.h
  28. 6 4
      drivers/net/wireless/ath/ath5k/sysfs.c
  29. 6 9
      drivers/net/wireless/ath/ath5k/trace.h
  30. 5 0
      drivers/net/wireless/ath/ath9k/ar5008_phy.c
  31. 0 39
      drivers/net/wireless/ath/ath9k/ar9002_hw.c
  32. 19 15
      drivers/net/wireless/ath/ath9k/ar9002_phy.c
  33. 4 6
      drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
  34. 1 2
      drivers/net/wireless/ath/ath9k/ar9003_mac.c
  35. 30 0
      drivers/net/wireless/ath/ath9k/ar9003_paprd.c
  36. 1 0
      drivers/net/wireless/ath/ath9k/htc_drv_init.c
  37. 7 2
      drivers/net/wireless/ath/ath9k/htc_drv_main.c
  38. 78 16
      drivers/net/wireless/ath/ath9k/hw.c
  39. 2 2
      drivers/net/wireless/ath/ath9k/hw.h
  40. 1 2
      drivers/net/wireless/ath/ath9k/mac.c
  41. 24 26
      drivers/net/wireless/ath/ath9k/rc.c
  42. 0 5
      drivers/net/wireless/ath/ath9k/reg.h
  43. 8 0
      drivers/net/wireless/ath/carl9170/main.c
  44. 14 0
      drivers/net/wireless/b43/Kconfig
  45. 1 0
      drivers/net/wireless/b43/Makefile
  46. 0 1
      drivers/net/wireless/b43/b43.h
  47. 129 0
      drivers/net/wireless/b43/bus.c
  48. 8 0
      drivers/net/wireless/b43/bus.h
  49. 8 1
      drivers/net/wireless/b43/dma.c
  50. 284 77
      drivers/net/wireless/b43/main.c
  51. 6 0
      drivers/net/wireless/b43/phy_common.c
  52. 3 0
      drivers/net/wireless/b43/phy_common.h
  53. 10 2
      drivers/net/wireless/b43/phy_ht.c
  54. 52 0
      drivers/net/wireless/b43/phy_lcn.c
  55. 14 0
      drivers/net/wireless/b43/phy_lcn.h
  56. 52 10
      drivers/net/wireless/b43/phy_n.c
  57. 34 0
      drivers/net/wireless/b43/tables_phy_lcn.c
  58. 6 0
      drivers/net/wireless/b43/tables_phy_lcn.h
  59. 1 2
      drivers/net/wireless/b43/xmit.c
  60. 1 2
      drivers/net/wireless/iwlegacy/iwl-4965-tx.c
  61. 1 1
      drivers/net/wireless/iwlegacy/iwl4965-base.c
  62. 2 11
      drivers/net/wireless/iwlwifi/iwl-1000.c
  63. 25 16
      drivers/net/wireless/iwlwifi/iwl-2000.c
  64. 6 23
      drivers/net/wireless/iwlwifi/iwl-5000.c
  65. 6 24
      drivers/net/wireless/iwlwifi/iwl-6000.c
  66. 8 7
      drivers/net/wireless/iwlwifi/iwl-agn-calib.c
  67. 0 7
      drivers/net/wireless/iwlwifi/iwl-agn-calib.h
  68. 3 3
      drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
  69. 9 106
      drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
  70. 127 35
      drivers/net/wireless/iwlwifi/iwl-agn-lib.c
  71. 18 10
      drivers/net/wireless/iwlwifi/iwl-agn-rs.c
  72. 47 8
      drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
  73. 2 1
      drivers/net/wireless/iwlwifi/iwl-agn-sta.c
  74. 23 86
      drivers/net/wireless/iwlwifi/iwl-agn-tx.c
  75. 9 5
      drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
  76. 51 11
      drivers/net/wireless/iwlwifi/iwl-agn.c
  77. 10 9
      drivers/net/wireless/iwlwifi/iwl-agn.h
  78. 3 0
      drivers/net/wireless/iwlwifi/iwl-commands.h
  79. 10 13
      drivers/net/wireless/iwlwifi/iwl-core.c
  80. 4 46
      drivers/net/wireless/iwlwifi/iwl-core.h
  81. 39 10
      drivers/net/wireless/iwlwifi/iwl-dev.h
  82. 1 6
      drivers/net/wireless/iwlwifi/iwl-eeprom.c
  83. 0 1
      drivers/net/wireless/iwlwifi/iwl-eeprom.h
  84. 1 1
      drivers/net/wireless/iwlwifi/iwl-fh.h
  85. 5 27
      drivers/net/wireless/iwlwifi/iwl-hcmd.c
  86. 2 1
      drivers/net/wireless/iwlwifi/iwl-led.c
  87. 5 4
      drivers/net/wireless/iwlwifi/iwl-power.c
  88. 44 3
      drivers/net/wireless/iwlwifi/iwl-rx.c
  89. 4 6
      drivers/net/wireless/iwlwifi/iwl-scan.c
  90. 16 4
      drivers/net/wireless/iwlwifi/iwl-sta.c
  91. 47 4
      drivers/net/wireless/iwlwifi/iwl-sv-open.c
  92. 12 2
      drivers/net/wireless/iwlwifi/iwl-testmode.h
  93. 151 3
      drivers/net/wireless/iwlwifi/iwl-trans.c
  94. 41 0
      drivers/net/wireless/iwlwifi/iwl-trans.h
  95. 12 127
      drivers/net/wireless/iwlwifi/iwl-tx.c
  96. 33 13
      drivers/net/wireless/libertas/cmd.c
  97. 2 0
      drivers/net/wireless/libertas/cmd.h
  98. 3 3
      drivers/net/wireless/libertas/cmdresp.c
  99. 10 2
      drivers/net/wireless/libertas/main.c
  100. 55 1
      drivers/net/wireless/mwifiex/cfg80211.c

+ 3 - 2
Documentation/DocBook/80211.tmpl

@@ -402,8 +402,9 @@
 !Finclude/net/mac80211.h set_key_cmd
 !Finclude/net/mac80211.h ieee80211_key_conf
 !Finclude/net/mac80211.h ieee80211_key_flags
-!Finclude/net/mac80211.h ieee80211_tkip_key_type
-!Finclude/net/mac80211.h ieee80211_get_tkip_key
+!Finclude/net/mac80211.h ieee80211_get_tkip_p1k
+!Finclude/net/mac80211.h ieee80211_get_tkip_p1k_iv
+!Finclude/net/mac80211.h ieee80211_get_tkip_p2k
 !Finclude/net/mac80211.h ieee80211_key_removed
       </chapter>
 

+ 3 - 1
drivers/bcma/main.c

@@ -149,7 +149,9 @@ int bcma_bus_register(struct bcma_bus *bus)
 
 	/* Try to get SPROM */
 	err = bcma_sprom_get(bus);
-	if (err) {
+	if (err == -ENOENT) {
+		pr_err("No SPROM available\n");
+	} else if (err) {
 		pr_err("Failed to get SPROM: %d\n", err);
 		return -ENOENT;
 	}

+ 3 - 0
drivers/bcma/sprom.c

@@ -143,6 +143,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
 	if (!bus->drv_cc.core)
 		return -EOPNOTSUPP;
 
+	if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
+		return -ENOENT;
+
 	sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
 			GFP_KERNEL);
 	if (!sprom)

+ 5 - 0
drivers/bluetooth/ath3k.c

@@ -375,6 +375,11 @@ static int ath3k_probe(struct usb_interface *intf,
 
 	/* load patch and sysconfig files for AR3012 */
 	if (id->driver_info & BTUSB_ATH3012) {
+
+		/* New firmware with patch and sysconfig files already loaded */
+		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001)
+			return -ENODEV;
+
 		ret = ath3k_load_patch(udev);
 		if (ret < 0) {
 			BT_ERR("Loading patch file failed");

+ 11 - 1
drivers/bluetooth/btusb.c

@@ -54,6 +54,7 @@ static struct usb_driver btusb_driver;
 #define BTUSB_BCM92035		0x10
 #define BTUSB_BROKEN_ISOC	0x20
 #define BTUSB_WRONG_SCO_MTU	0x40
+#define BTUSB_ATH3012		0x80
 
 static struct usb_device_id btusb_table[] = {
 	/* Generic Bluetooth USB device */
@@ -110,7 +111,7 @@ static struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
 
 	/* Atheros 3012 with sflash firmware */
-	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE },
+	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -914,6 +915,15 @@ static int btusb_probe(struct usb_interface *intf,
 	if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
 		return -ENODEV;
 
+	if (id->driver_info & BTUSB_ATH3012) {
+		struct usb_device *udev = interface_to_usbdev(intf);
+
+		/* Old firmware would otherwise let ath3k driver load
+		 * patch and sysconfig files */
+		if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
+			return -ENODEV;
+	}
+
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;

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

@@ -167,8 +167,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
 		 * driver for it
 		 */
 		if (to_platform_device(sc->dev)->id == 0 &&
-		    (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) ==
-		     (BD_WLAN1|BD_WLAN0))
+		    (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
+		     (BD_WLAN1 | BD_WLAN0))
 			__set_bit(ATH_STAT_2G_DISABLED, sc->status);
 	}
 

+ 7 - 2
drivers/net/wireless/ath/ath5k/ani.c

@@ -74,7 +74,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
 	static const s8 fr[] = { -78, -80 };
 #endif
 	if (level < 0 || level >= ARRAY_SIZE(sz)) {
-		ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range",
+		ATH5K_ERR(ah->ah_sc, "noise immunity level %d out of range",
 			  level);
 		return;
 	}
@@ -630,6 +630,11 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
 	if (ah->ah_version < AR5K_AR5212)
 		return;
 
+	if (mode < ATH5K_ANI_MODE_OFF || mode > ATH5K_ANI_MODE_AUTO) {
+		ATH5K_ERR(ah->ah_sc, "ANI mode %d out of range", mode);
+		return;
+	}
+
 	/* clear old state information */
 	memset(&ah->ah_sc->ani_state, 0, sizeof(ah->ah_sc->ani_state));
 
@@ -642,7 +647,7 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
 	/* initial values for our ani parameters */
 	if (mode == ATH5K_ANI_MODE_OFF) {
 		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI off\n");
-	} else if  (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
+	} else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
 		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
 			"ANI manual low -> high sensitivity\n");
 		ath5k_ani_set_noise_immunity_level(ah, 0);

+ 85 - 82
drivers/net/wireless/ath/ath5k/ath5k.h

@@ -18,9 +18,9 @@
 #ifndef _ATH5K_H
 #define _ATH5K_H
 
-/* TODO: Clean up channel debuging -doesn't work anyway- and start
+/* TODO: Clean up channel debugging (doesn't work anyway) and start
  * working on reg. control code using all available eeprom information
- * -rev. engineering needed- */
+ * (rev. engineering needed) */
 #define CHAN_DEBUG	0
 
 #include <linux/io.h>
@@ -39,40 +39,41 @@
 #include "../ath.h"
 
 /* PCI IDs */
-#define PCI_DEVICE_ID_ATHEROS_AR5210 		0x0007 /* AR5210 */
-#define PCI_DEVICE_ID_ATHEROS_AR5311 		0x0011 /* AR5311 */
-#define PCI_DEVICE_ID_ATHEROS_AR5211 		0x0012 /* AR5211 */
-#define PCI_DEVICE_ID_ATHEROS_AR5212 		0x0013 /* AR5212 */
-#define PCI_DEVICE_ID_3COM_3CRDAG675 		0x0013 /* 3CRDAG675 (Atheros AR5212) */
-#define PCI_DEVICE_ID_3COM_2_3CRPAG175 		0x0013 /* 3CRPAG175 (Atheros AR5212) */
-#define PCI_DEVICE_ID_ATHEROS_AR5210_AP 	0x0207 /* AR5210 (Early) */
+#define PCI_DEVICE_ID_ATHEROS_AR5210		0x0007 /* AR5210 */
+#define PCI_DEVICE_ID_ATHEROS_AR5311		0x0011 /* AR5311 */
+#define PCI_DEVICE_ID_ATHEROS_AR5211		0x0012 /* AR5211 */
+#define PCI_DEVICE_ID_ATHEROS_AR5212		0x0013 /* AR5212 */
+#define PCI_DEVICE_ID_3COM_3CRDAG675		0x0013 /* 3CRDAG675 (Atheros AR5212) */
+#define PCI_DEVICE_ID_3COM_2_3CRPAG175		0x0013 /* 3CRPAG175 (Atheros AR5212) */
+#define PCI_DEVICE_ID_ATHEROS_AR5210_AP		0x0207 /* AR5210 (Early) */
 #define PCI_DEVICE_ID_ATHEROS_AR5212_IBM	0x1014 /* AR5212 (IBM MiniPCI) */
-#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT 	0x1107 /* AR5210 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT 	0x1113 /* AR5212 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT 	0x1112 /* AR5211 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA 	0xf013 /* AR5212 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY 	0xff12 /* AR5211 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B 	0xf11b /* AR5211 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2 	0x0052 /* AR5312 WMAC (AP31) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7 	0x0057 /* AR5312 WMAC (AP30-040) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8 	0x0058 /* AR5312 WMAC (AP43-030) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0014 	0x0014 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0015 	0x0015 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0016 	0x0016 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0017 	0x0017 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0018 	0x0018 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0019 	0x0019 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR2413 		0x001a /* AR2413 (Griffin-lite) */
-#define PCI_DEVICE_ID_ATHEROS_AR5413 		0x001b /* AR5413 (Eagle) */
-#define PCI_DEVICE_ID_ATHEROS_AR5424 		0x001c /* AR5424 (Condor PCI-E) */
-#define PCI_DEVICE_ID_ATHEROS_AR5416 		0x0023 /* AR5416 */
-#define PCI_DEVICE_ID_ATHEROS_AR5418 		0x0024 /* AR5418 */
+#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT	0x1107 /* AR5210 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT	0x1113 /* AR5212 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT	0x1112 /* AR5211 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA	0xf013 /* AR5212 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY	0xff12 /* AR5211 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B	0xf11b /* AR5211 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2	0x0052 /* AR5312 WMAC (AP31) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7	0x0057 /* AR5312 WMAC (AP30-040) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8	0x0058 /* AR5312 WMAC (AP43-030) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0014	0x0014 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0015	0x0015 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0016	0x0016 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0017	0x0017 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0018	0x0018 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0019	0x0019 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR2413		0x001a /* AR2413 (Griffin-lite) */
+#define PCI_DEVICE_ID_ATHEROS_AR5413		0x001b /* AR5413 (Eagle) */
+#define PCI_DEVICE_ID_ATHEROS_AR5424		0x001c /* AR5424 (Condor PCI-E) */
+#define PCI_DEVICE_ID_ATHEROS_AR5416		0x0023 /* AR5416 */
+#define PCI_DEVICE_ID_ATHEROS_AR5418		0x0024 /* AR5418 */
 
 /****************************\
   GENERIC DRIVER DEFINITIONS
 \****************************/
 
-#define ATH5K_PRINTF(fmt, ...)   printk("%s: " fmt, __func__, ##__VA_ARGS__)
+#define ATH5K_PRINTF(fmt, ...) \
+	printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__)
 
 #define ATH5K_PRINTK(_sc, _level, _fmt, ...) \
 	printk(_level "ath5k %s: " _fmt, \
@@ -155,7 +156,7 @@
 } while (0)
 
 /*
- * Some tuneable values (these should be changeable by the user)
+ * Some tunable values (these should be changeable by the user)
  * TODO: Make use of them and add more options OR use debug/configfs
  */
 #define AR5K_TUNE_DMA_BEACON_RESP		2
@@ -170,8 +171,8 @@
 #define AR5K_TUNE_RSSI_THRES			129
 /* This must be set when setting the RSSI threshold otherwise it can
  * prevent a reset. If AR5K_RSSI_THR is read after writing to it
- * the BMISS_THRES will be seen as 0, seems harware doesn't keep
- * track of it. Max value depends on harware. For AR5210 this is just 7.
+ * the BMISS_THRES will be seen as 0, seems hardware doesn't keep
+ * track of it. Max value depends on hardware. For AR5210 this is just 7.
  * For AR5211+ this seems to be up to 255. */
 #define AR5K_TUNE_BMISS_THRES			7
 #define AR5K_TUNE_REGISTER_DWELL_TIME		20000
@@ -361,7 +362,7 @@ struct ath5k_srev_name {
 /*
  * Some of this information is based on Documentation from:
  *
- * http://madwifi-project.org/wiki/ChipsetFeatures/SuperAG 
+ * http://madwifi-project.org/wiki/ChipsetFeatures/SuperAG
  *
  * Modulation for Atheros' eXtended Range - range enhancing extension that is
  * supposed to double the distance an Atheros client device can keep a
@@ -374,12 +375,12 @@ struct ath5k_srev_name {
  * they are exclusive.
  *
  */
-#define MODULATION_XR 		0x00000200
+#define MODULATION_XR		0x00000200
 /*
  * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a
  * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s
  * signaling rate achieved through the bonding of two 54Mbit/s 802.11g
- * channels. To use this feature your Access Point must also suport it.
+ * channels. To use this feature your Access Point must also support it.
  * There is also a distinction between "static" and "dynamic" turbo modes:
  *
  * - Static: is the dumb version: devices set to this mode stick to it until
@@ -495,9 +496,9 @@ enum ath5k_tx_queue {
  */
 enum ath5k_tx_queue_subtype {
 	AR5K_WME_AC_BK = 0,	/*Background traffic*/
-	AR5K_WME_AC_BE, 	/*Best-effort (normal) traffic)*/
-	AR5K_WME_AC_VI, 	/*Video traffic*/
-	AR5K_WME_AC_VO, 	/*Voice traffic*/
+	AR5K_WME_AC_BE,		/*Best-effort (normal) traffic*/
+	AR5K_WME_AC_VI,		/*Video traffic*/
+	AR5K_WME_AC_VO,		/*Voice traffic*/
 };
 
 /*
@@ -616,8 +617,8 @@ struct ath5k_rx_status {
 #define AR5K_RXERR_FIFO		0x04
 #define AR5K_RXERR_DECRYPT	0x08
 #define AR5K_RXERR_MIC		0x10
-#define AR5K_RXKEYIX_INVALID	((u8) - 1)
-#define AR5K_TXKEYIX_INVALID	((u32) - 1)
+#define AR5K_RXKEYIX_INVALID	((u8) -1)
+#define AR5K_TXKEYIX_INVALID	((u32) -1)
 
 
 /**************************\
@@ -678,17 +679,18 @@ struct ath5k_gain {
 #define	CHANNEL_DYN	0x0400	/* Dynamic CCK-OFDM channel (for g operation) */
 #define	CHANNEL_XR	0x0800	/* XR channel */
 
-#define	CHANNEL_A	(CHANNEL_5GHZ|CHANNEL_OFDM)
-#define	CHANNEL_B	(CHANNEL_2GHZ|CHANNEL_CCK)
-#define	CHANNEL_G	(CHANNEL_2GHZ|CHANNEL_OFDM)
-#define	CHANNEL_X	(CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
+#define	CHANNEL_A	(CHANNEL_5GHZ | CHANNEL_OFDM)
+#define	CHANNEL_B	(CHANNEL_2GHZ | CHANNEL_CCK)
+#define	CHANNEL_G	(CHANNEL_2GHZ | CHANNEL_OFDM)
+#define	CHANNEL_X	(CHANNEL_5GHZ | CHANNEL_OFDM | CHANNEL_XR)
 
-#define	CHANNEL_ALL	(CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ)
+#define	CHANNEL_ALL	(CHANNEL_OFDM | CHANNEL_CCK | \
+			 CHANNEL_2GHZ | CHANNEL_5GHZ)
 
 #define CHANNEL_MODES		CHANNEL_ALL
 
 /*
- * Used internaly for reset_tx_queue).
+ * Used internally for ath5k_hw_reset_tx_queue().
  * Also see struct struct ieee80211_channel.
  */
 #define IS_CHAN_XR(_c)	((_c->hw_value & CHANNEL_XR) != 0)
@@ -710,7 +712,7 @@ struct ath5k_athchan_2ghz {
 \******************/
 
 /**
- * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32.
+ * Seems the ar5xxx hardware supports up to 32 rates, indexed by 1-32.
  *
  * The rate code is used to get the RX rate or set the TX rate on the
  * hardware descriptors. It is also used for internal modulation control
@@ -776,11 +778,11 @@ extern int ath5k_modparam_nohwcrypt;
 /*
  * Misc definitions
  */
-#define	AR5K_RSSI_EP_MULTIPLIER	(1<<7)
+#define	AR5K_RSSI_EP_MULTIPLIER	(1 << 7)
 
 #define AR5K_ASSERT_ENTRY(_e, _s) do {		\
 	if (_e >= _s)				\
-		return (false);			\
+		return false;			\
 } while (0)
 
 /*
@@ -791,52 +793,52 @@ extern int ath5k_modparam_nohwcrypt;
  * enum ath5k_int - Hardware interrupt masks helpers
  *
  * @AR5K_INT_RX: mask to identify received frame interrupts, of type
- * 	AR5K_ISR_RXOK or AR5K_ISR_RXERR
+ *	AR5K_ISR_RXOK or AR5K_ISR_RXERR
  * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?)
  * @AR5K_INT_RXNOFRM: No frame received (?)
  * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The
- * 	Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's
- * 	LinkPtr is NULL. For more details, refer to:
- * 	http://www.freepatentsonline.com/20030225739.html
+ *	Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's
+ *	LinkPtr is NULL. For more details, refer to:
+ *	http://www.freepatentsonline.com/20030225739.html
  * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors).
- * 	Note that Rx overrun is not always fatal, on some chips we can continue
- * 	operation without reseting the card, that's why int_fatal is not
- * 	common for all chips.
+ *	Note that Rx overrun is not always fatal, on some chips we can continue
+ *	operation without resetting the card, that's why int_fatal is not
+ *	common for all chips.
  * @AR5K_INT_TX: mask to identify received frame interrupts, of type
- * 	AR5K_ISR_TXOK or AR5K_ISR_TXERR
+ *	AR5K_ISR_TXOK or AR5K_ISR_TXERR
  * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?)
  * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
- * 	We currently do increments on interrupt by
- * 	(AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
+ *	We currently do increments on interrupt by
+ *	(AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
  * @AR5K_INT_MIB: Indicates the either Management Information Base counters or
  *	one of the PHY error counters reached the maximum value and should be
  *	read and cleared.
  * @AR5K_INT_RXPHY: RX PHY Error
  * @AR5K_INT_RXKCM: RX Key cache miss
  * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
- * 	beacon that must be handled in software. The alternative is if you
- * 	have VEOL support, in that case you let the hardware deal with things.
+ *	beacon that must be handled in software. The alternative is if you
+ *	have VEOL support, in that case you let the hardware deal with things.
  * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing
- * 	beacons from the AP have associated with, we should probably try to
- * 	reassociate. When in IBSS mode this might mean we have not received
- * 	any beacons from any local stations. Note that every station in an
- * 	IBSS schedules to send beacons at the Target Beacon Transmission Time
- * 	(TBTT) with a random backoff.
+ *	beacons from the AP have associated with, we should probably try to
+ *	reassociate. When in IBSS mode this might mean we have not received
+ *	any beacons from any local stations. Note that every station in an
+ *	IBSS schedules to send beacons at the Target Beacon Transmission Time
+ *	(TBTT) with a random backoff.
  * @AR5K_INT_BNR: Beacon Not Ready interrupt - ??
  * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now
- * 	until properly handled
+ *	until properly handled
  * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA
- * 	errors. These types of errors we can enable seem to be of type
- * 	AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
+ *	errors. These types of errors we can enable seem to be of type
+ *	AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
  * @AR5K_INT_GLOBAL: Used to clear and set the IER
  * @AR5K_INT_NOCARD: signals the card has been removed
- * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same
- * 	bit value
+ * @AR5K_INT_COMMON: common interrupts shared among MACs with the same
+ *	bit value
  *
  * These are mapped to take advantage of some common bits
  * between the MACs, to be able to set intr properties
  * easier. Some of them are not used yet inside hw.c. Most map
- * to the respective hw interrupt value as they are common amogst different
+ * to the respective hw interrupt value as they are common among different
  * MACs.
  */
 enum ath5k_int {
@@ -968,9 +970,9 @@ enum ath5k_capability_type {
 	AR5K_CAP_MCAST_KEYSRCH		= 14,	/* Supports multicast key search */
 	AR5K_CAP_TSF_ADJUST		= 15,	/* Supports beacon tsf adjust */
 	AR5K_CAP_XR			= 16,	/* Supports XR mode */
-	AR5K_CAP_WME_TKIPMIC 		= 17,	/* Supports TKIP MIC when using WMM */
-	AR5K_CAP_CHAN_HALFRATE 		= 18,	/* Supports half rate channels */
-	AR5K_CAP_CHAN_QUARTERRATE 	= 19,	/* Supports quarter rate channels */
+	AR5K_CAP_WME_TKIPMIC		= 17,	/* Supports TKIP MIC when using WMM */
+	AR5K_CAP_CHAN_HALFRATE		= 18,	/* Supports half rate channels */
+	AR5K_CAP_CHAN_QUARTERRATE	= 19,	/* Supports quarter rate channels */
 	AR5K_CAP_RFSILENT		= 20,	/* Supports RFsilent */
 };
 
@@ -1010,8 +1012,7 @@ struct ath5k_capabilities {
 
 /* size of noise floor history (keep it a power of two) */
 #define ATH5K_NF_CAL_HIST_MAX	8
-struct ath5k_nfcal_hist
-{
+struct ath5k_nfcal_hist {
 	s16 index;				/* current index into nfval */
 	s16 nfval[ATH5K_NF_CAL_HIST_MAX];	/* last few noise floors */
 };
@@ -1066,6 +1067,8 @@ struct ath5k_hw {
 	u8			ah_retry_long;
 	u8			ah_retry_short;
 
+	u32			ah_use_32khz_clock;
+
 	u8			ah_coverage_class;
 	bool			ah_ack_bitrate_high;
 	u8			ah_bwmode;
@@ -1357,17 +1360,17 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 				u8 mode, bool fast);
 
 /*
- * Functions used internaly
+ * Functions used internally
  */
 
 static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
 {
-        return &ah->common;
+	return &ah->common;
 }
 
 static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
 {
-        return &(ath5k_hw_common(ah)->regulatory);
+	return &(ath5k_hw_common(ah)->regulatory);
 }
 
 #ifdef CONFIG_ATHEROS_AR231X
@@ -1378,7 +1381,7 @@ static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
 	/* On AR2315 and AR2317 the PCI clock domain registers
 	 * are outside of the WMAC register space */
 	if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
-		(ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
+	    (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
 		return AR5K_AR2315_PCI_BASE + reg;
 
 	return ah->ah_iobase + reg;

+ 12 - 12
drivers/net/wireless/ath/ath5k/attach.c

@@ -104,6 +104,7 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
  */
 int ath5k_hw_init(struct ath5k_softc *sc)
 {
+	static const u8 zero_mac[ETH_ALEN] = { };
 	struct ath5k_hw *ah = sc->ah;
 	struct ath_common *common = ath5k_hw_common(ah);
 	struct pci_dev *pdev = sc->pdev;
@@ -191,7 +192,7 @@ int ath5k_hw_init(struct ath5k_softc *sc)
 		break;
 	case AR5K_SREV_RAD_5424:
 		if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
-		ah->ah_mac_version == AR5K_SREV_AR2417){
+		    ah->ah_mac_version == AR5K_SREV_AR2417) {
 			ah->ah_radio = AR5K_RF2425;
 			ah->ah_single_chip = true;
 		} else {
@@ -210,28 +211,28 @@ int ath5k_hw_init(struct ath5k_softc *sc)
 			ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
 								CHANNEL_2GHZ);
 		} else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
-		ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
-		ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
+			   ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
+			   ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
 			ah->ah_radio = AR5K_RF2425;
 			ah->ah_single_chip = true;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
 		} else if (srev == AR5K_SREV_AR5213A &&
-		ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
+			   ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
 			ah->ah_radio = AR5K_RF5112;
 			ah->ah_single_chip = false;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
 		} else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) ||
-			ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) {
+			   ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) {
 			ah->ah_radio = AR5K_RF2316;
 			ah->ah_single_chip = true;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
 		} else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
-		ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
+			   ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
 			ah->ah_radio = AR5K_RF5413;
 			ah->ah_single_chip = true;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
 		} else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
-		ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
+			   ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
 			ah->ah_radio = AR5K_RF2413;
 			ah->ah_single_chip = true;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
@@ -243,9 +244,8 @@ int ath5k_hw_init(struct ath5k_softc *sc)
 	}
 
 
-	/* Return on unsuported chips (unsupported eeprom etc) */
-	if ((srev >= AR5K_SREV_AR5416) &&
-	(srev < AR5K_SREV_AR2425)) {
+	/* Return on unsupported chips (unsupported eeprom etc) */
+	if ((srev >= AR5K_SREV_AR5416) && (srev < AR5K_SREV_AR2425)) {
 		ATH5K_ERR(sc, "Device not yet supported.\n");
 		ret = -ENODEV;
 		goto err;
@@ -285,7 +285,7 @@ int ath5k_hw_init(struct ath5k_softc *sc)
 		ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
 		ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
 
-		/* If serdes programing is enabled, increase PCI-E
+		/* If serdes programming is enabled, increase PCI-E
 		 * tx power for systems with long trace from host
 		 * to minicard connector. */
 		if (ee->ee_serdes)
@@ -334,7 +334,7 @@ int ath5k_hw_init(struct ath5k_softc *sc)
 	}
 
 	/* MAC address is cleared until add_interface */
-	ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
+	ath5k_hw_set_lladdr(ah, zero_mac);
 
 	/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
 	memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);

+ 37 - 34
drivers/net/wireless/ath/ath5k/base.c

@@ -532,7 +532,7 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
 	if (iter_data.n_stas > 1) {
 		/* If you have multiple STA interfaces connected to
 		 * different APs, ARPs are not received (most of the time?)
-		 * Enabling PROMISC appears to fix that probem.
+		 * Enabling PROMISC appears to fix that problem.
 		 */
 		sc->filter_flags |= AR5K_RX_FILTER_PROM;
 	}
@@ -815,8 +815,7 @@ ath5k_desc_alloc(struct ath5k_softc *sc)
 
 	INIT_LIST_HEAD(&sc->txbuf);
 	sc->txbuf_len = ATH_TXBUF;
-	for (i = 0; i < ATH_TXBUF; i++, bf++, ds++,
-			da += sizeof(*ds)) {
+	for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
 		bf->desc = ds;
 		bf->daddr = da;
 		list_add_tail(&bf->list, &sc->txbuf);
@@ -982,7 +981,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
 		goto err;
 
 	if (sc->opmode == NL80211_IFTYPE_AP ||
-		sc->opmode == NL80211_IFTYPE_MESH_POINT) {
+	    sc->opmode == NL80211_IFTYPE_MESH_POINT) {
 		/*
 		 * Always burst out beacon and CAB traffic
 		 * (aifs = cwmin = cwmax = 0)
@@ -1262,16 +1261,15 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
  */
 static int ath5k_common_padpos(struct sk_buff *skb)
 {
-	struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	__le16 frame_control = hdr->frame_control;
 	int padpos = 24;
 
-	if (ieee80211_has_a4(frame_control)) {
+	if (ieee80211_has_a4(frame_control))
 		padpos += ETH_ALEN;
-	}
-	if (ieee80211_is_data_qos(frame_control)) {
+
+	if (ieee80211_is_data_qos(frame_control))
 		padpos += IEEE80211_QOS_CTL_LEN;
-	}
 
 	return padpos;
 }
@@ -1285,13 +1283,13 @@ static int ath5k_add_padding(struct sk_buff *skb)
 	int padpos = ath5k_common_padpos(skb);
 	int padsize = padpos & 3;
 
-	if (padsize && skb->len>padpos) {
+	if (padsize && skb->len > padpos) {
 
 		if (skb_headroom(skb) < padsize)
 			return -1;
 
 		skb_push(skb, padsize);
-		memmove(skb->data, skb->data+padsize, padpos);
+		memmove(skb->data, skb->data + padsize, padpos);
 		return padsize;
 	}
 
@@ -1316,7 +1314,7 @@ static int ath5k_remove_padding(struct sk_buff *skb)
 	int padpos = ath5k_common_padpos(skb);
 	int padsize = padpos & 3;
 
-	if (padsize && skb->len>=padpos+padsize) {
+	if (padsize && skb->len >= padpos + padsize) {
 		memmove(skb->data + padsize, skb->data, padpos);
 		skb_pull(skb, padsize);
 		return padsize;
@@ -1352,7 +1350,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
 	 * timestamp (beginning of phy frame, data frame, end of rx?).
 	 * The only thing we know is that it is hardware specific...
 	 * On AR5213 it seems the rx timestamp is at the end of the
-	 * frame, but i'm not sure.
+	 * frame, but I'm not sure.
 	 *
 	 * NOTE: mac80211 defines mactime at the beginning of the first
 	 * data symbol. Since we don't have any time references it's
@@ -1450,10 +1448,11 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
 static void
 ath5k_set_current_imask(struct ath5k_softc *sc)
 {
-	enum ath5k_int imask = sc->imask;
+	enum ath5k_int imask;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sc->irqlock, flags);
+	imask = sc->imask;
 	if (sc->rx_pending)
 		imask &= ~AR5K_INT_RX_ALL;
 	if (sc->tx_pending)
@@ -1556,7 +1555,8 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
 		goto drop_packet;
 	}
 
-	if (txq->txq_len >= txq->txq_max)
+	if (txq->txq_len >= txq->txq_max &&
+	    txq->qnum <= AR5K_TX_QUEUE_ID_DATA_MAX)
 		ieee80211_stop_queue(hw, txq->qnum);
 
 	spin_lock_irqsave(&sc->txbuflock, flags);
@@ -1711,7 +1711,7 @@ ath5k_tasklet_tx(unsigned long data)
 	int i;
 	struct ath5k_softc *sc = (void *)data;
 
-	for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
+	for (i = 0; i < AR5K_NUM_TX_QUEUES; i++)
 		if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
 			ath5k_tx_processq(sc, &sc->txqs[i]);
 
@@ -1766,7 +1766,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
 	 * 4 beacons to make sure everybody hears our AP.
 	 * When a client tries to associate, hw will keep
 	 * track of the tx antenna to be used for this client
-	 * automaticaly, based on ACKed packets.
+	 * automatically, based on ACKed packets.
 	 *
 	 * Note: AP still listens and transmits RTS on the
 	 * default antenna which is supposed to be an omni.
@@ -1902,7 +1902,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
 	avf = (void *)vif->drv_priv;
 	bf = avf->bbuf;
 	if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
-			sc->opmode == NL80211_IFTYPE_MONITOR)) {
+		     sc->opmode == NL80211_IFTYPE_MONITOR)) {
 		ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
 		return;
 	}
@@ -1919,7 +1919,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
 
 	/* refresh the beacon for AP or MESH mode */
 	if (sc->opmode == NL80211_IFTYPE_AP ||
-			sc->opmode == NL80211_IFTYPE_MESH_POINT)
+	    sc->opmode == NL80211_IFTYPE_MESH_POINT)
 		ath5k_beacon_update(sc->hw, vif);
 
 	trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]);
@@ -1932,6 +1932,10 @@ ath5k_beacon_send(struct ath5k_softc *sc)
 	skb = ieee80211_get_buffered_bc(sc->hw, vif);
 	while (skb) {
 		ath5k_tx_queue(sc->hw, skb, sc->cabq);
+
+		if (sc->cabq->txq_len >= sc->cabq->txq_max)
+			break;
+
 		skb = ieee80211_get_buffered_bc(sc->hw, vif);
 	}
 
@@ -1978,7 +1982,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
 	hw_tsf = ath5k_hw_get_tsf64(ah);
 	hw_tu = TSF_TO_TU(hw_tsf);
 
-#define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3
+#define FUDGE (AR5K_TUNE_SW_BEACON_RESP + 3)
 	/* We use FUDGE to make sure the next TBTT is ahead of the current TU.
 	 * Since we later subtract AR5K_TUNE_SW_BEACON_RESP (10) in the timer
 	 * configuration we need to make sure it is bigger than that. */
@@ -2101,11 +2105,11 @@ static void ath5k_tasklet_beacon(unsigned long data)
 	 *
 	 * In IBSS mode we use this interrupt just to
 	 * keep track of the next TBTT (target beacon
-	 * transmission time) in order to detect wether
+	 * transmission time) in order to detect whether
 	 * automatic TSF updates happened.
 	 */
 	if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-		/* XXX: only if VEOL suppported */
+		/* XXX: only if VEOL supported */
 		u64 tsf = ath5k_hw_get_tsf64(sc->ah);
 		sc->nexttbtt += sc->bintval;
 		ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
@@ -2200,13 +2204,12 @@ ath5k_intr(int irq, void *dev_id)
 				ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
 					  "rx overrun, resetting\n");
 				ieee80211_queue_work(sc->hw, &sc->reset_work);
-			}
-			else
+			} else
 				ath5k_schedule_rx(sc);
 		} else {
-			if (status & AR5K_INT_SWBA) {
+			if (status & AR5K_INT_SWBA)
 				tasklet_hi_schedule(&sc->beacontq);
-			}
+
 			if (status & AR5K_INT_RXEOL) {
 				/*
 				* NB: the hardware should re-read the link when
@@ -2358,7 +2361,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
 * Initialization routines *
 \*************************/
 
-int
+int __devinit
 ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
 {
 	struct ieee80211_hw *hw = sc->hw;
@@ -2423,6 +2426,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
 	common->ah = sc->ah;
 	common->hw = hw;
 	common->priv = sc;
+	common->clockrate = 40;
 
 	/*
 	 * Cache line size is used to size and align various
@@ -2469,7 +2473,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
 						sc->ah->ah_radio_5ghz_revision),
 						sc->ah->ah_radio_5ghz_revision);
 			/* No 2GHz support (5110 and some
-			 * 5Ghz only cards) -> report 5Ghz radio */
+			 * 5GHz only cards) -> report 5GHz radio */
 			} else if (!test_bit(AR5K_MODE_11B,
 				sc->ah->ah_capabilities.cap_mode)) {
 				ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
@@ -2488,7 +2492,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
 		/* Multi chip radio (RF5111 - RF2111) ->
 		 * report both 2GHz/5GHz radios */
 		else if (sc->ah->ah_radio_5ghz_revision &&
-				sc->ah->ah_radio_2ghz_revision){
+				sc->ah->ah_radio_2ghz_revision) {
 			ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
 				ath5k_chip_name(AR5K_VERSION_RAD,
 					sc->ah->ah_radio_5ghz_revision),
@@ -2713,8 +2717,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
 
 	fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
 
-	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast,
-								skip_pcu);
+	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, skip_pcu);
 	if (ret) {
 		ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
 		goto err;
@@ -2728,7 +2731,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
 
 	ath5k_ani_init(ah, ani_mode);
 
-	ah->ah_cal_next_full = jiffies;
+	ah->ah_cal_next_full = jiffies + msecs_to_jiffies(100);
 	ah->ah_cal_next_ani = jiffies;
 	ah->ah_cal_next_nf = jiffies;
 	ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
@@ -2772,7 +2775,7 @@ static void ath5k_reset_work(struct work_struct *work)
 	mutex_unlock(&sc->lock);
 }
 
-static int
+static int __devinit
 ath5k_init(struct ieee80211_hw *hw)
 {
 
@@ -2800,7 +2803,7 @@ ath5k_init(struct ieee80211_hw *hw)
 
 	/*
 	 * Collect the channel list.  The 802.11 layer
-	 * is resposible for filtering this list based
+	 * is responsible for filtering this list based
 	 * on settings like the phy mode and regulatory
 	 * domain restrictions.
 	 */

+ 5 - 6
drivers/net/wireless/ath/ath5k/base.h

@@ -96,8 +96,7 @@ struct ath5k_txq {
 /*
  * State for LED triggers
  */
-struct ath5k_led
-{
+struct ath5k_led {
 	char name[ATH5K_LED_MAX_NAME_LEN + 1];	/* name of the LED in sysfs */
 	struct ath5k_softc *sc;			/* driver state */
 	struct led_classdev led_dev;		/* led classdev */
@@ -122,7 +121,7 @@ struct ath5k_statistics {
 	/* frame errors */
 	unsigned int rx_all_count;	/* all RX frames, including errors */
 	unsigned int tx_all_count;	/* all TX frames, including errors */
-	unsigned int rx_bytes_count;	/* all RX bytes, including errored pks
+	unsigned int rx_bytes_count;	/* all RX bytes, including errored pkts
 					 * and the MAC headers for each packet
 					 */
 	unsigned int tx_bytes_count;	/* all TX bytes, including errored pkts
@@ -154,9 +153,9 @@ struct ath5k_statistics {
 };
 
 #if CHAN_DEBUG
-#define ATH_CHAN_MAX	(26+26+26+200+200)
+#define ATH_CHAN_MAX	(26 + 26 + 26 + 200 + 200)
 #else
-#define ATH_CHAN_MAX	(14+14+14+252+20)
+#define ATH_CHAN_MAX	(14 + 14 + 14 + 252 + 20)
 #endif
 
 struct ath5k_vif {
@@ -251,7 +250,7 @@ struct ath5k_softc {
 	unsigned int		nexttbtt;	/* next beacon time in TU */
 	struct ath5k_txq	*cabq;		/* content after beacon */
 
-	int 			power_level;	/* Requested tx power in dbm */
+	int			power_level;	/* Requested tx power in dBm */
 	bool			assoc;		/* associate state */
 	bool			enable_beacon;	/* true if beacons are on */
 

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

@@ -52,8 +52,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
 		__set_bit(AR5K_MODE_11A, caps->cap_mode);
 	} else {
 		/*
-		 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
-		 * XXX and from 2312 to 2732GHz. There are problems with the
+		 * XXX The transceiver supports frequencies from 4920 to 6100MHz
+		 * XXX and from 2312 to 2732MHz. There are problems with the
 		 * XXX current ieee80211 implementation because the IEEE
 		 * XXX channel mapping does not support negative channel
 		 * XXX numbers (2312MHz is channel -19). Of course, this

+ 107 - 100
drivers/net/wireless/ath/ath5k/debug.c

@@ -205,35 +205,35 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
 	u64 tsf;
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
 		"AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
 		(v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
 
-	len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n",
 		"AR5K_LAST_TSTP", ath5k_hw_reg_read(sc->ah, AR5K_LAST_TSTP));
 
-	len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n\n",
 		"AR5K_BEACON_CNT", ath5k_hw_reg_read(sc->ah, AR5K_BEACON_CNT));
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER0);
-	len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
 		"AR5K_TIMER0 (TBTT)", v, v);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER1);
-	len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
 		"AR5K_TIMER1 (DMA)", v, v >> 3);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER2);
-	len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
 		"AR5K_TIMER2 (SWBA)", v, v >> 3);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER3);
-	len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
 		"AR5K_TIMER3 (ATIM)", v, v);
 
 	tsf = ath5k_hw_get_tsf64(sc->ah);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"TSF\t\t0x%016llx\tTU: %08x\n",
 		(unsigned long long)tsf, TSF_TO_TU(tsf));
 
@@ -323,16 +323,16 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf,
 	unsigned int len = 0;
 	unsigned int i;
 
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
 
 	for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
-		len += snprintf(buf+len, sizeof(buf)-len,
+		len += snprintf(buf + len, sizeof(buf) - len,
 			"%10s %c 0x%08x - %s\n", dbg_info[i].name,
 			sc->debug.level & dbg_info[i].level ? '+' : ' ',
 			dbg_info[i].level, dbg_info[i].desc);
 	}
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"%10s %c 0x%08x - %s\n", dbg_info[i].name,
 		sc->debug.level == dbg_info[i].level ? '+' : ' ',
 		dbg_info[i].level, dbg_info[i].desc);
@@ -384,60 +384,60 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
 	unsigned int i;
 	unsigned int v;
 
-	len += snprintf(buf+len, sizeof(buf)-len, "antenna mode\t%d\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "antenna mode\t%d\n",
 		sc->ah->ah_ant_mode);
-	len += snprintf(buf+len, sizeof(buf)-len, "default antenna\t%d\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "default antenna\t%d\n",
 		sc->ah->ah_def_ant);
-	len += snprintf(buf+len, sizeof(buf)-len, "tx antenna\t%d\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "tx antenna\t%d\n",
 		sc->ah->ah_tx_ant);
 
-	len += snprintf(buf+len, sizeof(buf)-len, "\nANTENNA\t\tRX\tTX\n");
+	len += snprintf(buf + len, sizeof(buf) - len, "\nANTENNA\t\tRX\tTX\n");
 	for (i = 1; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
-		len += snprintf(buf+len, sizeof(buf)-len,
+		len += snprintf(buf + len, sizeof(buf) - len,
 			"[antenna %d]\t%d\t%d\n",
 			i, sc->stats.antenna_rx[i], sc->stats.antenna_tx[i]);
 	}
-	len += snprintf(buf+len, sizeof(buf)-len, "[invalid]\t%d\t%d\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "[invalid]\t%d\t%d\n",
 			sc->stats.antenna_rx[0], sc->stats.antenna_tx[0]);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_DEFAULT_ANTENNA);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_STA_ID1);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n",
 		(v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"AR5K_STA_ID1_DESC_ANTENNA\t%d\n",
 		(v & AR5K_STA_ID1_DESC_ANTENNA) != 0);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n",
 		(v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n",
 		(v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_AGCCTL);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n",
 		(v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_RESTART);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"AR5K_PHY_RESTART_DIV_GC\t\t%x\n",
 		(v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_FAST_ANT_DIV);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
 		(v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
 
 	v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_0);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v);
 	v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_1);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
 
 	if (len > sizeof(buf))
@@ -494,36 +494,36 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
 	unsigned int len = 0;
 	u32 filt = ath5k_hw_get_rx_filter(sc->ah);
 
-	len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "bssid-mask: %pM\n",
 			sc->bssidmask);
-	len += snprintf(buf+len, sizeof(buf)-len, "filter-flags: 0x%x ",
+	len += snprintf(buf + len, sizeof(buf) - len, "filter-flags: 0x%x ",
 			filt);
 	if (filt & AR5K_RX_FILTER_UCAST)
-		len += snprintf(buf+len, sizeof(buf)-len, " UCAST");
+		len += snprintf(buf + len, sizeof(buf) - len, " UCAST");
 	if (filt & AR5K_RX_FILTER_MCAST)
-		len += snprintf(buf+len, sizeof(buf)-len, " MCAST");
+		len += snprintf(buf + len, sizeof(buf) - len, " MCAST");
 	if (filt & AR5K_RX_FILTER_BCAST)
-		len += snprintf(buf+len, sizeof(buf)-len, " BCAST");
+		len += snprintf(buf + len, sizeof(buf) - len, " BCAST");
 	if (filt & AR5K_RX_FILTER_CONTROL)
-		len += snprintf(buf+len, sizeof(buf)-len, " CONTROL");
+		len += snprintf(buf + len, sizeof(buf) - len, " CONTROL");
 	if (filt & AR5K_RX_FILTER_BEACON)
-		len += snprintf(buf+len, sizeof(buf)-len, " BEACON");
+		len += snprintf(buf + len, sizeof(buf) - len, " BEACON");
 	if (filt & AR5K_RX_FILTER_PROM)
-		len += snprintf(buf+len, sizeof(buf)-len, " PROM");
+		len += snprintf(buf + len, sizeof(buf) - len, " PROM");
 	if (filt & AR5K_RX_FILTER_XRPOLL)
-		len += snprintf(buf+len, sizeof(buf)-len, " XRPOLL");
+		len += snprintf(buf + len, sizeof(buf) - len, " XRPOLL");
 	if (filt & AR5K_RX_FILTER_PROBEREQ)
-		len += snprintf(buf+len, sizeof(buf)-len, " PROBEREQ");
+		len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
 	if (filt & AR5K_RX_FILTER_PHYERR_5212)
-		len += snprintf(buf+len, sizeof(buf)-len, " PHYERR-5212");
+		len += snprintf(buf + len, sizeof(buf) - len, " PHYERR-5212");
 	if (filt & AR5K_RX_FILTER_RADARERR_5212)
-		len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5212");
+		len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5212");
 	if (filt & AR5K_RX_FILTER_PHYERR_5211)
-		snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211");
+		snprintf(buf + len, sizeof(buf) - len, " PHYERR-5211");
 	if (filt & AR5K_RX_FILTER_RADARERR_5211)
-		len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211");
+		len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5211");
 
-	len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "\nopmode: %s (%d)\n",
 			ath_opmode_to_string(sc->opmode), sc->opmode);
 
 	if (len > sizeof(buf))
@@ -550,65 +550,65 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
 	unsigned int len = 0;
 	int i;
 
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"RX\n---------------------\n");
-	len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%u\t(%u%%)\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "CRC\t%u\t(%u%%)\n",
 			st->rxerr_crc,
 			st->rx_all_count > 0 ?
-				st->rxerr_crc*100/st->rx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%u\t(%u%%)\n",
+				st->rxerr_crc * 100 / st->rx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "PHY\t%u\t(%u%%)\n",
 			st->rxerr_phy,
 			st->rx_all_count > 0 ?
-				st->rxerr_phy*100/st->rx_all_count : 0);
+				st->rxerr_phy * 100 / st->rx_all_count : 0);
 	for (i = 0; i < 32; i++) {
 		if (st->rxerr_phy_code[i])
-			len += snprintf(buf+len, sizeof(buf)-len,
+			len += snprintf(buf + len, sizeof(buf) - len,
 				" phy_err[%u]\t%u\n",
 				i, st->rxerr_phy_code[i]);
 	}
 
-	len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n",
 			st->rxerr_fifo,
 			st->rx_all_count > 0 ?
-				st->rxerr_fifo*100/st->rx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%u\t(%u%%)\n",
+				st->rxerr_fifo * 100 / st->rx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "decrypt\t%u\t(%u%%)\n",
 			st->rxerr_decrypt,
 			st->rx_all_count > 0 ?
-				st->rxerr_decrypt*100/st->rx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%u\t(%u%%)\n",
+				st->rxerr_decrypt * 100 / st->rx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "MIC\t%u\t(%u%%)\n",
 			st->rxerr_mic,
 			st->rx_all_count > 0 ?
-				st->rxerr_mic*100/st->rx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "process\t%u\t(%u%%)\n",
+				st->rxerr_mic * 100 / st->rx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "process\t%u\t(%u%%)\n",
 			st->rxerr_proc,
 			st->rx_all_count > 0 ?
-				st->rxerr_proc*100/st->rx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%u\t(%u%%)\n",
+				st->rxerr_proc * 100 / st->rx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "jumbo\t%u\t(%u%%)\n",
 			st->rxerr_jumbo,
 			st->rx_all_count > 0 ?
-				st->rxerr_jumbo*100/st->rx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%u]\n",
+				st->rxerr_jumbo * 100 / st->rx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "[RX all\t%u]\n",
 			st->rx_all_count);
-	len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%u\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "RX-all-bytes\t%u\n",
 			st->rx_bytes_count);
 
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"\nTX\n---------------------\n");
-	len += snprintf(buf+len, sizeof(buf)-len, "retry\t%u\t(%u%%)\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "retry\t%u\t(%u%%)\n",
 			st->txerr_retry,
 			st->tx_all_count > 0 ?
-				st->txerr_retry*100/st->tx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
+				st->txerr_retry * 100 / st->tx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n",
 			st->txerr_fifo,
 			st->tx_all_count > 0 ?
-				st->txerr_fifo*100/st->tx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "filter\t%u\t(%u%%)\n",
+				st->txerr_fifo * 100 / st->tx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "filter\t%u\t(%u%%)\n",
 			st->txerr_filt,
 			st->tx_all_count > 0 ?
-				st->txerr_filt*100/st->tx_all_count : 0);
-	len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%u]\n",
+				st->txerr_filt * 100 / st->tx_all_count : 0);
+	len += snprintf(buf + len, sizeof(buf) - len, "[TX all\t%u]\n",
 			st->tx_all_count);
-	len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%u\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "TX-all-bytes\t%u\n",
 			st->tx_bytes_count);
 
 	if (len > sizeof(buf))
@@ -667,89 +667,93 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
 	char buf[700];
 	unsigned int len = 0;
 
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"HW has PHY error counters:\t%s\n",
 			sc->ah->ah_capabilities.cap_has_phyerr_counters ?
 			"yes" : "no");
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"HW max spur immunity level:\t%d\n",
 			as->max_spur_level);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"\nANI state\n--------------------------------------------\n");
-	len += snprintf(buf+len, sizeof(buf)-len, "operating mode:\t\t\t");
+	len += snprintf(buf + len, sizeof(buf) - len, "operating mode:\t\t\t");
 	switch (as->ani_mode) {
 	case ATH5K_ANI_MODE_OFF:
-		len += snprintf(buf+len, sizeof(buf)-len, "OFF\n");
+		len += snprintf(buf + len, sizeof(buf) - len, "OFF\n");
 		break;
 	case ATH5K_ANI_MODE_MANUAL_LOW:
-		len += snprintf(buf+len, sizeof(buf)-len,
+		len += snprintf(buf + len, sizeof(buf) - len,
 			"MANUAL LOW\n");
 		break;
 	case ATH5K_ANI_MODE_MANUAL_HIGH:
-		len += snprintf(buf+len, sizeof(buf)-len,
+		len += snprintf(buf + len, sizeof(buf) - len,
 			"MANUAL HIGH\n");
 		break;
 	case ATH5K_ANI_MODE_AUTO:
-		len += snprintf(buf+len, sizeof(buf)-len, "AUTO\n");
+		len += snprintf(buf + len, sizeof(buf) - len, "AUTO\n");
 		break;
 	default:
-		len += snprintf(buf+len, sizeof(buf)-len,
+		len += snprintf(buf + len, sizeof(buf) - len,
 			"??? (not good)\n");
 		break;
 	}
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"noise immunity level:\t\t%d\n",
 			as->noise_imm_level);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"spur immunity level:\t\t%d\n",
 			as->spur_level);
-	len += snprintf(buf+len, sizeof(buf)-len, "firstep level:\t\t\t%d\n",
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"firstep level:\t\t\t%d\n",
 			as->firstep_level);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"OFDM weak signal detection:\t%s\n",
 			as->ofdm_weak_sig ? "on" : "off");
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"CCK weak signal detection:\t%s\n",
 			as->cck_weak_sig ? "on" : "off");
 
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"\nMIB INTERRUPTS:\t\t%u\n",
 			st->mib_intr);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"beacon RSSI average:\t%d\n",
 			(int)ewma_read(&sc->ah->ah_beacon_rssi_avg));
 
 #define CC_PRINT(_struct, _field) \
 	_struct._field, \
 	_struct.cycles > 0 ? \
-	_struct._field*100/_struct.cycles : 0
+	_struct._field * 100 / _struct.cycles : 0
 
-	len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"profcnt tx\t\t%u\t(%d%%)\n",
 			CC_PRINT(as->last_cc, tx_frame));
-	len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"profcnt rx\t\t%u\t(%d%%)\n",
 			CC_PRINT(as->last_cc, rx_frame));
-	len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"profcnt busy\t\t%u\t(%d%%)\n",
 			CC_PRINT(as->last_cc, rx_busy));
 #undef CC_PRINT
-	len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
+	len += snprintf(buf + len, sizeof(buf) - len, "profcnt cycles\t\t%u\n",
 			as->last_cc.cycles);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"listen time\t\t%d\tlast: %d\n",
 			as->listen_time, as->last_listen);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"OFDM errors\t\t%u\tlast: %u\tsum: %u\n",
 			as->ofdm_errors, as->last_ofdm_errors,
 			as->sum_ofdm_errors);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"CCK errors\t\t%u\tlast: %u\tsum: %u\n",
 			as->cck_errors, as->last_cck_errors,
 			as->sum_cck_errors);
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"AR5K_PHYERR_CNT1\t%x\t(=%d)\n",
 			ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1),
 			ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
 			ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1)));
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"AR5K_PHYERR_CNT2\t%x\t(=%d)\n",
 			ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2),
 			ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
@@ -827,13 +831,13 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
 	struct ath5k_buf *bf, *bf0;
 	int i, n;
 
-	len += snprintf(buf+len, sizeof(buf)-len,
+	len += snprintf(buf + len, sizeof(buf) - len,
 			"available txbuffers: %d\n", sc->txbuf_len);
 
 	for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
 		txq = &sc->txqs[i];
 
-		len += snprintf(buf+len, sizeof(buf)-len,
+		len += snprintf(buf + len, sizeof(buf) - len,
 			"%02d: %ssetup\n", i, txq->setup ? "" : "not ");
 
 		if (!txq->setup)
@@ -845,9 +849,9 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
 			n++;
 		spin_unlock_bh(&txq->lock);
 
-		len += snprintf(buf+len, sizeof(buf)-len,
+		len += snprintf(buf + len, sizeof(buf) - len,
 				"  len: %d bufs: %d\n", txq->txq_len, n);
-		len += snprintf(buf+len, sizeof(buf)-len,
+		len += snprintf(buf + len, sizeof(buf) - len,
 				"  stuck: %d\n", txq->txq_stuck);
 	}
 
@@ -894,7 +898,7 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
 
 	phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir);
 	if (!phydir)
-	    return;
+		return;
 
 	debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc,
 			    &fops_debug);
@@ -918,6 +922,9 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
 
 	debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc,
 			    &fops_queue);
+
+	debugfs_create_bool("32khz_clock", S_IWUSR | S_IRUSR, phydir,
+			    &sc->ah->ah_use_32khz_clock);
 }
 
 /* functions used in other places */

+ 2 - 2
drivers/net/wireless/ath/ath5k/desc.h

@@ -58,11 +58,11 @@ struct ath5k_hw_rx_status {
 #define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK	0x00000002 /* reception success */
 #define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR		0x00000004 /* CRC error */
 #define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210	0x00000008 /* [5210] FIFO overrun */
-#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR	0x00000010 /* decyption CRC failure */
+#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR	0x00000010 /* decryption CRC failure */
 #define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR		0x000000e0 /* PHY error */
 #define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S		5
 #define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID	0x00000100 /* key index valid */
-#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX		0x00007e00 /* decyption key index */
+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX		0x00007e00 /* decryption key index */
 #define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S		9
 #define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP	0x0fff8000 /* 13 bit of TSF */
 #define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S	15

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

@@ -25,7 +25,7 @@
  *
  * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and
  * handle queue setup for 5210 chipset (rest are handled on qcu.c).
- * Also we setup interrupt mask register (IMR) and read the various iterrupt
+ * Also we setup interrupt mask register (IMR) and read the various interrupt
  * status registers (ISR).
  *
  * TODO: Handle SISR on 5211+ and introduce a function to return the queue
@@ -258,7 +258,7 @@ static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
 		/* For 2413+ order PCU to drop packets using
 		 * QUIET mechanism */
 		if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&
-		pending){
+		    pending) {
 			/* Set periodicity and duration */
 			ath5k_hw_reg_write(ah,
 				AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|
@@ -726,7 +726,7 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
 			int_mask |= AR5K_IMR_RXDOPPLER;
 
 		/* Note: Per queue interrupt masks
-		 * are set via reset_tx_queue (qcu.c) */
+		 * are set via ath5k_hw_reset_tx_queue() (qcu.c) */
 		ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
 		ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2);
 
@@ -783,7 +783,7 @@ void ath5k_hw_dma_init(struct ath5k_hw *ah)
 	 * for all PCI-E cards to be safe).
 	 *
 	 * XXX: need to check 5210 for this
-	 * TODO: Check out tx triger level, it's always 64 on dumps but I
+	 * TODO: Check out tx trigger level, it's always 64 on dumps but I
 	 * guess we can tweak it and see how it goes ;-)
 	 */
 	if (ah->ah_version != AR5K_AR5210) {

+ 24 - 22
drivers/net/wireless/ath/ath5k/eeprom.c

@@ -223,14 +223,14 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
 	ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
 	    (ee->ee_ant_control[mode][0] << 4);
 	ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
-	     ee->ee_ant_control[mode][1] 	|
-	    (ee->ee_ant_control[mode][2] << 6) 	|
+	     ee->ee_ant_control[mode][1]	|
+	    (ee->ee_ant_control[mode][2] << 6)	|
 	    (ee->ee_ant_control[mode][3] << 12) |
 	    (ee->ee_ant_control[mode][4] << 18) |
 	    (ee->ee_ant_control[mode][5] << 24);
 	ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
-	     ee->ee_ant_control[mode][6] 	|
-	    (ee->ee_ant_control[mode][7] << 6) 	|
+	     ee->ee_ant_control[mode][6]	|
+	    (ee->ee_ant_control[mode][7] << 6)	|
 	    (ee->ee_ant_control[mode][8] << 12) |
 	    (ee->ee_ant_control[mode][9] << 18) |
 	    (ee->ee_ant_control[mode][10] << 24);
@@ -255,7 +255,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
 	ee->ee_n_piers[mode] = 0;
 	AR5K_EEPROM_READ(o++, val);
 	ee->ee_adc_desired_size[mode]	= (s8)((val >> 8) & 0xff);
-	switch(mode) {
+	switch (mode) {
 	case AR5K_EEPROM_MODE_11A:
 		ee->ee_ob[mode][3]	= (val >> 5) & 0x7;
 		ee->ee_db[mode][3]	= (val >> 2) & 0x7;
@@ -349,7 +349,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
 	/* Note: >= v5 have bg freq piers on another location
 	 * so these freq piers are ignored for >= v5 (should be 0xff
 	 * anyway) */
-	switch(mode) {
+	switch (mode) {
 	case AR5K_EEPROM_MODE_11A:
 		if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
 			break;
@@ -422,7 +422,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
 	if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
 		goto done;
 
-	switch (mode){
+	switch (mode) {
 	case AR5K_EEPROM_MODE_11A:
 		ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
 
@@ -436,7 +436,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
 		ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
 		ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
 
-		if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2)
+		if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >= 2)
 			ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
 		break;
 	case AR5K_EEPROM_MODE_11G:
@@ -516,7 +516,7 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
 	u16 val;
 
 	ee->ee_n_piers[mode] = 0;
-	while(i < max) {
+	while (i < max) {
 		AR5K_EEPROM_READ(o++, val);
 
 		freq1 = val & 0xff;
@@ -602,7 +602,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	struct ath5k_chan_pcal_info *pcal;
 
-	switch(mode) {
+	switch (mode) {
 	case AR5K_EEPROM_MODE_11B:
 		pcal = ee->ee_pwr_cal_b;
 		break;
@@ -634,7 +634,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
 /* Used to match PCDAC steps with power values on RF5111 chips
  * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
  * steps that match with the power values we read from eeprom. On
- * older eeprom versions (< 3.2) these steps are equaly spaced at
+ * older eeprom versions (< 3.2) these steps are equally spaced at
  * 10% of the pcdac curve -until the curve reaches its maximum-
  * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
  * these 11 steps are spaced in a different way. This function returns
@@ -644,10 +644,12 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
 static inline void
 ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
 {
-	static const u16 intercepts3[] =
-		{ 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
-	static const u16 intercepts3_2[] =
-		{ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
+	static const u16 intercepts3[] = {
+		0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100
+	};
+	static const u16 intercepts3_2[] = {
+		0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
+	};
 	const u16 *ip;
 	int i;
 
@@ -762,7 +764,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
 
 		/* Fill raw dataset
 		 * (convert power to 0.25dB units
-		 * for RF5112 combatibility) */
+		 * for RF5112 compatibility) */
 		for (point = 0; point < pd->pd_points; point++) {
 
 			/* Absolute values */
@@ -796,7 +798,7 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
 	u16 val;
 
 	offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-	switch(mode) {
+	switch (mode) {
 	case AR5K_EEPROM_MODE_11A:
 		if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
 			return 0;
@@ -882,7 +884,7 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
  * Read power calibration for RF5112 chips
  *
  * For RF5112 we have 4 XPD -eXternal Power Detector- curves
- * for each calibrated channel on 0, -6, -12 and -18dbm but we only
+ * for each calibrated channel on 0, -6, -12 and -18dBm but we only
  * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
  * power steps on x axis and PCDAC steps on y axis and looks like a
  * linear function. To recreate the curve and pass the power values
@@ -1163,7 +1165,7 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
 {
 	u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
 
-	switch(mode) {
+	switch (mode) {
 	case AR5K_EEPROM_MODE_11G:
 		if (AR5K_EEPROM_HDR_11B(ee->ee_header))
 			offset += ath5k_pdgains_size_2413(ee,
@@ -1239,7 +1241,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
 
 			/* Fill raw dataset
 			 * convert all pwr levels to
-			 * quarter dB for RF5112 combatibility */
+			 * quarter dB for RF5112 compatibility */
 			pd->pd_step[0] = pcinfo->pddac_i[pdg];
 			pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
 
@@ -1620,8 +1622,8 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
 		offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
 
 	rep = ee->ee_ctl_pwr;
-	for(i = 0; i < ee->ee_ctls; i++) {
-		switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
+	for (i = 0; i < ee->ee_ctls; i++) {
+		switch (ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
 		case AR5K_CTL_11A:
 		case AR5K_CTL_TURBO:
 			ctl_mode = AR5K_EEPROM_MODE_11A;

+ 6 - 6
drivers/net/wireless/ath/ath5k/eeprom.h

@@ -50,7 +50,7 @@
 
 #define AR5K_EEPROM_VERSION		AR5K_EEPROM_INFO(1)	/* EEPROM Version */
 #define AR5K_EEPROM_VERSION_3_0		0x3000	/* No idea what's going on before this version */
-#define AR5K_EEPROM_VERSION_3_1		0x3001	/* ob/db values for 2Ghz (ar5211_rfregs) */
+#define AR5K_EEPROM_VERSION_3_1		0x3001	/* ob/db values for 2GHz (ar5211_rfregs) */
 #define AR5K_EEPROM_VERSION_3_2		0x3002	/* different frequency representation (eeprom_bin2freq) */
 #define AR5K_EEPROM_VERSION_3_3		0x3003	/* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
 #define AR5K_EEPROM_VERSION_3_4		0x3004	/* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */
@@ -75,11 +75,11 @@
 #define AR5K_EEPROM_HDR_11A(_v)		(((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
 #define AR5K_EEPROM_HDR_11B(_v)		(((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
 #define AR5K_EEPROM_HDR_11G(_v)		(((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
-#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v)	(((_v) >> 3) & 0x1)	/* Disable turbo for 2Ghz */
+#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v)	(((_v) >> 3) & 0x1)	/* Disable turbo for 2GHz */
 #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v)	(((_v) >> 4) & 0x7f)	/* Max turbo power for < 2W power consumption */
 #define AR5K_EEPROM_HDR_DEVICE(_v)	(((_v) >> 11) & 0x7)	/* Device type (1 Cardbus, 2 PCI, 3 MiniPCI, 4 AP) */
 #define AR5K_EEPROM_HDR_RFKILL(_v)	(((_v) >> 14) & 0x1)	/* Device has RFKill support */
-#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v)	(((_v) >> 15) & 0x1)	/* Disable turbo for 5Ghz */
+#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v)	(((_v) >> 15) & 0x1)	/* Disable turbo for 5GHz */
 
 /* Newer EEPROMs are using a different offset */
 #define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
@@ -120,7 +120,7 @@
 #define AR5K_EEPROM_FF_DIS(_v)		(((_v) >> 2) & 0x1)	/* disable fast frames */
 #define AR5K_EEPROM_BURST_DIS(_v)	(((_v) >> 3) & 0x1)	/* disable bursting */
 #define AR5K_EEPROM_MAX_QCU(_v)		(((_v) >> 4) & 0xf)	/* max number of QCUs. defaults to 10 */
-#define AR5K_EEPROM_HEAVY_CLIP_EN(_v)	(((_v) >> 8) & 0x1)	/* enable heayy clipping */
+#define AR5K_EEPROM_HEAVY_CLIP_EN(_v)	(((_v) >> 8) & 0x1)	/* enable heavy clipping */
 #define AR5K_EEPROM_KEY_CACHE_SIZE(_v)	(((_v) >> 12) & 0xf)	/* key cache size. defaults to 128 */
 
 #define AR5K_EEPROM_MISC6		AR5K_EEPROM_INFO(10)
@@ -223,7 +223,7 @@
 #define AR5K_EEPROM_CCK_OFDM_DELTA	15
 #define AR5K_EEPROM_N_IQ_CAL		2
 /* 5GHz/2GHz */
-enum ath5k_eeprom_freq_bands{
+enum ath5k_eeprom_freq_bands {
 	AR5K_EEPROM_BAND_5GHZ = 0,
 	AR5K_EEPROM_BAND_2GHZ = 1,
 	AR5K_EEPROM_N_FREQ_BANDS,
@@ -270,7 +270,7 @@ enum ath5k_ctl_mode {
 
 /* Per channel calibration data, used for power table setup */
 struct ath5k_chan_pcal_info_rf5111 {
-	/* Power levels in half dbm units
+	/* Power levels in half dBm units
 	 * for one power curve. */
 	u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
 	/* PCDAC table steps

+ 7 - 7
drivers/net/wireless/ath/ath5k/initvals.c

@@ -113,8 +113,8 @@ static const struct ath5k_ini ar5210_ini[] = {
 	{ AR5K_PHY(28),	0x0000000f },
 	{ AR5K_PHY(29),	0x00000080 },
 	{ AR5K_PHY(30),	0x00000004 },
-	{ AR5K_PHY(31),	0x00000018 }, 	/* 0x987c */
-	{ AR5K_PHY(64),	0x00000000 }, 	/* 0x9900 */
+	{ AR5K_PHY(31),	0x00000018 },	/* 0x987c */
+	{ AR5K_PHY(64),	0x00000000 },	/* 0x9900 */
 	{ AR5K_PHY(65),	0x00000000 },
 	{ AR5K_PHY(66),	0x00000000 },
 	{ AR5K_PHY(67),	0x00800000 },
@@ -549,7 +549,7 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
 	{ AR5K_DIAG_SW_5211,	0x00000000 },
 	{ AR5K_ADDAC_TEST,	0x00000000 },
 	{ AR5K_DEFAULT_ANTENNA,	0x00000000 },
-	{ AR5K_FRAME_CTL_QOSM, 	0x000fc78f },
+	{ AR5K_FRAME_CTL_QOSM,	0x000fc78f },
 	{ AR5K_XRMODE,		0x2a82301a },
 	{ AR5K_XRDELAY,		0x05dc01e0 },
 	{ AR5K_XRTIMEOUT,	0x1f402710 },
@@ -760,9 +760,9 @@ static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
 
 static const struct ath5k_ini rf5111_ini_common_end[] = {
 	{ AR5K_DCU_FP,		0x00000000 },
-	{ AR5K_PHY_AGC, 	0x00000000 },
-	{ AR5K_PHY_ADC_CTL, 	0x00022ffe },
-	{ 0x983c, 		0x00020100 },
+	{ AR5K_PHY_AGC,		0x00000000 },
+	{ AR5K_PHY_ADC_CTL,	0x00022ffe },
+	{ 0x983c,		0x00020100 },
 	{ AR5K_PHY_GAIN_OFFSET,	0x1284613c },
 	{ AR5K_PHY_PAPD_PROBE,	0x00004883 },
 	{ 0x9940,		0x00000004 },
@@ -1409,7 +1409,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu)
 	 * Write initial register settings
 	 */
 
-	/* For AR5212 and combatible */
+	/* For AR5212 and compatible */
 	if (ah->ah_version == AR5K_AR5212) {
 
 		/* First set of mode-specific settings */

+ 4 - 4
drivers/net/wireless/ath/ath5k/led.c

@@ -43,16 +43,16 @@
 #include "ath5k.h"
 #include "base.h"
 
-#define ATH_SDEVICE(subv,subd) \
+#define ATH_SDEVICE(subv, subd) \
 	.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
 	.subvendor = (subv), .subdevice = (subd)
 
-#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
+#define ATH_LED(pin, polarity) .driver_data = (((pin) << 8) | (polarity))
 #define ATH_PIN(data) ((data) >> 8)
 #define ATH_POLARITY(data) ((data) & 0xff)
 
 /* Devices we match on for LED config info (typically laptops) */
-static const struct pci_device_id ath5k_led_devices[] = {
+static DEFINE_PCI_DEVICE_TABLE(ath5k_led_devices) = {
 	/* AR5211 */
 	{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
 	/* HP Compaq nc6xx, nc4000, nx6000 */
@@ -157,7 +157,7 @@ void ath5k_unregister_leds(struct ath5k_softc *sc)
 	ath5k_unregister_led(&sc->tx_led);
 }
 
-int ath5k_init_leds(struct ath5k_softc *sc)
+int __devinit ath5k_init_leds(struct ath5k_softc *sc)
 {
 	int ret = 0;
 	struct ieee80211_hw *hw = sc->hw;

+ 2 - 2
drivers/net/wireless/ath/ath5k/mac80211-ops.c

@@ -348,7 +348,7 @@ ath5k_prepare_multicast(struct ieee80211_hw *hw,
 		mfilt[pos / 32] |= (1 << (pos % 32));
 		/* XXX: we might be able to just do this instead,
 		* but not sure, needs testing, if we do use this we'd
-		* neet to inform below to not reset the mcast */
+		* need to inform below not to reset the mcast */
 		/* ath5k_hw_set_mcast_filterindex(ah,
 		 *      ha->addr[5]); */
 	}
@@ -471,7 +471,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 	if (iter_data.n_stas > 1) {
 		/* If you have multiple STA interfaces connected to
 		 * different APs, ARPs are not received (most of the time?)
-		 * Enabling PROMISC appears to fix that probem.
+		 * Enabling PROMISC appears to fix that problem.
 		 */
 		rfilt |= AR5K_RX_FILTER_PROM;
 	}

+ 7 - 7
drivers/net/wireless/ath/ath5k/pci.c

@@ -34,12 +34,12 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
 	{ PCI_VDEVICE(3COM_2,  0x0013) }, /* 3com 5212 */
 	{ PCI_VDEVICE(3COM,    0x0013) }, /* 3com 3CRDAG675 5212 */
 	{ PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
-	{ PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 compatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 compatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 compatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 compatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 compatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 compatible */
 	{ PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
 	{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
 	{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
@@ -234,7 +234,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 
 	mem = pci_iomap(pdev, 0, 0);
 	if (!mem) {
-		dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
+		dev_err(&pdev->dev, "cannot remap PCI memory region\n");
 		ret = -EIO;
 		goto err_reg;
 	}

+ 8 - 8
drivers/net/wireless/ath/ath5k/pcu.c

@@ -32,7 +32,7 @@
 #include "base.h"
 
 /*
- * AR5212+ can use higher rates for ack transmition
+ * AR5212+ can use higher rates for ack transmission
  * based on current tx rate instead of the base rate.
  * It does this to better utilize channel usage.
  * This is a mapping between G rates (that cover both
@@ -534,9 +534,9 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
 
 	local_irq_restore(flags);
 
-	WARN_ON( i == ATH5K_MAX_TSF_READ );
+	WARN_ON(i == ATH5K_MAX_TSF_READ);
 
-	return (((u64)tsf_upper1 << 32) | tsf_lower);
+	return ((u64)tsf_upper1 << 32) | tsf_lower;
 }
 
 /**
@@ -643,14 +643,14 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
 	/* Flush any pending BMISS interrupts on ISR by
 	 * performing a clear-on-write operation on PISR
 	 * register for the BMISS bit (writing a bit on
-	 * ISR togles a reset for that bit and leaves
-	 * the rest bits intact) */
+	 * ISR toggles a reset for that bit and leaves
+	 * the remaining bits intact) */
 	if (ah->ah_version == AR5K_AR5210)
 		ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
 	else
 		ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
 
-	/* TODO: Set enchanced sleep registers on AR5212
+	/* TODO: Set enhanced sleep registers on AR5212
 	 * based on vif->bss_conf params, until then
 	 * disable power save reporting.*/
 	AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
@@ -738,7 +738,7 @@ ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
 	dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3;
 
 	/* NOTE: SWBA is different. Having a wrong window there does not
-	 * stop us from sending data and this condition is catched thru
+	 * stop us from sending data and this condition is caught by
 	 * other means (SWBA interrupt) */
 
 	if (ath5k_check_timer_win(nbtt, atim, 1, intval) &&
@@ -896,7 +896,7 @@ void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	/* Set RSSI/BRSSI thresholds
 	 *
 	 * Note: If we decide to set this value
-	 * dynamicaly, have in mind that when AR5K_RSSI_THR
+	 * dynamically, have in mind that when AR5K_RSSI_THR
 	 * register is read it might return 0x40 if we haven't
 	 * wrote anything to it plus BMISS RSSI threshold is zeroed.
 	 * So doing a save/restore procedure here isn't the right

+ 53 - 47
drivers/net/wireless/ath/ath5k/phy.c

@@ -105,6 +105,7 @@ bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
 
 	if ((ah->ah_radio == AR5K_RF5112) ||
 	(ah->ah_radio == AR5K_RF5413) ||
+	(ah->ah_radio == AR5K_RF2413) ||
 	(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
 		refclk_freq = 40;
 	else
@@ -173,7 +174,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
 		data = ath5k_hw_bitswap(val, num_bits);
 
 	for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
-	position = 0, entry++) {
+	     position = 0, entry++) {
 
 		last_bit = (position + bits_left > 8) ? 8 :
 					position + bits_left;
@@ -363,7 +364,7 @@ int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
 	return 0;
 }
 
-/* Schedule a gain probe check on the next transmited packet.
+/* Schedule a gain probe check on the next transmitted packet.
  * That means our next packet is going to be sent with lower
  * tx power and a Peak to Average Power Detector (PAPD) will try
  * to measure the gain.
@@ -472,7 +473,7 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
 		level[0] = 0;
 		level[1] = (step == 63) ? 50 : step + 4;
 		level[2] = (step != 63) ? 64 : level[0];
-		level[3] = level[2] + 50 ;
+		level[3] = level[2] + 50;
 
 		ah->ah_gain.g_high = level[3] -
 			(step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
@@ -549,7 +550,7 @@ static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
 
 		for (ah->ah_gain.g_target = ah->ah_gain.g_current;
 				ah->ah_gain.g_target <= ah->ah_gain.g_low &&
-				ah->ah_gain.g_step_idx < go->go_steps_count-1;
+				ah->ah_gain.g_step_idx < go->go_steps_count - 1;
 				g_step = &go->go_step[ah->ah_gain.g_step_idx])
 			ah->ah_gain.g_target -= 2 *
 			    (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
@@ -614,13 +615,13 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
 			ath5k_hw_rf_gainf_corr(ah);
 			ah->ah_gain.g_current =
 				ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
-				(ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
+				(ah->ah_gain.g_current - ah->ah_gain.g_f_corr) :
 				0;
 		}
 
 		/* Check if measurement is ok and if we need
 		 * to adjust gain, schedule a gain adjustment,
-		 * else switch back to the acive state */
+		 * else switch back to the active state */
 		if (ath5k_hw_rf_check_gainf_readback(ah) &&
 		AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
 		ath5k_hw_rf_gainf_adjust(ah)) {
@@ -807,7 +808,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
 		 * use b_OB and b_DB parameters stored
 		 * in eeprom on ee->ee_ob[ee_mode][0]
 		 *
-		 * For all other chips we use OB/DB for 2Ghz
+		 * For all other chips we use OB/DB for 2GHz
 		 * stored in the b/g modal section just like
 		 * 802.11a on ee->ee_ob[ee_mode][1] */
 		if ((ah->ah_radio == AR5K_RF5111) ||
@@ -970,17 +971,20 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
 			}
 
 			/* Lower synth voltage on Rev 2 */
-			ath5k_hw_rfb_op(ah, rf_regs, 2,
-					AR5K_RF_HIGH_VC_CP, true);
+			if (ah->ah_radio == AR5K_RF5112 &&
+			    (ah->ah_radio_5ghz_revision & AR5K_SREV_REV) > 0) {
+				ath5k_hw_rfb_op(ah, rf_regs, 2,
+						AR5K_RF_HIGH_VC_CP, true);
 
-			ath5k_hw_rfb_op(ah, rf_regs, 2,
-					AR5K_RF_MID_VC_CP, true);
+				ath5k_hw_rfb_op(ah, rf_regs, 2,
+						AR5K_RF_MID_VC_CP, true);
 
-			ath5k_hw_rfb_op(ah, rf_regs, 2,
-					AR5K_RF_LOW_VC_CP, true);
+				ath5k_hw_rfb_op(ah, rf_regs, 2,
+						AR5K_RF_LOW_VC_CP, true);
 
-			ath5k_hw_rfb_op(ah, rf_regs, 2,
-					AR5K_RF_PUSH_UP, true);
+				ath5k_hw_rfb_op(ah, rf_regs, 2,
+						AR5K_RF_PUSH_UP, true);
+			}
 
 			/* Decrease power consumption on 5213+ BaseBand */
 			if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
@@ -1259,7 +1263,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,
 {
 	int ret;
 	/*
-	 * Check bounds supported by the PHY (we don't care about regultory
+	 * Check bounds supported by the PHY (we don't care about regulatory
 	 * restrictions at this point). Note: hw_value already has the band
 	 * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok()
 	 * of the band by that */
@@ -1331,7 +1335,7 @@ void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
 static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor)
 {
 	struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist;
-	hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX-1);
+	hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX - 1);
 	hist->nfval[hist->index] = noise_floor;
 }
 
@@ -1344,10 +1348,10 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
 	memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort));
 	for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) {
 		for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) {
-			if (sort[j] > sort[j-1]) {
+			if (sort[j] > sort[j - 1]) {
 				tmp = sort[j];
-				sort[j] = sort[j-1];
-				sort[j-1] = tmp;
+				sort[j] = sort[j - 1];
+				sort[j - 1] = tmp;
 			}
 		}
 	}
@@ -1355,7 +1359,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
 		ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
 			"cal %d:%d\n", i, sort[i]);
 	}
-	return sort[(ATH5K_NF_CAL_HIST_MAX-1) / 2];
+	return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2];
 }
 
 /*
@@ -1604,11 +1608,13 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
 	int ret;
 
 	if (ah->ah_radio == AR5K_RF5110)
-		ret = ath5k_hw_rf5110_calibrate(ah, channel);
-	else {
-		ret = ath5k_hw_rf511x_iq_calibrate(ah);
+		return ath5k_hw_rf5110_calibrate(ah, channel);
+
+	ret = ath5k_hw_rf511x_iq_calibrate(ah);
+
+	if ((ah->ah_radio == AR5K_RF5111 || ah->ah_radio == AR5K_RF5112) &&
+	    (channel->hw_value & CHANNEL_OFDM))
 		ath5k_hw_request_rfgain_probe(ah);
-	}
 
 	return ret;
 }
@@ -1815,7 +1821,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
 
 	} else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) &
 	AR5K_PHY_IQ_SPUR_FILT_EN) {
-		/* Clean up spur mitigation settings and disable fliter */
+		/* Clean up spur mitigation settings and disable filter */
 		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
 					AR5K_PHY_BIN_MASK_CTL_RATE, 0);
 		AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ,
@@ -2080,7 +2086,7 @@ ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
 	 * always 1 instead of 1.25, 1.75 etc). We scale up by 100
 	 * to have some accuracy both for 0.5 and 0.25 steps.
 	 */
-	ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
+	ratio = ((100 * y_right - 100 * y_left) / (x_right - x_left));
 
 	/* Now scale down to be in range */
 	result = y_left + (ratio * (target - x_left) / 100);
@@ -2159,7 +2165,7 @@ ath5k_create_power_curve(s16 pmin, s16 pmax,
 			u8 *vpd_table, u8 type)
 {
 	u8 idx[2] = { 0, 1 };
-	s16 pwr_i = 2*pmin;
+	s16 pwr_i = 2 * pmin;
 	int i;
 
 	if (num_points < 2)
@@ -2437,7 +2443,7 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
 	}
 
 	if (edge_pwr)
-		ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
+		ah->ah_txpower.txp_max_pwr = 4 * min(edge_pwr, max_chan_pwr);
 }
 
 
@@ -2456,7 +2462,7 @@ static void
 ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
 							s16 *table_max)
 {
-	u8 	*pcdac_out = ah->ah_txpower.txp_pd_table;
+	u8	*pcdac_out = ah->ah_txpower.txp_pd_table;
 	u8	*pcdac_tmp = ah->ah_txpower.tmpL[0];
 	u8	pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
 	s16	min_pwr, max_pwr;
@@ -2475,8 +2481,8 @@ ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
 
 	/* Copy values from pcdac_tmp */
 	pwr_idx = min_pwr;
-	for (i = 0 ; pwr_idx <= max_pwr &&
-	pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
+	for (i = 0; pwr_idx <= max_pwr &&
+		    pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
 		pcdac_out[pcdac_i++] = pcdac_tmp[i];
 		pwr_idx++;
 	}
@@ -2502,7 +2508,7 @@ static void
 ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
 						s16 *table_max, u8 pdcurves)
 {
-	u8 	*pcdac_out = ah->ah_txpower.txp_pd_table;
+	u8	*pcdac_out = ah->ah_txpower.txp_pd_table;
 	u8	*pcdac_low_pwr;
 	u8	*pcdac_high_pwr;
 	u8	*pcdac_tmp;
@@ -2510,8 +2516,8 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
 	s16	max_pwr_idx;
 	s16	min_pwr_idx;
 	s16	mid_pwr_idx = 0;
-	/* Edge flag turs on the 7nth bit on the PCDAC
-	 * to delcare the higher power curve (force values
+	/* Edge flag turns on the 7nth bit on the PCDAC
+	 * to declare the higher power curve (force values
 	 * to be greater than 64). If we only have one curve
 	 * we don't need to set this, if we have 2 curves and
 	 * fill the table backwards this can also be used to
@@ -2552,7 +2558,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
 	}
 
 	/* This is used when setting tx power*/
-	ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
+	ah->ah_txpower.txp_min_idx = min_pwr_idx / 2;
 
 	/* Fill Power to PCDAC table backwards */
 	pwr = max_pwr_idx;
@@ -2561,14 +2567,14 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
 		 * edge flag and set pcdac_tmp to lower
 		 * power curve.*/
 		if (edge_flag == 0x40 &&
-		(2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
+		(2 * pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
 			edge_flag = 0x00;
 			pcdac_tmp = pcdac_low_pwr;
-			pwr = mid_pwr_idx/2;
+			pwr = mid_pwr_idx / 2;
 		}
 
 		/* Don't go below 1, extrapolate below if we have
-		 * already swithced to the lower power curve -or
+		 * already switched to the lower power curve -or
 		 * we only have one curve and edge_flag is zero
 		 * anyway */
 		if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
@@ -2596,7 +2602,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
 static void
 ath5k_write_pcdac_table(struct ath5k_hw *ah)
 {
-	u8 	*pcdac_out = ah->ah_txpower.txp_pd_table;
+	u8	*pcdac_out = ah->ah_txpower.txp_pd_table;
 	int	i;
 
 	/*
@@ -2604,8 +2610,8 @@ ath5k_write_pcdac_table(struct ath5k_hw *ah)
 	 */
 	for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
 		ath5k_hw_reg_write(ah,
-			(((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
-			(((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
+			(((pcdac_out[2 * i + 0] << 8 | 0xff) & 0xffff) << 0) |
+			(((pcdac_out[2 * i + 1] << 8 | 0xff) & 0xffff) << 16),
 			AR5K_PHY_PCDAC_TXPOWER(i));
 	}
 }
@@ -2789,10 +2795,10 @@ ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
 	 */
 	for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
 		ath5k_hw_reg_write(ah,
-			((pdadc_out[4*i + 0] & 0xff) << 0) |
-			((pdadc_out[4*i + 1] & 0xff) << 8) |
-			((pdadc_out[4*i + 2] & 0xff) << 16) |
-			((pdadc_out[4*i + 3] & 0xff) << 24),
+			((pdadc_out[4 * i + 0] & 0xff) << 0) |
+			((pdadc_out[4 * i + 1] & 0xff) << 8) |
+			((pdadc_out[4 * i + 2] & 0xff) << 16) |
+			((pdadc_out[4 * i + 3] & 0xff) << 24),
 			AR5K_PHY_PDADC_TXPOWER(i));
 	}
 }
@@ -2805,7 +2811,7 @@ ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
 /*
  * This is the main function that uses all of the above
  * to set PCDAC/PDADC table on hw for the current channel.
- * This table is used for tx power calibration on the basband,
+ * This table is used for tx power calibration on the baseband,
  * without it we get weird tx power levels and in some cases
  * distorted spectral mask
  */

+ 45 - 44
drivers/net/wireless/ath/ath5k/reg.h

@@ -72,7 +72,7 @@
 #define	AR5K_CFG_SWRD		0x00000004	/* Byte-swap RX descriptor */
 #define	AR5K_CFG_SWRB		0x00000008	/* Byte-swap RX buffer */
 #define	AR5K_CFG_SWRG		0x00000010	/* Byte-swap Register access */
-#define AR5K_CFG_IBSS		0x00000020 	/* 0-BSS, 1-IBSS [5211+] */
+#define AR5K_CFG_IBSS		0x00000020	/* 0-BSS, 1-IBSS [5211+] */
 #define AR5K_CFG_PHY_OK		0x00000100	/* [5211+] */
 #define AR5K_CFG_EEBS		0x00000200	/* EEPROM is busy */
 #define	AR5K_CFG_CLKGD		0x00000400	/* Clock gated (Disable dynamic clock) */
@@ -170,7 +170,7 @@
 #define AR5K_TXCFG_SDMAMR_S		0
 #define AR5K_TXCFG_B_MODE		0x00000008	/* Set b mode for 5111 (enable 2111) */
 #define AR5K_TXCFG_TXFSTP		0x00000008	/* TX DMA full Stop [5210] */
-#define AR5K_TXCFG_TXFULL		0x000003f0	/* TX Triger level mask */
+#define AR5K_TXCFG_TXFULL		0x000003f0	/* TX Trigger level mask */
 #define AR5K_TXCFG_TXFULL_S		4
 #define AR5K_TXCFG_TXFULL_0B		0x00000000
 #define AR5K_TXCFG_TXFULL_64B		0x00000010
@@ -283,16 +283,16 @@
  */
 #define AR5K_ISR		0x001c			/* Register Address [5210] */
 #define AR5K_PISR		0x0080			/* Register Address [5211+] */
-#define AR5K_ISR_RXOK		0x00000001	/* Frame successfuly received */
+#define AR5K_ISR_RXOK		0x00000001	/* Frame successfully received */
 #define AR5K_ISR_RXDESC		0x00000002	/* RX descriptor request */
 #define AR5K_ISR_RXERR		0x00000004	/* Receive error */
 #define AR5K_ISR_RXNOFRM	0x00000008	/* No frame received (receive timeout) */
 #define AR5K_ISR_RXEOL		0x00000010	/* Empty RX descriptor */
 #define AR5K_ISR_RXORN		0x00000020	/* Receive FIFO overrun */
-#define AR5K_ISR_TXOK		0x00000040	/* Frame successfuly transmited */
+#define AR5K_ISR_TXOK		0x00000040	/* Frame successfully transmitted */
 #define AR5K_ISR_TXDESC		0x00000080	/* TX descriptor request */
 #define AR5K_ISR_TXERR		0x00000100	/* Transmit error */
-#define AR5K_ISR_TXNOFRM	0x00000200	/* No frame transmited (transmit timeout) */
+#define AR5K_ISR_TXNOFRM	0x00000200	/* No frame transmitted (transmit timeout) */
 #define AR5K_ISR_TXEOL		0x00000400	/* Empty TX descriptor */
 #define AR5K_ISR_TXURN		0x00000800	/* Transmit FIFO underrun */
 #define AR5K_ISR_MIB		0x00001000	/* Update MIB counters */
@@ -303,7 +303,7 @@
 #define AR5K_ISR_BRSSI		0x00020000	/* Beacon rssi below threshold (?) */
 #define AR5K_ISR_BMISS		0x00040000	/* Beacon missed */
 #define AR5K_ISR_HIUERR		0x00080000	/* Host Interface Unit error [5211+] */
-#define AR5K_ISR_BNR		0x00100000 	/* Beacon not ready [5211+] */
+#define AR5K_ISR_BNR		0x00100000	/* Beacon not ready [5211+] */
 #define AR5K_ISR_MCABT		0x00100000	/* Master Cycle Abort [5210] */
 #define AR5K_ISR_RXCHIRP	0x00200000	/* CHIRP Received [5212+] */
 #define AR5K_ISR_SSERR		0x00200000	/* Signaled System Error [5210] */
@@ -377,16 +377,16 @@
  */
 #define	AR5K_IMR		0x0020			/* Register Address [5210] */
 #define AR5K_PIMR		0x00a0			/* Register Address [5211+] */
-#define AR5K_IMR_RXOK		0x00000001	/* Frame successfuly received*/
+#define AR5K_IMR_RXOK		0x00000001	/* Frame successfully received*/
 #define AR5K_IMR_RXDESC		0x00000002	/* RX descriptor request*/
 #define AR5K_IMR_RXERR		0x00000004	/* Receive error*/
 #define AR5K_IMR_RXNOFRM	0x00000008	/* No frame received (receive timeout)*/
 #define AR5K_IMR_RXEOL		0x00000010	/* Empty RX descriptor*/
 #define AR5K_IMR_RXORN		0x00000020	/* Receive FIFO overrun*/
-#define AR5K_IMR_TXOK		0x00000040	/* Frame successfuly transmited*/
+#define AR5K_IMR_TXOK		0x00000040	/* Frame successfully transmitted*/
 #define AR5K_IMR_TXDESC		0x00000080	/* TX descriptor request*/
 #define AR5K_IMR_TXERR		0x00000100	/* Transmit error*/
-#define AR5K_IMR_TXNOFRM	0x00000200	/* No frame transmited (transmit timeout)*/
+#define AR5K_IMR_TXNOFRM	0x00000200	/* No frame transmitted (transmit timeout)*/
 #define AR5K_IMR_TXEOL		0x00000400	/* Empty TX descriptor*/
 #define AR5K_IMR_TXURN		0x00000800	/* Transmit FIFO underrun*/
 #define AR5K_IMR_MIB		0x00001000	/* Update MIB counters*/
@@ -397,7 +397,7 @@
 #define AR5K_IMR_BRSSI		0x00020000	/* Beacon rssi below threshold (?) */
 #define AR5K_IMR_BMISS		0x00040000	/* Beacon missed*/
 #define AR5K_IMR_HIUERR		0x00080000	/* Host Interface Unit error [5211+] */
-#define AR5K_IMR_BNR		0x00100000 	/* Beacon not ready [5211+] */
+#define AR5K_IMR_BNR		0x00100000	/* Beacon not ready [5211+] */
 #define AR5K_IMR_MCABT		0x00100000	/* Master Cycle Abort [5210] */
 #define AR5K_IMR_RXCHIRP	0x00200000	/* CHIRP Received [5212+]*/
 #define AR5K_IMR_SSERR		0x00200000	/* Signaled System Error [5210] */
@@ -601,7 +601,7 @@
  * QCU misc registers
  */
 #define AR5K_QCU_MISC_BASE		0x09c0			/* Register Address -Queue0 MISC */
-#define	AR5K_QCU_MISC_FRSHED_M		0x0000000f	/* Frame sheduling mask */
+#define	AR5K_QCU_MISC_FRSHED_M		0x0000000f	/* Frame scheduling mask */
 #define	AR5K_QCU_MISC_FRSHED_ASAP		0	/* ASAP */
 #define	AR5K_QCU_MISC_FRSHED_CBR		1	/* Constant Bit Rate */
 #define	AR5K_QCU_MISC_FRSHED_DBA_GT		2	/* DMA Beacon alert gated */
@@ -653,13 +653,13 @@
  * registers [5211+]
  *
  * These registers control the various characteristics of each queue
- * for 802.11e (WME) combatibility so they go together with
+ * for 802.11e (WME) compatibility so they go together with
  * QCU registers in pairs. For each queue we have a QCU mask register,
  * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c),
  * a retry limit register (0x1080 - 0x10ac), a channel time register
  * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and
  * a sequence number register (0x1140 - 0x116c). It seems that "global"
- * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k).
+ * registers here affect all queues (see use of DCU_GBL_IFS_SLOT in ar5k).
  * We use the same macros here for easier register access.
  *
  */
@@ -779,7 +779,7 @@
  * and it's used for generating pseudo-random
  * number sequences.
  *
- * (If i understand corectly, random numbers are
+ * (If i understand correctly, random numbers are
  * used for idle sensing -multiplied with cwmin/max etc-)
  */
 #define AR5K_DCU_GBL_IFS_MISC			0x10f0			/* Register Address */
@@ -1007,7 +1007,7 @@
 #define	AR5K_PCIE_WAEN	0x407c
 
 /*
- * PCI-E Serializer/Desirializer
+ * PCI-E Serializer/Deserializer
  * registers
  */
 #define	AR5K_PCIE_SERDES	0x4080
@@ -1227,7 +1227,7 @@
 					AR5K_USEC_5210 : AR5K_USEC_5211)
 #define AR5K_USEC_1			0x0000007f	/* clock cycles for 1us */
 #define AR5K_USEC_1_S			0
-#define AR5K_USEC_32			0x00003f80	/* clock cycles for 1us while on 32Mhz clock */
+#define AR5K_USEC_32			0x00003f80	/* clock cycles for 1us while on 32MHz clock */
 #define AR5K_USEC_32_S			7
 #define AR5K_USEC_TX_LATENCY_5211	0x007fc000
 #define AR5K_USEC_TX_LATENCY_5211_S	14
@@ -1328,16 +1328,16 @@
 #define AR5K_RX_FILTER_5211	0x803c			/* Register Address [5211+] */
 #define AR5K_RX_FILTER		(ah->ah_version == AR5K_AR5210 ? \
 				AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211)
-#define	AR5K_RX_FILTER_UCAST 	0x00000001	/* Don't filter unicast frames */
-#define	AR5K_RX_FILTER_MCAST 	0x00000002	/* Don't filter multicast frames */
-#define	AR5K_RX_FILTER_BCAST 	0x00000004	/* Don't filter broadcast frames */
-#define	AR5K_RX_FILTER_CONTROL 	0x00000008	/* Don't filter control frames */
-#define	AR5K_RX_FILTER_BEACON 	0x00000010	/* Don't filter beacon frames */
-#define	AR5K_RX_FILTER_PROM 	0x00000020	/* Set promiscuous mode */
-#define	AR5K_RX_FILTER_XRPOLL 	0x00000040	/* Don't filter XR poll frame [5212+] */
+#define	AR5K_RX_FILTER_UCAST	0x00000001	/* Don't filter unicast frames */
+#define	AR5K_RX_FILTER_MCAST	0x00000002	/* Don't filter multicast frames */
+#define	AR5K_RX_FILTER_BCAST	0x00000004	/* Don't filter broadcast frames */
+#define	AR5K_RX_FILTER_CONTROL	0x00000008	/* Don't filter control frames */
+#define	AR5K_RX_FILTER_BEACON	0x00000010	/* Don't filter beacon frames */
+#define	AR5K_RX_FILTER_PROM	0x00000020	/* Set promiscuous mode */
+#define	AR5K_RX_FILTER_XRPOLL	0x00000040	/* Don't filter XR poll frame [5212+] */
 #define	AR5K_RX_FILTER_PROBEREQ 0x00000080	/* Don't filter probe requests [5212+] */
 #define	AR5K_RX_FILTER_PHYERR_5212	0x00000100	/* Don't filter phy errors [5212+] */
-#define	AR5K_RX_FILTER_RADARERR_5212 	0x00000200	/* Don't filter phy radar errors [5212+] */
+#define	AR5K_RX_FILTER_RADARERR_5212	0x00000200	/* Don't filter phy radar errors [5212+] */
 #define AR5K_RX_FILTER_PHYERR_5211	0x00000040	/* [5211] */
 #define AR5K_RX_FILTER_RADARERR_5211	0x00000080	/* [5211] */
 #define AR5K_RX_FILTER_PHYERR  \
@@ -1461,7 +1461,7 @@
  * ADDAC test register [5211+]
  */
 #define AR5K_ADDAC_TEST			0x8054			/* Register Address */
-#define AR5K_ADDAC_TEST_TXCONT 		0x00000001	/* Test continuous tx */
+#define AR5K_ADDAC_TEST_TXCONT		0x00000001	/* Test continuous tx */
 #define AR5K_ADDAC_TEST_TST_MODE	0x00000002	/* Test mode */
 #define AR5K_ADDAC_TEST_LOOP_EN		0x00000004	/* Enable loop */
 #define AR5K_ADDAC_TEST_LOOP_LEN	0x00000008	/* Loop length (field) */
@@ -1632,7 +1632,7 @@
 #define AR5K_SLEEP0_NEXT_DTIM		0x0007ffff	/* Mask for next DTIM (?) */
 #define AR5K_SLEEP0_NEXT_DTIM_S		0
 #define AR5K_SLEEP0_ASSUME_DTIM		0x00080000	/* Assume DTIM */
-#define AR5K_SLEEP0_ENH_SLEEP_EN	0x00100000	/* Enable enchanced sleep control */
+#define AR5K_SLEEP0_ENH_SLEEP_EN	0x00100000	/* Enable enhanced sleep control */
 #define AR5K_SLEEP0_CABTO		0xff000000	/* Mask for CAB Time Out */
 #define AR5K_SLEEP0_CABTO_S		24
 
@@ -1657,7 +1657,7 @@
 /*
  * TX power control (TPC) register
  *
- * XXX: PCDAC steps (0.5dbm) or DBM ?
+ * XXX: PCDAC steps (0.5dBm) or dBm ?
  *
  */
 #define AR5K_TXPC			0x80e8			/* Register Address */
@@ -1673,7 +1673,7 @@
 /*
  * Profile count registers
  *
- * These registers can be cleared and freezed with ATH5K_MIBC, but they do not
+ * These registers can be cleared and frozen with ATH5K_MIBC, but they do not
  * generate a MIB interrupt.
  * Instead of overflowing, they shift by one bit to the right. All registers
  * shift together, i.e. when one reaches the max, all shift at the same time by
@@ -1838,7 +1838,7 @@
 #define AR5K_PHY_TST2_TRIG_SEL		0x00000007	/* Trigger select (?)*/
 #define AR5K_PHY_TST2_TRIG		0x00000010	/* Trigger (?) */
 #define AR5K_PHY_TST2_CBUS_MODE		0x00000060	/* Cardbus mode (?) */
-#define AR5K_PHY_TST2_CLK32		0x00000400	/* CLK_OUT is CLK32 (32Khz external) */
+#define AR5K_PHY_TST2_CLK32		0x00000400	/* CLK_OUT is CLK32 (32kHz external) */
 #define AR5K_PHY_TST2_CHANCOR_DUMP_EN	0x00000800	/* Enable Chancor dump (?) */
 #define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP	0x00001000	/* Even Chancor dump (?) */
 #define AR5K_PHY_TST2_RFSILENT_EN	0x00002000	/* Enable RFSILENT */
@@ -2002,7 +2002,7 @@
 #define	AR5K_PHY_AGCCTL_OFDM_DIV_DIS	0x00000008	/* Disable antenna diversity on OFDM modes */
 #define	AR5K_PHY_AGCCTL_NF_EN		0x00008000	/* Enable nf calibration to happen (?) */
 #define	AR5K_PHY_AGCTL_FLTR_CAL		0x00010000	/* Allow filter calibration (?) */
-#define	AR5K_PHY_AGCCTL_NF_NOUPDATE	0x00020000	/* Don't update nf automaticaly */
+#define	AR5K_PHY_AGCCTL_NF_NOUPDATE	0x00020000	/* Don't update nf automatically */
 
 /*
  * PHY noise floor status register (CCA = Clear Channel Assessment)
@@ -2038,7 +2038,7 @@
 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S	24
 
 /* Low thresholds */
-#define AR5K_PHY_WEAK_OFDM_LOW_THR 		0x986c
+#define AR5K_PHY_WEAK_OFDM_LOW_THR		0x986c
 #define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN	0x00000001
 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT	0x00003f00
 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S	8
@@ -2089,7 +2089,7 @@
  *
  * It's obvious from the code that 0x989c is the buffer register but
  * for the other special registers that we write to after sending each
- * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
+ * packet, i have no idea. So I'll name them BUFFER_CONTROL_X registers
  * for now. It's interesting that they are also used for some other operations.
  */
 
@@ -2259,12 +2259,13 @@
 #define	AR5K_PHY_FRAME_CTL_ILLLEN_ERR	0x08000000	/* Illegal length */
 #define	AR5K_PHY_FRAME_CTL_SERVICE_ERR	0x20000000
 #define	AR5K_PHY_FRAME_CTL_TXURN_ERR	0x40000000	/* TX underrun */
-#define AR5K_PHY_FRAME_CTL_INI		AR5K_PHY_FRAME_CTL_SERVICE_ERR | \
-			AR5K_PHY_FRAME_CTL_TXURN_ERR | \
-			AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \
-			AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \
-			AR5K_PHY_FRAME_CTL_PARITY_ERR | \
-			AR5K_PHY_FRAME_CTL_TIMING_ERR
+#define AR5K_PHY_FRAME_CTL_INI	\
+			(AR5K_PHY_FRAME_CTL_SERVICE_ERR | \
+			 AR5K_PHY_FRAME_CTL_TXURN_ERR | \
+			 AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \
+			 AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \
+			 AR5K_PHY_FRAME_CTL_PARITY_ERR | \
+			 AR5K_PHY_FRAME_CTL_TIMING_ERR)
 
 /*
  * PHY Tx Power adjustment register [5212A+]
@@ -2281,22 +2282,22 @@
 #define	AR5K_PHY_RADAR			0x9954
 #define	AR5K_PHY_RADAR_ENABLE		0x00000001
 #define	AR5K_PHY_RADAR_DISABLE		0x00000000
-#define AR5K_PHY_RADAR_INBANDTHR    	0x0000003e	/* Inband threshold
+#define AR5K_PHY_RADAR_INBANDTHR	0x0000003e	/* Inband threshold
 							5-bits, units unknown {0..31}
 							(? MHz ?) */
 #define AR5K_PHY_RADAR_INBANDTHR_S	1
 
-#define AR5K_PHY_RADAR_PRSSI_THR    	0x00000fc0	/* Pulse RSSI/SNR threshold
+#define AR5K_PHY_RADAR_PRSSI_THR	0x00000fc0	/* Pulse RSSI/SNR threshold
 							6-bits, dBm range {0..63}
 							in dBm units. */
 #define AR5K_PHY_RADAR_PRSSI_THR_S	6
 
-#define AR5K_PHY_RADAR_PHEIGHT_THR   	0x0003f000	/* Pulse height threshold
+#define AR5K_PHY_RADAR_PHEIGHT_THR	0x0003f000	/* Pulse height threshold
 							6-bits, dBm range {0..63}
 							in dBm units. */
 #define AR5K_PHY_RADAR_PHEIGHT_THR_S	12
 
-#define AR5K_PHY_RADAR_RSSI_THR    	0x00fc0000	/* Radar RSSI/SNR threshold.
+#define AR5K_PHY_RADAR_RSSI_THR		0x00fc0000	/* Radar RSSI/SNR threshold.
 							6-bits, dBm range {0..63}
 							in dBm units. */
 #define AR5K_PHY_RADAR_RSSI_THR_S	18
@@ -2339,7 +2340,7 @@
 #define AR5K_PHY_RESTART_DIV_GC_S	18
 
 /*
- * RF Bus access request register (for synth-oly channel switching)
+ * RF Bus access request register (for synth-only channel switching)
  */
 #define AR5K_PHY_RFBUS_REQ		0x997C
 #define AR5K_PHY_RFBUS_REQ_REQUEST	0x00000001
@@ -2381,7 +2382,7 @@
  */
 #define	AR5K_BB_GAIN_BASE		0x9b00	/* BaseBand Amplifier Gain table base address */
 #define AR5K_BB_GAIN(_n)		(AR5K_BB_GAIN_BASE + ((_n) << 2))
-#define	AR5K_RF_GAIN_BASE		0x9a00	/* RF Amplrifier Gain table base address */
+#define	AR5K_RF_GAIN_BASE		0x9a00	/* RF Amplifier Gain table base address */
 #define AR5K_RF_GAIN(_n)		(AR5K_RF_GAIN_BASE + ((_n) << 2))
 
 /*

+ 30 - 15
drivers/net/wireless/ath/ath5k/reset.c

@@ -25,7 +25,7 @@
 
 #include <asm/unaligned.h>
 
-#include <linux/pci.h> 		/* To determine if a card is pci-e */
+#include <linux/pci.h>		/* To determine if a card is pci-e */
 #include <linux/log2.h>
 #include <linux/platform_device.h>
 #include "ath5k.h"
@@ -142,10 +142,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
 
 	/* Set 32MHz USEC counter */
 	if ((ah->ah_radio == AR5K_RF5112) ||
-		(ah->ah_radio == AR5K_RF5413) ||
-		(ah->ah_radio == AR5K_RF2316) ||
-		(ah->ah_radio == AR5K_RF2317))
-	/* Remain on 40MHz clock ? */
+	    (ah->ah_radio == AR5K_RF2413) ||
+	    (ah->ah_radio == AR5K_RF5413) ||
+	    (ah->ah_radio == AR5K_RF2316) ||
+	    (ah->ah_radio == AR5K_RF2317))
+		/* Remain on 40MHz clock ? */
 		sclock = 40 - 1;
 	else
 		sclock = 32 - 1;
@@ -213,7 +214,7 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
 	usec_reg = (usec | sclock | txlat | rxlat);
 	ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC);
 
-	/* On 5112 set tx frane to tx data start delay */
+	/* On 5112 set tx frame to tx data start delay */
 	if (ah->ah_radio == AR5K_RF5112) {
 		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2,
 					AR5K_PHY_RF_CTL2_TXF2TXD_START,
@@ -233,7 +234,7 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
 static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
 {
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-	u32 scal, spending;
+	u32 scal, spending, sclock;
 
 	/* Only set 32KHz settings if we have an external
 	 * 32KHz crystal present */
@@ -317,6 +318,15 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
 
 		/* Set up tsf increment on each cycle */
 		AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
+
+		if ((ah->ah_radio == AR5K_RF5112) ||
+			(ah->ah_radio == AR5K_RF5413) ||
+			(ah->ah_radio == AR5K_RF2316) ||
+			(ah->ah_radio == AR5K_RF2317))
+			sclock = 40 - 1;
+		else
+			sclock = 32 - 1;
+		AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, sclock);
 	}
 }
 
@@ -375,7 +385,7 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
 static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
 {
 	u32 mask = flags ? flags : ~0U;
-	volatile __iomem u32 *reg;
+	u32 __iomem *reg;
 	u32 regval;
 	u32 val = 0;
 
@@ -539,7 +549,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
 	 *
 	 * Note: putting PCI core on warm reset on PCI-E cards
 	 * results card to hang and always return 0xffff... so
-	 * we ingore that flag for PCI-E cards. On PCI cards
+	 * we ignore that flag for PCI-E cards. On PCI cards
 	 * this flag gets cleared after 64 PCI clocks.
 	 */
 	bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;
@@ -596,7 +606,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 	 *
 	 * Note: putting PCI core on warm reset on PCI-E cards
 	 * results card to hang and always return 0xffff... so
-	 * we ingore that flag for PCI-E cards. On PCI cards
+	 * we ignore that flag for PCI-E cards. On PCI cards
 	 * this flag gets cleared after 64 PCI clocks.
 	 */
 	bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;
@@ -627,7 +637,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 		return ret;
 	}
 
-	/* ...reset configuration regiter on Wisoc ...
+	/* ...reset configuration register on Wisoc ...
 	 * ...clear reset control register and pull device out of
 	 * warm reset on others */
 	if (ath5k_get_bus_type(ah) == ATH_AHB)
@@ -704,7 +714,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 
 		/*XXX: Can bwmode be used with dynamic mode ?
 		 * (I don't think it supports 44MHz) */
-		/* On 2425 initvals TURBO_SHORT is not pressent */
+		/* On 2425 initvals TURBO_SHORT is not present */
 		if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
 			turbo = AR5K_PHY_TURBO_MODE |
 				(ah->ah_radio == AR5K_RF2425) ? 0 :
@@ -1277,11 +1287,16 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	ath5k_hw_dma_init(ah);
 
 
-	/* Enable 32KHz clock function for AR5212+ chips
+	/*
+	 * Enable 32KHz clock function for AR5212+ chips
 	 * Set clocks to 32KHz operation and use an
 	 * external 32KHz crystal when sleeping if one
-	 * exists */
-	if (ah->ah_version == AR5K_AR5212 &&
+	 * exists.
+	 * Disabled by default because it is also disabled in
+	 * other drivers and it is known to cause stability
+	 * issues on some devices
+	 */
+	if (ah->ah_use_32khz_clock && ah->ah_version == AR5K_AR5212 &&
 	    op_mode != NL80211_IFTYPE_AP)
 		ath5k_hw_set_sleep_clock(ah, true);
 

+ 2 - 2
drivers/net/wireless/ath/ath5k/rfbuffer.h

@@ -254,7 +254,7 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = {
 
 /* RFX112 (Derby 1) */
 
-/* BANK 6 				len  pos col */
+/* BANK 6				len  pos col */
 #define	AR5K_RF5112_OB_2GHZ		{ 3, 269, 0 }
 #define	AR5K_RF5112_DB_2GHZ		{ 3, 272, 0 }
 
@@ -495,7 +495,7 @@ static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
 /* BANK 2				len  pos col */
 #define AR5K_RF2413_RF_TURBO		{ 1, 1,   2 }
 
-/* BANK 6 				len  pos col */
+/* BANK 6				len  pos col */
 #define	AR5K_RF2413_OB_2GHZ		{ 3, 168, 0 }
 #define	AR5K_RF2413_DB_2GHZ		{ 3, 165, 0 }
 

+ 4 - 4
drivers/net/wireless/ath/ath5k/rfgain.h

@@ -30,7 +30,7 @@ struct ath5k_ini_rfgain {
 
 /* Initial RF Gain settings for RF5111 */
 static const struct ath5k_ini_rfgain rfgain_5111[] = {
-	/*			      5Ghz	2Ghz	*/
+	/*			      5GHz	2GHz	*/
 	{ AR5K_RF_GAIN(0),	{ 0x000001a9, 0x00000000 } },
 	{ AR5K_RF_GAIN(1),	{ 0x000001e9, 0x00000040 } },
 	{ AR5K_RF_GAIN(2),	{ 0x00000029, 0x00000080 } },
@@ -99,7 +99,7 @@ static const struct ath5k_ini_rfgain rfgain_5111[] = {
 
 /* Initial RF Gain settings for RF5112 */
 static const struct ath5k_ini_rfgain rfgain_5112[] = {
-	/*			      5Ghz	2Ghz	*/
+	/*			      5GHz	2GHz	*/
 	{ AR5K_RF_GAIN(0),	{ 0x00000007, 0x00000007 } },
 	{ AR5K_RF_GAIN(1),	{ 0x00000047, 0x00000047 } },
 	{ AR5K_RF_GAIN(2),	{ 0x00000087, 0x00000087 } },
@@ -305,7 +305,7 @@ static const struct ath5k_ini_rfgain rfgain_2316[] = {
 
 /* Initial RF Gain settings for RF5413 */
 static const struct ath5k_ini_rfgain rfgain_5413[] = {
-	/*			      5Ghz	2Ghz	*/
+	/*			      5GHz	2GHz	*/
 	{ AR5K_RF_GAIN(0),	{ 0x00000000, 0x00000000 } },
 	{ AR5K_RF_GAIN(1),	{ 0x00000040, 0x00000040 } },
 	{ AR5K_RF_GAIN(2),	{ 0x00000080, 0x00000080 } },
@@ -452,7 +452,7 @@ static const struct ath5k_ini_rfgain rfgain_2425[] = {
 
 /* Check if our current measurement is inside our
  * current variable attenuation window */
-#define AR5K_GAIN_CHECK_ADJUST(_g) 		\
+#define AR5K_GAIN_CHECK_ADJUST(_g)		\
 	((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
 
 struct ath5k_gain_opt_step {

+ 6 - 4
drivers/net/wireless/ath/ath5k/sysfs.c

@@ -12,7 +12,7 @@ static ssize_t ath5k_attr_show_##name(struct device *dev,		\
 {									\
 	struct ieee80211_hw *hw = dev_get_drvdata(dev);			\
 	struct ath5k_softc *sc = hw->priv;				\
-	return snprintf(buf, PAGE_SIZE, "%d\n", get); 			\
+	return snprintf(buf, PAGE_SIZE, "%d\n", get);			\
 }									\
 									\
 static ssize_t ath5k_attr_store_##name(struct device *dev,		\
@@ -21,9 +21,11 @@ static ssize_t ath5k_attr_store_##name(struct device *dev,		\
 {									\
 	struct ieee80211_hw *hw = dev_get_drvdata(dev);			\
 	struct ath5k_softc *sc = hw->priv;				\
-	int val;							\
+	int val, ret;							\
 									\
-	val = (int)simple_strtoul(buf, NULL, 10);			\
+	ret = kstrtoint(buf, 10, &val);					\
+	if (ret < 0)							\
+		return ret;						\
 	set(sc->ah, val);						\
 	return count;							\
 }									\
@@ -37,7 +39,7 @@ static ssize_t ath5k_attr_show_##name(struct device *dev,		\
 {									\
 	struct ieee80211_hw *hw = dev_get_drvdata(dev);			\
 	struct ath5k_softc *sc = hw->priv;				\
-	return snprintf(buf, PAGE_SIZE, "%d\n", get); 			\
+	return snprintf(buf, PAGE_SIZE, "%d\n", get);			\
 }									\
 static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL)
 

+ 6 - 9
drivers/net/wireless/ath/ath5k/trace.h

@@ -12,9 +12,6 @@ static inline void trace_ ## name(proto) {}
 
 struct sk_buff;
 
-#define PRIV_ENTRY  __field(struct ath5k_softc *, priv)
-#define PRIV_ASSIGN __entry->priv = priv
-
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM ath5k
 
@@ -22,12 +19,12 @@ TRACE_EVENT(ath5k_rx,
 	TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb),
 	TP_ARGS(priv, skb),
 	TP_STRUCT__entry(
-		PRIV_ENTRY
+		__field(struct ath5k_softc *, priv)
 		__field(unsigned long, skbaddr)
 		__dynamic_array(u8, frame, skb->len)
 	),
 	TP_fast_assign(
-		PRIV_ASSIGN;
+		__entry->priv = priv;
 		__entry->skbaddr = (unsigned long) skb;
 		memcpy(__get_dynamic_array(frame), skb->data, skb->len);
 	),
@@ -43,14 +40,14 @@ TRACE_EVENT(ath5k_tx,
 	TP_ARGS(priv, skb, q),
 
 	TP_STRUCT__entry(
-		PRIV_ENTRY
+		__field(struct ath5k_softc *, priv)
 		__field(unsigned long, skbaddr)
 		__field(u8, qnum)
 		__dynamic_array(u8, frame, skb->len)
 	),
 
 	TP_fast_assign(
-		PRIV_ASSIGN;
+		__entry->priv = priv;
 		__entry->skbaddr = (unsigned long) skb;
 		__entry->qnum = (u8) q->qnum;
 		memcpy(__get_dynamic_array(frame), skb->data, skb->len);
@@ -69,7 +66,7 @@ TRACE_EVENT(ath5k_tx_complete,
 	TP_ARGS(priv, skb, q, ts),
 
 	TP_STRUCT__entry(
-		PRIV_ENTRY
+		__field(struct ath5k_softc *, priv)
 		__field(unsigned long, skbaddr)
 		__field(u8, qnum)
 		__field(u8, ts_status)
@@ -78,7 +75,7 @@ TRACE_EVENT(ath5k_tx_complete,
 	),
 
 	TP_fast_assign(
-		PRIV_ASSIGN;
+		__entry->priv = priv;
 		__entry->skbaddr = (unsigned long) skb;
 		__entry->qnum = (u8) q->qnum;
 		__entry->ts_status = ts->ts_status;

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

@@ -627,6 +627,11 @@ static void ar5008_hw_init_bb(struct ath_hw *ah,
 	else
 		synthDelay /= 10;
 
+	if (IS_CHAN_HALF_RATE(chan))
+		synthDelay *= 2;
+	else if (IS_CHAN_QUARTER_RATE(chan))
+		synthDelay *= 4;
+
 	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
 
 	udelay(synthDelay + BASE_ACTIVATE_DELAY);

+ 0 - 39
drivers/net/wireless/ath/ath9k/ar9002_hw.c

@@ -499,45 +499,6 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
 	}
 }
 
-/*
- * If Async FIFO is enabled, the following counters change as MAC now runs
- * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
- *
- * The values below tested for ht40 2 chain.
- * Overwrite the delay/timeouts initialized in process ini.
- */
-void ar9002_hw_update_async_fifo(struct ath_hw *ah)
-{
-	if (AR_SREV_9287_13_OR_LATER(ah)) {
-		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
-			  AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
-		REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
-			  AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
-		REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
-			  AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
-
-		REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
-		REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
-
-		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
-			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
-		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
-			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
-	}
-}
-
-/*
- * We don't enable WEP aggregation on mac80211 but we keep this
- * around for HAL unification purposes.
- */
-void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
-{
-	if (AR_SREV_9287_13_OR_LATER(ah)) {
-		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
-			    AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
-	}
-}
-
 /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
 void ar9002_hw_attach_ops(struct ath_hw *ah)
 {

+ 19 - 15
drivers/net/wireless/ath/ath9k/ar9002_phy.c

@@ -111,7 +111,9 @@ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 
 		switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
 		case 0:
-			if ((freq % 20) == 0)
+			if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
+				aModeRefSel = 0;
+			else if ((freq % 20) == 0)
 				aModeRefSel = 3;
 			else if ((freq % 10) == 0)
 				aModeRefSel = 2;
@@ -129,8 +131,9 @@ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 			channelSel = CHANSEL_5G(freq);
 
 			/* RefDivA setting */
-			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
-				      AR_AN_SYNTH9_REFDIVA, refDivA);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_SYNTH9,
+				      AR_AN_SYNTH9_REFDIVA,
+				      AR_AN_SYNTH9_REFDIVA_S, refDivA);
 
 		}
 
@@ -447,26 +450,27 @@ static void ar9002_olc_init(struct ath_hw *ah)
 static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
 					 struct ath9k_channel *chan)
 {
+	int ref_div = 5;
+	int pll_div = 0x2c;
 	u32 pll;
 
-	pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+	if (chan && IS_CHAN_5GHZ(chan) && !IS_CHAN_A_FAST_CLOCK(ah, chan)) {
+		if (AR_SREV_9280_20(ah)) {
+			ref_div = 10;
+			pll_div = 0x50;
+		} else {
+			pll_div = 0x28;
+		}
+	}
+
+	pll = SM(ref_div, AR_RTC_9160_PLL_REFDIV);
+	pll |= SM(pll_div, AR_RTC_9160_PLL_DIV);
 
 	if (chan && IS_CHAN_HALF_RATE(chan))
 		pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
 	else if (chan && IS_CHAN_QUARTER_RATE(chan))
 		pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
 
-	if (chan && IS_CHAN_5GHZ(chan)) {
-		if (IS_CHAN_A_FAST_CLOCK(ah, chan))
-			pll = 0x142c;
-		else if (AR_SREV_9280_20(ah))
-			pll = 0x2850;
-		else
-			pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
-	} else {
-		pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
-	}
-
 	return pll;
 }
 

+ 4 - 6
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h

@@ -653,8 +653,8 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
 	{0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
 	{0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
 	{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
-	{0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
-	{0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a},
+	{0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
+	{0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
 	{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
 	{0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
@@ -761,7 +761,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
 	{0x0000a3ec, 0x20202020},
 	{0x0000a3f0, 0x00000000},
 	{0x0000a3f4, 0x00000246},
-	{0x0000a3f8, 0x0cdbd380},
+	{0x0000a3f8, 0x0c9bd380},
 	{0x0000a3fc, 0x000f0f01},
 	{0x0000a400, 0x8fa91f01},
 	{0x0000a404, 0x00000000},
@@ -780,7 +780,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
 	{0x0000a43c, 0x00100000},
 	{0x0000a440, 0x00000000},
 	{0x0000a444, 0x00000000},
-	{0x0000a448, 0x06000080},
+	{0x0000a448, 0x05000080},
 	{0x0000a44c, 0x00000001},
 	{0x0000a450, 0x00010000},
 	{0x0000a458, 0x00000000},
@@ -1500,8 +1500,6 @@ static const u32 ar9300_2p2_mac_core[][2] = {
 	{0x0000816c, 0x00000000},
 	{0x000081c0, 0x00000000},
 	{0x000081c4, 0x33332210},
-	{0x000081c8, 0x00000000},
-	{0x000081cc, 0x00000000},
 	{0x000081ec, 0x00000000},
 	{0x000081f0, 0x00000000},
 	{0x000081f4, 0x00000000},

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

@@ -625,8 +625,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
 			rxs->rs_status |= ATH9K_RXERR_DECRYPT;
 		else if (rxsp->status11 & AR_MichaelErr)
 			rxs->rs_status |= ATH9K_RXERR_MIC;
-
-		if (rxsp->status11 & AR_KeyMiss)
+		else if (rxsp->status11 & AR_KeyMiss)
 			rxs->rs_status |= ATH9K_RXERR_DECRYPT;
 	}
 

+ 30 - 0
drivers/net/wireless/ath/ath9k/ar9003_paprd.c

@@ -21,6 +21,36 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
 {
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	struct ath9k_channel *chan = ah->curchan;
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	/*
+	 * 3 bits for modalHeader5G.papdRateMaskHt20
+	 * is used for sub-band disabling of PAPRD.
+	 * 5G band is divided into 3 sub-bands -- upper,
+	 * middle, lower.
+	 * if bit 30 of modalHeader5G.papdRateMaskHt20 is set
+	 * -- disable PAPRD for upper band 5GHz
+	 * if bit 29 of modalHeader5G.papdRateMaskHt20 is set
+	 * -- disable PAPRD for middle band 5GHz
+	 * if bit 28 of modalHeader5G.papdRateMaskHt20 is set
+	 * -- disable PAPRD for lower band 5GHz
+	 */
+
+	if (IS_CHAN_5GHZ(chan)) {
+		if (chan->channel >= UPPER_5G_SUB_BAND_START) {
+			if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20)
+								  & BIT(30))
+				val = false;
+		} else if (chan->channel >= MID_5G_SUB_BAND_START) {
+			if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20)
+								  & BIT(29))
+				val = false;
+		} else {
+			if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20)
+								  & BIT(28))
+				val = false;
+		}
+	}
 
 	if (val) {
 		ah->paprd_table_write_done = true;

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

@@ -754,6 +754,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
 		IEEE80211_HW_RX_INCLUDES_FCS |
 		IEEE80211_HW_SUPPORTS_PS |
 		IEEE80211_HW_PS_NULLFUNC_STACK |
+		IEEE80211_HW_REPORTS_TX_ACK_STATUS |
 		IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
 
 	hw->wiphy->interface_modes =

+ 7 - 2
drivers/net/wireless/ath/ath9k/htc_drv_main.c

@@ -1294,11 +1294,16 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
 	u32 rfilt;
 
 	mutex_lock(&priv->mutex);
-	ath9k_htc_ps_wakeup(priv);
-
 	changed_flags &= SUPPORTED_FILTERS;
 	*total_flags &= SUPPORTED_FILTERS;
 
+	if (priv->op_flags & OP_INVALID) {
+		ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_ANY,
+			"Unable to configure filter on invalid state\n");
+		return;
+	}
+	ath9k_htc_ps_wakeup(priv);
+
 	priv->rxfilter = *total_flags;
 	rfilt = ath9k_htc_calcrxfilter(priv);
 	ath9k_hw_setrxfilter(priv->ah, rfilt);

+ 78 - 16
drivers/net/wireless/ath/ath9k/hw.c

@@ -87,7 +87,10 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah)
 	struct ath_common *common = ath9k_hw_common(ah);
 	unsigned int clockrate;
 
-	if (!ah->curchan) /* should really check for CCK instead */
+	/* AR9287 v1.3+ uses async FIFO and runs the MAC at 117 MHz */
+	if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah))
+		clockrate = 117;
+	else if (!ah->curchan) /* should really check for CCK instead */
 		clockrate = ATH9K_CLOCK_RATE_CCK;
 	else if (conf->channel->band == IEEE80211_BAND_2GHZ)
 		clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
@@ -99,6 +102,13 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah)
 	if (conf_is_ht40(conf))
 		clockrate *= 2;
 
+	if (ah->curchan) {
+		if (IS_CHAN_HALF_RATE(ah->curchan))
+			clockrate /= 2;
+		if (IS_CHAN_QUARTER_RATE(ah->curchan))
+			clockrate /= 4;
+	}
+
 	common->clockrate = clockrate;
 }
 
@@ -895,6 +905,13 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
 	}
 }
 
+static void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us)
+{
+	u32 val = ath9k_hw_mac_to_clks(ah, us - 2);
+	val = min(val, (u32) 0xFFFF);
+	REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val);
+}
+
 static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
 {
 	u32 val = ath9k_hw_mac_to_clks(ah, us);
@@ -932,25 +949,60 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
 
 void ath9k_hw_init_global_settings(struct ath_hw *ah)
 {
-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ieee80211_conf *conf = &common->hw->conf;
+	const struct ath9k_channel *chan = ah->curchan;
 	int acktimeout;
 	int slottime;
 	int sifstime;
+	int rx_lat = 0, tx_lat = 0, eifs = 0;
+	u32 reg;
 
 	ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
 		ah->misc_mode);
 
+	if (!chan)
+		return;
+
 	if (ah->misc_mode != 0)
 		REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
 
-	if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
-		sifstime = 16;
-	else
-		sifstime = 10;
+	rx_lat = 37;
+	tx_lat = 54;
+
+	if (IS_CHAN_HALF_RATE(chan)) {
+		eifs = 175;
+		rx_lat *= 2;
+		tx_lat *= 2;
+		if (IS_CHAN_A_FAST_CLOCK(ah, chan))
+		    tx_lat += 11;
+
+		slottime = 13;
+		sifstime = 32;
+	} else if (IS_CHAN_QUARTER_RATE(chan)) {
+		eifs = 340;
+		rx_lat *= 4;
+		tx_lat *= 4;
+		if (IS_CHAN_A_FAST_CLOCK(ah, chan))
+		    tx_lat += 22;
+
+		slottime = 21;
+		sifstime = 64;
+	} else {
+		eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS);
+		reg = REG_READ(ah, AR_USEC);
+		rx_lat = MS(reg, AR_USEC_RX_LAT);
+		tx_lat = MS(reg, AR_USEC_TX_LAT);
+
+		slottime = ah->slottime;
+		if (IS_CHAN_5GHZ(chan))
+			sifstime = 16;
+		else
+			sifstime = 10;
+	}
 
 	/* As defined by IEEE 802.11-2007 17.3.8.6 */
-	slottime = ah->slottime + 3 * ah->coverage_class;
-	acktimeout = slottime + sifstime;
+	acktimeout = slottime + sifstime + 3 * ah->coverage_class;
 
 	/*
 	 * Workaround for early ACK timeouts, add an offset to match the
@@ -962,11 +1014,20 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
 	if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
 		acktimeout += 64 - sifstime - ah->slottime;
 
-	ath9k_hw_setslottime(ah, ah->slottime);
+	ath9k_hw_set_sifs_time(ah, sifstime);
+	ath9k_hw_setslottime(ah, slottime);
 	ath9k_hw_set_ack_timeout(ah, acktimeout);
 	ath9k_hw_set_cts_timeout(ah, acktimeout);
 	if (ah->globaltxtimeout != (u32) -1)
 		ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
+
+	REG_WRITE(ah, AR_D_GBL_IFS_EIFS, ath9k_hw_mac_to_clks(ah, eifs));
+	REG_RMW(ah, AR_USEC,
+		(common->clockrate - 1) |
+		SM(rx_lat, AR_USEC_RX_LAT) |
+		SM(tx_lat, AR_USEC_TX_LAT),
+		AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC);
+
 }
 EXPORT_SYMBOL(ath9k_hw_init_global_settings);
 
@@ -1570,9 +1631,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	ath9k_hw_init_global_settings(ah);
 
-	if (!AR_SREV_9300_20_OR_LATER(ah)) {
-		ar9002_hw_update_async_fifo(ah);
-		ar9002_hw_enable_wep_aggregation(ah);
+	if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
+		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
+			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
+		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
+			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
+		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+			    AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
 	}
 
 	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
@@ -2079,10 +2144,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 			pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
 	} else {
 		pCap->tx_desc_len = sizeof(struct ath_desc);
-		if (AR_SREV_9280_20(ah) &&
-		    ((ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) <=
-		      AR5416_EEP_MINOR_VER_16) ||
-		     ah->eep_ops->get_eeprom(ah, EEP_FSTCLK_5G)))
+		if (AR_SREV_9280_20(ah))
 			pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK;
 	}
 

+ 2 - 2
drivers/net/wireless/ath/ath9k/hw.h

@@ -143,6 +143,8 @@
 #define AR_KEYTABLE_SIZE            128
 #define POWER_UP_TIME               10000
 #define SPUR_RSSI_THRESH            40
+#define UPPER_5G_SUB_BAND_START		5700
+#define MID_5G_SUB_BAND_START		5400
 
 #define CAB_TIMEOUT_VAL             10
 #define BEACON_TIMEOUT_VAL          10
@@ -983,8 +985,6 @@ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
 void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
 int ar9002_hw_rf_claim(struct ath_hw *ah);
 void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
-void ar9002_hw_update_async_fifo(struct ath_hw *ah);
-void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
 
 /*
  * Code specific to AR9003, we stuff these here to avoid callbacks

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

@@ -645,8 +645,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 			rs->rs_status |= ATH9K_RXERR_DECRYPT;
 		else if (ads.ds_rxstatus8 & AR_MichaelErr)
 			rs->rs_status |= ATH9K_RXERR_MIC;
-
-		if (ads.ds_rxstatus8 & AR_KeyMiss)
+		else if (ads.ds_rxstatus8 & AR_KeyMiss)
 			rs->rs_status |= ATH9K_RXERR_DECRYPT;
 	}
 

+ 24 - 26
drivers/net/wireless/ath/ath9k/rc.c

@@ -379,7 +379,30 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
 };
 
 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 = 0, i = 0;
+	static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
+
+	if (!(rate->flags & IEEE80211_TX_RC_MCS))
+		return rate->idx;
+
+	while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) {
+		rix++; i++;
+	}
+
+	rix += rate->idx + rate_table->mcs_start;
+
+	if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+	    (rate->flags & IEEE80211_TX_RC_SHORT_GI))
+		rix = rate_table->info[rix].ht_index;
+	else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+		rix = rate_table->info[rix].sgi_index;
+	else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+		rix = rate_table->info[rix].cw40index;
+
+	return rix;
+}
 
 static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
 				   struct ath_rate_priv *ath_rc_priv)
@@ -1080,31 +1103,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
 
 }
 
-static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
-				struct ieee80211_tx_rate *rate)
-{
-	int rix = 0, i = 0;
-	static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
-
-	if (!(rate->flags & IEEE80211_TX_RC_MCS))
-		return rate->idx;
-
-	while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) {
-		rix++; i++;
-	}
-
-	rix += rate->idx + rate_table->mcs_start;
-
-	if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
-	    (rate->flags & IEEE80211_TX_RC_SHORT_GI))
-		rix = rate_table->info[rix].ht_index;
-	else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
-		rix = rate_table->info[rix].sgi_index;
-	else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-		rix = rate_table->info[rix].cw40index;
-
-	return rix;
-}
 
 static void ath_rc_tx_status(struct ath_softc *sc,
 			     struct ath_rate_priv *ath_rc_priv,

+ 0 - 5
drivers/net/wireless/ath/ath9k/reg.h

@@ -600,7 +600,6 @@
 
 #define AR_D_GBL_IFS_SIFS         0x1030
 #define AR_D_GBL_IFS_SIFS_M       0x0000FFFF
-#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB
 #define AR_D_GBL_IFS_SIFS_RESV0   0xFFFFFFFF
 
 #define AR_D_TXBLK_BASE            0x1038
@@ -616,12 +615,10 @@
 #define AR_D_GBL_IFS_SLOT         0x1070
 #define AR_D_GBL_IFS_SLOT_M       0x0000FFFF
 #define AR_D_GBL_IFS_SLOT_RESV0   0xFFFF0000
-#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR   0x00000420
 
 #define AR_D_GBL_IFS_EIFS         0x10b0
 #define AR_D_GBL_IFS_EIFS_M       0x0000FFFF
 #define AR_D_GBL_IFS_EIFS_RESV0   0xFFFF0000
-#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR   0x0000A5EB
 
 #define AR_D_GBL_IFS_MISC        0x10f0
 #define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL        0x00000007
@@ -1477,7 +1474,6 @@ enum {
 #define AR_TIME_OUT_ACK_S    0
 #define AR_TIME_OUT_CTS      0x3FFF0000
 #define AR_TIME_OUT_CTS_S    16
-#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR    0x16001D56
 
 #define AR_RSSI_THR          0x8018
 #define AR_RSSI_THR_MASK     0x000000FF
@@ -1493,7 +1489,6 @@ enum {
 #define AR_USEC_TX_LAT_S     14
 #define AR_USEC_RX_LAT       0x1F800000
 #define AR_USEC_RX_LAT_S     23
-#define AR_USEC_ASYNC_FIFO_DUR    0x12e00074
 
 #define AR_RESET_TSF        0x8020
 #define AR_RESET_TSF_ONCE   0x01000000

+ 8 - 0
drivers/net/wireless/ath/carl9170/main.c

@@ -1484,6 +1484,13 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw,
 	}
 }
 
+static bool carl9170_tx_frames_pending(struct ieee80211_hw *hw)
+{
+	struct ar9170 *ar = hw->priv;
+
+	return !!atomic_read(&ar->tx_total_queued);
+}
+
 static const struct ieee80211_ops carl9170_ops = {
 	.start			= carl9170_op_start,
 	.stop			= carl9170_op_stop,
@@ -1504,6 +1511,7 @@ static const struct ieee80211_ops carl9170_ops = {
 	.get_survey		= carl9170_op_get_survey,
 	.get_stats		= carl9170_op_get_stats,
 	.ampdu_action		= carl9170_op_ampdu_action,
+	.tx_frames_pending	= carl9170_tx_frames_pending,
 };
 
 void *carl9170_alloc(size_t priv_size)

+ 14 - 0
drivers/net/wireless/b43/Kconfig

@@ -90,6 +90,12 @@ config B43_SDIO
 
 #Data transfers to the device via PIO. We want it as a fallback even
 # if we can do DMA.
+config B43_BCMA_PIO
+	bool
+	depends on B43_BCMA
+	select BCMA_BLOCKIO
+	default y
+
 config B43_PIO
 	bool
 	depends on B43
@@ -125,6 +131,14 @@ config B43_PHY_HT
 
 	  Say N, this is BROKEN and crashes driver.
 
+config B43_PHY_LCN
+	bool "Support for LCN-PHY devices (BROKEN)"
+	depends on B43 && BROKEN
+	---help---
+	  Support for the LCN-PHY.
+
+	  Say N, this is BROKEN and crashes driver.
+
 # This config option automatically enables b43 LEDS support,
 # if it's possible.
 config B43_LEDS

+ 1 - 0
drivers/net/wireless/b43/Makefile

@@ -13,6 +13,7 @@ b43-$(CONFIG_B43_PHY_LP)	+= tables_lpphy.o
 b43-$(CONFIG_B43_PHY_HT)	+= phy_ht.o
 b43-$(CONFIG_B43_PHY_HT)	+= tables_phy_ht.o
 b43-$(CONFIG_B43_PHY_HT)	+= radio_2059.o
+b43-$(CONFIG_B43_PHY_LCN)	+= phy_lcn.o tables_phy_lcn.o
 b43-y				+= sysfs.o
 b43-y				+= xmit.o
 b43-y				+= lo.o

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

@@ -726,7 +726,6 @@ enum {
 
 /* Data structure for one wireless device (802.11 core) */
 struct b43_wldev {
-	struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */
 	struct b43_bus_dev *dev;
 	struct b43_wl *wl;
 

+ 129 - 0
drivers/net/wireless/b43/bus.c

@@ -23,6 +23,106 @@
 #include "b43.h"
 #include "bus.h"
 
+/* BCMA */
+#ifdef CONFIG_B43_BCMA
+static int b43_bus_bcma_bus_may_powerdown(struct b43_bus_dev *dev)
+{
+	return 0; /* bcma_bus_may_powerdown(dev->bdev->bus); */
+}
+static int b43_bus_bcma_bus_powerup(struct b43_bus_dev *dev,
+					  bool dynamic_pctl)
+{
+	return 0; /* bcma_bus_powerup(dev->sdev->bus, dynamic_pctl); */
+}
+static int b43_bus_bcma_device_is_enabled(struct b43_bus_dev *dev)
+{
+	return bcma_core_is_enabled(dev->bdev);
+}
+static void b43_bus_bcma_device_enable(struct b43_bus_dev *dev,
+					     u32 core_specific_flags)
+{
+	bcma_core_enable(dev->bdev, core_specific_flags);
+}
+static void b43_bus_bcma_device_disable(struct b43_bus_dev *dev,
+					      u32 core_specific_flags)
+{
+	bcma_core_disable(dev->bdev, core_specific_flags);
+}
+static u16 b43_bus_bcma_read16(struct b43_bus_dev *dev, u16 offset)
+{
+	return bcma_read16(dev->bdev, offset);
+}
+static u32 b43_bus_bcma_read32(struct b43_bus_dev *dev, u16 offset)
+{
+	return bcma_read32(dev->bdev, offset);
+}
+static
+void b43_bus_bcma_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
+{
+	bcma_write16(dev->bdev, offset, value);
+}
+static
+void b43_bus_bcma_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
+{
+	bcma_write32(dev->bdev, offset, value);
+}
+static
+void b43_bus_bcma_block_read(struct b43_bus_dev *dev, void *buffer,
+			     size_t count, u16 offset, u8 reg_width)
+{
+	bcma_block_read(dev->bdev, buffer, count, offset, reg_width);
+}
+static
+void b43_bus_bcma_block_write(struct b43_bus_dev *dev, const void *buffer,
+			      size_t count, u16 offset, u8 reg_width)
+{
+	bcma_block_write(dev->bdev, buffer, count, offset, reg_width);
+}
+
+struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
+{
+	struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+
+	dev->bus_type = B43_BUS_BCMA;
+	dev->bdev = core;
+
+	dev->bus_may_powerdown = b43_bus_bcma_bus_may_powerdown;
+	dev->bus_powerup = b43_bus_bcma_bus_powerup;
+	dev->device_is_enabled = b43_bus_bcma_device_is_enabled;
+	dev->device_enable = b43_bus_bcma_device_enable;
+	dev->device_disable = b43_bus_bcma_device_disable;
+
+	dev->read16 = b43_bus_bcma_read16;
+	dev->read32 = b43_bus_bcma_read32;
+	dev->write16 = b43_bus_bcma_write16;
+	dev->write32 = b43_bus_bcma_write32;
+	dev->block_read = b43_bus_bcma_block_read;
+	dev->block_write = b43_bus_bcma_block_write;
+
+	dev->dev = &core->dev;
+	dev->dma_dev = core->dma_dev;
+	dev->irq = core->irq;
+
+	/*
+	dev->board_vendor = core->bus->boardinfo.vendor;
+	dev->board_type = core->bus->boardinfo.type;
+	dev->board_rev = core->bus->boardinfo.rev;
+	*/
+
+	dev->chip_id = core->bus->chipinfo.id;
+	dev->chip_rev = core->bus->chipinfo.rev;
+	dev->chip_pkg = core->bus->chipinfo.pkg;
+
+	dev->bus_sprom = &core->bus->sprom;
+
+	dev->core_id = core->id.id;
+	dev->core_rev = core->id.rev;
+
+	return dev;
+}
+#endif /* CONFIG_B43_BCMA */
 
 /* SSB */
 #ifdef CONFIG_B43_SSB
@@ -125,3 +225,32 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
 	return dev;
 }
 #endif /* CONFIG_B43_SSB */
+
+void *b43_bus_get_wldev(struct b43_bus_dev *dev)
+{
+	switch (dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		return bcma_get_drvdata(dev->bdev);
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		return ssb_get_drvdata(dev->sdev);
+#endif
+	}
+	return NULL;
+}
+
+void b43_bus_set_wldev(struct b43_bus_dev *dev, void *wldev)
+{
+	switch (dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		bcma_set_drvdata(dev->bdev, wldev);
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		ssb_set_drvdata(dev->sdev, wldev);
+#endif
+	}
+}

+ 8 - 0
drivers/net/wireless/b43/bus.h

@@ -2,12 +2,16 @@
 #define B43_BUS_H_
 
 enum b43_bus_type {
+#ifdef CONFIG_B43_BCMA
+	B43_BUS_BCMA,
+#endif
 	B43_BUS_SSB,
 };
 
 struct b43_bus_dev {
 	enum b43_bus_type bus_type;
 	union {
+		struct bcma_device *bdev;
 		struct ssb_device *sdev;
 	};
 
@@ -57,6 +61,10 @@ static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev)
 		dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO);
 }
 
+struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core);
 struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev);
 
+void *b43_bus_get_wldev(struct b43_bus_dev *dev);
+void b43_bus_set_wldev(struct b43_bus_dev *dev, void *data);
+
 #endif /* B43_BUS_H_ */

+ 8 - 1
drivers/net/wireless/b43/dma.c

@@ -1055,7 +1055,14 @@ int b43_dma_init(struct b43_wldev *dev)
 	err = b43_dma_set_mask(dev, dmamask);
 	if (err)
 		return err;
-	dma->translation = ssb_dma_translation(dev->sdev);
+
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		dma->translation = ssb_dma_translation(dev->dev->sdev);
+		break;
+#endif
+	}
 
 	err = -ENOMEM;
 	/* setup TX DMA channels. */

+ 284 - 77
drivers/net/wireless/b43/main.c

@@ -1155,6 +1155,21 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
 	}
 }
 
+#ifdef CONFIG_B43_BCMA
+static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
+{
+	u32 flags = 0;
+
+	if (gmode)
+		flags = B43_BCMA_IOCTL_GMODE;
+	flags |= B43_BCMA_IOCTL_PHY_CLKEN;
+	flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */
+	b43_device_enable(dev, flags);
+
+	/* TODO: reset PHY */
+}
+#endif
+
 static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)
 {
 	struct ssb_device *sdev = dev->dev->sdev;
@@ -1187,7 +1202,18 @@ void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode)
 {
 	u32 macctl;
 
-	b43_ssb_wireless_core_reset(dev, gmode);
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		b43_bcma_wireless_core_reset(dev, gmode);
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		b43_ssb_wireless_core_reset(dev, gmode);
+		break;
+#endif
+	}
 
 	/* Turn Analog ON, but only if we already know the PHY-type.
 	 * This protects against very early setup where we don't know the
@@ -1938,7 +1964,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)
 		return IRQ_NONE;
 	reason &= dev->irq_mask;
 	if (!reason)
-		return IRQ_HANDLED;
+		return IRQ_NONE;
 
 	dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
 	    & 0x0001DC00;
@@ -2133,21 +2159,43 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
 	u32 tmshigh;
 	int err;
 
+	/* Files for HT and LCN were found by trying one by one */
+
 	/* Get microcode */
-	if ((rev >= 5) && (rev <= 10))
+	if ((rev >= 5) && (rev <= 10)) {
 		filename = "ucode5";
-	else if ((rev >= 11) && (rev <= 12))
+	} else if ((rev >= 11) && (rev <= 12)) {
 		filename = "ucode11";
-	else if (rev == 13)
+	} else if (rev == 13) {
 		filename = "ucode13";
-	else if (rev == 14)
+	} else if (rev == 14) {
 		filename = "ucode14";
-	else if (rev == 15)
+	} else if (rev == 15) {
 		filename = "ucode15";
-	else if ((rev >= 16) && (rev <= 20))
-		filename = "ucode16_mimo";
-	else
-		goto err_no_ucode;
+	} else {
+		switch (dev->phy.type) {
+		case B43_PHYTYPE_N:
+			if (rev >= 16)
+				filename = "ucode16_mimo";
+			else
+				goto err_no_ucode;
+			break;
+		case B43_PHYTYPE_HT:
+			if (rev == 29)
+				filename = "ucode29_mimo";
+			else
+				goto err_no_ucode;
+			break;
+		case B43_PHYTYPE_LCN:
+			if (rev == 24)
+				filename = "ucode24_mimo";
+			else
+				goto err_no_ucode;
+			break;
+		default:
+			goto err_no_ucode;
+		}
+	}
 	err = b43_do_request_fw(ctx, filename, &fw->ucode);
 	if (err)
 		goto err_load;
@@ -2206,6 +2254,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
 		else
 			goto err_no_initvals;
 		break;
+	case B43_PHYTYPE_HT:
+		if (rev == 29)
+			filename = "ht0initvals29";
+		else
+			goto err_no_initvals;
+		break;
+	case B43_PHYTYPE_LCN:
+		if (rev == 24)
+			filename = "lcn0initvals24";
+		else
+			goto err_no_initvals;
+		break;
 	default:
 		goto err_no_initvals;
 	}
@@ -2253,6 +2313,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
 		else
 			goto err_no_initvals;
 		break;
+	case B43_PHYTYPE_HT:
+		if (rev == 29)
+			filename = "ht0bsinitvals29";
+		else
+			goto err_no_initvals;
+		break;
+	case B43_PHYTYPE_LCN:
+		if (rev == 24)
+			filename = "lcn0bsinitvals24";
+		else
+			goto err_no_initvals;
+		break;
 	default:
 		goto err_no_initvals;
 	}
@@ -2624,11 +2696,24 @@ static int b43_gpio_init(struct b43_wldev *dev)
 	if (dev->dev->core_rev >= 2)
 		mask |= 0x0010;	/* FIXME: This is redundant. */
 
-	gpiodev = b43_ssb_gpio_dev(dev);
-	if (gpiodev)
-		ssb_write32(gpiodev, B43_GPIO_CONTROL,
-			    (ssb_read32(gpiodev, B43_GPIO_CONTROL)
-			     & mask) | set);
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL,
+				(bcma_cc_read32(&dev->dev->bdev->bus->drv_cc,
+					BCMA_CC_GPIOCTL) & mask) | set);
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		gpiodev = b43_ssb_gpio_dev(dev);
+		if (gpiodev)
+			ssb_write32(gpiodev, B43_GPIO_CONTROL,
+				    (ssb_read32(gpiodev, B43_GPIO_CONTROL)
+				    & mask) | set);
+		break;
+#endif
+	}
 
 	return 0;
 }
@@ -2638,9 +2723,21 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
 {
 	struct ssb_device *gpiodev;
 
-	gpiodev = b43_ssb_gpio_dev(dev);
-	if (gpiodev)
-		ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL,
+				0);
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		gpiodev = b43_ssb_gpio_dev(dev);
+		if (gpiodev)
+			ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
+		break;
+#endif
+	}
 }
 
 /* http://bcm-specs.sipsolutions.net/EnableMac */
@@ -2712,12 +2809,30 @@ out:
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
 void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
 {
-	u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
-	if (on)
-		tmslow |= B43_TMSLOW_MACPHYCLKEN;
-	else
-		tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
-	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
+	u32 tmp;
+
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL);
+		if (on)
+			tmp |= B43_BCMA_IOCTL_MACPHYCLKEN;
+		else
+			tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN;
+		bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp);
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
+		if (on)
+			tmp |= B43_TMSLOW_MACPHYCLKEN;
+		else
+			tmp &= ~B43_TMSLOW_MACPHYCLKEN;
+		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
+		break;
+#endif
+	}
 }
 
 static void b43_adjust_opmode(struct b43_wldev *dev)
@@ -2956,8 +3071,20 @@ static int b43_chip_init(struct b43_wldev *dev)
 
 	b43_mac_phy_clock_set(dev, true);
 
-	b43_write16(dev, B43_MMIO_POWERUP_DELAY,
-		    dev->sdev->bus->chipco.fast_pwrup_delay);
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		/* FIXME: 0xE74 is quite common, but should be read from CC */
+		b43_write16(dev, B43_MMIO_POWERUP_DELAY, 0xE74);
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		b43_write16(dev, B43_MMIO_POWERUP_DELAY,
+			    dev->dev->sdev->bus->chipco.fast_pwrup_delay);
+		break;
+#endif
+	}
 
 	err = 0;
 	b43dbg(dev->wl, "Chip initialized\n");
@@ -3473,21 +3600,33 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
 
 static void b43_put_phy_into_reset(struct b43_wldev *dev)
 {
-	struct ssb_device *sdev = dev->sdev;
-	u32 tmslow;
+	u32 tmp;
 
-	tmslow = ssb_read32(sdev, SSB_TMSLOW);
-	tmslow &= ~B43_TMSLOW_GMODE;
-	tmslow |= B43_TMSLOW_PHYRESET;
-	tmslow |= SSB_TMSLOW_FGC;
-	ssb_write32(sdev, SSB_TMSLOW, tmslow);
-	msleep(1);
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		b43err(dev->wl,
+		       "Putting PHY into reset not supported on BCMA\n");
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
+		tmp &= ~B43_TMSLOW_GMODE;
+		tmp |= B43_TMSLOW_PHYRESET;
+		tmp |= SSB_TMSLOW_FGC;
+		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
+		msleep(1);
+
+		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
+		tmp &= ~SSB_TMSLOW_FGC;
+		tmp |= B43_TMSLOW_PHYRESET;
+		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
+		msleep(1);
 
-	tmslow = ssb_read32(sdev, SSB_TMSLOW);
-	tmslow &= ~SSB_TMSLOW_FGC;
-	tmslow |= B43_TMSLOW_PHYRESET;
-	ssb_write32(sdev, SSB_TMSLOW, tmslow);
-	msleep(1);
+		break;
+#endif
+	}
 }
 
 static const char *band_to_string(enum ieee80211_band band)
@@ -4103,6 +4242,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 		if (phy_rev > 1)
 			unsupported = 1;
 		break;
+#endif
+#ifdef CONFIG_B43_PHY_LCN
+	case B43_PHYTYPE_LCN:
+		if (phy_rev > 1)
+			unsupported = 1;
+		break;
 #endif
 	default:
 		unsupported = 1;
@@ -4117,22 +4262,42 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 	       analog_type, phy_type, phy_rev);
 
 	/* Get RADIO versioning */
-	if (dev->dev->chip_id == 0x4317) {
-		if (dev->dev->chip_rev == 0)
-			tmp = 0x3205017F;
-		else if (dev->dev->chip_rev == 1)
-			tmp = 0x4205017F;
-		else
-			tmp = 0x5205017F;
+	if (dev->dev->core_rev >= 24) {
+		u16 radio24[3];
+
+		for (tmp = 0; tmp < 3; tmp++) {
+			b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
+			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
+		}
+
+		/* Broadcom uses "id" for our "ver" and has separated "ver" */
+		/* radio_ver = (radio24[0] & 0xF0) >> 4; */
+
+		radio_manuf = 0x17F;
+		radio_ver = (radio24[2] << 8) | radio24[1];
+		radio_rev = (radio24[0] & 0xF);
 	} else {
-		b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID);
-		tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
-		b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID);
-		tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
-	}
-	radio_manuf = (tmp & 0x00000FFF);
-	radio_ver = (tmp & 0x0FFFF000) >> 12;
-	radio_rev = (tmp & 0xF0000000) >> 28;
+		if (dev->dev->chip_id == 0x4317) {
+			if (dev->dev->chip_rev == 0)
+				tmp = 0x3205017F;
+			else if (dev->dev->chip_rev == 1)
+				tmp = 0x4205017F;
+			else
+				tmp = 0x5205017F;
+		} else {
+			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
+				    B43_RADIOCTL_ID);
+			tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
+			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
+				    B43_RADIOCTL_ID);
+			tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
+				<< 16;
+		}
+		radio_manuf = (tmp & 0x00000FFF);
+		radio_ver = (tmp & 0x0FFFF000) >> 12;
+		radio_rev = (tmp & 0xF0000000) >> 28;
+	}
+
 	if (radio_manuf != 0x17F /* Broadcom */)
 		unsupported = 1;
 	switch (phy_type) {
@@ -4164,6 +4329,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 		if (radio_ver != 0x2059)
 			unsupported = 1;
 		break;
+	case B43_PHYTYPE_LCN:
+		if (radio_ver != 0x2064)
+			unsupported = 1;
+		break;
 	default:
 		B43_WARN_ON(1);
 	}
@@ -4347,7 +4516,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
 /* Initialize a wireless core */
 static int b43_wireless_core_init(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->sdev->bus;
 	struct ssb_sprom *sprom = dev->dev->bus_sprom;
 	struct b43_phy *phy = &dev->phy;
 	int err;
@@ -4366,7 +4534,20 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
 	phy->ops->prepare_structs(dev);
 
 	/* Enable IRQ routing to this device. */
-	ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev);
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci,
+				      dev->dev->bdev, true);
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore,
+					       dev->dev->sdev);
+		break;
+#endif
+	}
 
 	b43_imcfglo_timeouts_workaround(dev);
 	b43_bluetooth_coext_disable(dev);
@@ -4397,8 +4578,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
 	if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
 		hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
 #ifdef CONFIG_SSB_DRIVER_PCICORE
-	if ((bus->bustype == SSB_BUSTYPE_PCI) &&
-	    (bus->pcicore.dev->id.revision <= 10))
+	if (dev->dev->bus_type == B43_BUS_SSB &&
+	    dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
+	    dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
 		hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */
 #endif
 	hf &= ~B43_HF_SKCFPUP;
@@ -4764,8 +4946,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev)
 static int b43_wireless_core_attach(struct b43_wldev *dev)
 {
 	struct b43_wl *wl = dev->wl;
-	struct ssb_bus *bus = dev->sdev->bus;
-	struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
+	struct pci_dev *pdev = NULL;
 	int err;
 	bool have_2ghz_phy = 0, have_5ghz_phy = 0;
 
@@ -4776,20 +4957,38 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
 	 * that in core_init(), too.
 	 */
 
+#ifdef CONFIG_B43_SSB
+	if (dev->dev->bus_type == B43_BUS_SSB &&
+	    dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI)
+		pdev = dev->dev->sdev->bus->host_pci;
+#endif
+
 	err = b43_bus_powerup(dev, 0);
 	if (err) {
 		b43err(wl, "Bus powerup failed\n");
 		goto out;
 	}
-	/* Get the PHY type. */
-	if (dev->dev->core_rev >= 5) {
-		u32 tmshigh;
 
-		tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
-		have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
-		have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
-	} else
-		B43_WARN_ON(1);
+	/* Get the PHY type. */
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		/* FIXME */
+		have_2ghz_phy = 1;
+		have_5ghz_phy = 0;
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		if (dev->dev->core_rev >= 5) {
+			u32 tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
+			have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
+			have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
+		} else
+			B43_WARN_ON(1);
+		break;
+#endif
+	}
 
 	dev->phy.gmode = have_2ghz_phy;
 	dev->phy.radio_on = 1;
@@ -4815,6 +5014,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
 #endif
 		case B43_PHYTYPE_G:
 		case B43_PHYTYPE_N:
+		case B43_PHYTYPE_HT:
+		case B43_PHYTYPE_LCN:
 			have_2ghz_phy = 1;
 			break;
 		default:
@@ -4877,13 +5078,13 @@ static void b43_one_core_detach(struct b43_bus_dev *dev)
 	/* Do not cancel ieee80211-workqueue based work here.
 	 * See comment in b43_remove(). */
 
-	wldev = ssb_get_drvdata(dev->sdev);
+	wldev = b43_bus_get_wldev(dev);
 	wl = wldev->wl;
 	b43_debugfs_remove_device(wldev);
 	b43_wireless_core_detach(wldev);
 	list_del(&wldev->list);
 	wl->nr_devs--;
-	ssb_set_drvdata(dev->sdev, NULL);
+	b43_bus_set_wldev(dev, NULL);
 	kfree(wldev);
 }
 
@@ -4898,7 +5099,6 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
 
 	wldev->use_pio = b43_modparam_pio;
 	wldev->dev = dev;
-	wldev->sdev = dev->sdev; /* TODO: Remove when not needed */
 	wldev->wl = wl;
 	b43_set_status(wldev, B43_STAT_UNINIT);
 	wldev->bad_frames_preempt = modparam_bad_frames_preempt;
@@ -4910,7 +5110,7 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
 
 	list_add(&wldev->list, &wl->devlist);
 	wl->nr_devs++;
-	ssb_set_drvdata(dev->sdev, wldev);
+	b43_bus_set_wldev(dev, wldev);
 	b43_debugfs_add_device(wldev);
 
       out:
@@ -4959,9 +5159,9 @@ static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl)
 	ieee80211_free_hw(hw);
 }
 
-static struct b43_wl *b43_wireless_init(struct ssb_device *dev)
+static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
 {
-	struct ssb_sprom *sprom = &dev->bus->sprom;
+	struct ssb_sprom *sprom = dev->bus_sprom;
 	struct ieee80211_hw *hw;
 	struct b43_wl *wl;
 
@@ -5003,14 +5203,21 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev)
 	skb_queue_head_init(&wl->tx_queue);
 
 	b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
-		dev->bus->chip_id, dev->id.revision);
+		dev->chip_id, dev->core_rev);
 	return wl;
 }
 
 #ifdef CONFIG_B43_BCMA
 static int b43_bcma_probe(struct bcma_device *core)
 {
+	struct b43_bus_dev *dev;
+
+	dev = b43_bus_dev_bcma_init(core);
+	if (!dev)
+		return -ENODEV;
+
 	b43err(NULL, "BCMA is not supported yet!");
+	kfree(dev);
 	return -EOPNOTSUPP;
 }
 
@@ -5045,7 +5252,7 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
 		/* Probing the first core. Must setup common struct b43_wl */
 		first = 1;
 		b43_sprom_fixup(sdev->bus);
-		wl = b43_wireless_init(sdev);
+		wl = b43_wireless_init(dev);
 		if (IS_ERR(wl)) {
 			err = PTR_ERR(wl);
 			goto out;

+ 6 - 0
drivers/net/wireless/b43/phy_common.c

@@ -32,6 +32,7 @@
 #include "phy_n.h"
 #include "phy_lp.h"
 #include "phy_ht.h"
+#include "phy_lcn.h"
 #include "b43.h"
 #include "main.h"
 
@@ -63,6 +64,11 @@ int b43_phy_allocate(struct b43_wldev *dev)
 	case B43_PHYTYPE_HT:
 #ifdef CONFIG_B43_PHY_HT
 		phy->ops = &b43_phyops_ht;
+#endif
+		break;
+	case B43_PHYTYPE_LCN:
+#ifdef CONFIG_B43_PHY_LCN
+		phy->ops = &b43_phyops_lcn;
 #endif
 		break;
 	}

+ 3 - 0
drivers/net/wireless/b43/phy_common.h

@@ -195,6 +195,7 @@ struct b43_phy_g;
 struct b43_phy_n;
 struct b43_phy_lp;
 struct b43_phy_ht;
+struct b43_phy_lcn;
 
 struct b43_phy {
 	/* Hardware operation callbacks. */
@@ -219,6 +220,8 @@ struct b43_phy {
 		struct b43_phy_lp *lp;
 		/* HT-PHY specific information */
 		struct b43_phy_ht *ht;
+		/* LCN-PHY specific information */
+		struct b43_phy_lcn *lcn;
 	};
 
 	/* Band support flags. */

+ 10 - 2
drivers/net/wireless/b43/phy_ht.c

@@ -373,6 +373,16 @@ static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
+static enum b43_txpwr_result
+b43_phy_ht_op_recalc_txpower(struct b43_wldev *dev, bool ignore_tssi)
+{
+	return B43_TXPWR_RES_DONE;
+}
+
+static void b43_phy_ht_op_adjust_txpower(struct b43_wldev *dev)
+{
+}
+
 /**************************************************
  * PHY ops struct.
  **************************************************/
@@ -391,8 +401,6 @@ const struct b43_phy_operations b43_phyops_ht = {
 	.switch_analog		= b43_phy_ht_op_switch_analog,
 	.switch_channel		= b43_phy_ht_op_switch_channel,
 	.get_default_chan	= b43_phy_ht_op_get_default_chan,
-	/*
 	.recalc_txpower		= b43_phy_ht_op_recalc_txpower,
 	.adjust_txpower		= b43_phy_ht_op_adjust_txpower,
-	*/
 };

+ 52 - 0
drivers/net/wireless/b43/phy_lcn.c

@@ -0,0 +1,52 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n LCN-PHY support
+
+  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; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include <linux/slab.h>
+
+#include "b43.h"
+#include "phy_lcn.h"
+#include "tables_phy_lcn.h"
+#include "main.h"
+
+/**************************************************
+ * PHY ops struct.
+ **************************************************/
+
+const struct b43_phy_operations b43_phyops_lcn = {
+	/*
+	.allocate		= b43_phy_lcn_op_allocate,
+	.free			= b43_phy_lcn_op_free,
+	.prepare_structs	= b43_phy_lcn_op_prepare_structs,
+	.init			= b43_phy_lcn_op_init,
+	.phy_read		= b43_phy_lcn_op_read,
+	.phy_write		= b43_phy_lcn_op_write,
+	.phy_maskset		= b43_phy_lcn_op_maskset,
+	.radio_read		= b43_phy_lcn_op_radio_read,
+	.radio_write		= b43_phy_lcn_op_radio_write,
+	.software_rfkill	= b43_phy_lcn_op_software_rfkill,
+	.switch_analog		= b43_phy_lcn_op_switch_analog,
+	.switch_channel		= b43_phy_lcn_op_switch_channel,
+	.get_default_chan	= b43_phy_lcn_op_get_default_chan,
+	.recalc_txpower		= b43_phy_lcn_op_recalc_txpower,
+	.adjust_txpower		= b43_phy_lcn_op_adjust_txpower,
+	*/
+};

+ 14 - 0
drivers/net/wireless/b43/phy_lcn.h

@@ -0,0 +1,14 @@
+#ifndef B43_PHY_LCN_H_
+#define B43_PHY_LCN_H_
+
+#include "phy_common.h"
+
+
+struct b43_phy_lcn {
+};
+
+
+struct b43_phy_operations;
+extern const struct b43_phy_operations b43_phyops_lcn;
+
+#endif /* B43_PHY_LCN_H_ */

+ 52 - 10
drivers/net/wireless/b43/phy_n.c

@@ -603,17 +603,33 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
 static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
 {
-	u32 tmslow;
+	u32 tmp;
 
 	if (dev->phy.type != B43_PHYTYPE_N)
 		return;
 
-	tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
-	if (force)
-		tmslow |= SSB_TMSLOW_FGC;
-	else
-		tmslow &= ~SSB_TMSLOW_FGC;
-	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL);
+		if (force)
+			tmp |= BCMA_IOCTL_FGC;
+		else
+			tmp &= ~BCMA_IOCTL_FGC;
+		bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp);
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
+		if (force)
+			tmp |= SSB_TMSLOW_FGC;
+		else
+			tmp &= ~SSB_TMSLOW_FGC;
+		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
+		break;
+#endif
+	}
 }
 
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
@@ -958,8 +974,21 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
 		b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
 		b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
 
-		ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00,
-					0xFC00);
+		switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+		case B43_BUS_BCMA:
+			bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc,
+						 0xFC00, 0xFC00);
+			break;
+#endif
+#ifdef CONFIG_B43_SSB
+		case B43_BUS_SSB:
+			ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco,
+						0xFC00, 0xFC00);
+			break;
+#endif
+		}
+
 		b43_write32(dev, B43_MMIO_MACCTL,
 			b43_read32(dev, B43_MMIO_MACCTL) &
 			~B43_MACCTL_GPOUTSMSK);
@@ -3600,7 +3629,20 @@ int b43_phy_initn(struct b43_wldev *dev)
 	if ((dev->phy.rev >= 3) &&
 	   (sprom->boardflags_lo & B43_BFL_EXTLNA) &&
 	   (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
-		chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
+		switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+		case B43_BUS_BCMA:
+			bcma_cc_set32(&dev->dev->bdev->bus->drv_cc,
+				      BCMA_CC_CHIPCTL, 0x40);
+			break;
+#endif
+#ifdef CONFIG_B43_SSB
+		case B43_BUS_SSB:
+			chipco_set32(&dev->dev->sdev->bus->chipco,
+				     SSB_CHIPCO_CHIPCTL, 0x40);
+			break;
+#endif
+		}
 	}
 	nphy->deaf_count = 0;
 	b43_nphy_tables_init(dev);

+ 34 - 0
drivers/net/wireless/b43/tables_phy_lcn.c

@@ -0,0 +1,34 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n LCN-PHY data tables
+
+  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; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "tables_phy_lcn.h"
+#include "phy_common.h"
+#include "phy_lcn.h"
+
+/**************************************************
+ * Tables ops.
+ **************************************************/
+
+void b43_phy_lcn_tables_init(struct b43_wldev *dev)
+{
+}

+ 6 - 0
drivers/net/wireless/b43/tables_phy_lcn.h

@@ -0,0 +1,6 @@
+#ifndef B43_TABLES_PHY_LCN_H_
+#define B43_TABLES_PHY_LCN_H_
+
+void b43_phy_lcn_tables_init(struct b43_wldev *dev);
+
+#endif /* B43_TABLES_PHY_LCN_H_ */

+ 1 - 2
drivers/net/wireless/b43/xmit.c

@@ -323,8 +323,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
 			/* we give the phase1key and iv16 here, the key is stored in
 			 * shm. With that the hardware can do phase 2 and encryption.
 			 */
-			ieee80211_get_tkip_key(info->control.hw_key, skb_frag,
-					IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
+			ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key);
 			/* phase1key is in host endian. Copy to little-endian txhdr->iv. */
 			for (i = 0; i < 5; i++) {
 				txhdr->iv[i * 2 + 0] = phase1key[i];

+ 1 - 2
drivers/net/wireless/iwlegacy/iwl-4965-tx.c

@@ -240,8 +240,7 @@ static void iwl4965_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
 
 	case WLAN_CIPHER_SUITE_TKIP:
 		tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
-		ieee80211_get_tkip_key(keyconf, skb_frag,
-			IEEE80211_TKIP_P2_KEY, tx_cmd->key);
+		ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
 		IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
 		break;
 

+ 1 - 1
drivers/net/wireless/iwlegacy/iwl4965-base.c

@@ -1484,7 +1484,7 @@ static const char * const desc_lookup_text[] = {
 	"NMI_INTERRUPT_DATA_ACTION_PT",
 	"NMI_TRM_HW_ER",
 	"NMI_INTERRUPT_TRM",
-	"NMI_INTERRUPT_BREAK_POINT"
+	"NMI_INTERRUPT_BREAK_POINT",
 	"DEBUG_0",
 	"DEBUG_1",
 	"DEBUG_2",

+ 2 - 11
drivers/net/wireless/iwlwifi/iwl-1000.c

@@ -125,7 +125,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
-	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
 	priv->hw_params.scd_bc_tbls_size =
 			priv->cfg->base_params->num_of_queues *
 			sizeof(struct iwlagn_scd_bc_tbl);
@@ -172,11 +171,7 @@ static struct iwl_lib_ops iwl1000_lib = {
 	.rx_handler_setup = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.update_chain_flags = iwl_update_chain_flags,
-	.apm_ops = {
-		.init = iwl_apm_init,
-		.config = iwl1000_nic_config,
-	},
+	.nic_config = iwl1000_nic_config,
 	.eeprom_ops = {
 		.regulatory_bands = {
 			EEPROM_REG_BAND_1_CHANNELS,
@@ -187,16 +182,12 @@ static struct iwl_lib_ops iwl1000_lib = {
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REGULATORY_BAND_NO_HT40,
 		},
-		.query_addr = iwlagn_eeprom_query_addr,
 	},
-	.temp_ops = {
-		.temperature = iwlagn_temperature,
-	 },
+	.temperature = iwlagn_temperature,
 };
 
 static const struct iwl_ops iwl1000_ops = {
 	.lib = &iwl1000_lib,
-	.utils = &iwlagn_hcmd_utils,
 };
 
 static struct iwl_base_params iwl1000_base_params = {

+ 25 - 16
drivers/net/wireless/iwlwifi/iwl-2000.c

@@ -123,7 +123,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
-	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
 	priv->hw_params.scd_bc_tbls_size =
 		priv->cfg->base_params->num_of_queues *
 		sizeof(struct iwlagn_scd_bc_tbl);
@@ -169,14 +168,31 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 static struct iwl_lib_ops iwl2000_lib = {
 	.set_hw_params = iwl2000_hw_set_hw_params,
 	.rx_handler_setup = iwlagn_rx_handler_setup,
+	.setup_deferred_work = iwlagn_setup_deferred_work,
+	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
+	.nic_config = iwl2000_nic_config,
+	.eeprom_ops = {
+		.regulatory_bands = {
+			EEPROM_REG_BAND_1_CHANNELS,
+			EEPROM_REG_BAND_2_CHANNELS,
+			EEPROM_REG_BAND_3_CHANNELS,
+			EEPROM_REG_BAND_4_CHANNELS,
+			EEPROM_REG_BAND_5_CHANNELS,
+			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
+			EEPROM_REGULATORY_BAND_NO_HT40,
+		},
+		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
+	},
+	.temperature = iwlagn_temperature,
+};
+
+static struct iwl_lib_ops iwl2030_lib = {
+	.set_hw_params = iwl2000_hw_set_hw_params,
+	.rx_handler_setup = iwlagn_bt_rx_handler_setup,
 	.setup_deferred_work = iwlagn_bt_setup_deferred_work,
 	.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.update_chain_flags = iwl_update_chain_flags,
-	.apm_ops = {
-		.init = iwl_apm_init,
-		.config = iwl2000_nic_config,
-	},
+	.nic_config = iwl2000_nic_config,
 	.eeprom_ops = {
 		.regulatory_bands = {
 			EEPROM_REG_BAND_1_CHANNELS,
@@ -187,32 +203,25 @@ static struct iwl_lib_ops iwl2000_lib = {
 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REGULATORY_BAND_NO_HT40,
 		},
-		.query_addr = iwlagn_eeprom_query_addr,
 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
 	},
-	.temp_ops = {
-		.temperature = iwlagn_temperature,
-	},
+	.temperature = iwlagn_temperature,
 };
 
 static const struct iwl_ops iwl2000_ops = {
 	.lib = &iwl2000_lib,
-	.utils = &iwlagn_hcmd_utils,
 };
 
 static const struct iwl_ops iwl2030_ops = {
-	.lib = &iwl2000_lib,
-	.utils = &iwlagn_hcmd_utils,
+	.lib = &iwl2030_lib,
 };
 
 static const struct iwl_ops iwl105_ops = {
 	.lib = &iwl2000_lib,
-	.utils = &iwlagn_hcmd_utils,
 };
 
 static const struct iwl_ops iwl135_ops = {
-	.lib = &iwl2000_lib,
-	.utils = &iwlagn_hcmd_utils,
+	.lib = &iwl2030_lib,
 };
 
 static struct iwl_base_params iwl2000_base_params = {

+ 6 - 23
drivers/net/wireless/iwlwifi/iwl-5000.c

@@ -46,6 +46,7 @@
 #include "iwl-agn.h"
 #include "iwl-agn-hw.h"
 #include "iwl-5000-hw.h"
+#include "iwl-trans.h"
 
 /* Highest firmware API version supported */
 #define IWL5000_UCODE_API_MAX 5
@@ -156,7 +157,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
-	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
 	priv->hw_params.scd_bc_tbls_size =
 			priv->cfg->base_params->num_of_queues *
 			sizeof(struct iwlagn_scd_bc_tbl);
@@ -200,7 +200,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
-	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
 	priv->hw_params.scd_bc_tbls_size =
 			priv->cfg->base_params->num_of_queues *
 			sizeof(struct iwlagn_scd_bc_tbl);
@@ -316,7 +315,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
 		return -EFAULT;
 	}
 
-	return iwl_send_cmd_sync(priv, &hcmd);
+	return trans_send_cmd(priv, &hcmd);
 }
 
 static struct iwl_lib_ops iwl5000_lib = {
@@ -324,12 +323,8 @@ static struct iwl_lib_ops iwl5000_lib = {
 	.rx_handler_setup = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.update_chain_flags = iwl_update_chain_flags,
 	.set_channel_switch = iwl5000_hw_channel_switch,
-	.apm_ops = {
-		.init = iwl_apm_init,
-		.config = iwl5000_nic_config,
-	},
+	.nic_config = iwl5000_nic_config,
 	.eeprom_ops = {
 		.regulatory_bands = {
 			EEPROM_REG_BAND_1_CHANNELS,
@@ -340,11 +335,8 @@ static struct iwl_lib_ops iwl5000_lib = {
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.query_addr = iwlagn_eeprom_query_addr,
 	},
-	.temp_ops = {
-		.temperature = iwlagn_temperature,
-	 },
+	.temperature = iwlagn_temperature,
 };
 
 static struct iwl_lib_ops iwl5150_lib = {
@@ -352,12 +344,8 @@ static struct iwl_lib_ops iwl5150_lib = {
 	.rx_handler_setup = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.update_chain_flags = iwl_update_chain_flags,
 	.set_channel_switch = iwl5000_hw_channel_switch,
-	.apm_ops = {
-		.init = iwl_apm_init,
-		.config = iwl5000_nic_config,
-	},
+	.nic_config = iwl5000_nic_config,
 	.eeprom_ops = {
 		.regulatory_bands = {
 			EEPROM_REG_BAND_1_CHANNELS,
@@ -368,21 +356,16 @@ static struct iwl_lib_ops iwl5150_lib = {
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.query_addr = iwlagn_eeprom_query_addr,
 	},
-	.temp_ops = {
-		.temperature = iwl5150_temperature,
-	 },
+	.temperature = iwl5150_temperature,
 };
 
 static const struct iwl_ops iwl5000_ops = {
 	.lib = &iwl5000_lib,
-	.utils = &iwlagn_hcmd_utils,
 };
 
 static const struct iwl_ops iwl5150_ops = {
 	.lib = &iwl5150_lib,
-	.utils = &iwlagn_hcmd_utils,
 };
 
 static struct iwl_base_params iwl5000_base_params = {

+ 6 - 24
drivers/net/wireless/iwlwifi/iwl-6000.c

@@ -45,6 +45,7 @@
 #include "iwl-helpers.h"
 #include "iwl-agn-hw.h"
 #include "iwl-6000-hw.h"
+#include "iwl-trans.h"
 
 /* Highest firmware API version supported */
 #define IWL6000_UCODE_API_MAX 4
@@ -144,7 +145,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
-	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
 	priv->hw_params.scd_bc_tbls_size =
 			priv->cfg->base_params->num_of_queues *
 			sizeof(struct iwlagn_scd_bc_tbl);
@@ -255,7 +255,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
 		return -EFAULT;
 	}
 
-	return iwl_send_cmd_sync(priv, &hcmd);
+	return trans_send_cmd(priv, &hcmd);
 }
 
 static struct iwl_lib_ops iwl6000_lib = {
@@ -263,12 +263,8 @@ static struct iwl_lib_ops iwl6000_lib = {
 	.rx_handler_setup = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.update_chain_flags = iwl_update_chain_flags,
 	.set_channel_switch = iwl6000_hw_channel_switch,
-	.apm_ops = {
-		.init = iwl_apm_init,
-		.config = iwl6000_nic_config,
-	},
+	.nic_config = iwl6000_nic_config,
 	.eeprom_ops = {
 		.regulatory_bands = {
 			EEPROM_REG_BAND_1_CHANNELS,
@@ -279,12 +275,9 @@ static struct iwl_lib_ops iwl6000_lib = {
 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.query_addr = iwlagn_eeprom_query_addr,
 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
 	},
-	.temp_ops = {
-		.temperature = iwlagn_temperature,
-	 },
+	.temperature = iwlagn_temperature,
 };
 
 static struct iwl_lib_ops iwl6030_lib = {
@@ -293,12 +286,8 @@ static struct iwl_lib_ops iwl6030_lib = {
 	.setup_deferred_work = iwlagn_bt_setup_deferred_work,
 	.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.update_chain_flags = iwl_update_chain_flags,
 	.set_channel_switch = iwl6000_hw_channel_switch,
-	.apm_ops = {
-		.init = iwl_apm_init,
-		.config = iwl6000_nic_config,
-	},
+	.nic_config = iwl6000_nic_config,
 	.eeprom_ops = {
 		.regulatory_bands = {
 			EEPROM_REG_BAND_1_CHANNELS,
@@ -309,12 +298,9 @@ static struct iwl_lib_ops iwl6030_lib = {
 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.query_addr = iwlagn_eeprom_query_addr,
 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
 	},
-	.temp_ops = {
-		.temperature = iwlagn_temperature,
-	 },
+	.temperature = iwlagn_temperature,
 };
 
 static struct iwl_nic_ops iwl6050_nic_ops = {
@@ -327,24 +313,20 @@ static struct iwl_nic_ops iwl6150_nic_ops = {
 
 static const struct iwl_ops iwl6000_ops = {
 	.lib = &iwl6000_lib,
-	.utils = &iwlagn_hcmd_utils,
 };
 
 static const struct iwl_ops iwl6050_ops = {
 	.lib = &iwl6000_lib,
-	.utils = &iwlagn_hcmd_utils,
 	.nic = &iwl6050_nic_ops,
 };
 
 static const struct iwl_ops iwl6150_ops = {
 	.lib = &iwl6000_lib,
-	.utils = &iwlagn_hcmd_utils,
 	.nic = &iwl6150_nic_ops,
 };
 
 static const struct iwl_ops iwl6030_ops = {
 	.lib = &iwl6030_lib,
-	.utils = &iwlagn_hcmd_utils,
 };
 
 static struct iwl_base_params iwl6000_base_params = {

+ 8 - 7
drivers/net/wireless/iwlwifi/iwl-agn-calib.c

@@ -66,6 +66,8 @@
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-agn-calib.h"
+#include "iwl-trans.h"
+#include "iwl-agn.h"
 
 /*****************************************************************************
  * INIT calibrations framework
@@ -87,6 +89,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
 
 	struct iwl_host_cmd hcmd = {
 		.id = REPLY_PHY_CALIBRATION_CMD,
+		.flags = CMD_SYNC,
 	};
 
 	for (i = 0; i < IWL_CALIB_MAX; i++) {
@@ -95,7 +98,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
 			hcmd.len[0] = priv->calib_results[i].buf_len;
 			hcmd.data[0] = priv->calib_results[i].buf;
 			hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
-			ret = iwl_send_cmd_sync(priv, &hcmd);
+			ret = trans_send_cmd(priv, &hcmd);
 			if (ret) {
 				IWL_ERR(priv, "Error %d iteration %d\n",
 					ret, i);
@@ -481,7 +484,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
 	memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
 	       sizeof(u16)*HD_TABLE_SIZE);
 
-	return iwl_send_cmd(priv, &cmd_out);
+	return trans_send_cmd(priv, &cmd_out);
 }
 
 /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
@@ -545,7 +548,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
 	       &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]),
 	       sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES);
 
-	return iwl_send_cmd(priv, &cmd_out);
+	return trans_send_cmd(priv, &cmd_out);
 }
 
 void iwl_init_sensitivity(struct iwl_priv *priv)
@@ -991,16 +994,14 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
 	IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n",
 			min_average_noise, min_average_noise_antenna_i);
 
-	if (priv->cfg->ops->utils->gain_computation)
-		priv->cfg->ops->utils->gain_computation(priv, average_noise,
+	iwlagn_gain_computation(priv, average_noise,
 				min_average_noise_antenna_i, min_average_noise,
 				find_first_chain(priv->cfg->valid_rx_ant));
 
 	/* Some power changes may have been made during the calibration.
 	 * Update and commit the RXON
 	 */
-	if (priv->cfg->ops->lib->update_chain_flags)
-		priv->cfg->ops->lib->update_chain_flags(priv);
+	iwl_update_chain_flags(priv);
 
 	data->state = IWL_CHAIN_NOISE_DONE;
 	iwl_power_update_mode(priv, false);

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

@@ -71,13 +71,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv);
 
 void iwl_init_sensitivity(struct iwl_priv *priv);
 void iwl_reset_run_time_calib(struct iwl_priv *priv);
-static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
-{
-
-	if (!priv->disable_chain_noise_cal &&
-	    priv->cfg->ops->utils->chain_noise_reset)
-		priv->cfg->ops->utils->chain_noise_reset(priv);
-}
 
 int iwl_send_calib_results(struct iwl_priv *priv);
 int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);

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

@@ -150,7 +150,7 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
 
 void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
 {
-	const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
+	const u8 *addr = iwl_eeprom_query_addr(priv,
 					EEPROM_MAC_ADDRESS);
 	memcpy(mac, addr, ETH_ALEN);
 }
@@ -245,10 +245,10 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
 	BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8);
 
 	/* the length is in 16-bit words, but we want entries */
-	txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS);
+	txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS);
 	entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
 
-	txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
+	txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
 
 	for (idx = 0; idx < entries; idx++) {
 		txp = &txp_array[idx];

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

@@ -36,6 +36,7 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-agn.h"
+#include "iwl-trans.h"
 
 int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
 {
@@ -45,7 +46,9 @@ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
 
 	if (IWL_UCODE_API(priv->ucode_ver) > 1) {
 		IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
-		return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD,
+		return trans_send_cmd_pdu(priv,
+					TX_ANT_CONFIGURATION_CMD,
+					CMD_SYNC,
 					sizeof(struct iwl_tx_ant_config_cmd),
 					&tx_ant_cmd);
 	} else {
@@ -54,17 +57,7 @@ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
 	}
 }
 
-static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
-{
-	u16 size = (u16)sizeof(struct iwl_addsta_cmd);
-	struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
-	memcpy(addsta, cmd, size);
-	/* resrved in 5000 */
-	addsta->rate_n_flags = cpu_to_le16(0);
-	return size;
-}
-
-static void iwlagn_gain_computation(struct iwl_priv *priv,
+void iwlagn_gain_computation(struct iwl_priv *priv,
 		u32 average_noise[NUM_RX_CHAINS],
 		u16 min_average_noise_antenna_i,
 		u32 min_average_noise,
@@ -115,96 +108,14 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
 			priv->_agn.phy_calib_chain_noise_gain_cmd);
 		cmd.delta_gain_1 = data->delta_gain_code[1];
 		cmd.delta_gain_2 = data->delta_gain_code[2];
-		iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
-			sizeof(cmd), &cmd, NULL);
+		trans_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
+			CMD_ASYNC, sizeof(cmd), &cmd);
 
 		data->radio_write = 1;
 		data->state = IWL_CHAIN_NOISE_CALIBRATED;
 	}
 }
 
-static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
-{
-	struct iwl_chain_noise_data *data = &priv->chain_noise_data;
-	int ret;
-
-	if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
-	    iwl_is_any_associated(priv)) {
-		struct iwl_calib_chain_noise_reset_cmd cmd;
-
-		/* clear data for chain noise calibration algorithm */
-		data->chain_noise_a = 0;
-		data->chain_noise_b = 0;
-		data->chain_noise_c = 0;
-		data->chain_signal_a = 0;
-		data->chain_signal_b = 0;
-		data->chain_signal_c = 0;
-		data->beacon_count = 0;
-
-		memset(&cmd, 0, sizeof(cmd));
-		iwl_set_calib_hdr(&cmd.hdr,
-			priv->_agn.phy_calib_chain_noise_reset_cmd);
-		ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
-					sizeof(cmd), &cmd);
-		if (ret)
-			IWL_ERR(priv,
-				"Could not send REPLY_PHY_CALIBRATION_CMD\n");
-		data->state = IWL_CHAIN_NOISE_ACCUMULATE;
-		IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
-	}
-}
-
-static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
-				     struct ieee80211_tx_info *info,
-				     __le16 fc, __le32 *tx_flags)
-{
-	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
-	    info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT ||
-	    info->flags & IEEE80211_TX_CTL_AMPDU)
-		*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
-}
-
-/* Calc max signal level (dBm) among 3 possible receivers */
-static int iwlagn_calc_rssi(struct iwl_priv *priv,
-			     struct iwl_rx_phy_res *rx_resp)
-{
-	/* data from PHY/DSP regarding signal strength, etc.,
-	 *   contents are always there, not configurable by host
-	 */
-	struct iwlagn_non_cfg_phy *ncphy =
-		(struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
-	u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
-	u8 agc;
-
-	val  = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]);
-	agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS;
-
-	/* Find max rssi among 3 possible receivers.
-	 * These values are measured by the digital signal processor (DSP).
-	 * They should stay fairly constant even as the signal strength varies,
-	 *   if the radio's automatic gain control (AGC) is working right.
-	 * AGC value (see below) will provide the "interesting" info.
-	 */
-	val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]);
-	rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >>
-		IWLAGN_OFDM_RSSI_A_BIT_POS;
-	rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >>
-		IWLAGN_OFDM_RSSI_B_BIT_POS;
-	val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]);
-	rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >>
-		IWLAGN_OFDM_RSSI_C_BIT_POS;
-
-	max_rssi = max_t(u32, rssi_a, rssi_b);
-	max_rssi = max_t(u32, max_rssi, rssi_c);
-
-	IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
-		rssi_a, rssi_b, rssi_c, max_rssi, agc);
-
-	/* dBm = max_rssi dB - agc dB - constant.
-	 * Higher AGC (higher radio gain) means lower signal. */
-	return max_rssi - agc - IWLAGN_RSSI_OFFSET;
-}
-
 int iwlagn_set_pan_params(struct iwl_priv *priv)
 {
 	struct iwl_wipan_params_cmd cmd;
@@ -290,18 +201,10 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
 	cmd.slots[0].width = cpu_to_le16(slot0);
 	cmd.slots[1].width = cpu_to_le16(slot1);
 
-	ret = iwl_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, sizeof(cmd), &cmd);
+	ret = trans_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC,
+			sizeof(cmd), &cmd);
 	if (ret)
 		IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
 
 	return ret;
 }
-
-struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
-	.build_addsta_hcmd = iwlagn_build_addsta_hcmd,
-	.gain_computation = iwlagn_gain_computation,
-	.chain_noise_reset = iwlagn_chain_noise_reset,
-	.tx_cmd_protection = iwlagn_tx_cmd_protection,
-	.calc_rssi = iwlagn_calc_rssi,
-	.request_scan = iwlagn_request_scan,
-};

+ 127 - 35
drivers/net/wireless/iwlwifi/iwl-agn-lib.c

@@ -39,6 +39,7 @@
 #include "iwl-agn-hw.h"
 #include "iwl-agn.h"
 #include "iwl-sta.h"
+#include "iwl-trans.h"
 
 static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
 {
@@ -540,8 +541,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
 	else
 		tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
 
-	return iwl_send_cmd_pdu(priv, tx_ant_cfg_cmd, sizeof(tx_power_cmd),
-				&tx_power_cmd);
+	return trans_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC,
+			sizeof(tx_power_cmd), &tx_power_cmd);
 }
 
 void iwlagn_temperature(struct iwl_priv *priv)
@@ -610,8 +611,7 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
 	return (address & ADDRESS_MSK) + (offset << 1);
 }
 
-const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
-					   size_t offset)
+const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
 {
 	u32 address = eeprom_indirect_address(priv, offset);
 	BUG_ON(address >= priv->cfg->base_params->eeprom_size);
@@ -702,7 +702,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
 
 	/* nic_init */
 	spin_lock_irqsave(&priv->lock, flags);
-	priv->cfg->ops->lib->apm_ops.init(priv);
+	iwl_apm_init(priv);
 
 	/* Set interrupt coalescing calibration timer to default (512 usecs) */
 	iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
@@ -711,10 +711,10 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
 
 	iwlagn_set_pwr_vmain(priv);
 
-	priv->cfg->ops->lib->apm_ops.config(priv);
+	priv->cfg->ops->lib->nic_config(priv);
 
 	/* Allocate the RX queue, or reset if it is already allocated */
-	priv->trans.ops->rx_init(priv);
+	trans_rx_init(priv);
 
 	iwlagn_rx_replenish(priv);
 
@@ -728,7 +728,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* Allocate or reset and init all Tx and Command queues */
-	if (priv->trans.ops->tx_init(priv))
+	if (trans_tx_init(priv))
 		return -ENOMEM;
 
 	if (priv->cfg->base_params->shadow_reg_enable) {
@@ -905,17 +905,6 @@ void iwlagn_rx_replenish_now(struct iwl_priv *priv)
 	iwlagn_rx_queue_restock(priv);
 }
 
-int iwlagn_rxq_stop(struct iwl_priv *priv)
-{
-
-	/* stop Rx DMA */
-	iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-	iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
-			    FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
-
-	return 0;
-}
-
 int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
 {
 	int idx = 0;
@@ -1074,6 +1063,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_CMD,
 		.len = { sizeof(struct iwl_scan_cmd), },
+		.flags = CMD_SYNC,
 	};
 	struct iwl_scan_cmd *scan;
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
@@ -1370,7 +1360,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	if (ret)
 		return ret;
 
-	ret = iwl_send_cmd_sync(priv, &cmd);
+	ret = trans_send_cmd(priv, &cmd);
 	if (ret) {
 		clear_bit(STATUS_SCAN_HW, &priv->status);
 		iwlagn_set_pan_params(priv);
@@ -1476,7 +1466,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
 		       flush_cmd.fifo_control);
 	flush_cmd.flush_control = cpu_to_le16(flush_control);
 
-	return iwl_send_cmd(priv, &cmd);
+	return trans_send_cmd(priv, &cmd);
 }
 
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
@@ -1644,9 +1634,11 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
 	} else {
 		basic.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
 					IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
-		if (priv->cfg->bt_params &&
-		    priv->cfg->bt_params->bt_sco_disable)
+
+		if (!priv->bt_enable_pspoll)
 			basic.flags |= IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE;
+		else
+			basic.flags &= ~IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE;
 
 		if (priv->bt_ch_announce)
 			basic.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
@@ -1668,19 +1660,97 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
 	if (priv->cfg->bt_params->bt_session_2) {
 		memcpy(&bt_cmd_2000.basic, &basic,
 			sizeof(basic));
-		ret = iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
-			sizeof(bt_cmd_2000), &bt_cmd_2000);
+		ret = trans_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+			CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000);
 	} else {
 		memcpy(&bt_cmd_6000.basic, &basic,
 			sizeof(basic));
-		ret = iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
-			sizeof(bt_cmd_6000), &bt_cmd_6000);
+		ret = trans_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+			CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000);
 	}
 	if (ret)
 		IWL_ERR(priv, "failed to send BT Coex Config\n");
 
 }
 
+void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena)
+{
+	struct iwl_rxon_context *ctx, *found_ctx = NULL;
+	bool found_ap = false;
+
+	lockdep_assert_held(&priv->mutex);
+
+	/* Check whether AP or GO mode is active. */
+	if (rssi_ena) {
+		for_each_context(priv, ctx) {
+			if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_AP &&
+			    iwl_is_associated_ctx(ctx)) {
+				found_ap = true;
+				break;
+			}
+		}
+	}
+
+	/*
+	 * If disable was received or If GO/AP mode, disable RSSI
+	 * measurements.
+	 */
+	if (!rssi_ena || found_ap) {
+		if (priv->cur_rssi_ctx) {
+			ctx = priv->cur_rssi_ctx;
+			ieee80211_disable_rssi_reports(ctx->vif);
+			priv->cur_rssi_ctx = NULL;
+		}
+		return;
+	}
+
+	/*
+	 * If rssi measurements need to be enabled, consider all cases now.
+	 * Figure out how many contexts are active.
+	 */
+	for_each_context(priv, ctx) {
+		if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION &&
+		    iwl_is_associated_ctx(ctx)) {
+			found_ctx = ctx;
+			break;
+		}
+	}
+
+	/*
+	 * rssi monitor already enabled for the correct interface...nothing
+	 * to do.
+	 */
+	if (found_ctx == priv->cur_rssi_ctx)
+		return;
+
+	/*
+	 * Figure out if rssi monitor is currently enabled, and needs
+	 * to be changed. If rssi monitor is already enabled, disable
+	 * it first else just enable rssi measurements on the
+	 * interface found above.
+	 */
+	if (priv->cur_rssi_ctx) {
+		ctx = priv->cur_rssi_ctx;
+		if (ctx->vif)
+			ieee80211_disable_rssi_reports(ctx->vif);
+	}
+
+	priv->cur_rssi_ctx = found_ctx;
+
+	if (!found_ctx)
+		return;
+
+	ieee80211_enable_rssi_reports(found_ctx->vif,
+			IWLAGN_BT_PSP_MIN_RSSI_THRESHOLD,
+			IWLAGN_BT_PSP_MAX_RSSI_THRESHOLD);
+}
+
+static bool iwlagn_bt_traffic_is_sco(struct iwl_bt_uart_msg *uart_msg)
+{
+	return BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3 >>
+			BT_UART_MSG_FRAME3SCOESCO_POS;
+}
+
 static void iwlagn_bt_traffic_change_work(struct work_struct *work)
 {
 	struct iwl_priv *priv =
@@ -1733,8 +1803,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
 	if (test_bit(STATUS_SCAN_HW, &priv->status))
 		goto out;
 
-	if (priv->cfg->ops->lib->update_chain_flags)
-		priv->cfg->ops->lib->update_chain_flags(priv);
+	iwl_update_chain_flags(priv);
 
 	if (smps_request != -1) {
 		priv->current_ht_config.smps = smps_request;
@@ -1743,10 +1812,30 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
 				ieee80211_request_smps(ctx->vif, smps_request);
 		}
 	}
+
+	/*
+	 * Dynamic PS poll related functionality. Adjust RSSI measurements if
+	 * necessary.
+	 */
+	iwlagn_bt_coex_rssi_monitor(priv);
 out:
 	mutex_unlock(&priv->mutex);
 }
 
+/*
+ * If BT sco traffic, and RSSI monitor is enabled, move measurements to the
+ * correct interface or disable it if this is the last interface to be
+ * removed.
+ */
+void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv)
+{
+	if (priv->bt_is_sco &&
+	    priv->bt_traffic_load == IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS)
+		iwlagn_bt_adjust_rssi_monitor(priv, true);
+	else
+		iwlagn_bt_adjust_rssi_monitor(priv, false);
+}
+
 static void iwlagn_print_uartmsg(struct iwl_priv *priv,
 				struct iwl_bt_uart_msg *uart_msg)
 {
@@ -1862,6 +1951,8 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
 	iwlagn_print_uartmsg(priv, uart_msg);
 
 	priv->last_bt_traffic_load = priv->bt_traffic_load;
+	priv->bt_is_sco = iwlagn_bt_traffic_is_sco(uart_msg);
+
 	if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
 		if (priv->bt_status != coex->bt_status ||
 		    priv->last_bt_traffic_load != coex->bt_traffic_load) {
@@ -2321,13 +2412,14 @@ void iwlagn_stop_device(struct iwl_priv *priv)
 	 * already dead.
 	 */
 	if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
-                iwlagn_txq_ctx_stop(priv);
-                iwlagn_rxq_stop(priv);
+		trans_tx_stop(priv);
+		trans_rx_stop(priv);
 
-                /* Power-down device's busmaster DMA clocks */
-                iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
-                udelay(5);
-        }
+		/* Power-down device's busmaster DMA clocks */
+		iwl_write_prph(priv, APMG_CLK_DIS_REG,
+			       APMG_CLK_VAL_DMA_CLK_RQT);
+		udelay(5);
+	}
 
 	/* Make sure (redundant) we've released our request to stay awake */
 	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);

+ 18 - 10
drivers/net/wireless/iwlwifi/iwl-agn-rs.c

@@ -336,6 +336,12 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
 }
 
 #ifdef CONFIG_MAC80211_DEBUGFS
+/**
+ * Program the device to use fixed rate for frame transmit
+ * This is for debugging/testing only
+ * once the device start use fixed rate, we need to reload the module
+ * to being back the normal operation.
+ */
 static void rs_program_fix_rate(struct iwl_priv *priv,
 				struct iwl_lq_sta *lq_sta)
 {
@@ -348,13 +354,15 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
 	lq_sta->active_mimo2_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
 	lq_sta->active_mimo3_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
 
-	lq_sta->dbg_fixed_rate = priv->dbg_fixed_rate;
+	/* testmode has higher priority to overwirte the fixed rate */
+	if (priv->tm_fixed_rate)
+		lq_sta->dbg_fixed_rate = priv->tm_fixed_rate;
 
 	IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
-		lq_sta->lq.sta_id, priv->dbg_fixed_rate);
+		lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
 
-	if (priv->dbg_fixed_rate) {
-		rs_fill_link_cmd(NULL, lq_sta, priv->dbg_fixed_rate);
+	if (lq_sta->dbg_fixed_rate) {
+		rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
 		iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
 				false);
 	}
@@ -1073,7 +1081,8 @@ done:
 	if (sta && sta->supp_rates[sband->band])
 		rs_rate_scale_perform(priv, skb, sta, lq_sta);
 #ifdef CONFIG_MAC80211_DEBUGFS
-	if (priv->dbg_fixed_rate != lq_sta->dbg_fixed_rate)
+	if ((priv->tm_fixed_rate) &&
+	    (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
 		rs_program_fix_rate(priv, lq_sta);
 #endif
 	if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
@@ -2896,7 +2905,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
 		lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
 	lq_sta->is_agg = 0;
 
-	priv->dbg_fixed_rate = 0;
+	priv->tm_fixed_rate = 0;
 #ifdef CONFIG_MAC80211_DEBUGFS
 	lq_sta->dbg_fixed_rate = 0;
 #endif
@@ -3095,7 +3104,6 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
 			IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
 		} else {
 			lq_sta->dbg_fixed_rate = 0;
-			priv->dbg_fixed_rate = 0;
 			IWL_ERR(priv,
 			    "Invalid antenna selection 0x%X, Valid is 0x%X\n",
 			    ant_sel_tx, valid_tx_ant);
@@ -3123,9 +3131,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
 		return -EFAULT;
 
 	if (sscanf(buf, "%x", &parsed_rate) == 1)
-		priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = parsed_rate;
+		lq_sta->dbg_fixed_rate = parsed_rate;
 	else
-		priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = 0;
+		lq_sta->dbg_fixed_rate = 0;
 
 	rs_program_fix_rate(priv, lq_sta);
 
@@ -3155,7 +3163,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 			lq_sta->total_failed, lq_sta->total_success,
 			lq_sta->active_legacy_rate);
 	desc += sprintf(buff+desc, "fixed rate 0x%X\n",
-			priv->dbg_fixed_rate);
+			lq_sta->dbg_fixed_rate);
 	desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
 	    (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
 	    (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",

+ 47 - 8
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c

@@ -30,6 +30,7 @@
 #include "iwl-core.h"
 #include "iwl-agn-calib.h"
 #include "iwl-helpers.h"
+#include "iwl-trans.h"
 
 static int iwlagn_disable_bss(struct iwl_priv *priv,
 			      struct iwl_rxon_context *ctx,
@@ -39,7 +40,8 @@ static int iwlagn_disable_bss(struct iwl_priv *priv,
 	int ret;
 
 	send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-	ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+	ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd,
+				CMD_SYNC, sizeof(*send), send);
 
 	send->filter_flags = old_filter;
 
@@ -64,7 +66,8 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
 
 	send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	send->dev_type = RXON_DEV_TYPE_P2P;
-	ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+	ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd,
+				CMD_SYNC, sizeof(*send), send);
 
 	send->filter_flags = old_filter;
 	send->dev_type = old_dev_type;
@@ -89,7 +92,8 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv,
 	int ret;
 
 	send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-	ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+	ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
+				sizeof(*send), send);
 
 	send->filter_flags = old_filter;
 
@@ -117,7 +121,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
 		      ctx->qos_data.qos_active,
 		      ctx->qos_data.def_qos_parm.qos_flags);
 
-	ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
+	ret = trans_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC,
 			       sizeof(struct iwl_qosparam_cmd),
 			       &ctx->qos_data.def_qos_parm);
 	if (ret)
@@ -176,8 +180,8 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
 		 ctx->staging.ofdm_ht_triple_stream_basic_rates;
 	rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
 
-	ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
-				     sizeof(rxon_assoc), &rxon_assoc, NULL);
+	ret = trans_send_cmd_pdu(priv, ctx->rxon_assoc_cmd,
+				CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc);
 	return ret;
 }
 
@@ -262,7 +266,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
 	 * Associated RXON doesn't clear the station table in uCode,
 	 * so we don't need to restore stations etc. after this.
 	 */
-	ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+	ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
 		      sizeof(struct iwl_rxon_cmd), &ctx->staging);
 	if (ret) {
 		IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
@@ -670,6 +674,38 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv,
 	ht_conf->single_chain_sufficient = !need_multiple;
 }
 
+static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
+{
+	struct iwl_chain_noise_data *data = &priv->chain_noise_data;
+	int ret;
+
+	if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
+	    iwl_is_any_associated(priv)) {
+		struct iwl_calib_chain_noise_reset_cmd cmd;
+
+		/* clear data for chain noise calibration algorithm */
+		data->chain_noise_a = 0;
+		data->chain_noise_b = 0;
+		data->chain_noise_c = 0;
+		data->chain_signal_a = 0;
+		data->chain_signal_b = 0;
+		data->chain_signal_c = 0;
+		data->beacon_count = 0;
+
+		memset(&cmd, 0, sizeof(cmd));
+		iwl_set_calib_hdr(&cmd.hdr,
+			priv->_agn.phy_calib_chain_noise_reset_cmd);
+		ret = trans_send_cmd_pdu(priv,
+					REPLY_PHY_CALIBRATION_CMD,
+					CMD_SYNC, sizeof(cmd), &cmd);
+		if (ret)
+			IWL_ERR(priv,
+				"Could not send REPLY_PHY_CALIBRATION_CMD\n");
+		data->state = IWL_CHAIN_NOISE_ACCUMULATE;
+		IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
+	}
+}
+
 void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
 			     struct ieee80211_bss_conf *bss_conf,
@@ -727,6 +763,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
 			}
 			ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 		}
+
+		iwlagn_bt_coex_rssi_monitor(priv);
 	}
 
 	if (ctx->ht.enabled) {
@@ -776,7 +814,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
 			iwl_power_update_mode(priv, false);
 
 		/* Enable RX differential gain and sensitivity calibrations */
-		iwl_chain_noise_reset(priv);
+		if (!priv->disable_chain_noise_cal)
+			iwlagn_chain_noise_reset(priv);
 		priv->start_calib = 1;
 	}
 

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

@@ -33,6 +33,7 @@
 #include "iwl-core.h"
 #include "iwl-sta.h"
 #include "iwl-agn.h"
+#include "iwl-trans.h"
 
 static struct iwl_link_quality_cmd *
 iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id)
@@ -180,7 +181,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
 	cmd.len[0] = cmd_size;
 
 	if (not_empty || send_if_empty)
-		return iwl_send_cmd(priv, &cmd);
+		return trans_send_cmd(priv, &cmd);
 	else
 		return 0;
 }

+ 23 - 86
drivers/net/wireless/iwlwifi/iwl-agn-tx.c

@@ -339,6 +339,16 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
 	iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
 }
 
+static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
+				     struct ieee80211_tx_info *info,
+				     __le16 fc, __le32 *tx_flags)
+{
+	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
+	    info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT ||
+	    info->flags & IEEE80211_TX_CTL_AMPDU)
+		*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
+}
+
 /*
  * handle build REPLY_TX command notification.
  */
@@ -388,7 +398,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
 		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
 	}
 
-	priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags);
+	iwlagn_tx_cmd_protection(priv, info, fc, &tx_flags);
 
 	tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
 	if (ieee80211_is_mgmt(fc)) {
@@ -436,6 +446,16 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
 	if (ieee80211_is_data(fc)) {
 		tx_cmd->initial_rate_index = 0;
 		tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
+		if (priv->tm_fixed_rate) {
+			/*
+			 * rate overwrite by testmode
+			 * we not only send lq command to change rate
+			 * we also re-enforce per data pkt base.
+			 */
+			tx_cmd->tx_flags &= ~TX_CMD_FLG_STA_RATE_MSK;
+			memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate,
+			       sizeof(tx_cmd->rate_n_flags));
+		}
 		return;
 	}
 
@@ -497,8 +517,7 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
 
 	case WLAN_CIPHER_SUITE_TKIP:
 		tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
-		ieee80211_get_tkip_key(keyconf, skb_frag,
-			IEEE80211_TKIP_P2_KEY, tx_cmd->key);
+		ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
 		IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
 		break;
 
@@ -831,88 +850,6 @@ drop_unlock_priv:
 	return -1;
 }
 
-static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv,
-				    struct iwl_dma_ptr *ptr, size_t size)
-{
-	ptr->addr = dma_alloc_coherent(priv->bus.dev, size,
-				       &ptr->dma, GFP_KERNEL);
-	if (!ptr->addr)
-		return -ENOMEM;
-	ptr->size = size;
-	return 0;
-}
-
-static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv,
-				    struct iwl_dma_ptr *ptr)
-{
-	if (unlikely(!ptr->addr))
-		return;
-
-	dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma);
-	memset(ptr, 0, sizeof(*ptr));
-}
-
-/**
- * iwlagn_hw_txq_ctx_free - Free TXQ Context
- *
- * Destroy all TX DMA queues and structures
- */
-void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
-{
-	int txq_id;
-
-	/* Tx queues */
-	if (priv->txq) {
-		for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
-			if (txq_id == priv->cmd_queue)
-				iwl_cmd_queue_free(priv);
-			else
-				iwl_tx_queue_free(priv, txq_id);
-	}
-	iwlagn_free_dma_ptr(priv, &priv->kw);
-
-	iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls);
-
-	/* free tx queue structure */
-	iwl_free_txq_mem(priv);
-}
-
-/**
- * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
- */
-void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
-{
-	int ch, txq_id;
-	unsigned long flags;
-
-	/* Turn off all Tx DMA fifos */
-	spin_lock_irqsave(&priv->lock, flags);
-
-	iwlagn_txq_set_sched(priv, 0);
-
-	/* Stop each Tx DMA channel, and wait for it to be idle */
-	for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
-		iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
-		if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
-				    FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
-				    1000))
-			IWL_ERR(priv, "Failing on timeout while stopping"
-			    " DMA channel %d [0x%08x]", ch,
-			    iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG));
-	}
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	if (!priv->txq)
-		return;
-
-	/* Unmap DMA from host system and free skb's */
-	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
-		if (txq_id == priv->cmd_queue)
-			iwl_cmd_queue_unmap(priv);
-		else
-			iwl_tx_queue_unmap(priv, txq_id);
-}
-
 /*
  * Find first available (lowest unused) Tx Queue, mark it "active".
  * Called only when finding queue for aggregation.
@@ -1171,7 +1108,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
 
 		iwlagn_txq_inval_byte_cnt_tbl(priv, txq);
 
-		iwlagn_txq_free_tfd(priv, txq);
+		iwlagn_txq_free_tfd(priv, txq, txq->q.read_ptr);
 	}
 	return nfreed;
 }

+ 9 - 5
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c

@@ -39,6 +39,7 @@
 #include "iwl-agn-hw.h"
 #include "iwl-agn.h"
 #include "iwl-agn-calib.h"
+#include "iwl-trans.h"
 
 #define IWL_AC_UNSET -1
 
@@ -223,7 +224,7 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
 	calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL;
 	calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL;
 
-	return iwl_send_cmd(priv, &cmd);
+	return trans_send_cmd(priv, &cmd);
 }
 
 void iwlagn_rx_calib_result(struct iwl_priv *priv,
@@ -321,7 +322,8 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
 		/* coexistence is disabled */
 		memset(&coex_cmd, 0, sizeof(coex_cmd));
 	}
-	return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
+	return trans_send_cmd_pdu(priv,
+				COEX_PRIORITY_TABLE_CMD, CMD_SYNC,
 				sizeof(coex_cmd), &coex_cmd);
 }
 
@@ -353,7 +355,8 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv)
 
 	memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl,
 		sizeof(iwlagn_bt_prio_tbl));
-	if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE,
+	if (trans_send_cmd_pdu(priv,
+				REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC,
 				sizeof(prio_tbl_cmd), &prio_tbl_cmd))
 		IWL_ERR(priv, "failed to send BT prio tbl command\n");
 }
@@ -365,7 +368,8 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
 
 	env_cmd.action = action;
 	env_cmd.type = type;
-	ret = iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
+	ret = trans_send_cmd_pdu(priv,
+			       REPLY_BT_COEX_PROT_ENV, CMD_SYNC,
 			       sizeof(env_cmd), &env_cmd);
 	if (ret)
 		IWL_ERR(priv, "failed to send BT env command\n");
@@ -403,7 +407,7 @@ static int iwlagn_alive_notify(struct iwl_priv *priv)
 		       priv->scd_bc_tbls.dma >> 10);
 
 	/* Enable DMA channel */
-	for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++)
+	for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++)
 		iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
 				FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
 				FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);

+ 51 - 11
drivers/net/wireless/iwlwifi/iwl-agn.c

@@ -129,6 +129,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
 	struct iwl_tx_beacon_cmd *tx_beacon_cmd;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_TX_BEACON,
+		.flags = CMD_SYNC,
 	};
 	struct ieee80211_tx_info *info;
 	u32 frame_size;
@@ -205,7 +206,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
 	cmd.data[1] = priv->beacon_skb->data;
 	cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
 
-	return iwl_send_cmd_sync(priv, &cmd);
+	return trans_send_cmd(priv, &cmd);
 }
 
 static void iwl_bg_beacon_update(struct work_struct *work)
@@ -578,7 +579,8 @@ static void iwl_rx_handle(struct iwl_priv *priv)
 
 		if (reclaim) {
 			/* Invoke any callbacks, transfer the buffer to caller,
-			 * and fire off the (possibly) blocking iwl_send_cmd()
+			 * and fire off the (possibly) blocking
+			 * trans_send_cmd()
 			 * as we reclaim the driver command queue */
 			if (rxb->page)
 				iwl_tx_cmd_complete(priv, rxb);
@@ -1563,7 +1565,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 	release_firmware(ucode_raw);
 }
 
-static const char *desc_lookup_text[] = {
+static const char * const desc_lookup_text[] = {
 	"OK",
 	"FAIL",
 	"BAD_PARAM",
@@ -1587,7 +1589,7 @@ static const char *desc_lookup_text[] = {
 	"NMI_INTERRUPT_DATA_ACTION_PT",
 	"NMI_TRM_HW_ER",
 	"NMI_INTERRUPT_TRM",
-	"NMI_INTERRUPT_BREAK_POINT"
+	"NMI_INTERRUPT_BREAK_POINT",
 	"DEBUG_0",
 	"DEBUG_1",
 	"DEBUG_2",
@@ -1940,8 +1942,9 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 		adv_cmd.critical_temperature_exit =
 			cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
 
-		ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
-				       sizeof(adv_cmd), &adv_cmd);
+		ret = trans_send_cmd_pdu(priv,
+				       REPLY_CT_KILL_CONFIG_CMD,
+				       CMD_SYNC, sizeof(adv_cmd), &adv_cmd);
 		if (ret)
 			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
 		else
@@ -1955,8 +1958,9 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 		cmd.critical_temperature_R =
 			cpu_to_le32(priv->hw_params.ct_kill_threshold);
 
-		ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
-				       sizeof(cmd), &cmd);
+		ret = trans_send_cmd_pdu(priv,
+				       REPLY_CT_KILL_CONFIG_CMD,
+				       CMD_SYNC, sizeof(cmd), &cmd);
 		if (ret)
 			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
 		else
@@ -1980,7 +1984,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
 	calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
 	calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
 
-	return iwl_send_cmd(priv, &cmd);
+	return trans_send_cmd(priv, &cmd);
 }
 
 
@@ -2011,11 +2015,18 @@ int iwl_alive_start(struct iwl_priv *priv)
 	if (priv->cfg->bt_params &&
 	    priv->cfg->bt_params->advanced_bt_coexist) {
 		/* Configure Bluetooth device coexistence support */
+		if (priv->cfg->bt_params->bt_sco_disable)
+			priv->bt_enable_pspoll = false;
+		else
+			priv->bt_enable_pspoll = true;
+
 		priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
 		priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
 		priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
 		iwlagn_send_advance_bt_config(priv);
 		priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
+		priv->cur_rssi_ctx = NULL;
+
 		iwlagn_send_prio_tbl(priv);
 
 		/* FIXME: w/a to force change uCode BT state machine */
@@ -2098,6 +2109,8 @@ static void __iwl_down(struct iwl_priv *priv)
 
 	/* reset BT coex data */
 	priv->bt_status = 0;
+	priv->cur_rssi_ctx = NULL;
+	priv->bt_is_sco = 0;
 	if (priv->cfg->bt_params)
 		priv->bt_traffic_load =
 			 priv->cfg->bt_params->bt_init_traffic_load;
@@ -2273,6 +2286,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv)
 	u8 bt_ci_compliance;
 	u8 bt_load;
 	u8 bt_status;
+	bool bt_is_sco;
 
 	lockdep_assert_held(&priv->mutex);
 
@@ -2293,6 +2307,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv)
 	bt_ci_compliance = priv->bt_ci_compliance;
 	bt_load = priv->bt_traffic_load;
 	bt_status = priv->bt_status;
+	bt_is_sco = priv->bt_is_sco;
 
 	__iwl_down(priv);
 
@@ -2300,6 +2315,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv)
 	priv->bt_ci_compliance = bt_ci_compliance;
 	priv->bt_traffic_load = bt_load;
 	priv->bt_status = bt_status;
+	priv->bt_is_sco = bt_is_sco;
 }
 
 static void iwl_bg_restart(struct work_struct *data)
@@ -3326,6 +3342,29 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
 	kfree(priv->beacon_cmd);
 }
 
+static void iwl_mac_rssi_callback(struct ieee80211_hw *hw,
+			   enum ieee80211_rssi_event rssi_event)
+{
+	struct iwl_priv *priv = hw->priv;
+
+	mutex_lock(&priv->mutex);
+
+	if (priv->cfg->bt_params &&
+			priv->cfg->bt_params->advanced_bt_coexist) {
+		if (rssi_event == RSSI_EVENT_LOW)
+			priv->bt_enable_pspoll = true;
+		else if (rssi_event == RSSI_EVENT_HIGH)
+			priv->bt_enable_pspoll = false;
+
+		iwlagn_send_advance_bt_config(priv);
+	} else {
+		IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled,"
+				"ignoring RSSI callback\n");
+	}
+
+	mutex_unlock(&priv->mutex);
+}
+
 struct ieee80211_ops iwlagn_hw_ops = {
 	.tx = iwlagn_mac_tx,
 	.start = iwlagn_mac_start,
@@ -3351,6 +3390,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
 	.cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
 	.offchannel_tx = iwl_mac_offchannel_tx,
 	.offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
+	.rssi_callback = iwl_mac_rssi_callback,
 	CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
 	CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
 };
@@ -3709,8 +3749,8 @@ void __devexit iwl_remove(struct iwl_priv * priv)
 
 	iwl_dealloc_ucode(priv);
 
-	priv->trans.ops->rx_free(priv);
-	iwlagn_hw_txq_ctx_free(priv);
+	trans_rx_free(priv);
+	trans_tx_free(priv);
 
 	iwl_eeprom_free(priv);
 

+ 10 - 9
drivers/net/wireless/iwlwifi/iwl-agn.h

@@ -109,9 +109,6 @@ extern struct iwl_cfg iwl135_bg_cfg;
 extern struct iwl_cfg iwl135_bgn_cfg;
 
 extern struct iwl_mod_params iwlagn_mod_params;
-extern struct iwl_hcmd_ops iwlagn_hcmd;
-extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
-extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
 
 extern struct ieee80211_ops iwlagn_hw_ops;
 
@@ -180,8 +177,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
 int iwlagn_send_tx_power(struct iwl_priv *priv);
 void iwlagn_temperature(struct iwl_priv *priv);
 u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv);
-const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
-				   size_t offset);
 int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 int iwlagn_hw_nic_init(struct iwl_priv *priv);
 int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
@@ -193,12 +188,12 @@ void iwlagn_rx_queue_restock(struct iwl_priv *priv);
 void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority);
 void iwlagn_rx_replenish(struct iwl_priv *priv);
 void iwlagn_rx_replenish_now(struct iwl_priv *priv);
-int iwlagn_rxq_stop(struct iwl_priv *priv);
 int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
 void iwl_setup_rx_handlers(struct iwl_priv *priv);
 
 /* tx */
-void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+				int index);
 int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
 				 struct iwl_tx_queue *txq,
 				 dma_addr_t addr, u16 len, u8 reset);
@@ -217,8 +212,6 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
 void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
 				struct iwl_rx_mem_buffer *rxb);
 int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
-void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv);
-void iwlagn_txq_ctx_stop(struct iwl_priv *priv);
 
 static inline u32 iwl_tx_status_to_mac80211(u32 status)
 {
@@ -257,6 +250,12 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
 int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
 int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
 int iwlagn_set_pan_params(struct iwl_priv *priv);
+void iwlagn_gain_computation(struct iwl_priv *priv,
+                u32 average_noise[NUM_RX_CHAINS],
+                u16 min_average_noise_antenna_i,
+                u32 min_average_noise,
+                u8 default_chain);
+
 
 /* bt coex */
 void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
@@ -265,6 +264,8 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
 void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
 void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
 void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
+void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv);
+void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 const char *iwl_get_tx_fail_reason(u32 status);

+ 3 - 0
drivers/net/wireless/iwlwifi/iwl-commands.h

@@ -1931,6 +1931,9 @@ struct iwl_bt_cmd {
 /* Disable Sync PSPoll on SCO/eSCO */
 #define IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE	BIT(7)
 
+#define IWLAGN_BT_PSP_MIN_RSSI_THRESHOLD	-75 /* dBm */
+#define IWLAGN_BT_PSP_MAX_RSSI_THRESHOLD	-65 /* dBm */
+
 #define IWLAGN_BT_PRIO_BOOST_MAX	0xFF
 #define IWLAGN_BT_PRIO_BOOST_MIN	0x00
 #define IWLAGN_BT_PRIO_BOOST_DEFAULT	0xF0

+ 10 - 13
drivers/net/wireless/iwlwifi/iwl-core.c

@@ -42,6 +42,7 @@
 #include "iwl-sta.h"
 #include "iwl-helpers.h"
 #include "iwl-agn.h"
+#include "iwl-trans.h"
 
 u32 iwl_debug_level;
 
@@ -375,8 +376,8 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 			le32_to_cpu(ctx->timing.beacon_init_val),
 			le16_to_cpu(ctx->timing.atim_window));
 
-	return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
-				sizeof(ctx->timing), &ctx->timing);
+	return trans_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
+				CMD_SYNC, sizeof(ctx->timing), &ctx->timing);
 }
 
 void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
@@ -1131,8 +1132,8 @@ void iwl_send_bt_config(struct iwl_priv *priv)
 	IWL_DEBUG_INFO(priv, "BT coex %s\n",
 		(bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
 
-	if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
-			     sizeof(struct iwl_bt_cmd), &bt_cmd))
+	if (trans_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+			     CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd))
 		IWL_ERR(priv, "failed to send BT Coex Config\n");
 }
 
@@ -1144,11 +1145,13 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
 	};
 
 	if (flags & CMD_ASYNC)
-		return iwl_send_cmd_pdu_async(priv, REPLY_STATISTICS_CMD,
+		return trans_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
+					      CMD_ASYNC,
 					       sizeof(struct iwl_statistics_cmd),
-					       &statistics_cmd, NULL);
+					       &statistics_cmd);
 	else
-		return iwl_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
+		return trans_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
+					CMD_SYNC,
 					sizeof(struct iwl_statistics_cmd),
 					&statistics_cmd);
 }
@@ -1370,12 +1373,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 
 }
 
-void iwl_free_txq_mem(struct iwl_priv *priv)
-{
-	kfree(priv->txq);
-	priv->txq = NULL;
-}
-
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 
 #define IWL_TRAFFIC_DUMP_SIZE	(IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)

+ 4 - 46
drivers/net/wireless/iwlwifi/iwl-core.h

@@ -80,31 +80,6 @@ struct iwl_cmd;
 
 #define IWL_CMD(x) case x: return #x
 
-struct iwl_hcmd_utils_ops {
-	u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
-	void (*gain_computation)(struct iwl_priv *priv,
-			u32 *average_noise,
-			u16 min_average_noise_antennat_i,
-			u32 min_average_noise,
-			u8 default_chain);
-	void (*chain_noise_reset)(struct iwl_priv *priv);
-	void (*tx_cmd_protection)(struct iwl_priv *priv,
-				  struct ieee80211_tx_info *info,
-				  __le16 fc, __le32 *tx_flags);
-	int  (*calc_rssi)(struct iwl_priv *priv,
-			  struct iwl_rx_phy_res *rx_resp);
-	int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
-};
-
-struct iwl_apm_ops {
-	int (*init)(struct iwl_priv *priv);
-	void (*config)(struct iwl_priv *priv);
-};
-
-struct iwl_temp_ops {
-	void (*temperature)(struct iwl_priv *priv);
-};
-
 struct iwl_lib_ops {
 	/* set hw dependent parameters */
 	int (*set_hw_params)(struct iwl_priv *priv);
@@ -118,17 +93,14 @@ struct iwl_lib_ops {
 	int (*is_valid_rtc_data_addr)(u32 addr);
 	int (*set_channel_switch)(struct iwl_priv *priv,
 				  struct ieee80211_channel_switch *ch_switch);
-	/* power management */
-	struct iwl_apm_ops apm_ops;
-
-	/* power */
-	void (*update_chain_flags)(struct iwl_priv *priv);
+	/* device specific configuration */
+	void (*nic_config)(struct iwl_priv *priv);
 
 	/* eeprom operations (as defined in iwl-eeprom.h) */
 	struct iwl_eeprom_ops eeprom_ops;
 
 	/* temperature */
-	struct iwl_temp_ops temp_ops;
+	void (*temperature)(struct iwl_priv *priv);
 };
 
 /* NIC specific ops */
@@ -138,7 +110,6 @@ struct iwl_nic_ops {
 
 struct iwl_ops {
 	const struct iwl_lib_ops *lib;
-	const struct iwl_hcmd_utils_ops *utils;
 	const struct iwl_nic_ops *nic;
 };
 
@@ -328,8 +299,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 int iwl_mac_change_interface(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
 			     enum nl80211_iftype newtype, bool newp2p);
-void iwl_free_txq_mem(struct iwl_priv *priv);
-
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_alloc_traffic_mem(struct iwl_priv *priv);
 void iwl_free_traffic_mem(struct iwl_priv *priv);
@@ -371,8 +340,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
 /*****************************************************
 * RX
 ******************************************************/
-void iwl_cmd_queue_free(struct iwl_priv *priv);
-void iwl_cmd_queue_unmap(struct iwl_priv *priv);
 void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
 				  struct iwl_rx_queue *q);
 int iwl_rx_queue_space(const struct iwl_rx_queue *q);
@@ -386,10 +353,8 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
 * TX
 ******************************************************/
 void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
-void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
 int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
 			  int count, int slots_num, u32 id);
-void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id);
 void iwl_setup_watchdog(struct iwl_priv *priv);
 /*****************************************************
  * TX power
@@ -440,16 +405,9 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
  *****************************************************/
 
 const char *get_cmd_string(u8 cmd);
-int __must_check iwl_send_cmd_sync(struct iwl_priv *priv,
-				   struct iwl_host_cmd *cmd);
 int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
-int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id,
+int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags,
 				  u16 len, const void *data);
-int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
-			   const void *data,
-			   void (*callback)(struct iwl_priv *priv,
-					    struct iwl_device_cmd *cmd,
-					    struct iwl_rx_packet *pkt));
 
 int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
 

+ 39 - 10
drivers/net/wireless/iwlwifi/iwl-dev.h

@@ -260,11 +260,9 @@ struct iwl_channel_info {
 
 enum {
 	CMD_SYNC = 0,
-	CMD_SIZE_NORMAL = 0,
-	CMD_NO_SKB = 0,
-	CMD_ASYNC = (1 << 1),
-	CMD_WANT_SKB = (1 << 2),
-	CMD_MAPPED = (1 << 3),
+	CMD_ASYNC = BIT(0),
+	CMD_WANT_SKB = BIT(1),
+	CMD_ON_DEMAND = BIT(2),
 };
 
 #define DEF_CMD_PAYLOAD_SIZE 320
@@ -297,6 +295,16 @@ enum iwl_hcmd_dataflag {
 	IWL_HCMD_DFL_NOCOPY	= BIT(0),
 };
 
+/**
+ * struct iwl_host_cmd - Host command to the uCode
+ * @data: array of chunks that composes the data of the host command
+ * @reply_page: pointer to the page that holds the response to the host command
+ * @callback:
+ * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
+ * @len: array of the lenths of the chunks in data
+ * @dataflags:
+ * @id: id of the host command
+ */
 struct iwl_host_cmd {
 	const void *data[IWL_MAX_CMD_TFDS];
 	unsigned long reply_page;
@@ -634,7 +642,6 @@ struct iwl_sensitivity_ranges {
 /**
  * struct iwl_hw_params
  * @max_txq_num: Max # Tx queues supported
- * @dma_chnl_num: Number of Tx DMA/FIFO channels
  * @scd_bc_tbls_size: size of scheduler byte count tables
  * @tfd_size: TFD size
  * @tx/rx_chains_num: Number of TX/RX chains
@@ -656,7 +663,6 @@ struct iwl_sensitivity_ranges {
  */
 struct iwl_hw_params {
 	u8 max_txq_num;
-	u8 dma_chnl_num;
 	u16 scd_bc_tbls_size;
 	u32 tfd_size;
 	u8  tx_chains_num;
@@ -696,8 +702,6 @@ struct iwl_hw_params {
  ****************************************************************************/
 extern void iwl_update_chain_flags(struct iwl_priv *priv);
 extern const u8 iwl_bcast_addr[ETH_ALEN];
-extern int iwl_rxq_stop(struct iwl_priv *priv);
-extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
 extern int iwl_queue_space(const struct iwl_queue *q);
 static inline int iwl_queue_used(const struct iwl_queue *q, int i)
 {
@@ -1233,19 +1237,37 @@ struct iwl_trans;
  * struct iwl_trans_ops - transport specific operations
 
  * @rx_init: inits the rx memory, allocate it if needed
+ * @rx_stop: stop the rx
  * @rx_free: frees the rx memory
  * @tx_init:inits the tx memory, allocate if needed
+ * @tx_stop: stop the tx
+ * @tx_free: frees the tx memory
+ * @send_cmd:send a host command
+ * @send_cmd_pdu:send a host command: flags can be CMD_*
  */
 struct iwl_trans_ops {
 	int (*rx_init)(struct iwl_priv *priv);
+	int (*rx_stop)(struct iwl_priv *priv);
 	void (*rx_free)(struct iwl_priv *priv);
+
 	int (*tx_init)(struct iwl_priv *priv);
+	int (*tx_stop)(struct iwl_priv *priv);
+	void (*tx_free)(struct iwl_priv *priv);
+
+	int (*send_cmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+
+	int (*send_cmd_pdu)(struct iwl_priv *priv, u8 id, u32 flags, u16 len,
+		     const void *data);
 };
 
 struct iwl_trans {
 	const struct iwl_trans_ops *ops;
 };
 
+/* uCode ownership */
+#define IWL_OWNERSHIP_DRIVER	0
+#define IWL_OWNERSHIP_TM	1
+
 struct iwl_priv {
 
 	/* ieee device used by generic ieee processing code */
@@ -1334,6 +1356,10 @@ struct iwl_priv {
 	int fw_index;			/* firmware we're trying to load */
 	u32 ucode_ver;			/* version of ucode, copy of
 					   iwl_ucode.ver */
+
+	/* uCode owner: default: IWL_OWNERSHIP_DRIVER */
+	u8 ucode_owner;
+
 	struct fw_img ucode_rt;
 	struct fw_img ucode_init;
 
@@ -1509,6 +1535,9 @@ struct iwl_priv {
 	u16 dynamic_frag_thresh;
 	u8 bt_ci_compliance;
 	struct work_struct bt_traffic_change_work;
+	bool bt_enable_pspoll;
+	struct iwl_rxon_context *cur_rssi_ctx;
+	bool bt_is_sco;
 
 	struct iwl_hw_params hw_params;
 
@@ -1577,7 +1606,7 @@ struct iwl_priv {
 #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
 	struct iwl_testmode_trace testmode_trace;
 #endif
-	u32 dbg_fixed_rate;
+	u32 tm_fixed_rate;
 
 }; /*iwl_priv */
 

+ 1 - 6
drivers/net/wireless/iwlwifi/iwl-eeprom.c

@@ -407,11 +407,6 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
 	return -EINVAL;
 }
 
-const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
-{
-	return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
-}
-
 u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
 {
 	if (!priv->eeprom)
@@ -449,7 +444,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
 	}
 	e = (__le16 *)priv->eeprom;
 
-	priv->cfg->ops->lib->apm_ops.init(priv);
+	iwl_apm_init(priv);
 
 	ret = iwl_eeprom_verify_signature(priv);
 	if (ret < 0) {

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

@@ -292,7 +292,6 @@ extern const u8 iwl_eeprom_band_1[14];
 
 struct iwl_eeprom_ops {
 	const u32 regulatory_bands[7];
-	const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
 	void (*update_enhanced_txpower) (struct iwl_priv *priv);
 };
 

+ 1 - 1
drivers/net/wireless/iwlwifi/iwl-fh.h

@@ -326,7 +326,7 @@
 #define FH_TCSR_UPPER_BOUND  (FH_MEM_LOWER_BOUND + 0xE60)
 
 /* Find Control/Status reg for given Tx DMA/FIFO channel */
-#define FH50_TCSR_CHNL_NUM                            (8)
+#define FH_TCSR_CHNL_NUM                            (8)
 
 /* TCSR: tx_config register values */
 #define FH_TCSR_CHNL_TX_CONFIG_REG(_chnl)	\

+ 5 - 27
drivers/net/wireless/iwlwifi/iwl-hcmd.c

@@ -143,9 +143,6 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 {
 	int ret;
 
-	if (WARN_ON(!(cmd->flags & CMD_ASYNC)))
-		return -EINVAL;
-
 	/* An asynchronous command can not expect an SKB to be set. */
 	if (WARN_ON(cmd->flags & CMD_WANT_SKB))
 		return -EINVAL;
@@ -166,16 +163,13 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	return 0;
 }
 
-int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+static int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 {
 	int cmd_idx;
 	int ret;
 
 	lockdep_assert_held(&priv->mutex);
 
-	if (WARN_ON(cmd->flags & CMD_ASYNC))
-		return -EINVAL;
-
 	 /* A synchronous command can not have a callback set. */
 	if (WARN_ON(cmd->callback))
 		return -EINVAL;
@@ -263,31 +257,15 @@ int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	return iwl_send_cmd_sync(priv, cmd);
 }
 
-int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data)
-{
-	struct iwl_host_cmd cmd = {
-		.id = id,
-		.len = { len, },
-		.data = { data, },
-	};
-
-	return iwl_send_cmd_sync(priv, &cmd);
-}
-
-int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
-			   u8 id, u16 len, const void *data,
-			   void (*callback)(struct iwl_priv *priv,
-					    struct iwl_device_cmd *cmd,
-					    struct iwl_rx_packet *pkt))
+int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags, u16 len,
+		     const void *data)
 {
 	struct iwl_host_cmd cmd = {
 		.id = id,
 		.len = { len, },
 		.data = { data, },
+		.flags = flags,
 	};
 
-	cmd.flags |= CMD_ASYNC;
-	cmd.callback = callback;
-
-	return iwl_send_cmd_async(priv, &cmd);
+	return iwl_send_cmd(priv, &cmd);
 }

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

@@ -40,6 +40,7 @@
 #include "iwl-core.h"
 #include "iwl-agn.h"
 #include "iwl-io.h"
+#include "iwl-trans.h"
 
 /* Throughput		OFF time(ms)	ON time (ms)
  *	>300			25		25
@@ -111,7 +112,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
 	if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
 		iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
 
-	return iwl_send_cmd(priv, &cmd);
+	return trans_send_cmd(priv, &cmd);
 }
 
 /* Set led pattern command */

+ 5 - 4
drivers/net/wireless/iwlwifi/iwl-power.c

@@ -42,6 +42,7 @@
 #include "iwl-commands.h"
 #include "iwl-debug.h"
 #include "iwl-power.h"
+#include "iwl-trans.h"
 
 /*
  * Setting power level allows the card to go to sleep when not busy.
@@ -334,7 +335,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
 			le32_to_cpu(cmd->sleep_interval[3]),
 			le32_to_cpu(cmd->sleep_interval[4]));
 
-	return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
+	return trans_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC,
 				sizeof(struct iwl_powertable_cmd), cmd);
 }
 
@@ -405,9 +406,9 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
 		if (!(cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
 			clear_bit(STATUS_POWER_PMI, &priv->status);
 
-		if (priv->cfg->ops->lib->update_chain_flags && update_chains)
-			priv->cfg->ops->lib->update_chain_flags(priv);
-		else if (priv->cfg->ops->lib->update_chain_flags)
+		if (update_chains)
+			iwl_update_chain_flags(priv);
+		else
 			IWL_DEBUG_POWER(priv,
 					"Cannot update the power, chain noise "
 					"calibration running: %d\n",

+ 44 - 3
drivers/net/wireless/iwlwifi/iwl-rx.c

@@ -624,8 +624,8 @@ static void iwl_rx_statistics(struct iwl_priv *priv,
 		iwl_rx_calc_noise(priv);
 		queue_work(priv->workqueue, &priv->run_time_calib_work);
 	}
-	if (priv->cfg->ops->lib->temp_ops.temperature && change)
-		priv->cfg->ops->lib->temp_ops.temperature(priv);
+	if (priv->cfg->ops->lib->temperature && change)
+		priv->cfg->ops->lib->temperature(priv);
 }
 
 static void iwl_rx_reply_statistics(struct iwl_priv *priv,
@@ -902,6 +902,47 @@ static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
 	return decrypt_out;
 }
 
+/* Calc max signal level (dBm) among 3 possible receivers */
+static int iwlagn_calc_rssi(struct iwl_priv *priv,
+			     struct iwl_rx_phy_res *rx_resp)
+{
+	/* data from PHY/DSP regarding signal strength, etc.,
+	 *   contents are always there, not configurable by host
+	 */
+	struct iwlagn_non_cfg_phy *ncphy =
+		(struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
+	u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
+	u8 agc;
+
+	val  = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]);
+	agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS;
+
+	/* Find max rssi among 3 possible receivers.
+	 * These values are measured by the digital signal processor (DSP).
+	 * They should stay fairly constant even as the signal strength varies,
+	 *   if the radio's automatic gain control (AGC) is working right.
+	 * AGC value (see below) will provide the "interesting" info.
+	 */
+	val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]);
+	rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >>
+		IWLAGN_OFDM_RSSI_A_BIT_POS;
+	rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >>
+		IWLAGN_OFDM_RSSI_B_BIT_POS;
+	val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]);
+	rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >>
+		IWLAGN_OFDM_RSSI_C_BIT_POS;
+
+	max_rssi = max_t(u32, rssi_a, rssi_b);
+	max_rssi = max_t(u32, max_rssi, rssi_c);
+
+	IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+		rssi_a, rssi_b, rssi_c, max_rssi, agc);
+
+	/* dBm = max_rssi dB - agc dB - constant.
+	 * Higher AGC (higher radio gain) means lower signal. */
+	return max_rssi - agc - IWLAGN_RSSI_OFFSET;
+}
+
 /* Called for REPLY_RX (legacy ABG frames), or
  * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
 static void iwl_rx_reply_rx(struct iwl_priv *priv,
@@ -983,7 +1024,7 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
 	priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
 
 	/* Find max signal strength (dBm) among 3 antenna/receiver chains */
-	rx_status.signal = priv->cfg->ops->utils->calc_rssi(priv, phy_res);
+	rx_status.signal = iwlagn_calc_rssi(priv, phy_res);
 
 	iwl_dbg_log_rx_data_frame(priv, len, header);
 	IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",

+ 4 - 6
drivers/net/wireless/iwlwifi/iwl-scan.c

@@ -37,6 +37,7 @@
 #include "iwl-io.h"
 #include "iwl-helpers.h"
 #include "iwl-agn.h"
+#include "iwl-trans.h"
 
 /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
  * sending probe req.  This should be set long enough to hear probe responses
@@ -61,7 +62,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
 	struct iwl_rx_packet *pkt;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_ABORT_CMD,
-		.flags = CMD_WANT_SKB,
+		.flags = CMD_SYNC | CMD_WANT_SKB,
 	};
 
 	/* Exit instantly with error when device is not ready
@@ -74,7 +75,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
 	    test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return -EIO;
 
-	ret = iwl_send_cmd_sync(priv, &cmd);
+	ret = trans_send_cmd(priv, &cmd);
 	if (ret)
 		return ret;
 
@@ -349,9 +350,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 
 	lockdep_assert_held(&priv->mutex);
 
-	if (WARN_ON(!priv->cfg->ops->utils->request_scan))
-		return -EOPNOTSUPP;
-
 	cancel_delayed_work(&priv->scan_check);
 
 	if (!iwl_is_ready_rf(priv)) {
@@ -380,7 +378,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 	priv->scan_start = jiffies;
 	priv->scan_band = band;
 
-	ret = priv->cfg->ops->utils->request_scan(priv, vif);
+	ret = iwlagn_request_scan(priv, vif);
 	if (ret) {
 		clear_bit(STATUS_SCANNING, &priv->status);
 		priv->scan_type = IWL_SCAN_NORMAL;

+ 16 - 4
drivers/net/wireless/iwlwifi/iwl-sta.c

@@ -35,6 +35,8 @@
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-sta.h"
+#include "iwl-trans.h"
+#include "iwl-agn.h"
 
 /* priv->sta_lock must be held */
 static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
@@ -132,6 +134,16 @@ static void iwl_add_sta_callback(struct iwl_priv *priv,
 
 }
 
+static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+{
+	u16 size = (u16)sizeof(struct iwl_addsta_cmd);
+	struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
+	memcpy(addsta, cmd, size);
+	/* resrved in 5000 */
+	addsta->rate_n_flags = cpu_to_le16(0);
+	return size;
+}
+
 int iwl_send_add_sta(struct iwl_priv *priv,
 		     struct iwl_addsta_cmd *sta, u8 flags)
 {
@@ -155,8 +167,8 @@ int iwl_send_add_sta(struct iwl_priv *priv,
 		might_sleep();
 	}
 
-	cmd.len[0] = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
-	ret = iwl_send_cmd(priv, &cmd);
+	cmd.len[0] = iwlagn_build_addsta_hcmd(sta, data);
+	ret = trans_send_cmd(priv, &cmd);
 
 	if (ret || (flags & CMD_ASYNC))
 		return ret;
@@ -412,7 +424,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 
 	cmd.flags |= CMD_WANT_SKB;
 
-	ret = iwl_send_cmd(priv, &cmd);
+	ret = trans_send_cmd(priv, &cmd);
 
 	if (ret)
 		return ret;
@@ -781,7 +793,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 		return -EINVAL;
 
 	if (is_lq_table_valid(priv, ctx, lq))
-		ret = iwl_send_cmd(priv, &cmd);
+		ret = trans_send_cmd(priv, &cmd);
 	else
 		ret = -EINVAL;
 

+ 47 - 4
drivers/net/wireless/iwlwifi/iwl-sv-open.c

@@ -76,7 +76,7 @@
 #include "iwl-io.h"
 #include "iwl-agn.h"
 #include "iwl-testmode.h"
-
+#include "iwl-trans.h"
 
 /* The TLVs used in the gnl message policy between the kernel module and
  * user space application. iwl_testmode_gnl_msg_policy is to be carried
@@ -105,6 +105,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
 
 	[IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
 
+	[IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
 };
 
 /*
@@ -232,6 +233,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
 		return -ENOMSG;
 	}
 
+	cmd.flags = CMD_ON_DEMAND;
 	cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
 	cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
 	cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
@@ -239,7 +241,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
 	IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
 				" len %d\n", cmd.id, cmd.flags, cmd.len[0]);
 	/* ok, let's submit the command to ucode */
-	return iwl_send_cmd(priv, &cmd);
+	return trans_send_cmd(priv, &cmd);
 }
 
 
@@ -452,7 +454,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 				       "Error finding fixrate setting\n");
 			return -ENOMSG;
 		}
-		priv->dbg_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
+		priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
 		break;
 
 	default:
@@ -586,6 +588,42 @@ static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
 	return -ENOBUFS;
 }
 
+/*
+ * This function handles the user application switch ucode ownership.
+ *
+ * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
+ * decide who the current owner of the uCode
+ *
+ * If the current owner is OWNERSHIP_TM, then the only host command
+ * can deliver to uCode is from testmode, all the other host commands
+ * will dropped.
+ *
+ * default driver is the owner of uCode in normal operational mode
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+	struct iwl_priv *priv = hw->priv;
+	u8 owner;
+
+	if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
+		IWL_DEBUG_INFO(priv, "Error finding ucode owner\n");
+		return -ENOMSG;
+	}
+
+	owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
+	if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
+		priv->ucode_owner = owner;
+	else {
+		IWL_DEBUG_INFO(priv, "Invalid owner\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
 /* The testmode gnl message handler that takes the gnl message from the
  * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
  * invoke the corresponding handlers.
@@ -607,7 +645,7 @@ static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
  */
 int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
 {
-	struct nlattr *tb[IWL_TM_ATTR_MAX - 1];
+	struct nlattr *tb[IWL_TM_ATTR_MAX];
 	struct iwl_priv *priv = hw->priv;
 	int result;
 
@@ -655,6 +693,11 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
 		result = iwl_testmode_trace(hw, tb);
 		break;
 
+	case IWL_TM_CMD_APP2DEV_OWNERSHIP:
+		IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
+		result = iwl_testmode_ownership(hw, tb);
+		break;
+
 	default:
 		IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
 		result = -ENOSYS;

+ 12 - 2
drivers/net/wireless/iwlwifi/iwl-testmode.h

@@ -103,6 +103,10 @@
  * @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
  *	commands from kernel space to carry the eeprom response
  *	to user application
+ * @IWL_TM_CMD_APP2DEV_OWNERSHIP:
+ *	commands from user application to own change the ownership of the uCode
+ *	if application has the ownership, the only host command from
+ *	testmode will deliver to uCode. Default owner is driver
  */
 enum iwl_tm_cmd_t {
 	IWL_TM_CMD_APP2DEV_UCODE		= 1,
@@ -121,7 +125,8 @@ enum iwl_tm_cmd_t {
 	IWL_TM_CMD_DEV2APP_SYNC_RSP		= 14,
 	IWL_TM_CMD_DEV2APP_UCODE_RX_PKT		= 15,
 	IWL_TM_CMD_DEV2APP_EEPROM_RSP		= 16,
-	IWL_TM_CMD_MAX				= 17,
+	IWL_TM_CMD_APP2DEV_OWNERSHIP		= 17,
+	IWL_TM_CMD_MAX				= 18,
 };
 
 /*
@@ -187,6 +192,10 @@ enum iwl_tm_cmd_t {
  *	The mandatory fields are:
  *	IWL_TM_ATTR_FIXRATE for the fixed rate
  *
+ * @IWL_TM_ATTR_UCODE_OWNER:
+ *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP,
+ *	The mandatory fields are:
+ *	IWL_TM_ATTR_UCODE_OWNER for the new owner
  */
 enum iwl_tm_attr_t {
 	IWL_TM_ATTR_NOT_APPLICABLE		= 0,
@@ -203,7 +212,8 @@ enum iwl_tm_attr_t {
 	IWL_TM_ATTR_TRACE_SIZE			= 11,
 	IWL_TM_ATTR_TRACE_DUMP			= 12,
 	IWL_TM_ATTR_FIXRATE			= 13,
-	IWL_TM_ATTR_MAX				= 14,
+	IWL_TM_ATTR_UCODE_OWNER			= 14,
+	IWL_TM_ATTR_MAX				= 15,
 };
 
 /* uCode trace buffer */

+ 151 - 3
drivers/net/wireless/iwlwifi/iwl-trans.c

@@ -66,6 +66,7 @@
 #include "iwl-helpers.h"
 /*TODO remove uneeded includes when the transport layer tx_free will be here */
 #include "iwl-agn.h"
+#include "iwl-core.h"
 
 static int iwl_trans_rx_alloc(struct iwl_priv *priv)
 {
@@ -188,7 +189,15 @@ static void iwl_trans_rx_free(struct iwl_priv *priv)
 	rxq->rb_stts = NULL;
 }
 
-/* TODO:remove this code duplication */
+static int iwl_trans_rx_stop(struct iwl_priv *priv)
+{
+
+	/* stop Rx DMA */
+	iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+	return iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
+			    FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
+}
+
 static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv,
 				    struct iwl_dma_ptr *ptr, size_t size)
 {
@@ -203,6 +212,16 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv,
 	return 0;
 }
 
+static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv,
+				    struct iwl_dma_ptr *ptr)
+{
+	if (unlikely(!ptr->addr))
+		return;
+
+	dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma);
+	memset(ptr, 0, sizeof(*ptr));
+}
+
 static int iwl_trans_txq_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 		      int slots_num, u32 txq_id)
 {
@@ -212,6 +231,8 @@ static int iwl_trans_txq_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 	if (WARN_ON(txq->meta || txq->cmd || txq->txb || txq->tfds))
 		return -EINVAL;
 
+	txq->q.n_window = slots_num;
+
 	txq->meta = kzalloc(sizeof(txq->meta[0]) * slots_num,
 			    GFP_KERNEL);
 	txq->cmd = kzalloc(sizeof(txq->cmd[0]) * slots_num,
@@ -306,6 +327,90 @@ static int iwl_trans_txq_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 	return 0;
 }
 
+/**
+ * iwl_tx_queue_unmap -  Unmap any remaining DMA mappings and free skb's
+ */
+static void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
+{
+	struct iwl_tx_queue *txq = &priv->txq[txq_id];
+	struct iwl_queue *q = &txq->q;
+
+	if (!q->n_bd)
+		return;
+
+	while (q->write_ptr != q->read_ptr) {
+		/* The read_ptr needs to bound by q->n_window */
+		iwlagn_txq_free_tfd(priv, txq, get_cmd_index(q, q->read_ptr));
+		q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
+	}
+}
+
+/**
+ * iwl_tx_queue_free - Deallocate DMA queue.
+ * @txq: Transmit queue to deallocate.
+ *
+ * Empty queue by removing and destroying all BD's.
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
+ */
+static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
+{
+	struct iwl_tx_queue *txq = &priv->txq[txq_id];
+	struct device *dev = priv->bus.dev;
+	int i;
+	if (WARN_ON(!txq))
+		return;
+
+	iwl_tx_queue_unmap(priv, txq_id);
+
+	/* De-alloc array of command/tx buffers */
+	for (i = 0; i < txq->q.n_window; i++)
+		kfree(txq->cmd[i]);
+
+	/* De-alloc circular buffer of TFDs */
+	if (txq->q.n_bd) {
+		dma_free_coherent(dev, priv->hw_params.tfd_size *
+				  txq->q.n_bd, txq->tfds, txq->q.dma_addr);
+		memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr));
+	}
+
+	/* De-alloc array of per-TFD driver data */
+	kfree(txq->txb);
+	txq->txb = NULL;
+
+	/* deallocate arrays */
+	kfree(txq->cmd);
+	kfree(txq->meta);
+	txq->cmd = NULL;
+	txq->meta = NULL;
+
+	/* 0-fill queue descriptor structure */
+	memset(txq, 0, sizeof(*txq));
+}
+
+/**
+ * iwl_trans_tx_free - Free TXQ Context
+ *
+ * Destroy all TX DMA queues and structures
+ */
+static void iwl_trans_tx_free(struct iwl_priv *priv)
+{
+	int txq_id;
+
+	/* Tx queues */
+	if (priv->txq) {
+		for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+			iwl_tx_queue_free(priv, txq_id);
+	}
+
+	kfree(priv->txq);
+	priv->txq = NULL;
+
+	iwlagn_free_dma_ptr(priv, &priv->kw);
+
+	iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls);
+}
+
 /**
  * iwl_trans_tx_alloc - allocate TX context
  * Allocate all Tx DMA structures and initialize them
@@ -362,7 +467,7 @@ static int iwl_trans_tx_alloc(struct iwl_priv *priv)
 	return 0;
 
 error:
-	iwlagn_hw_txq_ctx_free(priv);
+	trans_tx_free(priv);
 
 	return ret;
 }
@@ -406,15 +511,58 @@ static int iwl_trans_tx_init(struct iwl_priv *priv)
 error:
 	/*Upon error, free only if we allocated something */
 	if (alloc)
-		iwlagn_hw_txq_ctx_free(priv);
+		trans_tx_free(priv);
 	return ret;
 }
 
+/**
+ * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
+ */
+static int iwl_trans_tx_stop(struct iwl_priv *priv)
+{
+	int ch, txq_id;
+	unsigned long flags;
+
+	/* Turn off all Tx DMA fifos */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	iwlagn_txq_set_sched(priv, 0);
+
+	/* Stop each Tx DMA channel, and wait for it to be idle */
+	for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
+		iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
+		if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
+				    FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
+				    1000))
+			IWL_ERR(priv, "Failing on timeout while stopping"
+			    " DMA channel %d [0x%08x]", ch,
+			    iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG));
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (!priv->txq) {
+		IWL_WARN(priv, "Stopping tx queues that aren't allocated...");
+		return 0;
+	}
+
+	/* Unmap DMA from host system and free skb's */
+	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+		iwl_tx_queue_unmap(priv, txq_id);
+
+	return 0;
+}
+
 static const struct iwl_trans_ops trans_ops = {
 	.rx_init = iwl_trans_rx_init,
+	.rx_stop = iwl_trans_rx_stop,
 	.rx_free = iwl_trans_rx_free,
 
 	.tx_init = iwl_trans_tx_init,
+	.tx_stop = iwl_trans_tx_stop,
+	.tx_free = iwl_trans_tx_free,
+
+	.send_cmd = iwl_send_cmd,
+	.send_cmd_pdu = iwl_send_cmd_pdu,
 };
 
 void iwl_trans_register(struct iwl_trans *trans)

+ 41 - 0
drivers/net/wireless/iwlwifi/iwl-trans.h

@@ -60,5 +60,46 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+static inline int trans_rx_init(struct iwl_priv *priv)
+{
+	return priv->trans.ops->rx_init(priv);
+}
+
+static inline int trans_rx_stop(struct iwl_priv *priv)
+{
+	return priv->trans.ops->rx_stop(priv);
+}
+
+static inline void trans_rx_free(struct iwl_priv *priv)
+{
+	priv->trans.ops->rx_free(priv);
+}
+
+static inline int trans_tx_init(struct iwl_priv *priv)
+{
+	return priv->trans.ops->tx_init(priv);
+}
+
+static inline int trans_tx_stop(struct iwl_priv *priv)
+{
+	return priv->trans.ops->tx_stop(priv);
+}
+
+static inline void trans_tx_free(struct iwl_priv *priv)
+{
+	priv->trans.ops->tx_free(priv);
+}
+
+static inline int trans_send_cmd(struct iwl_priv *priv,
+				struct iwl_host_cmd *cmd)
+{
+	return priv->trans.ops->send_cmd(priv, cmd);
+}
+
+static inline int trans_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags,
+					u16 len, const void *data)
+{
+	return priv->trans.ops->send_cmd_pdu(priv, id, flags, len, data);
+}
 
 void iwl_trans_register(struct iwl_trans *trans);

+ 12 - 127
drivers/net/wireless/iwlwifi/iwl-tx.c

@@ -157,14 +157,15 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
  * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
  * @priv - driver private data
  * @txq - tx queue
+ * @index - the index of the TFD to be freed
  *
  * Does NOT advance any TFD circular buffer read/write indexes
  * Does NOT free the TFD itself (which is within circular buffer)
  */
-void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+	int index)
 {
 	struct iwl_tfd *tfd_tmp = txq->tfds;
-	int index = txq->q.read_ptr;
 
 	iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index],
 			 DMA_TO_DEVICE);
@@ -173,12 +174,12 @@ void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 	if (txq->txb) {
 		struct sk_buff *skb;
 
-		skb = txq->txb[txq->q.read_ptr].skb;
+		skb = txq->txb[index].skb;
 
 		/* can be called from irqs-disabled context */
 		if (skb) {
 			dev_kfree_skb_any(skb);
-			txq->txb[txq->q.read_ptr].skb = NULL;
+			txq->txb[index].skb = NULL;
 		}
 	}
 }
@@ -220,122 +221,6 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
 	return 0;
 }
 
-/**
- * iwl_tx_queue_unmap -  Unmap any remaining DMA mappings and free skb's
- */
-void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
-{
-	struct iwl_tx_queue *txq = &priv->txq[txq_id];
-	struct iwl_queue *q = &txq->q;
-
-	if (q->n_bd == 0)
-		return;
-
-	 while (q->write_ptr != q->read_ptr) {
-		iwlagn_txq_free_tfd(priv, txq);
-		q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
-	}
-}
-
-/**
- * iwl_tx_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
-{
-	struct iwl_tx_queue *txq = &priv->txq[txq_id];
-	struct device *dev = priv->bus.dev;
-	int i;
-
-	iwl_tx_queue_unmap(priv, txq_id);
-
-	/* De-alloc array of command/tx buffers */
-	for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
-		kfree(txq->cmd[i]);
-
-	/* De-alloc circular buffer of TFDs */
-	if (txq->q.n_bd)
-		dma_free_coherent(dev, priv->hw_params.tfd_size *
-				  txq->q.n_bd, txq->tfds, txq->q.dma_addr);
-
-	/* De-alloc array of per-TFD driver data */
-	kfree(txq->txb);
-	txq->txb = NULL;
-
-	/* deallocate arrays */
-	kfree(txq->cmd);
-	kfree(txq->meta);
-	txq->cmd = NULL;
-	txq->meta = NULL;
-
-	/* 0-fill queue descriptor structure */
-	memset(txq, 0, sizeof(*txq));
-}
-
-/**
- * iwl_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue
- */
-void iwl_cmd_queue_unmap(struct iwl_priv *priv)
-{
-	struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
-	struct iwl_queue *q = &txq->q;
-	int i;
-
-	if (q->n_bd == 0)
-		return;
-
-	while (q->read_ptr != q->write_ptr) {
-		i = get_cmd_index(q, q->read_ptr);
-
-		if (txq->meta[i].flags & CMD_MAPPED) {
-			iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i],
-					 DMA_BIDIRECTIONAL);
-			txq->meta[i].flags = 0;
-		}
-
-		q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
-	}
-}
-
-/**
- * iwl_cmd_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl_cmd_queue_free(struct iwl_priv *priv)
-{
-	struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
-	struct device *dev = priv->bus.dev;
-	int i;
-
-	iwl_cmd_queue_unmap(priv);
-
-	/* De-alloc array of command/tx buffers */
-	for (i = 0; i < TFD_CMD_SLOTS; i++)
-		kfree(txq->cmd[i]);
-
-	/* De-alloc circular buffer of TFDs */
-	if (txq->q.n_bd)
-		dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd,
-				  txq->tfds, txq->q.dma_addr);
-
-	/* deallocate arrays */
-	kfree(txq->cmd);
-	kfree(txq->meta);
-	txq->cmd = NULL;
-	txq->meta = NULL;
-
-	/* 0-fill queue descriptor structure */
-	memset(txq, 0, sizeof(*txq));
-}
-
 /*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
  * DMA services
  *
@@ -443,6 +328,12 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 		return -EIO;
 	}
 
+	if ((priv->ucode_owner == IWL_OWNERSHIP_TM) &&
+	    !(cmd->flags & CMD_ON_DEMAND)) {
+		IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n");
+		return -EIO;
+	}
+
 	copy_size = sizeof(out_cmd->hdr);
 	cmd_size = sizeof(out_cmd->hdr);
 
@@ -496,11 +387,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	out_cmd = txq->cmd[idx];
 	out_meta = &txq->meta[idx];
 
-	if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
-		spin_unlock_irqrestore(&priv->hcmd_lock, flags);
-		return -ENOSPC;
-	}
-
 	memset(out_meta, 0, sizeof(*out_meta));	/* re-initialize to NULL */
 	if (cmd->flags & CMD_WANT_SKB)
 		out_meta->source = cmd;
@@ -574,7 +460,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 #endif
 	}
 
-	out_meta->flags = cmd->flags | CMD_MAPPED;
+	out_meta->flags = cmd->flags;
 
 	txq->need_update = 1;
 
@@ -684,7 +570,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
 
-	/* Mark as unmapped */
 	meta->flags = 0;
 
 	spin_unlock_irqrestore(&priv->hcmd_lock, flags);

+ 33 - 13
drivers/net/wireless/libertas/cmd.c

@@ -874,6 +874,7 @@ int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 	cmd.action = cpu_to_le16(CMD_ACT_GET);
+	cmd.offset = cpu_to_le16(offset);
 
 	if (reg != CMD_MAC_REG_ACCESS &&
 	    reg != CMD_BBP_REG_ACCESS &&
@@ -883,7 +884,7 @@ int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
 	}
 
 	ret = lbs_cmd_with_response(priv, reg, &cmd);
-	if (ret) {
+	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)
@@ -916,6 +917,7 @@ int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 	cmd.action = cpu_to_le16(CMD_ACT_SET);
+	cmd.offset = cpu_to_le16(offset);
 
 	if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
 		cmd.value.bbp_rf = (u8) (value & 0xFF);
@@ -1068,16 +1070,34 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 }
 
-void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
-			  int result)
+void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
+			    int result)
 {
+	/*
+	 * Normally, commands are removed from cmdpendingq before being
+	 * submitted. However, we can arrive here on alternative codepaths
+	 * where the command is still pending. Make sure the command really
+	 * isn't part of a list at this point.
+	 */
+	list_del_init(&cmd->list);
+
 	cmd->result = result;
 	cmd->cmdwaitqwoken = 1;
-	wake_up_interruptible(&cmd->cmdwait_q);
+	wake_up(&cmd->cmdwait_q);
 
 	if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
 		__lbs_cleanup_and_insert_cmd(priv, cmd);
 	priv->cur_cmd = NULL;
+	wake_up_interruptible(&priv->waitq);
+}
+
+void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
+			  int result)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&priv->driver_lock, flags);
+	__lbs_complete_command(priv, cmd, result);
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
 }
 
 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
@@ -1249,7 +1269,7 @@ static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
 	if (!list_empty(&priv->cmdfreeq)) {
 		tempnode = list_first_entry(&priv->cmdfreeq,
 					    struct cmd_ctrl_node, list);
-		list_del(&tempnode->list);
+		list_del_init(&tempnode->list);
 	} else {
 		lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
 		tempnode = NULL;
@@ -1357,10 +1377,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 				    cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
-					spin_lock_irqsave(&priv->driver_lock, flags);
-					list_del(&cmdnode->list);
 					lbs_complete_command(priv, cmdnode, 0);
-					spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 					ret = 0;
 					goto done;
@@ -1370,10 +1387,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 				    (priv->psstate == PS_STATE_PRE_SLEEP)) {
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
-					spin_lock_irqsave(&priv->driver_lock, flags);
-					list_del(&cmdnode->list);
 					lbs_complete_command(priv, cmdnode, 0);
-					spin_unlock_irqrestore(&priv->driver_lock, flags);
 					priv->needtowakeup = 1;
 
 					ret = 0;
@@ -1385,7 +1399,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 			}
 		}
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		list_del(&cmdnode->list);
+		list_del_init(&cmdnode->list);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
 			    le16_to_cpu(cmd->command));
@@ -1668,7 +1682,13 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	}
 
 	might_sleep();
-	wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
+
+	/*
+	 * Be careful with signals here. A signal may be received as the system
+	 * goes into suspend or resume. We do not want this to interrupt the
+	 * command, so we perform an uninterruptible sleep.
+	 */
+	wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	ret = cmdnode->result;

+ 2 - 0
drivers/net/wireless/libertas/cmd.h

@@ -59,6 +59,8 @@ int lbs_allocate_cmd_buffer(struct lbs_private *priv);
 int lbs_free_cmd_buffer(struct lbs_private *priv);
 
 int lbs_execute_next_command(struct lbs_private *priv);
+void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
+			    int result);
 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
 			  int result);
 int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len);

+ 3 - 3
drivers/net/wireless/libertas/cmdresp.c

@@ -166,7 +166,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 			lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
 		}
 
-		lbs_complete_command(priv, priv->cur_cmd, result);
+		__lbs_complete_command(priv, priv->cur_cmd, result);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 		ret = 0;
@@ -187,7 +187,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 			break;
 
 		}
-		lbs_complete_command(priv, priv->cur_cmd, result);
+		__lbs_complete_command(priv, priv->cur_cmd, result);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 		ret = -1;
@@ -205,7 +205,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 
 	if (priv->cur_cmd) {
 		/* Clean up and Put current command back to cmdfreeq */
-		lbs_complete_command(priv, priv->cur_cmd, result);
+		__lbs_complete_command(priv, priv->cur_cmd, result);
 	}
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 

+ 10 - 2
drivers/net/wireless/libertas/main.c

@@ -639,6 +639,14 @@ static void lbs_cmd_timeout_handler(unsigned long data)
 		    le16_to_cpu(priv->cur_cmd->cmdbuf->command));
 
 	priv->cmd_timed_out = 1;
+
+	/*
+	 * If the device didn't even acknowledge the command, reset the state
+	 * so that we don't block all future commands due to this one timeout.
+	 */
+	if (priv->dnld_sent == DNLD_CMD_SENT)
+		priv->dnld_sent = DNLD_RES_RECEIVED;
+
 	wake_up_interruptible(&priv->waitq);
 out:
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -995,7 +1003,7 @@ void lbs_stop_card(struct lbs_private *priv)
 	list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
 		cmdnode->result = -ENOENT;
 		cmdnode->cmdwaitqwoken = 1;
-		wake_up_interruptible(&cmdnode->cmdwait_q);
+		wake_up(&cmdnode->cmdwait_q);
 	}
 
 	/* Flush the command the card is currently processing */
@@ -1003,7 +1011,7 @@ void lbs_stop_card(struct lbs_private *priv)
 		lbs_deb_main("clearing current command\n");
 		priv->cur_cmd->result = -ENOENT;
 		priv->cur_cmd->cmdwaitqwoken = 1;
-		wake_up_interruptible(&priv->cur_cmd->cmdwait_q);
+		wake_up(&priv->cur_cmd->cmdwait_q);
 	}
 	lbs_deb_main("done clearing commands\n");
 	spin_unlock_irqrestore(&priv->driver_lock, flags);

+ 55 - 1
drivers/net/wireless/mwifiex/cfg80211.c

@@ -671,6 +671,59 @@ static const u32 mwifiex_cipher_suites[] = {
 	WLAN_CIPHER_SUITE_CCMP,
 };
 
+/*
+ * CFG802.11 operation handler for setting bit rates.
+ *
+ * Function selects legacy bang B/G/BG from corresponding bitrates selection.
+ * Currently only 2.4GHz band is supported.
+ */
+static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
+				struct net_device *dev,
+				const u8 *peer,
+				const struct cfg80211_bitrate_mask *mask)
+{
+	struct mwifiex_ds_band_cfg band_cfg;
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+	int index = 0, mode = 0, i;
+
+	/* Currently only 2.4GHz is supported */
+	for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) {
+		/*
+		 * Rates below 6 Mbps in the table are CCK rates; 802.11b
+		 * and from 6 they are OFDM; 802.11G
+		 */
+		if (mwifiex_rates[i].bitrate == 60) {
+			index = 1 << i;
+			break;
+		}
+	}
+
+	if (mask->control[IEEE80211_BAND_2GHZ].legacy < index) {
+		mode = BAND_B;
+	} else {
+		mode = BAND_G;
+		if (mask->control[IEEE80211_BAND_2GHZ].legacy % index)
+			mode |=  BAND_B;
+	}
+
+	memset(&band_cfg, 0, sizeof(band_cfg));
+	band_cfg.config_bands = mode;
+
+	if (priv->bss_mode == NL80211_IFTYPE_ADHOC)
+		band_cfg.adhoc_start_band = mode;
+
+	band_cfg.sec_chan_offset = NO_SEC_CHANNEL;
+
+	if (mwifiex_set_radio_band_cfg(priv, &band_cfg))
+		return -EFAULT;
+
+	wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n",
+				(mode & BAND_B) ? "b" : "",
+				(mode & BAND_G) ? "g" : "");
+
+	return 0;
+}
+
 /*
  * CFG802.11 operation handler for disconnection request.
  *
@@ -960,7 +1013,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
 		ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
 
 	if (sme->key) {
-		if (mwifiex_is_alg_wep(0) | mwifiex_is_alg_wep(0)) {
+		if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) {
 			dev_dbg(priv->adapter->dev,
 				"info: setting wep encryption"
 				" with key len %d\n", sme->key_len);
@@ -1225,6 +1278,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
 	.set_default_key = mwifiex_cfg80211_set_default_key,
 	.set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
 	.set_tx_power = mwifiex_cfg80211_set_tx_power,
+	.set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
 };
 
 /*

部分文件因文件數量過多而無法顯示