aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/obsolete/sysfs-class-rfkill29
-rw-r--r--Documentation/ABI/stable/sysfs-class-rfkill67
-rw-r--r--Documentation/feature-removal-schedule.txt41
-rw-r--r--Documentation/rfkill.txt44
-rw-r--r--drivers/net/ps3_gelic_wireless.c35
-rw-r--r--drivers/net/wireless/airo.c37
-rw-r--r--drivers/net/wireless/ath/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.h2
-rw-r--r--drivers/net/wireless/ath/ar9170/eeprom.h4
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h1
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c13
-rw-r--r--drivers/net/wireless/ath/ath.h13
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c744
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h104
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h313
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c247
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h38
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c9
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c382
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h4
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c19
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h35
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h88
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c346
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c60
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c17
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h38
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig21
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile10
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c84
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c342
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c965
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h102
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h462
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c277
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c723
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c1733
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c704
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c463
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h246
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c213
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/initvals.h250
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c157
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h40
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c60
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c319
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h126
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c117
-rw-r--r--drivers/net/wireless/ath/debug.h1
-rw-r--r--drivers/net/wireless/ath/hw.c4
-rw-r--r--drivers/net/wireless/ath/regd.c3
-rw-r--r--drivers/net/wireless/b43/b43.h1
-rw-r--r--drivers/net/wireless/b43/main.c5
-rw-r--r--drivers/net/wireless/b43/phy_n.c479
-rw-r--r--drivers/net/wireless/b43/phy_n.h21
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c22
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h37
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c48
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c188
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h14
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c13
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c89
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c133
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c83
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c1401
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c213
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c274
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h118
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ict.c307
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c1103
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c137
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c1314
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c416
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c401
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h149
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c787
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h57
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c82
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h184
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c823
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c653
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c1053
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c163
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Kconfig9
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Makefile3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c17
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c14
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.h1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c13
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.c15
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.h5
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c9
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c76
-rw-r--r--drivers/net/wireless/iwmc3200wifi/trace.c3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/trace.h283
-rw-r--r--drivers/net/wireless/iwmc3200wifi/tx.c8
-rw-r--r--drivers/net/wireless/iwmc3200wifi/umac.h2
-rw-r--r--drivers/net/wireless/libertas/assoc.c22
-rw-r--r--drivers/net/wireless/libertas/debugfs.c2
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c22
-rw-r--r--drivers/net/wireless/libertas/main.c1
-rw-r--r--drivers/net/wireless/libertas/rx.c50
-rw-r--r--drivers/net/wireless/libertas/wext.c4
-rw-r--r--drivers/net/wireless/orinoco/Kconfig13
-rw-r--r--drivers/net/wireless/orinoco/hw.c7
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c79
-rw-r--r--drivers/net/wireless/orinoco/wext.c94
-rw-r--r--drivers/net/wireless/p54/main.c1
-rw-r--r--drivers/net/wireless/p54/txrx.c2
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c16
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c8
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c8
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c2
-rw-r--r--drivers/net/wireless/ray_cs.c224
-rw-r--r--drivers/net/wireless/rndis_wlan.c364
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c111
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c65
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c6
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig24
-rw-r--r--drivers/net/wireless/wl12xx/Makefile6
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.c3
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_io.h20
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ps.c8
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_sdio.c52
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h55
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c108
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h101
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c25
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.h7
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c335
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h27
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h385
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c47
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c52
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.c87
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.h135
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c1112
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c94
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c291
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c315
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.h96
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c133
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h9
-rw-r--r--drivers/net/wireless/wl3501_cs.c52
-rw-r--r--drivers/ssb/driver_chipcommon.c1
-rw-r--r--include/linux/ieee80211.h1
-rw-r--r--include/linux/mmc/sdio.h2
-rw-r--r--include/linux/nl80211.h58
-rw-r--r--include/linux/wireless.h4
-rw-r--r--include/net/cfg80211.h30
-rw-r--r--include/net/iw_handler.h2
-rw-r--r--include/net/mac80211.h68
-rw-r--r--net/mac80211/Kconfig9
-rw-r--r--net/mac80211/agg-rx.c72
-rw-r--r--net/mac80211/agg-tx.c6
-rw-r--r--net/mac80211/cfg.c34
-rw-r--r--net/mac80211/debugfs_netdev.c12
-rw-r--r--net/mac80211/debugfs_sta.c12
-rw-r--r--net/mac80211/ht.c3
-rw-r--r--net/mac80211/ibss.c16
-rw-r--r--net/mac80211/ieee80211_i.h26
-rw-r--r--net/mac80211/iface.c118
-rw-r--r--net/mac80211/mlme.c175
-rw-r--r--net/mac80211/pm.c2
-rw-r--r--net/mac80211/rc80211_minstrel.c2
-rw-r--r--net/mac80211/rc80211_minstrel.h11
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c41
-rw-r--r--net/mac80211/rx.c92
-rw-r--r--net/mac80211/scan.c71
-rw-r--r--net/mac80211/sta_info.c73
-rw-r--r--net/mac80211/sta_info.h12
-rw-r--r--net/mac80211/status.c14
-rw-r--r--net/mac80211/tx.c9
-rw-r--r--net/mac80211/util.c7
-rw-r--r--net/rfkill/core.c53
-rw-r--r--net/wireless/core.h15
-rw-r--r--net/wireless/mlme.c52
-rw-r--r--net/wireless/nl80211.c153
-rw-r--r--net/wireless/nl80211.h6
-rw-r--r--net/wireless/reg.c6
-rw-r--r--net/wireless/sme.c15
-rw-r--r--net/wireless/util.c24
-rw-r--r--net/wireless/wext-core.c134
235 files changed, 19614 insertions, 8457 deletions
diff --git a/Documentation/ABI/obsolete/sysfs-class-rfkill b/Documentation/ABI/obsolete/sysfs-class-rfkill
new file mode 100644
index 000000000000..4201d5b05515
--- /dev/null
+++ b/Documentation/ABI/obsolete/sysfs-class-rfkill
@@ -0,0 +1,29 @@
1rfkill - radio frequency (RF) connector kill switch support
2
3For details to this subsystem look at Documentation/rfkill.txt.
4
5What: /sys/class/rfkill/rfkill[0-9]+/state
6Date: 09-Jul-2007
7KernelVersion v2.6.22
8Contact: linux-wireless@vger.kernel.org
9Description: Current state of the transmitter.
10 This file is deprecated and sheduled to be removed in 2014,
11 because its not possible to express the 'soft and hard block'
12 state of the rfkill driver.
13Values: A numeric value.
14 0: RFKILL_STATE_SOFT_BLOCKED
15 transmitter is turned off by software
16 1: RFKILL_STATE_UNBLOCKED
17 transmitter is (potentially) active
18 2: RFKILL_STATE_HARD_BLOCKED
19 transmitter is forced off by something outside of
20 the driver's control.
21
22What: /sys/class/rfkill/rfkill[0-9]+/claim
23Date: 09-Jul-2007
24KernelVersion v2.6.22
25Contact: linux-wireless@vger.kernel.org
26Description: This file is deprecated because there no longer is a way to
27 claim just control over a single rfkill instance.
28 This file is scheduled to be removed in 2012.
29Values: 0: Kernel handles events
diff --git a/Documentation/ABI/stable/sysfs-class-rfkill b/Documentation/ABI/stable/sysfs-class-rfkill
new file mode 100644
index 000000000000..097f522c33bb
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-class-rfkill
@@ -0,0 +1,67 @@
1rfkill - radio frequency (RF) connector kill switch support
2
3For details to this subsystem look at Documentation/rfkill.txt.
4
5For the deprecated /sys/class/rfkill/*/state and
6/sys/class/rfkill/*/claim knobs of this interface look in
7Documentation/ABI/obsolete/sysfs-class-rfkill.
8
9What: /sys/class/rfkill
10Date: 09-Jul-2007
11KernelVersion: v2.6.22
12Contact: linux-wireless@vger.kernel.org,
13Description: The rfkill class subsystem folder.
14 Each registered rfkill driver is represented by an rfkillX
15 subfolder (X being an integer > 0).
16
17
18What: /sys/class/rfkill/rfkill[0-9]+/name
19Date: 09-Jul-2007
20KernelVersion v2.6.22
21Contact: linux-wireless@vger.kernel.org
22Description: Name assigned by driver to this key (interface or driver name).
23Values: arbitrary string.
24
25
26What: /sys/class/rfkill/rfkill[0-9]+/type
27Date: 09-Jul-2007
28KernelVersion v2.6.22
29Contact: linux-wireless@vger.kernel.org
30Description: Driver type string ("wlan", "bluetooth", etc).
31Values: See include/linux/rfkill.h.
32
33
34What: /sys/class/rfkill/rfkill[0-9]+/persistent
35Date: 09-Jul-2007
36KernelVersion v2.6.22
37Contact: linux-wireless@vger.kernel.org
38Description: Whether the soft blocked state is initialised from non-volatile
39 storage at startup.
40Values: A numeric value.
41 0: false
42 1: true
43
44
45What: /sys/class/rfkill/rfkill[0-9]+/hard
46Date: 12-March-2010
47KernelVersion v2.6.34
48Contact: linux-wireless@vger.kernel.org
49Description: Current hardblock state. This file is read only.
50Values: A numeric value.
51 0: inactive
52 The transmitter is (potentially) active.
53 1: active
54 The transmitter is forced off by something outside of
55 the driver's control.
56
57
58What: /sys/class/rfkill/rfkill[0-9]+/soft
59Date: 12-March-2010
60KernelVersion v2.6.34
61Contact: linux-wireless@vger.kernel.org
62Description: Current softblock state. This file is read and write.
63Values: A numeric value.
64 0: inactive
65 The transmitter is (potentially) active.
66 1: active
67 The transmitter is turned off by software.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 73ef30dbe612..5f460110c5ee 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -543,6 +543,24 @@ Who: Eric Miao <eric.y.miao@gmail.com>
543 543
544---------------------------- 544----------------------------
545 545
546What: sysfs-class-rfkill state file
547When: Feb 2014
548Files: net/rfkill/core.c
549Why: Documented as obsolete since Feb 2010. This file is limited to 3
550 states while the rfkill drivers can have 4 states.
551Who: anybody or Florian Mickler <florian@mickler.org>
552
553----------------------------
554
555What: sysfs-class-rfkill claim file
556When: Feb 2012
557Files: net/rfkill/core.c
558Why: It is not possible to claim an rfkill driver since 2007. This is
559 Documented as obsolete since Feb 2010.
560Who: anybody or Florian Mickler <florian@mickler.org>
561
562----------------------------
563
546What: capifs 564What: capifs
547When: February 2011 565When: February 2011
548Files: drivers/isdn/capi/capifs.* 566Files: drivers/isdn/capi/capifs.*
@@ -550,3 +568,26 @@ Why: udev fully replaces this special file system that only contains CAPI
550 NCCI TTY device nodes. User space (pppdcapiplugin) works without 568 NCCI TTY device nodes. User space (pppdcapiplugin) works without
551 noticing the difference. 569 noticing the difference.
552Who: Jan Kiszka <jan.kiszka@web.de> 570Who: Jan Kiszka <jan.kiszka@web.de>
571
572----------------------------
573
574What: iwlwifi 50XX module parameters
575When: 2.6.40
576Why: The "..50" modules parameters were used to configure 5000 series and
577 up devices; different set of module parameters also available for 4965
578 with same functionalities. Consolidate both set into single place
579 in drivers/net/wireless/iwlwifi/iwl-agn.c
580
581Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
582
583----------------------------
584
585What: iwl4965 alias support
586When: 2.6.40
587Why: Internal alias support has been present in module-init-tools for some
588 time, the MODULE_ALIAS("iwl4965") boilerplate aliases can be removed
589 with no impact.
590
591Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
592
593----------------------------
diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt
index b4860509c319..83668e5dd17f 100644
--- a/Documentation/rfkill.txt
+++ b/Documentation/rfkill.txt
@@ -99,37 +99,15 @@ system. Also, it is possible to switch all rfkill drivers (or all drivers of
99a specified type) into a state which also updates the default state for 99a specified type) into a state which also updates the default state for
100hotplugged devices. 100hotplugged devices.
101 101
102After an application opens /dev/rfkill, it can read the current state of 102After an application opens /dev/rfkill, it can read the current state of all
103all devices, and afterwards can poll the descriptor for hotplug or state 103devices. Changes can be either obtained by either polling the descriptor for
104change events. 104hotplug or state change events or by listening for uevents emitted by the
105 105rfkill core framework.
106Applications must ignore operations (the "op" field) they do not handle, 106
107this allows the API to be extended in the future. 107Additionally, each rfkill device is registered in sysfs and emits uevents.
108 108
109Additionally, each rfkill device is registered in sysfs and there has the 109rfkill devices issue uevents (with an action of "change"), with the following
110following attributes: 110environment variables set:
111
112 name: Name assigned by driver to this key (interface or driver name).
113 type: Driver type string ("wlan", "bluetooth", etc).
114 persistent: Whether the soft blocked state is initialised from
115 non-volatile storage at startup.
116 state: Current state of the transmitter
117 0: RFKILL_STATE_SOFT_BLOCKED
118 transmitter is turned off by software
119 1: RFKILL_STATE_UNBLOCKED
120 transmitter is (potentially) active
121 2: RFKILL_STATE_HARD_BLOCKED
122 transmitter is forced off by something outside of
123 the driver's control.
124 This file is deprecated because it can only properly show
125 three of the four possible states, soft-and-hard-blocked is
126 missing.
127 claim: 0: Kernel handles events
128 This file is deprecated because there no longer is a way to
129 claim just control over a single rfkill instance.
130
131rfkill devices also issue uevents (with an action of "change"), with the
132following environment variables set:
133 111
134RFKILL_NAME 112RFKILL_NAME
135RFKILL_STATE 113RFKILL_STATE
@@ -137,3 +115,7 @@ RFKILL_TYPE
137 115
138The contents of these variables corresponds to the "name", "state" and 116The contents of these variables corresponds to the "name", "state" and
139"type" sysfs files explained above. 117"type" sysfs files explained above.
118
119
120For further details consult Documentation/ABI/stable/dev-rfkill and
121Documentation/ABI/stable/sysfs-class-rfkill.
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 2663b2fdc0bb..f5fc0f78fc21 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2279,26 +2279,25 @@ void gelic_wl_interrupt(struct net_device *netdev, u64 status)
2279/* 2279/*
2280 * driver helpers 2280 * driver helpers
2281 */ 2281 */
2282#define IW_IOCTL(n) [(n) - SIOCSIWCOMMIT]
2283static const iw_handler gelic_wl_wext_handler[] = 2282static const iw_handler gelic_wl_wext_handler[] =
2284{ 2283{
2285 IW_IOCTL(SIOCGIWNAME) = gelic_wl_get_name, 2284 IW_HANDLER(SIOCGIWNAME, gelic_wl_get_name),
2286 IW_IOCTL(SIOCGIWRANGE) = gelic_wl_get_range, 2285 IW_HANDLER(SIOCGIWRANGE, gelic_wl_get_range),
2287 IW_IOCTL(SIOCSIWSCAN) = gelic_wl_set_scan, 2286 IW_HANDLER(SIOCSIWSCAN, gelic_wl_set_scan),
2288 IW_IOCTL(SIOCGIWSCAN) = gelic_wl_get_scan, 2287 IW_HANDLER(SIOCGIWSCAN, gelic_wl_get_scan),
2289 IW_IOCTL(SIOCSIWAUTH) = gelic_wl_set_auth, 2288 IW_HANDLER(SIOCSIWAUTH, gelic_wl_set_auth),
2290 IW_IOCTL(SIOCGIWAUTH) = gelic_wl_get_auth, 2289 IW_HANDLER(SIOCGIWAUTH, gelic_wl_get_auth),
2291 IW_IOCTL(SIOCSIWESSID) = gelic_wl_set_essid, 2290 IW_HANDLER(SIOCSIWESSID, gelic_wl_set_essid),
2292 IW_IOCTL(SIOCGIWESSID) = gelic_wl_get_essid, 2291 IW_HANDLER(SIOCGIWESSID, gelic_wl_get_essid),
2293 IW_IOCTL(SIOCSIWENCODE) = gelic_wl_set_encode, 2292 IW_HANDLER(SIOCSIWENCODE, gelic_wl_set_encode),
2294 IW_IOCTL(SIOCGIWENCODE) = gelic_wl_get_encode, 2293 IW_HANDLER(SIOCGIWENCODE, gelic_wl_get_encode),
2295 IW_IOCTL(SIOCSIWAP) = gelic_wl_set_ap, 2294 IW_HANDLER(SIOCSIWAP, gelic_wl_set_ap),
2296 IW_IOCTL(SIOCGIWAP) = gelic_wl_get_ap, 2295 IW_HANDLER(SIOCGIWAP, gelic_wl_get_ap),
2297 IW_IOCTL(SIOCSIWENCODEEXT) = gelic_wl_set_encodeext, 2296 IW_HANDLER(SIOCSIWENCODEEXT, gelic_wl_set_encodeext),
2298 IW_IOCTL(SIOCGIWENCODEEXT) = gelic_wl_get_encodeext, 2297 IW_HANDLER(SIOCGIWENCODEEXT, gelic_wl_get_encodeext),
2299 IW_IOCTL(SIOCSIWMODE) = gelic_wl_set_mode, 2298 IW_HANDLER(SIOCSIWMODE, gelic_wl_set_mode),
2300 IW_IOCTL(SIOCGIWMODE) = gelic_wl_get_mode, 2299 IW_HANDLER(SIOCGIWMODE, gelic_wl_get_mode),
2301 IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick, 2300 IW_HANDLER(SIOCGIWNICKN, gelic_wl_get_nick),
2302}; 2301};
2303 2302
2304static const struct iw_handler_def gelic_wl_wext_handler_def = { 2303static const struct iw_handler_def gelic_wl_wext_handler_def = {
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index dc5018a6d9ed..a441aad922c2 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2876,7 +2876,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2876 ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0; 2876 ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
2877 ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0; 2877 ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
2878 2878
2879 airo_print_info(dev->name, "Firmware version %x.%x.%02x", 2879 airo_print_info(dev->name, "Firmware version %x.%x.%02d",
2880 ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF), 2880 ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
2881 (le16_to_cpu(cap_rid.softVer) & 0xFF), 2881 (le16_to_cpu(cap_rid.softVer) & 0xFF),
2882 le16_to_cpu(cap_rid.softSubVer)); 2882 le16_to_cpu(cap_rid.softSubVer));
@@ -3193,19 +3193,26 @@ static void airo_print_status(const char *devname, u16 status)
3193{ 3193{
3194 u8 reason = status & 0xFF; 3194 u8 reason = status & 0xFF;
3195 3195
3196 switch (status) { 3196 switch (status & 0xFF00) {
3197 case STAT_NOBEACON: 3197 case STAT_NOBEACON:
3198 airo_print_dbg(devname, "link lost (missed beacons)"); 3198 switch (status) {
3199 break; 3199 case STAT_NOBEACON:
3200 case STAT_MAXRETRIES: 3200 airo_print_dbg(devname, "link lost (missed beacons)");
3201 case STAT_MAXARL: 3201 break;
3202 airo_print_dbg(devname, "link lost (max retries)"); 3202 case STAT_MAXRETRIES:
3203 break; 3203 case STAT_MAXARL:
3204 case STAT_FORCELOSS: 3204 airo_print_dbg(devname, "link lost (max retries)");
3205 airo_print_dbg(devname, "link lost (local choice)"); 3205 break;
3206 break; 3206 case STAT_FORCELOSS:
3207 case STAT_TSFSYNC: 3207 airo_print_dbg(devname, "link lost (local choice)");
3208 airo_print_dbg(devname, "link lost (TSF sync lost)"); 3208 break;
3209 case STAT_TSFSYNC:
3210 airo_print_dbg(devname, "link lost (TSF sync lost)");
3211 break;
3212 default:
3213 airo_print_dbg(devname, "unknow status %x\n", status);
3214 break;
3215 }
3209 break; 3216 break;
3210 case STAT_DEAUTH: 3217 case STAT_DEAUTH:
3211 airo_print_dbg(devname, "deauthenticated (reason: %d)", reason); 3218 airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
@@ -3221,7 +3228,11 @@ static void airo_print_status(const char *devname, u16 status)
3221 airo_print_dbg(devname, "authentication failed (reason: %d)", 3228 airo_print_dbg(devname, "authentication failed (reason: %d)",
3222 reason); 3229 reason);
3223 break; 3230 break;
3231 case STAT_ASSOC:
3232 case STAT_REASSOC:
3233 break;
3224 default: 3234 default:
3235 airo_print_dbg(devname, "unknow status %x\n", status);
3225 break; 3236 break;
3226 } 3237 }
3227} 3238}
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 4e7a7fd695c8..0a75be027afa 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -3,7 +3,7 @@ menuconfig ATH_COMMON
3 depends on CFG80211 3 depends on CFG80211
4 ---help--- 4 ---help---
5 This will enable the support for the Atheros wireless drivers. 5 This will enable the support for the Atheros wireless drivers.
6 ath5k, ath9k and ar9170 drivers share some common code, this option 6 ath5k, ath9k, ath9k_htc and ar9170 drivers share some common code, this option
7 enables the common ath.ko module which shares common helpers. 7 enables the common ath.ko module which shares common helpers.
8 8
9 For more information and documentation on this module you can visit: 9 For more information and documentation on this module you can visit:
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h
index 826c45e6b274..ec8134b4b949 100644
--- a/drivers/net/wireless/ath/ar9170/cmd.h
+++ b/drivers/net/wireless/ath/ar9170/cmd.h
@@ -79,7 +79,7 @@ __regwrite_out : \
79 if (__nreg) { \ 79 if (__nreg) { \
80 if (IS_ACCEPTING_CMD(__ar)) \ 80 if (IS_ACCEPTING_CMD(__ar)) \
81 __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \ 81 __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
82 8 * __nreg, \ 82 8 * __nreg, \
83 (u8 *) &__ar->cmdbuf[1], \ 83 (u8 *) &__ar->cmdbuf[1], \
84 0, NULL); \ 84 0, NULL); \
85 __nreg = 0; \ 85 __nreg = 0; \
diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h
index d2c8cc83f1dd..6c4663883423 100644
--- a/drivers/net/wireless/ath/ar9170/eeprom.h
+++ b/drivers/net/wireless/ath/ar9170/eeprom.h
@@ -127,8 +127,8 @@ struct ar9170_eeprom {
127 __le16 checksum; 127 __le16 checksum;
128 __le16 version; 128 __le16 version;
129 u8 operating_flags; 129 u8 operating_flags;
130#define AR9170_OPFLAG_5GHZ 1 130#define AR9170_OPFLAG_5GHZ 1
131#define AR9170_OPFLAG_2GHZ 2 131#define AR9170_OPFLAG_2GHZ 2
132 u8 misc; 132 u8 misc;
133 __le16 reg_domain[2]; 133 __le16 reg_domain[2];
134 u8 mac_address[6]; 134 u8 mac_address[6];
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
index 0a1d4c28e68a..06f1f3c951a4 100644
--- a/drivers/net/wireless/ath/ar9170/hw.h
+++ b/drivers/net/wireless/ath/ar9170/hw.h
@@ -425,5 +425,6 @@ enum ar9170_txq {
425 425
426#define AR9170_TXQ_DEPTH 32 426#define AR9170_TXQ_DEPTH 32
427#define AR9170_TX_MAX_PENDING 128 427#define AR9170_TX_MAX_PENDING 128
428#define AR9170_RX_STREAM_MAX_SIZE 65535
428 429
429#endif /* __AR9170_HW_H */ 430#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index f4650fcdebc9..fed6695ec04e 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -235,7 +235,7 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar,
235 wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); 235 wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
236 236
237 skb_queue_walk(queue, skb) { 237 skb_queue_walk(queue, skb) {
238 printk(KERN_DEBUG "index:%d => \n", i++); 238 printk(KERN_DEBUG "index:%d =>\n", i++);
239 ar9170_print_txheader(ar, skb); 239 ar9170_print_txheader(ar, skb);
240 } 240 }
241 if (i != skb_queue_len(queue)) 241 if (i != skb_queue_len(queue))
@@ -280,7 +280,7 @@ static void ar9170_dump_tx_status_ampdu(struct ar9170 *ar)
280 unsigned long flags; 280 unsigned long flags;
281 281
282 spin_lock_irqsave(&ar->tx_status_ampdu.lock, flags); 282 spin_lock_irqsave(&ar->tx_status_ampdu.lock, flags);
283 printk(KERN_DEBUG "%s: A-MPDU tx_status queue => \n", 283 printk(KERN_DEBUG "%s: A-MPDU tx_status queue =>\n",
284 wiphy_name(ar->hw->wiphy)); 284 wiphy_name(ar->hw->wiphy));
285 __ar9170_dump_txqueue(ar, &ar->tx_status_ampdu); 285 __ar9170_dump_txqueue(ar, &ar->tx_status_ampdu);
286 spin_unlock_irqrestore(&ar->tx_status_ampdu.lock, flags); 286 spin_unlock_irqrestore(&ar->tx_status_ampdu.lock, flags);
@@ -307,7 +307,7 @@ static void ar9170_recycle_expired(struct ar9170 *ar,
307 if (time_is_before_jiffies(arinfo->timeout)) { 307 if (time_is_before_jiffies(arinfo->timeout)) {
308#ifdef AR9170_QUEUE_DEBUG 308#ifdef AR9170_QUEUE_DEBUG
309 printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " 309 printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
310 "recycle \n", wiphy_name(ar->hw->wiphy), 310 "recycle\n", wiphy_name(ar->hw->wiphy),
311 jiffies, arinfo->timeout); 311 jiffies, arinfo->timeout);
312 ar9170_print_txheader(ar, skb); 312 ar9170_print_txheader(ar, skb);
313#endif /* AR9170_QUEUE_DEBUG */ 313#endif /* AR9170_QUEUE_DEBUG */
@@ -688,7 +688,8 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
688 688
689 /* firmware debug */ 689 /* firmware debug */
690 case 0xca: 690 case 0xca:
691 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4); 691 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4,
692 (char *)buf + 4);
692 break; 693 break;
693 case 0xcb: 694 case 0xcb:
694 len -= 4; 695 len -= 4;
@@ -1727,7 +1728,7 @@ static void ar9170_tx(struct ar9170 *ar)
1727 printk(KERN_DEBUG "%s: queue %d full\n", 1728 printk(KERN_DEBUG "%s: queue %d full\n",
1728 wiphy_name(ar->hw->wiphy), i); 1729 wiphy_name(ar->hw->wiphy), i);
1729 1730
1730 printk(KERN_DEBUG "%s: stuck frames: ===> \n", 1731 printk(KERN_DEBUG "%s: stuck frames: ===>\n",
1731 wiphy_name(ar->hw->wiphy)); 1732 wiphy_name(ar->hw->wiphy));
1732 ar9170_dump_txqueue(ar, &ar->tx_pending[i]); 1733 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1733 ar9170_dump_txqueue(ar, &ar->tx_status[i]); 1734 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
@@ -2515,7 +2516,7 @@ void *ar9170_alloc(size_t priv_size)
2515 * tends to split the streams into seperate rx descriptors. 2516 * tends to split the streams into seperate rx descriptors.
2516 */ 2517 */
2517 2518
2518 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); 2519 skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
2519 if (!skb) 2520 if (!skb)
2520 goto err_nomem; 2521 goto err_nomem;
2521 2522
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 71fc960814f0..1fbf6b1f9a7e 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -48,6 +48,12 @@ enum ath_device_state {
48 ATH_HW_INITIALIZED, 48 ATH_HW_INITIALIZED,
49}; 49};
50 50
51enum ath_bus_type {
52 ATH_PCI,
53 ATH_AHB,
54 ATH_USB,
55};
56
51struct reg_dmn_pair_mapping { 57struct reg_dmn_pair_mapping {
52 u16 regDmnEnum; 58 u16 regDmnEnum;
53 u16 reg_5ghz_ctl; 59 u16 reg_5ghz_ctl;
@@ -73,9 +79,10 @@ struct ath_ops {
73struct ath_common; 79struct ath_common;
74 80
75struct ath_bus_ops { 81struct ath_bus_ops {
76 void (*read_cachesize)(struct ath_common *common, int *csz); 82 enum ath_bus_type ath_bus_type;
77 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); 83 void (*read_cachesize)(struct ath_common *common, int *csz);
78 void (*bt_coex_prep)(struct ath_common *common); 84 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
85 void (*bt_coex_prep)(struct ath_common *common);
79}; 86};
80 87
81struct ath_common { 88struct ath_common {
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 090dc6d268a3..cc09595b781a 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -12,5 +12,6 @@ ath5k-y += attach.o
12ath5k-y += base.o 12ath5k-y += base.o
13ath5k-y += led.o 13ath5k-y += led.o
14ath5k-y += rfkill.o 14ath5k-y += rfkill.o
15ath5k-y += ani.o
15ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o 16ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
16obj-$(CONFIG_ATH5K) += ath5k.o 17obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
new file mode 100644
index 000000000000..584a32859bdb
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -0,0 +1,744 @@
1/*
2 * Copyright (C) 2010 Bruno Randolf <br1@einfach.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath5k.h"
18#include "base.h"
19#include "reg.h"
20#include "debug.h"
21#include "ani.h"
22
23/**
24 * DOC: Basic ANI Operation
25 *
26 * Adaptive Noise Immunity (ANI) controls five noise immunity parameters
27 * depending on the amount of interference in the environment, increasing
28 * or reducing sensitivity as necessary.
29 *
30 * The parameters are:
31 * - "noise immunity"
32 * - "spur immunity"
33 * - "firstep level"
34 * - "OFDM weak signal detection"
35 * - "CCK weak signal detection"
36 *
37 * Basically we look at the amount of ODFM and CCK timing errors we get and then
38 * raise or lower immunity accordingly by setting one or more of these
39 * parameters.
40 * Newer chipsets have PHY error counters in hardware which will generate a MIB
41 * interrupt when they overflow. Older hardware has too enable PHY error frames
42 * by setting a RX flag and then count every single PHY error. When a specified
43 * threshold of errors has been reached we will raise immunity.
44 * Also we regularly check the amount of errors and lower or raise immunity as
45 * necessary.
46 */
47
48
49/*** ANI parameter control ***/
50
51/**
52 * ath5k_ani_set_noise_immunity_level() - Set noise immunity level
53 *
54 * @level: level between 0 and @ATH5K_ANI_MAX_NOISE_IMM_LVL
55 */
56void
57ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
58{
59 /* TODO:
60 * ANI documents suggest the following five levels to use, but the HAL
61 * and ath9k use only use the last two levels, making this
62 * essentially an on/off option. There *may* be a reason for this (???),
63 * so i stick with the HAL version for now...
64 */
65#if 0
66 const s8 hi[] = { -18, -18, -16, -14, -12 };
67 const s8 lo[] = { -52, -56, -60, -64, -70 };
68 const s8 sz[] = { -34, -41, -48, -55, -62 };
69 const s8 fr[] = { -70, -72, -75, -78, -80 };
70#else
71 const s8 sz[] = { -55, -62 };
72 const s8 lo[] = { -64, -70 };
73 const s8 hi[] = { -14, -12 };
74 const s8 fr[] = { -78, -80 };
75#endif
76 if (level < 0 || level > ARRAY_SIZE(sz)) {
77 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
78 "level out of range %d", level);
79 return;
80 }
81
82 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
83 AR5K_PHY_DESIRED_SIZE_TOT, sz[level]);
84 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE,
85 AR5K_PHY_AGCCOARSE_LO, lo[level]);
86 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE,
87 AR5K_PHY_AGCCOARSE_HI, hi[level]);
88 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
89 AR5K_PHY_SIG_FIRPWR, fr[level]);
90
91 ah->ah_sc->ani_state.noise_imm_level = level;
92 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
93}
94
95
96/**
97 * ath5k_ani_set_spur_immunity_level() - Set spur immunity level
98 *
99 * @level: level between 0 and @max_spur_level (the maximum level is dependent
100 * on the chip revision).
101 */
102void
103ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
104{
105 const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
106
107 if (level < 0 || level > ARRAY_SIZE(val) ||
108 level > ah->ah_sc->ani_state.max_spur_level) {
109 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
110 "level out of range %d", level);
111 return;
112 }
113
114 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
115 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, val[level]);
116
117 ah->ah_sc->ani_state.spur_level = level;
118 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
119}
120
121
122/**
123 * ath5k_ani_set_firstep_level() - Set "firstep" level
124 *
125 * @level: level between 0 and @ATH5K_ANI_MAX_FIRSTEP_LVL
126 */
127void
128ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
129{
130 const int val[] = { 0, 4, 8 };
131
132 if (level < 0 || level > ARRAY_SIZE(val)) {
133 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
134 "level out of range %d", level);
135 return;
136 }
137
138 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
139 AR5K_PHY_SIG_FIRSTEP, val[level]);
140
141 ah->ah_sc->ani_state.firstep_level = level;
142 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
143}
144
145
146/**
147 * ath5k_ani_set_ofdm_weak_signal_detection() - Control OFDM weak signal
148 * detection
149 *
150 * @on: turn on or off
151 */
152void
153ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
154{
155 const int m1l[] = { 127, 50 };
156 const int m2l[] = { 127, 40 };
157 const int m1[] = { 127, 0x4d };
158 const int m2[] = { 127, 0x40 };
159 const int m2cnt[] = { 31, 16 };
160 const int m2lcnt[] = { 63, 48 };
161
162 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
163 AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]);
164 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
165 AR5K_PHY_WEAK_OFDM_LOW_THR_M2, m2l[on]);
166 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
167 AR5K_PHY_WEAK_OFDM_HIGH_THR_M1, m1[on]);
168 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
169 AR5K_PHY_WEAK_OFDM_HIGH_THR_M2, m2[on]);
170 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
171 AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT, m2cnt[on]);
172 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
173 AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT, m2lcnt[on]);
174
175 if (on)
176 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
177 AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN);
178 else
179 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
180 AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN);
181
182 ah->ah_sc->ani_state.ofdm_weak_sig = on;
183 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
184 on ? "on" : "off");
185}
186
187
188/**
189 * ath5k_ani_set_cck_weak_signal_detection() - control CCK weak signal detection
190 *
191 * @on: turn on or off
192 */
193void
194ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
195{
196 const int val[] = { 8, 6 };
197 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR,
198 AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]);
199 ah->ah_sc->ani_state.cck_weak_sig = on;
200 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
201 on ? "on" : "off");
202}
203
204
205/*** ANI algorithm ***/
206
207/**
208 * ath5k_ani_raise_immunity() - Increase noise immunity
209 *
210 * @ofdm_trigger: If this is true we are called because of too many OFDM errors,
211 * the algorithm will tune more parameters then.
212 *
213 * Try to raise noise immunity (=decrease sensitivity) in several steps
214 * depending on the average RSSI of the beacons we received.
215 */
216static void
217ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
218 bool ofdm_trigger)
219{
220 int rssi = ah->ah_beacon_rssi_avg.avg;
221
222 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
223 ofdm_trigger ? "ODFM" : "CCK");
224
225 /* first: raise noise immunity */
226 if (as->noise_imm_level < ATH5K_ANI_MAX_NOISE_IMM_LVL) {
227 ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level + 1);
228 return;
229 }
230
231 /* only OFDM: raise spur immunity level */
232 if (ofdm_trigger &&
233 as->spur_level < ah->ah_sc->ani_state.max_spur_level) {
234 ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1);
235 return;
236 }
237
238 /* AP mode */
239 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
240 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
241 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
242 return;
243 }
244
245 /* STA and IBSS mode */
246
247 /* TODO: for IBSS mode it would be better to keep a beacon RSSI average
248 * per each neighbour node and use the minimum of these, to make sure we
249 * don't shut out a remote node by raising immunity too high. */
250
251 if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
252 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
253 "beacon RSSI high");
254 /* only OFDM: beacon RSSI is high, we can disable ODFM weak
255 * signal detection */
256 if (ofdm_trigger && as->ofdm_weak_sig == true) {
257 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
258 ath5k_ani_set_spur_immunity_level(ah, 0);
259 return;
260 }
261 /* as a last resort or CCK: raise firstep level */
262 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) {
263 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
264 return;
265 }
266 } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
267 /* beacon RSSI in mid range, we need OFDM weak signal detect,
268 * but can raise firstep level */
269 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
270 "beacon RSSI mid");
271 if (ofdm_trigger && as->ofdm_weak_sig == false)
272 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
273 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
274 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
275 return;
276 } else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) {
277 /* beacon RSSI is low. in B/G mode turn of OFDM weak signal
278 * detect and zero firstep level to maximize CCK sensitivity */
279 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
280 "beacon RSSI low, 2GHz");
281 if (ofdm_trigger && as->ofdm_weak_sig == true)
282 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
283 if (as->firstep_level > 0)
284 ath5k_ani_set_firstep_level(ah, 0);
285 return;
286 }
287
288 /* TODO: why not?:
289 if (as->cck_weak_sig == true) {
290 ath5k_ani_set_cck_weak_signal_detection(ah, false);
291 }
292 */
293}
294
295
296/**
297 * ath5k_ani_lower_immunity() - Decrease noise immunity
298 *
299 * Try to lower noise immunity (=increase sensitivity) in several steps
300 * depending on the average RSSI of the beacons we received.
301 */
302static void
303ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
304{
305 int rssi = ah->ah_beacon_rssi_avg.avg;
306
307 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
308
309 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
310 /* AP mode */
311 if (as->firstep_level > 0) {
312 ath5k_ani_set_firstep_level(ah, as->firstep_level - 1);
313 return;
314 }
315 } else {
316 /* STA and IBSS mode (see TODO above) */
317 if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
318 /* beacon signal is high, leave OFDM weak signal
319 * detection off or it may oscillate
320 * TODO: who said it's off??? */
321 } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
322 /* beacon RSSI is mid-range: turn on ODFM weak signal
323 * detection and next, lower firstep level */
324 if (as->ofdm_weak_sig == false) {
325 ath5k_ani_set_ofdm_weak_signal_detection(ah,
326 true);
327 return;
328 }
329 if (as->firstep_level > 0) {
330 ath5k_ani_set_firstep_level(ah,
331 as->firstep_level - 1);
332 return;
333 }
334 } else {
335 /* beacon signal is low: only reduce firstep level */
336 if (as->firstep_level > 0) {
337 ath5k_ani_set_firstep_level(ah,
338 as->firstep_level - 1);
339 return;
340 }
341 }
342 }
343
344 /* all modes */
345 if (as->spur_level > 0) {
346 ath5k_ani_set_spur_immunity_level(ah, as->spur_level - 1);
347 return;
348 }
349
350 /* finally, reduce noise immunity */
351 if (as->noise_imm_level > 0) {
352 ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level - 1);
353 return;
354 }
355}
356
357
358/**
359 * ath5k_hw_ani_get_listen_time() - Calculate time spent listening
360 *
361 * Return an approximation of the time spent "listening" in milliseconds (ms)
362 * since the last call of this function by deducting the cycles spent
363 * transmitting and receiving from the total cycle count.
364 * Save profile count values for debugging/statistics and because we might want
365 * to use them later.
366 *
367 * We assume no one else clears these registers!
368 */
369static int
370ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
371{
372 int listen;
373
374 /* freeze */
375 ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC);
376 /* read */
377 as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE);
378 as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR);
379 as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX);
380 as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX);
381 /* clear */
382 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
383 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
384 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
385 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
386 /* un-freeze */
387 ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
388
389 /* TODO: where does 44000 come from? (11g clock rate?) */
390 listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
391
392 if (as->pfc_cycles == 0 || listen < 0)
393 return 0;
394 return listen;
395}
396
397
398/**
399 * ath5k_ani_save_and_clear_phy_errors() - Clear and save PHY error counters
400 *
401 * Clear the PHY error counters as soon as possible, since this might be called
402 * from a MIB interrupt and we want to make sure we don't get interrupted again.
403 * Add the count of CCK and OFDM errors to our internal state, so it can be used
404 * by the algorithm later.
405 *
406 * Will be called from interrupt and tasklet context.
407 * Returns 0 if both counters are zero.
408 */
409static int
410ath5k_ani_save_and_clear_phy_errors(struct ath5k_hw *ah,
411 struct ath5k_ani_state *as)
412{
413 unsigned int ofdm_err, cck_err;
414
415 if (!ah->ah_capabilities.cap_has_phyerr_counters)
416 return 0;
417
418 ofdm_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1);
419 cck_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2);
420
421 /* reset counters first, we might be in a hurry (interrupt) */
422 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH,
423 AR5K_PHYERR_CNT1);
424 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH,
425 AR5K_PHYERR_CNT2);
426
427 ofdm_err = ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - ofdm_err);
428 cck_err = ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - cck_err);
429
430 /* sometimes both can be zero, especially when there is a superfluous
431 * second interrupt. detect that here and return an error. */
432 if (ofdm_err <= 0 && cck_err <= 0)
433 return 0;
434
435 /* avoid negative values should one of the registers overflow */
436 if (ofdm_err > 0) {
437 as->ofdm_errors += ofdm_err;
438 as->sum_ofdm_errors += ofdm_err;
439 }
440 if (cck_err > 0) {
441 as->cck_errors += cck_err;
442 as->sum_cck_errors += cck_err;
443 }
444 return 1;
445}
446
447
448/**
449 * ath5k_ani_period_restart() - Restart ANI period
450 *
451 * Just reset counters, so they are clear for the next "ani period".
452 */
453static void
454ath5k_ani_period_restart(struct ath5k_hw *ah, struct ath5k_ani_state *as)
455{
456 /* keep last values for debugging */
457 as->last_ofdm_errors = as->ofdm_errors;
458 as->last_cck_errors = as->cck_errors;
459 as->last_listen = as->listen_time;
460
461 as->ofdm_errors = 0;
462 as->cck_errors = 0;
463 as->listen_time = 0;
464}
465
466
467/**
468 * ath5k_ani_calibration() - The main ANI calibration function
469 *
470 * We count OFDM and CCK errors relative to the time where we did not send or
471 * receive ("listen" time) and raise or lower immunity accordingly.
472 * This is called regularly (every second) from the calibration timer, but also
473 * when an error threshold has been reached.
474 *
475 * In order to synchronize access from different contexts, this should be
476 * called only indirectly by scheduling the ANI tasklet!
477 */
478void
479ath5k_ani_calibration(struct ath5k_hw *ah)
480{
481 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
482 int listen, ofdm_high, ofdm_low, cck_high, cck_low;
483
484 if (as->ani_mode != ATH5K_ANI_MODE_AUTO)
485 return;
486
487 /* get listen time since last call and add it to the counter because we
488 * might not have restarted the "ani period" last time */
489 listen = ath5k_hw_ani_get_listen_time(ah, as);
490 as->listen_time += listen;
491
492 ath5k_ani_save_and_clear_phy_errors(ah, as);
493
494 ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000;
495 cck_high = as->listen_time * ATH5K_ANI_CCK_TRIG_HIGH / 1000;
496 ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000;
497 cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000;
498
499 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
500 "listen %d (now %d)", as->listen_time, listen);
501 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
502 "check high ofdm %d/%d cck %d/%d",
503 as->ofdm_errors, ofdm_high, as->cck_errors, cck_high);
504
505 if (as->ofdm_errors > ofdm_high || as->cck_errors > cck_high) {
506 /* too many PHY errors - we have to raise immunity */
507 bool ofdm_flag = as->ofdm_errors > ofdm_high ? true : false;
508 ath5k_ani_raise_immunity(ah, as, ofdm_flag);
509 ath5k_ani_period_restart(ah, as);
510
511 } else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) {
512 /* If more than 5 (TODO: why 5?) periods have passed and we got
513 * relatively little errors we can try to lower immunity */
514 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
515 "check low ofdm %d/%d cck %d/%d",
516 as->ofdm_errors, ofdm_low, as->cck_errors, cck_low);
517
518 if (as->ofdm_errors <= ofdm_low && as->cck_errors <= cck_low)
519 ath5k_ani_lower_immunity(ah, as);
520
521 ath5k_ani_period_restart(ah, as);
522 }
523}
524
525
526/*** INTERRUPT HANDLER ***/
527
528/**
529 * ath5k_ani_mib_intr() - Interrupt handler for ANI MIB counters
530 *
531 * Just read & reset the registers quickly, so they don't generate more
532 * interrupts, save the counters and schedule the tasklet to decide whether
533 * to raise immunity or not.
534 *
535 * We just need to handle PHY error counters, ath5k_hw_update_mib_counters()
536 * should take care of all "normal" MIB interrupts.
537 */
538void
539ath5k_ani_mib_intr(struct ath5k_hw *ah)
540{
541 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
542
543 /* nothing to do here if HW does not have PHY error counters - they
544 * can't be the reason for the MIB interrupt then */
545 if (!ah->ah_capabilities.cap_has_phyerr_counters)
546 return;
547
548 /* not in use but clear anyways */
549 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
550 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
551
552 if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
553 return;
554
555 /* if one of the errors triggered, we can get a superfluous second
556 * interrupt, even though we have already reset the register. the
557 * function detects that so we can return early */
558 if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0)
559 return;
560
561 if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH ||
562 as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
563 tasklet_schedule(&ah->ah_sc->ani_tasklet);
564}
565
566
567/**
568 * ath5k_ani_phy_error_report() - Used by older HW to report PHY errors
569 *
570 * This is used by hardware without PHY error counters to report PHY errors
571 * on a frame-by-frame basis, instead of the interrupt.
572 */
573void
574ath5k_ani_phy_error_report(struct ath5k_hw *ah,
575 enum ath5k_phy_error_code phyerr)
576{
577 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
578
579 if (phyerr == AR5K_RX_PHY_ERROR_OFDM_TIMING) {
580 as->ofdm_errors++;
581 if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH)
582 tasklet_schedule(&ah->ah_sc->ani_tasklet);
583 } else if (phyerr == AR5K_RX_PHY_ERROR_CCK_TIMING) {
584 as->cck_errors++;
585 if (as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
586 tasklet_schedule(&ah->ah_sc->ani_tasklet);
587 }
588}
589
590
591/*** INIT ***/
592
593/**
594 * ath5k_enable_phy_err_counters() - Enable PHY error counters
595 *
596 * Enable PHY error counters for OFDM and CCK timing errors.
597 */
598static void
599ath5k_enable_phy_err_counters(struct ath5k_hw *ah)
600{
601 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH,
602 AR5K_PHYERR_CNT1);
603 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH,
604 AR5K_PHYERR_CNT2);
605 ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_OFDM, AR5K_PHYERR_CNT1_MASK);
606 ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_CCK, AR5K_PHYERR_CNT2_MASK);
607
608 /* not in use */
609 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
610 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
611}
612
613
614/**
615 * ath5k_disable_phy_err_counters() - Disable PHY error counters
616 *
617 * Disable PHY error counters for OFDM and CCK timing errors.
618 */
619static void
620ath5k_disable_phy_err_counters(struct ath5k_hw *ah)
621{
622 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1);
623 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2);
624 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1_MASK);
625 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2_MASK);
626
627 /* not in use */
628 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
629 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
630}
631
632
633/**
634 * ath5k_ani_init() - Initialize ANI
635 * @mode: Which mode to use (auto, manual high, manual low, off)
636 *
637 * Initialize ANI according to mode.
638 */
639void
640ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
641{
642 /* ANI is only possible on 5212 and newer */
643 if (ah->ah_version < AR5K_AR5212)
644 return;
645
646 /* clear old state information */
647 memset(&ah->ah_sc->ani_state, 0, sizeof(ah->ah_sc->ani_state));
648
649 /* older hardware has more spur levels than newer */
650 if (ah->ah_mac_srev < AR5K_SREV_AR2414)
651 ah->ah_sc->ani_state.max_spur_level = 7;
652 else
653 ah->ah_sc->ani_state.max_spur_level = 2;
654
655 /* initial values for our ani parameters */
656 if (mode == ATH5K_ANI_MODE_OFF) {
657 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI off\n");
658 } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
659 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
660 "ANI manual low -> high sensitivity\n");
661 ath5k_ani_set_noise_immunity_level(ah, 0);
662 ath5k_ani_set_spur_immunity_level(ah, 0);
663 ath5k_ani_set_firstep_level(ah, 0);
664 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
665 ath5k_ani_set_cck_weak_signal_detection(ah, true);
666 } else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) {
667 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
668 "ANI manual high -> low sensitivity\n");
669 ath5k_ani_set_noise_immunity_level(ah,
670 ATH5K_ANI_MAX_NOISE_IMM_LVL);
671 ath5k_ani_set_spur_immunity_level(ah,
672 ah->ah_sc->ani_state.max_spur_level);
673 ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
674 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
675 ath5k_ani_set_cck_weak_signal_detection(ah, false);
676 } else if (mode == ATH5K_ANI_MODE_AUTO) {
677 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI auto\n");
678 ath5k_ani_set_noise_immunity_level(ah, 0);
679 ath5k_ani_set_spur_immunity_level(ah, 0);
680 ath5k_ani_set_firstep_level(ah, 0);
681 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
682 ath5k_ani_set_cck_weak_signal_detection(ah, false);
683 }
684
685 /* newer hardware has PHY error counter registers which we can use to
686 * get OFDM and CCK error counts. older hardware has to set rxfilter and
687 * report every single PHY error by calling ath5k_ani_phy_error_report()
688 */
689 if (mode == ATH5K_ANI_MODE_AUTO) {
690 if (ah->ah_capabilities.cap_has_phyerr_counters)
691 ath5k_enable_phy_err_counters(ah);
692 else
693 ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) |
694 AR5K_RX_FILTER_PHYERR);
695 } else {
696 if (ah->ah_capabilities.cap_has_phyerr_counters)
697 ath5k_disable_phy_err_counters(ah);
698 else
699 ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) &
700 ~AR5K_RX_FILTER_PHYERR);
701 }
702
703 ah->ah_sc->ani_state.ani_mode = mode;
704}
705
706
707/*** DEBUG ***/
708
709#ifdef CONFIG_ATH5K_DEBUG
710
711void
712ath5k_ani_print_counters(struct ath5k_hw *ah)
713{
714 /* clears too */
715 printk(KERN_NOTICE "ACK fail\t%d\n",
716 ath5k_hw_reg_read(ah, AR5K_ACK_FAIL));
717 printk(KERN_NOTICE "RTS fail\t%d\n",
718 ath5k_hw_reg_read(ah, AR5K_RTS_FAIL));
719 printk(KERN_NOTICE "RTS success\t%d\n",
720 ath5k_hw_reg_read(ah, AR5K_RTS_OK));
721 printk(KERN_NOTICE "FCS error\t%d\n",
722 ath5k_hw_reg_read(ah, AR5K_FCS_FAIL));
723
724 /* no clear */
725 printk(KERN_NOTICE "tx\t%d\n",
726 ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX));
727 printk(KERN_NOTICE "rx\t%d\n",
728 ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX));
729 printk(KERN_NOTICE "busy\t%d\n",
730 ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR));
731 printk(KERN_NOTICE "cycles\t%d\n",
732 ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE));
733
734 printk(KERN_NOTICE "AR5K_PHYERR_CNT1\t%d\n",
735 ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1));
736 printk(KERN_NOTICE "AR5K_PHYERR_CNT2\t%d\n",
737 ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2));
738 printk(KERN_NOTICE "AR5K_OFDM_FIL_CNT\t%d\n",
739 ath5k_hw_reg_read(ah, AR5K_OFDM_FIL_CNT));
740 printk(KERN_NOTICE "AR5K_CCK_FIL_CNT\t%d\n",
741 ath5k_hw_reg_read(ah, AR5K_CCK_FIL_CNT));
742}
743
744#endif
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h
new file mode 100644
index 000000000000..55cf26d8522c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ani.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2010 Bruno Randolf <br1@einfach.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef ANI_H
17#define ANI_H
18
19/* these thresholds are relative to the ATH5K_ANI_LISTEN_PERIOD */
20#define ATH5K_ANI_LISTEN_PERIOD 100
21#define ATH5K_ANI_OFDM_TRIG_HIGH 500
22#define ATH5K_ANI_OFDM_TRIG_LOW 200
23#define ATH5K_ANI_CCK_TRIG_HIGH 200
24#define ATH5K_ANI_CCK_TRIG_LOW 100
25
26/* average beacon RSSI thresholds */
27#define ATH5K_ANI_RSSI_THR_HIGH 40
28#define ATH5K_ANI_RSSI_THR_LOW 7
29
30/* maximum availabe levels */
31#define ATH5K_ANI_MAX_FIRSTEP_LVL 2
32#define ATH5K_ANI_MAX_NOISE_IMM_LVL 1
33
34
35/**
36 * enum ath5k_ani_mode - mode for ANI / noise sensitivity
37 *
38 * @ATH5K_ANI_MODE_OFF: Turn ANI off. This can be useful to just stop the ANI
39 * algorithm after it has been on auto mode.
40 * ATH5K_ANI_MODE_MANUAL_LOW: Manually set all immunity parameters to low,
41 * maximizing sensitivity. ANI will not run.
42 * ATH5K_ANI_MODE_MANUAL_HIGH: Manually set all immunity parameters to high,
43 * minimizing sensitivity. ANI will not run.
44 * ATH5K_ANI_MODE_AUTO: Automatically control immunity parameters based on the
45 * amount of OFDM and CCK frame errors (default).
46 */
47enum ath5k_ani_mode {
48 ATH5K_ANI_MODE_OFF = 0,
49 ATH5K_ANI_MODE_MANUAL_LOW = 1,
50 ATH5K_ANI_MODE_MANUAL_HIGH = 2,
51 ATH5K_ANI_MODE_AUTO = 3
52};
53
54
55/**
56 * struct ath5k_ani_state - ANI state and associated counters
57 *
58 * @max_spur_level: the maximum spur level is chip dependent
59 */
60struct ath5k_ani_state {
61 enum ath5k_ani_mode ani_mode;
62
63 /* state */
64 int noise_imm_level;
65 int spur_level;
66 int firstep_level;
67 bool ofdm_weak_sig;
68 bool cck_weak_sig;
69
70 int max_spur_level;
71
72 /* used by the algorithm */
73 unsigned int listen_time;
74 unsigned int ofdm_errors;
75 unsigned int cck_errors;
76
77 /* debug/statistics only: numbers from last ANI calibration */
78 unsigned int pfc_tx;
79 unsigned int pfc_rx;
80 unsigned int pfc_busy;
81 unsigned int pfc_cycles;
82 unsigned int last_listen;
83 unsigned int last_ofdm_errors;
84 unsigned int last_cck_errors;
85 unsigned int sum_ofdm_errors;
86 unsigned int sum_cck_errors;
87};
88
89void ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode);
90void ath5k_ani_mib_intr(struct ath5k_hw *ah);
91void ath5k_ani_calibration(struct ath5k_hw *ah);
92void ath5k_ani_phy_error_report(struct ath5k_hw *ah,
93 enum ath5k_phy_error_code phyerr);
94
95/* for manual control */
96void ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level);
97void ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level);
98void ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level);
99void ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on);
100void ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on);
101
102void ath5k_ani_print_counters(struct ath5k_hw *ah);
103
104#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index ac67f02e26d8..2785946f659a 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -202,7 +202,8 @@
202#define AR5K_TUNE_MAX_TXPOWER 63 202#define AR5K_TUNE_MAX_TXPOWER 63
203#define AR5K_TUNE_DEFAULT_TXPOWER 25 203#define AR5K_TUNE_DEFAULT_TXPOWER 25
204#define AR5K_TUNE_TPC_TXPOWER false 204#define AR5K_TUNE_TPC_TXPOWER false
205#define AR5K_TUNE_HWTXTRIES 4 205#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */
206#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
206 207
207#define AR5K_INIT_CARR_SENSE_EN 1 208#define AR5K_INIT_CARR_SENSE_EN 1
208 209
@@ -614,28 +615,6 @@ struct ath5k_rx_status {
614#define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/ 615#define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/
615#define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/ 616#define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/
616 617
617#if 0
618/**
619 * struct ath5k_beacon_state - Per-station beacon timer state.
620 * @bs_interval: in TU's, can also include the above flags
621 * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a
622 * Point Coordination Function capable AP
623 */
624struct ath5k_beacon_state {
625 u32 bs_next_beacon;
626 u32 bs_next_dtim;
627 u32 bs_interval;
628 u8 bs_dtim_period;
629 u8 bs_cfp_period;
630 u16 bs_cfp_max_duration;
631 u16 bs_cfp_du_remain;
632 u16 bs_tim_offset;
633 u16 bs_sleep_duration;
634 u16 bs_bmiss_threshold;
635 u32 bs_cfp_next;
636};
637#endif
638
639 618
640/* 619/*
641 * TSF to TU conversion: 620 * TSF to TU conversion:
@@ -822,9 +801,9 @@ struct ath5k_athchan_2ghz {
822 * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold 801 * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
823 * We currently do increments on interrupt by 802 * We currently do increments on interrupt by
824 * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2 803 * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
825 * @AR5K_INT_MIB: Indicates the Management Information Base counters should be 804 * @AR5K_INT_MIB: Indicates the either Management Information Base counters or
826 * checked. We should do this with ath5k_hw_update_mib_counters() but 805 * one of the PHY error counters reached the maximum value and should be
827 * it seems we should also then do some noise immunity work. 806 * read and cleared.
828 * @AR5K_INT_RXPHY: RX PHY Error 807 * @AR5K_INT_RXPHY: RX PHY Error
829 * @AR5K_INT_RXKCM: RX Key cache miss 808 * @AR5K_INT_RXKCM: RX Key cache miss
830 * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a 809 * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
@@ -912,10 +891,11 @@ enum ath5k_int {
912 AR5K_INT_NOCARD = 0xffffffff 891 AR5K_INT_NOCARD = 0xffffffff
913}; 892};
914 893
915/* Software interrupts used for calibration */ 894/* mask which calibration is active at the moment */
916enum ath5k_software_interrupt { 895enum ath5k_calibration_mask {
917 AR5K_SWI_FULL_CALIBRATION = 0x01, 896 AR5K_CALIBRATION_FULL = 0x01,
918 AR5K_SWI_SHORT_CALIBRATION = 0x02, 897 AR5K_CALIBRATION_SHORT = 0x02,
898 AR5K_CALIBRATION_ANI = 0x04,
919}; 899};
920 900
921/* 901/*
@@ -1004,6 +984,8 @@ struct ath5k_capabilities {
1004 struct { 984 struct {
1005 u8 q_tx_num; 985 u8 q_tx_num;
1006 } cap_queues; 986 } cap_queues;
987
988 bool cap_has_phyerr_counters;
1007}; 989};
1008 990
1009/* size of noise floor history (keep it a power of two) */ 991/* size of noise floor history (keep it a power of two) */
@@ -1014,6 +996,15 @@ struct ath5k_nfcal_hist
1014 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ 996 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
1015}; 997};
1016 998
999/**
1000 * struct avg_val - Helper structure for average calculation
1001 * @avg: contains the actual average value
1002 * @avg_weight: is used internally during calculation to prevent rounding errors
1003 */
1004struct ath5k_avg_val {
1005 int avg;
1006 int avg_weight;
1007};
1017 1008
1018/***************************************\ 1009/***************************************\
1019 HARDWARE ABSTRACTION LAYER STRUCTURE 1010 HARDWARE ABSTRACTION LAYER STRUCTURE
@@ -1028,7 +1019,6 @@ struct ath5k_nfcal_hist
1028 1019
1029/* TODO: Clean up and merge with ath5k_softc */ 1020/* TODO: Clean up and merge with ath5k_softc */
1030struct ath5k_hw { 1021struct ath5k_hw {
1031 u32 ah_magic;
1032 struct ath_common common; 1022 struct ath_common common;
1033 1023
1034 struct ath5k_softc *ah_sc; 1024 struct ath5k_softc *ah_sc;
@@ -1036,7 +1026,6 @@ struct ath5k_hw {
1036 1026
1037 enum ath5k_int ah_imr; 1027 enum ath5k_int ah_imr;
1038 1028
1039 enum nl80211_iftype ah_op_mode;
1040 struct ieee80211_channel *ah_current_channel; 1029 struct ieee80211_channel *ah_current_channel;
1041 bool ah_turbo; 1030 bool ah_turbo;
1042 bool ah_calibration; 1031 bool ah_calibration;
@@ -1049,7 +1038,6 @@ struct ath5k_hw {
1049 u32 ah_phy; 1038 u32 ah_phy;
1050 u32 ah_mac_srev; 1039 u32 ah_mac_srev;
1051 u16 ah_mac_version; 1040 u16 ah_mac_version;
1052 u16 ah_mac_revision;
1053 u16 ah_phy_revision; 1041 u16 ah_phy_revision;
1054 u16 ah_radio_5ghz_revision; 1042 u16 ah_radio_5ghz_revision;
1055 u16 ah_radio_2ghz_revision; 1043 u16 ah_radio_2ghz_revision;
@@ -1071,8 +1059,6 @@ struct ath5k_hw {
1071 u8 ah_def_ant; 1059 u8 ah_def_ant;
1072 bool ah_software_retry; 1060 bool ah_software_retry;
1073 1061
1074 int ah_gpio_npins;
1075
1076 struct ath5k_capabilities ah_capabilities; 1062 struct ath5k_capabilities ah_capabilities;
1077 1063
1078 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; 1064 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES];
@@ -1123,17 +1109,18 @@ struct ath5k_hw {
1123 1109
1124 struct ath5k_nfcal_hist ah_nfcal_hist; 1110 struct ath5k_nfcal_hist ah_nfcal_hist;
1125 1111
1112 /* average beacon RSSI in our BSS (used by ANI) */
1113 struct ath5k_avg_val ah_beacon_rssi_avg;
1114
1126 /* noise floor from last periodic calibration */ 1115 /* noise floor from last periodic calibration */
1127 s32 ah_noise_floor; 1116 s32 ah_noise_floor;
1128 1117
1129 /* Calibration timestamp */ 1118 /* Calibration timestamp */
1130 unsigned long ah_cal_tstamp; 1119 unsigned long ah_cal_next_full;
1131 1120 unsigned long ah_cal_next_ani;
1132 /* Calibration interval (secs) */
1133 u8 ah_cal_intval;
1134 1121
1135 /* Software interrupt mask */ 1122 /* Calibration mask */
1136 u8 ah_swi_mask; 1123 u8 ah_cal_mask;
1137 1124
1138 /* 1125 /*
1139 * Function pointers 1126 * Function pointers
@@ -1141,9 +1128,9 @@ struct ath5k_hw {
1141 int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, 1128 int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
1142 u32 size, unsigned int flags); 1129 u32 size, unsigned int flags);
1143 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1130 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1144 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, 1131 unsigned int, unsigned int, int, enum ath5k_pkt_type,
1145 unsigned int, unsigned int, unsigned int, unsigned int, 1132 unsigned int, unsigned int, unsigned int, unsigned int,
1146 unsigned int, unsigned int, unsigned int); 1133 unsigned int, unsigned int, unsigned int, unsigned int);
1147 int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1134 int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1148 unsigned int, unsigned int, unsigned int, unsigned int, 1135 unsigned int, unsigned int, unsigned int, unsigned int,
1149 unsigned int, unsigned int); 1136 unsigned int, unsigned int);
@@ -1158,158 +1145,145 @@ struct ath5k_hw {
1158 */ 1145 */
1159 1146
1160/* Attach/Detach Functions */ 1147/* Attach/Detach Functions */
1161extern int ath5k_hw_attach(struct ath5k_softc *sc); 1148int ath5k_hw_attach(struct ath5k_softc *sc);
1162extern void ath5k_hw_detach(struct ath5k_hw *ah); 1149void ath5k_hw_detach(struct ath5k_hw *ah);
1163 1150
1164/* LED functions */ 1151/* LED functions */
1165extern int ath5k_init_leds(struct ath5k_softc *sc); 1152int ath5k_init_leds(struct ath5k_softc *sc);
1166extern void ath5k_led_enable(struct ath5k_softc *sc); 1153void ath5k_led_enable(struct ath5k_softc *sc);
1167extern void ath5k_led_off(struct ath5k_softc *sc); 1154void ath5k_led_off(struct ath5k_softc *sc);
1168extern void ath5k_unregister_leds(struct ath5k_softc *sc); 1155void ath5k_unregister_leds(struct ath5k_softc *sc);
1169 1156
1170/* Reset Functions */ 1157/* Reset Functions */
1171extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); 1158int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
1172extern int ath5k_hw_on_hold(struct ath5k_hw *ah); 1159int ath5k_hw_on_hold(struct ath5k_hw *ah);
1173extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel); 1160int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1161 struct ieee80211_channel *channel, bool change_channel);
1162int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
1163 bool is_set);
1174/* Power management functions */ 1164/* Power management functions */
1175extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
1176 1165
1177/* DMA Related Functions */ 1166/* DMA Related Functions */
1178extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); 1167void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
1179extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); 1168int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
1180extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); 1169u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
1181extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); 1170void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
1182extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1171int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1183extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1172int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1184extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); 1173u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
1185extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, 1174int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
1186 u32 phys_addr); 1175 u32 phys_addr);
1187extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); 1176int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
1188/* Interrupt handling */ 1177/* Interrupt handling */
1189extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); 1178bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
1190extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); 1179int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
1191extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum 1180enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
1192ath5k_int new_mask); 1181void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
1193extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
1194 1182
1195/* EEPROM access functions */ 1183/* EEPROM access functions */
1196extern int ath5k_eeprom_init(struct ath5k_hw *ah); 1184int ath5k_eeprom_init(struct ath5k_hw *ah);
1197extern void ath5k_eeprom_detach(struct ath5k_hw *ah); 1185void ath5k_eeprom_detach(struct ath5k_hw *ah);
1198extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); 1186int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1199extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1200 1187
1201/* Protocol Control Unit Functions */ 1188/* Protocol Control Unit Functions */
1202extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1189extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
1203extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); 1190void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1204/* BSSID Functions */ 1191/* BSSID Functions */
1205extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); 1192int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1206extern void ath5k_hw_set_associd(struct ath5k_hw *ah); 1193void ath5k_hw_set_associd(struct ath5k_hw *ah);
1207extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); 1194void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
1208/* Receive start/stop functions */ 1195/* Receive start/stop functions */
1209extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); 1196void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1210extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); 1197void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
1211/* RX Filter functions */ 1198/* RX Filter functions */
1212extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); 1199void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
1213extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1200u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1214extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1201void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1215extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1216extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1217/* Beacon control functions */ 1202/* Beacon control functions */
1218extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); 1203u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
1219extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); 1204void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
1220extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); 1205void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
1221extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); 1206void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1222extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1223#if 0
1224extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
1225extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
1226extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
1227#endif
1228/* ACK bit rate */ 1207/* ACK bit rate */
1229void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); 1208void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
1230/* ACK/CTS Timeouts */
1231extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
1232extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
1233extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
1234extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
1235/* Clock rate related functions */ 1209/* Clock rate related functions */
1236unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); 1210unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1237unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); 1211unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1238unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); 1212unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
1239/* Key table (WEP) functions */ 1213/* Key table (WEP) functions */
1240extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); 1214int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1241extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); 1215int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
1242extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac); 1216 const struct ieee80211_key_conf *key, const u8 *mac);
1243extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); 1217int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
1244 1218
1245/* Queue Control Unit, DFS Control Unit Functions */ 1219/* Queue Control Unit, DFS Control Unit Functions */
1246extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); 1220int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
1247extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, 1221 struct ath5k_txq_info *queue_info);
1248 const struct ath5k_txq_info *queue_info); 1222int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
1249extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, 1223 const struct ath5k_txq_info *queue_info);
1250 enum ath5k_tx_queue queue_type, 1224int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
1251 struct ath5k_txq_info *queue_info); 1225 enum ath5k_tx_queue queue_type,
1252extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); 1226 struct ath5k_txq_info *queue_info);
1253extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1227u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1254extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1228void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1255extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); 1229int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1256extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); 1230int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
1257 1231
1258/* Hardware Descriptor Functions */ 1232/* Hardware Descriptor Functions */
1259extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); 1233int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
1260 1234
1261/* GPIO Functions */ 1235/* GPIO Functions */
1262extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); 1236void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
1263extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); 1237int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
1264extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); 1238int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
1265extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); 1239u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
1266extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); 1240int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
1267extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); 1241void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
1242 u32 interrupt_level);
1268 1243
1269/* rfkill Functions */ 1244/* rfkill Functions */
1270extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); 1245void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
1271extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); 1246void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
1272 1247
1273/* Misc functions */ 1248/* Misc functions */
1274int ath5k_hw_set_capabilities(struct ath5k_hw *ah); 1249int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
1275extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); 1250int ath5k_hw_get_capability(struct ath5k_hw *ah,
1276extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); 1251 enum ath5k_capability_type cap_type, u32 capability,
1277extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); 1252 u32 *result);
1253int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
1254int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
1278 1255
1279/* Initial register settings functions */ 1256/* Initial register settings functions */
1280extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); 1257int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1281 1258
1282/* Initialize RF */ 1259/* Initialize RF */
1283extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah, 1260int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
1284 struct ieee80211_channel *channel, 1261 struct ieee80211_channel *channel,
1285 unsigned int mode); 1262 unsigned int mode);
1286extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); 1263int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
1287extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); 1264enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
1288extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); 1265int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
1289/* PHY/RF channel functions */ 1266/* PHY/RF channel functions */
1290extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1267bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1291extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1268int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1292/* PHY calibration */ 1269/* PHY calibration */
1293void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); 1270void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1294extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1271int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1295extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); 1272 struct ieee80211_channel *channel);
1296extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah);
1297extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
1298/* Spur mitigation */ 1273/* Spur mitigation */
1299bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1274bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
1300 struct ieee80211_channel *channel); 1275 struct ieee80211_channel *channel);
1301void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, 1276void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1302 struct ieee80211_channel *channel); 1277 struct ieee80211_channel *channel);
1303/* Misc PHY functions */ 1278/* Misc PHY functions */
1304extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); 1279u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1305extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1280int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1306/* Antenna control */ 1281/* Antenna control */
1307extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); 1282void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
1308extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
1309extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1310/* TX power setup */ 1283/* TX power setup */
1311extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); 1284int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1312extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); 1285 u8 ee_mode, u8 txpower);
1286int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1313 1287
1314/* 1288/*
1315 * Functions used internaly 1289 * Functions used internaly
@@ -1335,29 +1309,6 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1335 iowrite32(val, ah->ah_iobase + reg); 1309 iowrite32(val, ah->ah_iobase + reg);
1336} 1310}
1337 1311
1338#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
1339/*
1340 * Check if a register write has been completed
1341 */
1342static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag,
1343 u32 val, bool is_set)
1344{
1345 int i;
1346 u32 data;
1347
1348 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
1349 data = ath5k_hw_reg_read(ah, reg);
1350 if (is_set && (data & flag))
1351 break;
1352 else if ((data & flag) == val)
1353 break;
1354 udelay(15);
1355 }
1356
1357 return (i <= 0) ? -EAGAIN : 0;
1358}
1359#endif
1360
1361static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) 1312static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1362{ 1313{
1363 u32 retval = 0, bit, i; 1314 u32 retval = 0, bit, i;
@@ -1370,9 +1321,27 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1370 return retval; 1321 return retval;
1371} 1322}
1372 1323
1373static inline int ath5k_pad_size(int hdrlen) 1324#define AVG_SAMPLES 8
1325#define AVG_FACTOR 1000
1326
1327/**
1328 * ath5k_moving_average - Exponentially weighted moving average
1329 * @avg: average structure
1330 * @val: current value
1331 *
1332 * This implementation make use of a struct ath5k_avg_val to prevent rounding
1333 * errors.
1334 */
1335static inline struct ath5k_avg_val
1336ath5k_moving_average(const struct ath5k_avg_val avg, const int val)
1374{ 1337{
1375 return (hdrlen < 24) ? 0 : hdrlen & 3; 1338 struct ath5k_avg_val new;
1339 new.avg_weight = avg.avg_weight ?
1340 (((avg.avg_weight * ((AVG_SAMPLES) - 1)) +
1341 (val * (AVG_FACTOR))) / (AVG_SAMPLES)) :
1342 (val * (AVG_FACTOR));
1343 new.avg = new.avg_weight / (AVG_FACTOR);
1344 return new;
1376} 1345}
1377 1346
1378#endif 1347#endif
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 42284445b75e..dcf7c30f813f 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -113,7 +113,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
113 /* 113 /*
114 * HW information 114 * HW information
115 */ 115 */
116 ah->ah_op_mode = NL80211_IFTYPE_STATION;
117 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; 116 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
118 ah->ah_turbo = false; 117 ah->ah_turbo = false;
119 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; 118 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
@@ -123,6 +122,9 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
123 ah->ah_cw_min = AR5K_TUNE_CWMIN; 122 ah->ah_cw_min = AR5K_TUNE_CWMIN;
124 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; 123 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
125 ah->ah_software_retry = false; 124 ah->ah_software_retry = false;
125 ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
126 ah->ah_noise_floor = -95; /* until first NF calibration is run */
127 sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
126 128
127 /* 129 /*
128 * Find the mac version 130 * Find the mac version
@@ -148,7 +150,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
148 /* Get MAC, PHY and RADIO revisions */ 150 /* Get MAC, PHY and RADIO revisions */
149 ah->ah_mac_srev = srev; 151 ah->ah_mac_srev = srev;
150 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); 152 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
151 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
152 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & 153 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
153 0xffffffff; 154 0xffffffff;
154 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, 155 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
@@ -327,7 +328,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
327 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ 328 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
328 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); 329 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
329 ath5k_hw_set_associd(ah); 330 ath5k_hw_set_associd(ah);
330 ath5k_hw_set_opmode(ah); 331 ath5k_hw_set_opmode(ah, sc->opmode);
331 332
332 ath5k_hw_rfgain_opt_init(ah); 333 ath5k_hw_rfgain_opt_init(ah);
333 334
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 8dce0077b023..c085a06f1e05 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -58,8 +58,8 @@
58#include "base.h" 58#include "base.h"
59#include "reg.h" 59#include "reg.h"
60#include "debug.h" 60#include "debug.h"
61#include "ani.h"
61 62
62static u8 ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
63static int modparam_nohwcrypt; 63static int modparam_nohwcrypt;
64module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 64module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
65MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 65MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -198,7 +198,7 @@ static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
198static int ath5k_pci_suspend(struct device *dev); 198static int ath5k_pci_suspend(struct device *dev);
199static int ath5k_pci_resume(struct device *dev); 199static int ath5k_pci_resume(struct device *dev);
200 200
201SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); 201static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
202#define ATH5K_PM_OPS (&ath5k_pm_ops) 202#define ATH5K_PM_OPS (&ath5k_pm_ops)
203#else 203#else
204#define ATH5K_PM_OPS NULL 204#define ATH5K_PM_OPS NULL
@@ -307,7 +307,7 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
307 struct ath5k_buf *bf); 307 struct ath5k_buf *bf);
308static int ath5k_txbuf_setup(struct ath5k_softc *sc, 308static int ath5k_txbuf_setup(struct ath5k_softc *sc,
309 struct ath5k_buf *bf, 309 struct ath5k_buf *bf,
310 struct ath5k_txq *txq); 310 struct ath5k_txq *txq, int padsize);
311static inline void ath5k_txbuf_free(struct ath5k_softc *sc, 311static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
312 struct ath5k_buf *bf) 312 struct ath5k_buf *bf)
313{ 313{
@@ -364,6 +364,7 @@ static void ath5k_beacon_send(struct ath5k_softc *sc);
364static void ath5k_beacon_config(struct ath5k_softc *sc); 364static void ath5k_beacon_config(struct ath5k_softc *sc);
365static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); 365static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
366static void ath5k_tasklet_beacon(unsigned long data); 366static void ath5k_tasklet_beacon(unsigned long data);
367static void ath5k_tasklet_ani(unsigned long data);
367 368
368static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) 369static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
369{ 370{
@@ -829,6 +830,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
829 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); 830 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
830 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); 831 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
831 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); 832 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
833 tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
832 834
833 ret = ath5k_eeprom_read_mac(ah, mac); 835 ret = ath5k_eeprom_read_mac(ah, mac);
834 if (ret) { 836 if (ret) {
@@ -1137,8 +1139,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1137 struct ath5k_hw *ah = sc->ah; 1139 struct ath5k_hw *ah = sc->ah;
1138 u32 rfilt; 1140 u32 rfilt;
1139 1141
1140 ah->ah_op_mode = sc->opmode;
1141
1142 /* configure rx filter */ 1142 /* configure rx filter */
1143 rfilt = sc->filter_flags; 1143 rfilt = sc->filter_flags;
1144 ath5k_hw_set_rx_filter(ah, rfilt); 1144 ath5k_hw_set_rx_filter(ah, rfilt);
@@ -1147,8 +1147,9 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1147 ath5k_hw_set_bssid_mask(ah, sc->bssidmask); 1147 ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
1148 1148
1149 /* configure operational mode */ 1149 /* configure operational mode */
1150 ath5k_hw_set_opmode(ah); 1150 ath5k_hw_set_opmode(ah, sc->opmode);
1151 1151
1152 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
1152 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); 1153 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
1153} 1154}
1154 1155
@@ -1271,7 +1272,7 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1271 1272
1272static int 1273static int
1273ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1274ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1274 struct ath5k_txq *txq) 1275 struct ath5k_txq *txq, int padsize)
1275{ 1276{
1276 struct ath5k_hw *ah = sc->ah; 1277 struct ath5k_hw *ah = sc->ah;
1277 struct ath5k_desc *ds = bf->desc; 1278 struct ath5k_desc *ds = bf->desc;
@@ -1323,7 +1324,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1323 sc->vif, pktlen, info)); 1324 sc->vif, pktlen, info));
1324 } 1325 }
1325 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1326 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1326 ieee80211_get_hdrlen_from_skb(skb), 1327 ieee80211_get_hdrlen_from_skb(skb), padsize,
1327 get_hw_packet_type(skb), 1328 get_hw_packet_type(skb),
1328 (sc->power_level * 2), 1329 (sc->power_level * 2),
1329 hw_rate, 1330 hw_rate,
@@ -1806,6 +1807,86 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1806} 1807}
1807 1808
1808static void 1809static void
1810ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
1811{
1812 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1813 struct ath5k_hw *ah = sc->ah;
1814 struct ath_common *common = ath5k_hw_common(ah);
1815
1816 /* only beacons from our BSSID */
1817 if (!ieee80211_is_beacon(mgmt->frame_control) ||
1818 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
1819 return;
1820
1821 ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg,
1822 rssi);
1823
1824 /* in IBSS mode we should keep RSSI statistics per neighbour */
1825 /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
1826}
1827
1828/*
1829 * Compute padding position. skb must contains an IEEE 802.11 frame
1830 */
1831static int ath5k_common_padpos(struct sk_buff *skb)
1832{
1833 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
1834 __le16 frame_control = hdr->frame_control;
1835 int padpos = 24;
1836
1837 if (ieee80211_has_a4(frame_control)) {
1838 padpos += ETH_ALEN;
1839 }
1840 if (ieee80211_is_data_qos(frame_control)) {
1841 padpos += IEEE80211_QOS_CTL_LEN;
1842 }
1843
1844 return padpos;
1845}
1846
1847/*
1848 * This function expects a 802.11 frame and returns the number of
1849 * bytes added, or -1 if we don't have enought header room.
1850 */
1851
1852static int ath5k_add_padding(struct sk_buff *skb)
1853{
1854 int padpos = ath5k_common_padpos(skb);
1855 int padsize = padpos & 3;
1856
1857 if (padsize && skb->len>padpos) {
1858
1859 if (skb_headroom(skb) < padsize)
1860 return -1;
1861
1862 skb_push(skb, padsize);
1863 memmove(skb->data, skb->data+padsize, padpos);
1864 return padsize;
1865 }
1866
1867 return 0;
1868}
1869
1870/*
1871 * This function expects a 802.11 frame and returns the number of
1872 * bytes removed
1873 */
1874
1875static int ath5k_remove_padding(struct sk_buff *skb)
1876{
1877 int padpos = ath5k_common_padpos(skb);
1878 int padsize = padpos & 3;
1879
1880 if (padsize && skb->len>=padpos+padsize) {
1881 memmove(skb->data + padsize, skb->data, padpos);
1882 skb_pull(skb, padsize);
1883 return padsize;
1884 }
1885
1886 return 0;
1887}
1888
1889static void
1809ath5k_tasklet_rx(unsigned long data) 1890ath5k_tasklet_rx(unsigned long data)
1810{ 1891{
1811 struct ieee80211_rx_status *rxs; 1892 struct ieee80211_rx_status *rxs;
@@ -1818,8 +1899,6 @@ ath5k_tasklet_rx(unsigned long data)
1818 struct ath5k_buf *bf; 1899 struct ath5k_buf *bf;
1819 struct ath5k_desc *ds; 1900 struct ath5k_desc *ds;
1820 int ret; 1901 int ret;
1821 int hdrlen;
1822 int padsize;
1823 int rx_flag; 1902 int rx_flag;
1824 1903
1825 spin_lock(&sc->rxbuflock); 1904 spin_lock(&sc->rxbuflock);
@@ -1844,18 +1923,30 @@ ath5k_tasklet_rx(unsigned long data)
1844 break; 1923 break;
1845 else if (unlikely(ret)) { 1924 else if (unlikely(ret)) {
1846 ATH5K_ERR(sc, "error in processing rx descriptor\n"); 1925 ATH5K_ERR(sc, "error in processing rx descriptor\n");
1926 sc->stats.rxerr_proc++;
1847 spin_unlock(&sc->rxbuflock); 1927 spin_unlock(&sc->rxbuflock);
1848 return; 1928 return;
1849 } 1929 }
1850 1930
1931 sc->stats.rx_all_count++;
1932
1851 if (unlikely(rs.rs_more)) { 1933 if (unlikely(rs.rs_more)) {
1852 ATH5K_WARN(sc, "unsupported jumbo\n"); 1934 ATH5K_WARN(sc, "unsupported jumbo\n");
1935 sc->stats.rxerr_jumbo++;
1853 goto next; 1936 goto next;
1854 } 1937 }
1855 1938
1856 if (unlikely(rs.rs_status)) { 1939 if (unlikely(rs.rs_status)) {
1857 if (rs.rs_status & AR5K_RXERR_PHY) 1940 if (rs.rs_status & AR5K_RXERR_CRC)
1941 sc->stats.rxerr_crc++;
1942 if (rs.rs_status & AR5K_RXERR_FIFO)
1943 sc->stats.rxerr_fifo++;
1944 if (rs.rs_status & AR5K_RXERR_PHY) {
1945 sc->stats.rxerr_phy++;
1946 if (rs.rs_phyerr > 0 && rs.rs_phyerr < 32)
1947 sc->stats.rxerr_phy_code[rs.rs_phyerr]++;
1858 goto next; 1948 goto next;
1949 }
1859 if (rs.rs_status & AR5K_RXERR_DECRYPT) { 1950 if (rs.rs_status & AR5K_RXERR_DECRYPT) {
1860 /* 1951 /*
1861 * Decrypt error. If the error occurred 1952 * Decrypt error. If the error occurred
@@ -1867,12 +1958,14 @@ ath5k_tasklet_rx(unsigned long data)
1867 * 1958 *
1868 * XXX do key cache faulting 1959 * XXX do key cache faulting
1869 */ 1960 */
1961 sc->stats.rxerr_decrypt++;
1870 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && 1962 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
1871 !(rs.rs_status & AR5K_RXERR_CRC)) 1963 !(rs.rs_status & AR5K_RXERR_CRC))
1872 goto accept; 1964 goto accept;
1873 } 1965 }
1874 if (rs.rs_status & AR5K_RXERR_MIC) { 1966 if (rs.rs_status & AR5K_RXERR_MIC) {
1875 rx_flag |= RX_FLAG_MMIC_ERROR; 1967 rx_flag |= RX_FLAG_MMIC_ERROR;
1968 sc->stats.rxerr_mic++;
1876 goto accept; 1969 goto accept;
1877 } 1970 }
1878 1971
@@ -1904,12 +1997,8 @@ accept:
1904 * bytes and we can optimize this a bit. In addition, we must 1997 * bytes and we can optimize this a bit. In addition, we must
1905 * not try to remove padding from short control frames that do 1998 * not try to remove padding from short control frames that do
1906 * not have payload. */ 1999 * not have payload. */
1907 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2000 ath5k_remove_padding(skb);
1908 padsize = ath5k_pad_size(hdrlen); 2001
1909 if (padsize) {
1910 memmove(skb->data + padsize, skb->data, hdrlen);
1911 skb_pull(skb, padsize);
1912 }
1913 rxs = IEEE80211_SKB_RXCB(skb); 2002 rxs = IEEE80211_SKB_RXCB(skb);
1914 2003
1915 /* 2004 /*
@@ -1942,6 +2031,12 @@ accept:
1942 rxs->signal = rxs->noise + rs.rs_rssi; 2031 rxs->signal = rxs->noise + rs.rs_rssi;
1943 2032
1944 rxs->antenna = rs.rs_antenna; 2033 rxs->antenna = rs.rs_antenna;
2034
2035 if (rs.rs_antenna > 0 && rs.rs_antenna < 5)
2036 sc->stats.antenna_rx[rs.rs_antenna]++;
2037 else
2038 sc->stats.antenna_rx[0]++; /* invalid */
2039
1945 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); 2040 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
1946 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); 2041 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
1947 2042
@@ -1951,6 +2046,8 @@ accept:
1951 2046
1952 ath5k_debug_dump_skb(sc, skb, "RX ", 0); 2047 ath5k_debug_dump_skb(sc, skb, "RX ", 0);
1953 2048
2049 ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi);
2050
1954 /* check beacons in IBSS mode */ 2051 /* check beacons in IBSS mode */
1955 if (sc->opmode == NL80211_IFTYPE_ADHOC) 2052 if (sc->opmode == NL80211_IFTYPE_ADHOC)
1956 ath5k_check_ibss_tsf(sc, skb, rxs); 2053 ath5k_check_ibss_tsf(sc, skb, rxs);
@@ -1996,6 +2093,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1996 break; 2093 break;
1997 } 2094 }
1998 2095
2096 sc->stats.tx_all_count++;
1999 skb = bf->skb; 2097 skb = bf->skb;
2000 info = IEEE80211_SKB_CB(skb); 2098 info = IEEE80211_SKB_CB(skb);
2001 bf->skb = NULL; 2099 bf->skb = NULL;
@@ -2021,14 +2119,31 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
2021 info->status.rates[ts.ts_final_idx].count++; 2119 info->status.rates[ts.ts_final_idx].count++;
2022 2120
2023 if (unlikely(ts.ts_status)) { 2121 if (unlikely(ts.ts_status)) {
2024 sc->ll_stats.dot11ACKFailureCount++; 2122 sc->stats.ack_fail++;
2025 if (ts.ts_status & AR5K_TXERR_FILT) 2123 if (ts.ts_status & AR5K_TXERR_FILT) {
2026 info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 2124 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
2125 sc->stats.txerr_filt++;
2126 }
2127 if (ts.ts_status & AR5K_TXERR_XRETRY)
2128 sc->stats.txerr_retry++;
2129 if (ts.ts_status & AR5K_TXERR_FIFO)
2130 sc->stats.txerr_fifo++;
2027 } else { 2131 } else {
2028 info->flags |= IEEE80211_TX_STAT_ACK; 2132 info->flags |= IEEE80211_TX_STAT_ACK;
2029 info->status.ack_signal = ts.ts_rssi; 2133 info->status.ack_signal = ts.ts_rssi;
2030 } 2134 }
2031 2135
2136 /*
2137 * Remove MAC header padding before giving the frame
2138 * back to mac80211.
2139 */
2140 ath5k_remove_padding(skb);
2141
2142 if (ts.ts_antenna > 0 && ts.ts_antenna < 5)
2143 sc->stats.antenna_tx[ts.ts_antenna]++;
2144 else
2145 sc->stats.antenna_tx[0]++; /* invalid */
2146
2032 ieee80211_tx_status(sc->hw, skb); 2147 ieee80211_tx_status(sc->hw, skb);
2033 2148
2034 spin_lock(&sc->txbuflock); 2149 spin_lock(&sc->txbuflock);
@@ -2072,6 +2187,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2072 int ret = 0; 2187 int ret = 0;
2073 u8 antenna; 2188 u8 antenna;
2074 u32 flags; 2189 u32 flags;
2190 const int padsize = 0;
2075 2191
2076 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 2192 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
2077 PCI_DMA_TODEVICE); 2193 PCI_DMA_TODEVICE);
@@ -2119,7 +2235,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2119 * from tx power (value is in dB units already) */ 2235 * from tx power (value is in dB units already) */
2120 ds->ds_data = bf->skbaddr; 2236 ds->ds_data = bf->skbaddr;
2121 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 2237 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
2122 ieee80211_get_hdrlen_from_skb(skb), 2238 ieee80211_get_hdrlen_from_skb(skb), padsize,
2123 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), 2239 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
2124 ieee80211_get_tx_rate(sc->hw, info)->hw_value, 2240 ieee80211_get_tx_rate(sc->hw, info)->hw_value,
2125 1, AR5K_TXKEYIX_INVALID, 2241 1, AR5K_TXKEYIX_INVALID,
@@ -2406,9 +2522,6 @@ ath5k_init(struct ath5k_softc *sc)
2406 */ 2522 */
2407 ath5k_stop_locked(sc); 2523 ath5k_stop_locked(sc);
2408 2524
2409 /* Set PHY calibration interval */
2410 ah->ah_cal_intval = ath5k_calinterval;
2411
2412 /* 2525 /*
2413 * The basic interface to setting the hardware in a good 2526 * The basic interface to setting the hardware in a good
2414 * state is ``reset''. On return the hardware is known to 2527 * state is ``reset''. On return the hardware is known to
@@ -2420,7 +2533,8 @@ ath5k_init(struct ath5k_softc *sc)
2420 sc->curband = &sc->sbands[sc->curchan->band]; 2533 sc->curband = &sc->sbands[sc->curchan->band];
2421 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | 2534 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
2422 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | 2535 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2423 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI; 2536 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
2537
2424 ret = ath5k_reset(sc, NULL); 2538 ret = ath5k_reset(sc, NULL);
2425 if (ret) 2539 if (ret)
2426 goto done; 2540 goto done;
@@ -2532,12 +2646,33 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2532 tasklet_kill(&sc->restq); 2646 tasklet_kill(&sc->restq);
2533 tasklet_kill(&sc->calib); 2647 tasklet_kill(&sc->calib);
2534 tasklet_kill(&sc->beacontq); 2648 tasklet_kill(&sc->beacontq);
2649 tasklet_kill(&sc->ani_tasklet);
2535 2650
2536 ath5k_rfkill_hw_stop(sc->ah); 2651 ath5k_rfkill_hw_stop(sc->ah);
2537 2652
2538 return ret; 2653 return ret;
2539} 2654}
2540 2655
2656static void
2657ath5k_intr_calibration_poll(struct ath5k_hw *ah)
2658{
2659 if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) &&
2660 !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL)) {
2661 /* run ANI only when full calibration is not active */
2662 ah->ah_cal_next_ani = jiffies +
2663 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI);
2664 tasklet_schedule(&ah->ah_sc->ani_tasklet);
2665
2666 } else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) {
2667 ah->ah_cal_next_full = jiffies +
2668 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL);
2669 tasklet_schedule(&ah->ah_sc->calib);
2670 }
2671 /* we could use SWI to generate enough interrupts to meet our
2672 * calibration interval requirements, if necessary:
2673 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
2674}
2675
2541static irqreturn_t 2676static irqreturn_t
2542ath5k_intr(int irq, void *dev_id) 2677ath5k_intr(int irq, void *dev_id)
2543{ 2678{
@@ -2586,15 +2721,10 @@ ath5k_intr(int irq, void *dev_id)
2586 if (status & AR5K_INT_BMISS) { 2721 if (status & AR5K_INT_BMISS) {
2587 /* TODO */ 2722 /* TODO */
2588 } 2723 }
2589 if (status & AR5K_INT_SWI) {
2590 tasklet_schedule(&sc->calib);
2591 }
2592 if (status & AR5K_INT_MIB) { 2724 if (status & AR5K_INT_MIB) {
2593 /* 2725 sc->stats.mib_intr++;
2594 * These stats are also used for ANI i think 2726 ath5k_hw_update_mib_counters(ah);
2595 * so how about updating them more often ? 2727 ath5k_ani_mib_intr(ah);
2596 */
2597 ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
2598 } 2728 }
2599 if (status & AR5K_INT_GPIO) 2729 if (status & AR5K_INT_GPIO)
2600 tasklet_schedule(&sc->rf_kill.toggleq); 2730 tasklet_schedule(&sc->rf_kill.toggleq);
@@ -2605,7 +2735,7 @@ ath5k_intr(int irq, void *dev_id)
2605 if (unlikely(!counter)) 2735 if (unlikely(!counter))
2606 ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); 2736 ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
2607 2737
2608 ath5k_hw_calibration_poll(ah); 2738 ath5k_intr_calibration_poll(ah);
2609 2739
2610 return IRQ_HANDLED; 2740 return IRQ_HANDLED;
2611} 2741}
@@ -2629,8 +2759,7 @@ ath5k_tasklet_calibrate(unsigned long data)
2629 struct ath5k_hw *ah = sc->ah; 2759 struct ath5k_hw *ah = sc->ah;
2630 2760
2631 /* Only full calibration for now */ 2761 /* Only full calibration for now */
2632 if (ah->ah_swi_mask != AR5K_SWI_FULL_CALIBRATION) 2762 ah->ah_cal_mask |= AR5K_CALIBRATION_FULL;
2633 return;
2634 2763
2635 /* Stop queues so that calibration 2764 /* Stop queues so that calibration
2636 * doesn't interfere with tx */ 2765 * doesn't interfere with tx */
@@ -2653,11 +2782,22 @@ ath5k_tasklet_calibrate(unsigned long data)
2653 ieee80211_frequency_to_channel( 2782 ieee80211_frequency_to_channel(
2654 sc->curchan->center_freq)); 2783 sc->curchan->center_freq));
2655 2784
2656 ah->ah_swi_mask = 0;
2657
2658 /* Wake queues */ 2785 /* Wake queues */
2659 ieee80211_wake_queues(sc->hw); 2786 ieee80211_wake_queues(sc->hw);
2660 2787
2788 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
2789}
2790
2791
2792static void
2793ath5k_tasklet_ani(unsigned long data)
2794{
2795 struct ath5k_softc *sc = (void *)data;
2796 struct ath5k_hw *ah = sc->ah;
2797
2798 ah->ah_cal_mask |= AR5K_CALIBRATION_ANI;
2799 ath5k_ani_calibration(ah);
2800 ah->ah_cal_mask &= ~AR5K_CALIBRATION_ANI;
2661} 2801}
2662 2802
2663 2803
@@ -2679,7 +2819,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2679 struct ath5k_softc *sc = hw->priv; 2819 struct ath5k_softc *sc = hw->priv;
2680 struct ath5k_buf *bf; 2820 struct ath5k_buf *bf;
2681 unsigned long flags; 2821 unsigned long flags;
2682 int hdrlen;
2683 int padsize; 2822 int padsize;
2684 2823
2685 ath5k_debug_dump_skb(sc, skb, "TX ", 1); 2824 ath5k_debug_dump_skb(sc, skb, "TX ", 1);
@@ -2691,17 +2830,11 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2691 * the hardware expects the header padded to 4 byte boundaries 2830 * the hardware expects the header padded to 4 byte boundaries
2692 * if this is not the case we add the padding after the header 2831 * if this is not the case we add the padding after the header
2693 */ 2832 */
2694 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2833 padsize = ath5k_add_padding(skb);
2695 padsize = ath5k_pad_size(hdrlen); 2834 if (padsize < 0) {
2696 if (padsize) { 2835 ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
2697 2836 " headroom to pad");
2698 if (skb_headroom(skb) < padsize) { 2837 goto drop_packet;
2699 ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
2700 " headroom to pad %d\n", hdrlen, padsize);
2701 goto drop_packet;
2702 }
2703 skb_push(skb, padsize);
2704 memmove(skb->data, skb->data+padsize, hdrlen);
2705 } 2838 }
2706 2839
2707 spin_lock_irqsave(&sc->txbuflock, flags); 2840 spin_lock_irqsave(&sc->txbuflock, flags);
@@ -2720,7 +2853,7 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2720 2853
2721 bf->skb = skb; 2854 bf->skb = skb;
2722 2855
2723 if (ath5k_txbuf_setup(sc, bf, txq)) { 2856 if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
2724 bf->skb = NULL; 2857 bf->skb = NULL;
2725 spin_lock_irqsave(&sc->txbuflock, flags); 2858 spin_lock_irqsave(&sc->txbuflock, flags);
2726 list_add_tail(&bf->list, &sc->txbuf); 2859 list_add_tail(&bf->list, &sc->txbuf);
@@ -2767,6 +2900,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
2767 goto err; 2900 goto err;
2768 } 2901 }
2769 2902
2903 ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode);
2904
2770 /* 2905 /*
2771 * Change channels and update the h/w rate map if we're switching; 2906 * Change channels and update the h/w rate map if we're switching;
2772 * e.g. 11a to 11b/g. 2907 * e.g. 11a to 11b/g.
@@ -2835,6 +2970,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2835 goto end; 2970 goto end;
2836 } 2971 }
2837 2972
2973 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode);
2974
2838 ath5k_hw_set_lladdr(sc->ah, vif->addr); 2975 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2839 ath5k_mode_setup(sc); 2976 ath5k_mode_setup(sc);
2840 2977
@@ -2905,7 +3042,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2905 * then we must allow the user to set how many tx antennas we 3042 * then we must allow the user to set how many tx antennas we
2906 * have available 3043 * have available
2907 */ 3044 */
2908 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 3045 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
2909 3046
2910unlock: 3047unlock:
2911 mutex_unlock(&sc->lock); 3048 mutex_unlock(&sc->lock);
@@ -3123,12 +3260,14 @@ ath5k_get_stats(struct ieee80211_hw *hw,
3123 struct ieee80211_low_level_stats *stats) 3260 struct ieee80211_low_level_stats *stats)
3124{ 3261{
3125 struct ath5k_softc *sc = hw->priv; 3262 struct ath5k_softc *sc = hw->priv;
3126 struct ath5k_hw *ah = sc->ah;
3127 3263
3128 /* Force update */ 3264 /* Force update */
3129 ath5k_hw_update_mib_counters(ah, &sc->ll_stats); 3265 ath5k_hw_update_mib_counters(sc->ah);
3130 3266
3131 memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats)); 3267 stats->dot11ACKFailureCount = sc->stats.ack_fail;
3268 stats->dot11RTSFailureCount = sc->stats.rts_fail;
3269 stats->dot11RTSSuccessCount = sc->stats.rts_ok;
3270 stats->dot11FCSErrorCount = sc->stats.fcs_error;
3132 3271
3133 return 0; 3272 return 0;
3134} 3273}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 7e1a88a5abdb..53a5651c57a2 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -50,6 +50,7 @@
50 50
51#include "ath5k.h" 51#include "ath5k.h"
52#include "debug.h" 52#include "debug.h"
53#include "ani.h"
53 54
54#include "../regd.h" 55#include "../regd.h"
55#include "../ath.h" 56#include "../ath.h"
@@ -105,6 +106,37 @@ struct ath5k_rfkill {
105 struct tasklet_struct toggleq; 106 struct tasklet_struct toggleq;
106}; 107};
107 108
109/* statistics */
110struct ath5k_statistics {
111 /* antenna use */
112 unsigned int antenna_rx[5]; /* frames count per antenna RX */
113 unsigned int antenna_tx[5]; /* frames count per antenna TX */
114
115 /* frame errors */
116 unsigned int rx_all_count; /* all RX frames, including errors */
117 unsigned int tx_all_count; /* all TX frames, including errors */
118 unsigned int rxerr_crc;
119 unsigned int rxerr_phy;
120 unsigned int rxerr_phy_code[32];
121 unsigned int rxerr_fifo;
122 unsigned int rxerr_decrypt;
123 unsigned int rxerr_mic;
124 unsigned int rxerr_proc;
125 unsigned int rxerr_jumbo;
126 unsigned int txerr_retry;
127 unsigned int txerr_fifo;
128 unsigned int txerr_filt;
129
130 /* MIB counters */
131 unsigned int ack_fail;
132 unsigned int rts_fail;
133 unsigned int rts_ok;
134 unsigned int fcs_error;
135 unsigned int beacons;
136
137 unsigned int mib_intr;
138};
139
108#if CHAN_DEBUG 140#if CHAN_DEBUG
109#define ATH_CHAN_MAX (26+26+26+200+200) 141#define ATH_CHAN_MAX (26+26+26+200+200)
110#else 142#else
@@ -117,7 +149,6 @@ struct ath5k_softc {
117 struct pci_dev *pdev; /* for dma mapping */ 149 struct pci_dev *pdev; /* for dma mapping */
118 void __iomem *iobase; /* address of the device */ 150 void __iomem *iobase; /* address of the device */
119 struct mutex lock; /* dev-level lock */ 151 struct mutex lock; /* dev-level lock */
120 struct ieee80211_low_level_stats ll_stats;
121 struct ieee80211_hw *hw; /* IEEE 802.11 common */ 152 struct ieee80211_hw *hw; /* IEEE 802.11 common */
122 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 153 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
123 struct ieee80211_channel channels[ATH_CHAN_MAX]; 154 struct ieee80211_channel channels[ATH_CHAN_MAX];
@@ -191,6 +222,11 @@ struct ath5k_softc {
191 int power_level; /* Requested tx power in dbm */ 222 int power_level; /* Requested tx power in dbm */
192 bool assoc; /* associate state */ 223 bool assoc; /* associate state */
193 bool enable_beacon; /* true if beacons are on */ 224 bool enable_beacon; /* true if beacons are on */
225
226 struct ath5k_statistics stats;
227
228 struct ath5k_ani_state ani_state;
229 struct tasklet_struct ani_tasklet; /* ANI calibration */
194}; 230};
195 231
196#define ath5k_hw_hasbssidmask(_ah) \ 232#define ath5k_hw_hasbssidmask(_ah) \
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index 367a6c7d3cc7..74f007126f41 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -102,9 +102,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
102 } 102 }
103 } 103 }
104 104
105 /* GPIO */
106 ah->ah_gpio_npins = AR5K_NUM_GPIO;
107
108 /* Set number of supported TX queues */ 105 /* Set number of supported TX queues */
109 if (ah->ah_version == AR5K_AR5210) 106 if (ah->ah_version == AR5K_AR5210)
110 ah->ah_capabilities.cap_queues.q_tx_num = 107 ah->ah_capabilities.cap_queues.q_tx_num =
@@ -112,6 +109,12 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
112 else 109 else
113 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; 110 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
114 111
112 /* newer hardware has PHY error counters */
113 if (ah->ah_mac_srev >= AR5K_SREV_AR5213A)
114 ah->ah_capabilities.cap_has_phyerr_counters = true;
115 else
116 ah->ah_capabilities.cap_has_phyerr_counters = false;
117
115 return 0; 118 return 0;
116} 119}
117 120
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 747508c15d34..6fb5c5ffa5b1 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -69,6 +69,7 @@ module_param_named(debug, ath5k_debug, uint, 0);
69 69
70#include <linux/seq_file.h> 70#include <linux/seq_file.h>
71#include "reg.h" 71#include "reg.h"
72#include "ani.h"
72 73
73static struct dentry *ath5k_global_debugfs; 74static struct dentry *ath5k_global_debugfs;
74 75
@@ -307,6 +308,7 @@ static const struct {
307 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, 308 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
308 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, 309 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
309 { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, 310 { ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
311 { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
310 { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, 312 { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
311}; 313};
312 314
@@ -364,6 +366,369 @@ static const struct file_operations fops_debug = {
364}; 366};
365 367
366 368
369/* debugfs: antenna */
370
371static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
372 size_t count, loff_t *ppos)
373{
374 struct ath5k_softc *sc = file->private_data;
375 char buf[700];
376 unsigned int len = 0;
377 unsigned int i;
378 unsigned int v;
379
380 len += snprintf(buf+len, sizeof(buf)-len, "antenna mode\t%d\n",
381 sc->ah->ah_ant_mode);
382 len += snprintf(buf+len, sizeof(buf)-len, "default antenna\t%d\n",
383 sc->ah->ah_def_ant);
384 len += snprintf(buf+len, sizeof(buf)-len, "tx antenna\t%d\n",
385 sc->ah->ah_tx_ant);
386
387 len += snprintf(buf+len, sizeof(buf)-len, "\nANTENNA\t\tRX\tTX\n");
388 for (i = 1; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
389 len += snprintf(buf+len, sizeof(buf)-len,
390 "[antenna %d]\t%d\t%d\n",
391 i, sc->stats.antenna_rx[i], sc->stats.antenna_tx[i]);
392 }
393 len += snprintf(buf+len, sizeof(buf)-len, "[invalid]\t%d\t%d\n",
394 sc->stats.antenna_rx[0], sc->stats.antenna_tx[0]);
395
396 v = ath5k_hw_reg_read(sc->ah, AR5K_DEFAULT_ANTENNA);
397 len += snprintf(buf+len, sizeof(buf)-len,
398 "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v);
399
400 v = ath5k_hw_reg_read(sc->ah, AR5K_STA_ID1);
401 len += snprintf(buf+len, sizeof(buf)-len,
402 "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n",
403 (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0);
404 len += snprintf(buf+len, sizeof(buf)-len,
405 "AR5K_STA_ID1_DESC_ANTENNA\t%d\n",
406 (v & AR5K_STA_ID1_DESC_ANTENNA) != 0);
407 len += snprintf(buf+len, sizeof(buf)-len,
408 "AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n",
409 (v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0);
410 len += snprintf(buf+len, sizeof(buf)-len,
411 "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n",
412 (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0);
413
414 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_AGCCTL);
415 len += snprintf(buf+len, sizeof(buf)-len,
416 "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n",
417 (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0);
418
419 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_RESTART);
420 len += snprintf(buf+len, sizeof(buf)-len,
421 "AR5K_PHY_RESTART_DIV_GC\t\t%x\n",
422 (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S);
423
424 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_FAST_ANT_DIV);
425 len += snprintf(buf+len, sizeof(buf)-len,
426 "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
427 (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
428
429 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
430}
431
432static ssize_t write_file_antenna(struct file *file,
433 const char __user *userbuf,
434 size_t count, loff_t *ppos)
435{
436 struct ath5k_softc *sc = file->private_data;
437 unsigned int i;
438 char buf[20];
439
440 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
441 return -EFAULT;
442
443 if (strncmp(buf, "diversity", 9) == 0) {
444 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
445 printk(KERN_INFO "ath5k debug: enable diversity\n");
446 } else if (strncmp(buf, "fixed-a", 7) == 0) {
447 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
448 printk(KERN_INFO "ath5k debugfs: fixed antenna A\n");
449 } else if (strncmp(buf, "fixed-b", 7) == 0) {
450 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
451 printk(KERN_INFO "ath5k debug: fixed antenna B\n");
452 } else if (strncmp(buf, "clear", 5) == 0) {
453 for (i = 0; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
454 sc->stats.antenna_rx[i] = 0;
455 sc->stats.antenna_tx[i] = 0;
456 }
457 printk(KERN_INFO "ath5k debug: cleared antenna stats\n");
458 }
459 return count;
460}
461
462static const struct file_operations fops_antenna = {
463 .read = read_file_antenna,
464 .write = write_file_antenna,
465 .open = ath5k_debugfs_open,
466 .owner = THIS_MODULE,
467};
468
469
470/* debugfs: frameerrors */
471
472static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
473 size_t count, loff_t *ppos)
474{
475 struct ath5k_softc *sc = file->private_data;
476 struct ath5k_statistics *st = &sc->stats;
477 char buf[700];
478 unsigned int len = 0;
479 int i;
480
481 len += snprintf(buf+len, sizeof(buf)-len,
482 "RX\n---------------------\n");
483 len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n",
484 st->rxerr_crc,
485 st->rx_all_count > 0 ?
486 st->rxerr_crc*100/st->rx_all_count : 0);
487 len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n",
488 st->rxerr_phy,
489 st->rx_all_count > 0 ?
490 st->rxerr_phy*100/st->rx_all_count : 0);
491 for (i = 0; i < 32; i++) {
492 if (st->rxerr_phy_code[i])
493 len += snprintf(buf+len, sizeof(buf)-len,
494 " phy_err[%d]\t%d\n",
495 i, st->rxerr_phy_code[i]);
496 }
497
498 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
499 st->rxerr_fifo,
500 st->rx_all_count > 0 ?
501 st->rxerr_fifo*100/st->rx_all_count : 0);
502 len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n",
503 st->rxerr_decrypt,
504 st->rx_all_count > 0 ?
505 st->rxerr_decrypt*100/st->rx_all_count : 0);
506 len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n",
507 st->rxerr_mic,
508 st->rx_all_count > 0 ?
509 st->rxerr_mic*100/st->rx_all_count : 0);
510 len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n",
511 st->rxerr_proc,
512 st->rx_all_count > 0 ?
513 st->rxerr_proc*100/st->rx_all_count : 0);
514 len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n",
515 st->rxerr_jumbo,
516 st->rx_all_count > 0 ?
517 st->rxerr_jumbo*100/st->rx_all_count : 0);
518 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n",
519 st->rx_all_count);
520
521 len += snprintf(buf+len, sizeof(buf)-len,
522 "\nTX\n---------------------\n");
523 len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n",
524 st->txerr_retry,
525 st->tx_all_count > 0 ?
526 st->txerr_retry*100/st->tx_all_count : 0);
527 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
528 st->txerr_fifo,
529 st->tx_all_count > 0 ?
530 st->txerr_fifo*100/st->tx_all_count : 0);
531 len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n",
532 st->txerr_filt,
533 st->tx_all_count > 0 ?
534 st->txerr_filt*100/st->tx_all_count : 0);
535 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
536 st->tx_all_count);
537
538 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
539}
540
541static ssize_t write_file_frameerrors(struct file *file,
542 const char __user *userbuf,
543 size_t count, loff_t *ppos)
544{
545 struct ath5k_softc *sc = file->private_data;
546 struct ath5k_statistics *st = &sc->stats;
547 char buf[20];
548
549 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
550 return -EFAULT;
551
552 if (strncmp(buf, "clear", 5) == 0) {
553 st->rxerr_crc = 0;
554 st->rxerr_phy = 0;
555 st->rxerr_fifo = 0;
556 st->rxerr_decrypt = 0;
557 st->rxerr_mic = 0;
558 st->rxerr_proc = 0;
559 st->rxerr_jumbo = 0;
560 st->rx_all_count = 0;
561 st->txerr_retry = 0;
562 st->txerr_fifo = 0;
563 st->txerr_filt = 0;
564 st->tx_all_count = 0;
565 printk(KERN_INFO "ath5k debug: cleared frameerrors stats\n");
566 }
567 return count;
568}
569
570static const struct file_operations fops_frameerrors = {
571 .read = read_file_frameerrors,
572 .write = write_file_frameerrors,
573 .open = ath5k_debugfs_open,
574 .owner = THIS_MODULE,
575};
576
577
578/* debugfs: ani */
579
580static ssize_t read_file_ani(struct file *file, char __user *user_buf,
581 size_t count, loff_t *ppos)
582{
583 struct ath5k_softc *sc = file->private_data;
584 struct ath5k_statistics *st = &sc->stats;
585 struct ath5k_ani_state *as = &sc->ani_state;
586
587 char buf[700];
588 unsigned int len = 0;
589
590 len += snprintf(buf+len, sizeof(buf)-len,
591 "HW has PHY error counters:\t%s\n",
592 sc->ah->ah_capabilities.cap_has_phyerr_counters ?
593 "yes" : "no");
594 len += snprintf(buf+len, sizeof(buf)-len,
595 "HW max spur immunity level:\t%d\n",
596 as->max_spur_level);
597 len += snprintf(buf+len, sizeof(buf)-len,
598 "\nANI state\n--------------------------------------------\n");
599 len += snprintf(buf+len, sizeof(buf)-len, "operating mode:\t\t\t");
600 switch (as->ani_mode) {
601 case ATH5K_ANI_MODE_OFF:
602 len += snprintf(buf+len, sizeof(buf)-len, "OFF\n");
603 break;
604 case ATH5K_ANI_MODE_MANUAL_LOW:
605 len += snprintf(buf+len, sizeof(buf)-len,
606 "MANUAL LOW\n");
607 break;
608 case ATH5K_ANI_MODE_MANUAL_HIGH:
609 len += snprintf(buf+len, sizeof(buf)-len,
610 "MANUAL HIGH\n");
611 break;
612 case ATH5K_ANI_MODE_AUTO:
613 len += snprintf(buf+len, sizeof(buf)-len, "AUTO\n");
614 break;
615 default:
616 len += snprintf(buf+len, sizeof(buf)-len,
617 "??? (not good)\n");
618 break;
619 }
620 len += snprintf(buf+len, sizeof(buf)-len,
621 "noise immunity level:\t\t%d\n",
622 as->noise_imm_level);
623 len += snprintf(buf+len, sizeof(buf)-len,
624 "spur immunity level:\t\t%d\n",
625 as->spur_level);
626 len += snprintf(buf+len, sizeof(buf)-len, "firstep level:\t\t\t%d\n",
627 as->firstep_level);
628 len += snprintf(buf+len, sizeof(buf)-len,
629 "OFDM weak signal detection:\t%s\n",
630 as->ofdm_weak_sig ? "on" : "off");
631 len += snprintf(buf+len, sizeof(buf)-len,
632 "CCK weak signal detection:\t%s\n",
633 as->cck_weak_sig ? "on" : "off");
634
635 len += snprintf(buf+len, sizeof(buf)-len,
636 "\nMIB INTERRUPTS:\t\t%u\n",
637 st->mib_intr);
638 len += snprintf(buf+len, sizeof(buf)-len,
639 "beacon RSSI average:\t%d\n",
640 sc->ah->ah_beacon_rssi_avg.avg);
641 len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
642 as->pfc_tx,
643 as->pfc_cycles > 0 ?
644 as->pfc_tx*100/as->pfc_cycles : 0);
645 len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
646 as->pfc_rx,
647 as->pfc_cycles > 0 ?
648 as->pfc_rx*100/as->pfc_cycles : 0);
649 len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
650 as->pfc_busy,
651 as->pfc_cycles > 0 ?
652 as->pfc_busy*100/as->pfc_cycles : 0);
653 len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
654 as->pfc_cycles);
655 len += snprintf(buf+len, sizeof(buf)-len,
656 "listen time\t\t%d\tlast: %d\n",
657 as->listen_time, as->last_listen);
658 len += snprintf(buf+len, sizeof(buf)-len,
659 "OFDM errors\t\t%u\tlast: %u\tsum: %u\n",
660 as->ofdm_errors, as->last_ofdm_errors,
661 as->sum_ofdm_errors);
662 len += snprintf(buf+len, sizeof(buf)-len,
663 "CCK errors\t\t%u\tlast: %u\tsum: %u\n",
664 as->cck_errors, as->last_cck_errors,
665 as->sum_cck_errors);
666 len += snprintf(buf+len, sizeof(buf)-len,
667 "AR5K_PHYERR_CNT1\t%x\t(=%d)\n",
668 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1),
669 ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
670 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1)));
671 len += snprintf(buf+len, sizeof(buf)-len,
672 "AR5K_PHYERR_CNT2\t%x\t(=%d)\n",
673 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2),
674 ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
675 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2)));
676
677 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
678}
679
680static ssize_t write_file_ani(struct file *file,
681 const char __user *userbuf,
682 size_t count, loff_t *ppos)
683{
684 struct ath5k_softc *sc = file->private_data;
685 char buf[20];
686
687 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
688 return -EFAULT;
689
690 if (strncmp(buf, "sens-low", 8) == 0) {
691 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_HIGH);
692 } else if (strncmp(buf, "sens-high", 9) == 0) {
693 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_LOW);
694 } else if (strncmp(buf, "ani-off", 7) == 0) {
695 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_OFF);
696 } else if (strncmp(buf, "ani-on", 6) == 0) {
697 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_AUTO);
698 } else if (strncmp(buf, "noise-low", 9) == 0) {
699 ath5k_ani_set_noise_immunity_level(sc->ah, 0);
700 } else if (strncmp(buf, "noise-high", 10) == 0) {
701 ath5k_ani_set_noise_immunity_level(sc->ah,
702 ATH5K_ANI_MAX_NOISE_IMM_LVL);
703 } else if (strncmp(buf, "spur-low", 8) == 0) {
704 ath5k_ani_set_spur_immunity_level(sc->ah, 0);
705 } else if (strncmp(buf, "spur-high", 9) == 0) {
706 ath5k_ani_set_spur_immunity_level(sc->ah,
707 sc->ani_state.max_spur_level);
708 } else if (strncmp(buf, "fir-low", 7) == 0) {
709 ath5k_ani_set_firstep_level(sc->ah, 0);
710 } else if (strncmp(buf, "fir-high", 8) == 0) {
711 ath5k_ani_set_firstep_level(sc->ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
712 } else if (strncmp(buf, "ofdm-off", 8) == 0) {
713 ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, false);
714 } else if (strncmp(buf, "ofdm-on", 7) == 0) {
715 ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, true);
716 } else if (strncmp(buf, "cck-off", 7) == 0) {
717 ath5k_ani_set_cck_weak_signal_detection(sc->ah, false);
718 } else if (strncmp(buf, "cck-on", 6) == 0) {
719 ath5k_ani_set_cck_weak_signal_detection(sc->ah, true);
720 }
721 return count;
722}
723
724static const struct file_operations fops_ani = {
725 .read = read_file_ani,
726 .write = write_file_ani,
727 .open = ath5k_debugfs_open,
728 .owner = THIS_MODULE,
729};
730
731
367/* init */ 732/* init */
368 733
369void 734void
@@ -393,6 +758,20 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
393 758
394 sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, 759 sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
395 sc->debug.debugfs_phydir, sc, &fops_reset); 760 sc->debug.debugfs_phydir, sc, &fops_reset);
761
762 sc->debug.debugfs_antenna = debugfs_create_file("antenna",
763 S_IWUSR | S_IRUSR,
764 sc->debug.debugfs_phydir, sc, &fops_antenna);
765
766 sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors",
767 S_IWUSR | S_IRUSR,
768 sc->debug.debugfs_phydir, sc,
769 &fops_frameerrors);
770
771 sc->debug.debugfs_ani = debugfs_create_file("ani",
772 S_IWUSR | S_IRUSR,
773 sc->debug.debugfs_phydir, sc,
774 &fops_ani);
396} 775}
397 776
398void 777void
@@ -408,6 +787,9 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
408 debugfs_remove(sc->debug.debugfs_registers); 787 debugfs_remove(sc->debug.debugfs_registers);
409 debugfs_remove(sc->debug.debugfs_beacon); 788 debugfs_remove(sc->debug.debugfs_beacon);
410 debugfs_remove(sc->debug.debugfs_reset); 789 debugfs_remove(sc->debug.debugfs_reset);
790 debugfs_remove(sc->debug.debugfs_antenna);
791 debugfs_remove(sc->debug.debugfs_frameerrors);
792 debugfs_remove(sc->debug.debugfs_ani);
411 debugfs_remove(sc->debug.debugfs_phydir); 793 debugfs_remove(sc->debug.debugfs_phydir);
412} 794}
413 795
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 66f69f04e55e..ddd5b3a99e8d 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -74,6 +74,9 @@ struct ath5k_dbg_info {
74 struct dentry *debugfs_registers; 74 struct dentry *debugfs_registers;
75 struct dentry *debugfs_beacon; 75 struct dentry *debugfs_beacon;
76 struct dentry *debugfs_reset; 76 struct dentry *debugfs_reset;
77 struct dentry *debugfs_antenna;
78 struct dentry *debugfs_frameerrors;
79 struct dentry *debugfs_ani;
77}; 80};
78 81
79/** 82/**
@@ -113,6 +116,7 @@ enum ath5k_debug_level {
113 ATH5K_DEBUG_DUMP_TX = 0x00000200, 116 ATH5K_DEBUG_DUMP_TX = 0x00000200,
114 ATH5K_DEBUG_DUMPBANDS = 0x00000400, 117 ATH5K_DEBUG_DUMPBANDS = 0x00000400,
115 ATH5K_DEBUG_TRACE = 0x00001000, 118 ATH5K_DEBUG_TRACE = 0x00001000,
119 ATH5K_DEBUG_ANI = 0x00002000,
116 ATH5K_DEBUG_ANY = 0xffffffff 120 ATH5K_DEBUG_ANY = 0xffffffff
117}; 121};
118 122
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index dc30a2b70a6b..7d7b646ab65a 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -35,7 +35,8 @@
35 */ 35 */
36static int 36static int
37ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 37ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
38 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, 38 unsigned int pkt_len, unsigned int hdr_len, int padsize,
39 enum ath5k_pkt_type type,
39 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, 40 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
40 unsigned int key_index, unsigned int antenna_mode, unsigned int flags, 41 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
41 unsigned int rtscts_rate, unsigned int rtscts_duration) 42 unsigned int rtscts_rate, unsigned int rtscts_duration)
@@ -71,7 +72,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
71 /* Verify and set frame length */ 72 /* Verify and set frame length */
72 73
73 /* remove padding we might have added before */ 74 /* remove padding we might have added before */
74 frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; 75 frame_len = pkt_len - padsize + FCS_LEN;
75 76
76 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) 77 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
77 return -EINVAL; 78 return -EINVAL;
@@ -100,7 +101,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
100 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); 101 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
101 } 102 }
102 103
103 /*Diferences between 5210-5211*/ 104 /*Differences between 5210-5211*/
104 if (ah->ah_version == AR5K_AR5210) { 105 if (ah->ah_version == AR5K_AR5210) {
105 switch (type) { 106 switch (type) {
106 case AR5K_PKT_TYPE_BEACON: 107 case AR5K_PKT_TYPE_BEACON:
@@ -165,6 +166,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
165 */ 166 */
166static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, 167static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
167 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, 168 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
169 int padsize,
168 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, 170 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
169 unsigned int tx_tries0, unsigned int key_index, 171 unsigned int tx_tries0, unsigned int key_index,
170 unsigned int antenna_mode, unsigned int flags, 172 unsigned int antenna_mode, unsigned int flags,
@@ -206,7 +208,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
206 /* Verify and set frame length */ 208 /* Verify and set frame length */
207 209
208 /* remove padding we might have added before */ 210 /* remove padding we might have added before */
209 frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; 211 frame_len = pkt_len - padsize + FCS_LEN;
210 212
211 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) 213 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
212 return -EINVAL; 214 return -EINVAL;
@@ -229,7 +231,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
229 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); 231 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
230 tx_ctl->tx_control_1 |= AR5K_REG_SM(type, 232 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
231 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); 233 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
232 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, 234 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0,
233 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); 235 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
234 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; 236 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
235 237
@@ -643,6 +645,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
643 rs->rs_status |= AR5K_RXERR_PHY; 645 rs->rs_status |= AR5K_RXERR_PHY;
644 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, 646 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
645 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); 647 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
648 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
646 } 649 }
647 650
648 if (rx_status->rx_status_1 & 651 if (rx_status->rx_status_1 &
@@ -668,12 +671,6 @@ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
668 ah->ah_version != AR5K_AR5212) 671 ah->ah_version != AR5K_AR5212)
669 return -ENOTSUPP; 672 return -ENOTSUPP;
670 673
671 /* XXX: What is this magic value and where is it used ? */
672 if (ah->ah_version == AR5K_AR5212)
673 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
674 else if (ah->ah_version == AR5K_AR5211)
675 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
676
677 if (ah->ah_version == AR5K_AR5212) { 674 if (ah->ah_version == AR5K_AR5212) {
678 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; 675 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
679 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; 676 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index 56158c804e3e..64538fbe4167 100644
--- a/drivers/net/wireless/ath/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
@@ -112,15 +112,32 @@ struct ath5k_hw_rx_error {
112#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 112#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00
113#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 113#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8
114 114
115/* PHY Error codes */ 115/**
116#define AR5K_DESC_RX_PHY_ERROR_NONE 0x00 116 * enum ath5k_phy_error_code - PHY Error codes
117#define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20 117 */
118#define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40 118enum ath5k_phy_error_code {
119#define AR5K_DESC_RX_PHY_ERROR_RATE 0x60 119 AR5K_RX_PHY_ERROR_UNDERRUN = 0, /* Transmit underrun */
120#define AR5K_DESC_RX_PHY_ERROR_LENGTH 0x80 120 AR5K_RX_PHY_ERROR_TIMING = 1, /* Timing error */
121#define AR5K_DESC_RX_PHY_ERROR_64QAM 0xa0 121 AR5K_RX_PHY_ERROR_PARITY = 2, /* Illegal parity */
122#define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0 122 AR5K_RX_PHY_ERROR_RATE = 3, /* Illegal rate */
123#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0 123 AR5K_RX_PHY_ERROR_LENGTH = 4, /* Illegal length */
124 AR5K_RX_PHY_ERROR_RADAR = 5, /* Radar detect */
125 AR5K_RX_PHY_ERROR_SERVICE = 6, /* Illegal service */
126 AR5K_RX_PHY_ERROR_TOR = 7, /* Transmit override receive */
127 /* these are specific to the 5212 */
128 AR5K_RX_PHY_ERROR_OFDM_TIMING = 17,
129 AR5K_RX_PHY_ERROR_OFDM_SIGNAL_PARITY = 18,
130 AR5K_RX_PHY_ERROR_OFDM_RATE_ILLEGAL = 19,
131 AR5K_RX_PHY_ERROR_OFDM_LENGTH_ILLEGAL = 20,
132 AR5K_RX_PHY_ERROR_OFDM_POWER_DROP = 21,
133 AR5K_RX_PHY_ERROR_OFDM_SERVICE = 22,
134 AR5K_RX_PHY_ERROR_OFDM_RESTART = 23,
135 AR5K_RX_PHY_ERROR_CCK_TIMING = 25,
136 AR5K_RX_PHY_ERROR_CCK_HEADER_CRC = 26,
137 AR5K_RX_PHY_ERROR_CCK_RATE_ILLEGAL = 27,
138 AR5K_RX_PHY_ERROR_CCK_SERVICE = 30,
139 AR5K_RX_PHY_ERROR_CCK_RESTART = 31,
140};
124 141
125/* 142/*
126 * 5210/5211 hardware 2-word TX control descriptor 143 * 5210/5211 hardware 2-word TX control descriptor
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 10b52262b232..a3cbfe4fc389 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -329,7 +329,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
329 ee->ee_x_gain[mode] = (val >> 1) & 0xf; 329 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
330 ee->ee_xpd[mode] = val & 0x1; 330 ee->ee_xpd[mode] = val & 0x1;
331 331
332 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) 332 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
333 mode != AR5K_EEPROM_MODE_11B)
333 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; 334 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
334 335
335 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { 336 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
@@ -339,6 +340,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
339 if (mode == AR5K_EEPROM_MODE_11A) 340 if (mode == AR5K_EEPROM_MODE_11A)
340 ee->ee_xr_power[mode] = val & 0x3f; 341 ee->ee_xr_power[mode] = val & 0x3f;
341 else { 342 else {
343 /* b_DB_11[bg] and b_OB_11[bg] */
342 ee->ee_ob[mode][0] = val & 0x7; 344 ee->ee_ob[mode][0] = val & 0x7;
343 ee->ee_db[mode][0] = (val >> 3) & 0x7; 345 ee->ee_db[mode][0] = (val >> 3) & 0x7;
344 } 346 }
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 473a483bb9c3..c4a6d5f26af4 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -24,9 +24,6 @@
24 * SERDES infos are present */ 24 * SERDES infos are present */
25#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ 25#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
26#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ 26#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
27#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
28#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
29#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
30 27
31#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ 28#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
32 29
@@ -78,9 +75,9 @@
78#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) 75#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
79#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) 76#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
80#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) 77#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
81#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ 78#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz */
82#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ 79#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for < 2W power consumption */
83#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) 80#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) /* Device type (1 Cardbus, 2 PCI, 3 MiniPCI, 4 AP) */
84#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ 81#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
85#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ 82#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */
86 83
@@ -101,7 +98,7 @@
101 98
102#define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) 99#define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5)
103#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) 100#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
104#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) 101#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) /* has 32KHz crystal for sleep mode */
105#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) 102#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1)
106 103
107#define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) 104#define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6)
@@ -114,26 +111,27 @@
114 111
115#define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) 112#define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8)
116#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) 113#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff)
117#define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) 114#define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) /* modes supported by radio 0 (bit 1: G, bit 2: A) */
118#define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) 115#define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) /* modes supported by radio 1 (bit 1: G, bit 2: A) */
119 116
120#define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) 117#define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9)
121#define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) 118#define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) /* disable compression */
122#define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) 119#define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) /* disable AES */
123#define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) 120#define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) /* disable fast frames */
124#define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) 121#define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) /* disable bursting */
125#define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) 122#define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) /* max number of QCUs. defaults to 10 */
126#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) 123#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) /* enable heayy clipping */
127#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) 124#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) /* key cache size. defaults to 128 */
128 125
129#define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) 126#define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10)
130#define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x8) 127#define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x7) /* MIMO chains disabled for TX bitmask */
131#define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x8) 128#define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x7) /* MIMO chains disabled for RX bitmask */
132#define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) 129#define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) /* 5.47-5.7GHz supported */
133#define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) 130#define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) /* Japan UNII1 band (5.15-5.25GHz) on even channels (5180, 5200, 5220, 5240) supported */
134#define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) 131#define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) /* Japan UNII2 band (5.25-5.35GHz) supported */
135#define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 9) & 0x1) 132#define AR5K_EEPROM_JAP_MID_EN (((_v) >> 9) & 0x1) /* Japan band from 5.47-5.7GHz supported */
136#define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 10) & 0x1) 133#define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 10) & 0x1) /* Japan UNII2 band (5.15-5.25GHz) on odd channels (5170, 5190, 5210, 5230) supported */
134#define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 11) & 0x1) /* Japan A mode enabled (using even channels) */
137 135
138/* calibration settings */ 136/* calibration settings */
139#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) 137#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
@@ -389,7 +387,49 @@ struct ath5k_edge_power {
389 bool flag; 387 bool flag;
390}; 388};
391 389
392/* EEPROM calibration data */ 390/**
391 * struct ath5k_eeprom_info - EEPROM calibration data
392 *
393 * @ee_regdomain: ath/regd.c takes care of COUNTRY_ERD and WORLDWIDE_ROAMING
394 * flags
395 * @ee_ant_gain: Antenna gain in 0.5dB steps signed [5211 only?]
396 * @ee_cck_ofdm_gain_delta: difference in gainF to output the same power for
397 * OFDM and CCK packets
398 * @ee_cck_ofdm_power_delta: power difference between OFDM (6Mbps) and CCK
399 * (11Mbps) rate in G mode. 0.1dB steps
400 * @ee_scaled_cck_delta: for Japan Channel 14: 0.1dB resolution
401 *
402 * @ee_i_cal: Initial I coefficient to correct I/Q mismatch in the receive path
403 * @ee_q_cal: Initial Q coefficient to correct I/Q mismatch in the receive path
404 * @ee_fixed_bias: use ee_ob and ee_db settings or use automatic control
405 * @ee_switch_settling: RX/TX Switch settling time
406 * @ee_atn_tx_rx: Difference in attenuation between TX and RX in 1dB steps
407 * @ee_ant_control: Antenna Control Settings
408 * @ee_ob: Bias current for Output stage of PA
409 * B/G mode: Index [0] is used for AR2112/5112, otherwise [1]
410 * A mode: [0] 5.15-5.25 [1] 5.25-5.50 [2] 5.50-5.70 [3] 5.70-5.85 GHz
411 * @ee_db: Bias current for Output stage of PA. see @ee_ob
412 * @ee_tx_end2xlna_enable: Time difference from when BB finishes sending a frame
413 * to when the external LNA is activated
414 * @ee_tx_end2xpa_disable: Time difference from when BB finishes sending a frame
415 * to when the external PA switch is deactivated
416 * @ee_tx_frm2xpa_enable: Time difference from when MAC sends frame to when
417 * external PA switch is activated
418 * @ee_thr_62: Clear Channel Assessment (CCA) sensitivity
419 * (IEEE802.11a section 17.3.10.5 )
420 * @ee_xlna_gain: Total gain of the LNA (information only)
421 * @ee_xpd: Use external (1) or internal power detector
422 * @ee_x_gain: Gain for external power detector output (differences in EEMAP
423 * versions!)
424 * @ee_i_gain: Initial gain value after reset
425 * @ee_margin_tx_rx: Margin in dB when final attenuation stage should be used
426 *
427 * @ee_false_detect: Backoff in Sensitivity (dB) on channels with spur signals
428 * @ee_noise_floor_thr: Noise floor threshold in 1dB steps
429 * @ee_adc_desired_size: Desired amplitude for ADC, used by AGC; in 0.5 dB steps
430 * @ee_pga_desired_size: Desired output of PGA (for BB gain) in 0.5 dB steps
431 * @ee_pd_gain_overlap: PD ADC curves need to overlap in 0.5dB steps (ee_map>=2)
432 */
393struct ath5k_eeprom_info { 433struct ath5k_eeprom_info {
394 434
395 /* Header information */ 435 /* Header information */
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index aefe84f9c04b..710870ea179b 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -39,16 +39,16 @@
39 * ath5k_hw_set_opmode - Set PCU operating mode 39 * ath5k_hw_set_opmode - Set PCU operating mode
40 * 40 *
41 * @ah: The &struct ath5k_hw 41 * @ah: The &struct ath5k_hw
42 * @op_mode: &enum nl80211_iftype operating mode
42 * 43 *
43 * Initialize PCU for the various operating modes (AP/STA etc) 44 * Initialize PCU for the various operating modes (AP/STA etc)
44 *
45 * NOTE: ah->ah_op_mode must be set before calling this.
46 */ 45 */
47int ath5k_hw_set_opmode(struct ath5k_hw *ah) 46int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
48{ 47{
49 struct ath_common *common = ath5k_hw_common(ah); 48 struct ath_common *common = ath5k_hw_common(ah);
50 u32 pcu_reg, beacon_reg, low_id, high_id; 49 u32 pcu_reg, beacon_reg, low_id, high_id;
51 50
51 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
52 52
53 /* Preserve rest settings */ 53 /* Preserve rest settings */
54 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; 54 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
@@ -61,7 +61,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
61 61
62 ATH5K_TRACE(ah->ah_sc); 62 ATH5K_TRACE(ah->ah_sc);
63 63
64 switch (ah->ah_op_mode) { 64 switch (op_mode) {
65 case NL80211_IFTYPE_ADHOC: 65 case NL80211_IFTYPE_ADHOC:
66 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; 66 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
67 beacon_reg |= AR5K_BCR_ADHOC; 67 beacon_reg |= AR5K_BCR_ADHOC;
@@ -113,39 +113,26 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
113} 113}
114 114
115/** 115/**
116 * ath5k_hw_update - Update mib counters (mac layer statistics) 116 * ath5k_hw_update - Update MIB counters (mac layer statistics)
117 * 117 *
118 * @ah: The &struct ath5k_hw 118 * @ah: The &struct ath5k_hw
119 * @stats: The &struct ieee80211_low_level_stats we use to track
120 * statistics on the driver
121 * 119 *
122 * Reads MIB counters from PCU and updates sw statistics. Must be 120 * Reads MIB counters from PCU and updates sw statistics. Is called after a
123 * called after a MIB interrupt. 121 * MIB interrupt, because one of these counters might have reached their maximum
122 * and triggered the MIB interrupt, to let us read and clear the counter.
123 *
124 * Is called in interrupt context!
124 */ 125 */
125void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, 126void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
126 struct ieee80211_low_level_stats *stats)
127{ 127{
128 ATH5K_TRACE(ah->ah_sc); 128 struct ath5k_statistics *stats = &ah->ah_sc->stats;
129 129
130 /* Read-And-Clear */ 130 /* Read-And-Clear */
131 stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); 131 stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
132 stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); 132 stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
133 stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK); 133 stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
134 stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); 134 stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
135 135 stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
136 /* XXX: Should we use this to track beacon count ?
137 * -we read it anyway to clear the register */
138 ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
139
140 /* Reset profile count registers on 5212*/
141 if (ah->ah_version == AR5K_AR5212) {
142 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
143 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
144 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
145 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
146 }
147
148 /* TODO: Handle ANI stats */
149} 136}
150 137
151/** 138/**
@@ -179,25 +166,12 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
179\******************/ 166\******************/
180 167
181/** 168/**
182 * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
183 *
184 * @ah: The &struct ath5k_hw
185 */
186unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
187{
188 ATH5K_TRACE(ah->ah_sc);
189
190 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
191 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK));
192}
193
194/**
195 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU 169 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
196 * 170 *
197 * @ah: The &struct ath5k_hw 171 * @ah: The &struct ath5k_hw
198 * @timeout: Timeout in usec 172 * @timeout: Timeout in usec
199 */ 173 */
200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) 174static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
201{ 175{
202 ATH5K_TRACE(ah->ah_sc); 176 ATH5K_TRACE(ah->ah_sc);
203 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) 177 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
@@ -211,24 +185,12 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
211} 185}
212 186
213/** 187/**
214 * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
215 *
216 * @ah: The &struct ath5k_hw
217 */
218unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
219{
220 ATH5K_TRACE(ah->ah_sc);
221 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
222 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS));
223}
224
225/**
226 * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU 188 * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
227 * 189 *
228 * @ah: The &struct ath5k_hw 190 * @ah: The &struct ath5k_hw
229 * @timeout: Timeout in usec 191 * @timeout: Timeout in usec
230 */ 192 */
231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) 193static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
232{ 194{
233 ATH5K_TRACE(ah->ah_sc); 195 ATH5K_TRACE(ah->ah_sc);
234 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) 196 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
@@ -290,7 +252,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
290 * 252 *
291 * @ah: The &struct ath5k_hw 253 * @ah: The &struct ath5k_hw
292 */ 254 */
293unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) 255static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
294{ 256{
295 struct ieee80211_channel *channel = ah->ah_current_channel; 257 struct ieee80211_channel *channel = ah->ah_current_channel;
296 258
@@ -308,7 +270,7 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
308 * 270 *
309 * @ah: The &struct ath5k_hw 271 * @ah: The &struct ath5k_hw
310 */ 272 */
311unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) 273static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
312{ 274{
313 struct ieee80211_channel *channel = ah->ah_current_channel; 275 struct ieee80211_channel *channel = ah->ah_current_channel;
314 276
@@ -417,7 +379,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
417 * (ACK etc). 379 * (ACK etc).
418 * 380 *
419 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma 381 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
420 * TODO: Init ANI here
421 */ 382 */
422void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) 383void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
423{ 384{
@@ -451,42 +412,6 @@ void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
451 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); 412 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
452} 413}
453 414
454/*
455 * Set multicast filter by index
456 */
457int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
458{
459
460 ATH5K_TRACE(ah->ah_sc);
461 if (index >= 64)
462 return -EINVAL;
463 else if (index >= 32)
464 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
465 (1 << (index - 32)));
466 else
467 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
468
469 return 0;
470}
471
472/*
473 * Clear Multicast filter by index
474 */
475int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
476{
477
478 ATH5K_TRACE(ah->ah_sc);
479 if (index >= 64)
480 return -EINVAL;
481 else if (index >= 32)
482 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
483 (1 << (index - 32)));
484 else
485 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
486
487 return 0;
488}
489
490/** 415/**
491 * ath5k_hw_get_rx_filter - Get current rx filter 416 * ath5k_hw_get_rx_filter - Get current rx filter
492 * 417 *
@@ -572,19 +497,6 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
572\****************/ 497\****************/
573 498
574/** 499/**
575 * ath5k_hw_get_tsf32 - Get a 32bit TSF
576 *
577 * @ah: The &struct ath5k_hw
578 *
579 * Returns lower 32 bits of current TSF
580 */
581u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
582{
583 ATH5K_TRACE(ah->ah_sc);
584 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
585}
586
587/**
588 * ath5k_hw_get_tsf64 - Get the full 64bit TSF 500 * ath5k_hw_get_tsf64 - Get the full 64bit TSF
589 * 501 *
590 * @ah: The &struct ath5k_hw 502 * @ah: The &struct ath5k_hw
@@ -651,7 +563,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
651 /* 563 /*
652 * Set the additional timers by mode 564 * Set the additional timers by mode
653 */ 565 */
654 switch (ah->ah_op_mode) { 566 switch (ah->ah_sc->opmode) {
655 case NL80211_IFTYPE_MONITOR: 567 case NL80211_IFTYPE_MONITOR:
656 case NL80211_IFTYPE_STATION: 568 case NL80211_IFTYPE_STATION:
657 /* In STA mode timer1 is used as next wakeup 569 /* In STA mode timer1 is used as next wakeup
@@ -688,8 +600,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
688 * Set the beacon register and enable all timers. 600 * Set the beacon register and enable all timers.
689 */ 601 */
690 /* When in AP or Mesh Point mode zero timer0 to start TSF */ 602 /* When in AP or Mesh Point mode zero timer0 to start TSF */
691 if (ah->ah_op_mode == NL80211_IFTYPE_AP || 603 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP ||
692 ah->ah_op_mode == NL80211_IFTYPE_MESH_POINT) 604 ah->ah_sc->opmode == NL80211_IFTYPE_MESH_POINT)
693 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); 605 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
694 606
695 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); 607 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
@@ -722,203 +634,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
722 634
723} 635}
724 636
725#if 0
726/*
727 * Set beacon timers
728 */
729int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
730 const struct ath5k_beacon_state *state)
731{
732 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
733
734 /*
735 * TODO: should be changed through *state
736 * review struct ath5k_beacon_state struct
737 *
738 * XXX: These are used for cfp period bellow, are they
739 * ok ? Is it O.K. for tsf here to be 0 or should we use
740 * get_tsf ?
741 */
742 u32 dtim_count = 0; /* XXX */
743 u32 cfp_count = 0; /* XXX */
744 u32 tsf = 0; /* XXX */
745
746 ATH5K_TRACE(ah->ah_sc);
747 /* Return on an invalid beacon state */
748 if (state->bs_interval < 1)
749 return -EINVAL;
750
751 interval = state->bs_interval;
752 dtim = state->bs_dtim_period;
753
754 /*
755 * PCF support?
756 */
757 if (state->bs_cfp_period > 0) {
758 /*
759 * Enable PCF mode and set the CFP
760 * (Contention Free Period) and timer registers
761 */
762 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
763 state->bs_interval;
764 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
765 state->bs_interval;
766
767 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
768 AR5K_STA_ID1_DEFAULT_ANTENNA |
769 AR5K_STA_ID1_PCF);
770 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
771 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
772 AR5K_CFP_DUR);
773 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
774 next_cfp)) << 3, AR5K_TIMER2);
775 } else {
776 /* Disable PCF mode */
777 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
778 AR5K_STA_ID1_DEFAULT_ANTENNA |
779 AR5K_STA_ID1_PCF);
780 }
781
782 /*
783 * Enable the beacon timer register
784 */
785 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
786
787 /*
788 * Start the beacon timers
789 */
790 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
791 ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
792 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
793 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
794 AR5K_BEACON_PERIOD), AR5K_BEACON);
795
796 /*
797 * Write new beacon miss threshold, if it appears to be valid
798 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
799 * and return if its not in range. We can test this by reading value and
800 * setting value to a largest value and seeing which values register.
801 */
802
803 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
804 state->bs_bmiss_threshold);
805
806 /*
807 * Set sleep control register
808 * XXX: Didn't find this in 5210 code but since this register
809 * exists also in ar5k's 5210 headers i leave it as common code.
810 */
811 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
812 (state->bs_sleep_duration - 3) << 3);
813
814 /*
815 * Set enhanced sleep registers on 5212
816 */
817 if (ah->ah_version == AR5K_AR5212) {
818 if (state->bs_sleep_duration > state->bs_interval &&
819 roundup(state->bs_sleep_duration, interval) ==
820 state->bs_sleep_duration)
821 interval = state->bs_sleep_duration;
822
823 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
824 roundup(state->bs_sleep_duration, dtim) ==
825 state->bs_sleep_duration))
826 dtim = state->bs_sleep_duration;
827
828 if (interval > dtim)
829 return -EINVAL;
830
831 next_beacon = interval == dtim ? state->bs_next_dtim :
832 state->bs_next_beacon;
833
834 ath5k_hw_reg_write(ah,
835 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
836 AR5K_SLEEP0_NEXT_DTIM) |
837 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
838 AR5K_SLEEP0_ENH_SLEEP_EN |
839 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
840
841 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
842 AR5K_SLEEP1_NEXT_TIM) |
843 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
844
845 ath5k_hw_reg_write(ah,
846 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
847 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
848 }
849
850 return 0;
851}
852
853/*
854 * Reset beacon timers
855 */
856void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
857{
858 ATH5K_TRACE(ah->ah_sc);
859 /*
860 * Disable beacon timer
861 */
862 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
863
864 /*
865 * Disable some beacon register values
866 */
867 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
868 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
869 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
870}
871
872/*
873 * Wait for beacon queue to finish
874 */
875int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
876{
877 unsigned int i;
878 int ret;
879
880 ATH5K_TRACE(ah->ah_sc);
881
882 /* 5210 doesn't have QCU*/
883 if (ah->ah_version == AR5K_AR5210) {
884 /*
885 * Wait for beaconn queue to finish by checking
886 * Control Register and Beacon Status Register.
887 */
888 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
889 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
890 ||
891 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
892 break;
893 udelay(10);
894 }
895
896 /* Timeout... */
897 if (i <= 0) {
898 /*
899 * Re-schedule the beacon queue
900 */
901 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
902 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
903 AR5K_BCR);
904
905 return -EIO;
906 }
907 ret = 0;
908 } else {
909 /*5211/5212*/
910 ret = ath5k_hw_register_timeout(ah,
911 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
912 AR5K_QCU_STS_FRMPENDCNT, 0, false);
913
914 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
915 return -EIO;
916 }
917
918 return ret;
919}
920#endif
921
922 637
923/*********************\ 638/*********************\
924* Key table functions * 639* Key table functions *
@@ -971,19 +686,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
971 return 0; 686 return 0;
972} 687}
973 688
974/*
975 * Check if a table entry is valid
976 */
977int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
978{
979 ATH5K_TRACE(ah->ah_sc);
980 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
981
982 /* Check the validation flag at the end of the entry */
983 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
984 AR5K_KEYTABLE_VALID;
985}
986
987static 689static
988int ath5k_keycache_type(const struct ieee80211_key_conf *key) 690int ath5k_keycache_type(const struct ieee80211_key_conf *key)
989{ 691{
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index eff3323efb4b..b6704c93f808 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -20,8 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#define _ATH5K_PHY
24
25#include <linux/delay.h> 23#include <linux/delay.h>
26 24
27#include "ath5k.h" 25#include "ath5k.h"
@@ -1104,28 +1102,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1104 PHY calibration 1102 PHY calibration
1105\*****************/ 1103\*****************/
1106 1104
1107void
1108ath5k_hw_calibration_poll(struct ath5k_hw *ah)
1109{
1110 /* Calibration interval in jiffies */
1111 unsigned long cal_intval;
1112
1113 cal_intval = msecs_to_jiffies(ah->ah_cal_intval * 1000);
1114
1115 /* Initialize timestamp if needed */
1116 if (!ah->ah_cal_tstamp)
1117 ah->ah_cal_tstamp = jiffies;
1118
1119 /* For now we always do full calibration
1120 * Mark software interrupt mask and fire software
1121 * interrupt (bit gets auto-cleared) */
1122 if (time_is_before_eq_jiffies(ah->ah_cal_tstamp + cal_intval)) {
1123 ah->ah_cal_tstamp = jiffies;
1124 ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
1125 AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
1126 }
1127}
1128
1129static int sign_extend(int val, const int nbits) 1105static int sign_extend(int val, const int nbits)
1130{ 1106{
1131 int order = BIT(nbits-1); 1107 int order = BIT(nbits-1);
@@ -1190,7 +1166,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1190 * The median of the values in the history is then loaded into the 1166 * The median of the values in the history is then loaded into the
1191 * hardware for its own use for RSSI and CCA measurements. 1167 * hardware for its own use for RSSI and CCA measurements.
1192 */ 1168 */
1193void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) 1169static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1194{ 1170{
1195 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1171 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1196 u32 val; 1172 u32 val;
@@ -1399,7 +1375,11 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1399 } 1375 }
1400 1376
1401 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; 1377 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1402 q_coffd = q_pwr >> 7; 1378
1379 if (ah->ah_version == AR5K_AR5211)
1380 q_coffd = q_pwr >> 6;
1381 else
1382 q_coffd = q_pwr >> 7;
1403 1383
1404 /* protect against divide by 0 and loss of sign bits */ 1384 /* protect against divide by 0 and loss of sign bits */
1405 if (i_coffd == 0 || q_coffd < 2) 1385 if (i_coffd == 0 || q_coffd < 2)
@@ -1768,7 +1748,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1768* Antenna control * 1748* Antenna control *
1769\*****************/ 1749\*****************/
1770 1750
1771void /*TODO:Boundary check*/ 1751static void /*TODO:Boundary check*/
1772ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) 1752ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1773{ 1753{
1774 ATH5K_TRACE(ah->ah_sc); 1754 ATH5K_TRACE(ah->ah_sc);
@@ -1777,16 +1757,6 @@ ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1777 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); 1757 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
1778} 1758}
1779 1759
1780unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
1781{
1782 ATH5K_TRACE(ah->ah_sc);
1783
1784 if (ah->ah_version != AR5K_AR5210)
1785 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
1786
1787 return false; /*XXX: What do we return for 5210 ?*/
1788}
1789
1790/* 1760/*
1791 * Enable/disable fast rx antenna diversity 1761 * Enable/disable fast rx antenna diversity
1792 */ 1762 */
@@ -1930,6 +1900,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1930 1900
1931 ah->ah_tx_ant = tx_ant; 1901 ah->ah_tx_ant = tx_ant;
1932 ah->ah_ant_mode = ant_mode; 1902 ah->ah_ant_mode = ant_mode;
1903 ah->ah_def_ant = def_ant;
1933 1904
1934 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; 1905 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
1935 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; 1906 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
@@ -2440,19 +2411,6 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
2440 pcdac_tmp = pcdac_high_pwr; 2411 pcdac_tmp = pcdac_high_pwr;
2441 2412
2442 edge_flag = 0x40; 2413 edge_flag = 0x40;
2443#if 0
2444 /* If both min and max power limits are in lower
2445 * power curve's range, only use the low power curve.
2446 * TODO: min/max levels are related to target
2447 * power values requested from driver/user
2448 * XXX: Is this really needed ? */
2449 if (min_pwr < table_max[1] &&
2450 max_pwr < table_max[1]) {
2451 edge_flag = 0;
2452 pcdac_tmp = pcdac_low_pwr;
2453 max_pwr_idx = (table_max[1] - table_min[1])/2;
2454 }
2455#endif
2456 } else { 2414 } else {
2457 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ 2415 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
2458 pcdac_high_pwr = ah->ah_txpower.tmpL[0]; 2416 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
@@ -3143,5 +3101,3 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3143 3101
3144 return ath5k_hw_txpower(ah, channel, ee_mode, txpower); 3102 return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
3145} 3103}
3146
3147#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 9122a8556f45..f5831da33f7b 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -517,23 +517,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
517} 517}
518 518
519/* 519/*
520 * Get slot time from DCU
521 */
522unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
523{
524 unsigned int slot_time_clock;
525
526 ATH5K_TRACE(ah->ah_sc);
527
528 if (ah->ah_version == AR5K_AR5210)
529 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME);
530 else
531 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT);
532
533 return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff);
534}
535
536/*
537 * Set slot time on DCU 520 * Set slot time on DCU
538 */ 521 */
539int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 522int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 1464f89b249c..45d62e915e4c 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -212,10 +212,10 @@
212 * MIB control register 212 * MIB control register
213 */ 213 */
214#define AR5K_MIBC 0x0040 /* Register Address */ 214#define AR5K_MIBC 0x0040 /* Register Address */
215#define AR5K_MIBC_COW 0x00000001 /* Warn test indicator */ 215#define AR5K_MIBC_COW 0x00000001 /* Counter Overflow Warning */
216#define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */ 216#define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */
217#define AR5K_MIBC_CMC 0x00000004 /* Clean MIB Counters */ 217#define AR5K_MIBC_CMC 0x00000004 /* Clear MIB Counters */
218#define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe */ 218#define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe, increment all */
219 219
220/* 220/*
221 * Timeout prescale register 221 * Timeout prescale register
@@ -1516,7 +1516,14 @@
1516 AR5K_NAV_5210 : AR5K_NAV_5211) 1516 AR5K_NAV_5210 : AR5K_NAV_5211)
1517 1517
1518/* 1518/*
1519 * RTS success register 1519 * MIB counters:
1520 *
1521 * max value is 0xc000, if this is reached we get a MIB interrupt.
1522 * they can be controlled via AR5K_MIBC and are cleared on read.
1523 */
1524
1525/*
1526 * RTS success (MIB counter)
1520 */ 1527 */
1521#define AR5K_RTS_OK_5210 0x8090 1528#define AR5K_RTS_OK_5210 0x8090
1522#define AR5K_RTS_OK_5211 0x8088 1529#define AR5K_RTS_OK_5211 0x8088
@@ -1524,7 +1531,7 @@
1524 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211) 1531 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
1525 1532
1526/* 1533/*
1527 * RTS failure register 1534 * RTS failure (MIB counter)
1528 */ 1535 */
1529#define AR5K_RTS_FAIL_5210 0x8094 1536#define AR5K_RTS_FAIL_5210 0x8094
1530#define AR5K_RTS_FAIL_5211 0x808c 1537#define AR5K_RTS_FAIL_5211 0x808c
@@ -1532,7 +1539,7 @@
1532 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211) 1539 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
1533 1540
1534/* 1541/*
1535 * ACK failure register 1542 * ACK failure (MIB counter)
1536 */ 1543 */
1537#define AR5K_ACK_FAIL_5210 0x8098 1544#define AR5K_ACK_FAIL_5210 0x8098
1538#define AR5K_ACK_FAIL_5211 0x8090 1545#define AR5K_ACK_FAIL_5211 0x8090
@@ -1540,7 +1547,7 @@
1540 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211) 1547 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
1541 1548
1542/* 1549/*
1543 * FCS failure register 1550 * FCS failure (MIB counter)
1544 */ 1551 */
1545#define AR5K_FCS_FAIL_5210 0x809c 1552#define AR5K_FCS_FAIL_5210 0x809c
1546#define AR5K_FCS_FAIL_5211 0x8094 1553#define AR5K_FCS_FAIL_5211 0x8094
@@ -1667,11 +1674,17 @@
1667 1674
1668/* 1675/*
1669 * Profile count registers 1676 * Profile count registers
1677 *
1678 * These registers can be cleared and freezed with ATH5K_MIBC, but they do not
1679 * generate a MIB interrupt.
1680 * Instead of overflowing, they shift by one bit to the right. All registers
1681 * shift together, i.e. when one reaches the max, all shift at the same time by
1682 * one bit to the right. This way we should always get consistent values.
1670 */ 1683 */
1671#define AR5K_PROFCNT_TX 0x80ec /* Tx count */ 1684#define AR5K_PROFCNT_TX 0x80ec /* Tx count */
1672#define AR5K_PROFCNT_RX 0x80f0 /* Rx count */ 1685#define AR5K_PROFCNT_RX 0x80f0 /* Rx count */
1673#define AR5K_PROFCNT_RXCLR 0x80f4 /* Clear Rx count */ 1686#define AR5K_PROFCNT_RXCLR 0x80f4 /* Busy count */
1674#define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ 1687#define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle counter */
1675 1688
1676/* 1689/*
1677 * Quiet period control registers 1690 * Quiet period control registers
@@ -1758,7 +1771,7 @@
1758#define AR5K_CCK_FIL_CNT 0x8128 1771#define AR5K_CCK_FIL_CNT 0x8128
1759 1772
1760/* 1773/*
1761 * PHY Error Counters (?) 1774 * PHY Error Counters (same masks as AR5K_PHY_ERR_FIL)
1762 */ 1775 */
1763#define AR5K_PHYERR_CNT1 0x812c 1776#define AR5K_PHYERR_CNT1 0x812c
1764#define AR5K_PHYERR_CNT1_MASK 0x8130 1777#define AR5K_PHYERR_CNT1_MASK 0x8130
@@ -1766,6 +1779,9 @@
1766#define AR5K_PHYERR_CNT2 0x8134 1779#define AR5K_PHYERR_CNT2 0x8134
1767#define AR5K_PHYERR_CNT2_MASK 0x8138 1780#define AR5K_PHYERR_CNT2_MASK 0x8138
1768 1781
1782/* if the PHY Error Counters reach this maximum, we get MIB interrupts */
1783#define ATH5K_PHYERR_CNT_MAX 0x00c00000
1784
1769/* 1785/*
1770 * TSF Threshold register (?) 1786 * TSF Threshold register (?)
1771 */ 1787 */
@@ -1974,7 +1990,7 @@
1974#define AR5K_PHY_SETTLING 0x9844 /* Register Address */ 1990#define AR5K_PHY_SETTLING 0x9844 /* Register Address */
1975#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ 1991#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */
1976#define AR5K_PHY_SETTLING_AGC_S 0 1992#define AR5K_PHY_SETTLING_AGC_S 0
1977#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ 1993#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settling time */
1978#define AR5K_PHY_SETTLING_SWITCH_S 7 1994#define AR5K_PHY_SETTLING_SWITCH_S 7
1979 1995
1980/* 1996/*
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index cbf28e379843..44bbbf2a6edd 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -19,8 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#define _ATH5K_RESET
23
24/*****************************\ 22/*****************************\
25 Reset functions and helpers 23 Reset functions and helpers
26\*****************************/ 24\*****************************/
@@ -34,6 +32,27 @@
34#include "base.h" 32#include "base.h"
35#include "debug.h" 33#include "debug.h"
36 34
35/*
36 * Check if a register write has been completed
37 */
38int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
39 bool is_set)
40{
41 int i;
42 u32 data;
43
44 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
45 data = ath5k_hw_reg_read(ah, reg);
46 if (is_set && (data & flag))
47 break;
48 else if ((data & flag) == val)
49 break;
50 udelay(15);
51 }
52
53 return (i <= 0) ? -EAGAIN : 0;
54}
55
37/** 56/**
38 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 57 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
39 * 58 *
@@ -221,8 +240,8 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
221/* 240/*
222 * Sleep control 241 * Sleep control
223 */ 242 */
224int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, 243static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
225 bool set_chip, u16 sleep_duration) 244 bool set_chip, u16 sleep_duration)
226{ 245{
227 unsigned int i; 246 unsigned int i;
228 u32 staid, data; 247 u32 staid, data;
@@ -1017,11 +1036,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1017 if (ret) 1036 if (ret)
1018 return ret; 1037 return ret;
1019 1038
1020 /*
1021 * Initialize operating mode
1022 */
1023 ah->ah_op_mode = op_mode;
1024
1025 /* PHY access enable */ 1039 /* PHY access enable */
1026 if (ah->ah_mac_srev >= AR5K_SREV_AR5211) 1040 if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
1027 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); 1041 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
@@ -1192,7 +1206,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1192 ath5k_hw_set_associd(ah); 1206 ath5k_hw_set_associd(ah);
1193 1207
1194 /* Set PCU config */ 1208 /* Set PCU config */
1195 ath5k_hw_set_opmode(ah); 1209 ath5k_hw_set_opmode(ah, op_mode);
1196 1210
1197 /* Clear any pending interrupts 1211 /* Clear any pending interrupts
1198 * PISR/SISR Not available on 5210 */ 1212 * PISR/SISR Not available on 5210 */
@@ -1378,7 +1392,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1378 * external 32KHz crystal when sleeping if one 1392 * external 32KHz crystal when sleeping if one
1379 * exists */ 1393 * exists */
1380 if (ah->ah_version == AR5K_AR5212 && 1394 if (ah->ah_version == AR5K_AR5212 &&
1381 ah->ah_op_mode != NL80211_IFTYPE_AP) 1395 op_mode != NL80211_IFTYPE_AP)
1382 ath5k_hw_set_sleep_clock(ah, true); 1396 ath5k_hw_set_sleep_clock(ah, true);
1383 1397
1384 /* 1398 /*
@@ -1388,5 +1402,3 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1388 ath5k_hw_reset_tsf(ah); 1402 ath5k_hw_reset_tsf(ah);
1389 return 0; 1403 return 0;
1390} 1404}
1391
1392#undef _ATH5K_RESET
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 5774cea23a3b..35f23bdc442f 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -32,3 +32,24 @@ config ATH9K_DEBUGFS
32 32
33 Also required for changing debug message flags at run time. 33 Also required for changing debug message flags at run time.
34 34
35config ATH9K_HTC
36 tristate "Atheros HTC based wireless cards support"
37 depends on USB && MAC80211
38 select ATH9K_HW
39 select MAC80211_LEDS
40 select LEDS_CLASS
41 select NEW_LEDS
42 select ATH9K_COMMON
43 ---help---
44 Support for Atheros HTC based cards.
45 Chipsets supported: AR9271
46
47 For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc
48
49 The built module will be ath9k_htc.
50
51config ATH9K_HTC_DEBUGFS
52 bool "Atheros ath9k_htc debugging"
53 depends on ATH9K_HTC && DEBUG_FS
54 ---help---
55 Say Y, if you need access to ath9k_htc's statistics.
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 6b50d5eb9ec3..97133beda269 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -28,3 +28,13 @@ obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
28 28
29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o 29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
30ath9k_common-y:= common.o 30ath9k_common-y:= common.o
31
32ath9k_htc-y += htc_hst.o \
33 hif_usb.o \
34 wmi.o \
35 htc_drv_txrx.o \
36 htc_drv_main.o \
37 htc_drv_beacon.o \
38 htc_drv_init.o
39
40obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index ca4994f13151..85fdd26039c8 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -47,6 +47,7 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
47} 47}
48 48
49static struct ath_bus_ops ath_ahb_bus_ops = { 49static struct ath_bus_ops ath_ahb_bus_ops = {
50 .ath_bus_type = ATH_AHB,
50 .read_cachesize = ath_ahb_read_cachesize, 51 .read_cachesize = ath_ahb_read_cachesize,
51 .eeprom_read = ath_ahb_eeprom_read, 52 .eeprom_read = ath_ahb_eeprom_read,
52}; 53};
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 83c7ea4c007f..bdcd257ca7a4 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -178,9 +178,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
178#define BAW_WITHIN(_start, _bawsz, _seqno) \ 178#define BAW_WITHIN(_start, _bawsz, _seqno) \
179 ((((_seqno) - (_start)) & 4095) < (_bawsz)) 179 ((((_seqno) - (_start)) & 4095) < (_bawsz))
180 180
181#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
182#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
183#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
184#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) 181#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
185 182
186#define ATH_TX_COMPLETE_POLL_INT 1000 183#define ATH_TX_COMPLETE_POLL_INT 1000
@@ -483,7 +480,6 @@ struct ath_softc {
483 bool ps_enabled; 480 bool ps_enabled;
484 bool ps_idle; 481 bool ps_idle;
485 unsigned long ps_usecount; 482 unsigned long ps_usecount;
486 enum ath9k_int imask;
487 483
488 struct ath_config config; 484 struct ath_config config;
489 struct ath_rx rx; 485 struct ath_rx rx;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index b4a31a43a62c..22375a754718 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -524,6 +524,7 @@ static void ath9k_beacon_init(struct ath_softc *sc,
524static void ath_beacon_config_ap(struct ath_softc *sc, 524static void ath_beacon_config_ap(struct ath_softc *sc,
525 struct ath_beacon_config *conf) 525 struct ath_beacon_config *conf)
526{ 526{
527 struct ath_hw *ah = sc->sc_ah;
527 u32 nexttbtt, intval; 528 u32 nexttbtt, intval;
528 529
529 /* NB: the beacon interval is kept internally in TU's */ 530 /* NB: the beacon interval is kept internally in TU's */
@@ -539,15 +540,15 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
539 * prepare beacon frames. 540 * prepare beacon frames.
540 */ 541 */
541 intval |= ATH9K_BEACON_ENA; 542 intval |= ATH9K_BEACON_ENA;
542 sc->imask |= ATH9K_INT_SWBA; 543 ah->imask |= ATH9K_INT_SWBA;
543 ath_beaconq_config(sc); 544 ath_beaconq_config(sc);
544 545
545 /* Set the computed AP beacon timers */ 546 /* Set the computed AP beacon timers */
546 547
547 ath9k_hw_set_interrupts(sc->sc_ah, 0); 548 ath9k_hw_set_interrupts(ah, 0);
548 ath9k_beacon_init(sc, nexttbtt, intval); 549 ath9k_beacon_init(sc, nexttbtt, intval);
549 sc->beacon.bmisscnt = 0; 550 sc->beacon.bmisscnt = 0;
550 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 551 ath9k_hw_set_interrupts(ah, ah->imask);
551 552
552 /* Clear the reset TSF flag, so that subsequent beacon updation 553 /* Clear the reset TSF flag, so that subsequent beacon updation
553 will not reset the HW TSF. */ 554 will not reset the HW TSF. */
@@ -566,7 +567,8 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
566static void ath_beacon_config_sta(struct ath_softc *sc, 567static void ath_beacon_config_sta(struct ath_softc *sc,
567 struct ath_beacon_config *conf) 568 struct ath_beacon_config *conf)
568{ 569{
569 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 570 struct ath_hw *ah = sc->sc_ah;
571 struct ath_common *common = ath9k_hw_common(ah);
570 struct ath9k_beacon_state bs; 572 struct ath9k_beacon_state bs;
571 int dtimperiod, dtimcount, sleepduration; 573 int dtimperiod, dtimcount, sleepduration;
572 int cfpperiod, cfpcount; 574 int cfpperiod, cfpcount;
@@ -605,7 +607,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
605 * Pull nexttbtt forward to reflect the current 607 * Pull nexttbtt forward to reflect the current
606 * TSF and calculate dtim+cfp state for the result. 608 * TSF and calculate dtim+cfp state for the result.
607 */ 609 */
608 tsf = ath9k_hw_gettsf64(sc->sc_ah); 610 tsf = ath9k_hw_gettsf64(ah);
609 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 611 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
610 612
611 num_beacons = tsftu / intval + 1; 613 num_beacons = tsftu / intval + 1;
@@ -678,17 +680,18 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
678 680
679 /* Set the computed STA beacon timers */ 681 /* Set the computed STA beacon timers */
680 682
681 ath9k_hw_set_interrupts(sc->sc_ah, 0); 683 ath9k_hw_set_interrupts(ah, 0);
682 ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs); 684 ath9k_hw_set_sta_beacon_timers(ah, &bs);
683 sc->imask |= ATH9K_INT_BMISS; 685 ah->imask |= ATH9K_INT_BMISS;
684 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 686 ath9k_hw_set_interrupts(ah, ah->imask);
685} 687}
686 688
687static void ath_beacon_config_adhoc(struct ath_softc *sc, 689static void ath_beacon_config_adhoc(struct ath_softc *sc,
688 struct ath_beacon_config *conf, 690 struct ath_beacon_config *conf,
689 struct ieee80211_vif *vif) 691 struct ieee80211_vif *vif)
690{ 692{
691 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 693 struct ath_hw *ah = sc->sc_ah;
694 struct ath_common *common = ath9k_hw_common(ah);
692 u64 tsf; 695 u64 tsf;
693 u32 tsftu, intval, nexttbtt; 696 u32 tsftu, intval, nexttbtt;
694 697
@@ -703,7 +706,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
703 else if (intval) 706 else if (intval)
704 nexttbtt = roundup(nexttbtt, intval); 707 nexttbtt = roundup(nexttbtt, intval);
705 708
706 tsf = ath9k_hw_gettsf64(sc->sc_ah); 709 tsf = ath9k_hw_gettsf64(ah);
707 tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE; 710 tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
708 do { 711 do {
709 nexttbtt += intval; 712 nexttbtt += intval;
@@ -719,20 +722,20 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
719 * self-linked tx descriptor and let the hardware deal with things. 722 * self-linked tx descriptor and let the hardware deal with things.
720 */ 723 */
721 intval |= ATH9K_BEACON_ENA; 724 intval |= ATH9K_BEACON_ENA;
722 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) 725 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
723 sc->imask |= ATH9K_INT_SWBA; 726 ah->imask |= ATH9K_INT_SWBA;
724 727
725 ath_beaconq_config(sc); 728 ath_beaconq_config(sc);
726 729
727 /* Set the computed ADHOC beacon timers */ 730 /* Set the computed ADHOC beacon timers */
728 731
729 ath9k_hw_set_interrupts(sc->sc_ah, 0); 732 ath9k_hw_set_interrupts(ah, 0);
730 ath9k_beacon_init(sc, nexttbtt, intval); 733 ath9k_beacon_init(sc, nexttbtt, intval);
731 sc->beacon.bmisscnt = 0; 734 sc->beacon.bmisscnt = 0;
732 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 735 ath9k_hw_set_interrupts(ah, ah->imask);
733 736
734 /* FIXME: Handle properly when vif is NULL */ 737 /* FIXME: Handle properly when vif is NULL */
735 if (vif && sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL) 738 if (vif && ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
736 ath_beacon_start_adhoc(sc, vif); 739 ath_beacon_start_adhoc(sc, vif);
737} 740}
738 741
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 238a5744d8e9..064f5b51dfcd 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -18,6 +18,7 @@
18 18
19/* We can tune this as we go by monitoring really low values */ 19/* We can tune this as we go by monitoring really low values */
20#define ATH9K_NF_TOO_LOW -60 20#define ATH9K_NF_TOO_LOW -60
21#define AR9285_CLCAL_REDO_THRESH 1
21 22
22/* AR5416 may return very high value (like -31 dBm), in those cases the nf 23/* AR5416 may return very high value (like -31 dBm), in those cases the nf
23 * is incorrect and we should use the static NF value. Later we can try to 24 * is incorrect and we should use the static NF value. Later we can try to
@@ -101,9 +102,13 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
101 nf = 0 - ((nf ^ 0x1ff) + 1); 102 nf = 0 - ((nf ^ 0x1ff) + 1);
102 ath_print(common, ATH_DBG_CALIBRATE, 103 ath_print(common, ATH_DBG_CALIBRATE,
103 "NF calibrated [ctl] [chain 0] is %d\n", nf); 104 "NF calibrated [ctl] [chain 0] is %d\n", nf);
105
106 if (AR_SREV_9271(ah) && (nf >= -114))
107 nf = -116;
108
104 nfarray[0] = nf; 109 nfarray[0] = nf;
105 110
106 if (!AR_SREV_9285(ah)) { 111 if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
107 if (AR_SREV_9280_10_OR_LATER(ah)) 112 if (AR_SREV_9280_10_OR_LATER(ah))
108 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), 113 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
109 AR9280_PHY_CH1_MINCCA_PWR); 114 AR9280_PHY_CH1_MINCCA_PWR);
@@ -139,9 +144,13 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
139 nf = 0 - ((nf ^ 0x1ff) + 1); 144 nf = 0 - ((nf ^ 0x1ff) + 1);
140 ath_print(common, ATH_DBG_CALIBRATE, 145 ath_print(common, ATH_DBG_CALIBRATE,
141 "NF calibrated [ext] [chain 0] is %d\n", nf); 146 "NF calibrated [ext] [chain 0] is %d\n", nf);
147
148 if (AR_SREV_9271(ah) && (nf >= -114))
149 nf = -116;
150
142 nfarray[3] = nf; 151 nfarray[3] = nf;
143 152
144 if (!AR_SREV_9285(ah)) { 153 if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
145 if (AR_SREV_9280_10_OR_LATER(ah)) 154 if (AR_SREV_9280_10_OR_LATER(ah))
146 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), 155 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
147 AR9280_PHY_CH1_EXT_MINCCA_PWR); 156 AR9280_PHY_CH1_EXT_MINCCA_PWR);
@@ -621,7 +630,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
621 u8 chainmask, rx_chain_status; 630 u8 chainmask, rx_chain_status;
622 631
623 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK); 632 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
624 if (AR_SREV_9285(ah)) 633 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
625 chainmask = 0x9; 634 chainmask = 0x9;
626 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { 635 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
627 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4)) 636 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
@@ -715,7 +724,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
715 724
716 if (AR_SREV_9280(ah)) 725 if (AR_SREV_9280(ah))
717 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; 726 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
718 else if (AR_SREV_9285(ah)) 727 else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
719 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; 728 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
720 else if (AR_SREV_9287(ah)) 729 else if (AR_SREV_9287(ah))
721 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE; 730 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
@@ -1051,9 +1060,12 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
1051 /* Do NF cal only at longer intervals */ 1060 /* Do NF cal only at longer intervals */
1052 if (longcal) { 1061 if (longcal) {
1053 /* Do periodic PAOffset Cal */ 1062 /* Do periodic PAOffset Cal */
1054 if (AR_SREV_9271(ah)) 1063 if (AR_SREV_9271(ah)) {
1055 ath9k_hw_9271_pa_cal(ah, false); 1064 if (!ah->pacal_info.skipcount)
1056 else if (AR_SREV_9285_11_OR_LATER(ah)) { 1065 ath9k_hw_9271_pa_cal(ah, false);
1066 else
1067 ah->pacal_info.skipcount--;
1068 } else if (AR_SREV_9285_11_OR_LATER(ah)) {
1057 if (!ah->pacal_info.skipcount) 1069 if (!ah->pacal_info.skipcount)
1058 ath9k_hw_9285_pa_cal(ah, false); 1070 ath9k_hw_9285_pa_cal(ah, false);
1059 else 1071 else
@@ -1080,7 +1092,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
1080EXPORT_SYMBOL(ath9k_hw_calibrate); 1092EXPORT_SYMBOL(ath9k_hw_calibrate);
1081 1093
1082/* Carrier leakage Calibration fix */ 1094/* Carrier leakage Calibration fix */
1083static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) 1095static bool ar9285_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
1084{ 1096{
1085 struct ath_common *common = ath9k_hw_common(ah); 1097 struct ath_common *common = ath9k_hw_common(ah);
1086 1098
@@ -1121,6 +1133,62 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
1121 return true; 1133 return true;
1122} 1134}
1123 1135
1136static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
1137{
1138 int i;
1139 u_int32_t txgain_max;
1140 u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
1141 u_int32_t reg_clc_I0, reg_clc_Q0;
1142 u_int32_t i0_num = 0;
1143 u_int32_t q0_num = 0;
1144 u_int32_t total_num = 0;
1145 u_int32_t reg_rf2g5_org;
1146 bool retv = true;
1147
1148 if (!(ar9285_cl_cal(ah, chan)))
1149 return false;
1150
1151 txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
1152 AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
1153
1154 for (i = 0; i < (txgain_max+1); i++) {
1155 clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
1156 AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
1157 if (!(gain_mask & (1 << clc_gain))) {
1158 gain_mask |= (1 << clc_gain);
1159 clc_num++;
1160 }
1161 }
1162
1163 for (i = 0; i < clc_num; i++) {
1164 reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
1165 & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
1166 reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
1167 & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
1168 if (reg_clc_I0 == 0)
1169 i0_num++;
1170
1171 if (reg_clc_Q0 == 0)
1172 q0_num++;
1173 }
1174 total_num = i0_num + q0_num;
1175 if (total_num > AR9285_CLCAL_REDO_THRESH) {
1176 reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
1177 if (AR_SREV_9285E_20(ah)) {
1178 REG_WRITE(ah, AR9285_RF2G5,
1179 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
1180 AR9285_RF2G5_IC50TX_XE_SET);
1181 } else {
1182 REG_WRITE(ah, AR9285_RF2G5,
1183 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
1184 AR9285_RF2G5_IC50TX_SET);
1185 }
1186 retv = ar9285_cl_cal(ah, chan);
1187 REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
1188 }
1189 return retv;
1190}
1191
1124bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) 1192bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
1125{ 1193{
1126 struct ath_common *common = ath9k_hw_common(ah); 1194 struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 4d775ae141db..09effdedc8c0 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -255,7 +255,8 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
255 255
256 keyix = rx_stats->rs_keyix; 256 keyix = rx_stats->rs_keyix;
257 257
258 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { 258 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error &&
259 ieee80211_has_protected(fc)) {
259 rxs->flag |= RX_FLAG_DECRYPTED; 260 rxs->flag |= RX_FLAG_DECRYPTED;
260 } else if (ieee80211_has_protected(fc) 261 } else if (ieee80211_has_protected(fc)
261 && !decrypt_error && skb->len >= hdrlen + 4) { 262 && !decrypt_error && skb->len >= hdrlen + 4) {
@@ -286,6 +287,345 @@ int ath9k_cmn_padpos(__le16 frame_control)
286} 287}
287EXPORT_SYMBOL(ath9k_cmn_padpos); 288EXPORT_SYMBOL(ath9k_cmn_padpos);
288 289
290int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
291{
292 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
293
294 if (tx_info->control.hw_key) {
295 if (tx_info->control.hw_key->alg == ALG_WEP)
296 return ATH9K_KEY_TYPE_WEP;
297 else if (tx_info->control.hw_key->alg == ALG_TKIP)
298 return ATH9K_KEY_TYPE_TKIP;
299 else if (tx_info->control.hw_key->alg == ALG_CCMP)
300 return ATH9K_KEY_TYPE_AES;
301 }
302
303 return ATH9K_KEY_TYPE_CLEAR;
304}
305EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
306
307static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
308 enum nl80211_channel_type channel_type)
309{
310 u32 chanmode = 0;
311
312 switch (chan->band) {
313 case IEEE80211_BAND_2GHZ:
314 switch (channel_type) {
315 case NL80211_CHAN_NO_HT:
316 case NL80211_CHAN_HT20:
317 chanmode = CHANNEL_G_HT20;
318 break;
319 case NL80211_CHAN_HT40PLUS:
320 chanmode = CHANNEL_G_HT40PLUS;
321 break;
322 case NL80211_CHAN_HT40MINUS:
323 chanmode = CHANNEL_G_HT40MINUS;
324 break;
325 }
326 break;
327 case IEEE80211_BAND_5GHZ:
328 switch (channel_type) {
329 case NL80211_CHAN_NO_HT:
330 case NL80211_CHAN_HT20:
331 chanmode = CHANNEL_A_HT20;
332 break;
333 case NL80211_CHAN_HT40PLUS:
334 chanmode = CHANNEL_A_HT40PLUS;
335 break;
336 case NL80211_CHAN_HT40MINUS:
337 chanmode = CHANNEL_A_HT40MINUS;
338 break;
339 }
340 break;
341 default:
342 break;
343 }
344
345 return chanmode;
346}
347
348/*
349 * Update internal channel flags.
350 */
351void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
352 struct ath9k_channel *ichan)
353{
354 struct ieee80211_channel *chan = hw->conf.channel;
355 struct ieee80211_conf *conf = &hw->conf;
356
357 ichan->channel = chan->center_freq;
358 ichan->chan = chan;
359
360 if (chan->band == IEEE80211_BAND_2GHZ) {
361 ichan->chanmode = CHANNEL_G;
362 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
363 } else {
364 ichan->chanmode = CHANNEL_A;
365 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
366 }
367
368 if (conf_is_ht(conf))
369 ichan->chanmode = ath9k_get_extchanmode(chan,
370 conf->channel_type);
371}
372EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
373
374/*
375 * Get the internal channel reference.
376 */
377struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
378 struct ath_hw *ah)
379{
380 struct ieee80211_channel *curchan = hw->conf.channel;
381 struct ath9k_channel *channel;
382 u8 chan_idx;
383
384 chan_idx = curchan->hw_value;
385 channel = &ah->channels[chan_idx];
386 ath9k_cmn_update_ichannel(hw, channel);
387
388 return channel;
389}
390EXPORT_SYMBOL(ath9k_cmn_get_curchannel);
391
392static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
393 struct ath9k_keyval *hk, const u8 *addr,
394 bool authenticator)
395{
396 struct ath_hw *ah = common->ah;
397 const u8 *key_rxmic;
398 const u8 *key_txmic;
399
400 key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
401 key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
402
403 if (addr == NULL) {
404 /*
405 * Group key installation - only two key cache entries are used
406 * regardless of splitmic capability since group key is only
407 * used either for TX or RX.
408 */
409 if (authenticator) {
410 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
411 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
412 } else {
413 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
414 memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
415 }
416 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
417 }
418 if (!common->splitmic) {
419 /* TX and RX keys share the same key cache entry. */
420 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
421 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
422 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
423 }
424
425 /* Separate key cache entries for TX and RX */
426
427 /* TX key goes at first index, RX key at +32. */
428 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
429 if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
430 /* TX MIC entry failed. No need to proceed further */
431 ath_print(common, ATH_DBG_FATAL,
432 "Setting TX MIC Key Failed\n");
433 return 0;
434 }
435
436 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
437 /* XXX delete tx key on failure? */
438 return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
439}
440
441static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
442{
443 int i;
444
445 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
446 if (test_bit(i, common->keymap) ||
447 test_bit(i + 64, common->keymap))
448 continue; /* At least one part of TKIP key allocated */
449 if (common->splitmic &&
450 (test_bit(i + 32, common->keymap) ||
451 test_bit(i + 64 + 32, common->keymap)))
452 continue; /* At least one part of TKIP key allocated */
453
454 /* Found a free slot for a TKIP key */
455 return i;
456 }
457 return -1;
458}
459
460static int ath_reserve_key_cache_slot(struct ath_common *common)
461{
462 int i;
463
464 /* First, try to find slots that would not be available for TKIP. */
465 if (common->splitmic) {
466 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
467 if (!test_bit(i, common->keymap) &&
468 (test_bit(i + 32, common->keymap) ||
469 test_bit(i + 64, common->keymap) ||
470 test_bit(i + 64 + 32, common->keymap)))
471 return i;
472 if (!test_bit(i + 32, common->keymap) &&
473 (test_bit(i, common->keymap) ||
474 test_bit(i + 64, common->keymap) ||
475 test_bit(i + 64 + 32, common->keymap)))
476 return i + 32;
477 if (!test_bit(i + 64, common->keymap) &&
478 (test_bit(i , common->keymap) ||
479 test_bit(i + 32, common->keymap) ||
480 test_bit(i + 64 + 32, common->keymap)))
481 return i + 64;
482 if (!test_bit(i + 64 + 32, common->keymap) &&
483 (test_bit(i, common->keymap) ||
484 test_bit(i + 32, common->keymap) ||
485 test_bit(i + 64, common->keymap)))
486 return i + 64 + 32;
487 }
488 } else {
489 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
490 if (!test_bit(i, common->keymap) &&
491 test_bit(i + 64, common->keymap))
492 return i;
493 if (test_bit(i, common->keymap) &&
494 !test_bit(i + 64, common->keymap))
495 return i + 64;
496 }
497 }
498
499 /* No partially used TKIP slots, pick any available slot */
500 for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
501 /* Do not allow slots that could be needed for TKIP group keys
502 * to be used. This limitation could be removed if we know that
503 * TKIP will not be used. */
504 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
505 continue;
506 if (common->splitmic) {
507 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
508 continue;
509 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
510 continue;
511 }
512
513 if (!test_bit(i, common->keymap))
514 return i; /* Found a free slot for a key */
515 }
516
517 /* No free slot found */
518 return -1;
519}
520
521/*
522 * Configure encryption in the HW.
523 */
524int ath9k_cmn_key_config(struct ath_common *common,
525 struct ieee80211_vif *vif,
526 struct ieee80211_sta *sta,
527 struct ieee80211_key_conf *key)
528{
529 struct ath_hw *ah = common->ah;
530 struct ath9k_keyval hk;
531 const u8 *mac = NULL;
532 int ret = 0;
533 int idx;
534
535 memset(&hk, 0, sizeof(hk));
536
537 switch (key->alg) {
538 case ALG_WEP:
539 hk.kv_type = ATH9K_CIPHER_WEP;
540 break;
541 case ALG_TKIP:
542 hk.kv_type = ATH9K_CIPHER_TKIP;
543 break;
544 case ALG_CCMP:
545 hk.kv_type = ATH9K_CIPHER_AES_CCM;
546 break;
547 default:
548 return -EOPNOTSUPP;
549 }
550
551 hk.kv_len = key->keylen;
552 memcpy(hk.kv_val, key->key, key->keylen);
553
554 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
555 /* For now, use the default keys for broadcast keys. This may
556 * need to change with virtual interfaces. */
557 idx = key->keyidx;
558 } else if (key->keyidx) {
559 if (WARN_ON(!sta))
560 return -EOPNOTSUPP;
561 mac = sta->addr;
562
563 if (vif->type != NL80211_IFTYPE_AP) {
564 /* Only keyidx 0 should be used with unicast key, but
565 * allow this for client mode for now. */
566 idx = key->keyidx;
567 } else
568 return -EIO;
569 } else {
570 if (WARN_ON(!sta))
571 return -EOPNOTSUPP;
572 mac = sta->addr;
573
574 if (key->alg == ALG_TKIP)
575 idx = ath_reserve_key_cache_slot_tkip(common);
576 else
577 idx = ath_reserve_key_cache_slot(common);
578 if (idx < 0)
579 return -ENOSPC; /* no free key cache entries */
580 }
581
582 if (key->alg == ALG_TKIP)
583 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
584 vif->type == NL80211_IFTYPE_AP);
585 else
586 ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
587
588 if (!ret)
589 return -EIO;
590
591 set_bit(idx, common->keymap);
592 if (key->alg == ALG_TKIP) {
593 set_bit(idx + 64, common->keymap);
594 if (common->splitmic) {
595 set_bit(idx + 32, common->keymap);
596 set_bit(idx + 64 + 32, common->keymap);
597 }
598 }
599
600 return idx;
601}
602EXPORT_SYMBOL(ath9k_cmn_key_config);
603
604/*
605 * Delete Key.
606 */
607void ath9k_cmn_key_delete(struct ath_common *common,
608 struct ieee80211_key_conf *key)
609{
610 struct ath_hw *ah = common->ah;
611
612 ath9k_hw_keyreset(ah, key->hw_key_idx);
613 if (key->hw_key_idx < IEEE80211_WEP_NKID)
614 return;
615
616 clear_bit(key->hw_key_idx, common->keymap);
617 if (key->alg != ALG_TKIP)
618 return;
619
620 clear_bit(key->hw_key_idx + 64, common->keymap);
621 if (common->splitmic) {
622 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
623 clear_bit(key->hw_key_idx + 32, common->keymap);
624 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
625 }
626}
627EXPORT_SYMBOL(ath9k_cmn_key_delete);
628
289static int __init ath9k_cmn_init(void) 629static int __init ath9k_cmn_init(void)
290{ 630{
291 return 0; 631 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 042999c2fe9c..72a835d9e97f 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -23,6 +23,8 @@
23 23
24/* Common header for Atheros 802.11n base driver cores */ 24/* Common header for Atheros 802.11n base driver cores */
25 25
26#define IEEE80211_WEP_NKID 4
27
26#define WME_NUM_TID 16 28#define WME_NUM_TID 16
27#define WME_BA_BMP_SIZE 64 29#define WME_BA_BMP_SIZE 64
28#define WME_MAX_BA WME_BA_BMP_SIZE 30#define WME_MAX_BA WME_BA_BMP_SIZE
@@ -125,3 +127,14 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
125 bool decrypt_error); 127 bool decrypt_error);
126 128
127int ath9k_cmn_padpos(__le16 frame_control); 129int ath9k_cmn_padpos(__le16 frame_control);
130int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
131void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
132 struct ath9k_channel *ichan);
133struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
134 struct ath_hw *ah);
135int ath9k_cmn_key_config(struct ath_common *common,
136 struct ieee80211_vif *vif,
137 struct ieee80211_sta *sta,
138 struct ieee80211_key_conf *key);
139void ath9k_cmn_key_delete(struct ath_common *common,
140 struct ieee80211_key_conf *key);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 42d2a506845a..c7e895925393 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -556,10 +556,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
556} 556}
557 557
558void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 558void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
559 struct ath_buf *bf) 559 struct ath_buf *bf, struct ath_tx_status *ts)
560{ 560{
561 struct ath_desc *ds = bf->bf_desc;
562
563 if (bf_isampdu(bf)) { 561 if (bf_isampdu(bf)) {
564 if (bf_isxretried(bf)) 562 if (bf_isxretried(bf))
565 TX_STAT_INC(txq->axq_qnum, a_xretries); 563 TX_STAT_INC(txq->axq_qnum, a_xretries);
@@ -569,17 +567,17 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
569 TX_STAT_INC(txq->axq_qnum, completed); 567 TX_STAT_INC(txq->axq_qnum, completed);
570 } 568 }
571 569
572 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO) 570 if (ts->ts_status & ATH9K_TXERR_FIFO)
573 TX_STAT_INC(txq->axq_qnum, fifo_underrun); 571 TX_STAT_INC(txq->axq_qnum, fifo_underrun);
574 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XTXOP) 572 if (ts->ts_status & ATH9K_TXERR_XTXOP)
575 TX_STAT_INC(txq->axq_qnum, xtxop); 573 TX_STAT_INC(txq->axq_qnum, xtxop);
576 if (ds->ds_txstat.ts_status & ATH9K_TXERR_TIMER_EXPIRED) 574 if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
577 TX_STAT_INC(txq->axq_qnum, timer_exp); 575 TX_STAT_INC(txq->axq_qnum, timer_exp);
578 if (ds->ds_txstat.ts_flags & ATH9K_TX_DESC_CFG_ERR) 576 if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
579 TX_STAT_INC(txq->axq_qnum, desc_cfg_err); 577 TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
580 if (ds->ds_txstat.ts_flags & ATH9K_TX_DATA_UNDERRUN) 578 if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
581 TX_STAT_INC(txq->axq_qnum, data_underrun); 579 TX_STAT_INC(txq->axq_qnum, data_underrun);
582 if (ds->ds_txstat.ts_flags & ATH9K_TX_DELIM_UNDERRUN) 580 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
583 TX_STAT_INC(txq->axq_qnum, delim_underrun); 581 TX_STAT_INC(txq->axq_qnum, delim_underrun);
584} 582}
585 583
@@ -662,30 +660,29 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
662#undef PHY_ERR 660#undef PHY_ERR
663} 661}
664 662
665void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf) 663void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
666{ 664{
667#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ 665#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
668#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ 666#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
669 667
670 struct ath_desc *ds = bf->bf_desc;
671 u32 phyerr; 668 u32 phyerr;
672 669
673 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) 670 if (rs->rs_status & ATH9K_RXERR_CRC)
674 RX_STAT_INC(crc_err); 671 RX_STAT_INC(crc_err);
675 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) 672 if (rs->rs_status & ATH9K_RXERR_DECRYPT)
676 RX_STAT_INC(decrypt_crc_err); 673 RX_STAT_INC(decrypt_crc_err);
677 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) 674 if (rs->rs_status & ATH9K_RXERR_MIC)
678 RX_STAT_INC(mic_err); 675 RX_STAT_INC(mic_err);
679 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE) 676 if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
680 RX_STAT_INC(pre_delim_crc_err); 677 RX_STAT_INC(pre_delim_crc_err);
681 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST) 678 if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST)
682 RX_STAT_INC(post_delim_crc_err); 679 RX_STAT_INC(post_delim_crc_err);
683 if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY) 680 if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY)
684 RX_STAT_INC(decrypt_busy_err); 681 RX_STAT_INC(decrypt_busy_err);
685 682
686 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) { 683 if (rs->rs_status & ATH9K_RXERR_PHY) {
687 RX_STAT_INC(phy_err); 684 RX_STAT_INC(phy_err);
688 phyerr = ds->ds_rxstat.rs_phyerr & 0x24; 685 phyerr = rs->rs_phyerr & 0x24;
689 RX_PHY_ERR_INC(phyerr); 686 RX_PHY_ERR_INC(phyerr);
690 } 687 }
691 688
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 86780e68b31e..b2af9de755e6 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -167,8 +167,8 @@ void ath9k_debug_remove_root(void);
167void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 167void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
168void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); 168void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
169void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 169void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
170 struct ath_buf *bf); 170 struct ath_buf *bf, struct ath_tx_status *ts);
171void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf); 171void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
172void ath_debug_stat_retries(struct ath_softc *sc, int rix, 172void ath_debug_stat_retries(struct ath_softc *sc, int rix,
173 int xretries, int retries, u8 per); 173 int xretries, int retries, u8 per);
174 174
@@ -204,12 +204,13 @@ static inline void ath_debug_stat_rc(struct ath_softc *sc,
204 204
205static inline void ath_debug_stat_tx(struct ath_softc *sc, 205static inline void ath_debug_stat_tx(struct ath_softc *sc,
206 struct ath_txq *txq, 206 struct ath_txq *txq,
207 struct ath_buf *bf) 207 struct ath_buf *bf,
208 struct ath_tx_status *ts)
208{ 209{
209} 210}
210 211
211static inline void ath_debug_stat_rx(struct ath_softc *sc, 212static inline void ath_debug_stat_rx(struct ath_softc *sc,
212 struct ath_buf *bf) 213 struct ath_rx_status *rs)
213{ 214{
214} 215}
215 216
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index deab8beb0680..1e4578d303dd 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -283,22 +283,17 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
283 u32 timer_next, 283 u32 timer_next,
284 u32 timer_period) 284 u32 timer_period)
285{ 285{
286 struct ath_common *common = ath9k_hw_common(ah);
287 struct ath_softc *sc = (struct ath_softc *) common->priv;
288
289 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); 286 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
290 287
291 if ((sc->imask & ATH9K_INT_GENTIMER) == 0) { 288 if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
292 ath9k_hw_set_interrupts(ah, 0); 289 ath9k_hw_set_interrupts(ah, 0);
293 sc->imask |= ATH9K_INT_GENTIMER; 290 ah->imask |= ATH9K_INT_GENTIMER;
294 ath9k_hw_set_interrupts(ah, sc->imask); 291 ath9k_hw_set_interrupts(ah, ah->imask);
295 } 292 }
296} 293}
297 294
298static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) 295static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
299{ 296{
300 struct ath_common *common = ath9k_hw_common(ah);
301 struct ath_softc *sc = (struct ath_softc *) common->priv;
302 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 297 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
303 298
304 ath9k_hw_gen_timer_stop(ah, timer); 299 ath9k_hw_gen_timer_stop(ah, timer);
@@ -306,8 +301,8 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
306 /* if no timer is enabled, turn off interrupt mask */ 301 /* if no timer is enabled, turn off interrupt mask */
307 if (timer_table->timer_mask.val == 0) { 302 if (timer_table->timer_mask.val == 0) {
308 ath9k_hw_set_interrupts(ah, 0); 303 ath9k_hw_set_interrupts(ah, 0);
309 sc->imask &= ~ATH9K_INT_GENTIMER; 304 ah->imask &= ~ATH9K_INT_GENTIMER;
310 ath9k_hw_set_interrupts(ah, sc->imask); 305 ath9k_hw_set_interrupts(ah, ah->imask);
311 } 306 }
312} 307}
313 308
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
new file mode 100644
index 000000000000..3afc747ccfbf
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -0,0 +1,965 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#define ATH9K_FW_USB_DEV(devid, fw) \
20 { USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw }
21
22static struct usb_device_id ath9k_hif_usb_ids[] = {
23 ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"),
24 ATH9K_FW_USB_DEV(0x1006, "ar9271.fw"),
25 { },
26};
27
28MODULE_DEVICE_TABLE(usb, ath9k_hif_usb_ids);
29
30static int __hif_usb_tx(struct hif_device_usb *hif_dev);
31
32static void hif_usb_regout_cb(struct urb *urb)
33{
34 struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
35 struct hif_device_usb *hif_dev = cmd->hif_dev;
36
37 if (!hif_dev) {
38 usb_free_urb(urb);
39 if (cmd) {
40 if (cmd->skb)
41 dev_kfree_skb_any(cmd->skb);
42 kfree(cmd);
43 }
44 return;
45 }
46
47 switch (urb->status) {
48 case 0:
49 break;
50 case -ENOENT:
51 case -ECONNRESET:
52 break;
53 case -ENODEV:
54 case -ESHUTDOWN:
55 return;
56 default:
57 break;
58 }
59
60 if (cmd) {
61 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
62 cmd->skb, 1);
63 kfree(cmd);
64 usb_free_urb(urb);
65 }
66}
67
68static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
69 struct sk_buff *skb)
70{
71 struct urb *urb;
72 struct cmd_buf *cmd;
73 int ret = 0;
74
75 urb = usb_alloc_urb(0, GFP_KERNEL);
76 if (urb == NULL)
77 return -ENOMEM;
78
79 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
80 if (cmd == NULL) {
81 usb_free_urb(urb);
82 return -ENOMEM;
83 }
84
85 cmd->skb = skb;
86 cmd->hif_dev = hif_dev;
87
88 usb_fill_int_urb(urb, hif_dev->udev,
89 usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE),
90 skb->data, skb->len,
91 hif_usb_regout_cb, cmd, 1);
92
93 ret = usb_submit_urb(urb, GFP_KERNEL);
94 if (ret) {
95 usb_free_urb(urb);
96 kfree(cmd);
97 }
98
99 return ret;
100}
101
102static void hif_usb_tx_cb(struct urb *urb)
103{
104 struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
105 struct hif_device_usb *hif_dev = tx_buf->hif_dev;
106 struct sk_buff *skb;
107 bool drop, flush;
108
109 if (!hif_dev)
110 return;
111
112 switch (urb->status) {
113 case 0:
114 break;
115 case -ENOENT:
116 case -ECONNRESET:
117 break;
118 case -ENODEV:
119 case -ESHUTDOWN:
120 return;
121 default:
122 break;
123 }
124
125 if (tx_buf) {
126 spin_lock(&hif_dev->tx.tx_lock);
127 drop = !!(hif_dev->tx.flags & HIF_USB_TX_STOP);
128 flush = !!(hif_dev->tx.flags & HIF_USB_TX_FLUSH);
129 spin_unlock(&hif_dev->tx.tx_lock);
130
131 while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
132 if (!drop && !flush) {
133 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
134 skb, 1);
135 TX_STAT_INC(skb_completed);
136 } else {
137 dev_kfree_skb_any(skb);
138 }
139 }
140
141 if (flush)
142 return;
143
144 tx_buf->len = tx_buf->offset = 0;
145 __skb_queue_head_init(&tx_buf->skb_queue);
146
147 spin_lock(&hif_dev->tx.tx_lock);
148 list_del(&tx_buf->list);
149 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
150 hif_dev->tx.tx_buf_cnt++;
151 if (!drop)
152 __hif_usb_tx(hif_dev); /* Check for pending SKBs */
153 TX_STAT_INC(buf_completed);
154 spin_unlock(&hif_dev->tx.tx_lock);
155 }
156}
157
158/* TX lock has to be taken */
159static int __hif_usb_tx(struct hif_device_usb *hif_dev)
160{
161 struct tx_buf *tx_buf = NULL;
162 struct sk_buff *nskb = NULL;
163 int ret = 0, i;
164 u16 *hdr, tx_skb_cnt = 0;
165 u8 *buf;
166
167 if (hif_dev->tx.tx_skb_cnt == 0)
168 return 0;
169
170 /* Check if a free TX buffer is available */
171 if (list_empty(&hif_dev->tx.tx_buf))
172 return 0;
173
174 tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list);
175 list_del(&tx_buf->list);
176 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
177 hif_dev->tx.tx_buf_cnt--;
178
179 tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM);
180
181 for (i = 0; i < tx_skb_cnt; i++) {
182 nskb = __skb_dequeue(&hif_dev->tx.tx_skb_queue);
183
184 /* Should never be NULL */
185 BUG_ON(!nskb);
186
187 hif_dev->tx.tx_skb_cnt--;
188
189 buf = tx_buf->buf;
190 buf += tx_buf->offset;
191 hdr = (u16 *)buf;
192 *hdr++ = nskb->len;
193 *hdr++ = ATH_USB_TX_STREAM_MODE_TAG;
194 buf += 4;
195 memcpy(buf, nskb->data, nskb->len);
196 tx_buf->len = nskb->len + 4;
197
198 if (i < (tx_skb_cnt - 1))
199 tx_buf->offset += (((tx_buf->len - 1) / 4) + 1) * 4;
200
201 if (i == (tx_skb_cnt - 1))
202 tx_buf->len += tx_buf->offset;
203
204 __skb_queue_tail(&tx_buf->skb_queue, nskb);
205 TX_STAT_INC(skb_queued);
206 }
207
208 usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
209 usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
210 tx_buf->buf, tx_buf->len,
211 hif_usb_tx_cb, tx_buf);
212
213 ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
214 if (ret) {
215 tx_buf->len = tx_buf->offset = 0;
216 __skb_queue_purge(&tx_buf->skb_queue);
217 __skb_queue_head_init(&tx_buf->skb_queue);
218 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
219 hif_dev->tx.tx_buf_cnt++;
220 }
221
222 if (!ret)
223 TX_STAT_INC(buf_queued);
224
225 return ret;
226}
227
228static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
229 struct ath9k_htc_tx_ctl *tx_ctl)
230{
231 unsigned long flags;
232
233 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
234
235 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
236 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
237 return -ENODEV;
238 }
239
240 /* Check if the max queue count has been reached */
241 if (hif_dev->tx.tx_skb_cnt > MAX_TX_BUF_NUM) {
242 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
243 return -ENOMEM;
244 }
245
246 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
247 hif_dev->tx.tx_skb_cnt++;
248
249 /* Send normal frames immediately */
250 if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
251 __hif_usb_tx(hif_dev);
252
253 /* Check if AMPDUs have to be sent immediately */
254 if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
255 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
256 (hif_dev->tx.tx_skb_cnt < 2)) {
257 __hif_usb_tx(hif_dev);
258 }
259
260 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
261
262 return 0;
263}
264
265static void hif_usb_start(void *hif_handle, u8 pipe_id)
266{
267 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
268 unsigned long flags;
269
270 hif_dev->flags |= HIF_USB_START;
271
272 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
273 hif_dev->tx.flags &= ~HIF_USB_TX_STOP;
274 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
275}
276
277static void hif_usb_stop(void *hif_handle, u8 pipe_id)
278{
279 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
280 unsigned long flags;
281
282 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
283 __skb_queue_purge(&hif_dev->tx.tx_skb_queue);
284 hif_dev->tx.tx_skb_cnt = 0;
285 hif_dev->tx.flags |= HIF_USB_TX_STOP;
286 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
287}
288
289static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
290 struct ath9k_htc_tx_ctl *tx_ctl)
291{
292 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
293 int ret = 0;
294
295 switch (pipe_id) {
296 case USB_WLAN_TX_PIPE:
297 ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
298 break;
299 case USB_REG_OUT_PIPE:
300 ret = hif_usb_send_regout(hif_dev, skb);
301 break;
302 default:
303 dev_err(&hif_dev->udev->dev,
304 "ath9k_htc: Invalid TX pipe: %d\n", pipe_id);
305 ret = -EINVAL;
306 break;
307 }
308
309 return ret;
310}
311
312static struct ath9k_htc_hif hif_usb = {
313 .transport = ATH9K_HIF_USB,
314 .name = "ath9k_hif_usb",
315
316 .control_ul_pipe = USB_REG_OUT_PIPE,
317 .control_dl_pipe = USB_REG_IN_PIPE,
318
319 .start = hif_usb_start,
320 .stop = hif_usb_stop,
321 .send = hif_usb_send,
322};
323
324static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
325 struct sk_buff *skb)
326{
327 struct sk_buff *nskb, *skb_pool[8];
328 int index = 0, i = 0, chk_idx, len = skb->len;
329 int rx_remain_len = 0, rx_pkt_len = 0;
330 u16 pkt_len, pkt_tag, pool_index = 0;
331 u8 *ptr;
332
333 rx_remain_len = hif_dev->rx_remain_len;
334 rx_pkt_len = hif_dev->rx_transfer_len;
335
336 if (rx_remain_len != 0) {
337 struct sk_buff *remain_skb = hif_dev->remain_skb;
338
339 if (remain_skb) {
340 ptr = (u8 *) remain_skb->data;
341
342 index = rx_remain_len;
343 rx_remain_len -= hif_dev->rx_pad_len;
344 ptr += rx_pkt_len;
345
346 memcpy(ptr, skb->data, rx_remain_len);
347
348 rx_pkt_len += rx_remain_len;
349 hif_dev->rx_remain_len = 0;
350 skb_put(remain_skb, rx_pkt_len);
351
352 skb_pool[pool_index++] = remain_skb;
353
354 } else {
355 index = rx_remain_len;
356 }
357 }
358
359 while (index < len) {
360 ptr = (u8 *) skb->data;
361
362 pkt_len = ptr[index] + (ptr[index+1] << 8);
363 pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
364
365 if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
366 u16 pad_len;
367
368 pad_len = 4 - (pkt_len & 0x3);
369 if (pad_len == 4)
370 pad_len = 0;
371
372 chk_idx = index;
373 index = index + 4 + pkt_len + pad_len;
374
375 if (index > MAX_RX_BUF_SIZE) {
376 hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
377 hif_dev->rx_transfer_len =
378 MAX_RX_BUF_SIZE - chk_idx - 4;
379 hif_dev->rx_pad_len = pad_len;
380
381 nskb = __dev_alloc_skb(pkt_len + 32,
382 GFP_ATOMIC);
383 if (!nskb) {
384 dev_err(&hif_dev->udev->dev,
385 "ath9k_htc: RX memory allocation"
386 " error\n");
387 goto err;
388 }
389 skb_reserve(nskb, 32);
390 RX_STAT_INC(skb_allocated);
391
392 memcpy(nskb->data, &(skb->data[chk_idx+4]),
393 hif_dev->rx_transfer_len);
394
395 /* Record the buffer pointer */
396 hif_dev->remain_skb = nskb;
397 } else {
398 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
399 if (!nskb) {
400 dev_err(&hif_dev->udev->dev,
401 "ath9k_htc: RX memory allocation"
402 " error\n");
403 goto err;
404 }
405 skb_reserve(nskb, 32);
406 RX_STAT_INC(skb_allocated);
407
408 memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
409 skb_put(nskb, pkt_len);
410 skb_pool[pool_index++] = nskb;
411 }
412 } else {
413 RX_STAT_INC(skb_dropped);
414 return;
415 }
416 }
417
418err:
419 for (i = 0; i < pool_index; i++) {
420 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
421 skb_pool[i]->len, USB_WLAN_RX_PIPE);
422 RX_STAT_INC(skb_completed);
423 }
424}
425
426static void ath9k_hif_usb_rx_cb(struct urb *urb)
427{
428 struct sk_buff *skb = (struct sk_buff *) urb->context;
429 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
430 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
431 int ret;
432
433 if (!skb)
434 return;
435
436 if (!hif_dev)
437 goto free;
438
439 switch (urb->status) {
440 case 0:
441 break;
442 case -ENOENT:
443 case -ECONNRESET:
444 case -ENODEV:
445 case -ESHUTDOWN:
446 goto free;
447 default:
448 goto resubmit;
449 }
450
451 if (likely(urb->actual_length != 0)) {
452 skb_put(skb, urb->actual_length);
453 ath9k_hif_usb_rx_stream(hif_dev, skb);
454 }
455
456resubmit:
457 skb_reset_tail_pointer(skb);
458 skb_trim(skb, 0);
459
460 usb_anchor_urb(urb, &hif_dev->rx_submitted);
461 ret = usb_submit_urb(urb, GFP_ATOMIC);
462 if (ret) {
463 usb_unanchor_urb(urb);
464 goto free;
465 }
466
467 return;
468free:
469 dev_kfree_skb_any(skb);
470}
471
472static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
473{
474 struct sk_buff *skb = (struct sk_buff *) urb->context;
475 struct sk_buff *nskb;
476 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
477 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
478 int ret;
479
480 if (!skb)
481 return;
482
483 if (!hif_dev)
484 goto free;
485
486 switch (urb->status) {
487 case 0:
488 break;
489 case -ENOENT:
490 case -ECONNRESET:
491 case -ENODEV:
492 case -ESHUTDOWN:
493 goto free;
494 default:
495 goto resubmit;
496 }
497
498 if (likely(urb->actual_length != 0)) {
499 skb_put(skb, urb->actual_length);
500
501 nskb = __dev_alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
502 if (!nskb)
503 goto resubmit;
504
505 usb_fill_int_urb(urb, hif_dev->udev,
506 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
507 nskb->data, MAX_REG_IN_BUF_SIZE,
508 ath9k_hif_usb_reg_in_cb, nskb, 1);
509
510 ret = usb_submit_urb(urb, GFP_ATOMIC);
511 if (ret) {
512 dev_kfree_skb_any(nskb);
513 goto free;
514 }
515
516 ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
517 skb->len, USB_REG_IN_PIPE);
518
519 return;
520 }
521
522resubmit:
523 skb_reset_tail_pointer(skb);
524 skb_trim(skb, 0);
525
526 ret = usb_submit_urb(urb, GFP_ATOMIC);
527 if (ret)
528 goto free;
529
530 return;
531free:
532 dev_kfree_skb_any(skb);
533 urb->context = NULL;
534}
535
536static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
537{
538 unsigned long flags;
539 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
540
541 list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) {
542 list_del(&tx_buf->list);
543 usb_free_urb(tx_buf->urb);
544 kfree(tx_buf->buf);
545 kfree(tx_buf);
546 }
547
548 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
549 hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
550 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
551
552 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
553 &hif_dev->tx.tx_pending, list) {
554 usb_kill_urb(tx_buf->urb);
555 list_del(&tx_buf->list);
556 usb_free_urb(tx_buf->urb);
557 kfree(tx_buf->buf);
558 kfree(tx_buf);
559 }
560
561 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
562 hif_dev->tx.flags &= ~HIF_USB_TX_FLUSH;
563 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
564}
565
566static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
567{
568 struct tx_buf *tx_buf;
569 int i;
570
571 INIT_LIST_HEAD(&hif_dev->tx.tx_buf);
572 INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
573 spin_lock_init(&hif_dev->tx.tx_lock);
574 __skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
575
576 for (i = 0; i < MAX_TX_URB_NUM; i++) {
577 tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
578 if (!tx_buf)
579 goto err;
580
581 tx_buf->buf = kzalloc(MAX_TX_BUF_SIZE, GFP_KERNEL);
582 if (!tx_buf->buf)
583 goto err;
584
585 tx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
586 if (!tx_buf->urb)
587 goto err;
588
589 tx_buf->hif_dev = hif_dev;
590 __skb_queue_head_init(&tx_buf->skb_queue);
591
592 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
593 }
594
595 hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM;
596
597 return 0;
598err:
599 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
600 return -ENOMEM;
601}
602
603static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
604{
605 usb_kill_anchored_urbs(&hif_dev->rx_submitted);
606}
607
608static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
609{
610 struct urb *urb = NULL;
611 struct sk_buff *skb = NULL;
612 int i, ret;
613
614 init_usb_anchor(&hif_dev->rx_submitted);
615
616 for (i = 0; i < MAX_RX_URB_NUM; i++) {
617
618 /* Allocate URB */
619 urb = usb_alloc_urb(0, GFP_KERNEL);
620 if (urb == NULL) {
621 ret = -ENOMEM;
622 goto err_urb;
623 }
624
625 /* Allocate buffer */
626 skb = __dev_alloc_skb(MAX_RX_BUF_SIZE, GFP_KERNEL);
627 if (!skb) {
628 ret = -ENOMEM;
629 goto err_skb;
630 }
631
632 usb_fill_bulk_urb(urb, hif_dev->udev,
633 usb_rcvbulkpipe(hif_dev->udev,
634 USB_WLAN_RX_PIPE),
635 skb->data, MAX_RX_BUF_SIZE,
636 ath9k_hif_usb_rx_cb, skb);
637
638 /* Anchor URB */
639 usb_anchor_urb(urb, &hif_dev->rx_submitted);
640
641 /* Submit URB */
642 ret = usb_submit_urb(urb, GFP_KERNEL);
643 if (ret) {
644 usb_unanchor_urb(urb);
645 goto err_submit;
646 }
647 }
648
649 return 0;
650
651err_submit:
652 dev_kfree_skb_any(skb);
653err_skb:
654 usb_free_urb(urb);
655err_urb:
656 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
657 return ret;
658}
659
660static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
661{
662 if (hif_dev->reg_in_urb) {
663 usb_kill_urb(hif_dev->reg_in_urb);
664 if (hif_dev->reg_in_urb->context)
665 dev_kfree_skb_any((void *)hif_dev->reg_in_urb->context);
666 usb_free_urb(hif_dev->reg_in_urb);
667 hif_dev->reg_in_urb = NULL;
668 }
669}
670
671static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
672{
673 struct sk_buff *skb;
674
675 hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
676 if (hif_dev->reg_in_urb == NULL)
677 return -ENOMEM;
678
679 skb = __dev_alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
680 if (!skb)
681 goto err;
682
683 usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev,
684 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
685 skb->data, MAX_REG_IN_BUF_SIZE,
686 ath9k_hif_usb_reg_in_cb, skb, 1);
687
688 if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
689 goto err;
690
691 return 0;
692
693err:
694 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
695 return -ENOMEM;
696}
697
698static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
699{
700 /* TX */
701 if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
702 goto err;
703
704 /* RX */
705 if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
706 goto err;
707
708 /* Register Read/Write */
709 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
710 goto err;
711
712 return 0;
713err:
714 return -ENOMEM;
715}
716
717static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
718{
719 int transfer, err;
720 const void *data = hif_dev->firmware->data;
721 size_t len = hif_dev->firmware->size;
722 u32 addr = AR9271_FIRMWARE;
723 u8 *buf = kzalloc(4096, GFP_KERNEL);
724
725 if (!buf)
726 return -ENOMEM;
727
728 while (len) {
729 transfer = min_t(int, len, 4096);
730 memcpy(buf, data, transfer);
731
732 err = usb_control_msg(hif_dev->udev,
733 usb_sndctrlpipe(hif_dev->udev, 0),
734 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
735 addr >> 8, 0, buf, transfer, HZ);
736 if (err < 0) {
737 kfree(buf);
738 return err;
739 }
740
741 len -= transfer;
742 data += transfer;
743 addr += transfer;
744 }
745 kfree(buf);
746
747 /*
748 * Issue FW download complete command to firmware.
749 */
750 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
751 FIRMWARE_DOWNLOAD_COMP,
752 0x40 | USB_DIR_OUT,
753 AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ);
754 if (err)
755 return -EIO;
756
757 dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
758 "ar9271.fw", (unsigned long) hif_dev->firmware->size);
759
760 return 0;
761}
762
763static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
764 const char *fw_name)
765{
766 int ret;
767
768 /* Request firmware */
769 ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev);
770 if (ret) {
771 dev_err(&hif_dev->udev->dev,
772 "ath9k_htc: Firmware - %s not found\n", fw_name);
773 goto err_fw_req;
774 }
775
776 /* Download firmware */
777 ret = ath9k_hif_usb_download_fw(hif_dev);
778 if (ret) {
779 dev_err(&hif_dev->udev->dev,
780 "ath9k_htc: Firmware - %s download failed\n", fw_name);
781 goto err_fw_download;
782 }
783
784 /* Alloc URBs */
785 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
786 if (ret) {
787 dev_err(&hif_dev->udev->dev,
788 "ath9k_htc: Unable to allocate URBs\n");
789 goto err_urb;
790 }
791
792 return 0;
793
794err_urb:
795 /* Nothing */
796err_fw_download:
797 release_firmware(hif_dev->firmware);
798err_fw_req:
799 hif_dev->firmware = NULL;
800 return ret;
801}
802
803static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
804{
805 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
806 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
807 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
808}
809
810static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
811{
812 ath9k_hif_usb_dealloc_urbs(hif_dev);
813 if (hif_dev->firmware)
814 release_firmware(hif_dev->firmware);
815}
816
817static int ath9k_hif_usb_probe(struct usb_interface *interface,
818 const struct usb_device_id *id)
819{
820 struct usb_device *udev = interface_to_usbdev(interface);
821 struct hif_device_usb *hif_dev;
822 const char *fw_name = (const char *) id->driver_info;
823 int ret = 0;
824
825 hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
826 if (!hif_dev) {
827 ret = -ENOMEM;
828 goto err_alloc;
829 }
830
831 usb_get_dev(udev);
832 hif_dev->udev = udev;
833 hif_dev->interface = interface;
834 hif_dev->device_id = id->idProduct;
835#ifdef CONFIG_PM
836 udev->reset_resume = 1;
837#endif
838 usb_set_intfdata(interface, hif_dev);
839
840 ret = ath9k_hif_usb_dev_init(hif_dev, fw_name);
841 if (ret) {
842 ret = -EINVAL;
843 goto err_hif_init_usb;
844 }
845
846 hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev);
847 if (hif_dev->htc_handle == NULL) {
848 ret = -ENOMEM;
849 goto err_htc_hw_alloc;
850 }
851
852 ret = ath9k_htc_hw_init(&hif_usb, hif_dev->htc_handle, hif_dev,
853 &hif_dev->udev->dev, hif_dev->device_id,
854 ATH9K_HIF_USB);
855 if (ret) {
856 ret = -EINVAL;
857 goto err_htc_hw_init;
858 }
859
860 dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");
861
862 return 0;
863
864err_htc_hw_init:
865 ath9k_htc_hw_free(hif_dev->htc_handle);
866err_htc_hw_alloc:
867 ath9k_hif_usb_dev_deinit(hif_dev);
868err_hif_init_usb:
869 usb_set_intfdata(interface, NULL);
870 kfree(hif_dev);
871 usb_put_dev(udev);
872err_alloc:
873 return ret;
874}
875
876static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
877{
878 struct usb_device *udev = interface_to_usbdev(interface);
879 struct hif_device_usb *hif_dev =
880 (struct hif_device_usb *) usb_get_intfdata(interface);
881
882 if (hif_dev) {
883 ath9k_htc_hw_deinit(hif_dev->htc_handle, true);
884 ath9k_htc_hw_free(hif_dev->htc_handle);
885 ath9k_hif_usb_dev_deinit(hif_dev);
886 usb_set_intfdata(interface, NULL);
887 }
888
889 if (hif_dev->flags & HIF_USB_START)
890 usb_reset_device(udev);
891
892 kfree(hif_dev);
893 dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n");
894 usb_put_dev(udev);
895}
896
897#ifdef CONFIG_PM
898static int ath9k_hif_usb_suspend(struct usb_interface *interface,
899 pm_message_t message)
900{
901 struct hif_device_usb *hif_dev =
902 (struct hif_device_usb *) usb_get_intfdata(interface);
903
904 ath9k_hif_usb_dealloc_urbs(hif_dev);
905
906 return 0;
907}
908
909static int ath9k_hif_usb_resume(struct usb_interface *interface)
910{
911 struct hif_device_usb *hif_dev =
912 (struct hif_device_usb *) usb_get_intfdata(interface);
913 int ret;
914
915 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
916 if (ret)
917 return ret;
918
919 if (hif_dev->firmware) {
920 ret = ath9k_hif_usb_download_fw(hif_dev);
921 if (ret)
922 goto fail_resume;
923 } else {
924 ath9k_hif_usb_dealloc_urbs(hif_dev);
925 return -EIO;
926 }
927
928 mdelay(100);
929
930 ret = ath9k_htc_resume(hif_dev->htc_handle);
931
932 if (ret)
933 goto fail_resume;
934
935 return 0;
936
937fail_resume:
938 ath9k_hif_usb_dealloc_urbs(hif_dev);
939
940 return ret;
941}
942#endif
943
944static struct usb_driver ath9k_hif_usb_driver = {
945 .name = "ath9k_hif_usb",
946 .probe = ath9k_hif_usb_probe,
947 .disconnect = ath9k_hif_usb_disconnect,
948#ifdef CONFIG_PM
949 .suspend = ath9k_hif_usb_suspend,
950 .resume = ath9k_hif_usb_resume,
951 .reset_resume = ath9k_hif_usb_resume,
952#endif
953 .id_table = ath9k_hif_usb_ids,
954 .soft_unbind = 1,
955};
956
957int ath9k_hif_usb_init(void)
958{
959 return usb_register(&ath9k_hif_usb_driver);
960}
961
962void ath9k_hif_usb_exit(void)
963{
964 usb_deregister(&ath9k_hif_usb_driver);
965}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
new file mode 100644
index 000000000000..ea9257bdc411
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -0,0 +1,102 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_USB_H
18#define HTC_USB_H
19
20#define AR9271_FIRMWARE 0x501000
21#define AR9271_FIRMWARE_TEXT 0x903000
22
23#define FIRMWARE_DOWNLOAD 0x30
24#define FIRMWARE_DOWNLOAD_COMP 0x31
25
26#define ATH_USB_RX_STREAM_MODE_TAG 0x4e00
27#define ATH_USB_TX_STREAM_MODE_TAG 0x697e
28
29/* FIXME: Verify these numbers (with Windows) */
30#define MAX_TX_URB_NUM 8
31#define MAX_TX_BUF_NUM 1024
32#define MAX_TX_BUF_SIZE 32768
33#define MAX_TX_AGGR_NUM 20
34
35#define MAX_RX_URB_NUM 8
36#define MAX_RX_BUF_SIZE 16384
37
38#define MAX_REG_OUT_URB_NUM 1
39#define MAX_REG_OUT_BUF_NUM 8
40
41#define MAX_REG_IN_BUF_SIZE 64
42
43/* USB Endpoint definition */
44#define USB_WLAN_TX_PIPE 1
45#define USB_WLAN_RX_PIPE 2
46#define USB_REG_IN_PIPE 3
47#define USB_REG_OUT_PIPE 4
48
49#define HIF_USB_MAX_RXPIPES 2
50#define HIF_USB_MAX_TXPIPES 4
51
52struct tx_buf {
53 u8 *buf;
54 u16 len;
55 u16 offset;
56 struct urb *urb;
57 struct sk_buff_head skb_queue;
58 struct hif_device_usb *hif_dev;
59 struct list_head list;
60};
61
62#define HIF_USB_TX_STOP BIT(0)
63#define HIF_USB_TX_FLUSH BIT(1)
64
65struct hif_usb_tx {
66 u8 flags;
67 u8 tx_buf_cnt;
68 u16 tx_skb_cnt;
69 struct sk_buff_head tx_skb_queue;
70 struct list_head tx_buf;
71 struct list_head tx_pending;
72 spinlock_t tx_lock;
73};
74
75struct cmd_buf {
76 struct sk_buff *skb;
77 struct hif_device_usb *hif_dev;
78};
79
80#define HIF_USB_START BIT(0)
81
82struct hif_device_usb {
83 u16 device_id;
84 struct usb_device *udev;
85 struct usb_interface *interface;
86 const struct firmware *firmware;
87 struct htc_target *htc_handle;
88 struct hif_usb_tx tx;
89 struct urb *reg_in_urb;
90 struct usb_anchor rx_submitted;
91 struct sk_buff *remain_skb;
92 int rx_remain_len;
93 int rx_pkt_len;
94 int rx_transfer_len;
95 int rx_pad_len;
96 u8 flags; /* HIF_USB_* */
97};
98
99int ath9k_hif_usb_init(void);
100void ath9k_hif_usb_exit(void);
101
102#endif /* HTC_USB_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
new file mode 100644
index 000000000000..78213fc71b09
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -0,0 +1,462 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_H
18#define HTC_H
19
20#include <linux/module.h>
21#include <linux/usb.h>
22#include <linux/firmware.h>
23#include <linux/skbuff.h>
24#include <linux/netdevice.h>
25#include <linux/leds.h>
26#include <net/mac80211.h>
27
28#include "common.h"
29#include "htc_hst.h"
30#include "hif_usb.h"
31#include "wmi.h"
32
33#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
34#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
35#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
36#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
37
38#define ATH_DEFAULT_BMISS_LIMIT 10
39#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
40#define TSF_TO_TU(_h, _l) \
41 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
42
43extern struct ieee80211_ops ath9k_htc_ops;
44extern int htc_modparam_nohwcrypt;
45
46enum htc_phymode {
47 HTC_MODE_AUTO = 0,
48 HTC_MODE_11A = 1,
49 HTC_MODE_11B = 2,
50 HTC_MODE_11G = 3,
51 HTC_MODE_FH = 4,
52 HTC_MODE_TURBO_A = 5,
53 HTC_MODE_TURBO_G = 6,
54 HTC_MODE_11NA = 7,
55 HTC_MODE_11NG = 8
56};
57
58enum htc_opmode {
59 HTC_M_STA = 1,
60 HTC_M_IBSS = 0,
61 HTC_M_AHDEMO = 3,
62 HTC_M_HOSTAP = 6,
63 HTC_M_MONITOR = 8,
64 HTC_M_WDS = 2
65};
66
67#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
68#define ATH9K_HTC_AMPDU 1
69#define ATH9K_HTC_NORMAL 2
70
71#define ATH9K_HTC_TX_CTSONLY 0x1
72#define ATH9K_HTC_TX_RTSCTS 0x2
73#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
74
75struct tx_frame_hdr {
76 u8 data_type;
77 u8 node_idx;
78 u8 vif_idx;
79 u8 tidno;
80 u32 flags; /* ATH9K_HTC_TX_* */
81 u8 key_type;
82 u8 keyix;
83 u8 reserved[26];
84} __packed;
85
86struct tx_mgmt_hdr {
87 u8 node_idx;
88 u8 vif_idx;
89 u8 tidno;
90 u8 flags;
91 u8 key_type;
92 u8 keyix;
93 u16 reserved;
94} __packed;
95
96struct tx_beacon_header {
97 u8 len_changed;
98 u8 vif_index;
99 u16 rev;
100} __packed;
101
102struct ath9k_htc_target_hw {
103 u32 flags;
104 u32 flags_ext;
105 u32 ampdu_limit;
106 u8 ampdu_subframes;
107 u8 tx_chainmask;
108 u8 tx_chainmask_legacy;
109 u8 rtscts_ratecode;
110 u8 protmode;
111} __packed;
112
113struct ath9k_htc_cap_target {
114 u32 flags;
115 u32 flags_ext;
116 u32 ampdu_limit;
117 u8 ampdu_subframes;
118 u8 tx_chainmask;
119 u8 tx_chainmask_legacy;
120 u8 rtscts_ratecode;
121 u8 protmode;
122} __packed;
123
124struct ath9k_htc_target_vif {
125 u8 index;
126 u8 des_bssid[ETH_ALEN];
127 enum htc_opmode opmode;
128 u8 myaddr[ETH_ALEN];
129 u8 bssid[ETH_ALEN];
130 u32 flags;
131 u32 flags_ext;
132 u16 ps_sta;
133 u16 rtsthreshold;
134 u8 ath_cap;
135 u8 node;
136 s8 mcast_rate;
137} __packed;
138
139#define ATH_HTC_STA_AUTH 0x0001
140#define ATH_HTC_STA_QOS 0x0002
141#define ATH_HTC_STA_ERP 0x0004
142#define ATH_HTC_STA_HT 0x0008
143
144/* FIXME: UAPSD variables */
145struct ath9k_htc_target_sta {
146 u16 associd;
147 u16 txpower;
148 u32 ucastkey;
149 u8 macaddr[ETH_ALEN];
150 u8 bssid[ETH_ALEN];
151 u8 sta_index;
152 u8 vif_index;
153 u8 vif_sta;
154 u16 flags; /* ATH_HTC_STA_* */
155 u16 htcap;
156 u8 valid;
157 u16 capinfo;
158 struct ath9k_htc_target_hw *hw;
159 struct ath9k_htc_target_vif *vif;
160 u16 txseqmgmt;
161 u8 is_vif_sta;
162 u16 maxampdu;
163 u16 iv16;
164 u32 iv32;
165} __packed;
166
167struct ath9k_htc_target_aggr {
168 u8 sta_index;
169 u8 tidno;
170 u8 aggr_enable;
171 u8 padding;
172} __packed;
173
174#define ATH_HTC_RATE_MAX 30
175
176#define WLAN_RC_DS_FLAG 0x01
177#define WLAN_RC_40_FLAG 0x02
178#define WLAN_RC_SGI_FLAG 0x04
179#define WLAN_RC_HT_FLAG 0x08
180
181struct ath9k_htc_rateset {
182 u8 rs_nrates;
183 u8 rs_rates[ATH_HTC_RATE_MAX];
184};
185
186struct ath9k_htc_rate {
187 struct ath9k_htc_rateset legacy_rates;
188 struct ath9k_htc_rateset ht_rates;
189} __packed;
190
191struct ath9k_htc_target_rate {
192 u8 sta_index;
193 u8 isnew;
194 u32 capflags;
195 struct ath9k_htc_rate rates;
196};
197
198struct ath9k_htc_target_stats {
199 u32 tx_shortretry;
200 u32 tx_longretry;
201 u32 tx_xretries;
202 u32 ht_txunaggr_xretry;
203 u32 ht_tx_xretries;
204} __packed;
205
206struct ath9k_htc_vif {
207 u8 index;
208};
209
210#define ATH9K_HTC_MAX_STA 8
211#define ATH9K_HTC_MAX_TID 8
212
213enum tid_aggr_state {
214 AGGR_STOP = 0,
215 AGGR_PROGRESS,
216 AGGR_START,
217 AGGR_OPERATIONAL
218};
219
220struct ath9k_htc_sta {
221 u8 index;
222 enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
223};
224
225struct ath9k_htc_aggr_work {
226 u16 tid;
227 u8 sta_addr[ETH_ALEN];
228 struct ieee80211_hw *hw;
229 struct ieee80211_vif *vif;
230 enum ieee80211_ampdu_mlme_action action;
231 struct mutex mutex;
232};
233
234#define ATH9K_HTC_RXBUF 256
235#define HTC_RX_FRAME_HEADER_SIZE 40
236
237struct ath9k_htc_rxbuf {
238 bool in_process;
239 struct sk_buff *skb;
240 struct ath_htc_rx_status rxstatus;
241 struct list_head list;
242};
243
244struct ath9k_htc_rx {
245 int last_rssi; /* FIXME: per-STA */
246 struct list_head rxbuf;
247 spinlock_t rxbuflock;
248};
249
250struct ath9k_htc_tx_ctl {
251 u8 type; /* ATH9K_HTC_* */
252};
253
254#ifdef CONFIG_ATH9K_HTC_DEBUGFS
255
256#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
257#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
258
259struct ath_tx_stats {
260 u32 buf_queued;
261 u32 buf_completed;
262 u32 skb_queued;
263 u32 skb_completed;
264};
265
266struct ath_rx_stats {
267 u32 skb_allocated;
268 u32 skb_completed;
269 u32 skb_dropped;
270};
271
272struct ath9k_debug {
273 struct dentry *debugfs_phy;
274 struct dentry *debugfs_tgt_stats;
275 struct dentry *debugfs_xmit;
276 struct dentry *debugfs_recv;
277 struct ath_tx_stats tx_stats;
278 struct ath_rx_stats rx_stats;
279 u32 txrate;
280};
281
282#else
283
284#define TX_STAT_INC(c) do { } while (0)
285#define RX_STAT_INC(c) do { } while (0)
286
287#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
288
289#define ATH_LED_PIN_DEF 1
290#define ATH_LED_PIN_9287 8
291#define ATH_LED_PIN_9271 15
292#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
293#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
294
295enum ath_led_type {
296 ATH_LED_RADIO,
297 ATH_LED_ASSOC,
298 ATH_LED_TX,
299 ATH_LED_RX
300};
301
302struct ath_led {
303 struct ath9k_htc_priv *priv;
304 struct led_classdev led_cdev;
305 enum ath_led_type led_type;
306 struct delayed_work brightness_work;
307 char name[32];
308 bool registered;
309 int brightness;
310};
311
312struct htc_beacon_config {
313 u16 beacon_interval;
314 u16 listen_interval;
315 u16 dtim_period;
316 u16 bmiss_timeout;
317 u8 dtim_count;
318};
319
320#define OP_INVALID BIT(0)
321#define OP_SCANNING BIT(1)
322#define OP_FULL_RESET BIT(2)
323#define OP_LED_ASSOCIATED BIT(3)
324#define OP_LED_ON BIT(4)
325#define OP_PREAMBLE_SHORT BIT(5)
326#define OP_PROTECT_ENABLE BIT(6)
327#define OP_TXAGGR BIT(7)
328#define OP_ASSOCIATED BIT(8)
329#define OP_ENABLE_BEACON BIT(9)
330#define OP_LED_DEINIT BIT(10)
331
332struct ath9k_htc_priv {
333 struct device *dev;
334 struct ieee80211_hw *hw;
335 struct ath_hw *ah;
336 struct htc_target *htc;
337 struct wmi *wmi;
338
339 enum htc_endpoint_id wmi_cmd_ep;
340 enum htc_endpoint_id beacon_ep;
341 enum htc_endpoint_id cab_ep;
342 enum htc_endpoint_id uapsd_ep;
343 enum htc_endpoint_id mgmt_ep;
344 enum htc_endpoint_id data_be_ep;
345 enum htc_endpoint_id data_bk_ep;
346 enum htc_endpoint_id data_vi_ep;
347 enum htc_endpoint_id data_vo_ep;
348
349 u16 op_flags;
350 u16 curtxpow;
351 u16 txpowlimit;
352 u16 nvifs;
353 u16 nstations;
354 u16 seq_no;
355 u32 bmiss_cnt;
356
357 struct sk_buff *beacon;
358 spinlock_t beacon_lock;
359
360 bool tx_queues_stop;
361 spinlock_t tx_lock;
362
363 struct ieee80211_vif *vif;
364 struct htc_beacon_config cur_beacon_conf;
365 unsigned int rxfilter;
366 struct tasklet_struct wmi_tasklet;
367 struct tasklet_struct rx_tasklet;
368 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
369 struct ath9k_htc_rx rx;
370 struct tasklet_struct tx_tasklet;
371 struct sk_buff_head tx_queue;
372 struct ath9k_htc_aggr_work aggr_work;
373 struct delayed_work ath9k_aggr_work;
374 struct delayed_work ath9k_ani_work;
375 struct work_struct ps_work;
376
377 struct mutex htc_pm_lock;
378 unsigned long ps_usecount;
379 bool ps_enabled;
380
381 struct ath_led radio_led;
382 struct ath_led assoc_led;
383 struct ath_led tx_led;
384 struct ath_led rx_led;
385 struct delayed_work ath9k_led_blink_work;
386 int led_on_duration;
387 int led_off_duration;
388 int led_on_cnt;
389 int led_off_cnt;
390 int hwq_map[ATH9K_WME_AC_VO+1];
391
392#ifdef CONFIG_ATH9K_HTC_DEBUGFS
393 struct ath9k_debug debug;
394#endif
395 struct ath9k_htc_target_rate tgt_rate;
396
397 struct mutex mutex;
398};
399
400static inline void ath_read_cachesize(struct ath_common *common, int *csz)
401{
402 common->bus_ops->read_cachesize(common, csz);
403}
404
405void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
406 struct ieee80211_vif *vif);
407void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
408void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
409 struct ieee80211_vif *vif);
410
411void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
412 enum htc_endpoint_id ep_id);
413void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
414 bool txok);
415
416void ath9k_htc_station_work(struct work_struct *work);
417void ath9k_htc_aggr_work(struct work_struct *work);
418void ath9k_ani_work(struct work_struct *work);;
419
420int ath9k_tx_init(struct ath9k_htc_priv *priv);
421void ath9k_tx_tasklet(unsigned long data);
422int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
423void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
424bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
425 enum ath9k_tx_queue_subtype qtype);
426int get_hw_qnum(u16 queue, int *hwq_map);
427int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
428 struct ath9k_tx_queue_info *qinfo);
429
430int ath9k_rx_init(struct ath9k_htc_priv *priv);
431void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
432void ath9k_host_rx_init(struct ath9k_htc_priv *priv);
433void ath9k_rx_tasklet(unsigned long data);
434u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv);
435
436void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
437void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
438void ath9k_ps_work(struct work_struct *work);
439
440void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
441void ath9k_init_leds(struct ath9k_htc_priv *priv);
442void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
443
444int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
445 u16 devid);
446void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
447#ifdef CONFIG_PM
448int ath9k_htc_resume(struct htc_target *htc_handle);
449#endif
450#ifdef CONFIG_ATH9K_HTC_DEBUGFS
451int ath9k_htc_debug_create_root(void);
452void ath9k_htc_debug_remove_root(void);
453int ath9k_htc_init_debug(struct ath_hw *ah);
454void ath9k_htc_exit_debug(struct ath_hw *ah);
455#else
456static inline int ath9k_htc_debug_create_root(void) { return 0; };
457static inline void ath9k_htc_debug_remove_root(void) {};
458static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; };
459static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {};
460#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
461
462#endif /* HTC_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
new file mode 100644
index 000000000000..5e21f4d92ff5
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -0,0 +1,277 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#define FUDGE 2
20
21static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
22 struct htc_beacon_config *bss_conf)
23{
24 struct ath_common *common = ath9k_hw_common(priv->ah);
25 struct ath9k_beacon_state bs;
26 enum ath9k_int imask = 0;
27 int dtimperiod, dtimcount, sleepduration;
28 int cfpperiod, cfpcount, bmiss_timeout;
29 u32 nexttbtt = 0, intval, tsftu, htc_imask = 0;
30 u64 tsf;
31 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
32 int ret;
33 u8 cmd_rsp;
34
35 memset(&bs, 0, sizeof(bs));
36
37 intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
38 bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval);
39
40 /*
41 * Setup dtim and cfp parameters according to
42 * last beacon we received (which may be none).
43 */
44 dtimperiod = bss_conf->dtim_period;
45 if (dtimperiod <= 0) /* NB: 0 if not known */
46 dtimperiod = 1;
47 dtimcount = 1;
48 if (dtimcount >= dtimperiod) /* NB: sanity check */
49 dtimcount = 0;
50 cfpperiod = 1; /* NB: no PCF support yet */
51 cfpcount = 0;
52
53 sleepduration = intval;
54 if (sleepduration <= 0)
55 sleepduration = intval;
56
57 /*
58 * Pull nexttbtt forward to reflect the current
59 * TSF and calculate dtim+cfp state for the result.
60 */
61 tsf = ath9k_hw_gettsf64(priv->ah);
62 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
63
64 num_beacons = tsftu / intval + 1;
65 offset = tsftu % intval;
66 nexttbtt = tsftu - offset;
67 if (offset)
68 nexttbtt += intval;
69
70 /* DTIM Beacon every dtimperiod Beacon */
71 dtim_dec_count = num_beacons % dtimperiod;
72 /* CFP every cfpperiod DTIM Beacon */
73 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
74 if (dtim_dec_count)
75 cfp_dec_count++;
76
77 dtimcount -= dtim_dec_count;
78 if (dtimcount < 0)
79 dtimcount += dtimperiod;
80
81 cfpcount -= cfp_dec_count;
82 if (cfpcount < 0)
83 cfpcount += cfpperiod;
84
85 bs.bs_intval = intval;
86 bs.bs_nexttbtt = nexttbtt;
87 bs.bs_dtimperiod = dtimperiod*intval;
88 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
89 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
90 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
91 bs.bs_cfpmaxduration = 0;
92
93 /*
94 * Calculate the number of consecutive beacons to miss* before taking
95 * a BMISS interrupt. The configuration is specified in TU so we only
96 * need calculate based on the beacon interval. Note that we clamp the
97 * result to at most 15 beacons.
98 */
99 if (sleepduration > intval) {
100 bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2;
101 } else {
102 bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval);
103 if (bs.bs_bmissthreshold > 15)
104 bs.bs_bmissthreshold = 15;
105 else if (bs.bs_bmissthreshold <= 0)
106 bs.bs_bmissthreshold = 1;
107 }
108
109 /*
110 * Calculate sleep duration. The configuration is given in ms.
111 * We ensure a multiple of the beacon period is used. Also, if the sleep
112 * duration is greater than the DTIM period then it makes senses
113 * to make it a multiple of that.
114 *
115 * XXX fixed at 100ms
116 */
117
118 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
119 if (bs.bs_sleepduration > bs.bs_dtimperiod)
120 bs.bs_sleepduration = bs.bs_dtimperiod;
121
122 /* TSF out of range threshold fixed at 1 second */
123 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
124
125 ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
126 ath_print(common, ATH_DBG_BEACON,
127 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
128 bs.bs_bmissthreshold, bs.bs_sleepduration,
129 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
130
131 /* Set the computed STA beacon timers */
132
133 WMI_CMD(WMI_DISABLE_INTR_CMDID);
134 ath9k_hw_set_sta_beacon_timers(priv->ah, &bs);
135 imask |= ATH9K_INT_BMISS;
136 htc_imask = cpu_to_be32(imask);
137 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
138}
139
140static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
141 struct htc_beacon_config *bss_conf)
142{
143 struct ath_common *common = ath9k_hw_common(priv->ah);
144 enum ath9k_int imask = 0;
145 u32 nexttbtt, intval, htc_imask = 0;
146 int ret;
147 u8 cmd_rsp;
148
149 intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
150 nexttbtt = intval;
151 intval |= ATH9K_BEACON_ENA;
152 if (priv->op_flags & OP_ENABLE_BEACON)
153 imask |= ATH9K_INT_SWBA;
154
155 ath_print(common, ATH_DBG_BEACON,
156 "IBSS Beacon config, intval: %d, imask: 0x%x\n",
157 bss_conf->beacon_interval, imask);
158
159 WMI_CMD(WMI_DISABLE_INTR_CMDID);
160 ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
161 priv->bmiss_cnt = 0;
162 htc_imask = cpu_to_be32(imask);
163 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
164}
165
166void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
167 struct ieee80211_vif *vif)
168{
169 struct ath_common *common = ath9k_hw_common(priv->ah);
170
171 spin_lock_bh(&priv->beacon_lock);
172
173 if (priv->beacon)
174 dev_kfree_skb_any(priv->beacon);
175
176 priv->beacon = ieee80211_beacon_get(priv->hw, vif);
177 if (!priv->beacon)
178 ath_print(common, ATH_DBG_BEACON,
179 "Unable to allocate beacon\n");
180
181 spin_unlock_bh(&priv->beacon_lock);
182}
183
184void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
185{
186 struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv;
187 struct tx_beacon_header beacon_hdr;
188 struct ath9k_htc_tx_ctl tx_ctl;
189 struct ieee80211_tx_info *info;
190 u8 *tx_fhdr;
191
192 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
193 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
194
195 /* FIXME: Handle BMISS */
196 if (beacon_pending != 0) {
197 priv->bmiss_cnt++;
198 return;
199 }
200
201 spin_lock_bh(&priv->beacon_lock);
202
203 if (unlikely(priv->op_flags & OP_SCANNING)) {
204 spin_unlock_bh(&priv->beacon_lock);
205 return;
206 }
207
208 if (unlikely(priv->beacon == NULL)) {
209 spin_unlock_bh(&priv->beacon_lock);
210 return;
211 }
212
213 /* Free the old SKB first */
214 dev_kfree_skb_any(priv->beacon);
215
216 /* Get a new beacon */
217 priv->beacon = ieee80211_beacon_get(priv->hw, priv->vif);
218 if (!priv->beacon) {
219 spin_unlock_bh(&priv->beacon_lock);
220 return;
221 }
222
223 info = IEEE80211_SKB_CB(priv->beacon);
224 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
225 struct ieee80211_hdr *hdr =
226 (struct ieee80211_hdr *) priv->beacon->data;
227 priv->seq_no += 0x10;
228 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
229 hdr->seq_ctrl |= cpu_to_le16(priv->seq_no);
230 }
231
232 tx_ctl.type = ATH9K_HTC_NORMAL;
233 beacon_hdr.vif_index = avp->index;
234 tx_fhdr = skb_push(priv->beacon, sizeof(beacon_hdr));
235 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
236
237 htc_send(priv->htc, priv->beacon, priv->beacon_ep, &tx_ctl);
238
239 spin_unlock_bh(&priv->beacon_lock);
240}
241
242
243void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
244 struct ieee80211_vif *vif)
245{
246 struct ath_common *common = ath9k_hw_common(priv->ah);
247 enum nl80211_iftype iftype;
248 struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
249
250 if (vif) {
251 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
252 iftype = vif->type;
253 cur_conf->beacon_interval = bss_conf->beacon_int;
254 cur_conf->dtim_period = bss_conf->dtim_period;
255 cur_conf->listen_interval = 1;
256 cur_conf->dtim_count = 1;
257 cur_conf->bmiss_timeout =
258 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
259 } else
260 iftype = priv->ah->opmode;
261
262 if (cur_conf->beacon_interval == 0)
263 cur_conf->beacon_interval = 100;
264
265 switch (iftype) {
266 case NL80211_IFTYPE_STATION:
267 ath9k_htc_beacon_config_sta(priv, cur_conf);
268 break;
269 case NL80211_IFTYPE_ADHOC:
270 ath9k_htc_beacon_config_adhoc(priv, cur_conf);
271 break;
272 default:
273 ath_print(common, ATH_DBG_CONFIG,
274 "Unsupported beaconing mode\n");
275 return;
276 }
277}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
new file mode 100644
index 000000000000..aed53573c547
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -0,0 +1,723 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19MODULE_AUTHOR("Atheros Communications");
20MODULE_LICENSE("Dual BSD/GPL");
21MODULE_DESCRIPTION("Atheros driver 802.11n HTC based wireless devices");
22
23static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
24module_param_named(debug, ath9k_debug, uint, 0);
25MODULE_PARM_DESC(debug, "Debugging mask");
26
27int htc_modparam_nohwcrypt;
28module_param_named(nohwcrypt, htc_modparam_nohwcrypt, int, 0444);
29MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
30
31#define CHAN2G(_freq, _idx) { \
32 .center_freq = (_freq), \
33 .hw_value = (_idx), \
34 .max_power = 20, \
35}
36
37static struct ieee80211_channel ath9k_2ghz_channels[] = {
38 CHAN2G(2412, 0), /* Channel 1 */
39 CHAN2G(2417, 1), /* Channel 2 */
40 CHAN2G(2422, 2), /* Channel 3 */
41 CHAN2G(2427, 3), /* Channel 4 */
42 CHAN2G(2432, 4), /* Channel 5 */
43 CHAN2G(2437, 5), /* Channel 6 */
44 CHAN2G(2442, 6), /* Channel 7 */
45 CHAN2G(2447, 7), /* Channel 8 */
46 CHAN2G(2452, 8), /* Channel 9 */
47 CHAN2G(2457, 9), /* Channel 10 */
48 CHAN2G(2462, 10), /* Channel 11 */
49 CHAN2G(2467, 11), /* Channel 12 */
50 CHAN2G(2472, 12), /* Channel 13 */
51 CHAN2G(2484, 13), /* Channel 14 */
52};
53
54/* Atheros hardware rate code addition for short premble */
55#define SHPCHECK(__hw_rate, __flags) \
56 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0)
57
58#define RATE(_bitrate, _hw_rate, _flags) { \
59 .bitrate = (_bitrate), \
60 .flags = (_flags), \
61 .hw_value = (_hw_rate), \
62 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
63}
64
65static struct ieee80211_rate ath9k_legacy_rates[] = {
66 RATE(10, 0x1b, 0),
67 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */
68 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */
69 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */
70 RATE(60, 0x0b, 0),
71 RATE(90, 0x0f, 0),
72 RATE(120, 0x0a, 0),
73 RATE(180, 0x0e, 0),
74 RATE(240, 0x09, 0),
75 RATE(360, 0x0d, 0),
76 RATE(480, 0x08, 0),
77 RATE(540, 0x0c, 0),
78};
79
80static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
81{
82 int time_left;
83
84 /* Firmware can take up to 50ms to get ready, to be safe use 1 second */
85 time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
86 if (!time_left) {
87 dev_err(priv->dev, "ath9k_htc: Target is unresponsive\n");
88 return -ETIMEDOUT;
89 }
90
91 return 0;
92}
93
94static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
95{
96 ath9k_htc_exit_debug(priv->ah);
97 ath9k_hw_deinit(priv->ah);
98 tasklet_kill(&priv->wmi_tasklet);
99 tasklet_kill(&priv->rx_tasklet);
100 tasklet_kill(&priv->tx_tasklet);
101 kfree(priv->ah);
102 priv->ah = NULL;
103}
104
105static void ath9k_deinit_device(struct ath9k_htc_priv *priv)
106{
107 struct ieee80211_hw *hw = priv->hw;
108
109 wiphy_rfkill_stop_polling(hw->wiphy);
110 ath9k_deinit_leds(priv);
111 ieee80211_unregister_hw(hw);
112 ath9k_rx_cleanup(priv);
113 ath9k_tx_cleanup(priv);
114 ath9k_deinit_priv(priv);
115}
116
117static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
118 u16 service_id,
119 void (*tx) (void *,
120 struct sk_buff *,
121 enum htc_endpoint_id,
122 bool txok),
123 enum htc_endpoint_id *ep_id)
124{
125 struct htc_service_connreq req;
126
127 memset(&req, 0, sizeof(struct htc_service_connreq));
128
129 req.service_id = service_id;
130 req.ep_callbacks.priv = priv;
131 req.ep_callbacks.rx = ath9k_htc_rxep;
132 req.ep_callbacks.tx = tx;
133
134 return htc_connect_service(priv->htc, &req, ep_id);
135}
136
137static int ath9k_init_htc_services(struct ath9k_htc_priv *priv)
138{
139 int ret;
140
141 /* WMI CMD*/
142 ret = ath9k_wmi_connect(priv->htc, priv->wmi, &priv->wmi_cmd_ep);
143 if (ret)
144 goto err;
145
146 /* Beacon */
147 ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, NULL,
148 &priv->beacon_ep);
149 if (ret)
150 goto err;
151
152 /* CAB */
153 ret = ath9k_htc_connect_svc(priv, WMI_CAB_SVC, ath9k_htc_txep,
154 &priv->cab_ep);
155 if (ret)
156 goto err;
157
158
159 /* UAPSD */
160 ret = ath9k_htc_connect_svc(priv, WMI_UAPSD_SVC, ath9k_htc_txep,
161 &priv->uapsd_ep);
162 if (ret)
163 goto err;
164
165 /* MGMT */
166 ret = ath9k_htc_connect_svc(priv, WMI_MGMT_SVC, ath9k_htc_txep,
167 &priv->mgmt_ep);
168 if (ret)
169 goto err;
170
171 /* DATA BE */
172 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BE_SVC, ath9k_htc_txep,
173 &priv->data_be_ep);
174 if (ret)
175 goto err;
176
177 /* DATA BK */
178 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BK_SVC, ath9k_htc_txep,
179 &priv->data_bk_ep);
180 if (ret)
181 goto err;
182
183 /* DATA VI */
184 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VI_SVC, ath9k_htc_txep,
185 &priv->data_vi_ep);
186 if (ret)
187 goto err;
188
189 /* DATA VO */
190 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VO_SVC, ath9k_htc_txep,
191 &priv->data_vo_ep);
192 if (ret)
193 goto err;
194
195 ret = htc_init(priv->htc);
196 if (ret)
197 goto err;
198
199 return 0;
200
201err:
202 dev_err(priv->dev, "ath9k_htc: Unable to initialize HTC services\n");
203 return ret;
204}
205
206static int ath9k_reg_notifier(struct wiphy *wiphy,
207 struct regulatory_request *request)
208{
209 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
210 struct ath9k_htc_priv *priv = hw->priv;
211
212 return ath_reg_notifier_apply(wiphy, request,
213 ath9k_hw_regulatory(priv->ah));
214}
215
216static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
217{
218 struct ath_hw *ah = (struct ath_hw *) hw_priv;
219 struct ath_common *common = ath9k_hw_common(ah);
220 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
221 __be32 val, reg = cpu_to_be32(reg_offset);
222 int r;
223
224 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
225 (u8 *) &reg, sizeof(reg),
226 (u8 *) &val, sizeof(val),
227 100);
228 if (unlikely(r)) {
229 ath_print(common, ATH_DBG_WMI,
230 "REGISTER READ FAILED: (0x%04x, %d)\n",
231 reg_offset, r);
232 return -EIO;
233 }
234
235 return be32_to_cpu(val);
236}
237
238static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
239{
240 struct ath_hw *ah = (struct ath_hw *) hw_priv;
241 struct ath_common *common = ath9k_hw_common(ah);
242 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
243 __be32 buf[2] = {
244 cpu_to_be32(reg_offset),
245 cpu_to_be32(val),
246 };
247 int r;
248
249 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
250 (u8 *) &buf, sizeof(buf),
251 (u8 *) &val, sizeof(val),
252 100);
253 if (unlikely(r)) {
254 ath_print(common, ATH_DBG_WMI,
255 "REGISTER WRITE FAILED:(0x%04x, %d)\n",
256 reg_offset, r);
257 }
258}
259
260static const struct ath_ops ath9k_common_ops = {
261 .read = ath9k_ioread32,
262 .write = ath9k_iowrite32,
263};
264
265static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
266{
267 *csz = L1_CACHE_BYTES >> 2;
268}
269
270static bool ath_usb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
271{
272 struct ath_hw *ah = (struct ath_hw *) common->ah;
273
274 (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
275
276 if (!ath9k_hw_wait(ah,
277 AR_EEPROM_STATUS_DATA,
278 AR_EEPROM_STATUS_DATA_BUSY |
279 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
280 AH_WAIT_TIMEOUT))
281 return false;
282
283 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
284 AR_EEPROM_STATUS_DATA_VAL);
285
286 return true;
287}
288
289static const struct ath_bus_ops ath9k_usb_bus_ops = {
290 .ath_bus_type = ATH_USB,
291 .read_cachesize = ath_usb_read_cachesize,
292 .eeprom_read = ath_usb_eeprom_read,
293};
294
295static void setup_ht_cap(struct ath9k_htc_priv *priv,
296 struct ieee80211_sta_ht_cap *ht_info)
297{
298 ht_info->ht_supported = true;
299 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
300 IEEE80211_HT_CAP_SM_PS |
301 IEEE80211_HT_CAP_SGI_40 |
302 IEEE80211_HT_CAP_DSSSCCK40;
303
304 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
305 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
306
307 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
308 ht_info->mcs.rx_mask[0] = 0xff;
309 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
310}
311
312static int ath9k_init_queues(struct ath9k_htc_priv *priv)
313{
314 struct ath_common *common = ath9k_hw_common(priv->ah);
315 int i;
316
317 for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++)
318 priv->hwq_map[i] = -1;
319
320 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) {
321 ath_print(common, ATH_DBG_FATAL,
322 "Unable to setup xmit queue for BE traffic\n");
323 goto err;
324 }
325
326 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) {
327 ath_print(common, ATH_DBG_FATAL,
328 "Unable to setup xmit queue for BK traffic\n");
329 goto err;
330 }
331 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) {
332 ath_print(common, ATH_DBG_FATAL,
333 "Unable to setup xmit queue for VI traffic\n");
334 goto err;
335 }
336 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) {
337 ath_print(common, ATH_DBG_FATAL,
338 "Unable to setup xmit queue for VO traffic\n");
339 goto err;
340 }
341
342 return 0;
343
344err:
345 return -EINVAL;
346}
347
348static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
349{
350 struct ath_common *common = ath9k_hw_common(priv->ah);
351 int i = 0;
352
353 /* Get the hardware key cache size. */
354 common->keymax = priv->ah->caps.keycache_size;
355 if (common->keymax > ATH_KEYMAX) {
356 ath_print(common, ATH_DBG_ANY,
357 "Warning, using only %u entries in %u key cache\n",
358 ATH_KEYMAX, common->keymax);
359 common->keymax = ATH_KEYMAX;
360 }
361
362 /*
363 * Reset the key cache since some parts do not
364 * reset the contents on initial power up.
365 */
366 for (i = 0; i < common->keymax; i++)
367 ath9k_hw_keyreset(priv->ah, (u16) i);
368
369 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
370 ATH9K_CIPHER_TKIP, NULL)) {
371 /*
372 * Whether we should enable h/w TKIP MIC.
373 * XXX: if we don't support WME TKIP MIC, then we wouldn't
374 * report WMM capable, so it's always safe to turn on
375 * TKIP MIC in this case.
376 */
377 ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
378 }
379
380 /*
381 * Check whether the separate key cache entries
382 * are required to handle both tx+rx MIC keys.
383 * With split mic keys the number of stations is limited
384 * to 27 otherwise 59.
385 */
386 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
387 ATH9K_CIPHER_TKIP, NULL)
388 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
389 ATH9K_CIPHER_MIC, NULL)
390 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT,
391 0, NULL))
392 common->splitmic = 1;
393
394 /* turn on mcast key search if possible */
395 if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
396 (void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH,
397 1, 1, NULL);
398}
399
400static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
401{
402 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
403 priv->sbands[IEEE80211_BAND_2GHZ].channels =
404 ath9k_2ghz_channels;
405 priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
406 priv->sbands[IEEE80211_BAND_2GHZ].n_channels =
407 ARRAY_SIZE(ath9k_2ghz_channels);
408 priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
409 priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
410 ARRAY_SIZE(ath9k_legacy_rates);
411 }
412}
413
414static void ath9k_init_misc(struct ath9k_htc_priv *priv)
415{
416 struct ath_common *common = ath9k_hw_common(priv->ah);
417
418 common->tx_chainmask = priv->ah->caps.tx_chainmask;
419 common->rx_chainmask = priv->ah->caps.rx_chainmask;
420
421 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
422 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
423
424 priv->op_flags |= OP_TXAGGR;
425 priv->ah->opmode = NL80211_IFTYPE_STATION;
426}
427
428static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
429{
430 struct ath_hw *ah = NULL;
431 struct ath_common *common;
432 int ret = 0, csz = 0;
433
434 priv->op_flags |= OP_INVALID;
435
436 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
437 if (!ah)
438 return -ENOMEM;
439
440 ah->hw_version.devid = devid;
441 ah->hw_version.subsysid = 0; /* FIXME */
442 priv->ah = ah;
443
444 common = ath9k_hw_common(ah);
445 common->ops = &ath9k_common_ops;
446 common->bus_ops = &ath9k_usb_bus_ops;
447 common->ah = ah;
448 common->hw = priv->hw;
449 common->priv = priv;
450 common->debug_mask = ath9k_debug;
451
452 spin_lock_init(&priv->wmi->wmi_lock);
453 spin_lock_init(&priv->beacon_lock);
454 spin_lock_init(&priv->tx_lock);
455 mutex_init(&priv->mutex);
456 mutex_init(&priv->aggr_work.mutex);
457 mutex_init(&priv->htc_pm_lock);
458 tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
459 (unsigned long)priv);
460 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
461 (unsigned long)priv);
462 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
463 INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work);
464 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
465 INIT_WORK(&priv->ps_work, ath9k_ps_work);
466
467 /*
468 * Cache line size is used to size and align various
469 * structures used to communicate with the hardware.
470 */
471 ath_read_cachesize(common, &csz);
472 common->cachelsz = csz << 2; /* convert to bytes */
473
474 ret = ath9k_hw_init(ah);
475 if (ret) {
476 ath_print(common, ATH_DBG_FATAL,
477 "Unable to initialize hardware; "
478 "initialization status: %d\n", ret);
479 goto err_hw;
480 }
481
482 ret = ath9k_htc_init_debug(ah);
483 if (ret) {
484 ath_print(common, ATH_DBG_FATAL,
485 "Unable to create debugfs files\n");
486 goto err_debug;
487 }
488
489 ret = ath9k_init_queues(priv);
490 if (ret)
491 goto err_queues;
492
493 ath9k_init_crypto(priv);
494 ath9k_init_channels_rates(priv);
495 ath9k_init_misc(priv);
496
497 return 0;
498
499err_queues:
500 ath9k_htc_exit_debug(ah);
501err_debug:
502 ath9k_hw_deinit(ah);
503err_hw:
504
505 kfree(ah);
506 priv->ah = NULL;
507
508 return ret;
509}
510
511static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
512 struct ieee80211_hw *hw)
513{
514 struct ath_common *common = ath9k_hw_common(priv->ah);
515
516 hw->flags = IEEE80211_HW_SIGNAL_DBM |
517 IEEE80211_HW_AMPDU_AGGREGATION |
518 IEEE80211_HW_SPECTRUM_MGMT |
519 IEEE80211_HW_HAS_RATE_CONTROL |
520 IEEE80211_HW_RX_INCLUDES_FCS |
521 IEEE80211_HW_SUPPORTS_PS |
522 IEEE80211_HW_PS_NULLFUNC_STACK;
523
524 hw->wiphy->interface_modes =
525 BIT(NL80211_IFTYPE_STATION) |
526 BIT(NL80211_IFTYPE_ADHOC);
527
528 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
529
530 hw->queues = 4;
531 hw->channel_change_time = 5000;
532 hw->max_listen_interval = 10;
533 hw->vif_data_size = sizeof(struct ath9k_htc_vif);
534 hw->sta_data_size = sizeof(struct ath9k_htc_sta);
535
536 /* tx_frame_hdr is larger than tx_mgmt_hdr anyway */
537 hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
538 sizeof(struct htc_frame_hdr) + 4;
539
540 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
541 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
542 &priv->sbands[IEEE80211_BAND_2GHZ];
543
544 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
545 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
546 setup_ht_cap(priv,
547 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
548 }
549
550 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
551}
552
553static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
554{
555 struct ieee80211_hw *hw = priv->hw;
556 struct ath_common *common;
557 struct ath_hw *ah;
558 int error = 0;
559 struct ath_regulatory *reg;
560
561 /* Bring up device */
562 error = ath9k_init_priv(priv, devid);
563 if (error != 0)
564 goto err_init;
565
566 ah = priv->ah;
567 common = ath9k_hw_common(ah);
568 ath9k_set_hw_capab(priv, hw);
569
570 /* Initialize regulatory */
571 error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
572 ath9k_reg_notifier);
573 if (error)
574 goto err_regd;
575
576 reg = &common->regulatory;
577
578 /* Setup TX */
579 error = ath9k_tx_init(priv);
580 if (error != 0)
581 goto err_tx;
582
583 /* Setup RX */
584 error = ath9k_rx_init(priv);
585 if (error != 0)
586 goto err_rx;
587
588 /* Register with mac80211 */
589 error = ieee80211_register_hw(hw);
590 if (error)
591 goto err_register;
592
593 /* Handle world regulatory */
594 if (!ath_is_world_regd(reg)) {
595 error = regulatory_hint(hw->wiphy, reg->alpha2);
596 if (error)
597 goto err_world;
598 }
599
600 ath9k_init_leds(priv);
601 ath9k_start_rfkill_poll(priv);
602
603 return 0;
604
605err_world:
606 ieee80211_unregister_hw(hw);
607err_register:
608 ath9k_rx_cleanup(priv);
609err_rx:
610 ath9k_tx_cleanup(priv);
611err_tx:
612 /* Nothing */
613err_regd:
614 ath9k_deinit_priv(priv);
615err_init:
616 return error;
617}
618
619int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
620 u16 devid)
621{
622 struct ieee80211_hw *hw;
623 struct ath9k_htc_priv *priv;
624 int ret;
625
626 hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
627 if (!hw)
628 return -ENOMEM;
629
630 priv = hw->priv;
631 priv->hw = hw;
632 priv->htc = htc_handle;
633 priv->dev = dev;
634 htc_handle->drv_priv = priv;
635 SET_IEEE80211_DEV(hw, priv->dev);
636
637 ret = ath9k_htc_wait_for_target(priv);
638 if (ret)
639 goto err_free;
640
641 priv->wmi = ath9k_init_wmi(priv);
642 if (!priv->wmi) {
643 ret = -EINVAL;
644 goto err_free;
645 }
646
647 ret = ath9k_init_htc_services(priv);
648 if (ret)
649 goto err_init;
650
651 ret = ath9k_init_device(priv, devid);
652 if (ret)
653 goto err_init;
654
655 return 0;
656
657err_init:
658 ath9k_deinit_wmi(priv);
659err_free:
660 ieee80211_free_hw(hw);
661 return ret;
662}
663
664void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
665{
666 if (htc_handle->drv_priv) {
667 ath9k_deinit_device(htc_handle->drv_priv);
668 ath9k_deinit_wmi(htc_handle->drv_priv);
669 ieee80211_free_hw(htc_handle->drv_priv->hw);
670 }
671}
672
673#ifdef CONFIG_PM
674int ath9k_htc_resume(struct htc_target *htc_handle)
675{
676 int ret;
677
678 ret = ath9k_htc_wait_for_target(htc_handle->drv_priv);
679 if (ret)
680 return ret;
681
682 ret = ath9k_init_htc_services(htc_handle->drv_priv);
683 return ret;
684}
685#endif
686
687static int __init ath9k_htc_init(void)
688{
689 int error;
690
691 error = ath9k_htc_debug_create_root();
692 if (error < 0) {
693 printk(KERN_ERR
694 "ath9k_htc: Unable to create debugfs root: %d\n",
695 error);
696 goto err_dbg;
697 }
698
699 error = ath9k_hif_usb_init();
700 if (error < 0) {
701 printk(KERN_ERR
702 "ath9k_htc: No USB devices found,"
703 " driver not installed.\n");
704 error = -ENODEV;
705 goto err_usb;
706 }
707
708 return 0;
709
710err_usb:
711 ath9k_htc_debug_remove_root();
712err_dbg:
713 return error;
714}
715module_init(ath9k_htc_init);
716
717static void __exit ath9k_htc_exit(void)
718{
719 ath9k_hif_usb_exit();
720 ath9k_htc_debug_remove_root();
721 printk(KERN_INFO "ath9k_htc: Driver unloaded\n");
722}
723module_exit(ath9k_htc_exit);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
new file mode 100644
index 000000000000..eb7722b2cfcc
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -0,0 +1,1733 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#ifdef CONFIG_ATH9K_HTC_DEBUGFS
20static struct dentry *ath9k_debugfs_root;
21#endif
22
23/*************/
24/* Utilities */
25/*************/
26
27static void ath_update_txpow(struct ath9k_htc_priv *priv)
28{
29 struct ath_hw *ah = priv->ah;
30 u32 txpow;
31
32 if (priv->curtxpow != priv->txpowlimit) {
33 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
34 /* read back in case value is clamped */
35 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
36 priv->curtxpow = txpow;
37 }
38}
39
40/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
41static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
42 struct ath9k_channel *ichan)
43{
44 enum htc_phymode mode;
45
46 mode = HTC_MODE_AUTO;
47
48 switch (ichan->chanmode) {
49 case CHANNEL_G:
50 case CHANNEL_G_HT20:
51 case CHANNEL_G_HT40PLUS:
52 case CHANNEL_G_HT40MINUS:
53 mode = HTC_MODE_11NG;
54 break;
55 case CHANNEL_A:
56 case CHANNEL_A_HT20:
57 case CHANNEL_A_HT40PLUS:
58 case CHANNEL_A_HT40MINUS:
59 mode = HTC_MODE_11NA;
60 break;
61 default:
62 break;
63 }
64
65 return mode;
66}
67
68static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
69 enum ath9k_power_mode mode)
70{
71 bool ret;
72
73 mutex_lock(&priv->htc_pm_lock);
74 ret = ath9k_hw_setpower(priv->ah, mode);
75 mutex_unlock(&priv->htc_pm_lock);
76
77 return ret;
78}
79
80void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
81{
82 mutex_lock(&priv->htc_pm_lock);
83 if (++priv->ps_usecount != 1)
84 goto unlock;
85 ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE);
86
87unlock:
88 mutex_unlock(&priv->htc_pm_lock);
89}
90
91void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
92{
93 mutex_lock(&priv->htc_pm_lock);
94 if (--priv->ps_usecount != 0)
95 goto unlock;
96
97 if (priv->ps_enabled)
98 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
99unlock:
100 mutex_unlock(&priv->htc_pm_lock);
101}
102
103void ath9k_ps_work(struct work_struct *work)
104{
105 struct ath9k_htc_priv *priv =
106 container_of(work, struct ath9k_htc_priv,
107 ps_work);
108 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
109
110 /* The chip wakes up after receiving the first beacon
111 while network sleep is enabled. For the driver to
112 be in sync with the hw, set the chip to awake and
113 only then set it to sleep.
114 */
115 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
116}
117
118static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
119 struct ieee80211_hw *hw,
120 struct ath9k_channel *hchan)
121{
122 struct ath_hw *ah = priv->ah;
123 struct ath_common *common = ath9k_hw_common(ah);
124 struct ieee80211_conf *conf = &common->hw->conf;
125 bool fastcc = true;
126 struct ieee80211_channel *channel = hw->conf.channel;
127 enum htc_phymode mode;
128 u16 htc_mode;
129 u8 cmd_rsp;
130 int ret;
131
132 if (priv->op_flags & OP_INVALID)
133 return -EIO;
134
135 if (priv->op_flags & OP_FULL_RESET)
136 fastcc = false;
137
138 /* Fiddle around with fastcc later on, for now just use full reset */
139 fastcc = false;
140 ath9k_htc_ps_wakeup(priv);
141 htc_stop(priv->htc);
142 WMI_CMD(WMI_DISABLE_INTR_CMDID);
143 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
144 WMI_CMD(WMI_STOP_RECV_CMDID);
145
146 ath_print(common, ATH_DBG_CONFIG,
147 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n",
148 priv->ah->curchan->channel,
149 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
150
151 ret = ath9k_hw_reset(ah, hchan, fastcc);
152 if (ret) {
153 ath_print(common, ATH_DBG_FATAL,
154 "Unable to reset channel (%u Mhz) "
155 "reset status %d\n", channel->center_freq, ret);
156 ath9k_htc_ps_restore(priv);
157 goto err;
158 }
159
160 ath_update_txpow(priv);
161
162 WMI_CMD(WMI_START_RECV_CMDID);
163 if (ret)
164 goto err;
165
166 ath9k_host_rx_init(priv);
167
168 mode = ath9k_htc_get_curmode(priv, hchan);
169 htc_mode = cpu_to_be16(mode);
170 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
171 if (ret)
172 goto err;
173
174 WMI_CMD(WMI_ENABLE_INTR_CMDID);
175 if (ret)
176 goto err;
177
178 htc_start(priv->htc);
179
180 priv->op_flags &= ~OP_FULL_RESET;
181err:
182 ath9k_htc_ps_restore(priv);
183 return ret;
184}
185
186static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
187{
188 struct ath_common *common = ath9k_hw_common(priv->ah);
189 struct ath9k_htc_target_vif hvif;
190 int ret = 0;
191 u8 cmd_rsp;
192
193 if (priv->nvifs > 0)
194 return -ENOBUFS;
195
196 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
197 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
198
199 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
200 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
201 hvif.index = priv->nvifs;
202
203 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
204 if (ret)
205 return ret;
206
207 priv->nvifs++;
208 return 0;
209}
210
211static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
212{
213 struct ath_common *common = ath9k_hw_common(priv->ah);
214 struct ath9k_htc_target_vif hvif;
215 int ret = 0;
216 u8 cmd_rsp;
217
218 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
219 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
220 hvif.index = 0; /* Should do for now */
221 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
222 priv->nvifs--;
223
224 return ret;
225}
226
227static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
228 struct ieee80211_vif *vif,
229 struct ieee80211_sta *sta)
230{
231 struct ath_common *common = ath9k_hw_common(priv->ah);
232 struct ath9k_htc_target_sta tsta;
233 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
234 struct ath9k_htc_sta *ista;
235 int ret;
236 u8 cmd_rsp;
237
238 if (priv->nstations >= ATH9K_HTC_MAX_STA)
239 return -ENOBUFS;
240
241 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
242
243 if (sta) {
244 ista = (struct ath9k_htc_sta *) sta->drv_priv;
245 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
246 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
247 tsta.associd = common->curaid;
248 tsta.is_vif_sta = 0;
249 tsta.valid = true;
250 ista->index = priv->nstations;
251 } else {
252 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
253 tsta.is_vif_sta = 1;
254 }
255
256 tsta.sta_index = priv->nstations;
257 tsta.vif_index = avp->index;
258 tsta.maxampdu = 0xffff;
259 if (sta && sta->ht_cap.ht_supported)
260 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
261
262 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
263 if (ret) {
264 if (sta)
265 ath_print(common, ATH_DBG_FATAL,
266 "Unable to add station entry for: %pM\n", sta->addr);
267 return ret;
268 }
269
270 if (sta)
271 ath_print(common, ATH_DBG_CONFIG,
272 "Added a station entry for: %pM (idx: %d)\n",
273 sta->addr, tsta.sta_index);
274
275 priv->nstations++;
276 return 0;
277}
278
279static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
280 struct ieee80211_vif *vif,
281 struct ieee80211_sta *sta)
282{
283 struct ath_common *common = ath9k_hw_common(priv->ah);
284 struct ath9k_htc_sta *ista;
285 int ret;
286 u8 cmd_rsp, sta_idx;
287
288 if (sta) {
289 ista = (struct ath9k_htc_sta *) sta->drv_priv;
290 sta_idx = ista->index;
291 } else {
292 sta_idx = 0;
293 }
294
295 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
296 if (ret) {
297 if (sta)
298 ath_print(common, ATH_DBG_FATAL,
299 "Unable to remove station entry for: %pM\n",
300 sta->addr);
301 return ret;
302 }
303
304 if (sta)
305 ath_print(common, ATH_DBG_CONFIG,
306 "Removed a station entry for: %pM (idx: %d)\n",
307 sta->addr, sta_idx);
308
309 priv->nstations--;
310 return 0;
311}
312
313static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
314{
315 struct ath9k_htc_cap_target tcap;
316 int ret;
317 u8 cmd_rsp;
318
319 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
320
321 /* FIXME: Values are hardcoded */
322 tcap.flags = 0x240c40;
323 tcap.flags_ext = 0x80601000;
324 tcap.ampdu_limit = 0xffff0000;
325 tcap.ampdu_subframes = 20;
326 tcap.tx_chainmask_legacy = 1;
327 tcap.protmode = 1;
328 tcap.tx_chainmask = 1;
329
330 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
331
332 return ret;
333}
334
335static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
336 struct ieee80211_vif *vif,
337 struct ieee80211_sta *sta)
338{
339 struct ath_common *common = ath9k_hw_common(priv->ah);
340 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
341 struct ieee80211_supported_band *sband;
342 struct ath9k_htc_target_rate trate;
343 u32 caps = 0;
344 u8 cmd_rsp;
345 int i, j, ret;
346
347 memset(&trate, 0, sizeof(trate));
348
349 /* Only 2GHz is supported */
350 sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
351
352 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
353 if (sta->supp_rates[sband->band] & BIT(i)) {
354 priv->tgt_rate.rates.legacy_rates.rs_rates[j]
355 = (sband->bitrates[i].bitrate * 2) / 10;
356 j++;
357 }
358 }
359 priv->tgt_rate.rates.legacy_rates.rs_nrates = j;
360
361 if (sta->ht_cap.ht_supported) {
362 for (i = 0, j = 0; i < 77; i++) {
363 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
364 priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i;
365 if (j == ATH_HTC_RATE_MAX)
366 break;
367 }
368 priv->tgt_rate.rates.ht_rates.rs_nrates = j;
369
370 caps = WLAN_RC_HT_FLAG;
371 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
372 caps |= WLAN_RC_40_FLAG;
373 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
374 caps |= WLAN_RC_SGI_FLAG;
375
376 }
377
378 priv->tgt_rate.sta_index = ista->index;
379 priv->tgt_rate.isnew = 1;
380 trate = priv->tgt_rate;
381 priv->tgt_rate.capflags = caps;
382 trate.capflags = cpu_to_be32(caps);
383
384 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
385 if (ret) {
386 ath_print(common, ATH_DBG_FATAL,
387 "Unable to initialize Rate information on target\n");
388 return ret;
389 }
390
391 ath_print(common, ATH_DBG_CONFIG,
392 "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps);
393 return 0;
394}
395
396static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40)
397{
398 struct ath9k_htc_priv *priv = hw->priv;
399 struct ieee80211_conf *conf = &hw->conf;
400
401 if (!conf_is_ht(conf))
402 return false;
403
404 if (!(priv->op_flags & OP_ASSOCIATED) ||
405 (priv->op_flags & OP_SCANNING))
406 return false;
407
408 if (conf_is_ht40(conf)) {
409 if (priv->ah->curchan->chanmode &
410 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) {
411 return false;
412 } else {
413 *cw40 = true;
414 return true;
415 }
416 } else { /* ht20 */
417 if (priv->ah->curchan->chanmode & CHANNEL_HT20)
418 return false;
419 else
420 return true;
421 }
422}
423
424static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
425{
426 struct ath9k_htc_target_rate trate;
427 struct ath_common *common = ath9k_hw_common(priv->ah);
428 int ret;
429 u8 cmd_rsp;
430
431 memset(&trate, 0, sizeof(trate));
432
433 trate = priv->tgt_rate;
434
435 if (is_cw40)
436 priv->tgt_rate.capflags |= WLAN_RC_40_FLAG;
437 else
438 priv->tgt_rate.capflags &= ~WLAN_RC_40_FLAG;
439
440 trate.capflags = cpu_to_be32(priv->tgt_rate.capflags);
441
442 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
443 if (ret) {
444 ath_print(common, ATH_DBG_FATAL,
445 "Unable to update Rate information on target\n");
446 return;
447 }
448
449 ath_print(common, ATH_DBG_CONFIG, "Rate control updated with "
450 "caps:0x%x on target\n", priv->tgt_rate.capflags);
451}
452
453static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
454 struct ieee80211_vif *vif,
455 u8 *sta_addr, u8 tid, bool oper)
456{
457 struct ath_common *common = ath9k_hw_common(priv->ah);
458 struct ath9k_htc_target_aggr aggr;
459 struct ieee80211_sta *sta = NULL;
460 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
461 int ret = 0;
462 u8 cmd_rsp;
463
464 if (tid > ATH9K_HTC_MAX_TID)
465 return -EINVAL;
466
467 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
468
469 rcu_read_lock();
470
471 /* Check if we are able to retrieve the station */
472 sta = ieee80211_find_sta(vif, sta_addr);
473 if (!sta) {
474 rcu_read_unlock();
475 return -EINVAL;
476 }
477
478 ista = (struct ath9k_htc_sta *) sta->drv_priv;
479
480 if (oper)
481 ista->tid_state[tid] = AGGR_START;
482 else
483 ista->tid_state[tid] = AGGR_STOP;
484
485 aggr.sta_index = ista->index;
486
487 rcu_read_unlock();
488
489 aggr.tidno = tid;
490 aggr.aggr_enable = oper;
491
492 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
493 if (ret)
494 ath_print(common, ATH_DBG_CONFIG,
495 "Unable to %s TX aggregation for (%pM, %d)\n",
496 (oper) ? "start" : "stop", sta->addr, tid);
497 else
498 ath_print(common, ATH_DBG_CONFIG,
499 "%s aggregation for (%pM, %d)\n",
500 (oper) ? "Starting" : "Stopping", sta->addr, tid);
501
502 return ret;
503}
504
505void ath9k_htc_aggr_work(struct work_struct *work)
506{
507 int ret = 0;
508 struct ath9k_htc_priv *priv =
509 container_of(work, struct ath9k_htc_priv,
510 ath9k_aggr_work.work);
511 struct ath9k_htc_aggr_work *wk = &priv->aggr_work;
512
513 mutex_lock(&wk->mutex);
514
515 switch (wk->action) {
516 case IEEE80211_AMPDU_TX_START:
517 ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
518 wk->tid, true);
519 if (!ret)
520 ieee80211_start_tx_ba_cb(wk->vif, wk->sta_addr,
521 wk->tid);
522 break;
523 case IEEE80211_AMPDU_TX_STOP:
524 ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
525 wk->tid, false);
526 ieee80211_stop_tx_ba_cb(wk->vif, wk->sta_addr, wk->tid);
527 break;
528 default:
529 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
530 "Unknown AMPDU action\n");
531 }
532
533 mutex_unlock(&wk->mutex);
534}
535
536/*********/
537/* DEBUG */
538/*********/
539
540#ifdef CONFIG_ATH9K_HTC_DEBUGFS
541
542static int ath9k_debugfs_open(struct inode *inode, struct file *file)
543{
544 file->private_data = inode->i_private;
545 return 0;
546}
547
548static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
549 size_t count, loff_t *ppos)
550{
551 struct ath9k_htc_priv *priv =
552 (struct ath9k_htc_priv *) file->private_data;
553 struct ath9k_htc_target_stats cmd_rsp;
554 char buf[512];
555 unsigned int len = 0;
556 int ret = 0;
557
558 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
559
560 WMI_CMD(WMI_TGT_STATS_CMDID);
561 if (ret)
562 return -EINVAL;
563
564
565 len += snprintf(buf + len, sizeof(buf) - len,
566 "%19s : %10u\n", "TX Short Retries",
567 be32_to_cpu(cmd_rsp.tx_shortretry));
568 len += snprintf(buf + len, sizeof(buf) - len,
569 "%19s : %10u\n", "TX Long Retries",
570 be32_to_cpu(cmd_rsp.tx_longretry));
571 len += snprintf(buf + len, sizeof(buf) - len,
572 "%19s : %10u\n", "TX Xretries",
573 be32_to_cpu(cmd_rsp.tx_xretries));
574 len += snprintf(buf + len, sizeof(buf) - len,
575 "%19s : %10u\n", "TX Unaggr. Xretries",
576 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
577 len += snprintf(buf + len, sizeof(buf) - len,
578 "%19s : %10u\n", "TX Xretries (HT)",
579 be32_to_cpu(cmd_rsp.ht_tx_xretries));
580 len += snprintf(buf + len, sizeof(buf) - len,
581 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
582
583 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
584}
585
586static const struct file_operations fops_tgt_stats = {
587 .read = read_file_tgt_stats,
588 .open = ath9k_debugfs_open,
589 .owner = THIS_MODULE
590};
591
592static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
593 size_t count, loff_t *ppos)
594{
595 struct ath9k_htc_priv *priv =
596 (struct ath9k_htc_priv *) file->private_data;
597 char buf[512];
598 unsigned int len = 0;
599
600 len += snprintf(buf + len, sizeof(buf) - len,
601 "%20s : %10u\n", "Buffers queued",
602 priv->debug.tx_stats.buf_queued);
603 len += snprintf(buf + len, sizeof(buf) - len,
604 "%20s : %10u\n", "Buffers completed",
605 priv->debug.tx_stats.buf_completed);
606 len += snprintf(buf + len, sizeof(buf) - len,
607 "%20s : %10u\n", "SKBs queued",
608 priv->debug.tx_stats.skb_queued);
609 len += snprintf(buf + len, sizeof(buf) - len,
610 "%20s : %10u\n", "SKBs completed",
611 priv->debug.tx_stats.skb_completed);
612
613 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
614}
615
616static const struct file_operations fops_xmit = {
617 .read = read_file_xmit,
618 .open = ath9k_debugfs_open,
619 .owner = THIS_MODULE
620};
621
622static ssize_t read_file_recv(struct file *file, char __user *user_buf,
623 size_t count, loff_t *ppos)
624{
625 struct ath9k_htc_priv *priv =
626 (struct ath9k_htc_priv *) file->private_data;
627 char buf[512];
628 unsigned int len = 0;
629
630 len += snprintf(buf + len, sizeof(buf) - len,
631 "%20s : %10u\n", "SKBs allocated",
632 priv->debug.rx_stats.skb_allocated);
633 len += snprintf(buf + len, sizeof(buf) - len,
634 "%20s : %10u\n", "SKBs completed",
635 priv->debug.rx_stats.skb_completed);
636 len += snprintf(buf + len, sizeof(buf) - len,
637 "%20s : %10u\n", "SKBs Dropped",
638 priv->debug.rx_stats.skb_dropped);
639
640 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
641}
642
643static const struct file_operations fops_recv = {
644 .read = read_file_recv,
645 .open = ath9k_debugfs_open,
646 .owner = THIS_MODULE
647};
648
649int ath9k_htc_init_debug(struct ath_hw *ah)
650{
651 struct ath_common *common = ath9k_hw_common(ah);
652 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
653
654 if (!ath9k_debugfs_root)
655 return -ENOENT;
656
657 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
658 ath9k_debugfs_root);
659 if (!priv->debug.debugfs_phy)
660 goto err;
661
662 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
663 priv->debug.debugfs_phy,
664 priv, &fops_tgt_stats);
665 if (!priv->debug.debugfs_tgt_stats)
666 goto err;
667
668
669 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
670 priv->debug.debugfs_phy,
671 priv, &fops_xmit);
672 if (!priv->debug.debugfs_xmit)
673 goto err;
674
675 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
676 priv->debug.debugfs_phy,
677 priv, &fops_recv);
678 if (!priv->debug.debugfs_recv)
679 goto err;
680
681 return 0;
682
683err:
684 ath9k_htc_exit_debug(ah);
685 return -ENOMEM;
686}
687
688void ath9k_htc_exit_debug(struct ath_hw *ah)
689{
690 struct ath_common *common = ath9k_hw_common(ah);
691 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
692
693 debugfs_remove(priv->debug.debugfs_recv);
694 debugfs_remove(priv->debug.debugfs_xmit);
695 debugfs_remove(priv->debug.debugfs_tgt_stats);
696 debugfs_remove(priv->debug.debugfs_phy);
697}
698
699int ath9k_htc_debug_create_root(void)
700{
701 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
702 if (!ath9k_debugfs_root)
703 return -ENOENT;
704
705 return 0;
706}
707
708void ath9k_htc_debug_remove_root(void)
709{
710 debugfs_remove(ath9k_debugfs_root);
711 ath9k_debugfs_root = NULL;
712}
713
714#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
715
716/*******/
717/* ANI */
718/*******/
719
720static void ath_start_ani(struct ath9k_htc_priv *priv)
721{
722 struct ath_common *common = ath9k_hw_common(priv->ah);
723 unsigned long timestamp = jiffies_to_msecs(jiffies);
724
725 common->ani.longcal_timer = timestamp;
726 common->ani.shortcal_timer = timestamp;
727 common->ani.checkani_timer = timestamp;
728
729 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
730 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
731}
732
733void ath9k_ani_work(struct work_struct *work)
734{
735 struct ath9k_htc_priv *priv =
736 container_of(work, struct ath9k_htc_priv,
737 ath9k_ani_work.work);
738 struct ath_hw *ah = priv->ah;
739 struct ath_common *common = ath9k_hw_common(ah);
740 bool longcal = false;
741 bool shortcal = false;
742 bool aniflag = false;
743 unsigned int timestamp = jiffies_to_msecs(jiffies);
744 u32 cal_interval, short_cal_interval;
745
746 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
747
748 /* Only calibrate if awake */
749 if (ah->power_mode != ATH9K_PM_AWAKE)
750 goto set_timer;
751
752 /* Long calibration runs independently of short calibration. */
753 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
754 longcal = true;
755 ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
756 common->ani.longcal_timer = timestamp;
757 }
758
759 /* Short calibration applies only while caldone is false */
760 if (!common->ani.caldone) {
761 if ((timestamp - common->ani.shortcal_timer) >=
762 short_cal_interval) {
763 shortcal = true;
764 ath_print(common, ATH_DBG_ANI,
765 "shortcal @%lu\n", jiffies);
766 common->ani.shortcal_timer = timestamp;
767 common->ani.resetcal_timer = timestamp;
768 }
769 } else {
770 if ((timestamp - common->ani.resetcal_timer) >=
771 ATH_RESTART_CALINTERVAL) {
772 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
773 if (common->ani.caldone)
774 common->ani.resetcal_timer = timestamp;
775 }
776 }
777
778 /* Verify whether we must check ANI */
779 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
780 aniflag = true;
781 common->ani.checkani_timer = timestamp;
782 }
783
784 /* Skip all processing if there's nothing to do. */
785 if (longcal || shortcal || aniflag) {
786
787 ath9k_htc_ps_wakeup(priv);
788
789 /* Call ANI routine if necessary */
790 if (aniflag)
791 ath9k_hw_ani_monitor(ah, ah->curchan);
792
793 /* Perform calibration if necessary */
794 if (longcal || shortcal) {
795 common->ani.caldone =
796 ath9k_hw_calibrate(ah, ah->curchan,
797 common->rx_chainmask,
798 longcal);
799
800 if (longcal)
801 common->ani.noise_floor =
802 ath9k_hw_getchan_noise(ah, ah->curchan);
803
804 ath_print(common, ATH_DBG_ANI,
805 " calibrate chan %u/%x nf: %d\n",
806 ah->curchan->channel,
807 ah->curchan->channelFlags,
808 common->ani.noise_floor);
809 }
810
811 ath9k_htc_ps_restore(priv);
812 }
813
814set_timer:
815 /*
816 * Set timer interval based on previous results.
817 * The interval must be the shortest necessary to satisfy ANI,
818 * short calibration and long calibration.
819 */
820 cal_interval = ATH_LONG_CALINTERVAL;
821 if (priv->ah->config.enable_ani)
822 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
823 if (!common->ani.caldone)
824 cal_interval = min(cal_interval, (u32)short_cal_interval);
825
826 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
827 msecs_to_jiffies(cal_interval));
828}
829
830/*******/
831/* LED */
832/*******/
833
834static void ath9k_led_blink_work(struct work_struct *work)
835{
836 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
837 ath9k_led_blink_work.work);
838
839 if (!(priv->op_flags & OP_LED_ASSOCIATED))
840 return;
841
842 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
843 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
844 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
845 else
846 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
847 (priv->op_flags & OP_LED_ON) ? 1 : 0);
848
849 ieee80211_queue_delayed_work(priv->hw,
850 &priv->ath9k_led_blink_work,
851 (priv->op_flags & OP_LED_ON) ?
852 msecs_to_jiffies(priv->led_off_duration) :
853 msecs_to_jiffies(priv->led_on_duration));
854
855 priv->led_on_duration = priv->led_on_cnt ?
856 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
857 ATH_LED_ON_DURATION_IDLE;
858 priv->led_off_duration = priv->led_off_cnt ?
859 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
860 ATH_LED_OFF_DURATION_IDLE;
861 priv->led_on_cnt = priv->led_off_cnt = 0;
862
863 if (priv->op_flags & OP_LED_ON)
864 priv->op_flags &= ~OP_LED_ON;
865 else
866 priv->op_flags |= OP_LED_ON;
867}
868
869static void ath9k_led_brightness_work(struct work_struct *work)
870{
871 struct ath_led *led = container_of(work, struct ath_led,
872 brightness_work.work);
873 struct ath9k_htc_priv *priv = led->priv;
874
875 switch (led->brightness) {
876 case LED_OFF:
877 if (led->led_type == ATH_LED_ASSOC ||
878 led->led_type == ATH_LED_RADIO) {
879 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
880 (led->led_type == ATH_LED_RADIO));
881 priv->op_flags &= ~OP_LED_ASSOCIATED;
882 if (led->led_type == ATH_LED_RADIO)
883 priv->op_flags &= ~OP_LED_ON;
884 } else {
885 priv->led_off_cnt++;
886 }
887 break;
888 case LED_FULL:
889 if (led->led_type == ATH_LED_ASSOC) {
890 priv->op_flags |= OP_LED_ASSOCIATED;
891 ieee80211_queue_delayed_work(priv->hw,
892 &priv->ath9k_led_blink_work, 0);
893 } else if (led->led_type == ATH_LED_RADIO) {
894 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
895 priv->op_flags |= OP_LED_ON;
896 } else {
897 priv->led_on_cnt++;
898 }
899 break;
900 default:
901 break;
902 }
903}
904
905static void ath9k_led_brightness(struct led_classdev *led_cdev,
906 enum led_brightness brightness)
907{
908 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
909 struct ath9k_htc_priv *priv = led->priv;
910
911 led->brightness = brightness;
912 if (!(priv->op_flags & OP_LED_DEINIT))
913 ieee80211_queue_delayed_work(priv->hw,
914 &led->brightness_work, 0);
915}
916
917static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
918{
919 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
920 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
921 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
922 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
923}
924
925static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
926 char *trigger)
927{
928 int ret;
929
930 led->priv = priv;
931 led->led_cdev.name = led->name;
932 led->led_cdev.default_trigger = trigger;
933 led->led_cdev.brightness_set = ath9k_led_brightness;
934
935 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
936 if (ret)
937 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
938 "Failed to register led:%s", led->name);
939 else
940 led->registered = 1;
941
942 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
943
944 return ret;
945}
946
947static void ath9k_unregister_led(struct ath_led *led)
948{
949 if (led->registered) {
950 led_classdev_unregister(&led->led_cdev);
951 led->registered = 0;
952 }
953}
954
955void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
956{
957 priv->op_flags |= OP_LED_DEINIT;
958 ath9k_unregister_led(&priv->assoc_led);
959 priv->op_flags &= ~OP_LED_ASSOCIATED;
960 ath9k_unregister_led(&priv->tx_led);
961 ath9k_unregister_led(&priv->rx_led);
962 ath9k_unregister_led(&priv->radio_led);
963 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
964}
965
966void ath9k_init_leds(struct ath9k_htc_priv *priv)
967{
968 char *trigger;
969 int ret;
970
971 if (AR_SREV_9287(priv->ah))
972 priv->ah->led_pin = ATH_LED_PIN_9287;
973 else if (AR_SREV_9271(priv->ah))
974 priv->ah->led_pin = ATH_LED_PIN_9271;
975 else
976 priv->ah->led_pin = ATH_LED_PIN_DEF;
977
978 /* Configure gpio 1 for output */
979 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
980 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
981 /* LED off, active low */
982 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
983
984 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
985
986 trigger = ieee80211_get_radio_led_name(priv->hw);
987 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
988 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
989 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
990 priv->radio_led.led_type = ATH_LED_RADIO;
991 if (ret)
992 goto fail;
993
994 trigger = ieee80211_get_assoc_led_name(priv->hw);
995 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
996 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
997 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
998 priv->assoc_led.led_type = ATH_LED_ASSOC;
999 if (ret)
1000 goto fail;
1001
1002 trigger = ieee80211_get_tx_led_name(priv->hw);
1003 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
1004 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
1005 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
1006 priv->tx_led.led_type = ATH_LED_TX;
1007 if (ret)
1008 goto fail;
1009
1010 trigger = ieee80211_get_rx_led_name(priv->hw);
1011 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
1012 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
1013 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
1014 priv->rx_led.led_type = ATH_LED_RX;
1015 if (ret)
1016 goto fail;
1017
1018 priv->op_flags &= ~OP_LED_DEINIT;
1019
1020 return;
1021
1022fail:
1023 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1024 ath9k_deinit_leds(priv);
1025}
1026
1027/*******************/
1028/* Rfkill */
1029/*******************/
1030
1031static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
1032{
1033 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
1034 priv->ah->rfkill_polarity;
1035}
1036
1037static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
1038{
1039 struct ath9k_htc_priv *priv = hw->priv;
1040 bool blocked = !!ath_is_rfkill_set(priv);
1041
1042 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1043}
1044
1045void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
1046{
1047 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1048 wiphy_rfkill_start_polling(priv->hw->wiphy);
1049}
1050
1051/**********************/
1052/* mac80211 Callbacks */
1053/**********************/
1054
1055static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1056{
1057 struct ieee80211_hdr *hdr;
1058 struct ath9k_htc_priv *priv = hw->priv;
1059 int padpos, padsize, ret;
1060
1061 hdr = (struct ieee80211_hdr *) skb->data;
1062
1063 /* Add the padding after the header if this is not already done */
1064 padpos = ath9k_cmn_padpos(hdr->frame_control);
1065 padsize = padpos & 3;
1066 if (padsize && skb->len > padpos) {
1067 if (skb_headroom(skb) < padsize)
1068 return -1;
1069 skb_push(skb, padsize);
1070 memmove(skb->data, skb->data + padsize, padpos);
1071 }
1072
1073 ret = ath9k_htc_tx_start(priv, skb);
1074 if (ret != 0) {
1075 if (ret == -ENOMEM) {
1076 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1077 "Stopping TX queues\n");
1078 ieee80211_stop_queues(hw);
1079 spin_lock_bh(&priv->tx_lock);
1080 priv->tx_queues_stop = true;
1081 spin_unlock_bh(&priv->tx_lock);
1082 } else {
1083 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1084 "Tx failed");
1085 }
1086 goto fail_tx;
1087 }
1088
1089 return 0;
1090
1091fail_tx:
1092 dev_kfree_skb_any(skb);
1093 return 0;
1094}
1095
1096static int ath9k_htc_start(struct ieee80211_hw *hw)
1097{
1098 struct ath9k_htc_priv *priv = hw->priv;
1099 struct ath_hw *ah = priv->ah;
1100 struct ath_common *common = ath9k_hw_common(ah);
1101 struct ieee80211_channel *curchan = hw->conf.channel;
1102 struct ath9k_channel *init_channel;
1103 int ret = 0;
1104 enum htc_phymode mode;
1105 u16 htc_mode;
1106 u8 cmd_rsp;
1107
1108 ath_print(common, ATH_DBG_CONFIG,
1109 "Starting driver with initial channel: %d MHz\n",
1110 curchan->center_freq);
1111
1112 mutex_lock(&priv->mutex);
1113
1114 /* setup initial channel */
1115 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1116
1117 /* Reset SERDES registers */
1118 ath9k_hw_configpcipowersave(ah, 0, 0);
1119
1120 ath9k_hw_htc_resetinit(ah);
1121 ret = ath9k_hw_reset(ah, init_channel, false);
1122 if (ret) {
1123 ath_print(common, ATH_DBG_FATAL,
1124 "Unable to reset hardware; reset status %d "
1125 "(freq %u MHz)\n", ret, curchan->center_freq);
1126 goto mutex_unlock;
1127 }
1128
1129 ath_update_txpow(priv);
1130
1131 mode = ath9k_htc_get_curmode(priv, init_channel);
1132 htc_mode = cpu_to_be16(mode);
1133 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
1134 if (ret)
1135 goto mutex_unlock;
1136
1137 WMI_CMD(WMI_ATH_INIT_CMDID);
1138 if (ret)
1139 goto mutex_unlock;
1140
1141 WMI_CMD(WMI_START_RECV_CMDID);
1142 if (ret)
1143 goto mutex_unlock;
1144
1145 ath9k_host_rx_init(priv);
1146
1147 priv->op_flags &= ~OP_INVALID;
1148 htc_start(priv->htc);
1149
1150 spin_lock_bh(&priv->tx_lock);
1151 priv->tx_queues_stop = false;
1152 spin_unlock_bh(&priv->tx_lock);
1153
1154 ieee80211_wake_queues(hw);
1155
1156mutex_unlock:
1157 mutex_unlock(&priv->mutex);
1158 return ret;
1159}
1160
1161static void ath9k_htc_stop(struct ieee80211_hw *hw)
1162{
1163 struct ath9k_htc_priv *priv = hw->priv;
1164 struct ath_hw *ah = priv->ah;
1165 struct ath_common *common = ath9k_hw_common(ah);
1166 int ret = 0;
1167 u8 cmd_rsp;
1168
1169 mutex_lock(&priv->mutex);
1170
1171 if (priv->op_flags & OP_INVALID) {
1172 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1173 mutex_unlock(&priv->mutex);
1174 return;
1175 }
1176
1177 ath9k_htc_ps_wakeup(priv);
1178 htc_stop(priv->htc);
1179 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1180 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1181 WMI_CMD(WMI_STOP_RECV_CMDID);
1182 ath9k_hw_phy_disable(ah);
1183 ath9k_hw_disable(ah);
1184 ath9k_hw_configpcipowersave(ah, 1, 1);
1185 ath9k_htc_ps_restore(priv);
1186 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1187
1188 cancel_work_sync(&priv->ps_work);
1189 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1190 cancel_delayed_work_sync(&priv->ath9k_aggr_work);
1191 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1192 ath9k_led_stop_brightness(priv);
1193 skb_queue_purge(&priv->tx_queue);
1194
1195 /* Remove monitor interface here */
1196 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1197 if (ath9k_htc_remove_monitor_interface(priv))
1198 ath_print(common, ATH_DBG_FATAL,
1199 "Unable to remove monitor interface\n");
1200 else
1201 ath_print(common, ATH_DBG_CONFIG,
1202 "Monitor interface removed\n");
1203 }
1204
1205 priv->op_flags |= OP_INVALID;
1206 mutex_unlock(&priv->mutex);
1207
1208 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1209}
1210
1211static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1212 struct ieee80211_vif *vif)
1213{
1214 struct ath9k_htc_priv *priv = hw->priv;
1215 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1216 struct ath_common *common = ath9k_hw_common(priv->ah);
1217 struct ath9k_htc_target_vif hvif;
1218 int ret = 0;
1219 u8 cmd_rsp;
1220
1221 mutex_lock(&priv->mutex);
1222
1223 /* Only one interface for now */
1224 if (priv->nvifs > 0) {
1225 ret = -ENOBUFS;
1226 goto out;
1227 }
1228
1229 ath9k_htc_ps_wakeup(priv);
1230 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1231 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1232
1233 switch (vif->type) {
1234 case NL80211_IFTYPE_STATION:
1235 hvif.opmode = cpu_to_be32(HTC_M_STA);
1236 break;
1237 case NL80211_IFTYPE_ADHOC:
1238 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1239 break;
1240 default:
1241 ath_print(common, ATH_DBG_FATAL,
1242 "Interface type %d not yet supported\n", vif->type);
1243 ret = -EOPNOTSUPP;
1244 goto out;
1245 }
1246
1247 ath_print(common, ATH_DBG_CONFIG,
1248 "Attach a VIF of type: %d\n", vif->type);
1249
1250 priv->ah->opmode = vif->type;
1251
1252 /* Index starts from zero on the target */
1253 avp->index = hvif.index = priv->nvifs;
1254 hvif.rtsthreshold = cpu_to_be16(2304);
1255 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1256 if (ret)
1257 goto out;
1258
1259 priv->nvifs++;
1260
1261 /*
1262 * We need a node in target to tx mgmt frames
1263 * before association.
1264 */
1265 ret = ath9k_htc_add_station(priv, vif, NULL);
1266 if (ret)
1267 goto out;
1268
1269 ret = ath9k_htc_update_cap_target(priv);
1270 if (ret)
1271 ath_print(common, ATH_DBG_CONFIG, "Failed to update"
1272 " capability in target \n");
1273
1274 priv->vif = vif;
1275out:
1276 ath9k_htc_ps_restore(priv);
1277 mutex_unlock(&priv->mutex);
1278 return ret;
1279}
1280
1281static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1282 struct ieee80211_vif *vif)
1283{
1284 struct ath9k_htc_priv *priv = hw->priv;
1285 struct ath_common *common = ath9k_hw_common(priv->ah);
1286 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1287 struct ath9k_htc_target_vif hvif;
1288 int ret = 0;
1289 u8 cmd_rsp;
1290
1291 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1292
1293 mutex_lock(&priv->mutex);
1294
1295 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1296 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1297 hvif.index = avp->index;
1298 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1299 priv->nvifs--;
1300
1301 ath9k_htc_remove_station(priv, vif, NULL);
1302
1303 if (vif->type == NL80211_IFTYPE_ADHOC) {
1304 spin_lock_bh(&priv->beacon_lock);
1305 if (priv->beacon)
1306 dev_kfree_skb_any(priv->beacon);
1307 priv->beacon = NULL;
1308 spin_unlock_bh(&priv->beacon_lock);
1309 }
1310
1311 priv->vif = NULL;
1312
1313 mutex_unlock(&priv->mutex);
1314}
1315
1316static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1317{
1318 struct ath9k_htc_priv *priv = hw->priv;
1319 struct ath_common *common = ath9k_hw_common(priv->ah);
1320 struct ieee80211_conf *conf = &hw->conf;
1321
1322 mutex_lock(&priv->mutex);
1323
1324 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1325 struct ieee80211_channel *curchan = hw->conf.channel;
1326 int pos = curchan->hw_value;
1327 bool is_cw40 = false;
1328
1329 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1330 curchan->center_freq);
1331
1332 if (check_rc_update(hw, &is_cw40))
1333 ath9k_htc_rc_update(priv, is_cw40);
1334
1335 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1336
1337 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1338 ath_print(common, ATH_DBG_FATAL,
1339 "Unable to set channel\n");
1340 mutex_unlock(&priv->mutex);
1341 return -EINVAL;
1342 }
1343
1344 }
1345 if (changed & IEEE80211_CONF_CHANGE_PS) {
1346 if (conf->flags & IEEE80211_CONF_PS) {
1347 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1348 priv->ps_enabled = true;
1349 } else {
1350 priv->ps_enabled = false;
1351 cancel_work_sync(&priv->ps_work);
1352 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1353 }
1354 }
1355
1356 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1357 if (conf->flags & IEEE80211_CONF_MONITOR) {
1358 if (ath9k_htc_add_monitor_interface(priv))
1359 ath_print(common, ATH_DBG_FATAL,
1360 "Failed to set monitor mode\n");
1361 else
1362 ath_print(common, ATH_DBG_CONFIG,
1363 "HW opmode set to Monitor mode\n");
1364 }
1365 }
1366
1367 mutex_unlock(&priv->mutex);
1368
1369 return 0;
1370}
1371
1372#define SUPPORTED_FILTERS \
1373 (FIF_PROMISC_IN_BSS | \
1374 FIF_ALLMULTI | \
1375 FIF_CONTROL | \
1376 FIF_PSPOLL | \
1377 FIF_OTHER_BSS | \
1378 FIF_BCN_PRBRESP_PROMISC | \
1379 FIF_FCSFAIL)
1380
1381static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1382 unsigned int changed_flags,
1383 unsigned int *total_flags,
1384 u64 multicast)
1385{
1386 struct ath9k_htc_priv *priv = hw->priv;
1387 u32 rfilt;
1388
1389 mutex_lock(&priv->mutex);
1390
1391 ath9k_htc_ps_wakeup(priv);
1392 changed_flags &= SUPPORTED_FILTERS;
1393 *total_flags &= SUPPORTED_FILTERS;
1394
1395 priv->rxfilter = *total_flags;
1396 rfilt = ath9k_htc_calcrxfilter(priv);
1397 ath9k_hw_setrxfilter(priv->ah, rfilt);
1398
1399 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1400 "Set HW RX filter: 0x%x\n", rfilt);
1401
1402 ath9k_htc_ps_restore(priv);
1403 mutex_unlock(&priv->mutex);
1404}
1405
1406static void ath9k_htc_sta_notify(struct ieee80211_hw *hw,
1407 struct ieee80211_vif *vif,
1408 enum sta_notify_cmd cmd,
1409 struct ieee80211_sta *sta)
1410{
1411 struct ath9k_htc_priv *priv = hw->priv;
1412 int ret;
1413
1414 switch (cmd) {
1415 case STA_NOTIFY_ADD:
1416 ret = ath9k_htc_add_station(priv, vif, sta);
1417 if (!ret)
1418 ath9k_htc_init_rate(priv, vif, sta);
1419 break;
1420 case STA_NOTIFY_REMOVE:
1421 ath9k_htc_remove_station(priv, vif, sta);
1422 break;
1423 default:
1424 break;
1425 }
1426}
1427
1428static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1429 const struct ieee80211_tx_queue_params *params)
1430{
1431 struct ath9k_htc_priv *priv = hw->priv;
1432 struct ath_common *common = ath9k_hw_common(priv->ah);
1433 struct ath9k_tx_queue_info qi;
1434 int ret = 0, qnum;
1435
1436 if (queue >= WME_NUM_AC)
1437 return 0;
1438
1439 mutex_lock(&priv->mutex);
1440
1441 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1442
1443 qi.tqi_aifs = params->aifs;
1444 qi.tqi_cwmin = params->cw_min;
1445 qi.tqi_cwmax = params->cw_max;
1446 qi.tqi_burstTime = params->txop;
1447
1448 qnum = get_hw_qnum(queue, priv->hwq_map);
1449
1450 ath_print(common, ATH_DBG_CONFIG,
1451 "Configure tx [queue/hwq] [%d/%d], "
1452 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1453 queue, qnum, params->aifs, params->cw_min,
1454 params->cw_max, params->txop);
1455
1456 ret = ath_htc_txq_update(priv, qnum, &qi);
1457 if (ret)
1458 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1459
1460 mutex_unlock(&priv->mutex);
1461
1462 return ret;
1463}
1464
1465static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1466 enum set_key_cmd cmd,
1467 struct ieee80211_vif *vif,
1468 struct ieee80211_sta *sta,
1469 struct ieee80211_key_conf *key)
1470{
1471 struct ath9k_htc_priv *priv = hw->priv;
1472 struct ath_common *common = ath9k_hw_common(priv->ah);
1473 int ret = 0;
1474
1475 if (htc_modparam_nohwcrypt)
1476 return -ENOSPC;
1477
1478 mutex_lock(&priv->mutex);
1479 ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1480 ath9k_htc_ps_wakeup(priv);
1481
1482 switch (cmd) {
1483 case SET_KEY:
1484 ret = ath9k_cmn_key_config(common, vif, sta, key);
1485 if (ret >= 0) {
1486 key->hw_key_idx = ret;
1487 /* push IV and Michael MIC generation to stack */
1488 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1489 if (key->alg == ALG_TKIP)
1490 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1491 if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
1492 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1493 ret = 0;
1494 }
1495 break;
1496 case DISABLE_KEY:
1497 ath9k_cmn_key_delete(common, key);
1498 break;
1499 default:
1500 ret = -EINVAL;
1501 }
1502
1503 ath9k_htc_ps_restore(priv);
1504 mutex_unlock(&priv->mutex);
1505
1506 return ret;
1507}
1508
1509static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1510 struct ieee80211_vif *vif,
1511 struct ieee80211_bss_conf *bss_conf,
1512 u32 changed)
1513{
1514 struct ath9k_htc_priv *priv = hw->priv;
1515 struct ath_hw *ah = priv->ah;
1516 struct ath_common *common = ath9k_hw_common(ah);
1517
1518 mutex_lock(&priv->mutex);
1519 ath9k_htc_ps_wakeup(priv);
1520
1521 if (changed & BSS_CHANGED_ASSOC) {
1522 common->curaid = bss_conf->assoc ?
1523 bss_conf->aid : 0;
1524 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1525 bss_conf->assoc);
1526
1527 if (bss_conf->assoc) {
1528 priv->op_flags |= OP_ASSOCIATED;
1529 ath_start_ani(priv);
1530 } else {
1531 priv->op_flags &= ~OP_ASSOCIATED;
1532 cancel_work_sync(&priv->ps_work);
1533 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1534 }
1535 }
1536
1537 if (changed & BSS_CHANGED_BSSID) {
1538 /* Set BSSID */
1539 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1540 ath9k_hw_write_associd(ah);
1541
1542 ath_print(common, ATH_DBG_CONFIG,
1543 "BSSID: %pM aid: 0x%x\n",
1544 common->curbssid, common->curaid);
1545 }
1546
1547 if ((changed & BSS_CHANGED_BEACON_INT) ||
1548 (changed & BSS_CHANGED_BEACON) ||
1549 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1550 bss_conf->enable_beacon)) {
1551 priv->op_flags |= OP_ENABLE_BEACON;
1552 ath9k_htc_beacon_config(priv, vif);
1553 }
1554
1555 if (changed & BSS_CHANGED_BEACON)
1556 ath9k_htc_beacon_update(priv, vif);
1557
1558 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1559 !bss_conf->enable_beacon) {
1560 priv->op_flags &= ~OP_ENABLE_BEACON;
1561 ath9k_htc_beacon_config(priv, vif);
1562 }
1563
1564 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1565 ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1566 bss_conf->use_short_preamble);
1567 if (bss_conf->use_short_preamble)
1568 priv->op_flags |= OP_PREAMBLE_SHORT;
1569 else
1570 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1571 }
1572
1573 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1574 ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1575 bss_conf->use_cts_prot);
1576 if (bss_conf->use_cts_prot &&
1577 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1578 priv->op_flags |= OP_PROTECT_ENABLE;
1579 else
1580 priv->op_flags &= ~OP_PROTECT_ENABLE;
1581 }
1582
1583 if (changed & BSS_CHANGED_ERP_SLOT) {
1584 if (bss_conf->use_short_slot)
1585 ah->slottime = 9;
1586 else
1587 ah->slottime = 20;
1588
1589 ath9k_hw_init_global_settings(ah);
1590 }
1591
1592 ath9k_htc_ps_restore(priv);
1593 mutex_unlock(&priv->mutex);
1594}
1595
1596static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1597{
1598 struct ath9k_htc_priv *priv = hw->priv;
1599 u64 tsf;
1600
1601 mutex_lock(&priv->mutex);
1602 tsf = ath9k_hw_gettsf64(priv->ah);
1603 mutex_unlock(&priv->mutex);
1604
1605 return tsf;
1606}
1607
1608static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1609{
1610 struct ath9k_htc_priv *priv = hw->priv;
1611
1612 mutex_lock(&priv->mutex);
1613 ath9k_hw_settsf64(priv->ah, tsf);
1614 mutex_unlock(&priv->mutex);
1615}
1616
1617static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1618{
1619 struct ath9k_htc_priv *priv = hw->priv;
1620
1621 ath9k_htc_ps_wakeup(priv);
1622 mutex_lock(&priv->mutex);
1623 ath9k_hw_reset_tsf(priv->ah);
1624 mutex_unlock(&priv->mutex);
1625 ath9k_htc_ps_restore(priv);
1626}
1627
1628static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1629 struct ieee80211_vif *vif,
1630 enum ieee80211_ampdu_mlme_action action,
1631 struct ieee80211_sta *sta,
1632 u16 tid, u16 *ssn)
1633{
1634 struct ath9k_htc_priv *priv = hw->priv;
1635 struct ath9k_htc_aggr_work *work = &priv->aggr_work;
1636 struct ath9k_htc_sta *ista;
1637
1638 switch (action) {
1639 case IEEE80211_AMPDU_RX_START:
1640 break;
1641 case IEEE80211_AMPDU_RX_STOP:
1642 break;
1643 case IEEE80211_AMPDU_TX_START:
1644 case IEEE80211_AMPDU_TX_STOP:
1645 if (!(priv->op_flags & OP_TXAGGR))
1646 return -ENOTSUPP;
1647 memcpy(work->sta_addr, sta->addr, ETH_ALEN);
1648 work->hw = hw;
1649 work->vif = vif;
1650 work->action = action;
1651 work->tid = tid;
1652 ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0);
1653 break;
1654 case IEEE80211_AMPDU_TX_OPERATIONAL:
1655 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1656 ista->tid_state[tid] = AGGR_OPERATIONAL;
1657 break;
1658 default:
1659 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1660 "Unknown AMPDU action\n");
1661 }
1662
1663 return 0;
1664}
1665
1666static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1667{
1668 struct ath9k_htc_priv *priv = hw->priv;
1669
1670 mutex_lock(&priv->mutex);
1671 spin_lock_bh(&priv->beacon_lock);
1672 priv->op_flags |= OP_SCANNING;
1673 spin_unlock_bh(&priv->beacon_lock);
1674 cancel_work_sync(&priv->ps_work);
1675 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1676 mutex_unlock(&priv->mutex);
1677}
1678
1679static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1680{
1681 struct ath9k_htc_priv *priv = hw->priv;
1682
1683 ath9k_htc_ps_wakeup(priv);
1684 mutex_lock(&priv->mutex);
1685 spin_lock_bh(&priv->beacon_lock);
1686 priv->op_flags &= ~OP_SCANNING;
1687 spin_unlock_bh(&priv->beacon_lock);
1688 priv->op_flags |= OP_FULL_RESET;
1689 if (priv->op_flags & OP_ASSOCIATED)
1690 ath9k_htc_beacon_config(priv, NULL);
1691 ath_start_ani(priv);
1692 mutex_unlock(&priv->mutex);
1693 ath9k_htc_ps_restore(priv);
1694}
1695
1696static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1697{
1698 return 0;
1699}
1700
1701static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1702 u8 coverage_class)
1703{
1704 struct ath9k_htc_priv *priv = hw->priv;
1705
1706 mutex_lock(&priv->mutex);
1707 priv->ah->coverage_class = coverage_class;
1708 ath9k_hw_init_global_settings(priv->ah);
1709 mutex_unlock(&priv->mutex);
1710}
1711
1712struct ieee80211_ops ath9k_htc_ops = {
1713 .tx = ath9k_htc_tx,
1714 .start = ath9k_htc_start,
1715 .stop = ath9k_htc_stop,
1716 .add_interface = ath9k_htc_add_interface,
1717 .remove_interface = ath9k_htc_remove_interface,
1718 .config = ath9k_htc_config,
1719 .configure_filter = ath9k_htc_configure_filter,
1720 .sta_notify = ath9k_htc_sta_notify,
1721 .conf_tx = ath9k_htc_conf_tx,
1722 .bss_info_changed = ath9k_htc_bss_info_changed,
1723 .set_key = ath9k_htc_set_key,
1724 .get_tsf = ath9k_htc_get_tsf,
1725 .set_tsf = ath9k_htc_set_tsf,
1726 .reset_tsf = ath9k_htc_reset_tsf,
1727 .ampdu_action = ath9k_htc_ampdu_action,
1728 .sw_scan_start = ath9k_htc_sw_scan_start,
1729 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1730 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1731 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1732 .set_coverage_class = ath9k_htc_set_coverage_class,
1733};
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
new file mode 100644
index 000000000000..0a7cb30af5b4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -0,0 +1,704 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19/******/
20/* TX */
21/******/
22
23int get_hw_qnum(u16 queue, int *hwq_map)
24{
25 switch (queue) {
26 case 0:
27 return hwq_map[ATH9K_WME_AC_VO];
28 case 1:
29 return hwq_map[ATH9K_WME_AC_VI];
30 case 2:
31 return hwq_map[ATH9K_WME_AC_BE];
32 case 3:
33 return hwq_map[ATH9K_WME_AC_BK];
34 default:
35 return hwq_map[ATH9K_WME_AC_BE];
36 }
37}
38
39int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
40 struct ath9k_tx_queue_info *qinfo)
41{
42 struct ath_hw *ah = priv->ah;
43 int error = 0;
44 struct ath9k_tx_queue_info qi;
45
46 ath9k_hw_get_txq_props(ah, qnum, &qi);
47
48 qi.tqi_aifs = qinfo->tqi_aifs;
49 qi.tqi_cwmin = qinfo->tqi_cwmin / 2; /* XXX */
50 qi.tqi_cwmax = qinfo->tqi_cwmax;
51 qi.tqi_burstTime = qinfo->tqi_burstTime;
52 qi.tqi_readyTime = qinfo->tqi_readyTime;
53
54 if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
55 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
56 "Unable to update hardware queue %u!\n", qnum);
57 error = -EIO;
58 } else {
59 ath9k_hw_resettxqueue(ah, qnum);
60 }
61
62 return error;
63}
64
65int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
66{
67 struct ieee80211_hdr *hdr;
68 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
69 struct ieee80211_sta *sta = tx_info->control.sta;
70 struct ath9k_htc_sta *ista;
71 struct ath9k_htc_vif *avp;
72 struct ath9k_htc_tx_ctl tx_ctl;
73 enum htc_endpoint_id epid;
74 u16 qnum, hw_qnum;
75 __le16 fc;
76 u8 *tx_fhdr;
77 u8 sta_idx;
78
79 hdr = (struct ieee80211_hdr *) skb->data;
80 fc = hdr->frame_control;
81
82 avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv;
83 if (sta) {
84 ista = (struct ath9k_htc_sta *) sta->drv_priv;
85 sta_idx = ista->index;
86 } else {
87 sta_idx = 0;
88 }
89
90 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
91
92 if (ieee80211_is_data(fc)) {
93 struct tx_frame_hdr tx_hdr;
94 u8 *qc;
95
96 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
97
98 tx_hdr.node_idx = sta_idx;
99 tx_hdr.vif_idx = avp->index;
100
101 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
102 tx_ctl.type = ATH9K_HTC_AMPDU;
103 tx_hdr.data_type = ATH9K_HTC_AMPDU;
104 } else {
105 tx_ctl.type = ATH9K_HTC_NORMAL;
106 tx_hdr.data_type = ATH9K_HTC_NORMAL;
107 }
108
109 if (ieee80211_is_data(fc)) {
110 qc = ieee80211_get_qos_ctl(hdr);
111 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
112 }
113
114 /* Check for RTS protection */
115 if (priv->hw->wiphy->rts_threshold != (u32) -1)
116 if (skb->len > priv->hw->wiphy->rts_threshold)
117 tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS;
118
119 /* CTS-to-self */
120 if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) &&
121 (priv->op_flags & OP_PROTECT_ENABLE))
122 tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY;
123
124 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
125 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
126 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
127 else
128 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
129
130 tx_fhdr = skb_push(skb, sizeof(tx_hdr));
131 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
132
133 qnum = skb_get_queue_mapping(skb);
134 hw_qnum = get_hw_qnum(qnum, priv->hwq_map);
135
136 switch (hw_qnum) {
137 case 0:
138 epid = priv->data_be_ep;
139 break;
140 case 2:
141 epid = priv->data_vi_ep;
142 break;
143 case 3:
144 epid = priv->data_vo_ep;
145 break;
146 case 1:
147 default:
148 epid = priv->data_bk_ep;
149 break;
150 }
151 } else {
152 struct tx_mgmt_hdr mgmt_hdr;
153
154 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
155
156 tx_ctl.type = ATH9K_HTC_NORMAL;
157
158 mgmt_hdr.node_idx = sta_idx;
159 mgmt_hdr.vif_idx = avp->index;
160 mgmt_hdr.tidno = 0;
161 mgmt_hdr.flags = 0;
162
163 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
164 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
165 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
166 else
167 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
168
169 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
170 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
171 epid = priv->mgmt_ep;
172 }
173
174 return htc_send(priv->htc, skb, epid, &tx_ctl);
175}
176
177void ath9k_tx_tasklet(unsigned long data)
178{
179 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
180 struct ieee80211_sta *sta;
181 struct ieee80211_hdr *hdr;
182 struct ieee80211_tx_info *tx_info;
183 struct sk_buff *skb = NULL;
184 __le16 fc;
185
186 while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) {
187
188 hdr = (struct ieee80211_hdr *) skb->data;
189 fc = hdr->frame_control;
190 tx_info = IEEE80211_SKB_CB(skb);
191
192 memset(&tx_info->status, 0, sizeof(tx_info->status));
193
194 rcu_read_lock();
195
196 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
197 if (!sta) {
198 rcu_read_unlock();
199 ieee80211_tx_status(priv->hw, skb);
200 continue;
201 }
202
203 /* Check if we need to start aggregation */
204
205 if (sta && conf_is_ht(&priv->hw->conf) &&
206 (priv->op_flags & OP_TXAGGR)
207 && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
208 if (ieee80211_is_data_qos(fc)) {
209 u8 *qc, tid;
210 struct ath9k_htc_sta *ista;
211
212 qc = ieee80211_get_qos_ctl(hdr);
213 tid = qc[0] & 0xf;
214 ista = (struct ath9k_htc_sta *)sta->drv_priv;
215
216 if ((tid < ATH9K_HTC_MAX_TID) &&
217 ista->tid_state[tid] == AGGR_STOP) {
218 ieee80211_start_tx_ba_session(sta, tid);
219 ista->tid_state[tid] = AGGR_PROGRESS;
220 }
221 }
222 }
223
224 rcu_read_unlock();
225
226 /* Send status to mac80211 */
227 ieee80211_tx_status(priv->hw, skb);
228 }
229
230 /* Wake TX queues if needed */
231 spin_lock_bh(&priv->tx_lock);
232 if (priv->tx_queues_stop) {
233 priv->tx_queues_stop = false;
234 spin_unlock_bh(&priv->tx_lock);
235 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
236 "Waking up TX queues\n");
237 ieee80211_wake_queues(priv->hw);
238 return;
239 }
240 spin_unlock_bh(&priv->tx_lock);
241}
242
243void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
244 enum htc_endpoint_id ep_id, bool txok)
245{
246 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv;
247 struct ieee80211_tx_info *tx_info;
248
249 if (!skb)
250 return;
251
252 if (ep_id == priv->mgmt_ep)
253 skb_pull(skb, sizeof(struct tx_mgmt_hdr));
254 else
255 /* TODO: Check for cab/uapsd/data */
256 skb_pull(skb, sizeof(struct tx_frame_hdr));
257
258 tx_info = IEEE80211_SKB_CB(skb);
259
260 if (txok)
261 tx_info->flags |= IEEE80211_TX_STAT_ACK;
262
263 skb_queue_tail(&priv->tx_queue, skb);
264 tasklet_schedule(&priv->tx_tasklet);
265}
266
267int ath9k_tx_init(struct ath9k_htc_priv *priv)
268{
269 skb_queue_head_init(&priv->tx_queue);
270 return 0;
271}
272
273void ath9k_tx_cleanup(struct ath9k_htc_priv *priv)
274{
275
276}
277
278bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
279 enum ath9k_tx_queue_subtype subtype)
280{
281 struct ath_hw *ah = priv->ah;
282 struct ath_common *common = ath9k_hw_common(ah);
283 struct ath9k_tx_queue_info qi;
284 int qnum;
285
286 memset(&qi, 0, sizeof(qi));
287
288 qi.tqi_subtype = subtype;
289 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
290 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
291 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
292 qi.tqi_physCompBuf = 0;
293 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE;
294
295 qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi);
296 if (qnum == -1)
297 return false;
298
299 if (qnum >= ARRAY_SIZE(priv->hwq_map)) {
300 ath_print(common, ATH_DBG_FATAL,
301 "qnum %u out of range, max %u!\n",
302 qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map));
303 ath9k_hw_releasetxqueue(ah, qnum);
304 return false;
305 }
306
307 priv->hwq_map[subtype] = qnum;
308 return true;
309}
310
311/******/
312/* RX */
313/******/
314
315/*
316 * Calculate the RX filter to be set in the HW.
317 */
318u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
319{
320#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
321
322 struct ath_hw *ah = priv->ah;
323 u32 rfilt;
324
325 rfilt = (ath9k_hw_getrxfilter(ah) & RX_FILTER_PRESERVE)
326 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
327 | ATH9K_RX_FILTER_MCAST;
328
329 /* If not a STA, enable processing of Probe Requests */
330 if (ah->opmode != NL80211_IFTYPE_STATION)
331 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
332
333 /*
334 * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
335 * mode interface or when in monitor mode. AP mode does not need this
336 * since it receives all in-BSS frames anyway.
337 */
338 if (((ah->opmode != NL80211_IFTYPE_AP) &&
339 (priv->rxfilter & FIF_PROMISC_IN_BSS)) ||
340 (ah->opmode == NL80211_IFTYPE_MONITOR))
341 rfilt |= ATH9K_RX_FILTER_PROM;
342
343 if (priv->rxfilter & FIF_CONTROL)
344 rfilt |= ATH9K_RX_FILTER_CONTROL;
345
346 if ((ah->opmode == NL80211_IFTYPE_STATION) &&
347 !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC))
348 rfilt |= ATH9K_RX_FILTER_MYBEACON;
349 else
350 rfilt |= ATH9K_RX_FILTER_BEACON;
351
352 if (conf_is_ht(&priv->hw->conf))
353 rfilt |= ATH9K_RX_FILTER_COMP_BAR;
354
355 return rfilt;
356
357#undef RX_FILTER_PRESERVE
358}
359
360/*
361 * Recv initialization for opmode change.
362 */
363static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)
364{
365 struct ath_hw *ah = priv->ah;
366 struct ath_common *common = ath9k_hw_common(ah);
367
368 u32 rfilt, mfilt[2];
369
370 /* configure rx filter */
371 rfilt = ath9k_htc_calcrxfilter(priv);
372 ath9k_hw_setrxfilter(ah, rfilt);
373
374 /* configure bssid mask */
375 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
376 ath_hw_setbssidmask(common);
377
378 /* configure operational mode */
379 ath9k_hw_setopmode(ah);
380
381 /* Handle any link-level address change. */
382 ath9k_hw_setmac(ah, common->macaddr);
383
384 /* calculate and install multicast filter */
385 mfilt[0] = mfilt[1] = ~0;
386 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
387}
388
389void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
390{
391 ath9k_hw_rxena(priv->ah);
392 ath9k_htc_opmode_init(priv);
393 ath9k_hw_startpcureceive(priv->ah);
394 priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER;
395}
396
397static void ath9k_process_rate(struct ieee80211_hw *hw,
398 struct ieee80211_rx_status *rxs,
399 u8 rx_rate, u8 rs_flags)
400{
401 struct ieee80211_supported_band *sband;
402 enum ieee80211_band band;
403 unsigned int i = 0;
404
405 if (rx_rate & 0x80) {
406 /* HT rate */
407 rxs->flag |= RX_FLAG_HT;
408 if (rs_flags & ATH9K_RX_2040)
409 rxs->flag |= RX_FLAG_40MHZ;
410 if (rs_flags & ATH9K_RX_GI)
411 rxs->flag |= RX_FLAG_SHORT_GI;
412 rxs->rate_idx = rx_rate & 0x7f;
413 return;
414 }
415
416 band = hw->conf.channel->band;
417 sband = hw->wiphy->bands[band];
418
419 for (i = 0; i < sband->n_bitrates; i++) {
420 if (sband->bitrates[i].hw_value == rx_rate) {
421 rxs->rate_idx = i;
422 return;
423 }
424 if (sband->bitrates[i].hw_value_short == rx_rate) {
425 rxs->rate_idx = i;
426 rxs->flag |= RX_FLAG_SHORTPRE;
427 return;
428 }
429 }
430
431}
432
433static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
434 struct ath9k_htc_rxbuf *rxbuf,
435 struct ieee80211_rx_status *rx_status)
436
437{
438 struct ieee80211_hdr *hdr;
439 struct ieee80211_hw *hw = priv->hw;
440 struct sk_buff *skb = rxbuf->skb;
441 struct ath_common *common = ath9k_hw_common(priv->ah);
442 int hdrlen, padpos, padsize;
443 int last_rssi = ATH_RSSI_DUMMY_MARKER;
444 __le16 fc;
445
446 hdr = (struct ieee80211_hdr *)skb->data;
447 fc = hdr->frame_control;
448 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
449
450 padpos = ath9k_cmn_padpos(fc);
451
452 padsize = padpos & 3;
453 if (padsize && skb->len >= padpos+padsize+FCS_LEN) {
454 memmove(skb->data + padsize, skb->data, padpos);
455 skb_pull(skb, padsize);
456 }
457
458 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
459
460 if (rxbuf->rxstatus.rs_status != 0) {
461 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_CRC)
462 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
463 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_PHY)
464 goto rx_next;
465
466 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT) {
467 /* FIXME */
468 } else if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_MIC) {
469 if (ieee80211_is_ctl(fc))
470 /*
471 * Sometimes, we get invalid
472 * MIC failures on valid control frames.
473 * Remove these mic errors.
474 */
475 rxbuf->rxstatus.rs_status &= ~ATH9K_RXERR_MIC;
476 else
477 rx_status->flag |= RX_FLAG_MMIC_ERROR;
478 }
479
480 /*
481 * Reject error frames with the exception of
482 * decryption and MIC failures. For monitor mode,
483 * we also ignore the CRC error.
484 */
485 if (priv->ah->opmode == NL80211_IFTYPE_MONITOR) {
486 if (rxbuf->rxstatus.rs_status &
487 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
488 ATH9K_RXERR_CRC))
489 goto rx_next;
490 } else {
491 if (rxbuf->rxstatus.rs_status &
492 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
493 goto rx_next;
494 }
495 }
496 }
497
498 if (!(rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT)) {
499 u8 keyix;
500 keyix = rxbuf->rxstatus.rs_keyix;
501 if (keyix != ATH9K_RXKEYIX_INVALID) {
502 rx_status->flag |= RX_FLAG_DECRYPTED;
503 } else if (ieee80211_has_protected(fc) &&
504 skb->len >= hdrlen + 4) {
505 keyix = skb->data[hdrlen + 3] >> 6;
506 if (test_bit(keyix, common->keymap))
507 rx_status->flag |= RX_FLAG_DECRYPTED;
508 }
509 }
510
511 ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate,
512 rxbuf->rxstatus.rs_flags);
513
514 if (priv->op_flags & OP_ASSOCIATED) {
515 if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD &&
516 !rxbuf->rxstatus.rs_moreaggr)
517 ATH_RSSI_LPF(priv->rx.last_rssi,
518 rxbuf->rxstatus.rs_rssi);
519
520 last_rssi = priv->rx.last_rssi;
521
522 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
523 rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
524 ATH_RSSI_EP_MULTIPLIER);
525
526 if (rxbuf->rxstatus.rs_rssi < 0)
527 rxbuf->rxstatus.rs_rssi = 0;
528
529 if (ieee80211_is_beacon(fc))
530 priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
531 }
532
533 rx_status->mactime = rxbuf->rxstatus.rs_tstamp;
534 rx_status->band = hw->conf.channel->band;
535 rx_status->freq = hw->conf.channel->center_freq;
536 rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
537 rx_status->antenna = rxbuf->rxstatus.rs_antenna;
538 rx_status->flag |= RX_FLAG_TSFT;
539
540 return true;
541
542rx_next:
543 return false;
544}
545
546/*
547 * FIXME: Handle FLUSH later on.
548 */
549void ath9k_rx_tasklet(unsigned long data)
550{
551 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
552 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
553 struct ieee80211_rx_status rx_status;
554 struct sk_buff *skb;
555 unsigned long flags;
556 struct ieee80211_hdr *hdr;
557
558 do {
559 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
560 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
561 if (tmp_buf->in_process) {
562 rxbuf = tmp_buf;
563 break;
564 }
565 }
566
567 if (rxbuf == NULL) {
568 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
569 break;
570 }
571
572 if (!rxbuf->skb)
573 goto requeue;
574
575 if (!ath9k_rx_prepare(priv, rxbuf, &rx_status)) {
576 dev_kfree_skb_any(rxbuf->skb);
577 goto requeue;
578 }
579
580 memcpy(IEEE80211_SKB_RXCB(rxbuf->skb), &rx_status,
581 sizeof(struct ieee80211_rx_status));
582 skb = rxbuf->skb;
583 hdr = (struct ieee80211_hdr *) skb->data;
584
585 if (ieee80211_is_beacon(hdr->frame_control) && priv->ps_enabled)
586 ieee80211_queue_work(priv->hw, &priv->ps_work);
587
588 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
589
590 ieee80211_rx(priv->hw, skb);
591
592 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
593requeue:
594 rxbuf->in_process = false;
595 rxbuf->skb = NULL;
596 list_move_tail(&rxbuf->list, &priv->rx.rxbuf);
597 rxbuf = NULL;
598 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
599 } while (1);
600
601}
602
603void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
604 enum htc_endpoint_id ep_id)
605{
606 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)drv_priv;
607 struct ath_hw *ah = priv->ah;
608 struct ath_common *common = ath9k_hw_common(ah);
609 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
610 struct ath_htc_rx_status *rxstatus;
611 u32 len = 0;
612
613 spin_lock(&priv->rx.rxbuflock);
614 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
615 if (!tmp_buf->in_process) {
616 rxbuf = tmp_buf;
617 break;
618 }
619 }
620 spin_unlock(&priv->rx.rxbuflock);
621
622 if (rxbuf == NULL) {
623 ath_print(common, ATH_DBG_ANY,
624 "No free RX buffer\n");
625 goto err;
626 }
627
628 len = skb->len;
629 if (len <= HTC_RX_FRAME_HEADER_SIZE) {
630 ath_print(common, ATH_DBG_FATAL,
631 "Corrupted RX frame, dropping\n");
632 goto err;
633 }
634
635 rxstatus = (struct ath_htc_rx_status *)skb->data;
636
637 rxstatus->rs_tstamp = be64_to_cpu(rxstatus->rs_tstamp);
638 rxstatus->rs_datalen = be16_to_cpu(rxstatus->rs_datalen);
639 rxstatus->evm0 = be32_to_cpu(rxstatus->evm0);
640 rxstatus->evm1 = be32_to_cpu(rxstatus->evm1);
641 rxstatus->evm2 = be32_to_cpu(rxstatus->evm2);
642
643 if (rxstatus->rs_datalen - (len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
644 ath_print(common, ATH_DBG_FATAL,
645 "Corrupted RX data len, dropping "
646 "(epid: %d, dlen: %d, skblen: %d)\n",
647 ep_id, rxstatus->rs_datalen, len);
648 goto err;
649 }
650
651 spin_lock(&priv->rx.rxbuflock);
652 memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
653 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
654 rxbuf->skb = skb;
655 rxbuf->in_process = true;
656 spin_unlock(&priv->rx.rxbuflock);
657
658 tasklet_schedule(&priv->rx_tasklet);
659 return;
660err:
661 dev_kfree_skb_any(skb);
662 return;
663}
664
665/* FIXME: Locking for cleanup/init */
666
667void ath9k_rx_cleanup(struct ath9k_htc_priv *priv)
668{
669 struct ath9k_htc_rxbuf *rxbuf, *tbuf;
670
671 list_for_each_entry_safe(rxbuf, tbuf, &priv->rx.rxbuf, list) {
672 list_del(&rxbuf->list);
673 if (rxbuf->skb)
674 dev_kfree_skb_any(rxbuf->skb);
675 kfree(rxbuf);
676 }
677}
678
679int ath9k_rx_init(struct ath9k_htc_priv *priv)
680{
681 struct ath_hw *ah = priv->ah;
682 struct ath_common *common = ath9k_hw_common(ah);
683 struct ath9k_htc_rxbuf *rxbuf;
684 int i = 0;
685
686 INIT_LIST_HEAD(&priv->rx.rxbuf);
687 spin_lock_init(&priv->rx.rxbuflock);
688
689 for (i = 0; i < ATH9K_HTC_RXBUF; i++) {
690 rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL);
691 if (rxbuf == NULL) {
692 ath_print(common, ATH_DBG_FATAL,
693 "Unable to allocate RX buffers\n");
694 goto err;
695 }
696 list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
697 }
698
699 return 0;
700
701err:
702 ath9k_rx_cleanup(priv);
703 return -ENOMEM;
704}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
new file mode 100644
index 000000000000..30f608bfc567
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -0,0 +1,463 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
20 u16 len, u8 flags, u8 epid,
21 struct ath9k_htc_tx_ctl *tx_ctl)
22{
23 struct htc_frame_hdr *hdr;
24 struct htc_endpoint *endpoint = &target->endpoint[epid];
25 int status;
26
27 hdr = (struct htc_frame_hdr *)
28 skb_push(skb, sizeof(struct htc_frame_hdr));
29 hdr->endpoint_id = epid;
30 hdr->flags = flags;
31 hdr->payload_len = cpu_to_be16(len);
32
33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb,
34 tx_ctl);
35 return status;
36}
37
38static struct htc_endpoint *get_next_avail_ep(struct htc_endpoint *endpoint)
39{
40 enum htc_endpoint_id avail_epid;
41
42 for (avail_epid = ENDPOINT_MAX; avail_epid > ENDPOINT0; avail_epid--)
43 if (endpoint[avail_epid].service_id == 0)
44 return &endpoint[avail_epid];
45 return NULL;
46}
47
48static u8 service_to_ulpipe(u16 service_id)
49{
50 switch (service_id) {
51 case WMI_CONTROL_SVC:
52 return 4;
53 case WMI_BEACON_SVC:
54 case WMI_CAB_SVC:
55 case WMI_UAPSD_SVC:
56 case WMI_MGMT_SVC:
57 case WMI_DATA_VO_SVC:
58 case WMI_DATA_VI_SVC:
59 case WMI_DATA_BE_SVC:
60 case WMI_DATA_BK_SVC:
61 return 1;
62 default:
63 return 0;
64 }
65}
66
67static u8 service_to_dlpipe(u16 service_id)
68{
69 switch (service_id) {
70 case WMI_CONTROL_SVC:
71 return 3;
72 case WMI_BEACON_SVC:
73 case WMI_CAB_SVC:
74 case WMI_UAPSD_SVC:
75 case WMI_MGMT_SVC:
76 case WMI_DATA_VO_SVC:
77 case WMI_DATA_VI_SVC:
78 case WMI_DATA_BE_SVC:
79 case WMI_DATA_BK_SVC:
80 return 2;
81 default:
82 return 0;
83 }
84}
85
86static void htc_process_target_rdy(struct htc_target *target,
87 void *buf)
88{
89 struct htc_endpoint *endpoint;
90 struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
91
92 target->credits = be16_to_cpu(htc_ready_msg->credits);
93 target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
94
95 endpoint = &target->endpoint[ENDPOINT0];
96 endpoint->service_id = HTC_CTRL_RSVD_SVC;
97 endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
98 complete(&target->target_wait);
99}
100
101static void htc_process_conn_rsp(struct htc_target *target,
102 struct htc_frame_hdr *htc_hdr)
103{
104 struct htc_conn_svc_rspmsg *svc_rspmsg;
105 struct htc_endpoint *endpoint, *tmp_endpoint = NULL;
106 u16 service_id;
107 u16 max_msglen;
108 enum htc_endpoint_id epid, tepid;
109
110 svc_rspmsg = (struct htc_conn_svc_rspmsg *)
111 ((void *) htc_hdr + sizeof(struct htc_frame_hdr));
112
113 if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
114 epid = svc_rspmsg->endpoint_id;
115 service_id = be16_to_cpu(svc_rspmsg->service_id);
116 max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
117 endpoint = &target->endpoint[epid];
118
119 for (tepid = ENDPOINT_MAX; tepid > ENDPOINT0; tepid--) {
120 tmp_endpoint = &target->endpoint[tepid];
121 if (tmp_endpoint->service_id == service_id) {
122 tmp_endpoint->service_id = 0;
123 break;
124 }
125 }
126
127 if (!tmp_endpoint)
128 return;
129
130 endpoint->service_id = service_id;
131 endpoint->max_txqdepth = tmp_endpoint->max_txqdepth;
132 endpoint->ep_callbacks = tmp_endpoint->ep_callbacks;
133 endpoint->ul_pipeid = tmp_endpoint->ul_pipeid;
134 endpoint->dl_pipeid = tmp_endpoint->dl_pipeid;
135 endpoint->max_msglen = max_msglen;
136 target->conn_rsp_epid = epid;
137 complete(&target->cmd_wait);
138 } else {
139 target->conn_rsp_epid = ENDPOINT_UNUSED;
140 }
141}
142
143static int htc_config_pipe_credits(struct htc_target *target)
144{
145 struct sk_buff *skb;
146 struct htc_config_pipe_msg *cp_msg;
147 int ret, time_left;
148
149 skb = dev_alloc_skb(50 + sizeof(struct htc_frame_hdr));
150 if (!skb) {
151 dev_err(target->dev, "failed to allocate send buffer\n");
152 return -ENOMEM;
153 }
154 skb_reserve(skb, sizeof(struct htc_frame_hdr));
155
156 cp_msg = (struct htc_config_pipe_msg *)
157 skb_put(skb, sizeof(struct htc_config_pipe_msg));
158
159 cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID);
160 cp_msg->pipe_id = USB_WLAN_TX_PIPE;
161 cp_msg->credits = 28;
162
163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
164
165 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
166 if (ret)
167 goto err;
168
169 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
170 if (!time_left) {
171 dev_err(target->dev, "HTC credit config timeout\n");
172 return -ETIMEDOUT;
173 }
174
175 return 0;
176err:
177 dev_kfree_skb(skb);
178 return -EINVAL;
179}
180
181static int htc_setup_complete(struct htc_target *target)
182{
183 struct sk_buff *skb;
184 struct htc_comp_msg *comp_msg;
185 int ret = 0, time_left;
186
187 skb = dev_alloc_skb(50 + sizeof(struct htc_frame_hdr));
188 if (!skb) {
189 dev_err(target->dev, "failed to allocate send buffer\n");
190 return -ENOMEM;
191 }
192 skb_reserve(skb, sizeof(struct htc_frame_hdr));
193
194 comp_msg = (struct htc_comp_msg *)
195 skb_put(skb, sizeof(struct htc_comp_msg));
196 comp_msg->msg_id = cpu_to_be16(HTC_MSG_SETUP_COMPLETE_ID);
197
198 target->htc_flags |= HTC_OP_START_WAIT;
199
200 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
201 if (ret)
202 goto err;
203
204 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
205 if (!time_left) {
206 dev_err(target->dev, "HTC start timeout\n");
207 return -ETIMEDOUT;
208 }
209
210 return 0;
211
212err:
213 dev_kfree_skb(skb);
214 return -EINVAL;
215}
216
217/* HTC APIs */
218
219int htc_init(struct htc_target *target)
220{
221 int ret;
222
223 ret = htc_config_pipe_credits(target);
224 if (ret)
225 return ret;
226
227 return htc_setup_complete(target);
228}
229
230int htc_connect_service(struct htc_target *target,
231 struct htc_service_connreq *service_connreq,
232 enum htc_endpoint_id *conn_rsp_epid)
233{
234 struct sk_buff *skb;
235 struct htc_endpoint *endpoint;
236 struct htc_conn_svc_msg *conn_msg;
237 int ret, time_left;
238
239 /* Find an available endpoint */
240 endpoint = get_next_avail_ep(target->endpoint);
241 if (!endpoint) {
242 dev_err(target->dev, "Endpoint is not available for"
243 "service %d\n", service_connreq->service_id);
244 return -EINVAL;
245 }
246
247 endpoint->service_id = service_connreq->service_id;
248 endpoint->max_txqdepth = service_connreq->max_send_qdepth;
249 endpoint->ul_pipeid = service_to_ulpipe(service_connreq->service_id);
250 endpoint->dl_pipeid = service_to_dlpipe(service_connreq->service_id);
251 endpoint->ep_callbacks = service_connreq->ep_callbacks;
252
253 skb = dev_alloc_skb(sizeof(struct htc_conn_svc_msg) +
254 sizeof(struct htc_frame_hdr));
255 if (!skb) {
256 dev_err(target->dev, "Failed to allocate buf to send"
257 "service connect req\n");
258 return -ENOMEM;
259 }
260
261 skb_reserve(skb, sizeof(struct htc_frame_hdr));
262
263 conn_msg = (struct htc_conn_svc_msg *)
264 skb_put(skb, sizeof(struct htc_conn_svc_msg));
265 conn_msg->service_id = cpu_to_be16(service_connreq->service_id);
266 conn_msg->msg_id = cpu_to_be16(HTC_MSG_CONNECT_SERVICE_ID);
267 conn_msg->con_flags = cpu_to_be16(service_connreq->con_flags);
268 conn_msg->dl_pipeid = endpoint->dl_pipeid;
269 conn_msg->ul_pipeid = endpoint->ul_pipeid;
270
271 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
272 if (ret)
273 goto err;
274
275 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
276 if (!time_left) {
277 dev_err(target->dev, "Service connection timeout for: %d\n",
278 service_connreq->service_id);
279 return -ETIMEDOUT;
280 }
281
282 *conn_rsp_epid = target->conn_rsp_epid;
283 return 0;
284err:
285 dev_kfree_skb(skb);
286 return ret;
287}
288
289int htc_send(struct htc_target *target, struct sk_buff *skb,
290 enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl)
291{
292 return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl);
293}
294
295void htc_stop(struct htc_target *target)
296{
297 enum htc_endpoint_id epid;
298 struct htc_endpoint *endpoint;
299
300 for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
301 endpoint = &target->endpoint[epid];
302 if (endpoint->service_id != 0)
303 target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
304 }
305}
306
307void htc_start(struct htc_target *target)
308{
309 enum htc_endpoint_id epid;
310 struct htc_endpoint *endpoint;
311
312 for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
313 endpoint = &target->endpoint[epid];
314 if (endpoint->service_id != 0)
315 target->hif->start(target->hif_dev,
316 endpoint->ul_pipeid);
317 }
318}
319
320void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
321 struct sk_buff *skb, bool txok)
322{
323 struct htc_endpoint *endpoint;
324 struct htc_frame_hdr *htc_hdr;
325
326 if (htc_handle->htc_flags & HTC_OP_CONFIG_PIPE_CREDITS) {
327 complete(&htc_handle->cmd_wait);
328 htc_handle->htc_flags &= ~HTC_OP_CONFIG_PIPE_CREDITS;
329 }
330
331 if (htc_handle->htc_flags & HTC_OP_START_WAIT) {
332 complete(&htc_handle->cmd_wait);
333 htc_handle->htc_flags &= ~HTC_OP_START_WAIT;
334 }
335
336 if (skb) {
337 htc_hdr = (struct htc_frame_hdr *) skb->data;
338 endpoint = &htc_handle->endpoint[htc_hdr->endpoint_id];
339 skb_pull(skb, sizeof(struct htc_frame_hdr));
340
341 if (endpoint->ep_callbacks.tx) {
342 endpoint->ep_callbacks.tx(htc_handle->drv_priv, skb,
343 htc_hdr->endpoint_id, txok);
344 }
345 }
346}
347
348/*
349 * HTC Messages are handled directly here and the obtained SKB
350 * is freed.
351 *
352 * Sevice messages (Data, WMI) passed to the corresponding
353 * endpoint RX handlers, which have to free the SKB.
354 */
355void ath9k_htc_rx_msg(struct htc_target *htc_handle,
356 struct sk_buff *skb, u32 len, u8 pipe_id)
357{
358 struct htc_frame_hdr *htc_hdr;
359 enum htc_endpoint_id epid;
360 struct htc_endpoint *endpoint;
361 u16 *msg_id;
362
363 if (!htc_handle || !skb)
364 return;
365
366 htc_hdr = (struct htc_frame_hdr *) skb->data;
367 epid = htc_hdr->endpoint_id;
368
369 if (epid >= ENDPOINT_MAX) {
370 dev_kfree_skb_any(skb);
371 return;
372 }
373
374 if (epid == ENDPOINT0) {
375
376 /* Handle trailer */
377 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
378 if (be32_to_cpu(*(u32 *) skb->data) == 0x00C60000)
379 /* Move past the Watchdog pattern */
380 htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
381 }
382
383 /* Get the message ID */
384 msg_id = (u16 *) ((void *) htc_hdr +
385 sizeof(struct htc_frame_hdr));
386
387 /* Now process HTC messages */
388 switch (be16_to_cpu(*msg_id)) {
389 case HTC_MSG_READY_ID:
390 htc_process_target_rdy(htc_handle, htc_hdr);
391 break;
392 case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
393 htc_process_conn_rsp(htc_handle, htc_hdr);
394 break;
395 default:
396 break;
397 }
398
399 dev_kfree_skb_any(skb);
400
401 } else {
402 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER)
403 skb_trim(skb, len - htc_hdr->control[0]);
404
405 skb_pull(skb, sizeof(struct htc_frame_hdr));
406
407 endpoint = &htc_handle->endpoint[epid];
408 if (endpoint->ep_callbacks.rx)
409 endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
410 skb, epid);
411 }
412}
413
414struct htc_target *ath9k_htc_hw_alloc(void *hif_handle)
415{
416 struct htc_target *target;
417
418 target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
419 if (!target)
420 printk(KERN_ERR "Unable to allocate memory for"
421 "target device\n");
422
423 return target;
424}
425
426void ath9k_htc_hw_free(struct htc_target *htc)
427{
428 kfree(htc);
429}
430
431int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
432 void *hif_handle, struct device *dev, u16 devid,
433 enum ath9k_hif_transports transport)
434{
435 struct htc_endpoint *endpoint;
436 int err = 0;
437
438 init_completion(&target->target_wait);
439 init_completion(&target->cmd_wait);
440
441 target->hif = hif;
442 target->hif_dev = hif_handle;
443 target->dev = dev;
444
445 /* Assign control endpoint pipe IDs */
446 endpoint = &target->endpoint[ENDPOINT0];
447 endpoint->ul_pipeid = hif->control_ul_pipe;
448 endpoint->dl_pipeid = hif->control_dl_pipe;
449
450 err = ath9k_htc_probe_device(target, dev, devid);
451 if (err) {
452 printk(KERN_ERR "Failed to initialize the device\n");
453 return -ENODEV;
454 }
455
456 return 0;
457}
458
459void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug)
460{
461 if (target)
462 ath9k_htc_disconnect_device(target, hot_unplug);
463}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
new file mode 100644
index 000000000000..cd7048ffd239
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -0,0 +1,246 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_HST_H
18#define HTC_HST_H
19
20struct ath9k_htc_priv;
21struct htc_target;
22struct ath9k_htc_tx_ctl;
23
24enum ath9k_hif_transports {
25 ATH9K_HIF_USB,
26};
27
28struct ath9k_htc_hif {
29 struct list_head list;
30 const enum ath9k_hif_transports transport;
31 const char *name;
32
33 u8 control_dl_pipe;
34 u8 control_ul_pipe;
35
36 void (*start) (void *hif_handle, u8 pipe);
37 void (*stop) (void *hif_handle, u8 pipe);
38 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf,
39 struct ath9k_htc_tx_ctl *tx_ctl);
40};
41
42enum htc_endpoint_id {
43 ENDPOINT_UNUSED = -1,
44 ENDPOINT0 = 0,
45 ENDPOINT1 = 1,
46 ENDPOINT2 = 2,
47 ENDPOINT3 = 3,
48 ENDPOINT4 = 4,
49 ENDPOINT5 = 5,
50 ENDPOINT6 = 6,
51 ENDPOINT7 = 7,
52 ENDPOINT8 = 8,
53 ENDPOINT_MAX = 22
54};
55
56/* Htc frame hdr flags */
57#define HTC_FLAGS_RECV_TRAILER (1 << 1)
58
59struct htc_frame_hdr {
60 u8 endpoint_id;
61 u8 flags;
62 u16 payload_len;
63 u8 control[4];
64} __packed;
65
66struct htc_ready_msg {
67 u16 message_id;
68 u16 credits;
69 u16 credit_size;
70 u8 max_endpoints;
71 u8 pad;
72} __packed;
73
74struct htc_config_pipe_msg {
75 u16 message_id;
76 u8 pipe_id;
77 u8 credits;
78} __packed;
79
80struct htc_packet {
81 void *pktcontext;
82 u8 *buf;
83 u8 *buf_payload;
84 u32 buflen;
85 u32 payload_len;
86
87 int endpoint;
88 int status;
89
90 void *context;
91 u32 reserved;
92};
93
94struct htc_ep_callbacks {
95 void *priv;
96 void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
97 void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
98};
99
100#define HTC_TX_QUEUE_SIZE 256
101
102struct htc_txq {
103 struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
104 u32 txqdepth;
105 u16 txbuf_cnt;
106 u16 txq_head;
107 u16 txq_tail;
108};
109
110struct htc_endpoint {
111 u16 service_id;
112
113 struct htc_ep_callbacks ep_callbacks;
114 struct htc_txq htc_txq;
115 u32 max_txqdepth;
116 int max_msglen;
117
118 u8 ul_pipeid;
119 u8 dl_pipeid;
120};
121
122#define HTC_MAX_CONTROL_MESSAGE_LENGTH 255
123#define HTC_CONTROL_BUFFER_SIZE \
124 (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
125
126#define NUM_CONTROL_BUFFERS 8
127#define HST_ENDPOINT_MAX 8
128
129struct htc_control_buf {
130 struct htc_packet htc_pkt;
131 u8 buf[HTC_CONTROL_BUFFER_SIZE];
132};
133
134#define HTC_OP_START_WAIT BIT(0)
135#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
136
137struct htc_target {
138 void *hif_dev;
139 struct ath9k_htc_priv *drv_priv;
140 struct device *dev;
141 struct ath9k_htc_hif *hif;
142 struct htc_endpoint endpoint[HST_ENDPOINT_MAX];
143 struct completion target_wait;
144 struct completion cmd_wait;
145 struct list_head list;
146 enum htc_endpoint_id conn_rsp_epid;
147 u16 credits;
148 u16 credit_size;
149 u8 htc_flags;
150};
151
152enum htc_msg_id {
153 HTC_MSG_READY_ID = 1,
154 HTC_MSG_CONNECT_SERVICE_ID,
155 HTC_MSG_CONNECT_SERVICE_RESPONSE_ID,
156 HTC_MSG_SETUP_COMPLETE_ID,
157 HTC_MSG_CONFIG_PIPE_ID,
158 HTC_MSG_CONFIG_PIPE_RESPONSE_ID,
159};
160
161struct htc_service_connreq {
162 u16 service_id;
163 u16 con_flags;
164 u32 max_send_qdepth;
165 struct htc_ep_callbacks ep_callbacks;
166};
167
168/* Current service IDs */
169
170enum htc_service_group_ids{
171 RSVD_SERVICE_GROUP = 0,
172 WMI_SERVICE_GROUP = 1,
173
174 HTC_SERVICE_GROUP_LAST = 255
175};
176
177#define MAKE_SERVICE_ID(group, index) \
178 (int)(((int)group << 8) | (int)(index))
179
180/* NOTE: service ID of 0x0000 is reserved and should never be used */
181#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
182#define HTC_LOOPBACK_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 2)
183
184#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
185#define WMI_BEACON_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
186#define WMI_CAB_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
187#define WMI_UAPSD_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
188#define WMI_MGMT_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
189#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 5)
190#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 6)
191#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 7)
192#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8)
193
194struct htc_conn_svc_msg {
195 u16 msg_id;
196 u16 service_id;
197 u16 con_flags;
198 u8 dl_pipeid;
199 u8 ul_pipeid;
200 u8 svc_meta_len;
201 u8 pad;
202} __packed;
203
204/* connect response status codes */
205#define HTC_SERVICE_SUCCESS 0
206#define HTC_SERVICE_NOT_FOUND 1
207#define HTC_SERVICE_FAILED 2
208#define HTC_SERVICE_NO_RESOURCES 3
209#define HTC_SERVICE_NO_MORE_EP 4
210
211struct htc_conn_svc_rspmsg {
212 u16 msg_id;
213 u16 service_id;
214 u8 status;
215 u8 endpoint_id;
216 u16 max_msg_len;
217 u8 svc_meta_len;
218 u8 pad;
219} __packed;
220
221struct htc_comp_msg {
222 u16 msg_id;
223} __packed;
224
225int htc_init(struct htc_target *target);
226int htc_connect_service(struct htc_target *target,
227 struct htc_service_connreq *service_connreq,
228 enum htc_endpoint_id *conn_rsp_eid);
229int htc_send(struct htc_target *target, struct sk_buff *skb,
230 enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl);
231void htc_stop(struct htc_target *target);
232void htc_start(struct htc_target *target);
233
234void ath9k_htc_rx_msg(struct htc_target *htc_handle,
235 struct sk_buff *skb, u32 len, u8 pipe_id);
236void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
237 struct sk_buff *skb, bool txok);
238
239struct htc_target *ath9k_htc_hw_alloc(void *hif_handle);
240void ath9k_htc_hw_free(struct htc_target *htc);
241int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
242 void *hif_handle, struct device *dev, u16 devid,
243 enum ath9k_hif_transports transport);
244void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
245
246#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2e767cf22f1e..88f8bfdbded4 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -499,8 +499,10 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
499{ 499{
500 int ecode; 500 int ecode;
501 501
502 if (!ath9k_hw_chip_test(ah)) 502 if (!AR_SREV_9271(ah)) {
503 return -ENODEV; 503 if (!ath9k_hw_chip_test(ah))
504 return -ENODEV;
505 }
504 506
505 ecode = ath9k_hw_rf_claim(ah); 507 ecode = ath9k_hw_rf_claim(ah);
506 if (ecode != 0) 508 if (ecode != 0)
@@ -545,7 +547,6 @@ static bool ath9k_hw_devid_supported(u16 devid)
545 case AR9285_DEVID_PCIE: 547 case AR9285_DEVID_PCIE:
546 case AR5416_DEVID_AR9287_PCI: 548 case AR5416_DEVID_AR9287_PCI:
547 case AR5416_DEVID_AR9287_PCIE: 549 case AR5416_DEVID_AR9287_PCIE:
548 case AR9271_USB:
549 case AR2427_DEVID_PCIE: 550 case AR2427_DEVID_PCIE:
550 return true; 551 return true;
551 default: 552 default:
@@ -603,9 +604,23 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
603 ARRAY_SIZE(ar9271Modes_9271), 6); 604 ARRAY_SIZE(ar9271Modes_9271), 6);
604 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, 605 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
605 ARRAY_SIZE(ar9271Common_9271), 2); 606 ARRAY_SIZE(ar9271Common_9271), 2);
607 INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
608 ar9271Common_normal_cck_fir_coeff_9271,
609 ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
610 INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
611 ar9271Common_japan_2484_cck_fir_coeff_9271,
612 ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
606 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, 613 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
607 ar9271Modes_9271_1_0_only, 614 ar9271Modes_9271_1_0_only,
608 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6); 615 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
616 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
617 ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
618 INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
619 ar9271Modes_high_power_tx_gain_9271,
620 ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
621 INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
622 ar9271Modes_normal_power_tx_gain_9271,
623 ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
609 return; 624 return;
610 } 625 }
611 626
@@ -800,15 +815,30 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
800 815
801 /* txgain table */ 816 /* txgain table */
802 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { 817 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
803 INIT_INI_ARRAY(&ah->iniModesTxGain, 818 if (AR_SREV_9285E_20(ah)) {
804 ar9285Modes_high_power_tx_gain_9285_1_2, 819 INIT_INI_ARRAY(&ah->iniModesTxGain,
805 ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6); 820 ar9285Modes_XE2_0_high_power,
821 ARRAY_SIZE(
822 ar9285Modes_XE2_0_high_power), 6);
823 } else {
824 INIT_INI_ARRAY(&ah->iniModesTxGain,
825 ar9285Modes_high_power_tx_gain_9285_1_2,
826 ARRAY_SIZE(
827 ar9285Modes_high_power_tx_gain_9285_1_2), 6);
828 }
806 } else { 829 } else {
807 INIT_INI_ARRAY(&ah->iniModesTxGain, 830 if (AR_SREV_9285E_20(ah)) {
808 ar9285Modes_original_tx_gain_9285_1_2, 831 INIT_INI_ARRAY(&ah->iniModesTxGain,
809 ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6); 832 ar9285Modes_XE2_0_normal_power,
833 ARRAY_SIZE(
834 ar9285Modes_XE2_0_normal_power), 6);
835 } else {
836 INIT_INI_ARRAY(&ah->iniModesTxGain,
837 ar9285Modes_original_tx_gain_9285_1_2,
838 ARRAY_SIZE(
839 ar9285Modes_original_tx_gain_9285_1_2), 6);
840 }
810 } 841 }
811
812 } 842 }
813} 843}
814 844
@@ -839,11 +869,13 @@ int ath9k_hw_init(struct ath_hw *ah)
839 struct ath_common *common = ath9k_hw_common(ah); 869 struct ath_common *common = ath9k_hw_common(ah);
840 int r = 0; 870 int r = 0;
841 871
842 if (!ath9k_hw_devid_supported(ah->hw_version.devid)) { 872 if (common->bus_ops->ath_bus_type != ATH_USB) {
843 ath_print(common, ATH_DBG_FATAL, 873 if (!ath9k_hw_devid_supported(ah->hw_version.devid)) {
844 "Unsupported device ID: 0x%0x\n", 874 ath_print(common, ATH_DBG_FATAL,
845 ah->hw_version.devid); 875 "Unsupported device ID: 0x%0x\n",
846 return -EOPNOTSUPP; 876 ah->hw_version.devid);
877 return -EOPNOTSUPP;
878 }
847 } 879 }
848 880
849 ath9k_hw_init_defaults(ah); 881 ath9k_hw_init_defaults(ah);
@@ -990,22 +1022,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
990 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 1022 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
991} 1023}
992 1024
993static void ath9k_hw_change_target_baud(struct ath_hw *ah, u32 freq, u32 baud)
994{
995 u32 lcr;
996 u32 baud_divider = freq * 1000 * 1000 / 16 / baud;
997
998 lcr = REG_READ(ah , 0x5100c);
999 lcr |= 0x80;
1000
1001 REG_WRITE(ah, 0x5100c, lcr);
1002 REG_WRITE(ah, 0x51004, (baud_divider >> 8));
1003 REG_WRITE(ah, 0x51000, (baud_divider & 0xff));
1004
1005 lcr &= ~0x80;
1006 REG_WRITE(ah, 0x5100c, lcr);
1007}
1008
1009static void ath9k_hw_init_pll(struct ath_hw *ah, 1025static void ath9k_hw_init_pll(struct ath_hw *ah,
1010 struct ath9k_channel *chan) 1026 struct ath9k_channel *chan)
1011{ 1027{
@@ -1071,22 +1087,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
1071 1087
1072 /* Switch the core clock for ar9271 to 117Mhz */ 1088 /* Switch the core clock for ar9271 to 117Mhz */
1073 if (AR_SREV_9271(ah)) { 1089 if (AR_SREV_9271(ah)) {
1074 if ((pll == 0x142c) || (pll == 0x2850) ) { 1090 udelay(500);
1075 udelay(500); 1091 REG_WRITE(ah, 0x50040, 0x304);
1076 /* set CLKOBS to output AHB clock */
1077 REG_WRITE(ah, 0x7020, 0xe);
1078 /*
1079 * 0x304: 117Mhz, ahb_ratio: 1x1
1080 * 0x306: 40Mhz, ahb_ratio: 1x1
1081 */
1082 REG_WRITE(ah, 0x50040, 0x304);
1083 /*
1084 * makes adjustments for the baud dividor to keep the
1085 * targetted baud rate based on the used core clock.
1086 */
1087 ath9k_hw_change_target_baud(ah, AR9271_CORE_CLOCK,
1088 AR9271_TARGET_BAUD_RATE);
1089 }
1090 } 1092 }
1091 1093
1092 udelay(RTC_PLL_SETTLE_DELAY); 1094 udelay(RTC_PLL_SETTLE_DELAY);
@@ -1134,24 +1136,25 @@ static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
1134static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, 1136static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1135 enum nl80211_iftype opmode) 1137 enum nl80211_iftype opmode)
1136{ 1138{
1137 ah->mask_reg = AR_IMR_TXERR | 1139 u32 imr_reg = AR_IMR_TXERR |
1138 AR_IMR_TXURN | 1140 AR_IMR_TXURN |
1139 AR_IMR_RXERR | 1141 AR_IMR_RXERR |
1140 AR_IMR_RXORN | 1142 AR_IMR_RXORN |
1141 AR_IMR_BCNMISC; 1143 AR_IMR_BCNMISC;
1142 1144
1143 if (ah->config.rx_intr_mitigation) 1145 if (ah->config.rx_intr_mitigation)
1144 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; 1146 imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
1145 else 1147 else
1146 ah->mask_reg |= AR_IMR_RXOK; 1148 imr_reg |= AR_IMR_RXOK;
1147 1149
1148 ah->mask_reg |= AR_IMR_TXOK; 1150 imr_reg |= AR_IMR_TXOK;
1149 1151
1150 if (opmode == NL80211_IFTYPE_AP) 1152 if (opmode == NL80211_IFTYPE_AP)
1151 ah->mask_reg |= AR_IMR_MIB; 1153 imr_reg |= AR_IMR_MIB;
1152 1154
1153 REG_WRITE(ah, AR_IMR, ah->mask_reg); 1155 REG_WRITE(ah, AR_IMR, imr_reg);
1154 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT); 1156 ah->imrs2_reg |= AR_IMR_S2_GTT;
1157 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
1155 1158
1156 if (!AR_SREV_9100(ah)) { 1159 if (!AR_SREV_9100(ah)) {
1157 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); 1160 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
@@ -1240,7 +1243,7 @@ void ath9k_hw_deinit(struct ath_hw *ah)
1240{ 1243{
1241 struct ath_common *common = ath9k_hw_common(ah); 1244 struct ath_common *common = ath9k_hw_common(ah);
1242 1245
1243 if (common->state <= ATH_HW_INITIALIZED) 1246 if (common->state < ATH_HW_INITIALIZED)
1244 goto free_hw; 1247 goto free_hw;
1245 1248
1246 if (!AR_SREV_9100(ah)) 1249 if (!AR_SREV_9100(ah))
@@ -1251,8 +1254,6 @@ void ath9k_hw_deinit(struct ath_hw *ah)
1251free_hw: 1254free_hw:
1252 if (!AR_SREV_9280_10_OR_LATER(ah)) 1255 if (!AR_SREV_9280_10_OR_LATER(ah))
1253 ath9k_hw_rf_free_ext_banks(ah); 1256 ath9k_hw_rf_free_ext_banks(ah);
1254 kfree(ah);
1255 ah = NULL;
1256} 1257}
1257EXPORT_SYMBOL(ath9k_hw_deinit); 1258EXPORT_SYMBOL(ath9k_hw_deinit);
1258 1259
@@ -1265,26 +1266,6 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
1265{ 1266{
1266 u32 val; 1267 u32 val;
1267 1268
1268 if (AR_SREV_9271(ah)) {
1269 /*
1270 * Enable spectral scan to solution for issues with stuck
1271 * beacons on AR9271 1.0. The beacon stuck issue is not seeon on
1272 * AR9271 1.1
1273 */
1274 if (AR_SREV_9271_10(ah)) {
1275 val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) |
1276 AR_PHY_SPECTRAL_SCAN_ENABLE;
1277 REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
1278 }
1279 else if (AR_SREV_9271_11(ah))
1280 /*
1281 * change AR_PHY_RF_CTL3 setting to fix MAC issue
1282 * present on AR9271 1.1
1283 */
1284 REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001);
1285 return;
1286 }
1287
1288 /* 1269 /*
1289 * Set the RX_ABORT and RX_DIS and clear if off only after 1270 * Set the RX_ABORT and RX_DIS and clear if off only after
1290 * RXE is set for MAC. This prevents frames with corrupted 1271 * RXE is set for MAC. This prevents frames with corrupted
@@ -1293,8 +1274,10 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
1293 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 1274 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
1294 1275
1295 if (AR_SREV_9280_10_OR_LATER(ah)) { 1276 if (AR_SREV_9280_10_OR_LATER(ah)) {
1296 val = REG_READ(ah, AR_PCU_MISC_MODE2) & 1277 val = REG_READ(ah, AR_PCU_MISC_MODE2);
1297 (~AR_PCU_MISC_MODE2_HWWAR1); 1278
1279 if (!AR_SREV_9271(ah))
1280 val &= ~AR_PCU_MISC_MODE2_HWWAR1;
1298 1281
1299 if (AR_SREV_9287_10_OR_LATER(ah)) 1282 if (AR_SREV_9287_10_OR_LATER(ah))
1300 val = val & (~AR_PCU_MISC_MODE2_HWWAR2); 1283 val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
@@ -1438,7 +1421,10 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1438 return -EINVAL; 1421 return -EINVAL;
1439 } 1422 }
1440 1423
1424 /* Set correct baseband to analog shift setting to access analog chips */
1441 REG_WRITE(ah, AR_PHY(0), 0x00000007); 1425 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1426
1427 /* Write ADDAC shifts */
1442 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); 1428 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
1443 ah->eep_ops->set_addac(ah, chan); 1429 ah->eep_ops->set_addac(ah, chan);
1444 1430
@@ -1450,9 +1436,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1450 sizeof(u32) * ah->iniAddac.ia_rows * 1436 sizeof(u32) * ah->iniAddac.ia_rows *
1451 ah->iniAddac.ia_columns; 1437 ah->iniAddac.ia_columns;
1452 1438
1439 /* For AR5416 2.0/2.1 */
1453 memcpy(ah->addac5416_21, 1440 memcpy(ah->addac5416_21,
1454 ah->iniAddac.ia_array, addacSize); 1441 ah->iniAddac.ia_array, addacSize);
1455 1442
1443 /* override CLKDRV value at [row, column] = [31, 1] */
1456 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; 1444 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
1457 1445
1458 temp.ia_array = ah->addac5416_21; 1446 temp.ia_array = ah->addac5416_21;
@@ -1484,6 +1472,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1484 AR_SREV_9287_10_OR_LATER(ah)) 1472 AR_SREV_9287_10_OR_LATER(ah))
1485 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); 1473 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
1486 1474
1475 if (AR_SREV_9271_10(ah))
1476 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
1477 modesIndex, regWrites);
1478
1479 /* Write common array parameters */
1487 for (i = 0; i < ah->iniCommon.ia_rows; i++) { 1480 for (i = 0; i < ah->iniCommon.ia_rows; i++) {
1488 u32 reg = INI_RA(&ah->iniCommon, i, 0); 1481 u32 reg = INI_RA(&ah->iniCommon, i, 0);
1489 u32 val = INI_RA(&ah->iniCommon, i, 1); 1482 u32 val = INI_RA(&ah->iniCommon, i, 1);
@@ -1498,11 +1491,16 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1498 DO_DELAY(regWrites); 1491 DO_DELAY(regWrites);
1499 } 1492 }
1500 1493
1501 ath9k_hw_write_regs(ah, freqIndex, regWrites); 1494 if (AR_SREV_9271(ah)) {
1495 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
1496 REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
1497 modesIndex, regWrites);
1498 else
1499 REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
1500 modesIndex, regWrites);
1501 }
1502 1502
1503 if (AR_SREV_9271_10(ah)) 1503 ath9k_hw_write_regs(ah, freqIndex, regWrites);
1504 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
1505 modesIndex, regWrites);
1506 1504
1507 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { 1505 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
1508 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, 1506 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
@@ -1516,6 +1514,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1516 if (OLC_FOR_AR9280_20_LATER) 1514 if (OLC_FOR_AR9280_20_LATER)
1517 ath9k_olc_init(ah); 1515 ath9k_olc_init(ah);
1518 1516
1517 /* Set TX power */
1519 ah->eep_ops->set_txpower(ah, chan, 1518 ah->eep_ops->set_txpower(ah, chan,
1520 ath9k_regd_get_ctl(regulatory, chan), 1519 ath9k_regd_get_ctl(regulatory, chan),
1521 channel->max_antenna_gain * 2, 1520 channel->max_antenna_gain * 2,
@@ -1523,6 +1522,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1523 min((u32) MAX_RATE_POWER, 1522 min((u32) MAX_RATE_POWER,
1524 (u32) regulatory->power_limit)); 1523 (u32) regulatory->power_limit));
1525 1524
1525 /* Write analog registers */
1526 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 1526 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
1527 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 1527 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
1528 "ar5416SetRfRegs failed\n"); 1528 "ar5416SetRfRegs failed\n");
@@ -1965,6 +1965,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1965 1965
1966 ath9k_hw_mark_phy_inactive(ah); 1966 ath9k_hw_mark_phy_inactive(ah);
1967 1967
1968 /* Only required on the first reset */
1968 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1969 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1969 REG_WRITE(ah, 1970 REG_WRITE(ah,
1970 AR9271_RESET_POWER_DOWN_CONTROL, 1971 AR9271_RESET_POWER_DOWN_CONTROL,
@@ -1977,6 +1978,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1977 return -EINVAL; 1978 return -EINVAL;
1978 } 1979 }
1979 1980
1981 /* Only required on the first reset */
1980 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1982 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1981 ah->htc_reset_init = false; 1983 ah->htc_reset_init = false;
1982 REG_WRITE(ah, 1984 REG_WRITE(ah,
@@ -2437,7 +2439,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
2437 if (!AR_SREV_9100(ah)) 2439 if (!AR_SREV_9100(ah))
2438 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); 2440 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
2439 2441
2440 if(!AR_SREV_5416(ah)) 2442 if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
2441 REG_CLR_BIT(ah, (AR_RTC_RESET), 2443 REG_CLR_BIT(ah, (AR_RTC_RESET),
2442 AR_RTC_RESET_EN); 2444 AR_RTC_RESET_EN);
2443 } 2445 }
@@ -2853,7 +2855,7 @@ EXPORT_SYMBOL(ath9k_hw_getisr);
2853 2855
2854enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) 2856enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2855{ 2857{
2856 u32 omask = ah->mask_reg; 2858 enum ath9k_int omask = ah->imask;
2857 u32 mask, mask2; 2859 u32 mask, mask2;
2858 struct ath9k_hw_capabilities *pCap = &ah->caps; 2860 struct ath9k_hw_capabilities *pCap = &ah->caps;
2859 struct ath_common *common = ath9k_hw_common(ah); 2861 struct ath_common *common = ath9k_hw_common(ah);
@@ -2920,15 +2922,11 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2920 2922
2921 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); 2923 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
2922 REG_WRITE(ah, AR_IMR, mask); 2924 REG_WRITE(ah, AR_IMR, mask);
2923 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | 2925 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
2924 AR_IMR_S2_DTIM | 2926 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
2925 AR_IMR_S2_DTIMSYNC | 2927 AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
2926 AR_IMR_S2_CABEND | 2928 ah->imrs2_reg |= mask2;
2927 AR_IMR_S2_CABTO | 2929 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
2928 AR_IMR_S2_TSFOOR |
2929 AR_IMR_S2_GTT | AR_IMR_S2_CST);
2930 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
2931 ah->mask_reg = ints;
2932 2930
2933 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 2931 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2934 if (ints & ATH9K_INT_TIM_TIMER) 2932 if (ints & ATH9K_INT_TIM_TIMER)
@@ -3218,7 +3216,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
3218 else 3216 else
3219 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; 3217 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3220 3218
3221 if (AR_SREV_9285_10_OR_LATER(ah)) 3219 if (AR_SREV_9271(ah))
3220 pCap->num_gpio_pins = AR9271_NUM_GPIO;
3221 else if (AR_SREV_9285_10_OR_LATER(ah))
3222 pCap->num_gpio_pins = AR9285_NUM_GPIO; 3222 pCap->num_gpio_pins = AR9285_NUM_GPIO;
3223 else if (AR_SREV_9280_10_OR_LATER(ah)) 3223 else if (AR_SREV_9280_10_OR_LATER(ah))
3224 pCap->num_gpio_pins = AR928X_NUM_GPIO; 3224 pCap->num_gpio_pins = AR928X_NUM_GPIO;
@@ -3245,8 +3245,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
3245 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; 3245 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
3246 } 3246 }
3247#endif 3247#endif
3248 3248 if (AR_SREV_9271(ah))
3249 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; 3249 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
3250 else
3251 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3250 3252
3251 if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) 3253 if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
3252 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; 3254 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
@@ -3454,7 +3456,9 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
3454 if (gpio >= ah->caps.num_gpio_pins) 3456 if (gpio >= ah->caps.num_gpio_pins)
3455 return 0xffffffff; 3457 return 0xffffffff;
3456 3458
3457 if (AR_SREV_9287_10_OR_LATER(ah)) 3459 if (AR_SREV_9271(ah))
3460 return MS_REG_READ(AR9271, gpio) != 0;
3461 else if (AR_SREV_9287_10_OR_LATER(ah))
3458 return MS_REG_READ(AR9287, gpio) != 0; 3462 return MS_REG_READ(AR9287, gpio) != 0;
3459 else if (AR_SREV_9285_10_OR_LATER(ah)) 3463 else if (AR_SREV_9285_10_OR_LATER(ah))
3460 return MS_REG_READ(AR9285, gpio) != 0; 3464 return MS_REG_READ(AR9285, gpio) != 0;
@@ -3483,6 +3487,9 @@ EXPORT_SYMBOL(ath9k_hw_cfg_output);
3483 3487
3484void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) 3488void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
3485{ 3489{
3490 if (AR_SREV_9271(ah))
3491 val = ~val;
3492
3486 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), 3493 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
3487 AR_GPIO_BIT(gpio)); 3494 AR_GPIO_BIT(gpio));
3488} 3495}
@@ -3867,6 +3874,16 @@ void ath_gen_timer_isr(struct ath_hw *ah)
3867} 3874}
3868EXPORT_SYMBOL(ath_gen_timer_isr); 3875EXPORT_SYMBOL(ath_gen_timer_isr);
3869 3876
3877/********/
3878/* HTC */
3879/********/
3880
3881void ath9k_hw_htc_resetinit(struct ath_hw *ah)
3882{
3883 ah->htc_reset_init = true;
3884}
3885EXPORT_SYMBOL(ath9k_hw_htc_resetinit);
3886
3870static struct { 3887static struct {
3871 u32 version; 3888 u32 version;
3872 const char * name; 3889 const char * name;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index dbbf7ca5f97d..b02a97c72c64 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -44,8 +44,6 @@
44 44
45#define AR5416_AR9100_DEVID 0x000b 45#define AR5416_AR9100_DEVID 0x000b
46 46
47#define AR9271_USB 0x9271
48
49#define AR_SUBVENDOR_ID_NOG 0x0e11 47#define AR_SUBVENDOR_ID_NOG 0x0e11
50#define AR_SUBVENDOR_ID_NEW_A 0x7065 48#define AR_SUBVENDOR_ID_NEW_A 0x7065
51#define AR5416_MAGIC 0x19641014 49#define AR5416_MAGIC 0x19641014
@@ -478,7 +476,8 @@ struct ath_hw {
478 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; 476 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
479 477
480 int16_t curchan_rad_index; 478 int16_t curchan_rad_index;
481 u32 mask_reg; 479 enum ath9k_int imask;
480 u32 imrs2_reg;
482 u32 txok_interrupt_mask; 481 u32 txok_interrupt_mask;
483 u32 txerr_interrupt_mask; 482 u32 txerr_interrupt_mask;
484 u32 txdesc_interrupt_mask; 483 u32 txdesc_interrupt_mask;
@@ -598,6 +597,11 @@ struct ath_hw {
598 struct ar5416IniArray iniModes_9271_1_0_only; 597 struct ar5416IniArray iniModes_9271_1_0_only;
599 struct ar5416IniArray iniCckfirNormal; 598 struct ar5416IniArray iniCckfirNormal;
600 struct ar5416IniArray iniCckfirJapan2484; 599 struct ar5416IniArray iniCckfirJapan2484;
600 struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
601 struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
602 struct ar5416IniArray iniModes_9271_ANI_reg;
603 struct ar5416IniArray iniModes_high_power_tx_gain_9271;
604 struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
601 605
602 u32 intr_gen_timer_trigger; 606 u32 intr_gen_timer_trigger;
603 u32 intr_gen_timer_thresh; 607 u32 intr_gen_timer_thresh;
@@ -701,6 +705,9 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
701 705
702void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); 706void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
703 707
708/* HTC */
709void ath9k_hw_htc_resetinit(struct ath_hw *ah);
710
704#define ATH_PCIE_CAP_LINK_CTRL 0x70 711#define ATH_PCIE_CAP_LINK_CTRL 0x70
705#define ATH_PCIE_CAP_LINK_L0S 1 712#define ATH_PCIE_CAP_LINK_L0S 1
706#define ATH_PCIE_CAP_LINK_L1 2 713#define ATH_PCIE_CAP_LINK_L1 2
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 623c2f884987..6063f5463708 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -758,6 +758,9 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
758 758
759 tasklet_kill(&sc->intr_tq); 759 tasklet_kill(&sc->intr_tq);
760 tasklet_kill(&sc->bcon_tasklet); 760 tasklet_kill(&sc->bcon_tasklet);
761
762 kfree(sc->sc_ah);
763 sc->sc_ah = NULL;
761} 764}
762 765
763void ath9k_deinit_device(struct ath_softc *sc) 766void ath9k_deinit_device(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index 8a3bf3ab998d..455e9d3b3f13 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
@@ -4184,7 +4184,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4184 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 4184 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
4185 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 4185 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
4186 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 4186 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
4187 { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 4187 { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
4188 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 4188 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
4189 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 4189 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
4190 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 4190 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -4198,8 +4198,8 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4198 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 4198 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
4199 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 4199 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
4200 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 4200 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
4201 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 4201 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
4202 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 4202 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
4203 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 4203 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
4204 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 4204 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
4205 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 4205 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -4312,7 +4312,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4312 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 4312 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
4313 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 4313 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
4314 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 4314 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
4315 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 4315 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
4316 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 4316 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
4317 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 4317 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
4318 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 4318 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -4326,8 +4326,8 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4326 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 4326 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
4327 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 4327 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
4328 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 4328 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
4329 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 4329 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
4330 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 4330 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
4331 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 4331 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
4332 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 4332 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
4333 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 4333 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -4731,17 +4731,12 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
4731 { 0x00007808, 0x54214514 }, 4731 { 0x00007808, 0x54214514 },
4732 { 0x0000780c, 0x02025830 }, 4732 { 0x0000780c, 0x02025830 },
4733 { 0x00007810, 0x71c0d388 }, 4733 { 0x00007810, 0x71c0d388 },
4734 { 0x00007814, 0x924934a8 },
4735 { 0x0000781c, 0x00000000 }, 4734 { 0x0000781c, 0x00000000 },
4736 { 0x00007824, 0x00d86fff }, 4735 { 0x00007824, 0x00d86fff },
4737 { 0x00007828, 0x26d2491b },
4738 { 0x0000782c, 0x6e36d97b }, 4736 { 0x0000782c, 0x6e36d97b },
4739 { 0x00007830, 0xedb6d96e },
4740 { 0x00007834, 0x71400087 }, 4737 { 0x00007834, 0x71400087 },
4741 { 0x0000783c, 0x0001fffe },
4742 { 0x00007840, 0xffeb1a20 },
4743 { 0x00007844, 0x000c0db6 }, 4738 { 0x00007844, 0x000c0db6 },
4744 { 0x00007848, 0x6db61b6f }, 4739 { 0x00007848, 0x6db6246f },
4745 { 0x0000784c, 0x6d9b66db }, 4740 { 0x0000784c, 0x6d9b66db },
4746 { 0x00007850, 0x6d8c6dba }, 4741 { 0x00007850, 0x6d8c6dba },
4747 { 0x00007854, 0x00040000 }, 4742 { 0x00007854, 0x00040000 },
@@ -4777,7 +4772,12 @@ static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
4777 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 4772 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4778 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 4773 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4779 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 4774 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4775 { 0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8 },
4776 { 0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b },
4777 { 0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e },
4780 { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 }, 4778 { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
4779 { 0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe },
4780 { 0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20 },
4781 { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, 4781 { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
4782 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, 4782 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
4783 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 }, 4783 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 },
@@ -4813,7 +4813,12 @@ static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
4813 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 4813 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4814 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 4814 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4815 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 4815 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4816 { 0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8 },
4817 { 0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b },
4818 { 0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e },
4816 { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 }, 4819 { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
4820 { 0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe },
4821 { 0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20 },
4817 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, 4822 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
4818 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, 4823 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
4819 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, 4824 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
@@ -4825,6 +4830,86 @@ static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
4825 { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, 4830 { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
4826}; 4831};
4827 4832
4833static const u_int32_t ar9285Modes_XE2_0_normal_power[][6] = {
4834 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4835 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
4836 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
4837 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
4838 { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
4839 { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
4840 { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
4841 { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
4842 { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
4843 { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
4844 { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
4845 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
4846 { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
4847 { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
4848 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
4849 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
4850 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4851 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4852 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4853 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4854 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4855 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4856 { 0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8 },
4857 { 0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b },
4858 { 0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae },
4859 { 0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441 },
4860 { 0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe },
4861 { 0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c },
4862 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
4863 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
4864 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
4865 { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
4866 { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
4867 { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
4868 { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
4869 { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
4870 { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
4871};
4872
4873static const u_int32_t ar9285Modes_XE2_0_high_power[][6] = {
4874 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4875 { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 },
4876 { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 },
4877 { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
4878 { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
4879 { 0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000 },
4880 { 0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000 },
4881 { 0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000 },
4882 { 0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000 },
4883 { 0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000 },
4884 { 0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000 },
4885 { 0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
4886 { 0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000 },
4887 { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
4888 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
4889 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
4890 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4891 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4892 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4893 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4894 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4895 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4896 { 0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8 },
4897 { 0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b },
4898 { 0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e },
4899 { 0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443 },
4900 { 0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe },
4901 { 0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c },
4902 { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
4903 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
4904 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 },
4905 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
4906 { 0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7 },
4907 { 0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
4908 { 0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
4909 { 0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
4910 { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
4911};
4912
4828static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { 4913static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
4829 {0x00004040, 0x9248fd00 }, 4914 {0x00004040, 0x9248fd00 },
4830 {0x00004040, 0x24924924 }, 4915 {0x00004040, 0x24924924 },
@@ -6441,7 +6526,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6441 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 6526 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6442 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 6527 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6443 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 6528 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6444 { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 6529 { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
6445 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 6530 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6446 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 6531 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6447 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 6532 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -6455,8 +6540,8 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6455 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 6540 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6456 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 6541 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6457 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 6542 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6458 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 6543 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
6459 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6544 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6460 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6545 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6461 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 6546 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6462 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 6547 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -6569,7 +6654,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6569 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 6654 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6570 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 6655 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6571 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 6656 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6572 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 6657 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
6573 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 6658 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6574 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 6659 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6575 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 6660 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -6583,8 +6668,8 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6583 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 6668 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6584 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 6669 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6585 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 6670 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6586 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 6671 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
6587 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6672 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6588 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6673 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6589 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 6674 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6590 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 6675 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -6683,25 +6768,6 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6683 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, 6768 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
6684 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, 6769 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
6685 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, 6770 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
6686 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
6687 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6688 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
6689 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
6690 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
6691 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
6692 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
6693 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
6694 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
6695 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
6696 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
6697 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
6698 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
6699 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
6700 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
6701 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
6702 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
6703 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6704 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6705 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, 6771 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
6706}; 6772};
6707 6773
@@ -6879,7 +6945,7 @@ static const u_int32_t ar9271Common_9271[][2] = {
6879 { 0x00008258, 0x00000000 }, 6945 { 0x00008258, 0x00000000 },
6880 { 0x0000825c, 0x400000ff }, 6946 { 0x0000825c, 0x400000ff },
6881 { 0x00008260, 0x00080922 }, 6947 { 0x00008260, 0x00080922 },
6882 { 0x00008264, 0x88a00010 }, 6948 { 0x00008264, 0xa8a00010 },
6883 { 0x00008270, 0x00000000 }, 6949 { 0x00008270, 0x00000000 },
6884 { 0x00008274, 0x40000000 }, 6950 { 0x00008274, 0x40000000 },
6885 { 0x00008278, 0x003e4180 }, 6951 { 0x00008278, 0x003e4180 },
@@ -6910,13 +6976,10 @@ static const u_int32_t ar9271Common_9271[][2] = {
6910 { 0x00007810, 0x71c0d388 }, 6976 { 0x00007810, 0x71c0d388 },
6911 { 0x00007814, 0x924934a8 }, 6977 { 0x00007814, 0x924934a8 },
6912 { 0x0000781c, 0x00000000 }, 6978 { 0x0000781c, 0x00000000 },
6913 { 0x00007820, 0x00000c04 },
6914 { 0x00007824, 0x00d8abff },
6915 { 0x00007828, 0x66964300 }, 6979 { 0x00007828, 0x66964300 },
6916 { 0x0000782c, 0x8db6d961 }, 6980 { 0x0000782c, 0x8db6d961 },
6917 { 0x00007830, 0x8db6d96c }, 6981 { 0x00007830, 0x8db6d96c },
6918 { 0x00007834, 0x6140008b }, 6982 { 0x00007834, 0x6140008b },
6919 { 0x00007838, 0x00000029 },
6920 { 0x0000783c, 0x72ee0a72 }, 6983 { 0x0000783c, 0x72ee0a72 },
6921 { 0x00007840, 0xbbfffffc }, 6984 { 0x00007840, 0xbbfffffc },
6922 { 0x00007844, 0x000c0db6 }, 6985 { 0x00007844, 0x000c0db6 },
@@ -6929,7 +6992,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
6929 { 0x00007860, 0x21084210 }, 6992 { 0x00007860, 0x21084210 },
6930 { 0x00007864, 0xf7d7ffde }, 6993 { 0x00007864, 0xf7d7ffde },
6931 { 0x00007868, 0xc2034080 }, 6994 { 0x00007868, 0xc2034080 },
6932 { 0x0000786c, 0x48609eb4 },
6933 { 0x00007870, 0x10142c00 }, 6995 { 0x00007870, 0x10142c00 },
6934 { 0x00009808, 0x00000000 }, 6996 { 0x00009808, 0x00000000 },
6935 { 0x0000980c, 0xafe68e30 }, 6997 { 0x0000980c, 0xafe68e30 },
@@ -6982,9 +7044,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
6982 { 0x000099e8, 0x3c466478 }, 7044 { 0x000099e8, 0x3c466478 },
6983 { 0x000099ec, 0x0cc80caa }, 7045 { 0x000099ec, 0x0cc80caa },
6984 { 0x000099f0, 0x00000000 }, 7046 { 0x000099f0, 0x00000000 },
6985 { 0x0000a1f4, 0x00000000 },
6986 { 0x0000a1f8, 0x71733d01 },
6987 { 0x0000a1fc, 0xd0ad5c12 },
6988 { 0x0000a208, 0x803e68c8 }, 7047 { 0x0000a208, 0x803e68c8 },
6989 { 0x0000a210, 0x4080a333 }, 7048 { 0x0000a210, 0x4080a333 },
6990 { 0x0000a214, 0x00206c10 }, 7049 { 0x0000a214, 0x00206c10 },
@@ -7004,13 +7063,9 @@ static const u_int32_t ar9271Common_9271[][2] = {
7004 { 0x0000a260, 0xdfa90f01 }, 7063 { 0x0000a260, 0xdfa90f01 },
7005 { 0x0000a268, 0x00000000 }, 7064 { 0x0000a268, 0x00000000 },
7006 { 0x0000a26c, 0x0ebae9e6 }, 7065 { 0x0000a26c, 0x0ebae9e6 },
7007 { 0x0000a278, 0x3bdef7bd },
7008 { 0x0000a27c, 0x050e83bd },
7009 { 0x0000a388, 0x0c000000 }, 7066 { 0x0000a388, 0x0c000000 },
7010 { 0x0000a38c, 0x20202020 }, 7067 { 0x0000a38c, 0x20202020 },
7011 { 0x0000a390, 0x20202020 }, 7068 { 0x0000a390, 0x20202020 },
7012 { 0x0000a394, 0x3bdef7bd },
7013 { 0x0000a398, 0x000003bd },
7014 { 0x0000a39c, 0x00000001 }, 7069 { 0x0000a39c, 0x00000001 },
7015 { 0x0000a3a0, 0x00000000 }, 7070 { 0x0000a3a0, 0x00000000 },
7016 { 0x0000a3a4, 0x00000000 }, 7071 { 0x0000a3a4, 0x00000000 },
@@ -7025,8 +7080,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
7025 { 0x0000a3cc, 0x20202020 }, 7080 { 0x0000a3cc, 0x20202020 },
7026 { 0x0000a3d0, 0x20202020 }, 7081 { 0x0000a3d0, 0x20202020 },
7027 { 0x0000a3d4, 0x20202020 }, 7082 { 0x0000a3d4, 0x20202020 },
7028 { 0x0000a3dc, 0x3bdef7bd },
7029 { 0x0000a3e0, 0x000003bd },
7030 { 0x0000a3e4, 0x00000000 }, 7083 { 0x0000a3e4, 0x00000000 },
7031 { 0x0000a3e8, 0x18c43433 }, 7084 { 0x0000a3e8, 0x18c43433 },
7032 { 0x0000a3ec, 0x00f70081 }, 7085 { 0x0000a3ec, 0x00f70081 },
@@ -7046,7 +7099,102 @@ static const u_int32_t ar9271Common_9271[][2] = {
7046 { 0x0000d384, 0xf3307ff0 }, 7099 { 0x0000d384, 0xf3307ff0 },
7047}; 7100};
7048 7101
7102static const u_int32_t ar9271Common_normal_cck_fir_coeff_9271[][2] = {
7103 { 0x0000a1f4, 0x00fffeff },
7104 { 0x0000a1f8, 0x00f5f9ff },
7105 { 0x0000a1fc, 0xb79f6427 },
7106};
7107
7108static const u_int32_t ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
7109 { 0x0000a1f4, 0x00000000 },
7110 { 0x0000a1f8, 0xefff0301 },
7111 { 0x0000a1fc, 0xca9228ee },
7112};
7113
7049static const u_int32_t ar9271Modes_9271_1_0_only[][6] = { 7114static const u_int32_t ar9271Modes_9271_1_0_only[][6] = {
7050 { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 }, 7115 { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 },
7051 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, 7116 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
7052}; 7117};
7118
7119static const u_int32_t ar9271Modes_9271_ANI_reg[][6] = {
7120 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
7121 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
7122 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
7123 { 0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881 },
7124 { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
7125 { 0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8 },
7126 { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
7127 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
7128};
7129
7130static const u_int32_t ar9271Modes_normal_power_tx_gain_9271[][6] = {
7131 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
7132 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
7133 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
7134 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
7135 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
7136 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
7137 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
7138 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
7139 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
7140 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
7141 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
7142 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
7143 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
7144 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
7145 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
7146 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
7147 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7148 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7149 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7150 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7151 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7152 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7153 { 0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029 },
7154 { 0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff },
7155 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
7156 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
7157 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
7158 { 0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7159 { 0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd },
7160 { 0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7161 { 0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
7162 { 0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7163 { 0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
7164};
7165
7166static const u_int32_t ar9271Modes_high_power_tx_gain_9271[][6] = {
7167 { 0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000 },
7168 { 0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000 },
7169 { 0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000 },
7170 { 0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000 },
7171 { 0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000 },
7172 { 0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000 },
7173 { 0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000 },
7174 { 0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000 },
7175 { 0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000 },
7176 { 0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000 },
7177 { 0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000 },
7178 { 0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000 },
7179 { 0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000 },
7180 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
7181 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
7182 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
7183 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7184 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7185 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7186 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7187 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7188 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7189 { 0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b },
7190 { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff },
7191 { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 },
7192 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
7193 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a212652, 0x0a212652, 0x0a22a652 },
7194 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
7195 { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 },
7196 { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
7197 { 0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
7198 { 0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
7199 { 0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
7200};
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index efc420cd42bf..4a2060e5a777 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -31,8 +31,10 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
31 REG_WRITE(ah, AR_IMR_S1, 31 REG_WRITE(ah, AR_IMR_S1,
32 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) 32 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
33 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); 33 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
34 REG_RMW_FIELD(ah, AR_IMR_S2, 34
35 AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask); 35 ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
36 ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
37 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
36} 38}
37 39
38u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) 40u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -103,7 +105,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
103 if (ah->tx_trig_level >= ah->config.max_txtrig_level) 105 if (ah->tx_trig_level >= ah->config.max_txtrig_level)
104 return false; 106 return false;
105 107
106 omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL); 108 omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
107 109
108 txcfg = REG_READ(ah, AR_TXCFG); 110 txcfg = REG_READ(ah, AR_TXCFG);
109 curLevel = MS(txcfg, AR_FTRIG); 111 curLevel = MS(txcfg, AR_FTRIG);
@@ -244,79 +246,80 @@ void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
244} 246}
245EXPORT_SYMBOL(ath9k_hw_cleartxdesc); 247EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
246 248
247int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds) 249int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
250 struct ath_tx_status *ts)
248{ 251{
249 struct ar5416_desc *ads = AR5416DESC(ds); 252 struct ar5416_desc *ads = AR5416DESC(ds);
250 253
251 if ((ads->ds_txstatus9 & AR_TxDone) == 0) 254 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
252 return -EINPROGRESS; 255 return -EINPROGRESS;
253 256
254 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum); 257 ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
255 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp; 258 ts->ts_tstamp = ads->AR_SendTimestamp;
256 ds->ds_txstat.ts_status = 0; 259 ts->ts_status = 0;
257 ds->ds_txstat.ts_flags = 0; 260 ts->ts_flags = 0;
258 261
259 if (ads->ds_txstatus1 & AR_FrmXmitOK) 262 if (ads->ds_txstatus1 & AR_FrmXmitOK)
260 ds->ds_txstat.ts_status |= ATH9K_TX_ACKED; 263 ts->ts_status |= ATH9K_TX_ACKED;
261 if (ads->ds_txstatus1 & AR_ExcessiveRetries) 264 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
262 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY; 265 ts->ts_status |= ATH9K_TXERR_XRETRY;
263 if (ads->ds_txstatus1 & AR_Filtered) 266 if (ads->ds_txstatus1 & AR_Filtered)
264 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT; 267 ts->ts_status |= ATH9K_TXERR_FILT;
265 if (ads->ds_txstatus1 & AR_FIFOUnderrun) { 268 if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
266 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO; 269 ts->ts_status |= ATH9K_TXERR_FIFO;
267 ath9k_hw_updatetxtriglevel(ah, true); 270 ath9k_hw_updatetxtriglevel(ah, true);
268 } 271 }
269 if (ads->ds_txstatus9 & AR_TxOpExceeded) 272 if (ads->ds_txstatus9 & AR_TxOpExceeded)
270 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP; 273 ts->ts_status |= ATH9K_TXERR_XTXOP;
271 if (ads->ds_txstatus1 & AR_TxTimerExpired) 274 if (ads->ds_txstatus1 & AR_TxTimerExpired)
272 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED; 275 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
273 276
274 if (ads->ds_txstatus1 & AR_DescCfgErr) 277 if (ads->ds_txstatus1 & AR_DescCfgErr)
275 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR; 278 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
276 if (ads->ds_txstatus1 & AR_TxDataUnderrun) { 279 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
277 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN; 280 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
278 ath9k_hw_updatetxtriglevel(ah, true); 281 ath9k_hw_updatetxtriglevel(ah, true);
279 } 282 }
280 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) { 283 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
281 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN; 284 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
282 ath9k_hw_updatetxtriglevel(ah, true); 285 ath9k_hw_updatetxtriglevel(ah, true);
283 } 286 }
284 if (ads->ds_txstatus0 & AR_TxBaStatus) { 287 if (ads->ds_txstatus0 & AR_TxBaStatus) {
285 ds->ds_txstat.ts_flags |= ATH9K_TX_BA; 288 ts->ts_flags |= ATH9K_TX_BA;
286 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow; 289 ts->ba_low = ads->AR_BaBitmapLow;
287 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh; 290 ts->ba_high = ads->AR_BaBitmapHigh;
288 } 291 }
289 292
290 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx); 293 ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
291 switch (ds->ds_txstat.ts_rateindex) { 294 switch (ts->ts_rateindex) {
292 case 0: 295 case 0:
293 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0); 296 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
294 break; 297 break;
295 case 1: 298 case 1:
296 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1); 299 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
297 break; 300 break;
298 case 2: 301 case 2:
299 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2); 302 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
300 break; 303 break;
301 case 3: 304 case 3:
302 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3); 305 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
303 break; 306 break;
304 } 307 }
305 308
306 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined); 309 ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
307 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00); 310 ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
308 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01); 311 ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
309 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02); 312 ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
310 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10); 313 ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
311 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11); 314 ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
312 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12); 315 ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
313 ds->ds_txstat.evm0 = ads->AR_TxEVM0; 316 ts->evm0 = ads->AR_TxEVM0;
314 ds->ds_txstat.evm1 = ads->AR_TxEVM1; 317 ts->evm1 = ads->AR_TxEVM1;
315 ds->ds_txstat.evm2 = ads->AR_TxEVM2; 318 ts->evm2 = ads->AR_TxEVM2;
316 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt); 319 ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
317 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt); 320 ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
318 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt); 321 ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
319 ds->ds_txstat.ts_antenna = 0; 322 ts->ts_antenna = 0;
320 323
321 return 0; 324 return 0;
322} 325}
@@ -349,7 +352,7 @@ void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
349 352
350 ads->ds_ctl6 = SM(keyType, AR_EncrType); 353 ads->ds_ctl6 = SM(keyType, AR_EncrType);
351 354
352 if (AR_SREV_9285(ah)) { 355 if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
353 ads->ds_ctl8 = 0; 356 ads->ds_ctl8 = 0;
354 ads->ds_ctl9 = 0; 357 ads->ds_ctl9 = 0;
355 ads->ds_ctl10 = 0; 358 ads->ds_ctl10 = 0;
@@ -856,7 +859,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
856EXPORT_SYMBOL(ath9k_hw_resettxqueue); 859EXPORT_SYMBOL(ath9k_hw_resettxqueue);
857 860
858int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 861int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
859 u32 pa, struct ath_desc *nds, u64 tsf) 862 struct ath_rx_status *rs, u64 tsf)
860{ 863{
861 struct ar5416_desc ads; 864 struct ar5416_desc ads;
862 struct ar5416_desc *adsp = AR5416DESC(ds); 865 struct ar5416_desc *adsp = AR5416DESC(ds);
@@ -867,70 +870,70 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
867 870
868 ads.u.rx = adsp->u.rx; 871 ads.u.rx = adsp->u.rx;
869 872
870 ds->ds_rxstat.rs_status = 0; 873 rs->rs_status = 0;
871 ds->ds_rxstat.rs_flags = 0; 874 rs->rs_flags = 0;
872 875
873 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen; 876 rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
874 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp; 877 rs->rs_tstamp = ads.AR_RcvTimestamp;
875 878
876 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { 879 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
877 ds->ds_rxstat.rs_rssi = ATH9K_RSSI_BAD; 880 rs->rs_rssi = ATH9K_RSSI_BAD;
878 ds->ds_rxstat.rs_rssi_ctl0 = ATH9K_RSSI_BAD; 881 rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
879 ds->ds_rxstat.rs_rssi_ctl1 = ATH9K_RSSI_BAD; 882 rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
880 ds->ds_rxstat.rs_rssi_ctl2 = ATH9K_RSSI_BAD; 883 rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
881 ds->ds_rxstat.rs_rssi_ext0 = ATH9K_RSSI_BAD; 884 rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
882 ds->ds_rxstat.rs_rssi_ext1 = ATH9K_RSSI_BAD; 885 rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
883 ds->ds_rxstat.rs_rssi_ext2 = ATH9K_RSSI_BAD; 886 rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
884 } else { 887 } else {
885 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); 888 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
886 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, 889 rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
887 AR_RxRSSIAnt00); 890 AR_RxRSSIAnt00);
888 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, 891 rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
889 AR_RxRSSIAnt01); 892 AR_RxRSSIAnt01);
890 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, 893 rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
891 AR_RxRSSIAnt02); 894 AR_RxRSSIAnt02);
892 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, 895 rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
893 AR_RxRSSIAnt10); 896 AR_RxRSSIAnt10);
894 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, 897 rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
895 AR_RxRSSIAnt11); 898 AR_RxRSSIAnt11);
896 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, 899 rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
897 AR_RxRSSIAnt12); 900 AR_RxRSSIAnt12);
898 } 901 }
899 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) 902 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
900 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); 903 rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
901 else 904 else
902 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID; 905 rs->rs_keyix = ATH9K_RXKEYIX_INVALID;
903 906
904 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads)); 907 rs->rs_rate = RXSTATUS_RATE(ah, (&ads));
905 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; 908 rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
906 909
907 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; 910 rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
908 ds->ds_rxstat.rs_moreaggr = 911 rs->rs_moreaggr =
909 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; 912 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
910 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); 913 rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
911 ds->ds_rxstat.rs_flags = 914 rs->rs_flags =
912 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; 915 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
913 ds->ds_rxstat.rs_flags |= 916 rs->rs_flags |=
914 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; 917 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
915 918
916 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) 919 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
917 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE; 920 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
918 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) 921 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
919 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST; 922 rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
920 if (ads.ds_rxstatus8 & AR_DecryptBusyErr) 923 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
921 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY; 924 rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
922 925
923 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { 926 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
924 if (ads.ds_rxstatus8 & AR_CRCErr) 927 if (ads.ds_rxstatus8 & AR_CRCErr)
925 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC; 928 rs->rs_status |= ATH9K_RXERR_CRC;
926 else if (ads.ds_rxstatus8 & AR_PHYErr) { 929 else if (ads.ds_rxstatus8 & AR_PHYErr) {
927 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY; 930 rs->rs_status |= ATH9K_RXERR_PHY;
928 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); 931 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
929 ds->ds_rxstat.rs_phyerr = phyerr; 932 rs->rs_phyerr = phyerr;
930 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) 933 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
931 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT; 934 rs->rs_status |= ATH9K_RXERR_DECRYPT;
932 else if (ads.ds_rxstatus8 & AR_MichaelErr) 935 else if (ads.ds_rxstatus8 & AR_MichaelErr)
933 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC; 936 rs->rs_status |= ATH9K_RXERR_MIC;
934 } 937 }
935 938
936 return 0; 939 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 29851e6376a9..68dbd7a8ddca 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -150,6 +150,32 @@ struct ath_rx_status {
150 u32 evm2; 150 u32 evm2;
151}; 151};
152 152
153struct ath_htc_rx_status {
154 u64 rs_tstamp;
155 u16 rs_datalen;
156 u8 rs_status;
157 u8 rs_phyerr;
158 int8_t rs_rssi;
159 int8_t rs_rssi_ctl0;
160 int8_t rs_rssi_ctl1;
161 int8_t rs_rssi_ctl2;
162 int8_t rs_rssi_ext0;
163 int8_t rs_rssi_ext1;
164 int8_t rs_rssi_ext2;
165 u8 rs_keyix;
166 u8 rs_rate;
167 u8 rs_antenna;
168 u8 rs_more;
169 u8 rs_isaggr;
170 u8 rs_moreaggr;
171 u8 rs_num_delims;
172 u8 rs_flags;
173 u8 rs_dummy;
174 u32 evm0;
175 u32 evm1;
176 u32 evm2;
177};
178
153#define ATH9K_RXERR_CRC 0x01 179#define ATH9K_RXERR_CRC 0x01
154#define ATH9K_RXERR_PHY 0x02 180#define ATH9K_RXERR_PHY 0x02
155#define ATH9K_RXERR_FIFO 0x04 181#define ATH9K_RXERR_FIFO 0x04
@@ -207,18 +233,9 @@ struct ath_desc {
207 u32 ds_ctl0; 233 u32 ds_ctl0;
208 u32 ds_ctl1; 234 u32 ds_ctl1;
209 u32 ds_hw[20]; 235 u32 ds_hw[20];
210 union {
211 struct ath_tx_status tx;
212 struct ath_rx_status rx;
213 void *stats;
214 } ds_us;
215 void *ds_vdata; 236 void *ds_vdata;
216} __packed; 237} __packed;
217 238
218#define ds_txstat ds_us.tx
219#define ds_rxstat ds_us.rx
220#define ds_stat ds_us.stats
221
222#define ATH9K_TXDESC_CLRDMASK 0x0001 239#define ATH9K_TXDESC_CLRDMASK 0x0001
223#define ATH9K_TXDESC_NOACK 0x0002 240#define ATH9K_TXDESC_NOACK 0x0002
224#define ATH9K_TXDESC_RTSENA 0x0004 241#define ATH9K_TXDESC_RTSENA 0x0004
@@ -676,7 +693,8 @@ void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
676 u32 segLen, bool firstSeg, 693 u32 segLen, bool firstSeg,
677 bool lastSeg, const struct ath_desc *ds0); 694 bool lastSeg, const struct ath_desc *ds0);
678void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds); 695void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
679int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds); 696int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
697 struct ath_tx_status *ts);
680void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds, 698void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
681 u32 pktLen, enum ath9k_pkt_type type, u32 txPower, 699 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
682 u32 keyIx, enum ath9k_key_type keyType, u32 flags); 700 u32 keyIx, enum ath9k_key_type keyType, u32 flags);
@@ -706,7 +724,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
706bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); 724bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
707bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); 725bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
708int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 726int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
709 u32 pa, struct ath_desc *nds, u64 tsf); 727 struct ath_rx_status *rs, u64 tsf);
710void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 728void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
711 u32 size, u32 flags); 729 u32 size, u32 flags);
712bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); 730bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 115e1aeedb59..f7ef11407e27 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -225,7 +225,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
225 225
226 ath_cache_conf_rate(sc, &hw->conf); 226 ath_cache_conf_rate(sc, &hw->conf);
227 ath_update_txpow(sc); 227 ath_update_txpow(sc);
228 ath9k_hw_set_interrupts(ah, sc->imask); 228 ath9k_hw_set_interrupts(ah, ah->imask);
229 229
230 ps_restore: 230 ps_restore:
231 ath9k_ps_restore(sc); 231 ath9k_ps_restore(sc);
@@ -434,7 +434,7 @@ void ath9k_tasklet(unsigned long data)
434 ath_gen_timer_isr(sc->sc_ah); 434 ath_gen_timer_isr(sc->sc_ah);
435 435
436 /* re-enable hardware interrupt */ 436 /* re-enable hardware interrupt */
437 ath9k_hw_set_interrupts(ah, sc->imask); 437 ath9k_hw_set_interrupts(ah, ah->imask);
438 ath9k_ps_restore(sc); 438 ath9k_ps_restore(sc);
439} 439}
440 440
@@ -477,7 +477,7 @@ irqreturn_t ath_isr(int irq, void *dev)
477 * value to insure we only process bits we requested. 477 * value to insure we only process bits we requested.
478 */ 478 */
479 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ 479 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
480 status &= sc->imask; /* discard unasked-for bits */ 480 status &= ah->imask; /* discard unasked-for bits */
481 481
482 /* 482 /*
483 * If there are no status bits set, then this interrupt was not 483 * If there are no status bits set, then this interrupt was not
@@ -518,7 +518,7 @@ irqreturn_t ath_isr(int irq, void *dev)
518 * the interrupt. 518 * the interrupt.
519 */ 519 */
520 ath9k_hw_procmibevent(ah); 520 ath9k_hw_procmibevent(ah);
521 ath9k_hw_set_interrupts(ah, sc->imask); 521 ath9k_hw_set_interrupts(ah, ah->imask);
522 } 522 }
523 523
524 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) 524 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
@@ -536,7 +536,7 @@ chip_reset:
536 536
537 if (sched) { 537 if (sched) {
538 /* turn off every interrupt except SWBA */ 538 /* turn off every interrupt except SWBA */
539 ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA)); 539 ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
540 tasklet_schedule(&sc->intr_tq); 540 tasklet_schedule(&sc->intr_tq);
541 } 541 }
542 542
@@ -887,7 +887,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
887 ath_beacon_config(sc, NULL); /* restart beacons */ 887 ath_beacon_config(sc, NULL); /* restart beacons */
888 888
889 /* Re-Enable interrupts */ 889 /* Re-Enable interrupts */
890 ath9k_hw_set_interrupts(ah, sc->imask); 890 ath9k_hw_set_interrupts(ah, ah->imask);
891 891
892 /* Enable LED */ 892 /* Enable LED */
893 ath9k_hw_cfg_output(ah, ah->led_pin, 893 ath9k_hw_cfg_output(ah, ah->led_pin,
@@ -977,7 +977,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
977 if (sc->sc_flags & SC_OP_BEACONS) 977 if (sc->sc_flags & SC_OP_BEACONS)
978 ath_beacon_config(sc, NULL); /* restart beacons */ 978 ath_beacon_config(sc, NULL); /* restart beacons */
979 979
980 ath9k_hw_set_interrupts(ah, sc->imask); 980 ath9k_hw_set_interrupts(ah, ah->imask);
981 981
982 if (retry_tx) { 982 if (retry_tx) {
983 int i; 983 int i;
@@ -1162,23 +1162,23 @@ static int ath9k_start(struct ieee80211_hw *hw)
1162 } 1162 }
1163 1163
1164 /* Setup our intr mask. */ 1164 /* Setup our intr mask. */
1165 sc->imask = ATH9K_INT_RX | ATH9K_INT_TX 1165 ah->imask = ATH9K_INT_RX | ATH9K_INT_TX
1166 | ATH9K_INT_RXEOL | ATH9K_INT_RXORN 1166 | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
1167 | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; 1167 | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
1168 1168
1169 if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) 1169 if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
1170 sc->imask |= ATH9K_INT_GTT; 1170 ah->imask |= ATH9K_INT_GTT;
1171 1171
1172 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) 1172 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
1173 sc->imask |= ATH9K_INT_CST; 1173 ah->imask |= ATH9K_INT_CST;
1174 1174
1175 ath_cache_conf_rate(sc, &hw->conf); 1175 ath_cache_conf_rate(sc, &hw->conf);
1176 1176
1177 sc->sc_flags &= ~SC_OP_INVALID; 1177 sc->sc_flags &= ~SC_OP_INVALID;
1178 1178
1179 /* Disable BMISS interrupt when we're not associated */ 1179 /* Disable BMISS interrupt when we're not associated */
1180 sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 1180 ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
1181 ath9k_hw_set_interrupts(ah, sc->imask); 1181 ath9k_hw_set_interrupts(ah, ah->imask);
1182 1182
1183 ieee80211_wake_queues(hw); 1183 ieee80211_wake_queues(hw);
1184 1184
@@ -1372,14 +1372,15 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1372{ 1372{
1373 struct ath_wiphy *aphy = hw->priv; 1373 struct ath_wiphy *aphy = hw->priv;
1374 struct ath_softc *sc = aphy->sc; 1374 struct ath_softc *sc = aphy->sc;
1375 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1375 struct ath_hw *ah = sc->sc_ah;
1376 struct ath_common *common = ath9k_hw_common(ah);
1376 struct ath_vif *avp = (void *)vif->drv_priv; 1377 struct ath_vif *avp = (void *)vif->drv_priv;
1377 enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; 1378 enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
1378 int ret = 0; 1379 int ret = 0;
1379 1380
1380 mutex_lock(&sc->mutex); 1381 mutex_lock(&sc->mutex);
1381 1382
1382 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) && 1383 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
1383 sc->nvifs > 0) { 1384 sc->nvifs > 0) {
1384 ret = -ENOBUFS; 1385 ret = -ENOBUFS;
1385 goto out; 1386 goto out;
@@ -1414,19 +1415,19 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1414 1415
1415 sc->nvifs++; 1416 sc->nvifs++;
1416 1417
1417 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) 1418 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
1418 ath9k_set_bssid_mask(hw); 1419 ath9k_set_bssid_mask(hw);
1419 1420
1420 if (sc->nvifs > 1) 1421 if (sc->nvifs > 1)
1421 goto out; /* skip global settings for secondary vif */ 1422 goto out; /* skip global settings for secondary vif */
1422 1423
1423 if (ic_opmode == NL80211_IFTYPE_AP) { 1424 if (ic_opmode == NL80211_IFTYPE_AP) {
1424 ath9k_hw_set_tsfadjust(sc->sc_ah, 1); 1425 ath9k_hw_set_tsfadjust(ah, 1);
1425 sc->sc_flags |= SC_OP_TSF_RESET; 1426 sc->sc_flags |= SC_OP_TSF_RESET;
1426 } 1427 }
1427 1428
1428 /* Set the device opmode */ 1429 /* Set the device opmode */
1429 sc->sc_ah->opmode = ic_opmode; 1430 ah->opmode = ic_opmode;
1430 1431
1431 /* 1432 /*
1432 * Enable MIB interrupts when there are hardware phy counters. 1433 * Enable MIB interrupts when there are hardware phy counters.
@@ -1435,11 +1436,11 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1435 if ((vif->type == NL80211_IFTYPE_STATION) || 1436 if ((vif->type == NL80211_IFTYPE_STATION) ||
1436 (vif->type == NL80211_IFTYPE_ADHOC) || 1437 (vif->type == NL80211_IFTYPE_ADHOC) ||
1437 (vif->type == NL80211_IFTYPE_MESH_POINT)) { 1438 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
1438 sc->imask |= ATH9K_INT_MIB; 1439 ah->imask |= ATH9K_INT_MIB;
1439 sc->imask |= ATH9K_INT_TSFOOR; 1440 ah->imask |= ATH9K_INT_TSFOOR;
1440 } 1441 }
1441 1442
1442 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 1443 ath9k_hw_set_interrupts(ah, ah->imask);
1443 1444
1444 if (vif->type == NL80211_IFTYPE_AP || 1445 if (vif->type == NL80211_IFTYPE_AP ||
1445 vif->type == NL80211_IFTYPE_ADHOC || 1446 vif->type == NL80211_IFTYPE_ADHOC ||
@@ -1495,15 +1496,16 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1495 1496
1496void ath9k_enable_ps(struct ath_softc *sc) 1497void ath9k_enable_ps(struct ath_softc *sc)
1497{ 1498{
1499 struct ath_hw *ah = sc->sc_ah;
1500
1498 sc->ps_enabled = true; 1501 sc->ps_enabled = true;
1499 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 1502 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1500 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { 1503 if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) {
1501 sc->imask |= ATH9K_INT_TIM_TIMER; 1504 ah->imask |= ATH9K_INT_TIM_TIMER;
1502 ath9k_hw_set_interrupts(sc->sc_ah, 1505 ath9k_hw_set_interrupts(ah, ah->imask);
1503 sc->imask);
1504 } 1506 }
1505 } 1507 }
1506 ath9k_hw_setrxabort(sc->sc_ah, 1); 1508 ath9k_hw_setrxabort(ah, 1);
1507} 1509}
1508 1510
1509static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 1511static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
@@ -1579,10 +1581,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1579 PS_WAIT_FOR_CAB | 1581 PS_WAIT_FOR_CAB |
1580 PS_WAIT_FOR_PSPOLL_DATA | 1582 PS_WAIT_FOR_PSPOLL_DATA |
1581 PS_WAIT_FOR_TX_ACK); 1583 PS_WAIT_FOR_TX_ACK);
1582 if (sc->imask & ATH9K_INT_TIM_TIMER) { 1584 if (ah->imask & ATH9K_INT_TIM_TIMER) {
1583 sc->imask &= ~ATH9K_INT_TIM_TIMER; 1585 ah->imask &= ~ATH9K_INT_TIM_TIMER;
1584 ath9k_hw_set_interrupts(sc->sc_ah, 1586 ath9k_hw_set_interrupts(sc->sc_ah,
1585 sc->imask); 1587 ah->imask);
1586 } 1588 }
1587 } 1589 }
1588 } 1590 }
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 9441c6718a30..1ec836cf1c0d 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -88,6 +88,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
88} 88}
89 89
90static const struct ath_bus_ops ath_pci_bus_ops = { 90static const struct ath_bus_ops ath_pci_bus_ops = {
91 .ath_bus_type = ATH_PCI,
91 .read_cachesize = ath_pci_read_cachesize, 92 .read_cachesize = ath_pci_read_cachesize,
92 .eeprom_read = ath_pci_eeprom_read, 93 .eeprom_read = ath_pci_eeprom_read,
93 .bt_coex_prep = ath_pci_bt_coex_prep, 94 .bt_coex_prep = ath_pci_bt_coex_prep,
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 0999a495fd46..0132e4c9a9f9 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -503,6 +503,8 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
503#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 503#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
504 504
505#define AR_PHY_TX_PWRCTRL7 0xa274 505#define AR_PHY_TX_PWRCTRL7 0xa274
506#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX 0x0007E000
507#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13
506#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 508#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
507#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 509#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
508 510
@@ -513,8 +515,16 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
513#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31 515#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
514 516
515#define AR_PHY_TX_GAIN_TBL1 0xa300 517#define AR_PHY_TX_GAIN_TBL1 0xa300
516#define AR_PHY_TX_GAIN 0x0007F000 518#define AR_PHY_TX_GAIN_CLC 0x0000001E
517#define AR_PHY_TX_GAIN_S 12 519#define AR_PHY_TX_GAIN_CLC_S 1
520#define AR_PHY_TX_GAIN 0x0007F000
521#define AR_PHY_TX_GAIN_S 12
522
523#define AR_PHY_CLC_TBL1 0xa35c
524#define AR_PHY_CLC_I0 0x07ff0000
525#define AR_PHY_CLC_I0_S 16
526#define AR_PHY_CLC_Q0 0x0000ffd0
527#define AR_PHY_CLC_Q0_S 5
518 528
519#define AR_PHY_CH0_TX_PWRCTRL11 0xa398 529#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
520#define AR_PHY_CH1_TX_PWRCTRL11 0xb398 530#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 0e79e58cf4c9..3c4b5d2d9e16 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1226,8 +1226,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1226 long_retry = rate->count - 1; 1226 long_retry = rate->count - 1;
1227 } 1227 }
1228 1228
1229 if (!priv_sta || !ieee80211_is_data(fc) || 1229 if (!priv_sta || !ieee80211_is_data(fc))
1230 !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC)) 1230 return;
1231
1232 /* This packet was aggregated but doesn't carry status info */
1233 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1234 !(tx_info->flags & IEEE80211_TX_STAT_AMPDU))
1231 return; 1235 return;
1232 1236
1233 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) 1237 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 4f6d6fd442f4..3d8d40cdc99e 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -110,8 +110,8 @@ struct ath_rate_table {
110 int rate_cnt; 110 int rate_cnt;
111 int mcs_start; 111 int mcs_start;
112 struct { 112 struct {
113 int valid; 113 u8 valid;
114 int valid_single_stream; 114 u8 valid_single_stream;
115 u8 phy; 115 u8 phy;
116 u32 ratekbps; 116 u32 ratekbps;
117 u32 user_ratekbps; 117 u32 user_ratekbps;
@@ -172,14 +172,13 @@ struct ath_rate_priv {
172 172
173#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) 173#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0)
174#define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) 174#define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1)
175#define ATH_TX_INFO_UPDATE_RC (1 << 2)
176#define ATH_TX_INFO_XRETRY (1 << 3) 175#define ATH_TX_INFO_XRETRY (1 << 3)
177#define ATH_TX_INFO_UNDERRUN (1 << 4) 176#define ATH_TX_INFO_UNDERRUN (1 << 4)
178 177
179enum ath9k_internal_frame_type { 178enum ath9k_internal_frame_type {
180 ATH9K_NOT_INTERNAL, 179 ATH9K_IFT_NOT_INTERNAL,
181 ATH9K_INT_PAUSE, 180 ATH9K_IFT_PAUSE,
182 ATH9K_INT_UNPAUSE 181 ATH9K_IFT_UNPAUSE
183}; 182};
184 183
185int ath_rate_control_register(void); 184int ath_rate_control_register(void);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 1ca42e5148c8..94560e2fe376 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -477,7 +477,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
477 477
478 struct ath_buf *bf; 478 struct ath_buf *bf;
479 struct ath_desc *ds; 479 struct ath_desc *ds;
480 struct ath_rx_status *rx_stats;
481 struct sk_buff *skb = NULL, *requeue_skb; 480 struct sk_buff *skb = NULL, *requeue_skb;
482 struct ieee80211_rx_status *rxs; 481 struct ieee80211_rx_status *rxs;
483 struct ath_hw *ah = sc->sc_ah; 482 struct ath_hw *ah = sc->sc_ah;
@@ -491,6 +490,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
491 struct ieee80211_hdr *hdr; 490 struct ieee80211_hdr *hdr;
492 int retval; 491 int retval;
493 bool decrypt_error = false; 492 bool decrypt_error = false;
493 struct ath_rx_status rs;
494 494
495 spin_lock_bh(&sc->rx.rxbuflock); 495 spin_lock_bh(&sc->rx.rxbuflock);
496 496
@@ -518,14 +518,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
518 * on. All this is necessary because of our use of 518 * on. All this is necessary because of our use of
519 * a self-linked list to avoid rx overruns. 519 * a self-linked list to avoid rx overruns.
520 */ 520 */
521 retval = ath9k_hw_rxprocdesc(ah, ds, 521 memset(&rs, 0, sizeof(rs));
522 bf->bf_daddr, 522 retval = ath9k_hw_rxprocdesc(ah, ds, &rs, 0);
523 PA2DESC(sc, ds->ds_link),
524 0);
525 if (retval == -EINPROGRESS) { 523 if (retval == -EINPROGRESS) {
524 struct ath_rx_status trs;
526 struct ath_buf *tbf; 525 struct ath_buf *tbf;
527 struct ath_desc *tds; 526 struct ath_desc *tds;
528 527
528 memset(&trs, 0, sizeof(trs));
529 if (list_is_last(&bf->list, &sc->rx.rxbuf)) { 529 if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
530 sc->rx.rxlink = NULL; 530 sc->rx.rxlink = NULL;
531 break; 531 break;
@@ -545,8 +545,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
545 */ 545 */
546 546
547 tds = tbf->bf_desc; 547 tds = tbf->bf_desc;
548 retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr, 548 retval = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
549 PA2DESC(sc, tds->ds_link), 0);
550 if (retval == -EINPROGRESS) { 549 if (retval == -EINPROGRESS) {
551 break; 550 break;
552 } 551 }
@@ -569,9 +568,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
569 rxs = IEEE80211_SKB_RXCB(skb); 568 rxs = IEEE80211_SKB_RXCB(skb);
570 569
571 hw = ath_get_virt_hw(sc, hdr); 570 hw = ath_get_virt_hw(sc, hdr);
572 rx_stats = &ds->ds_rxstat;
573 571
574 ath_debug_stat_rx(sc, bf); 572 ath_debug_stat_rx(sc, &rs);
575 573
576 /* 574 /*
577 * If we're asked to flush receive queue, directly 575 * If we're asked to flush receive queue, directly
@@ -580,7 +578,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
580 if (flush) 578 if (flush)
581 goto requeue; 579 goto requeue;
582 580
583 retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, rx_stats, 581 retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, &rs,
584 rxs, &decrypt_error); 582 rxs, &decrypt_error);
585 if (retval) 583 if (retval)
586 goto requeue; 584 goto requeue;
@@ -601,9 +599,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
601 common->rx_bufsize, 599 common->rx_bufsize,
602 DMA_FROM_DEVICE); 600 DMA_FROM_DEVICE);
603 601
604 skb_put(skb, rx_stats->rs_datalen); 602 skb_put(skb, rs.rs_datalen);
605 603
606 ath9k_cmn_rx_skb_postprocess(common, skb, rx_stats, 604 ath9k_cmn_rx_skb_postprocess(common, skb, &rs,
607 rxs, decrypt_error); 605 rxs, decrypt_error);
608 606
609 /* We will now give hardware our shiny new allocated skb */ 607 /* We will now give hardware our shiny new allocated skb */
@@ -626,9 +624,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
626 * change the default rx antenna if rx diversity chooses the 624 * change the default rx antenna if rx diversity chooses the
627 * other antenna 3 times in a row. 625 * other antenna 3 times in a row.
628 */ 626 */
629 if (sc->rx.defant != ds->ds_rxstat.rs_antenna) { 627 if (sc->rx.defant != rs.rs_antenna) {
630 if (++sc->rx.rxotherant >= 3) 628 if (++sc->rx.rxotherant >= 3)
631 ath_setdefantenna(sc, rx_stats->rs_antenna); 629 ath_setdefantenna(sc, rs.rs_antenna);
632 } else { 630 } else {
633 sc->rx.rxotherant = 0; 631 sc->rx.rxotherant = 0;
634 } 632 }
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 72cfa8ebd9ae..7e36ad7421b7 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -679,7 +679,7 @@
679 679
680#define AR_WA 0x4004 680#define AR_WA 0x4004
681#define AR_WA_D3_L1_DISABLE (1 << 14) 681#define AR_WA_D3_L1_DISABLE (1 << 14)
682#define AR9285_WA_DEFAULT 0x004a05cb 682#define AR9285_WA_DEFAULT 0x004a050b
683#define AR9280_WA_DEFAULT 0x0040073b 683#define AR9280_WA_DEFAULT 0x0040073b
684#define AR_WA_DEFAULT 0x0000073f 684#define AR_WA_DEFAULT 0x0000073f
685 685
@@ -845,6 +845,10 @@
845 (AR_SREV_9271(_ah) && \ 845 (AR_SREV_9271(_ah) && \
846 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11)) 846 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11))
847 847
848#define AR_SREV_9285E_20(_ah) \
849 (AR_SREV_9285_12_OR_LATER(_ah) && \
850 ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
851
848#define AR_RADIO_SREV_MAJOR 0xf0 852#define AR_RADIO_SREV_MAJOR 0xf0
849#define AR_RAD5133_SREV_MAJOR 0xc0 853#define AR_RAD5133_SREV_MAJOR 0xc0
850#define AR_RAD2133_SREV_MAJOR 0xd0 854#define AR_RAD2133_SREV_MAJOR 0xd0
@@ -940,6 +944,7 @@ enum {
940#define AR928X_NUM_GPIO 10 944#define AR928X_NUM_GPIO 10
941#define AR9285_NUM_GPIO 12 945#define AR9285_NUM_GPIO 12
942#define AR9287_NUM_GPIO 11 946#define AR9287_NUM_GPIO 11
947#define AR9271_NUM_GPIO 16
943 948
944#define AR_GPIO_IN_OUT 0x4048 949#define AR_GPIO_IN_OUT 0x4048
945#define AR_GPIO_IN_VAL 0x0FFFC000 950#define AR_GPIO_IN_VAL 0x0FFFC000
@@ -950,6 +955,8 @@ enum {
950#define AR9285_GPIO_IN_VAL_S 12 955#define AR9285_GPIO_IN_VAL_S 12
951#define AR9287_GPIO_IN_VAL 0x003FF800 956#define AR9287_GPIO_IN_VAL 0x003FF800
952#define AR9287_GPIO_IN_VAL_S 11 957#define AR9287_GPIO_IN_VAL_S 11
958#define AR9271_GPIO_IN_VAL 0xFFFF0000
959#define AR9271_GPIO_IN_VAL_S 16
953 960
954#define AR_GPIO_OE_OUT 0x404c 961#define AR_GPIO_OE_OUT 0x404c
955#define AR_GPIO_OE_OUT_DRV 0x3 962#define AR_GPIO_OE_OUT_DRV 0x3
@@ -1178,6 +1185,13 @@ enum {
1178#define AR9285_AN_RF2G4_DB2_4 0x00003800 1185#define AR9285_AN_RF2G4_DB2_4 0x00003800
1179#define AR9285_AN_RF2G4_DB2_4_S 11 1186#define AR9285_AN_RF2G4_DB2_4_S 11
1180 1187
1188#define AR9285_RF2G5 0x7830
1189#define AR9285_RF2G5_IC50TX 0xfffff8ff
1190#define AR9285_RF2G5_IC50TX_SET 0x00000400
1191#define AR9285_RF2G5_IC50TX_XE_SET 0x00000500
1192#define AR9285_RF2G5_IC50TX_CLEAR 0x00000700
1193#define AR9285_RF2G5_IC50TX_CLEAR_S 8
1194
1181/* AR9271 : 0x7828, 0x782c different setting from AR9285 */ 1195/* AR9271 : 0x7828, 0x782c different setting from AR9285 */
1182#define AR9271_AN_RF2G3_OB_cck 0x001C0000 1196#define AR9271_AN_RF2G3_OB_cck 0x001C0000
1183#define AR9271_AN_RF2G3_OB_cck_S 18 1197#define AR9271_AN_RF2G3_OB_cck_S 18
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index a43fbf84dab9..e95aaa3f18f3 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -218,7 +218,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
218 218
219 memset(&txctl, 0, sizeof(struct ath_tx_control)); 219 memset(&txctl, 0, sizeof(struct ath_tx_control));
220 txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; 220 txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
221 txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE; 221 txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;
222 222
223 if (ath_tx_start(aphy->hw, skb, &txctl) != 0) 223 if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
224 goto exit; 224 goto exit;
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
new file mode 100644
index 000000000000..818dea0164ec
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -0,0 +1,319 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
20{
21 switch (wmi_cmd) {
22 case WMI_ECHO_CMDID:
23 return "WMI_ECHO_CMDID";
24 case WMI_ACCESS_MEMORY_CMDID:
25 return "WMI_ACCESS_MEMORY_CMDID";
26 case WMI_DISABLE_INTR_CMDID:
27 return "WMI_DISABLE_INTR_CMDID";
28 case WMI_ENABLE_INTR_CMDID:
29 return "WMI_ENABLE_INTR_CMDID";
30 case WMI_RX_LINK_CMDID:
31 return "WMI_RX_LINK_CMDID";
32 case WMI_ATH_INIT_CMDID:
33 return "WMI_ATH_INIT_CMDID";
34 case WMI_ABORT_TXQ_CMDID:
35 return "WMI_ABORT_TXQ_CMDID";
36 case WMI_STOP_TX_DMA_CMDID:
37 return "WMI_STOP_TX_DMA_CMDID";
38 case WMI_STOP_DMA_RECV_CMDID:
39 return "WMI_STOP_DMA_RECV_CMDID";
40 case WMI_ABORT_TX_DMA_CMDID:
41 return "WMI_ABORT_TX_DMA_CMDID";
42 case WMI_DRAIN_TXQ_CMDID:
43 return "WMI_DRAIN_TXQ_CMDID";
44 case WMI_DRAIN_TXQ_ALL_CMDID:
45 return "WMI_DRAIN_TXQ_ALL_CMDID";
46 case WMI_START_RECV_CMDID:
47 return "WMI_START_RECV_CMDID";
48 case WMI_STOP_RECV_CMDID:
49 return "WMI_STOP_RECV_CMDID";
50 case WMI_FLUSH_RECV_CMDID:
51 return "WMI_FLUSH_RECV_CMDID";
52 case WMI_SET_MODE_CMDID:
53 return "WMI_SET_MODE_CMDID";
54 case WMI_RESET_CMDID:
55 return "WMI_RESET_CMDID";
56 case WMI_NODE_CREATE_CMDID:
57 return "WMI_NODE_CREATE_CMDID";
58 case WMI_NODE_REMOVE_CMDID:
59 return "WMI_NODE_REMOVE_CMDID";
60 case WMI_VAP_REMOVE_CMDID:
61 return "WMI_VAP_REMOVE_CMDID";
62 case WMI_VAP_CREATE_CMDID:
63 return "WMI_VAP_CREATE_CMDID";
64 case WMI_BEACON_UPDATE_CMDID:
65 return "WMI_BEACON_UPDATE_CMDID";
66 case WMI_REG_READ_CMDID:
67 return "WMI_REG_READ_CMDID";
68 case WMI_REG_WRITE_CMDID:
69 return "WMI_REG_WRITE_CMDID";
70 case WMI_RC_STATE_CHANGE_CMDID:
71 return "WMI_RC_STATE_CHANGE_CMDID";
72 case WMI_RC_RATE_UPDATE_CMDID:
73 return "WMI_RC_RATE_UPDATE_CMDID";
74 case WMI_DEBUG_INFO_CMDID:
75 return "WMI_DEBUG_INFO_CMDID";
76 case WMI_HOST_ATTACH:
77 return "WMI_HOST_ATTACH";
78 case WMI_TARGET_IC_UPDATE_CMDID:
79 return "WMI_TARGET_IC_UPDATE_CMDID";
80 case WMI_TGT_STATS_CMDID:
81 return "WMI_TGT_STATS_CMDID";
82 case WMI_TX_AGGR_ENABLE_CMDID:
83 return "WMI_TX_AGGR_ENABLE_CMDID";
84 case WMI_TGT_DETACH_CMDID:
85 return "WMI_TGT_DETACH_CMDID";
86 case WMI_TGT_TXQ_ENABLE_CMDID:
87 return "WMI_TGT_TXQ_ENABLE_CMDID";
88 }
89
90 return "Bogus";
91}
92
93struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
94{
95 struct wmi *wmi;
96
97 wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
98 if (!wmi)
99 return NULL;
100
101 wmi->drv_priv = priv;
102 wmi->stopped = false;
103 mutex_init(&wmi->op_mutex);
104 init_completion(&wmi->cmd_wait);
105
106 return wmi;
107}
108
109void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
110{
111 struct wmi *wmi = priv->wmi;
112
113 mutex_lock(&wmi->op_mutex);
114 wmi->stopped = true;
115 mutex_unlock(&wmi->op_mutex);
116
117 kfree(priv->wmi);
118}
119
120void ath9k_wmi_tasklet(unsigned long data)
121{
122 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
123 struct ath_common *common = ath9k_hw_common(priv->ah);
124 struct wmi_cmd_hdr *hdr;
125 struct wmi_swba *swba_hdr;
126 enum wmi_event_id event;
127 struct sk_buff *skb;
128 void *wmi_event;
129 unsigned long flags;
130#ifdef CONFIG_ATH9K_HTC_DEBUGFS
131 u32 txrate;
132#endif
133
134 spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
135 skb = priv->wmi->wmi_skb;
136 spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
137
138 hdr = (struct wmi_cmd_hdr *) skb->data;
139 event = be16_to_cpu(hdr->command_id);
140 wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
141
142 ath_print(common, ATH_DBG_WMI,
143 "WMI Event: 0x%x\n", event);
144
145 switch (event) {
146 case WMI_TGT_RDY_EVENTID:
147 break;
148 case WMI_SWBA_EVENTID:
149 swba_hdr = (struct wmi_swba *) wmi_event;
150 ath9k_htc_swba(priv, swba_hdr->beacon_pending);
151 break;
152 case WMI_FATAL_EVENTID:
153 break;
154 case WMI_TXTO_EVENTID:
155 break;
156 case WMI_BMISS_EVENTID:
157 break;
158 case WMI_WLAN_TXCOMP_EVENTID:
159 break;
160 case WMI_DELBA_EVENTID:
161 break;
162 case WMI_TXRATE_EVENTID:
163#ifdef CONFIG_ATH9K_HTC_DEBUGFS
164 txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
165 priv->debug.txrate = be32_to_cpu(txrate);
166#endif
167 break;
168 default:
169 break;
170 }
171
172 dev_kfree_skb_any(skb);
173}
174
175static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
176{
177 skb_pull(skb, sizeof(struct wmi_cmd_hdr));
178
179 if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0)
180 memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len);
181
182 complete(&wmi->cmd_wait);
183}
184
185static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
186 enum htc_endpoint_id epid)
187{
188 struct wmi *wmi = (struct wmi *) priv;
189 struct wmi_cmd_hdr *hdr;
190 u16 cmd_id;
191
192 if (unlikely(wmi->stopped))
193 goto free_skb;
194
195 hdr = (struct wmi_cmd_hdr *) skb->data;
196 cmd_id = be16_to_cpu(hdr->command_id);
197
198 if (cmd_id & 0x1000) {
199 spin_lock(&wmi->wmi_lock);
200 wmi->wmi_skb = skb;
201 spin_unlock(&wmi->wmi_lock);
202 tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
203 return;
204 }
205
206 /* WMI command response */
207 ath9k_wmi_rsp_callback(wmi, skb);
208
209free_skb:
210 dev_kfree_skb_any(skb);
211}
212
213static void ath9k_wmi_ctrl_tx(void *priv, struct sk_buff *skb,
214 enum htc_endpoint_id epid, bool txok)
215{
216 dev_kfree_skb_any(skb);
217}
218
219int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
220 enum htc_endpoint_id *wmi_ctrl_epid)
221{
222 struct htc_service_connreq connect;
223 int ret;
224
225 wmi->htc = htc;
226
227 memset(&connect, 0, sizeof(connect));
228
229 connect.ep_callbacks.priv = wmi;
230 connect.ep_callbacks.tx = ath9k_wmi_ctrl_tx;
231 connect.ep_callbacks.rx = ath9k_wmi_ctrl_rx;
232 connect.service_id = WMI_CONTROL_SVC;
233
234 ret = htc_connect_service(htc, &connect, &wmi->ctrl_epid);
235 if (ret)
236 return ret;
237
238 *wmi_ctrl_epid = wmi->ctrl_epid;
239
240 return 0;
241}
242
243static int ath9k_wmi_cmd_issue(struct wmi *wmi,
244 struct sk_buff *skb,
245 enum wmi_cmd_id cmd, u16 len)
246{
247 struct wmi_cmd_hdr *hdr;
248
249 hdr = (struct wmi_cmd_hdr *) skb_push(skb, sizeof(struct wmi_cmd_hdr));
250 hdr->command_id = cpu_to_be16(cmd);
251 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
252
253 return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
254}
255
256int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
257 u8 *cmd_buf, u32 cmd_len,
258 u8 *rsp_buf, u32 rsp_len,
259 u32 timeout)
260{
261 struct ath_hw *ah = wmi->drv_priv->ah;
262 struct ath_common *common = ath9k_hw_common(ah);
263 u16 headroom = sizeof(struct htc_frame_hdr) +
264 sizeof(struct wmi_cmd_hdr);
265 struct sk_buff *skb;
266 u8 *data;
267 int time_left, ret = 0;
268
269 if (!wmi)
270 return -EINVAL;
271
272 skb = dev_alloc_skb(headroom + cmd_len);
273 if (!skb)
274 return -ENOMEM;
275
276 skb_reserve(skb, headroom);
277
278 if (cmd_len != 0 && cmd_buf != NULL) {
279 data = (u8 *) skb_put(skb, cmd_len);
280 memcpy(data, cmd_buf, cmd_len);
281 }
282
283 mutex_lock(&wmi->op_mutex);
284
285 /* check if wmi stopped flag is set */
286 if (unlikely(wmi->stopped)) {
287 ret = -EPROTO;
288 goto out;
289 }
290
291 /* record the rsp buffer and length */
292 wmi->cmd_rsp_buf = rsp_buf;
293 wmi->cmd_rsp_len = rsp_len;
294
295 ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
296 if (ret)
297 goto out;
298
299 time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
300 if (!time_left) {
301 ath_print(common, ATH_DBG_WMI,
302 "Timeout waiting for WMI command: %s\n",
303 wmi_cmd_to_name(cmd_id));
304 mutex_unlock(&wmi->op_mutex);
305 return -ETIMEDOUT;
306 }
307
308 mutex_unlock(&wmi->op_mutex);
309
310 return 0;
311
312out:
313 ath_print(common, ATH_DBG_WMI,
314 "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
315 mutex_unlock(&wmi->op_mutex);
316 dev_kfree_skb_any(skb);
317
318 return ret;
319}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
new file mode 100644
index 000000000000..39ef926f27c2
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef WMI_H
18#define WMI_H
19
20
21struct wmi_event_txrate {
22 u32 txrate;
23 struct {
24 u8 rssi_thresh;
25 u8 per;
26 } rc_stats;
27} __packed;
28
29struct wmi_cmd_hdr {
30 u16 command_id;
31 u16 seq_no;
32} __packed;
33
34struct wmi_swba {
35 u8 beacon_pending;
36} __packed;
37
38enum wmi_cmd_id {
39 WMI_ECHO_CMDID = 0x0001,
40 WMI_ACCESS_MEMORY_CMDID,
41
42 /* Commands to Target */
43 WMI_DISABLE_INTR_CMDID,
44 WMI_ENABLE_INTR_CMDID,
45 WMI_RX_LINK_CMDID,
46 WMI_ATH_INIT_CMDID,
47 WMI_ABORT_TXQ_CMDID,
48 WMI_STOP_TX_DMA_CMDID,
49 WMI_STOP_DMA_RECV_CMDID,
50 WMI_ABORT_TX_DMA_CMDID,
51 WMI_DRAIN_TXQ_CMDID,
52 WMI_DRAIN_TXQ_ALL_CMDID,
53 WMI_START_RECV_CMDID,
54 WMI_STOP_RECV_CMDID,
55 WMI_FLUSH_RECV_CMDID,
56 WMI_SET_MODE_CMDID,
57 WMI_RESET_CMDID,
58 WMI_NODE_CREATE_CMDID,
59 WMI_NODE_REMOVE_CMDID,
60 WMI_VAP_REMOVE_CMDID,
61 WMI_VAP_CREATE_CMDID,
62 WMI_BEACON_UPDATE_CMDID,
63 WMI_REG_READ_CMDID,
64 WMI_REG_WRITE_CMDID,
65 WMI_RC_STATE_CHANGE_CMDID,
66 WMI_RC_RATE_UPDATE_CMDID,
67 WMI_DEBUG_INFO_CMDID,
68 WMI_HOST_ATTACH,
69 WMI_TARGET_IC_UPDATE_CMDID,
70 WMI_TGT_STATS_CMDID,
71 WMI_TX_AGGR_ENABLE_CMDID,
72 WMI_TGT_DETACH_CMDID,
73 WMI_TGT_TXQ_ENABLE_CMDID,
74};
75
76enum wmi_event_id {
77 WMI_TGT_RDY_EVENTID = 0x1001,
78 WMI_SWBA_EVENTID,
79 WMI_FATAL_EVENTID,
80 WMI_TXTO_EVENTID,
81 WMI_BMISS_EVENTID,
82 WMI_WLAN_TXCOMP_EVENTID,
83 WMI_DELBA_EVENTID,
84 WMI_TXRATE_EVENTID,
85};
86
87struct wmi {
88 struct ath9k_htc_priv *drv_priv;
89 struct htc_target *htc;
90 enum htc_endpoint_id ctrl_epid;
91 struct mutex op_mutex;
92 struct completion cmd_wait;
93 u16 tx_seq_id;
94 u8 *cmd_rsp_buf;
95 u32 cmd_rsp_len;
96 bool stopped;
97
98 struct sk_buff *wmi_skb;
99 spinlock_t wmi_lock;
100};
101
102struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
103void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
104int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
105 enum htc_endpoint_id *wmi_ctrl_epid);
106int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
107 u8 *cmd_buf, u32 cmd_len,
108 u8 *rsp_buf, u32 rsp_len,
109 u32 timeout);
110void ath9k_wmi_tasklet(unsigned long data);
111
112#define WMI_CMD(_wmi_cmd) \
113 do { \
114 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \
115 (u8 *) &cmd_rsp, \
116 sizeof(cmd_rsp), HZ); \
117 } while (0)
118
119#define WMI_CMD_BUF(_wmi_cmd, _buf) \
120 do { \
121 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \
122 (u8 *) _buf, sizeof(*_buf), \
123 &cmd_rsp, sizeof(cmd_rsp), HZ); \
124 } while (0)
125
126#endif /* WMI_H */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 294b486bc3ed..02df4cbf179f 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -59,15 +59,14 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
59 struct ath_atx_tid *tid, 59 struct ath_atx_tid *tid,
60 struct list_head *bf_head); 60 struct list_head *bf_head);
61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
62 struct ath_txq *txq, 62 struct ath_txq *txq, struct list_head *bf_q,
63 struct list_head *bf_q, 63 struct ath_tx_status *ts, int txok, int sendbar);
64 int txok, int sendbar);
65static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 64static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
66 struct list_head *head); 65 struct list_head *head);
67static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); 66static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
68static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, 67static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
69 int txok); 68 struct ath_tx_status *ts, int txok);
70static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 69static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
71 int nbad, int txok, bool update_rc); 70 int nbad, int txok, bool update_rc);
72 71
73enum { 72enum {
@@ -223,6 +222,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
223{ 222{
224 struct ath_buf *bf; 223 struct ath_buf *bf;
225 struct list_head bf_head; 224 struct list_head bf_head;
225 struct ath_tx_status ts;
226
227 memset(&ts, 0, sizeof(ts));
226 INIT_LIST_HEAD(&bf_head); 228 INIT_LIST_HEAD(&bf_head);
227 229
228 for (;;) { 230 for (;;) {
@@ -236,7 +238,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
236 ath_tx_update_baw(sc, tid, bf->bf_seqno); 238 ath_tx_update_baw(sc, tid, bf->bf_seqno);
237 239
238 spin_unlock(&txq->axq_lock); 240 spin_unlock(&txq->axq_lock);
239 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 241 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
240 spin_lock(&txq->axq_lock); 242 spin_lock(&txq->axq_lock);
241 } 243 }
242 244
@@ -286,7 +288,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
286 288
287static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, 289static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
288 struct ath_buf *bf, struct list_head *bf_q, 290 struct ath_buf *bf, struct list_head *bf_q,
289 int txok) 291 struct ath_tx_status *ts, int txok)
290{ 292{
291 struct ath_node *an = NULL; 293 struct ath_node *an = NULL;
292 struct sk_buff *skb; 294 struct sk_buff *skb;
@@ -296,7 +298,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
296 struct ieee80211_tx_info *tx_info; 298 struct ieee80211_tx_info *tx_info;
297 struct ath_atx_tid *tid = NULL; 299 struct ath_atx_tid *tid = NULL;
298 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; 300 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
299 struct ath_desc *ds = bf_last->bf_desc;
300 struct list_head bf_head, bf_pending; 301 struct list_head bf_head, bf_pending;
301 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; 302 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
302 u32 ba[WME_BA_BMP_SIZE >> 5]; 303 u32 ba[WME_BA_BMP_SIZE >> 5];
@@ -325,10 +326,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
325 memset(ba, 0, WME_BA_BMP_SIZE >> 3); 326 memset(ba, 0, WME_BA_BMP_SIZE >> 3);
326 327
327 if (isaggr && txok) { 328 if (isaggr && txok) {
328 if (ATH_DS_TX_BA(ds)) { 329 if (ts->ts_flags & ATH9K_TX_BA) {
329 seq_st = ATH_DS_BA_SEQ(ds); 330 seq_st = ts->ts_seqnum;
330 memcpy(ba, ATH_DS_BA_BITMAP(ds), 331 memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
331 WME_BA_BMP_SIZE >> 3);
332 } else { 332 } else {
333 /* 333 /*
334 * AR5416 can become deaf/mute when BA 334 * AR5416 can become deaf/mute when BA
@@ -345,7 +345,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
345 INIT_LIST_HEAD(&bf_pending); 345 INIT_LIST_HEAD(&bf_pending);
346 INIT_LIST_HEAD(&bf_head); 346 INIT_LIST_HEAD(&bf_head);
347 347
348 nbad = ath_tx_num_badfrms(sc, bf, txok); 348 nbad = ath_tx_num_badfrms(sc, bf, ts, txok);
349 while (bf) { 349 while (bf) {
350 txfail = txpending = 0; 350 txfail = txpending = 0;
351 bf_next = bf->bf_next; 351 bf_next = bf->bf_next;
@@ -359,7 +359,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
359 acked_cnt++; 359 acked_cnt++;
360 } else { 360 } else {
361 if (!(tid->state & AGGR_CLEANUP) && 361 if (!(tid->state & AGGR_CLEANUP) &&
362 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { 362 ts->ts_flags != ATH9K_TX_SW_ABORTED) {
363 if (bf->bf_retries < ATH_MAX_SW_RETRIES) { 363 if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
364 ath_tx_set_retry(sc, txq, bf); 364 ath_tx_set_retry(sc, txq, bf);
365 txpending = 1; 365 txpending = 1;
@@ -402,13 +402,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
402 spin_unlock_bh(&txq->axq_lock); 402 spin_unlock_bh(&txq->axq_lock);
403 403
404 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { 404 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
405 ath_tx_rc_status(bf, ds, nbad, txok, true); 405 ath_tx_rc_status(bf, ts, nbad, txok, true);
406 rc_update = false; 406 rc_update = false;
407 } else { 407 } else {
408 ath_tx_rc_status(bf, ds, nbad, txok, false); 408 ath_tx_rc_status(bf, ts, nbad, txok, false);
409 } 409 }
410 410
411 ath_tx_complete_buf(sc, bf, txq, &bf_head, !txfail, sendbar); 411 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
412 !txfail, sendbar);
412 } else { 413 } else {
413 /* retry the un-acked ones */ 414 /* retry the un-acked ones */
414 if (bf->bf_next == NULL && bf_last->bf_stale) { 415 if (bf->bf_next == NULL && bf_last->bf_stale) {
@@ -426,10 +427,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
426 spin_unlock_bh(&txq->axq_lock); 427 spin_unlock_bh(&txq->axq_lock);
427 428
428 bf->bf_state.bf_type |= BUF_XRETRY; 429 bf->bf_state.bf_type |= BUF_XRETRY;
429 ath_tx_rc_status(bf, ds, nbad, 430 ath_tx_rc_status(bf, ts, nbad,
430 0, false); 431 0, false);
431 ath_tx_complete_buf(sc, bf, txq, 432 ath_tx_complete_buf(sc, bf, txq,
432 &bf_head, 0, 0); 433 &bf_head, ts, 0, 0);
433 break; 434 break;
434 } 435 }
435 436
@@ -752,8 +753,11 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
752 struct ath_node *an = (struct ath_node *)sta->drv_priv; 753 struct ath_node *an = (struct ath_node *)sta->drv_priv;
753 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); 754 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
754 struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; 755 struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
756 struct ath_tx_status ts;
755 struct ath_buf *bf; 757 struct ath_buf *bf;
756 struct list_head bf_head; 758 struct list_head bf_head;
759
760 memset(&ts, 0, sizeof(ts));
757 INIT_LIST_HEAD(&bf_head); 761 INIT_LIST_HEAD(&bf_head);
758 762
759 if (txtid->state & AGGR_CLEANUP) 763 if (txtid->state & AGGR_CLEANUP)
@@ -780,7 +784,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
780 } 784 }
781 list_move_tail(&bf->list, &bf_head); 785 list_move_tail(&bf->list, &bf_head);
782 ath_tx_update_baw(sc, txtid, bf->bf_seqno); 786 ath_tx_update_baw(sc, txtid, bf->bf_seqno);
783 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 787 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
784 } 788 }
785 spin_unlock_bh(&txq->axq_lock); 789 spin_unlock_bh(&txq->axq_lock);
786 790
@@ -1028,6 +1032,11 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1028{ 1032{
1029 struct ath_buf *bf, *lastbf; 1033 struct ath_buf *bf, *lastbf;
1030 struct list_head bf_head; 1034 struct list_head bf_head;
1035 struct ath_tx_status ts;
1036
1037 memset(&ts, 0, sizeof(ts));
1038 if (!retry_tx)
1039 ts.ts_flags = ATH9K_TX_SW_ABORTED;
1031 1040
1032 INIT_LIST_HEAD(&bf_head); 1041 INIT_LIST_HEAD(&bf_head);
1033 1042
@@ -1053,9 +1062,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1053 } 1062 }
1054 1063
1055 lastbf = bf->bf_lastbf; 1064 lastbf = bf->bf_lastbf;
1056 if (!retry_tx)
1057 lastbf->bf_desc->ds_txstat.ts_flags =
1058 ATH9K_TX_SW_ABORTED;
1059 1065
1060 /* remove ath_buf's of the same mpdu from txq */ 1066 /* remove ath_buf's of the same mpdu from txq */
1061 list_cut_position(&bf_head, &txq->axq_q, &lastbf->list); 1067 list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
@@ -1064,9 +1070,9 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1064 spin_unlock_bh(&txq->axq_lock); 1070 spin_unlock_bh(&txq->axq_lock);
1065 1071
1066 if (bf_isampdu(bf)) 1072 if (bf_isampdu(bf))
1067 ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0); 1073 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0);
1068 else 1074 else
1069 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 1075 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
1070 } 1076 }
1071 1077
1072 spin_lock_bh(&txq->axq_lock); 1078 spin_lock_bh(&txq->axq_lock);
@@ -1568,12 +1574,12 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1568 1574
1569 tx_info->pad[0] = 0; 1575 tx_info->pad[0] = 0;
1570 switch (txctl->frame_type) { 1576 switch (txctl->frame_type) {
1571 case ATH9K_NOT_INTERNAL: 1577 case ATH9K_IFT_NOT_INTERNAL:
1572 break; 1578 break;
1573 case ATH9K_INT_PAUSE: 1579 case ATH9K_IFT_PAUSE:
1574 tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; 1580 tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE;
1575 /* fall through */ 1581 /* fall through */
1576 case ATH9K_INT_UNPAUSE: 1582 case ATH9K_IFT_UNPAUSE:
1577 tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; 1583 tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL;
1578 break; 1584 break;
1579 } 1585 }
@@ -1852,9 +1858,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1852} 1858}
1853 1859
1854static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 1860static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1855 struct ath_txq *txq, 1861 struct ath_txq *txq, struct list_head *bf_q,
1856 struct list_head *bf_q, 1862 struct ath_tx_status *ts, int txok, int sendbar)
1857 int txok, int sendbar)
1858{ 1863{
1859 struct sk_buff *skb = bf->bf_mpdu; 1864 struct sk_buff *skb = bf->bf_mpdu;
1860 unsigned long flags; 1865 unsigned long flags;
@@ -1872,7 +1877,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1872 1877
1873 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1878 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1874 ath_tx_complete(sc, skb, bf->aphy, tx_flags); 1879 ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1875 ath_debug_stat_tx(sc, txq, bf); 1880 ath_debug_stat_tx(sc, txq, bf, ts);
1876 1881
1877 /* 1882 /*
1878 * Return the list of ath_buf of this mpdu to free queue 1883 * Return the list of ath_buf of this mpdu to free queue
@@ -1883,23 +1888,21 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1883} 1888}
1884 1889
1885static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, 1890static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1886 int txok) 1891 struct ath_tx_status *ts, int txok)
1887{ 1892{
1888 struct ath_buf *bf_last = bf->bf_lastbf;
1889 struct ath_desc *ds = bf_last->bf_desc;
1890 u16 seq_st = 0; 1893 u16 seq_st = 0;
1891 u32 ba[WME_BA_BMP_SIZE >> 5]; 1894 u32 ba[WME_BA_BMP_SIZE >> 5];
1892 int ba_index; 1895 int ba_index;
1893 int nbad = 0; 1896 int nbad = 0;
1894 int isaggr = 0; 1897 int isaggr = 0;
1895 1898
1896 if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) 1899 if (ts->ts_flags == ATH9K_TX_SW_ABORTED)
1897 return 0; 1900 return 0;
1898 1901
1899 isaggr = bf_isaggr(bf); 1902 isaggr = bf_isaggr(bf);
1900 if (isaggr) { 1903 if (isaggr) {
1901 seq_st = ATH_DS_BA_SEQ(ds); 1904 seq_st = ts->ts_seqnum;
1902 memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); 1905 memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
1903 } 1906 }
1904 1907
1905 while (bf) { 1908 while (bf) {
@@ -1913,7 +1916,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1913 return nbad; 1916 return nbad;
1914} 1917}
1915 1918
1916static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 1919static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
1917 int nbad, int txok, bool update_rc) 1920 int nbad, int txok, bool update_rc)
1918{ 1921{
1919 struct sk_buff *skb = bf->bf_mpdu; 1922 struct sk_buff *skb = bf->bf_mpdu;
@@ -1923,24 +1926,24 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
1923 u8 i, tx_rateindex; 1926 u8 i, tx_rateindex;
1924 1927
1925 if (txok) 1928 if (txok)
1926 tx_info->status.ack_signal = ds->ds_txstat.ts_rssi; 1929 tx_info->status.ack_signal = ts->ts_rssi;
1927 1930
1928 tx_rateindex = ds->ds_txstat.ts_rateindex; 1931 tx_rateindex = ts->ts_rateindex;
1929 WARN_ON(tx_rateindex >= hw->max_rates); 1932 WARN_ON(tx_rateindex >= hw->max_rates);
1930 1933
1931 if (update_rc) 1934 if (ts->ts_status & ATH9K_TXERR_FILT)
1932 tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC;
1933 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
1934 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 1935 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1936 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc)
1937 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1935 1938
1936 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && 1939 if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
1937 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { 1940 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
1938 if (ieee80211_is_data(hdr->frame_control)) { 1941 if (ieee80211_is_data(hdr->frame_control)) {
1939 if (ds->ds_txstat.ts_flags & 1942 if (ts->ts_flags &
1940 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) 1943 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN))
1941 tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; 1944 tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN;
1942 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) || 1945 if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
1943 (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)) 1946 (ts->ts_status & ATH9K_TXERR_FIFO))
1944 tx_info->pad[0] |= ATH_TX_INFO_XRETRY; 1947 tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
1945 tx_info->status.ampdu_len = bf->bf_nframes; 1948 tx_info->status.ampdu_len = bf->bf_nframes;
1946 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; 1949 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
@@ -1978,6 +1981,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1978 struct ath_buf *bf, *lastbf, *bf_held = NULL; 1981 struct ath_buf *bf, *lastbf, *bf_held = NULL;
1979 struct list_head bf_head; 1982 struct list_head bf_head;
1980 struct ath_desc *ds; 1983 struct ath_desc *ds;
1984 struct ath_tx_status ts;
1981 int txok; 1985 int txok;
1982 int status; 1986 int status;
1983 1987
@@ -2017,7 +2021,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2017 lastbf = bf->bf_lastbf; 2021 lastbf = bf->bf_lastbf;
2018 ds = lastbf->bf_desc; 2022 ds = lastbf->bf_desc;
2019 2023
2020 status = ath9k_hw_txprocdesc(ah, ds); 2024 memset(&ts, 0, sizeof(ts));
2025 status = ath9k_hw_txprocdesc(ah, ds, &ts);
2021 if (status == -EINPROGRESS) { 2026 if (status == -EINPROGRESS) {
2022 spin_unlock_bh(&txq->axq_lock); 2027 spin_unlock_bh(&txq->axq_lock);
2023 break; 2028 break;
@@ -2028,7 +2033,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2028 * can disable RX. 2033 * can disable RX.
2029 */ 2034 */
2030 if (bf->bf_isnullfunc && 2035 if (bf->bf_isnullfunc &&
2031 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { 2036 (ts.ts_status & ATH9K_TX_ACKED)) {
2032 if ((sc->ps_flags & PS_ENABLED)) 2037 if ((sc->ps_flags & PS_ENABLED))
2033 ath9k_enable_ps(sc); 2038 ath9k_enable_ps(sc);
2034 else 2039 else
@@ -2047,7 +2052,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2047 &txq->axq_q, lastbf->list.prev); 2052 &txq->axq_q, lastbf->list.prev);
2048 2053
2049 txq->axq_depth--; 2054 txq->axq_depth--;
2050 txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK); 2055 txok = !(ts.ts_status & ATH9K_TXERR_MASK);
2051 txq->axq_tx_inprogress = false; 2056 txq->axq_tx_inprogress = false;
2052 spin_unlock_bh(&txq->axq_lock); 2057 spin_unlock_bh(&txq->axq_lock);
2053 2058
@@ -2062,16 +2067,16 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2062 * This frame is sent out as a single frame. 2067 * This frame is sent out as a single frame.
2063 * Use hardware retry status for this frame. 2068 * Use hardware retry status for this frame.
2064 */ 2069 */
2065 bf->bf_retries = ds->ds_txstat.ts_longretry; 2070 bf->bf_retries = ts.ts_longretry;
2066 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) 2071 if (ts.ts_status & ATH9K_TXERR_XRETRY)
2067 bf->bf_state.bf_type |= BUF_XRETRY; 2072 bf->bf_state.bf_type |= BUF_XRETRY;
2068 ath_tx_rc_status(bf, ds, 0, txok, true); 2073 ath_tx_rc_status(bf, &ts, 0, txok, true);
2069 } 2074 }
2070 2075
2071 if (bf_isampdu(bf)) 2076 if (bf_isampdu(bf))
2072 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); 2077 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok);
2073 else 2078 else
2074 ath_tx_complete_buf(sc, bf, txq, &bf_head, txok, 0); 2079 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
2075 2080
2076 ath_wake_mac80211_queue(sc, txq); 2081 ath_wake_mac80211_queue(sc, txq);
2077 2082
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 8263633c003c..873bf526e11f 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -59,6 +59,7 @@ enum ATH_DEBUG {
59 ATH_DBG_PS = 0x00000800, 59 ATH_DBG_PS = 0x00000800,
60 ATH_DBG_HWTIMER = 0x00001000, 60 ATH_DBG_HWTIMER = 0x00001000,
61 ATH_DBG_BTCOEX = 0x00002000, 61 ATH_DBG_BTCOEX = 0x00002000,
62 ATH_DBG_WMI = 0x00004000,
62 ATH_DBG_ANY = 0xffffffff 63 ATH_DBG_ANY = 0xffffffff
63}; 64};
64 65
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index ecc9eb01f4fa..a8f81ea09f14 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -19,8 +19,8 @@
19#include "ath.h" 19#include "ath.h"
20#include "reg.h" 20#include "reg.h"
21 21
22#define REG_READ common->ops->read 22#define REG_READ (common->ops->read)
23#define REG_WRITE common->ops->write 23#define REG_WRITE (common->ops->write)
24 24
25/** 25/**
26 * ath_hw_set_bssid_mask - filter out bssids we listen 26 * ath_hw_set_bssid_mask - filter out bssids we listen
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 04abd1f556b7..d5c23328aef1 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -51,6 +51,7 @@
51 51
52#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \ 52#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \
53 ATH9K_5GHZ_5470_5850 53 ATH9K_5GHZ_5470_5850
54
54/* This one skips what we call "mid band" */ 55/* This one skips what we call "mid band" */
55#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ 56#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
56 ATH9K_5GHZ_5725_5850 57 ATH9K_5GHZ_5725_5850
@@ -361,7 +362,7 @@ EXPORT_SYMBOL(ath_reg_notifier_apply);
361 362
362static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) 363static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
363{ 364{
364 u16 rd = ath_regd_get_eepromRD(reg); 365 u16 rd = ath_regd_get_eepromRD(reg);
365 int i; 366 int i;
366 367
367 if (rd & COUNTRY_ERD_FLAG) { 368 if (rd & COUNTRY_ERD_FLAG) {
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index b8807fb12c92..3a003e6803a5 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -104,6 +104,7 @@
104#define B43_MMIO_MACFILTER_CONTROL 0x420 104#define B43_MMIO_MACFILTER_CONTROL 0x420
105#define B43_MMIO_MACFILTER_DATA 0x422 105#define B43_MMIO_MACFILTER_DATA 0x422
106#define B43_MMIO_RCMTA_COUNT 0x43C 106#define B43_MMIO_RCMTA_COUNT 0x43C
107#define B43_MMIO_PSM_PHY_HDR 0x492
107#define B43_MMIO_RADIO_HWENABLED_LO 0x49A 108#define B43_MMIO_RADIO_HWENABLED_LO 0x49A
108#define B43_MMIO_GPIO_CONTROL 0x49C 109#define B43_MMIO_GPIO_CONTROL 0x49C
109#define B43_MMIO_GPIO_MASK 0x49E 110#define B43_MMIO_GPIO_MASK 0x49E
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 1521b1e78d21..14cf3bd7ea51 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4348,11 +4348,10 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4348 b43_set_phytxctl_defaults(dev); 4348 b43_set_phytxctl_defaults(dev);
4349 4349
4350 /* Minimum Contention Window */ 4350 /* Minimum Contention Window */
4351 if (phy->type == B43_PHYTYPE_B) { 4351 if (phy->type == B43_PHYTYPE_B)
4352 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F); 4352 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F);
4353 } else { 4353 else
4354 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF); 4354 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF);
4355 }
4356 /* Maximum Contention Window */ 4355 /* Maximum Contention Window */
4357 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4356 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4358 4357
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 795bb1e3345d..9e93eb4a17cf 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -72,6 +72,22 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
72 u16 value, u8 core, bool off); 72 u16 value, u8 core, bool off);
73static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, 73static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
74 u16 value, u8 core); 74 u16 value, u8 core);
75static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel);
76
77static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
78{
79 return !chanspec->channel && !chanspec->sideband &&
80 !chanspec->b_width && !chanspec->b_freq;
81}
82
83static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
84 struct b43_chanspec *chanspec2)
85{
86 return (chanspec1->channel == chanspec2->channel &&
87 chanspec1->sideband == chanspec2->sideband &&
88 chanspec1->b_width == chanspec2->b_width &&
89 chanspec1->b_freq == chanspec2->b_freq);
90}
75 91
76void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 92void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
77{//TODO 93{//TODO
@@ -88,34 +104,44 @@ static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
88} 104}
89 105
90static void b43_chantab_radio_upload(struct b43_wldev *dev, 106static void b43_chantab_radio_upload(struct b43_wldev *dev,
91 const struct b43_nphy_channeltab_entry *e) 107 const struct b43_nphy_channeltab_entry_rev2 *e)
92{ 108{
93 b43_radio_write16(dev, B2055_PLL_REF, e->radio_pll_ref); 109 b43_radio_write(dev, B2055_PLL_REF, e->radio_pll_ref);
94 b43_radio_write16(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0); 110 b43_radio_write(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0);
95 b43_radio_write16(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1); 111 b43_radio_write(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1);
96 b43_radio_write16(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail); 112 b43_radio_write(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail);
97 b43_radio_write16(dev, B2055_VCO_CAL1, e->radio_vco_cal1); 113 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
98 b43_radio_write16(dev, B2055_VCO_CAL2, e->radio_vco_cal2); 114
99 b43_radio_write16(dev, B2055_PLL_LFC1, e->radio_pll_lfc1); 115 b43_radio_write(dev, B2055_VCO_CAL1, e->radio_vco_cal1);
100 b43_radio_write16(dev, B2055_PLL_LFR1, e->radio_pll_lfr1); 116 b43_radio_write(dev, B2055_VCO_CAL2, e->radio_vco_cal2);
101 b43_radio_write16(dev, B2055_PLL_LFC2, e->radio_pll_lfc2); 117 b43_radio_write(dev, B2055_PLL_LFC1, e->radio_pll_lfc1);
102 b43_radio_write16(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf); 118 b43_radio_write(dev, B2055_PLL_LFR1, e->radio_pll_lfr1);
103 b43_radio_write16(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1); 119 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
104 b43_radio_write16(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2); 120
105 b43_radio_write16(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune); 121 b43_radio_write(dev, B2055_PLL_LFC2, e->radio_pll_lfc2);
106 b43_radio_write16(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune); 122 b43_radio_write(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf);
107 b43_radio_write16(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1); 123 b43_radio_write(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1);
108 b43_radio_write16(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn); 124 b43_radio_write(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2);
109 b43_radio_write16(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim); 125 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
110 b43_radio_write16(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune); 126
111 b43_radio_write16(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune); 127 b43_radio_write(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune);
112 b43_radio_write16(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1); 128 b43_radio_write(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune);
113 b43_radio_write16(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn); 129 b43_radio_write(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1);
114 b43_radio_write16(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); 130 b43_radio_write(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn);
131 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
132
133 b43_radio_write(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim);
134 b43_radio_write(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune);
135 b43_radio_write(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune);
136 b43_radio_write(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1);
137 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
138
139 b43_radio_write(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn);
140 b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
115} 141}
116 142
117static void b43_chantab_phy_upload(struct b43_wldev *dev, 143static void b43_chantab_phy_upload(struct b43_wldev *dev,
118 const struct b43_nphy_channeltab_entry *e) 144 const struct b43_phy_n_sfo_cfg *e)
119{ 145{
120 b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a); 146 b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a);
121 b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2); 147 b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2);
@@ -130,34 +156,20 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
130 //TODO 156 //TODO
131} 157}
132 158
133/* Tune the hardware to a new channel. */
134static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
135{
136 const struct b43_nphy_channeltab_entry *tabent;
137 159
138 tabent = b43_nphy_get_chantabent(dev, channel); 160/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */
139 if (!tabent) 161static void b43_radio_2055_setup(struct b43_wldev *dev,
140 return -ESRCH; 162 const struct b43_nphy_channeltab_entry_rev2 *e)
163{
164 B43_WARN_ON(dev->phy.rev >= 3);
141 165
142 //FIXME enable/disable band select upper20 in RXCTL 166 b43_chantab_radio_upload(dev, e);
143 if (0 /*FIXME 5Ghz*/)
144 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x20);
145 else
146 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x50);
147 b43_chantab_radio_upload(dev, tabent);
148 udelay(50); 167 udelay(50);
149 b43_radio_write16(dev, B2055_VCO_CAL10, 5); 168 b43_radio_write(dev, B2055_VCO_CAL10, 0x05);
150 b43_radio_write16(dev, B2055_VCO_CAL10, 45); 169 b43_radio_write(dev, B2055_VCO_CAL10, 0x45);
151 b43_radio_write16(dev, B2055_VCO_CAL10, 65); 170 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
171 b43_radio_write(dev, B2055_VCO_CAL10, 0x65);
152 udelay(300); 172 udelay(300);
153 if (0 /*FIXME 5Ghz*/)
154 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
155 else
156 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
157 b43_chantab_phy_upload(dev, tabent);
158 b43_nphy_tx_power_fix(dev);
159
160 return 0;
161} 173}
162 174
163static void b43_radio_init2055_pre(struct b43_wldev *dev) 175static void b43_radio_init2055_pre(struct b43_wldev *dev)
@@ -173,52 +185,64 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev)
173 185
174static void b43_radio_init2055_post(struct b43_wldev *dev) 186static void b43_radio_init2055_post(struct b43_wldev *dev)
175{ 187{
188 struct b43_phy_n *nphy = dev->phy.n;
176 struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 189 struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
177 struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); 190 struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo);
178 int i; 191 int i;
179 u16 val; 192 u16 val;
193 bool workaround = false;
194
195 if (sprom->revision < 4)
196 workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM ||
197 binfo->type != 0x46D ||
198 binfo->rev < 0x41);
199 else
200 workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0);
180 201
181 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); 202 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
182 msleep(1); 203 if (workaround) {
183 if ((sprom->revision != 4) || 204 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
184 !(sprom->boardflags_hi & B43_BFH_RSSIINV)) { 205 b43_radio_mask(dev, B2055_C2_RX_BB_REG, 0x7F);
185 if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) ||
186 (binfo->type != 0x46D) ||
187 (binfo->rev < 0x41)) {
188 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
189 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
190 msleep(1);
191 }
192 } 206 }
193 b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0x3F, 0x2C); 207 b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C);
194 msleep(1); 208 b43_radio_write(dev, B2055_CAL_MISC, 0x3C);
195 b43_radio_write16(dev, B2055_CAL_MISC, 0x3C);
196 msleep(1);
197 b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE); 209 b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE);
198 msleep(1);
199 b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80); 210 b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80);
200 msleep(1);
201 b43_radio_set(dev, B2055_CAL_MISC, 0x1); 211 b43_radio_set(dev, B2055_CAL_MISC, 0x1);
202 msleep(1); 212 msleep(1);
203 b43_radio_set(dev, B2055_CAL_MISC, 0x40); 213 b43_radio_set(dev, B2055_CAL_MISC, 0x40);
204 msleep(1); 214 for (i = 0; i < 200; i++) {
205 for (i = 0; i < 100; i++) { 215 val = b43_radio_read(dev, B2055_CAL_COUT2);
206 val = b43_radio_read16(dev, B2055_CAL_COUT2); 216 if (val & 0x80) {
207 if (val & 0x80) 217 i = 0;
208 break; 218 break;
219 }
209 udelay(10); 220 udelay(10);
210 } 221 }
211 msleep(1); 222 if (i)
223 b43err(dev->wl, "radio post init timeout\n");
212 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); 224 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
213 msleep(1);
214 nphy_channel_switch(dev, dev->phy.channel); 225 nphy_channel_switch(dev, dev->phy.channel);
215 b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9); 226 b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9);
216 b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9); 227 b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9);
217 b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83); 228 b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
218 b43_radio_write16(dev, B2055_C2_RX_BB_MIDACHP, 0x83); 229 b43_radio_write(dev, B2055_C2_RX_BB_MIDACHP, 0x83);
230 b43_radio_maskset(dev, B2055_C1_LNA_GAINBST, 0xFFF8, 0x6);
231 b43_radio_maskset(dev, B2055_C2_LNA_GAINBST, 0xFFF8, 0x6);
232 if (!nphy->gain_boost) {
233 b43_radio_set(dev, B2055_C1_RX_RFSPC1, 0x2);
234 b43_radio_set(dev, B2055_C2_RX_RFSPC1, 0x2);
235 } else {
236 b43_radio_mask(dev, B2055_C1_RX_RFSPC1, 0xFFFD);
237 b43_radio_mask(dev, B2055_C2_RX_RFSPC1, 0xFFFD);
238 }
239 udelay(2);
219} 240}
220 241
221/* Initialize a Broadcom 2055 N-radio */ 242/*
243 * Initialize a Broadcom 2055 N-radio
244 * http://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init
245 */
222static void b43_radio_init2055(struct b43_wldev *dev) 246static void b43_radio_init2055(struct b43_wldev *dev)
223{ 247{
224 b43_radio_init2055_pre(dev); 248 b43_radio_init2055_pre(dev);
@@ -229,16 +253,15 @@ static void b43_radio_init2055(struct b43_wldev *dev)
229 b43_radio_init2055_post(dev); 253 b43_radio_init2055_post(dev);
230} 254}
231 255
232void b43_nphy_radio_turn_on(struct b43_wldev *dev) 256/*
257 * Initialize a Broadcom 2056 N-radio
258 * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init
259 */
260static void b43_radio_init2056(struct b43_wldev *dev)
233{ 261{
234 b43_radio_init2055(dev); 262 /* TODO */
235} 263}
236 264
237void b43_nphy_radio_turn_off(struct b43_wldev *dev)
238{
239 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
240 ~B43_NPHY_RFCTL_CMD_EN);
241}
242 265
243/* 266/*
244 * Upload the N-PHY tables. 267 * Upload the N-PHY tables.
@@ -646,6 +669,41 @@ static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
646 clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES); 669 clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES);
647} 670}
648 671
672/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
673static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
674{
675 if (dev->phy.rev >= 3) {
676 if (!init)
677 return;
678 if (0 /* FIXME */) {
679 b43_ntab_write(dev, B43_NTAB16(9, 2), 0x211);
680 b43_ntab_write(dev, B43_NTAB16(9, 3), 0x222);
681 b43_ntab_write(dev, B43_NTAB16(9, 8), 0x144);
682 b43_ntab_write(dev, B43_NTAB16(9, 12), 0x188);
683 }
684 } else {
685 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
686 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
687
688 ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00,
689 0xFC00);
690 b43_write32(dev, B43_MMIO_MACCTL,
691 b43_read32(dev, B43_MMIO_MACCTL) &
692 ~B43_MACCTL_GPOUTSMSK);
693 b43_write16(dev, B43_MMIO_GPIO_MASK,
694 b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00);
695 b43_write16(dev, B43_MMIO_GPIO_CONTROL,
696 b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00);
697
698 if (init) {
699 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
700 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
701 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
702 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
703 }
704 }
705}
706
649/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ 707/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
650static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) 708static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
651{ 709{
@@ -722,7 +780,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
722{ 780{
723 struct b43_phy_n *nphy = dev->phy.n; 781 struct b43_phy_n *nphy = dev->phy.n;
724 782
725 unsigned int channel; 783 u8 channel = nphy->radio_chanspec.channel;
726 int tone[2] = { 57, 58 }; 784 int tone[2] = { 57, 58 };
727 u32 noise[2] = { 0x3FF, 0x3FF }; 785 u32 noise[2] = { 0x3FF, 0x3FF };
728 786
@@ -731,8 +789,6 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
731 if (nphy->hang_avoid) 789 if (nphy->hang_avoid)
732 b43_nphy_stay_in_carrier_search(dev, 1); 790 b43_nphy_stay_in_carrier_search(dev, 1);
733 791
734 /* FIXME: channel = radio_chanspec */
735
736 if (nphy->gband_spurwar_en) { 792 if (nphy->gband_spurwar_en) {
737 /* TODO: N PHY Adjust Analog Pfbw (7) */ 793 /* TODO: N PHY Adjust Analog Pfbw (7) */
738 if (channel == 11 && dev->phy.is_40mhz) 794 if (channel == 11 && dev->phy.is_40mhz)
@@ -778,6 +834,62 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
778 b43_nphy_stay_in_carrier_search(dev, 0); 834 b43_nphy_stay_in_carrier_search(dev, 0);
779} 835}
780 836
837/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
838static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
839{
840 struct b43_phy_n *nphy = dev->phy.n;
841
842 u8 i;
843 s16 tmp;
844 u16 data[4];
845 s16 gain[2];
846 u16 minmax[2];
847 u16 lna_gain[4] = { -2, 10, 19, 25 };
848
849 if (nphy->hang_avoid)
850 b43_nphy_stay_in_carrier_search(dev, 1);
851
852 if (nphy->gain_boost) {
853 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
854 gain[0] = 6;
855 gain[1] = 6;
856 } else {
857 tmp = 40370 - 315 * nphy->radio_chanspec.channel;
858 gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
859 tmp = 23242 - 224 * nphy->radio_chanspec.channel;
860 gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
861 }
862 } else {
863 gain[0] = 0;
864 gain[1] = 0;
865 }
866
867 for (i = 0; i < 2; i++) {
868 if (nphy->elna_gain_config) {
869 data[0] = 19 + gain[i];
870 data[1] = 25 + gain[i];
871 data[2] = 25 + gain[i];
872 data[3] = 25 + gain[i];
873 } else {
874 data[0] = lna_gain[0] + gain[i];
875 data[1] = lna_gain[1] + gain[i];
876 data[2] = lna_gain[2] + gain[i];
877 data[3] = lna_gain[3] + gain[i];
878 }
879 b43_ntab_write_bulk(dev, B43_NTAB16(10, 8), 4, data);
880
881 minmax[i] = 23 + gain[i];
882 }
883
884 b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, ~B43_NPHY_C1_MINGAIN,
885 minmax[0] << B43_NPHY_C1_MINGAIN_SHIFT);
886 b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, ~B43_NPHY_C2_MINGAIN,
887 minmax[1] << B43_NPHY_C2_MINGAIN_SHIFT);
888
889 if (nphy->hang_avoid)
890 b43_nphy_stay_in_carrier_search(dev, 0);
891}
892
781/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ 893/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
782static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) 894static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
783{ 895{
@@ -862,7 +974,7 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
862 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 974 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
863 (code << 8 | 0x7C)); 975 (code << 8 | 0x7C));
864 976
865 /* TODO: b43_nphy_adjust_lna_gain_table(dev); */ 977 b43_nphy_adjust_lna_gain_table(dev);
866 978
867 if (nphy->elna_gain_config) { 979 if (nphy->elna_gain_config) {
868 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); 980 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808);
@@ -1969,12 +2081,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
1969 u16 *rssical_phy_regs = NULL; 2081 u16 *rssical_phy_regs = NULL;
1970 2082
1971 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2083 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1972 if (!nphy->rssical_chanspec_2G) 2084 if (b43_empty_chanspec(&nphy->rssical_chanspec_2G))
1973 return; 2085 return;
1974 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; 2086 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
1975 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; 2087 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
1976 } else { 2088 } else {
1977 if (!nphy->rssical_chanspec_5G) 2089 if (b43_empty_chanspec(&nphy->rssical_chanspec_5G))
1978 return; 2090 return;
1979 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; 2091 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
1980 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; 2092 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
@@ -2394,7 +2506,7 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
2394 2506
2395 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; 2507 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2396 u16 *txcal_radio_regs = NULL; 2508 u16 *txcal_radio_regs = NULL;
2397 u8 *iqcal_chanspec; 2509 struct b43_chanspec *iqcal_chanspec;
2398 u16 *table = NULL; 2510 u16 *table = NULL;
2399 2511
2400 if (nphy->hang_avoid) 2512 if (nphy->hang_avoid)
@@ -2450,12 +2562,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
2450 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; 2562 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2451 2563
2452 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2564 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2453 if (nphy->iqcal_chanspec_2G == 0) 2565 if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G))
2454 return; 2566 return;
2455 table = nphy->cal_cache.txcal_coeffs_2G; 2567 table = nphy->cal_cache.txcal_coeffs_2G;
2456 loft = &nphy->cal_cache.txcal_coeffs_2G[5]; 2568 loft = &nphy->cal_cache.txcal_coeffs_2G[5];
2457 } else { 2569 } else {
2458 if (nphy->iqcal_chanspec_5G == 0) 2570 if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G))
2459 return; 2571 return;
2460 table = nphy->cal_cache.txcal_coeffs_5G; 2572 table = nphy->cal_cache.txcal_coeffs_5G;
2461 loft = &nphy->cal_cache.txcal_coeffs_5G[5]; 2573 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
@@ -2688,7 +2800,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2688 } 2800 }
2689 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, 2801 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
2690 buffer); 2802 buffer);
2691 b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2, 2803 b43_ntab_read_bulk(dev, B43_NTAB16(15, 101), 2,
2692 buffer); 2804 buffer);
2693 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, 2805 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
2694 buffer); 2806 buffer);
@@ -2700,8 +2812,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2700 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, 2812 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
2701 nphy->txiqlocal_bestc); 2813 nphy->txiqlocal_bestc);
2702 nphy->txiqlocal_coeffsvalid = true; 2814 nphy->txiqlocal_coeffsvalid = true;
2703 /* TODO: Set nphy->txiqlocal_chanspec to 2815 nphy->txiqlocal_chanspec = nphy->radio_chanspec;
2704 the current channel */
2705 } else { 2816 } else {
2706 length = 11; 2817 length = 11;
2707 if (dev->phy.rev < 3) 2818 if (dev->phy.rev < 3)
@@ -2736,7 +2847,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
2736 u16 buffer[7]; 2847 u16 buffer[7];
2737 bool equal = true; 2848 bool equal = true;
2738 2849
2739 if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */) 2850 if (!nphy->txiqlocal_coeffsvalid ||
2851 b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec))
2740 return; 2852 return;
2741 2853
2742 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); 2854 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -3091,9 +3203,11 @@ int b43_phy_initn(struct b43_wldev *dev)
3091 do_rssi_cal = false; 3203 do_rssi_cal = false;
3092 if (phy->rev >= 3) { 3204 if (phy->rev >= 3) {
3093 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3205 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3094 do_rssi_cal = (nphy->rssical_chanspec_2G == 0); 3206 do_rssi_cal =
3207 b43_empty_chanspec(&nphy->rssical_chanspec_2G);
3095 else 3208 else
3096 do_rssi_cal = (nphy->rssical_chanspec_5G == 0); 3209 do_rssi_cal =
3210 b43_empty_chanspec(&nphy->rssical_chanspec_5G);
3097 3211
3098 if (do_rssi_cal) 3212 if (do_rssi_cal)
3099 b43_nphy_rssi_cal(dev); 3213 b43_nphy_rssi_cal(dev);
@@ -3105,9 +3219,9 @@ int b43_phy_initn(struct b43_wldev *dev)
3105 3219
3106 if (!((nphy->measure_hold & 0x6) != 0)) { 3220 if (!((nphy->measure_hold & 0x6) != 0)) {
3107 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3221 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3108 do_cal = (nphy->iqcal_chanspec_2G == 0); 3222 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G);
3109 else 3223 else
3110 do_cal = (nphy->iqcal_chanspec_5G == 0); 3224 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G);
3111 3225
3112 if (nphy->mute) 3226 if (nphy->mute)
3113 do_cal = false; 3227 do_cal = false;
@@ -3116,7 +3230,7 @@ int b43_phy_initn(struct b43_wldev *dev)
3116 target = b43_nphy_get_tx_gains(dev); 3230 target = b43_nphy_get_tx_gains(dev);
3117 3231
3118 if (nphy->antsel_type == 2) 3232 if (nphy->antsel_type == 2)
3119 ;/*TODO NPHY Superswitch Init with argument 1*/ 3233 b43_nphy_superswitch_init(dev, true);
3120 if (nphy->perical != 2) { 3234 if (nphy->perical != 2) {
3121 b43_nphy_rssi_cal(dev); 3235 b43_nphy_rssi_cal(dev);
3122 if (phy->rev >= 3) { 3236 if (phy->rev >= 3) {
@@ -3154,6 +3268,133 @@ int b43_phy_initn(struct b43_wldev *dev)
3154 return 0; 3268 return 0;
3155} 3269}
3156 3270
3271/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
3272static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
3273 const struct b43_phy_n_sfo_cfg *e,
3274 struct b43_chanspec chanspec)
3275{
3276 struct b43_phy *phy = &dev->phy;
3277 struct b43_phy_n *nphy = dev->phy.n;
3278
3279 u16 tmp;
3280 u32 tmp32;
3281
3282 tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
3283 if (chanspec.b_freq == 1 && tmp == 0) {
3284 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3285 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
3286 b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
3287 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
3288 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
3289 } else if (chanspec.b_freq == 1) {
3290 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
3291 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3292 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
3293 b43_phy_mask(dev, B43_PHY_B_BBCFG, (u16)~0xC000);
3294 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
3295 }
3296
3297 b43_chantab_phy_upload(dev, e);
3298
3299 tmp = chanspec.channel;
3300 if (chanspec.b_freq == 1)
3301 tmp |= 0x0100;
3302 if (chanspec.b_width == 3)
3303 tmp |= 0x0200;
3304 b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp);
3305
3306 if (nphy->radio_chanspec.channel == 14) {
3307 b43_nphy_classifier(dev, 2, 0);
3308 b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
3309 } else {
3310 b43_nphy_classifier(dev, 2, 2);
3311 if (chanspec.b_freq == 2)
3312 b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
3313 }
3314
3315 if (nphy->txpwrctrl)
3316 b43_nphy_tx_power_fix(dev);
3317
3318 if (dev->phy.rev < 3)
3319 b43_nphy_adjust_lna_gain_table(dev);
3320
3321 b43_nphy_tx_lp_fbw(dev);
3322
3323 if (dev->phy.rev >= 3 && 0) {
3324 /* TODO */
3325 }
3326
3327 b43_phy_write(dev, B43_NPHY_NDATAT_DUP40, 0x3830);
3328
3329 if (phy->rev >= 3)
3330 b43_nphy_spur_workaround(dev);
3331}
3332
3333/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
3334static int b43_nphy_set_chanspec(struct b43_wldev *dev,
3335 struct b43_chanspec chanspec)
3336{
3337 struct b43_phy_n *nphy = dev->phy.n;
3338
3339 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
3340 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
3341
3342 u8 tmp;
3343 u8 channel = chanspec.channel;
3344
3345 if (dev->phy.rev >= 3) {
3346 /* TODO */
3347 tabent_r3 = NULL;
3348 if (!tabent_r3)
3349 return -ESRCH;
3350 } else {
3351 tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel);
3352 if (!tabent_r2)
3353 return -ESRCH;
3354 }
3355
3356 nphy->radio_chanspec = chanspec;
3357
3358 if (chanspec.b_width != nphy->b_width)
3359 ; /* TODO: BMAC BW Set (chanspec.b_width) */
3360
3361 /* TODO: use defines */
3362 if (chanspec.b_width == 3) {
3363 if (chanspec.sideband == 2)
3364 b43_phy_set(dev, B43_NPHY_RXCTL,
3365 B43_NPHY_RXCTL_BSELU20);
3366 else
3367 b43_phy_mask(dev, B43_NPHY_RXCTL,
3368 ~B43_NPHY_RXCTL_BSELU20);
3369 }
3370
3371 if (dev->phy.rev >= 3) {
3372 tmp = (chanspec.b_freq == 1) ? 4 : 0;
3373 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
3374 /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
3375 b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec);
3376 } else {
3377 tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050;
3378 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
3379 b43_radio_2055_setup(dev, tabent_r2);
3380 b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec);
3381 }
3382
3383 return 0;
3384}
3385
3386/* Tune the hardware to a new channel */
3387static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
3388{
3389 struct b43_phy_n *nphy = dev->phy.n;
3390
3391 struct b43_chanspec chanspec;
3392 chanspec = nphy->radio_chanspec;
3393 chanspec.channel = channel;
3394
3395 return b43_nphy_set_chanspec(dev, chanspec);
3396}
3397
3157static int b43_nphy_op_allocate(struct b43_wldev *dev) 3398static int b43_nphy_op_allocate(struct b43_wldev *dev)
3158{ 3399{
3159 struct b43_phy_n *nphy; 3400 struct b43_phy_n *nphy;
@@ -3242,9 +3483,43 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
3242 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); 3483 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
3243} 3484}
3244 3485
3486/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
3245static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, 3487static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
3246 bool blocked) 3488 bool blocked)
3247{//TODO 3489{
3490 struct b43_phy_n *nphy = dev->phy.n;
3491
3492 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
3493 b43err(dev->wl, "MAC not suspended\n");
3494
3495 if (blocked) {
3496 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3497 ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3498 if (dev->phy.rev >= 3) {
3499 b43_radio_mask(dev, 0x09, ~0x2);
3500
3501 b43_radio_write(dev, 0x204D, 0);
3502 b43_radio_write(dev, 0x2053, 0);
3503 b43_radio_write(dev, 0x2058, 0);
3504 b43_radio_write(dev, 0x205E, 0);
3505 b43_radio_mask(dev, 0x2062, ~0xF0);
3506 b43_radio_write(dev, 0x2064, 0);
3507
3508 b43_radio_write(dev, 0x304D, 0);
3509 b43_radio_write(dev, 0x3053, 0);
3510 b43_radio_write(dev, 0x3058, 0);
3511 b43_radio_write(dev, 0x305E, 0);
3512 b43_radio_mask(dev, 0x3062, ~0xF0);
3513 b43_radio_write(dev, 0x3064, 0);
3514 }
3515 } else {
3516 if (dev->phy.rev >= 3) {
3517 b43_radio_init2056(dev);
3518 b43_nphy_set_chanspec(dev, nphy->radio_chanspec);
3519 } else {
3520 b43_radio_init2055(dev);
3521 }
3522 }
3248} 3523}
3249 3524
3250static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) 3525static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 403aad3f894f..8b6d570dd0aa 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -711,6 +711,8 @@
711#define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ 711#define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */
712#define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ 712#define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */
713 713
714#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
715#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
714 716
715 717
716/* Broadcom 2055 radio registers */ 718/* Broadcom 2055 radio registers */
@@ -924,6 +926,13 @@
924 926
925struct b43_wldev; 927struct b43_wldev;
926 928
929struct b43_chanspec {
930 u8 channel;
931 u8 sideband;
932 u8 b_width;
933 u8 b_freq;
934};
935
927struct b43_phy_n_iq_comp { 936struct b43_phy_n_iq_comp {
928 s16 a0; 937 s16 a0;
929 s16 b0; 938 s16 b0;
@@ -975,7 +984,8 @@ struct b43_phy_n {
975 u16 papd_epsilon_offset[2]; 984 u16 papd_epsilon_offset[2];
976 s32 preamble_override; 985 s32 preamble_override;
977 u32 bb_mult_save; 986 u32 bb_mult_save;
978 u16 radio_chanspec; 987 u8 b_width;
988 struct b43_chanspec radio_chanspec;
979 989
980 bool gain_boost; 990 bool gain_boost;
981 bool elna_gain_config; 991 bool elna_gain_config;
@@ -991,6 +1001,7 @@ struct b43_phy_n {
991 u16 txiqlocal_bestc[11]; 1001 u16 txiqlocal_bestc[11];
992 bool txiqlocal_coeffsvalid; 1002 bool txiqlocal_coeffsvalid;
993 struct b43_phy_n_txpwrindex txpwrindex[2]; 1003 struct b43_phy_n_txpwrindex txpwrindex[2];
1004 struct b43_chanspec txiqlocal_chanspec;
994 1005
995 u8 txrx_chain; 1006 u8 txrx_chain;
996 u16 tx_rx_cal_phy_saveregs[11]; 1007 u16 tx_rx_cal_phy_saveregs[11];
@@ -1006,12 +1017,12 @@ struct b43_phy_n {
1006 bool gband_spurwar_en; 1017 bool gband_spurwar_en;
1007 1018
1008 bool ipa2g_on; 1019 bool ipa2g_on;
1009 u8 iqcal_chanspec_2G; 1020 struct b43_chanspec iqcal_chanspec_2G;
1010 u8 rssical_chanspec_2G; 1021 struct b43_chanspec rssical_chanspec_2G;
1011 1022
1012 bool ipa5g_on; 1023 bool ipa5g_on;
1013 u8 iqcal_chanspec_5G; 1024 struct b43_chanspec iqcal_chanspec_5G;
1014 u8 rssical_chanspec_5G; 1025 struct b43_chanspec rssical_chanspec_5G;
1015 1026
1016 struct b43_phy_n_rssical_cache rssical_cache; 1027 struct b43_phy_n_rssical_cache rssical_cache;
1017 struct b43_phy_n_cal_cache cal_cache; 1028 struct b43_phy_n_cal_cache cal_cache;
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index a00d509150f7..d96e870ab8fe 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -318,14 +318,14 @@ void b2055_upload_inittab(struct b43_wldev *dev,
318 .radio_c2_tx_mxbgtrim = r21 318 .radio_c2_tx_mxbgtrim = r21
319 319
320#define PHYREGS(r0, r1, r2, r3, r4, r5) \ 320#define PHYREGS(r0, r1, r2, r3, r4, r5) \
321 .phy_bw1a = r0, \ 321 .phy_regs.phy_bw1a = r0, \
322 .phy_bw2 = r1, \ 322 .phy_regs.phy_bw2 = r1, \
323 .phy_bw3 = r2, \ 323 .phy_regs.phy_bw3 = r2, \
324 .phy_bw4 = r3, \ 324 .phy_regs.phy_bw4 = r3, \
325 .phy_bw5 = r4, \ 325 .phy_regs.phy_bw5 = r4, \
326 .phy_bw6 = r5 326 .phy_regs.phy_bw6 = r5
327 327
328static const struct b43_nphy_channeltab_entry b43_nphy_channeltab[] = { 328static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = {
329 { .channel = 184, 329 { .channel = 184,
330 .freq = 4920, /* MHz */ 330 .freq = 4920, /* MHz */
331 .unk2 = 3280, 331 .unk2 = 3280,
@@ -1320,10 +1320,10 @@ static const struct b43_nphy_channeltab_entry b43_nphy_channeltab[] = {
1320 }, 1320 },
1321}; 1321};
1322 1322
1323const struct b43_nphy_channeltab_entry * 1323const struct b43_nphy_channeltab_entry_rev2 *
1324b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel) 1324b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
1325{ 1325{
1326 const struct b43_nphy_channeltab_entry *e; 1326 const struct b43_nphy_channeltab_entry_rev2 *e;
1327 unsigned int i; 1327 unsigned int i;
1328 1328
1329 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) { 1329 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) {
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 9c1c6ecd3672..8fc1da9f8fe5 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -4,9 +4,22 @@
4#include <linux/types.h> 4#include <linux/types.h>
5 5
6 6
7struct b43_nphy_channeltab_entry { 7struct b43_phy_n_sfo_cfg {
8 u16 phy_bw1a;
9 u16 phy_bw2;
10 u16 phy_bw3;
11 u16 phy_bw4;
12 u16 phy_bw5;
13 u16 phy_bw6;
14};
15
16struct b43_nphy_channeltab_entry_rev2 {
8 /* The channel number */ 17 /* The channel number */
9 u8 channel; 18 u8 channel;
19 /* The channel frequency in MHz */
20 u16 freq;
21 /* An unknown value */
22 u16 unk2;
10 /* Radio register values on channelswitch */ 23 /* Radio register values on channelswitch */
11 u8 radio_pll_ref; 24 u8 radio_pll_ref;
12 u8 radio_rf_pllmod0; 25 u8 radio_rf_pllmod0;
@@ -31,16 +44,18 @@ struct b43_nphy_channeltab_entry {
31 u8 radio_c2_tx_pgapadtn; 44 u8 radio_c2_tx_pgapadtn;
32 u8 radio_c2_tx_mxbgtrim; 45 u8 radio_c2_tx_mxbgtrim;
33 /* PHY register values on channelswitch */ 46 /* PHY register values on channelswitch */
34 u16 phy_bw1a; 47 struct b43_phy_n_sfo_cfg phy_regs;
35 u16 phy_bw2; 48};
36 u16 phy_bw3; 49
37 u16 phy_bw4; 50struct b43_nphy_channeltab_entry_rev3 {
38 u16 phy_bw5; 51 /* The channel number */
39 u16 phy_bw6; 52 u8 channel;
40 /* The channel frequency in MHz */ 53 /* The channel frequency in MHz */
41 u16 freq; 54 u16 freq;
42 /* An unknown value */ 55 /* Radio register values on channelswitch */
43 u16 unk2; 56 /* TODO */
57 /* PHY register values on channelswitch */
58 struct b43_phy_n_sfo_cfg phy_regs;
44}; 59};
45 60
46 61
@@ -77,8 +92,8 @@ void b2055_upload_inittab(struct b43_wldev *dev,
77 92
78/* Get the NPHY Channel Switch Table entry for a channel number. 93/* Get the NPHY Channel Switch Table entry for a channel number.
79 * Returns NULL on failure to find an entry. */ 94 * Returns NULL on failure to find an entry. */
80const struct b43_nphy_channeltab_entry * 95const struct b43_nphy_channeltab_entry_rev2 *
81b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel); 96b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
82 97
83 98
84/* The N-PHY tables. */ 99/* The N-PHY tables. */
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 9b72c45a7748..2088ac029b35 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -2140,7 +2140,7 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2140 DECLARE_SSID_BUF(ssid); 2140 DECLARE_SSID_BUF(ssid);
2141 2141
2142 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, 2142 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
2143 "disassociated: '%s' %pM \n", 2143 "disassociated: '%s' %pM\n",
2144 print_ssid(ssid, priv->essid, priv->essid_len), 2144 print_ssid(ssid, priv->essid, priv->essid_len),
2145 priv->bssid); 2145 priv->bssid);
2146 2146
@@ -3285,7 +3285,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3285 3285
3286 if (inta & IPW2100_INTA_PARITY_ERROR) { 3286 if (inta & IPW2100_INTA_PARITY_ERROR) {
3287 printk(KERN_ERR DRV_NAME 3287 printk(KERN_ERR DRV_NAME
3288 ": ***** PARITY ERROR INTERRUPT !!!! \n"); 3288 ": ***** PARITY ERROR INTERRUPT !!!!\n");
3289 priv->inta_other++; 3289 priv->inta_other++;
3290 write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR); 3290 write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR);
3291 } 3291 }
@@ -6102,7 +6102,7 @@ static const struct net_device_ops ipw2100_netdev_ops = {
6102 .ndo_validate_addr = eth_validate_addr, 6102 .ndo_validate_addr = eth_validate_addr,
6103}; 6103};
6104 6104
6105/* Look into using netdev destructor to shutdown ieee80211? */ 6105/* Look into using netdev destructor to shutdown libipw? */
6106 6106
6107static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, 6107static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6108 void __iomem * base_addr, 6108 void __iomem * base_addr,
@@ -6112,7 +6112,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6112 struct ipw2100_priv *priv; 6112 struct ipw2100_priv *priv;
6113 struct net_device *dev; 6113 struct net_device *dev;
6114 6114
6115 dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0); 6115 dev = alloc_libipw(sizeof(struct ipw2100_priv), 0);
6116 if (!dev) 6116 if (!dev)
6117 return NULL; 6117 return NULL;
6118 priv = libipw_priv(dev); 6118 priv = libipw_priv(dev);
@@ -6425,7 +6425,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6425 sysfs_remove_group(&pci_dev->dev.kobj, 6425 sysfs_remove_group(&pci_dev->dev.kobj,
6426 &ipw2100_attribute_group); 6426 &ipw2100_attribute_group);
6427 6427
6428 free_ieee80211(dev, 0); 6428 free_libipw(dev, 0);
6429 pci_set_drvdata(pci_dev, NULL); 6429 pci_set_drvdata(pci_dev, NULL);
6430 } 6430 }
6431 6431
@@ -6483,10 +6483,10 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6483 if (dev->base_addr) 6483 if (dev->base_addr)
6484 iounmap((void __iomem *)dev->base_addr); 6484 iounmap((void __iomem *)dev->base_addr);
6485 6485
6486 /* wiphy_unregister needs to be here, before free_ieee80211 */ 6486 /* wiphy_unregister needs to be here, before free_libipw */
6487 wiphy_unregister(priv->ieee->wdev.wiphy); 6487 wiphy_unregister(priv->ieee->wdev.wiphy);
6488 kfree(priv->ieee->bg_band.channels); 6488 kfree(priv->ieee->bg_band.channels);
6489 free_ieee80211(dev, 0); 6489 free_libipw(dev, 0);
6490 } 6490 }
6491 6491
6492 pci_release_regions(pci_dev); 6492 pci_release_regions(pci_dev);
@@ -6753,7 +6753,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6753 err = -EOPNOTSUPP; 6753 err = -EOPNOTSUPP;
6754 goto done; 6754 goto done;
6755 } else { /* Set the channel */ 6755 } else { /* Set the channel */
6756 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 6756 IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);
6757 err = ipw2100_set_channel(priv, fwrq->m, 0); 6757 err = ipw2100_set_channel(priv, fwrq->m, 0);
6758 } 6758 }
6759 6759
@@ -6782,7 +6782,7 @@ static int ipw2100_wx_get_freq(struct net_device *dev,
6782 else 6782 else
6783 wrqu->freq.m = 0; 6783 wrqu->freq.m = 0;
6784 6784
6785 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 6785 IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);
6786 return 0; 6786 return 0;
6787 6787
6788} 6788}
@@ -6794,7 +6794,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
6794 struct ipw2100_priv *priv = libipw_priv(dev); 6794 struct ipw2100_priv *priv = libipw_priv(dev);
6795 int err = 0; 6795 int err = 0;
6796 6796
6797 IPW_DEBUG_WX("SET Mode -> %d \n", wrqu->mode); 6797 IPW_DEBUG_WX("SET Mode -> %d\n", wrqu->mode);
6798 6798
6799 if (wrqu->mode == priv->ieee->iw_mode) 6799 if (wrqu->mode == priv->ieee->iw_mode)
6800 return 0; 6800 return 0;
@@ -7149,7 +7149,7 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
7149 memset(priv->nick, 0, sizeof(priv->nick)); 7149 memset(priv->nick, 0, sizeof(priv->nick));
7150 memcpy(priv->nick, extra, wrqu->data.length); 7150 memcpy(priv->nick, extra, wrqu->data.length);
7151 7151
7152 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick); 7152 IPW_DEBUG_WX("SET Nickname -> %s\n", priv->nick);
7153 7153
7154 return 0; 7154 return 0;
7155} 7155}
@@ -7168,7 +7168,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
7168 memcpy(extra, priv->nick, wrqu->data.length); 7168 memcpy(extra, priv->nick, wrqu->data.length);
7169 wrqu->data.flags = 1; /* active */ 7169 wrqu->data.flags = 1; /* active */
7170 7170
7171 IPW_DEBUG_WX("GET Nickname -> %s \n", extra); 7171 IPW_DEBUG_WX("GET Nickname -> %s\n", extra);
7172 7172
7173 return 0; 7173 return 0;
7174} 7174}
@@ -7207,7 +7207,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
7207 7207
7208 err = ipw2100_set_tx_rates(priv, rate, 0); 7208 err = ipw2100_set_tx_rates(priv, rate, 0);
7209 7209
7210 IPW_DEBUG_WX("SET Rate -> %04X \n", rate); 7210 IPW_DEBUG_WX("SET Rate -> %04X\n", rate);
7211 done: 7211 done:
7212 mutex_unlock(&priv->action_mutex); 7212 mutex_unlock(&priv->action_mutex);
7213 return err; 7213 return err;
@@ -7258,7 +7258,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
7258 wrqu->bitrate.value = 0; 7258 wrqu->bitrate.value = 0;
7259 } 7259 }
7260 7260
7261 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 7261 IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);
7262 7262
7263 done: 7263 done:
7264 mutex_unlock(&priv->action_mutex); 7264 mutex_unlock(&priv->action_mutex);
@@ -7294,7 +7294,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7294 7294
7295 err = ipw2100_set_rts_threshold(priv, value); 7295 err = ipw2100_set_rts_threshold(priv, value);
7296 7296
7297 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); 7297 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X\n", value);
7298 done: 7298 done:
7299 mutex_unlock(&priv->action_mutex); 7299 mutex_unlock(&priv->action_mutex);
7300 return err; 7300 return err;
@@ -7316,7 +7316,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
7316 /* If RTS is set to the default value, then it is disabled */ 7316 /* If RTS is set to the default value, then it is disabled */
7317 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0; 7317 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
7318 7318
7319 IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X \n", wrqu->rts.value); 7319 IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X\n", wrqu->rts.value);
7320 7320
7321 return 0; 7321 return 0;
7322} 7322}
@@ -7355,7 +7355,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7355 7355
7356 err = ipw2100_set_tx_power(priv, value); 7356 err = ipw2100_set_tx_power(priv, value);
7357 7357
7358 IPW_DEBUG_WX("SET TX Power -> %d \n", value); 7358 IPW_DEBUG_WX("SET TX Power -> %d\n", value);
7359 7359
7360 done: 7360 done:
7361 mutex_unlock(&priv->action_mutex); 7361 mutex_unlock(&priv->action_mutex);
@@ -7384,7 +7384,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
7384 7384
7385 wrqu->txpower.flags = IW_TXPOW_DBM; 7385 wrqu->txpower.flags = IW_TXPOW_DBM;
7386 7386
7387 IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->txpower.value); 7387 IPW_DEBUG_WX("GET TX Power -> %d\n", wrqu->txpower.value);
7388 7388
7389 return 0; 7389 return 0;
7390} 7390}
@@ -7414,7 +7414,7 @@ static int ipw2100_wx_set_frag(struct net_device *dev,
7414 priv->frag_threshold = priv->ieee->fts; 7414 priv->frag_threshold = priv->ieee->fts;
7415 } 7415 }
7416 7416
7417 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", priv->ieee->fts); 7417 IPW_DEBUG_WX("SET Frag Threshold -> %d\n", priv->ieee->fts);
7418 7418
7419 return 0; 7419 return 0;
7420} 7420}
@@ -7432,7 +7432,7 @@ static int ipw2100_wx_get_frag(struct net_device *dev,
7432 wrqu->frag.fixed = 0; /* no auto select */ 7432 wrqu->frag.fixed = 0; /* no auto select */
7433 wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0; 7433 wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0;
7434 7434
7435 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 7435 IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);
7436 7436
7437 return 0; 7437 return 0;
7438} 7438}
@@ -7458,14 +7458,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7458 7458
7459 if (wrqu->retry.flags & IW_RETRY_SHORT) { 7459 if (wrqu->retry.flags & IW_RETRY_SHORT) {
7460 err = ipw2100_set_short_retry(priv, wrqu->retry.value); 7460 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7461 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", 7461 IPW_DEBUG_WX("SET Short Retry Limit -> %d\n",
7462 wrqu->retry.value); 7462 wrqu->retry.value);
7463 goto done; 7463 goto done;
7464 } 7464 }
7465 7465
7466 if (wrqu->retry.flags & IW_RETRY_LONG) { 7466 if (wrqu->retry.flags & IW_RETRY_LONG) {
7467 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7467 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7468 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", 7468 IPW_DEBUG_WX("SET Long Retry Limit -> %d\n",
7469 wrqu->retry.value); 7469 wrqu->retry.value);
7470 goto done; 7470 goto done;
7471 } 7471 }
@@ -7474,7 +7474,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7474 if (!err) 7474 if (!err)
7475 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7475 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7476 7476
7477 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); 7477 IPW_DEBUG_WX("SET Both Retry Limits -> %d\n", wrqu->retry.value);
7478 7478
7479 done: 7479 done:
7480 mutex_unlock(&priv->action_mutex); 7480 mutex_unlock(&priv->action_mutex);
@@ -7508,7 +7508,7 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
7508 wrqu->retry.value = priv->short_retry_limit; 7508 wrqu->retry.value = priv->short_retry_limit;
7509 } 7509 }
7510 7510
7511 IPW_DEBUG_WX("GET Retry -> %d \n", wrqu->retry.value); 7511 IPW_DEBUG_WX("GET Retry -> %d\n", wrqu->retry.value);
7512 7512
7513 return 0; 7513 return 0;
7514} 7514}
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 5c7aa1b1eb56..9e2ae8f3ecb0 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -458,7 +458,7 @@ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
458{ 458{
459 u32 word; 459 u32 word;
460 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK); 460 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
461 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg); 461 IPW_DEBUG_IO(" reg = 0x%8X :\n", reg);
462 word = _ipw_read32(priv, IPW_INDIRECT_DATA); 462 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
463 return (word >> ((reg & 0x3) * 8)) & 0xff; 463 return (word >> ((reg & 0x3) * 8)) & 0xff;
464} 464}
@@ -472,7 +472,7 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
472 472
473 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg); 473 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
474 value = _ipw_read32(priv, IPW_INDIRECT_DATA); 474 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
475 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value); 475 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x\n", reg, value);
476 return value; 476 return value;
477} 477}
478 478
@@ -2348,16 +2348,25 @@ static void ipw_bg_adapter_restart(struct work_struct *work)
2348 mutex_unlock(&priv->mutex); 2348 mutex_unlock(&priv->mutex);
2349} 2349}
2350 2350
2351#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) 2351static void ipw_abort_scan(struct ipw_priv *priv);
2352
2353#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
2352 2354
2353static void ipw_scan_check(void *data) 2355static void ipw_scan_check(void *data)
2354{ 2356{
2355 struct ipw_priv *priv = data; 2357 struct ipw_priv *priv = data;
2356 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { 2358
2359 if (priv->status & STATUS_SCAN_ABORTING) {
2357 IPW_DEBUG_SCAN("Scan completion watchdog resetting " 2360 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
2358 "adapter after (%dms).\n", 2361 "adapter after (%dms).\n",
2359 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG)); 2362 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
2360 queue_work(priv->workqueue, &priv->adapter_restart); 2363 queue_work(priv->workqueue, &priv->adapter_restart);
2364 } else if (priv->status & STATUS_SCANNING) {
2365 IPW_DEBUG_SCAN("Scan completion watchdog aborting scan "
2366 "after (%dms).\n",
2367 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
2368 ipw_abort_scan(priv);
2369 queue_delayed_work(priv->workqueue, &priv->scan_check, HZ);
2361 } 2370 }
2362} 2371}
2363 2372
@@ -2738,7 +2747,7 @@ static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
2738static int ipw_fw_dma_enable(struct ipw_priv *priv) 2747static int ipw_fw_dma_enable(struct ipw_priv *priv)
2739{ /* start dma engine but no transfers yet */ 2748{ /* start dma engine but no transfers yet */
2740 2749
2741 IPW_DEBUG_FW(">> : \n"); 2750 IPW_DEBUG_FW(">> :\n");
2742 2751
2743 /* Start the dma */ 2752 /* Start the dma */
2744 ipw_fw_dma_reset_command_blocks(priv); 2753 ipw_fw_dma_reset_command_blocks(priv);
@@ -2746,7 +2755,7 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv)
2746 /* Write CB base address */ 2755 /* Write CB base address */
2747 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL); 2756 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
2748 2757
2749 IPW_DEBUG_FW("<< : \n"); 2758 IPW_DEBUG_FW("<< :\n");
2750 return 0; 2759 return 0;
2751} 2760}
2752 2761
@@ -2761,7 +2770,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
2761 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control); 2770 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
2762 priv->sram_desc.last_cb_index = 0; 2771 priv->sram_desc.last_cb_index = 0;
2763 2772
2764 IPW_DEBUG_FW("<< \n"); 2773 IPW_DEBUG_FW("<<\n");
2765} 2774}
2766 2775
2767static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index, 2776static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
@@ -2812,29 +2821,29 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
2812 2821
2813 IPW_DEBUG_FW(">> :\n"); 2822 IPW_DEBUG_FW(">> :\n");
2814 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB); 2823 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
2815 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address); 2824 IPW_DEBUG_FW_INFO("Current CB is 0x%x\n", address);
2816 2825
2817 /* Read the DMA Controlor register */ 2826 /* Read the DMA Controlor register */
2818 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL); 2827 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
2819 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value); 2828 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x\n", register_value);
2820 2829
2821 /* Print the CB values */ 2830 /* Print the CB values */
2822 cb_fields_address = address; 2831 cb_fields_address = address;
2823 register_value = ipw_read_reg32(priv, cb_fields_address); 2832 register_value = ipw_read_reg32(priv, cb_fields_address);
2824 IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n", register_value); 2833 IPW_DEBUG_FW_INFO("Current CB Control Field is 0x%x\n", register_value);
2825 2834
2826 cb_fields_address += sizeof(u32); 2835 cb_fields_address += sizeof(u32);
2827 register_value = ipw_read_reg32(priv, cb_fields_address); 2836 register_value = ipw_read_reg32(priv, cb_fields_address);
2828 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n", register_value); 2837 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x\n", register_value);
2829 2838
2830 cb_fields_address += sizeof(u32); 2839 cb_fields_address += sizeof(u32);
2831 register_value = ipw_read_reg32(priv, cb_fields_address); 2840 register_value = ipw_read_reg32(priv, cb_fields_address);
2832 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x \n", 2841 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x\n",
2833 register_value); 2842 register_value);
2834 2843
2835 cb_fields_address += sizeof(u32); 2844 cb_fields_address += sizeof(u32);
2836 register_value = ipw_read_reg32(priv, cb_fields_address); 2845 register_value = ipw_read_reg32(priv, cb_fields_address);
2837 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n", register_value); 2846 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x\n", register_value);
2838 2847
2839 IPW_DEBUG_FW(">> :\n"); 2848 IPW_DEBUG_FW(">> :\n");
2840} 2849}
@@ -2850,7 +2859,7 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
2850 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) / 2859 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
2851 sizeof(struct command_block); 2860 sizeof(struct command_block);
2852 2861
2853 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", 2862 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X\n",
2854 current_cb_index, current_cb_address); 2863 current_cb_index, current_cb_address);
2855 2864
2856 IPW_DEBUG_FW(">> :\n"); 2865 IPW_DEBUG_FW(">> :\n");
@@ -2909,7 +2918,7 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
2909 int ret, i; 2918 int ret, i;
2910 u32 size; 2919 u32 size;
2911 2920
2912 IPW_DEBUG_FW(">> \n"); 2921 IPW_DEBUG_FW(">>\n");
2913 IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n", 2922 IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n",
2914 nr, dest_address, len); 2923 nr, dest_address, len);
2915 2924
@@ -2926,7 +2935,7 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
2926 IPW_DEBUG_FW_INFO(": Added new cb\n"); 2935 IPW_DEBUG_FW_INFO(": Added new cb\n");
2927 } 2936 }
2928 2937
2929 IPW_DEBUG_FW("<< \n"); 2938 IPW_DEBUG_FW("<<\n");
2930 return 0; 2939 return 0;
2931} 2940}
2932 2941
@@ -2935,7 +2944,7 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
2935 u32 current_index = 0, previous_index; 2944 u32 current_index = 0, previous_index;
2936 u32 watchdog = 0; 2945 u32 watchdog = 0;
2937 2946
2938 IPW_DEBUG_FW(">> : \n"); 2947 IPW_DEBUG_FW(">> :\n");
2939 2948
2940 current_index = ipw_fw_dma_command_block_index(priv); 2949 current_index = ipw_fw_dma_command_block_index(priv);
2941 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n", 2950 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",
@@ -2964,7 +2973,7 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
2964 ipw_set_bit(priv, IPW_RESET_REG, 2973 ipw_set_bit(priv, IPW_RESET_REG,
2965 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER); 2974 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
2966 2975
2967 IPW_DEBUG_FW("<< dmaWaitSync \n"); 2976 IPW_DEBUG_FW("<< dmaWaitSync\n");
2968 return 0; 2977 return 0;
2969} 2978}
2970 2979
@@ -3025,7 +3034,7 @@ static int ipw_stop_master(struct ipw_priv *priv)
3025{ 3034{
3026 int rc; 3035 int rc;
3027 3036
3028 IPW_DEBUG_TRACE(">> \n"); 3037 IPW_DEBUG_TRACE(">>\n");
3029 /* stop master. typical delay - 0 */ 3038 /* stop master. typical delay - 0 */
3030 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER); 3039 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
3031 3040
@@ -3044,7 +3053,7 @@ static int ipw_stop_master(struct ipw_priv *priv)
3044 3053
3045static void ipw_arc_release(struct ipw_priv *priv) 3054static void ipw_arc_release(struct ipw_priv *priv)
3046{ 3055{
3047 IPW_DEBUG_TRACE(">> \n"); 3056 IPW_DEBUG_TRACE(">>\n");
3048 mdelay(5); 3057 mdelay(5);
3049 3058
3050 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 3059 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
@@ -3066,7 +3075,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
3066 3075
3067 image = (__le16 *) data; 3076 image = (__le16 *) data;
3068 3077
3069 IPW_DEBUG_TRACE(">> \n"); 3078 IPW_DEBUG_TRACE(">>\n");
3070 3079
3071 rc = ipw_stop_master(priv); 3080 rc = ipw_stop_master(priv);
3072 3081
@@ -3180,7 +3189,7 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
3180 void **virts; 3189 void **virts;
3181 dma_addr_t *phys; 3190 dma_addr_t *phys;
3182 3191
3183 IPW_DEBUG_TRACE("<< : \n"); 3192 IPW_DEBUG_TRACE("<< :\n");
3184 3193
3185 virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL, 3194 virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
3186 GFP_KERNEL); 3195 GFP_KERNEL);
@@ -4481,7 +4490,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4481 case CMAS_ASSOCIATED:{ 4490 case CMAS_ASSOCIATED:{
4482 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4491 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4483 IPW_DL_ASSOC, 4492 IPW_DL_ASSOC,
4484 "associated: '%s' %pM \n", 4493 "associated: '%s' %pM\n",
4485 print_ssid(ssid, priv->essid, 4494 print_ssid(ssid, priv->essid,
4486 priv->essid_len), 4495 priv->essid_len),
4487 priv->bssid); 4496 priv->bssid);
@@ -4562,7 +4571,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4562 IPW_DL_ASSOC, 4571 IPW_DL_ASSOC,
4563 "deauthenticated: '%s' " 4572 "deauthenticated: '%s' "
4564 "%pM" 4573 "%pM"
4565 ": (0x%04X) - %s \n", 4574 ": (0x%04X) - %s\n",
4566 print_ssid(ssid, 4575 print_ssid(ssid,
4567 priv-> 4576 priv->
4568 essid, 4577 essid,
@@ -4613,7 +4622,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4613 4622
4614 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4623 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4615 IPW_DL_ASSOC, 4624 IPW_DL_ASSOC,
4616 "disassociated: '%s' %pM \n", 4625 "disassociated: '%s' %pM\n",
4617 print_ssid(ssid, priv->essid, 4626 print_ssid(ssid, priv->essid,
4618 priv->essid_len), 4627 priv->essid_len),
4619 priv->bssid); 4628 priv->bssid);
@@ -4651,7 +4660,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4651 switch (auth->state) { 4660 switch (auth->state) {
4652 case CMAS_AUTHENTICATED: 4661 case CMAS_AUTHENTICATED:
4653 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, 4662 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4654 "authenticated: '%s' %pM \n", 4663 "authenticated: '%s' %pM\n",
4655 print_ssid(ssid, priv->essid, 4664 print_ssid(ssid, priv->essid,
4656 priv->essid_len), 4665 priv->essid_len),
4657 priv->bssid); 4666 priv->bssid);
@@ -6924,7 +6933,7 @@ static u8 ipw_qos_current_mode(struct ipw_priv * priv)
6924 } else { 6933 } else {
6925 mode = priv->ieee->mode; 6934 mode = priv->ieee->mode;
6926 } 6935 }
6927 IPW_DEBUG_QOS("QoS network/card mode %d \n", mode); 6936 IPW_DEBUG_QOS("QoS network/card mode %d\n", mode);
6928 return mode; 6937 return mode;
6929} 6938}
6930 6939
@@ -6964,7 +6973,7 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6964 &def_parameters_OFDM, size); 6973 &def_parameters_OFDM, size);
6965 6974
6966 if ((network->qos_data.active == 1) && (active_network == 1)) { 6975 if ((network->qos_data.active == 1) && (active_network == 1)) {
6967 IPW_DEBUG_QOS("QoS was disabled call qos_activate \n"); 6976 IPW_DEBUG_QOS("QoS was disabled call qos_activate\n");
6968 schedule_work(&priv->qos_activate); 6977 schedule_work(&priv->qos_activate);
6969 } 6978 }
6970 6979
@@ -7541,7 +7550,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
7541 return err; 7550 return err;
7542 } 7551 }
7543 7552
7544 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM \n", 7553 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM\n",
7545 print_ssid(ssid, priv->essid, priv->essid_len), 7554 print_ssid(ssid, priv->essid, priv->essid_len),
7546 priv->bssid); 7555 priv->bssid);
7547 7556
@@ -8792,7 +8801,7 @@ static int ipw_wx_set_freq(struct net_device *dev,
8792 } 8801 }
8793 } 8802 }
8794 8803
8795 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 8804 IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);
8796 mutex_lock(&priv->mutex); 8805 mutex_lock(&priv->mutex);
8797 ret = ipw_set_channel(priv, channel); 8806 ret = ipw_set_channel(priv, channel);
8798 mutex_unlock(&priv->mutex); 8807 mutex_unlock(&priv->mutex);
@@ -8834,7 +8843,7 @@ static int ipw_wx_get_freq(struct net_device *dev,
8834 wrqu->freq.m = 0; 8843 wrqu->freq.m = 0;
8835 8844
8836 mutex_unlock(&priv->mutex); 8845 mutex_unlock(&priv->mutex);
8837 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 8846 IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);
8838 return 0; 8847 return 0;
8839} 8848}
8840 8849
@@ -9229,7 +9238,7 @@ static int ipw_wx_get_sens(struct net_device *dev,
9229 wrqu->sens.value = priv->roaming_threshold; 9238 wrqu->sens.value = priv->roaming_threshold;
9230 mutex_unlock(&priv->mutex); 9239 mutex_unlock(&priv->mutex);
9231 9240
9232 IPW_DEBUG_WX("GET roaming threshold -> %s %d \n", 9241 IPW_DEBUG_WX("GET roaming threshold -> %s %d\n",
9233 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); 9242 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
9234 9243
9235 return 0; 9244 return 0;
@@ -9357,7 +9366,7 @@ static int ipw_wx_get_rate(struct net_device *dev,
9357 wrqu->bitrate.value = priv->last_rate; 9366 wrqu->bitrate.value = priv->last_rate;
9358 wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0; 9367 wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0;
9359 mutex_unlock(&priv->mutex); 9368 mutex_unlock(&priv->mutex);
9360 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 9369 IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);
9361 return 0; 9370 return 0;
9362} 9371}
9363 9372
@@ -9380,7 +9389,7 @@ static int ipw_wx_set_rts(struct net_device *dev,
9380 9389
9381 ipw_send_rts_threshold(priv, priv->rts_threshold); 9390 ipw_send_rts_threshold(priv, priv->rts_threshold);
9382 mutex_unlock(&priv->mutex); 9391 mutex_unlock(&priv->mutex);
9383 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); 9392 IPW_DEBUG_WX("SET RTS Threshold -> %d\n", priv->rts_threshold);
9384 return 0; 9393 return 0;
9385} 9394}
9386 9395
@@ -9394,7 +9403,7 @@ static int ipw_wx_get_rts(struct net_device *dev,
9394 wrqu->rts.fixed = 0; /* no auto select */ 9403 wrqu->rts.fixed = 0; /* no auto select */
9395 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 9404 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
9396 mutex_unlock(&priv->mutex); 9405 mutex_unlock(&priv->mutex);
9397 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); 9406 IPW_DEBUG_WX("GET RTS Threshold -> %d\n", wrqu->rts.value);
9398 return 0; 9407 return 0;
9399} 9408}
9400 9409
@@ -9444,7 +9453,7 @@ static int ipw_wx_get_txpow(struct net_device *dev,
9444 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; 9453 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
9445 mutex_unlock(&priv->mutex); 9454 mutex_unlock(&priv->mutex);
9446 9455
9447 IPW_DEBUG_WX("GET TX Power -> %s %d \n", 9456 IPW_DEBUG_WX("GET TX Power -> %s %d\n",
9448 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); 9457 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
9449 9458
9450 return 0; 9459 return 0;
@@ -9470,7 +9479,7 @@ static int ipw_wx_set_frag(struct net_device *dev,
9470 9479
9471 ipw_send_frag_threshold(priv, wrqu->frag.value); 9480 ipw_send_frag_threshold(priv, wrqu->frag.value);
9472 mutex_unlock(&priv->mutex); 9481 mutex_unlock(&priv->mutex);
9473 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); 9482 IPW_DEBUG_WX("SET Frag Threshold -> %d\n", wrqu->frag.value);
9474 return 0; 9483 return 0;
9475} 9484}
9476 9485
@@ -9484,7 +9493,7 @@ static int ipw_wx_get_frag(struct net_device *dev,
9484 wrqu->frag.fixed = 0; /* no auto select */ 9493 wrqu->frag.fixed = 0; /* no auto select */
9485 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); 9494 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
9486 mutex_unlock(&priv->mutex); 9495 mutex_unlock(&priv->mutex);
9487 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 9496 IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);
9488 9497
9489 return 0; 9498 return 0;
9490} 9499}
@@ -9548,7 +9557,7 @@ static int ipw_wx_get_retry(struct net_device *dev,
9548 } 9557 }
9549 mutex_unlock(&priv->mutex); 9558 mutex_unlock(&priv->mutex);
9550 9559
9551 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value); 9560 IPW_DEBUG_WX("GET retry -> %d\n", wrqu->retry.value);
9552 9561
9553 return 0; 9562 return 0;
9554} 9563}
@@ -9995,49 +10004,48 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9995} 10004}
9996 10005
9997/* Rebase the WE IOCTLs to zero for the handler array */ 10006/* Rebase the WE IOCTLs to zero for the handler array */
9998#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
9999static iw_handler ipw_wx_handlers[] = { 10007static iw_handler ipw_wx_handlers[] = {
10000 IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, 10008 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
10001 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 10009 IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
10002 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 10010 IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
10003 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 10011 IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
10004 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 10012 IW_HANDLER(SIOCGIWMODE, ipw_wx_get_mode),
10005 IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens, 10013 IW_HANDLER(SIOCSIWSENS, ipw_wx_set_sens),
10006 IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens, 10014 IW_HANDLER(SIOCGIWSENS, ipw_wx_get_sens),
10007 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 10015 IW_HANDLER(SIOCGIWRANGE, ipw_wx_get_range),
10008 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 10016 IW_HANDLER(SIOCSIWAP, ipw_wx_set_wap),
10009 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 10017 IW_HANDLER(SIOCGIWAP, ipw_wx_get_wap),
10010 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, 10018 IW_HANDLER(SIOCSIWSCAN, ipw_wx_set_scan),
10011 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, 10019 IW_HANDLER(SIOCGIWSCAN, ipw_wx_get_scan),
10012 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, 10020 IW_HANDLER(SIOCSIWESSID, ipw_wx_set_essid),
10013 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, 10021 IW_HANDLER(SIOCGIWESSID, ipw_wx_get_essid),
10014 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, 10022 IW_HANDLER(SIOCSIWNICKN, ipw_wx_set_nick),
10015 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, 10023 IW_HANDLER(SIOCGIWNICKN, ipw_wx_get_nick),
10016 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, 10024 IW_HANDLER(SIOCSIWRATE, ipw_wx_set_rate),
10017 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, 10025 IW_HANDLER(SIOCGIWRATE, ipw_wx_get_rate),
10018 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, 10026 IW_HANDLER(SIOCSIWRTS, ipw_wx_set_rts),
10019 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, 10027 IW_HANDLER(SIOCGIWRTS, ipw_wx_get_rts),
10020 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, 10028 IW_HANDLER(SIOCSIWFRAG, ipw_wx_set_frag),
10021 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, 10029 IW_HANDLER(SIOCGIWFRAG, ipw_wx_get_frag),
10022 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, 10030 IW_HANDLER(SIOCSIWTXPOW, ipw_wx_set_txpow),
10023 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, 10031 IW_HANDLER(SIOCGIWTXPOW, ipw_wx_get_txpow),
10024 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, 10032 IW_HANDLER(SIOCSIWRETRY, ipw_wx_set_retry),
10025 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, 10033 IW_HANDLER(SIOCGIWRETRY, ipw_wx_get_retry),
10026 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, 10034 IW_HANDLER(SIOCSIWENCODE, ipw_wx_set_encode),
10027 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 10035 IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
10028 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 10036 IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
10029 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 10037 IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
10030 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy, 10038 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
10031 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy, 10039 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
10032 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy, 10040 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
10033 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy, 10041 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
10034 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie, 10042 IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
10035 IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie, 10043 IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
10036 IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme, 10044 IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
10037 IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth, 10045 IW_HANDLER(SIOCSIWAUTH, ipw_wx_set_auth),
10038 IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth, 10046 IW_HANDLER(SIOCGIWAUTH, ipw_wx_get_auth),
10039 IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext, 10047 IW_HANDLER(SIOCSIWENCODEEXT, ipw_wx_set_encodeext),
10040 IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext, 10048 IW_HANDLER(SIOCGIWENCODEEXT, ipw_wx_get_encodeext),
10041}; 10049};
10042 10050
10043enum { 10051enum {
@@ -11666,7 +11674,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
11666 if (priv->prom_net_dev) 11674 if (priv->prom_net_dev)
11667 return -EPERM; 11675 return -EPERM;
11668 11676
11669 priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1); 11677 priv->prom_net_dev = alloc_libipw(sizeof(struct ipw_prom_priv), 1);
11670 if (priv->prom_net_dev == NULL) 11678 if (priv->prom_net_dev == NULL)
11671 return -ENOMEM; 11679 return -ENOMEM;
11672 11680
@@ -11685,7 +11693,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
11685 11693
11686 rc = register_netdev(priv->prom_net_dev); 11694 rc = register_netdev(priv->prom_net_dev);
11687 if (rc) { 11695 if (rc) {
11688 free_ieee80211(priv->prom_net_dev, 1); 11696 free_libipw(priv->prom_net_dev, 1);
11689 priv->prom_net_dev = NULL; 11697 priv->prom_net_dev = NULL;
11690 return rc; 11698 return rc;
11691 } 11699 }
@@ -11699,7 +11707,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
11699 return; 11707 return;
11700 11708
11701 unregister_netdev(priv->prom_net_dev); 11709 unregister_netdev(priv->prom_net_dev);
11702 free_ieee80211(priv->prom_net_dev, 1); 11710 free_libipw(priv->prom_net_dev, 1);
11703 11711
11704 priv->prom_net_dev = NULL; 11712 priv->prom_net_dev = NULL;
11705} 11713}
@@ -11727,7 +11735,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11727 struct ipw_priv *priv; 11735 struct ipw_priv *priv;
11728 int i; 11736 int i;
11729 11737
11730 net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0); 11738 net_dev = alloc_libipw(sizeof(struct ipw_priv), 0);
11731 if (net_dev == NULL) { 11739 if (net_dev == NULL) {
11732 err = -ENOMEM; 11740 err = -ENOMEM;
11733 goto out; 11741 goto out;
@@ -11747,7 +11755,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11747 mutex_init(&priv->mutex); 11755 mutex_init(&priv->mutex);
11748 if (pci_enable_device(pdev)) { 11756 if (pci_enable_device(pdev)) {
11749 err = -ENODEV; 11757 err = -ENODEV;
11750 goto out_free_ieee80211; 11758 goto out_free_libipw;
11751 } 11759 }
11752 11760
11753 pci_set_master(pdev); 11761 pci_set_master(pdev);
@@ -11874,8 +11882,8 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11874 out_pci_disable_device: 11882 out_pci_disable_device:
11875 pci_disable_device(pdev); 11883 pci_disable_device(pdev);
11876 pci_set_drvdata(pdev, NULL); 11884 pci_set_drvdata(pdev, NULL);
11877 out_free_ieee80211: 11885 out_free_libipw:
11878 free_ieee80211(priv->net_dev, 0); 11886 free_libipw(priv->net_dev, 0);
11879 out: 11887 out:
11880 return err; 11888 return err;
11881} 11889}
@@ -11942,11 +11950,11 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
11942 pci_release_regions(pdev); 11950 pci_release_regions(pdev);
11943 pci_disable_device(pdev); 11951 pci_disable_device(pdev);
11944 pci_set_drvdata(pdev, NULL); 11952 pci_set_drvdata(pdev, NULL);
11945 /* wiphy_unregister needs to be here, before free_ieee80211 */ 11953 /* wiphy_unregister needs to be here, before free_libipw */
11946 wiphy_unregister(priv->ieee->wdev.wiphy); 11954 wiphy_unregister(priv->ieee->wdev.wiphy);
11947 kfree(priv->ieee->a_band.channels); 11955 kfree(priv->ieee->a_band.channels);
11948 kfree(priv->ieee->bg_band.channels); 11956 kfree(priv->ieee->bg_band.channels);
11949 free_ieee80211(priv->net_dev, 0); 11957 free_libipw(priv->net_dev, 0);
11950 free_firmware(); 11958 free_firmware();
11951} 11959}
11952 11960
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index a6d5e42647e4..284b0e4cb815 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -64,7 +64,7 @@
64extern u32 libipw_debug_level; 64extern u32 libipw_debug_level;
65#define LIBIPW_DEBUG(level, fmt, args...) \ 65#define LIBIPW_DEBUG(level, fmt, args...) \
66do { if (libipw_debug_level & (level)) \ 66do { if (libipw_debug_level & (level)) \
67 printk(KERN_DEBUG "ieee80211: %c %s " fmt, \ 67 printk(KERN_DEBUG "libipw: %c %s " fmt, \
68 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) 68 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
69static inline bool libipw_ratelimit_debug(u32 level) 69static inline bool libipw_ratelimit_debug(u32 level)
70{ 70{
@@ -116,8 +116,8 @@ static inline bool libipw_ratelimit_debug(u32 level)
116#define LIBIPW_DL_RX (1<<9) 116#define LIBIPW_DL_RX (1<<9)
117#define LIBIPW_DL_QOS (1<<31) 117#define LIBIPW_DL_QOS (1<<31)
118 118
119#define LIBIPW_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) 119#define LIBIPW_ERROR(f, a...) printk(KERN_ERR "libipw: " f, ## a)
120#define LIBIPW_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) 120#define LIBIPW_WARNING(f, a...) printk(KERN_WARNING "libipw: " f, ## a)
121#define LIBIPW_DEBUG_INFO(f, a...) LIBIPW_DEBUG(LIBIPW_DL_INFO, f, ## a) 121#define LIBIPW_DEBUG_INFO(f, a...) LIBIPW_DEBUG(LIBIPW_DL_INFO, f, ## a)
122 122
123#define LIBIPW_DEBUG_WX(f, a...) LIBIPW_DEBUG(LIBIPW_DL_WX, f, ## a) 123#define LIBIPW_DEBUG_WX(f, a...) LIBIPW_DEBUG(LIBIPW_DL_WX, f, ## a)
@@ -905,7 +905,7 @@ struct libipw_device {
905 struct libipw_reassoc_request * req); 905 struct libipw_reassoc_request * req);
906 906
907 /* This must be the last item so that it points to the data 907 /* This must be the last item so that it points to the data
908 * allocated beyond this structure by alloc_ieee80211 */ 908 * allocated beyond this structure by alloc_libipw */
909 u8 priv[0]; 909 u8 priv[0];
910}; 910};
911 911
@@ -1017,9 +1017,9 @@ static inline int libipw_is_cck_rate(u8 rate)
1017 return 0; 1017 return 0;
1018} 1018}
1019 1019
1020/* ieee80211.c */ 1020/* libipw.c */
1021extern void free_ieee80211(struct net_device *dev, int monitor); 1021extern void free_libipw(struct net_device *dev, int monitor);
1022extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); 1022extern struct net_device *alloc_libipw(int sizeof_priv, int monitor);
1023extern int libipw_change_mtu(struct net_device *dev, int new_mtu); 1023extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
1024 1024
1025extern void libipw_networks_age(struct libipw_device *ieee, 1025extern void libipw_networks_age(struct libipw_device *ieee,
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 2fa55867bd8b..55965408ff3f 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -53,7 +53,7 @@
53#include "libipw.h" 53#include "libipw.h"
54 54
55#define DRV_DESCRIPTION "802.11 data/management/control stack" 55#define DRV_DESCRIPTION "802.11 data/management/control stack"
56#define DRV_NAME "ieee80211" 56#define DRV_NAME "libipw"
57#define DRV_VERSION LIBIPW_VERSION 57#define DRV_VERSION LIBIPW_VERSION
58#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>" 58#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
59 59
@@ -140,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu)
140} 140}
141EXPORT_SYMBOL(libipw_change_mtu); 141EXPORT_SYMBOL(libipw_change_mtu);
142 142
143struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) 143struct net_device *alloc_libipw(int sizeof_priv, int monitor)
144{ 144{
145 struct libipw_device *ieee; 145 struct libipw_device *ieee;
146 struct net_device *dev; 146 struct net_device *dev;
@@ -222,8 +222,9 @@ failed_free_netdev:
222failed: 222failed:
223 return NULL; 223 return NULL;
224} 224}
225EXPORT_SYMBOL(alloc_libipw);
225 226
226void free_ieee80211(struct net_device *dev, int monitor) 227void free_libipw(struct net_device *dev, int monitor)
227{ 228{
228 struct libipw_device *ieee = netdev_priv(dev); 229 struct libipw_device *ieee = netdev_priv(dev);
229 230
@@ -237,6 +238,7 @@ void free_ieee80211(struct net_device *dev, int monitor)
237 238
238 free_netdev(dev); 239 free_netdev(dev);
239} 240}
241EXPORT_SYMBOL(free_libipw);
240 242
241#ifdef CONFIG_LIBIPW_DEBUG 243#ifdef CONFIG_LIBIPW_DEBUG
242 244
@@ -291,7 +293,7 @@ static int __init libipw_init(void)
291 struct proc_dir_entry *e; 293 struct proc_dir_entry *e;
292 294
293 libipw_debug_level = debug; 295 libipw_debug_level = debug;
294 libipw_proc = proc_mkdir(DRV_NAME, init_net.proc_net); 296 libipw_proc = proc_mkdir("ieee80211", init_net.proc_net);
295 if (libipw_proc == NULL) { 297 if (libipw_proc == NULL) {
296 LIBIPW_ERROR("Unable to create " DRV_NAME 298 LIBIPW_ERROR("Unable to create " DRV_NAME
297 " proc directory\n"); 299 " proc directory\n");
@@ -331,6 +333,3 @@ MODULE_PARM_DESC(debug, "debug output mask");
331 333
332module_exit(libipw_exit); 334module_exit(libipw_exit);
333module_init(libipw_init); 335module_init(libipw_init);
334
335EXPORT_SYMBOL(alloc_ieee80211);
336EXPORT_SYMBOL(free_ieee80211);
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 4e378faee650..a684a72eb6e9 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -9,7 +9,9 @@ CFLAGS_iwl-devtrace.o := -I$(src)
9 9
10# AGN 10# AGN
11obj-$(CONFIG_IWLAGN) += iwlagn.o 11obj-$(CONFIG_IWLAGN) += iwlagn.o
12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o 12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
13iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
14iwlagn-objs += iwl-agn-lib.o
13 15
14iwlagn-$(CONFIG_IWL4965) += iwl-4965.o 16iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
15iwlagn-$(CONFIG_IWL5000) += iwl-5000.o 17iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 3bf2e6e9b2d9..b941b3e95697 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -42,8 +42,9 @@
42#include "iwl-core.h" 42#include "iwl-core.h"
43#include "iwl-io.h" 43#include "iwl-io.h"
44#include "iwl-sta.h" 44#include "iwl-sta.h"
45#include "iwl-agn.h"
45#include "iwl-helpers.h" 46#include "iwl-helpers.h"
46#include "iwl-5000-hw.h" 47#include "iwl-agn-hw.h"
47#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
48 49
49/* Highest firmware API version supported */ 50/* Highest firmware API version supported */
@@ -117,7 +118,7 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
117static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) 118static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
118{ 119{
119 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 120 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
120 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) 121 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
121 priv->cfg->num_of_queues = 122 priv->cfg->num_of_queues =
122 priv->cfg->mod_params->num_of_queues; 123 priv->cfg->mod_params->num_of_queues;
123 124
@@ -125,13 +126,13 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
125 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 126 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
126 priv->hw_params.scd_bc_tbls_size = 127 priv->hw_params.scd_bc_tbls_size =
127 priv->cfg->num_of_queues * 128 priv->cfg->num_of_queues *
128 sizeof(struct iwl5000_scd_bc_tbl); 129 sizeof(struct iwlagn_scd_bc_tbl);
129 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 130 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
130 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 131 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
131 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 132 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
132 133
133 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; 134 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
134 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE; 135 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
135 136
136 priv->hw_params.max_bsm_size = 0; 137 priv->hw_params.max_bsm_size = 0;
137 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 138 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
@@ -161,25 +162,25 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
161 162
162static struct iwl_lib_ops iwl1000_lib = { 163static struct iwl_lib_ops iwl1000_lib = {
163 .set_hw_params = iwl1000_hw_set_hw_params, 164 .set_hw_params = iwl1000_hw_set_hw_params,
164 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 165 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
165 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 166 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
166 .txq_set_sched = iwl5000_txq_set_sched, 167 .txq_set_sched = iwlagn_txq_set_sched,
167 .txq_agg_enable = iwl5000_txq_agg_enable, 168 .txq_agg_enable = iwlagn_txq_agg_enable,
168 .txq_agg_disable = iwl5000_txq_agg_disable, 169 .txq_agg_disable = iwlagn_txq_agg_disable,
169 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 170 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
170 .txq_free_tfd = iwl_hw_txq_free_tfd, 171 .txq_free_tfd = iwl_hw_txq_free_tfd,
171 .txq_init = iwl_hw_tx_queue_init, 172 .txq_init = iwl_hw_tx_queue_init,
172 .rx_handler_setup = iwl5000_rx_handler_setup, 173 .rx_handler_setup = iwlagn_rx_handler_setup,
173 .setup_deferred_work = iwl5000_setup_deferred_work, 174 .setup_deferred_work = iwlagn_setup_deferred_work,
174 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 175 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
175 .load_ucode = iwl5000_load_ucode, 176 .load_ucode = iwlagn_load_ucode,
176 .dump_nic_event_log = iwl_dump_nic_event_log, 177 .dump_nic_event_log = iwl_dump_nic_event_log,
177 .dump_nic_error_log = iwl_dump_nic_error_log, 178 .dump_nic_error_log = iwl_dump_nic_error_log,
178 .dump_csr = iwl_dump_csr, 179 .dump_csr = iwl_dump_csr,
179 .dump_fh = iwl_dump_fh, 180 .dump_fh = iwl_dump_fh,
180 .init_alive_start = iwl5000_init_alive_start, 181 .init_alive_start = iwlagn_init_alive_start,
181 .alive_notify = iwl5000_alive_notify, 182 .alive_notify = iwlagn_alive_notify,
182 .send_tx_power = iwl5000_send_tx_power, 183 .send_tx_power = iwlagn_send_tx_power,
183 .update_chain_flags = iwl_update_chain_flags, 184 .update_chain_flags = iwl_update_chain_flags,
184 .apm_ops = { 185 .apm_ops = {
185 .init = iwl_apm_init, 186 .init = iwl_apm_init,
@@ -189,40 +190,43 @@ static struct iwl_lib_ops iwl1000_lib = {
189 }, 190 },
190 .eeprom_ops = { 191 .eeprom_ops = {
191 .regulatory_bands = { 192 .regulatory_bands = {
192 EEPROM_5000_REG_BAND_1_CHANNELS, 193 EEPROM_REG_BAND_1_CHANNELS,
193 EEPROM_5000_REG_BAND_2_CHANNELS, 194 EEPROM_REG_BAND_2_CHANNELS,
194 EEPROM_5000_REG_BAND_3_CHANNELS, 195 EEPROM_REG_BAND_3_CHANNELS,
195 EEPROM_5000_REG_BAND_4_CHANNELS, 196 EEPROM_REG_BAND_4_CHANNELS,
196 EEPROM_5000_REG_BAND_5_CHANNELS, 197 EEPROM_REG_BAND_5_CHANNELS,
197 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 198 EEPROM_REG_BAND_24_HT40_CHANNELS,
198 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 199 EEPROM_REG_BAND_52_HT40_CHANNELS
199 }, 200 },
200 .verify_signature = iwlcore_eeprom_verify_signature, 201 .verify_signature = iwlcore_eeprom_verify_signature,
201 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 202 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
202 .release_semaphore = iwlcore_eeprom_release_semaphore, 203 .release_semaphore = iwlcore_eeprom_release_semaphore,
203 .calib_version = iwl5000_eeprom_calib_version, 204 .calib_version = iwlagn_eeprom_calib_version,
204 .query_addr = iwl5000_eeprom_query_addr, 205 .query_addr = iwlagn_eeprom_query_addr,
205 }, 206 },
206 .post_associate = iwl_post_associate, 207 .post_associate = iwl_post_associate,
207 .isr = iwl_isr_ict, 208 .isr = iwl_isr_ict,
208 .config_ap = iwl_config_ap, 209 .config_ap = iwl_config_ap,
209 .temp_ops = { 210 .temp_ops = {
210 .temperature = iwl5000_temperature, 211 .temperature = iwlagn_temperature,
211 .set_ct_kill = iwl1000_set_ct_threshold, 212 .set_ct_kill = iwl1000_set_ct_threshold,
212 }, 213 },
213 .add_bcast_station = iwl_add_bcast_station, 214 .add_bcast_station = iwl_add_bcast_station,
215 .recover_from_tx_stall = iwl_bg_monitor_recover,
216 .check_plcp_health = iwl_good_plcp_health,
217 .check_ack_health = iwl_good_ack_health,
214}; 218};
215 219
216static const struct iwl_ops iwl1000_ops = { 220static const struct iwl_ops iwl1000_ops = {
217 .ucode = &iwl5000_ucode, 221 .ucode = &iwlagn_ucode,
218 .lib = &iwl1000_lib, 222 .lib = &iwl1000_lib,
219 .hcmd = &iwl5000_hcmd, 223 .hcmd = &iwlagn_hcmd,
220 .utils = &iwl5000_hcmd_utils, 224 .utils = &iwlagn_hcmd_utils,
221 .led = &iwlagn_led_ops, 225 .led = &iwlagn_led_ops,
222}; 226};
223 227
224struct iwl_cfg iwl1000_bgn_cfg = { 228struct iwl_cfg iwl1000_bgn_cfg = {
225 .name = "1000 Series BGN", 229 .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
226 .fw_name_pre = IWL1000_FW_PRE, 230 .fw_name_pre = IWL1000_FW_PRE,
227 .ucode_api_max = IWL1000_UCODE_API_MAX, 231 .ucode_api_max = IWL1000_UCODE_API_MAX,
228 .ucode_api_min = IWL1000_UCODE_API_MIN, 232 .ucode_api_min = IWL1000_UCODE_API_MIN,
@@ -230,10 +234,10 @@ struct iwl_cfg iwl1000_bgn_cfg = {
230 .ops = &iwl1000_ops, 234 .ops = &iwl1000_ops,
231 .eeprom_size = OTP_LOW_IMAGE_SIZE, 235 .eeprom_size = OTP_LOW_IMAGE_SIZE,
232 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, 236 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
233 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 237 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
234 .num_of_queues = IWL50_NUM_QUEUES, 238 .num_of_queues = IWLAGN_NUM_QUEUES,
235 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 239 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
236 .mod_params = &iwl50_mod_params, 240 .mod_params = &iwlagn_mod_params,
237 .valid_tx_ant = ANT_A, 241 .valid_tx_ant = ANT_A,
238 .valid_rx_ant = ANT_AB, 242 .valid_rx_ant = ANT_AB,
239 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 243 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -248,10 +252,11 @@ struct iwl_cfg iwl1000_bgn_cfg = {
248 .support_ct_kill_exit = true, 252 .support_ct_kill_exit = true,
249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 253 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
250 .chain_noise_scale = 1000, 254 .chain_noise_scale = 1000,
255 .monitor_recover_period = IWL_MONITORING_PERIOD,
251}; 256};
252 257
253struct iwl_cfg iwl1000_bg_cfg = { 258struct iwl_cfg iwl1000_bg_cfg = {
254 .name = "1000 Series BG", 259 .name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
255 .fw_name_pre = IWL1000_FW_PRE, 260 .fw_name_pre = IWL1000_FW_PRE,
256 .ucode_api_max = IWL1000_UCODE_API_MAX, 261 .ucode_api_max = IWL1000_UCODE_API_MAX,
257 .ucode_api_min = IWL1000_UCODE_API_MIN, 262 .ucode_api_min = IWL1000_UCODE_API_MIN,
@@ -259,10 +264,10 @@ struct iwl_cfg iwl1000_bg_cfg = {
259 .ops = &iwl1000_ops, 264 .ops = &iwl1000_ops,
260 .eeprom_size = OTP_LOW_IMAGE_SIZE, 265 .eeprom_size = OTP_LOW_IMAGE_SIZE,
261 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, 266 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
262 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 267 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
263 .num_of_queues = IWL50_NUM_QUEUES, 268 .num_of_queues = IWLAGN_NUM_QUEUES,
264 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 269 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
265 .mod_params = &iwl50_mod_params, 270 .mod_params = &iwlagn_mod_params,
266 .valid_tx_ant = ANT_A, 271 .valid_tx_ant = ANT_A,
267 .valid_rx_ant = ANT_AB, 272 .valid_rx_ant = ANT_AB,
268 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 273 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -276,6 +281,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
276 .support_ct_kill_exit = true, 281 .support_ct_kill_exit = true,
277 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 282 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
278 .chain_noise_scale = 1000, 283 .chain_noise_scale = 1000,
284 .monitor_recover_period = IWL_MONITORING_PERIOD,
279}; 285};
280 286
281MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 287MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 3a876a8ece38..91bcb4e3cdfb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -71,13 +71,11 @@
71 71
72#include "iwl-eeprom.h" 72#include "iwl-eeprom.h"
73 73
74/* Time constants */
75#define SHORT_SLOT_TIME 9
76#define LONG_SLOT_TIME 20
77
78/* RSSI to dBm */ 74/* RSSI to dBm */
79#define IWL39_RSSI_OFFSET 95 75#define IWL39_RSSI_OFFSET 95
80 76
77#define IWL_DEFAULT_TX_POWER 0x0F
78
81/* 79/*
82 * EEPROM related constants, enums, and structures. 80 * EEPROM related constants, enums, and structures.
83 */ 81 */
@@ -228,7 +226,6 @@ struct iwl3945_eeprom {
228 226
229/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */ 227/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */
230#define IWL39_NUM_QUEUES 5 228#define IWL39_NUM_QUEUES 5
231#define IWL_NUM_SCAN_RATES (2)
232 229
233#define IWL_DEFAULT_TX_RETRY 15 230#define IWL_DEFAULT_TX_RETRY 15
234 231
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 47909f94271e..9e411dc0e5e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -329,16 +329,25 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
329 329
330} 330}
331 331
332static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, 332/*
333 struct ieee80211_sta *sta, void *priv_sta) 333 * Called after adding a new station to initialize rate scaling
334 */
335void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id)
334{ 336{
335 struct iwl3945_rs_sta *rs_sta = priv_sta; 337 struct ieee80211_hw *hw = priv->hw;
336 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 338 struct ieee80211_conf *conf = &priv->hw->conf;
339 struct iwl3945_sta_priv *psta;
340 struct iwl3945_rs_sta *rs_sta;
341 struct ieee80211_supported_band *sband;
337 int i; 342 int i;
338 343
339 IWL_DEBUG_RATE(priv, "enter\n"); 344 IWL_DEBUG_INFO(priv, "enter\n");
345 if (sta_id == priv->hw_params.bcast_sta_id)
346 goto out;
340 347
341 spin_lock_init(&rs_sta->lock); 348 psta = (struct iwl3945_sta_priv *) sta->drv_priv;
349 rs_sta = &psta->rs_sta;
350 sband = hw->wiphy->bands[conf->channel->band];
342 351
343 rs_sta->priv = priv; 352 rs_sta->priv = priv;
344 353
@@ -351,9 +360,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
351 rs_sta->last_flush = jiffies; 360 rs_sta->last_flush = jiffies;
352 rs_sta->flush_time = IWL_RATE_FLUSH; 361 rs_sta->flush_time = IWL_RATE_FLUSH;
353 rs_sta->last_tx_packets = 0; 362 rs_sta->last_tx_packets = 0;
354 rs_sta->ibss_sta_added = 0;
355 363
356 init_timer(&rs_sta->rate_scale_flush);
357 rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; 364 rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
358 rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; 365 rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush;
359 366
@@ -372,16 +379,18 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
372 } 379 }
373 } 380 }
374 381
375 priv->sta_supp_rates = sta->supp_rates[sband->band]; 382 priv->_3945.sta_supp_rates = sta->supp_rates[sband->band];
376 /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ 383 /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
377 if (sband->band == IEEE80211_BAND_5GHZ) { 384 if (sband->band == IEEE80211_BAND_5GHZ) {
378 rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 385 rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
379 priv->sta_supp_rates = priv->sta_supp_rates << 386 priv->_3945.sta_supp_rates = priv->_3945.sta_supp_rates <<
380 IWL_FIRST_OFDM_RATE; 387 IWL_FIRST_OFDM_RATE;
381 } 388 }
382 389
390out:
391 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
383 392
384 IWL_DEBUG_RATE(priv, "leave\n"); 393 IWL_DEBUG_INFO(priv, "leave\n");
385} 394}
386 395
387static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 396static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -405,6 +414,9 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
405 414
406 rs_sta = &psta->rs_sta; 415 rs_sta = &psta->rs_sta;
407 416
417 spin_lock_init(&rs_sta->lock);
418 init_timer(&rs_sta->rate_scale_flush);
419
408 IWL_DEBUG_RATE(priv, "leave\n"); 420 IWL_DEBUG_RATE(priv, "leave\n");
409 421
410 return rs_sta; 422 return rs_sta;
@@ -413,13 +425,14 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
413static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, 425static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
414 void *priv_sta) 426 void *priv_sta)
415{ 427{
416 struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; 428 struct iwl3945_rs_sta *rs_sta = priv_sta;
417 struct iwl3945_rs_sta *rs_sta = &psta->rs_sta;
418 struct iwl_priv *priv __maybe_unused = rs_sta->priv;
419 429
420 IWL_DEBUG_RATE(priv, "enter\n"); 430 /*
431 * Be careful not to use any members of iwl3945_rs_sta (like trying
432 * to use iwl_priv to print out debugging) since it may not be fully
433 * initialized at this point.
434 */
421 del_timer_sync(&rs_sta->rate_scale_flush); 435 del_timer_sync(&rs_sta->rate_scale_flush);
422 IWL_DEBUG_RATE(priv, "leave\n");
423} 436}
424 437
425 438
@@ -458,6 +471,13 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
458 return; 471 return;
459 } 472 }
460 473
474 /* Treat uninitialized rate scaling data same as non-existing. */
475 if (!rs_sta->priv) {
476 IWL_DEBUG_RATE(priv, "leave: STA priv data uninitialized!\n");
477 return;
478 }
479
480
461 rs_sta->tx_packets++; 481 rs_sta->tx_packets++;
462 482
463 scale_rate_index = first_index; 483 scale_rate_index = first_index;
@@ -625,7 +645,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
625 u32 fail_count; 645 u32 fail_count;
626 s8 scale_action = 0; 646 s8 scale_action = 0;
627 unsigned long flags; 647 unsigned long flags;
628 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
629 u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; 648 u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
630 s8 max_rate_idx = -1; 649 s8 max_rate_idx = -1;
631 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 650 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
@@ -633,6 +652,12 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
633 652
634 IWL_DEBUG_RATE(priv, "enter\n"); 653 IWL_DEBUG_RATE(priv, "enter\n");
635 654
655 /* Treat uninitialized rate scaling data same as non-existing. */
656 if (rs_sta && !rs_sta->priv) {
657 IWL_DEBUG_RATE(priv, "Rate scaling information not initialized yet.\n");
658 priv_sta = NULL;
659 }
660
636 if (rate_control_send_low(sta, priv_sta, txrc)) 661 if (rate_control_send_low(sta, priv_sta, txrc))
637 return; 662 return;
638 663
@@ -650,20 +675,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
650 if (sband->band == IEEE80211_BAND_5GHZ) 675 if (sband->band == IEEE80211_BAND_5GHZ)
651 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; 676 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
652 677
653 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
654 !rs_sta->ibss_sta_added) {
655 u8 sta_id = iwl_find_station(priv, hdr->addr1);
656
657 if (sta_id == IWL_INVALID_STATION) {
658 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
659 hdr->addr1);
660 sta_id = iwl_add_station(priv, hdr->addr1, false,
661 CMD_ASYNC, NULL);
662 }
663 if (sta_id != IWL_INVALID_STATION)
664 rs_sta->ibss_sta_added = 1;
665 }
666
667 spin_lock_irqsave(&rs_sta->lock, flags); 678 spin_lock_irqsave(&rs_sta->lock, flags);
668 679
669 /* for recent assoc, choose best rate regarding 680 /* for recent assoc, choose best rate regarding
@@ -883,12 +894,22 @@ static void iwl3945_remove_debugfs(void *priv, void *priv_sta)
883} 894}
884#endif 895#endif
885 896
897/*
898 * Initialization of rate scaling information is done by driver after
899 * the station is added. Since mac80211 calls this function before a
900 * station is added we ignore it.
901 */
902static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,
903 struct ieee80211_sta *sta, void *priv_sta)
904{
905}
906
886static struct rate_control_ops rs_ops = { 907static struct rate_control_ops rs_ops = {
887 .module = NULL, 908 .module = NULL,
888 .name = RS_NAME, 909 .name = RS_NAME,
889 .tx_status = rs_tx_status, 910 .tx_status = rs_tx_status,
890 .get_rate = rs_get_rate, 911 .get_rate = rs_get_rate,
891 .rate_init = rs_rate_init, 912 .rate_init = rs_rate_init_stub,
892 .alloc = rs_alloc, 913 .alloc = rs_alloc,
893 .free = rs_free, 914 .free = rs_free,
894 .alloc_sta = rs_alloc_sta, 915 .alloc_sta = rs_alloc_sta,
@@ -899,7 +920,6 @@ static struct rate_control_ops rs_ops = {
899#endif 920#endif
900 921
901}; 922};
902
903void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) 923void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
904{ 924{
905 struct iwl_priv *priv = hw->priv; 925 struct iwl_priv *priv = hw->priv;
@@ -916,6 +936,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
916 sta = ieee80211_find_sta(priv->vif, 936 sta = ieee80211_find_sta(priv->vif,
917 priv->stations[sta_id].sta.sta.addr); 937 priv->stations[sta_id].sta.sta.addr);
918 if (!sta) { 938 if (!sta) {
939 IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n");
919 rcu_read_unlock(); 940 rcu_read_unlock();
920 return; 941 return;
921 } 942 }
@@ -946,7 +967,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
946 967
947 spin_unlock_irqrestore(&rs_sta->lock, flags); 968 spin_unlock_irqrestore(&rs_sta->lock, flags);
948 969
949 rssi = priv->last_rx_rssi; 970 rssi = priv->_3945.last_rx_rssi;
950 if (rssi == 0) 971 if (rssi == 0)
951 rssi = IWL_MIN_RSSI_VAL; 972 rssi = IWL_MIN_RSSI_VAL;
952 973
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index e0678d921055..f88f75dfd96e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -242,7 +242,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
242 next_rate = IWL_RATE_6M_INDEX; 242 next_rate = IWL_RATE_6M_INDEX;
243 break; 243 break;
244 case IEEE80211_BAND_2GHZ: 244 case IEEE80211_BAND_2GHZ:
245 if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && 245 if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
246 iwl_is_associated(priv)) { 246 iwl_is_associated(priv)) {
247 if (rate == IWL_RATE_11M_INDEX) 247 if (rate == IWL_RATE_11M_INDEX)
248 next_rate = IWL_RATE_5M_INDEX; 248 next_rate = IWL_RATE_5M_INDEX;
@@ -359,7 +359,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
359 (int)sizeof(struct iwl3945_notif_statistics), 359 (int)sizeof(struct iwl3945_notif_statistics),
360 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 360 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
361 361
362 memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); 362 memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics));
363} 363}
364 364
365/****************************************************************************** 365/******************************************************************************
@@ -486,7 +486,7 @@ static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
486 * but you can hack it to show more, if you'd like to. */ 486 * but you can hack it to show more, if you'd like to. */
487 if (dataframe) 487 if (dataframe)
488 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " 488 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
489 "len=%u, rssi=%d, chnl=%d, rate=%d, \n", 489 "len=%u, rssi=%d, chnl=%d, rate=%d,\n",
490 title, le16_to_cpu(fc), header->addr1[5], 490 title, le16_to_cpu(fc), header->addr1[5],
491 length, rssi, channel, rate); 491 length, rssi, channel, rate);
492 else { 492 else {
@@ -548,7 +548,6 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
548 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); 548 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
549 u16 len = le16_to_cpu(rx_hdr->len); 549 u16 len = le16_to_cpu(rx_hdr->len);
550 struct sk_buff *skb; 550 struct sk_buff *skb;
551 int ret;
552 __le16 fc = hdr->frame_control; 551 __le16 fc = hdr->frame_control;
553 552
554 /* We received data from the HW, so stop the watchdog */ 553 /* We received data from the HW, so stop the watchdog */
@@ -565,9 +564,9 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
565 return; 564 return;
566 } 565 }
567 566
568 skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC); 567 skb = dev_alloc_skb(128);
569 if (!skb) { 568 if (!skb) {
570 IWL_ERR(priv, "alloc_skb failed\n"); 569 IWL_ERR(priv, "dev_alloc_skb failed\n");
571 return; 570 return;
572 } 571 }
573 572
@@ -576,37 +575,13 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
576 (struct ieee80211_hdr *)rxb_addr(rxb), 575 (struct ieee80211_hdr *)rxb_addr(rxb),
577 le32_to_cpu(rx_end->status), stats); 576 le32_to_cpu(rx_end->status), stats);
578 577
579 skb_reserve(skb, IWL_LINK_HDR_MAX);
580 skb_add_rx_frag(skb, 0, rxb->page, 578 skb_add_rx_frag(skb, 0, rxb->page,
581 (void *)rx_hdr->payload - (void *)pkt, len); 579 (void *)rx_hdr->payload - (void *)pkt, len);
582 580
583 /* mac80211 currently doesn't support paged SKB. Convert it to
584 * linear SKB for management frame and data frame requires
585 * software decryption or software defragementation. */
586 if (ieee80211_is_mgmt(fc) ||
587 ieee80211_has_protected(fc) ||
588 ieee80211_has_morefrags(fc) ||
589 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
590 ret = skb_linearize(skb);
591 else
592 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
593 0 : -ENOMEM;
594
595 if (ret) {
596 kfree_skb(skb);
597 goto out;
598 }
599
600 /*
601 * XXX: We cannot touch the page and its virtual memory (pkt) after
602 * here. It might have already been freed by the above skb change.
603 */
604
605 iwl_update_stats(priv, false, fc, len); 581 iwl_update_stats(priv, false, fc, len);
606 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 582 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
607 583
608 ieee80211_rx(priv->hw, skb); 584 ieee80211_rx(priv->hw, skb);
609 out:
610 priv->alloc_rxb_page--; 585 priv->alloc_rxb_page--;
611 rxb->page = NULL; 586 rxb->page = NULL;
612} 587}
@@ -622,7 +597,6 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
622 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); 597 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
623 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); 598 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
624 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); 599 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
625 int snr;
626 u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg); 600 u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg);
627 u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff); 601 u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
628 u8 network_packet; 602 u8 network_packet;
@@ -662,53 +636,29 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
662 /* Convert 3945's rssi indicator to dBm */ 636 /* Convert 3945's rssi indicator to dBm */
663 rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; 637 rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET;
664 638
665 /* Set default noise value to -127 */ 639 IWL_DEBUG_STATS(priv, "Rssi %d sig_avg %d noise_diff %d\n",
666 if (priv->last_rx_noise == 0) 640 rx_status.signal, rx_stats_sig_avg,
667 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 641 rx_stats_noise_diff);
668
669 /* 3945 provides noise info for OFDM frames only.
670 * sig_avg and noise_diff are measured by the 3945's digital signal
671 * processor (DSP), and indicate linear levels of signal level and
672 * distortion/noise within the packet preamble after
673 * automatic gain control (AGC). sig_avg should stay fairly
674 * constant if the radio's AGC is working well.
675 * Since these values are linear (not dB or dBm), linear
676 * signal-to-noise ratio (SNR) is (sig_avg / noise_diff).
677 * Convert linear SNR to dB SNR, then subtract that from rssi dBm
678 * to obtain noise level in dBm.
679 * Calculate rx_status.signal (quality indicator in %) based on SNR. */
680 if (rx_stats_noise_diff) {
681 snr = rx_stats_sig_avg / rx_stats_noise_diff;
682 rx_status.noise = rx_status.signal -
683 iwl3945_calc_db_from_ratio(snr);
684 } else {
685 rx_status.noise = priv->last_rx_noise;
686 }
687
688
689 IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n",
690 rx_status.signal, rx_status.noise,
691 rx_stats_sig_avg, rx_stats_noise_diff);
692 642
693 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); 643 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
694 644
695 network_packet = iwl3945_is_network_packet(priv, header); 645 network_packet = iwl3945_is_network_packet(priv, header);
696 646
697 IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", 647 IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Rate:%u\n",
698 network_packet ? '*' : ' ', 648 network_packet ? '*' : ' ',
699 le16_to_cpu(rx_hdr->channel), 649 le16_to_cpu(rx_hdr->channel),
700 rx_status.signal, rx_status.signal, 650 rx_status.signal, rx_status.signal,
701 rx_status.noise, rx_status.rate_idx); 651 rx_status.rate_idx);
702 652
703 /* Set "1" to report good data frames in groups of 100 */ 653 /* Set "1" to report good data frames in groups of 100 */
704 iwl3945_dbg_report_frame(priv, pkt, header, 1); 654 iwl3945_dbg_report_frame(priv, pkt, header, 1);
705 iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); 655 iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header);
706 656
707 if (network_packet) { 657 if (network_packet) {
708 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); 658 priv->_3945.last_beacon_time =
709 priv->last_tsf = le64_to_cpu(rx_end->timestamp); 659 le32_to_cpu(rx_end->beacon_timestamp);
710 priv->last_rx_rssi = rx_status.signal; 660 priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp);
711 priv->last_rx_noise = rx_status.noise; 661 priv->_3945.last_rx_rssi = rx_status.signal;
712 } 662 }
713 663
714 iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); 664 iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
@@ -956,7 +906,7 @@ static int iwl3945_tx_reset(struct iwl_priv *priv)
956 iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); 906 iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
957 907
958 iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, 908 iwl_write_direct32(priv, FH39_TSSR_CBB_BASE,
959 priv->shared_phys); 909 priv->_3945.shared_phys);
960 910
961 iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, 911 iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
962 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | 912 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
@@ -1048,7 +998,7 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
1048 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); 998 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
1049 999
1050 if (rev_id & PCI_CFG_REV_ID_BIT_RTP) 1000 if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
1051 IWL_DEBUG_INFO(priv, "RTP type \n"); 1001 IWL_DEBUG_INFO(priv, "RTP type\n");
1052 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { 1002 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
1053 IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); 1003 IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n");
1054 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1004 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
@@ -1606,7 +1556,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv,
1606 int power; 1556 int power;
1607 1557
1608 /* Get this chnlgrp's rate-to-max/clip-powers table */ 1558 /* Get this chnlgrp's rate-to-max/clip-powers table */
1609 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; 1559 clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers;
1610 1560
1611 /* Get this channel's rate-to-current-power settings table */ 1561 /* Get this channel's rate-to-current-power settings table */
1612 power_info = ch_info->power_info; 1562 power_info = ch_info->power_info;
@@ -1732,7 +1682,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
1732 } 1682 }
1733 1683
1734 /* Get this chnlgrp's rate-to-max/clip-powers table */ 1684 /* Get this chnlgrp's rate-to-max/clip-powers table */
1735 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; 1685 clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers;
1736 1686
1737 /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ 1687 /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */
1738 for (scan_tbl_index = 0; 1688 for (scan_tbl_index = 0;
@@ -1910,6 +1860,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1910 "configuration (%d).\n", rc); 1860 "configuration (%d).\n", rc);
1911 return rc; 1861 return rc;
1912 } 1862 }
1863 iwl_clear_ucode_stations(priv, false);
1864 iwl_restore_stations(priv);
1913 } 1865 }
1914 1866
1915 IWL_DEBUG_INFO(priv, "Sending RXON\n" 1867 IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -1940,7 +1892,10 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1940 1892
1941 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); 1893 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
1942 1894
1943 iwl_clear_stations_table(priv); 1895 if (!new_assoc) {
1896 iwl_clear_ucode_stations(priv, false);
1897 iwl_restore_stations(priv);
1898 }
1944 1899
1945 /* If we issue a new RXON command which required a tune then we must 1900 /* If we issue a new RXON command which required a tune then we must
1946 * send a new TXPOWER command or we won't be able to Tx any frames */ 1901 * send a new TXPOWER command or we won't be able to Tx any frames */
@@ -1950,19 +1905,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1950 return rc; 1905 return rc;
1951 } 1906 }
1952 1907
1953 /* Add the broadcast address so we can send broadcast frames */
1954 priv->cfg->ops->lib->add_bcast_station(priv);
1955
1956 /* If we have set the ASSOC_MSK and we are in BSS mode then
1957 * add the IWL_AP_ID to the station rate table */
1958 if (iwl_is_associated(priv) &&
1959 (priv->iw_mode == NL80211_IFTYPE_STATION))
1960 if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
1961 true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
1962 IWL_ERR(priv, "Error adding AP address for transmit\n");
1963 return -EIO;
1964 }
1965
1966 /* Init the hardware's rate fallback order based on the band */ 1908 /* Init the hardware's rate fallback order based on the band */
1967 rc = iwl3945_init_hw_rate_table(priv); 1909 rc = iwl3945_init_hw_rate_table(priv);
1968 if (rc) { 1910 if (rc) {
@@ -1997,13 +1939,13 @@ void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
1997 1939
1998 reschedule: 1940 reschedule:
1999 queue_delayed_work(priv->workqueue, 1941 queue_delayed_work(priv->workqueue,
2000 &priv->thermal_periodic, REG_RECALIB_PERIOD * HZ); 1942 &priv->_3945.thermal_periodic, REG_RECALIB_PERIOD * HZ);
2001} 1943}
2002 1944
2003static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) 1945static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
2004{ 1946{
2005 struct iwl_priv *priv = container_of(work, struct iwl_priv, 1947 struct iwl_priv *priv = container_of(work, struct iwl_priv,
2006 thermal_periodic.work); 1948 _3945.thermal_periodic.work);
2007 1949
2008 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 1950 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2009 return; 1951 return;
@@ -2139,7 +2081,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
2139 * power peaks, without too much distortion (clipping). 2081 * power peaks, without too much distortion (clipping).
2140 */ 2082 */
2141 /* we'll fill in this array with h/w max power levels */ 2083 /* we'll fill in this array with h/w max power levels */
2142 clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers; 2084 clip_pwrs = (s8 *) priv->_3945.clip_groups[i].clip_powers;
2143 2085
2144 /* divide factory saturation power by 2 to find -3dB level */ 2086 /* divide factory saturation power by 2 to find -3dB level */
2145 satur_pwr = (s8) (group->saturation_power >> 1); 2087 satur_pwr = (s8) (group->saturation_power >> 1);
@@ -2223,7 +2165,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
2223 iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); 2165 iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
2224 2166
2225 /* Get this chnlgrp's rate->max/clip-powers table */ 2167 /* Get this chnlgrp's rate->max/clip-powers table */
2226 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; 2168 clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers;
2227 2169
2228 /* calculate power index *adjustment* value according to 2170 /* calculate power index *adjustment* value according to
2229 * diff between current temperature and factory temperature */ 2171 * diff between current temperature and factory temperature */
@@ -2331,7 +2273,7 @@ int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
2331{ 2273{
2332 int txq_id = txq->q.id; 2274 int txq_id = txq->q.id;
2333 2275
2334 struct iwl3945_shared *shared_data = priv->shared_virt; 2276 struct iwl3945_shared *shared_data = priv->_3945.shared_virt;
2335 2277
2336 shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); 2278 shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
2337 2279
@@ -2431,7 +2373,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
2431 /* If an OFDM rate is used, have it fall back to the 2373 /* If an OFDM rate is used, have it fall back to the
2432 * 1M CCK rates */ 2374 * 1M CCK rates */
2433 2375
2434 if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && 2376 if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
2435 iwl_is_associated(priv)) { 2377 iwl_is_associated(priv)) {
2436 2378
2437 index = IWL_FIRST_CCK_RATE; 2379 index = IWL_FIRST_CCK_RATE;
@@ -2470,10 +2412,11 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2470 memset((void *)&priv->hw_params, 0, 2412 memset((void *)&priv->hw_params, 0,
2471 sizeof(struct iwl_hw_params)); 2413 sizeof(struct iwl_hw_params));
2472 2414
2473 priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev, 2415 priv->_3945.shared_virt =
2474 sizeof(struct iwl3945_shared), 2416 dma_alloc_coherent(&priv->pci_dev->dev,
2475 &priv->shared_phys, GFP_KERNEL); 2417 sizeof(struct iwl3945_shared),
2476 if (!priv->shared_virt) { 2418 &priv->_3945.shared_phys, GFP_KERNEL);
2419 if (!priv->_3945.shared_virt) {
2477 IWL_ERR(priv, "failed to allocate pci memory\n"); 2420 IWL_ERR(priv, "failed to allocate pci memory\n");
2478 mutex_unlock(&priv->mutex); 2421 mutex_unlock(&priv->mutex);
2479 return -ENOMEM; 2422 return -ENOMEM;
@@ -2536,13 +2479,13 @@ void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv)
2536 2479
2537void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) 2480void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv)
2538{ 2481{
2539 INIT_DELAYED_WORK(&priv->thermal_periodic, 2482 INIT_DELAYED_WORK(&priv->_3945.thermal_periodic,
2540 iwl3945_bg_reg_txpower_periodic); 2483 iwl3945_bg_reg_txpower_periodic);
2541} 2484}
2542 2485
2543void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) 2486void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv)
2544{ 2487{
2545 cancel_delayed_work(&priv->thermal_periodic); 2488 cancel_delayed_work(&priv->_3945.thermal_periodic);
2546} 2489}
2547 2490
2548/* check contents of special bootstrap uCode SRAM */ 2491/* check contents of special bootstrap uCode SRAM */
@@ -2826,6 +2769,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2826 .led_compensation = 64, 2769 .led_compensation = 64,
2827 .broken_powersave = true, 2770 .broken_powersave = true,
2828 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2771 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2772 .monitor_recover_period = IWL_MONITORING_PERIOD,
2829}; 2773};
2830 2774
2831static struct iwl_cfg iwl3945_abg_cfg = { 2775static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2844,6 +2788,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2844 .led_compensation = 64, 2788 .led_compensation = 64,
2845 .broken_powersave = true, 2789 .broken_powersave = true,
2846 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2790 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2791 .monitor_recover_period = IWL_MONITORING_PERIOD,
2847}; 2792};
2848 2793
2849DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { 2794DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 452dfd5456c6..b89219573b91 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -95,7 +95,6 @@ struct iwl3945_rs_sta {
95 u8 tgg; 95 u8 tgg;
96 u8 flush_pending; 96 u8 flush_pending;
97 u8 start_rate; 97 u8 start_rate;
98 u8 ibss_sta_added;
99 struct timer_list rate_scale_flush; 98 struct timer_list rate_scale_flush;
100 struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945]; 99 struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
101#ifdef CONFIG_MAC80211_DEBUGFS 100#ifdef CONFIG_MAC80211_DEBUGFS
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 67ef562e8db1..cd4b61ae25b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -81,26 +81,6 @@
81 */ 81 */
82#define IWL49_FIRST_AMPDU_QUEUE 7 82#define IWL49_FIRST_AMPDU_QUEUE 7
83 83
84/* Time constants */
85#define SHORT_SLOT_TIME 9
86#define LONG_SLOT_TIME 20
87
88/* RSSI to dBm */
89#define IWL49_RSSI_OFFSET 44
90
91
92/* PCI registers */
93#define PCI_CFG_RETRY_TIMEOUT 0x041
94
95/* PCI register values */
96#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
97#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
98
99#define IWL_NUM_SCAN_RATES (2)
100
101#define IWL_DEFAULT_TX_RETRY 15
102
103
104/* Sizes and addresses for instruction and data memory (SRAM) in 84/* Sizes and addresses for instruction and data memory (SRAM) in
105 * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ 85 * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */
106#define IWL49_RTC_INST_LOWER_BOUND (0x000000) 86#define IWL49_RTC_INST_LOWER_BOUND (0x000000)
@@ -393,10 +373,6 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
393 * location(s) in command (struct iwl4965_txpowertable_cmd). 373 * location(s) in command (struct iwl4965_txpowertable_cmd).
394 */ 374 */
395 375
396/* Limit range of txpower output target to be between these values */
397#define IWL_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm = 1 milliwatt */
398#define IWL_TX_POWER_TARGET_POWER_MAX (16) /* 16 dBm */
399
400/** 376/**
401 * When MIMO is used (2 transmitters operating simultaneously), driver should 377 * When MIMO is used (2 transmitters operating simultaneously), driver should
402 * limit each transmitter to deliver a max of 3 dB below the regulatory limit 378 * limit each transmitter to deliver a max of 3 dB below the regulatory limit
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 83c52a682622..6edae9b83bb7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -46,6 +46,7 @@
46#include "iwl-calib.h" 46#include "iwl-calib.h"
47#include "iwl-sta.h" 47#include "iwl-sta.h"
48#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
49#include "iwl-agn.h"
49 50
50static int iwl4965_send_tx_power(struct iwl_priv *priv); 51static int iwl4965_send_tx_power(struct iwl_priv *priv);
51static int iwl4965_hw_get_temperature(struct iwl_priv *priv); 52static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -60,14 +61,6 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
60#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode" 61#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode"
61#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api) 62#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api)
62 63
63
64/* module parameters */
65static struct iwl_mod_params iwl4965_mod_params = {
66 .amsdu_size_8K = 1,
67 .restart_fw = 1,
68 /* the rest are 0 by default */
69};
70
71/* check contents of special bootstrap uCode SRAM */ 64/* check contents of special bootstrap uCode SRAM */
72static int iwl4965_verify_bsm(struct iwl_priv *priv) 65static int iwl4965_verify_bsm(struct iwl_priv *priv)
73{ 66{
@@ -417,7 +410,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
417 sizeof(cmd), &cmd); 410 sizeof(cmd), &cmd);
418 if (ret) 411 if (ret)
419 IWL_DEBUG_CALIB(priv, "fail sending cmd " 412 IWL_DEBUG_CALIB(priv, "fail sending cmd "
420 "REPLY_PHY_CALIBRATION_CMD \n"); 413 "REPLY_PHY_CALIBRATION_CMD\n");
421 414
422 /* TODO we might want recalculate 415 /* TODO we might want recalculate
423 * rx_chain in rxon cmd */ 416 * rx_chain in rxon cmd */
@@ -502,14 +495,14 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
502 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); 495 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
503} 496}
504 497
505static const u16 default_queue_to_tx_fifo[] = { 498static const s8 default_queue_to_tx_fifo[] = {
506 IWL_TX_FIFO_AC3, 499 IWL_TX_FIFO_VO,
507 IWL_TX_FIFO_AC2, 500 IWL_TX_FIFO_VI,
508 IWL_TX_FIFO_AC1, 501 IWL_TX_FIFO_BE,
509 IWL_TX_FIFO_AC0, 502 IWL_TX_FIFO_BK,
510 IWL49_CMD_FIFO_NUM, 503 IWL49_CMD_FIFO_NUM,
511 IWL_TX_FIFO_HCCA_1, 504 IWL_TX_FIFO_UNUSED,
512 IWL_TX_FIFO_HCCA_2 505 IWL_TX_FIFO_UNUSED,
513}; 506};
514 507
515static int iwl4965_alive_notify(struct iwl_priv *priv) 508static int iwl4965_alive_notify(struct iwl_priv *priv)
@@ -589,9 +582,15 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
589 /* reset to 0 to enable all the queue first */ 582 /* reset to 0 to enable all the queue first */
590 priv->txq_ctx_active_msk = 0; 583 priv->txq_ctx_active_msk = 0;
591 /* Map each Tx/cmd queue to its corresponding fifo */ 584 /* Map each Tx/cmd queue to its corresponding fifo */
585 BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
592 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { 586 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
593 int ac = default_queue_to_tx_fifo[i]; 587 int ac = default_queue_to_tx_fifo[i];
588
594 iwl_txq_ctx_activate(priv, i); 589 iwl_txq_ctx_activate(priv, i);
590
591 if (ac == IWL_TX_FIFO_UNUSED)
592 continue;
593
595 iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); 594 iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
596 } 595 }
597 596
@@ -1613,19 +1612,19 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
1613 1612
1614 /* get absolute value */ 1613 /* get absolute value */
1615 if (temp_diff < 0) { 1614 if (temp_diff < 0) {
1616 IWL_DEBUG_POWER(priv, "Getting cooler, delta %d, \n", temp_diff); 1615 IWL_DEBUG_POWER(priv, "Getting cooler, delta %d\n", temp_diff);
1617 temp_diff = -temp_diff; 1616 temp_diff = -temp_diff;
1618 } else if (temp_diff == 0) 1617 } else if (temp_diff == 0)
1619 IWL_DEBUG_POWER(priv, "Same temp, \n"); 1618 IWL_DEBUG_POWER(priv, "Temperature unchanged\n");
1620 else 1619 else
1621 IWL_DEBUG_POWER(priv, "Getting warmer, delta %d, \n", temp_diff); 1620 IWL_DEBUG_POWER(priv, "Getting warmer, delta %d\n", temp_diff);
1622 1621
1623 if (temp_diff < IWL_TEMPERATURE_THRESHOLD) { 1622 if (temp_diff < IWL_TEMPERATURE_THRESHOLD) {
1624 IWL_DEBUG_POWER(priv, "Thermal txpower calib not needed\n"); 1623 IWL_DEBUG_POWER(priv, " => thermal txpower calib not needed\n");
1625 return 0; 1624 return 0;
1626 } 1625 }
1627 1626
1628 IWL_DEBUG_POWER(priv, "Thermal txpower calib needed\n"); 1627 IWL_DEBUG_POWER(priv, " => thermal txpower calib needed\n");
1629 1628
1630 return 1; 1629 return 1;
1631} 1630}
@@ -1874,7 +1873,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
1874 info->status.rates[0].count = tx_resp->failure_frame + 1; 1873 info->status.rates[0].count = tx_resp->failure_frame + 1;
1875 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 1874 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1876 info->flags |= iwl_tx_status_to_mac80211(status); 1875 info->flags |= iwl_tx_status_to_mac80211(status);
1877 iwl_hwrate_to_tx_control(priv, rate_n_flags, info); 1876 iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
1878 /* FIXME: code repetition end */ 1877 /* FIXME: code repetition end */
1879 1878
1880 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", 1879 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
@@ -2014,7 +2013,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2014 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); 2013 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
2015 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " 2014 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
2016 "%d index %d\n", scd_ssn , index); 2015 "%d index %d\n", scd_ssn , index);
2017 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2016 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
2018 iwl_free_tfds_in_queue(priv, sta_id, tid, freed); 2017 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
2019 2018
2020 if (priv->mac80211_registered && 2019 if (priv->mac80211_registered &&
@@ -2029,7 +2028,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2029 } else { 2028 } else {
2030 info->status.rates[0].count = tx_resp->failure_frame + 1; 2029 info->status.rates[0].count = tx_resp->failure_frame + 1;
2031 info->flags |= iwl_tx_status_to_mac80211(status); 2030 info->flags |= iwl_tx_status_to_mac80211(status);
2032 iwl_hwrate_to_tx_control(priv, 2031 iwlagn_hwrate_to_tx_control(priv,
2033 le32_to_cpu(tx_resp->rate_n_flags), 2032 le32_to_cpu(tx_resp->rate_n_flags),
2034 info); 2033 info);
2035 2034
@@ -2040,7 +2039,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2040 le32_to_cpu(tx_resp->rate_n_flags), 2039 le32_to_cpu(tx_resp->rate_n_flags),
2041 tx_resp->failure_frame); 2040 tx_resp->failure_frame);
2042 2041
2043 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2042 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
2044 iwl_free_tfds_in_queue(priv, sta_id, tid, freed); 2043 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
2045 2044
2046 if (priv->mac80211_registered && 2045 if (priv->mac80211_registered &&
@@ -2048,7 +2047,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2048 iwl_wake_queue(priv, txq_id); 2047 iwl_wake_queue(priv, txq_id);
2049 } 2048 }
2050 2049
2051 iwl_txq_check_empty(priv, sta_id, tid, txq_id); 2050 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
2052 2051
2053 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 2052 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
2054 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); 2053 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
@@ -2085,7 +2084,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
2085 2084
2086 /* dBm = max_rssi dB - agc dB - constant. 2085 /* dBm = max_rssi dB - agc dB - constant.
2087 * Higher AGC (higher radio gain) means lower signal. */ 2086 * Higher AGC (higher radio gain) means lower signal. */
2088 return max_rssi - agc - IWL49_RSSI_OFFSET; 2087 return max_rssi - agc - IWLAGN_RSSI_OFFSET;
2089} 2088}
2090 2089
2091 2090
@@ -2093,7 +2092,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
2093static void iwl4965_rx_handler_setup(struct iwl_priv *priv) 2092static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
2094{ 2093{
2095 /* Legacy Rx frames */ 2094 /* Legacy Rx frames */
2096 priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx; 2095 priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx;
2097 /* Tx response */ 2096 /* Tx response */
2098 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; 2097 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
2099} 2098}
@@ -2179,6 +2178,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2179 .load_ucode = iwl4965_load_bsm, 2178 .load_ucode = iwl4965_load_bsm,
2180 .dump_nic_event_log = iwl_dump_nic_event_log, 2179 .dump_nic_event_log = iwl_dump_nic_event_log,
2181 .dump_nic_error_log = iwl_dump_nic_error_log, 2180 .dump_nic_error_log = iwl_dump_nic_error_log,
2181 .dump_fh = iwl_dump_fh,
2182 .set_channel_switch = iwl4965_hw_channel_switch, 2182 .set_channel_switch = iwl4965_hw_channel_switch,
2183 .apm_ops = { 2183 .apm_ops = {
2184 .init = iwl_apm_init, 2184 .init = iwl_apm_init,
@@ -2212,6 +2212,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2212 .set_ct_kill = iwl4965_set_ct_threshold, 2212 .set_ct_kill = iwl4965_set_ct_threshold,
2213 }, 2213 },
2214 .add_bcast_station = iwl_add_bcast_station, 2214 .add_bcast_station = iwl_add_bcast_station,
2215 .check_plcp_health = iwl_good_plcp_health,
2215}; 2216};
2216 2217
2217static const struct iwl_ops iwl4965_ops = { 2218static const struct iwl_ops iwl4965_ops = {
@@ -2223,7 +2224,7 @@ static const struct iwl_ops iwl4965_ops = {
2223}; 2224};
2224 2225
2225struct iwl_cfg iwl4965_agn_cfg = { 2226struct iwl_cfg iwl4965_agn_cfg = {
2226 .name = "4965AGN", 2227 .name = "Intel(R) Wireless WiFi Link 4965AGN",
2227 .fw_name_pre = IWL4965_FW_PRE, 2228 .fw_name_pre = IWL4965_FW_PRE,
2228 .ucode_api_max = IWL4965_UCODE_API_MAX, 2229 .ucode_api_max = IWL4965_UCODE_API_MAX,
2229 .ucode_api_min = IWL4965_UCODE_API_MIN, 2230 .ucode_api_min = IWL4965_UCODE_API_MIN,
@@ -2234,7 +2235,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2234 .ops = &iwl4965_ops, 2235 .ops = &iwl4965_ops,
2235 .num_of_queues = IWL49_NUM_QUEUES, 2236 .num_of_queues = IWL49_NUM_QUEUES,
2236 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, 2237 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
2237 .mod_params = &iwl4965_mod_params, 2238 .mod_params = &iwlagn_mod_params,
2238 .valid_tx_ant = ANT_AB, 2239 .valid_tx_ant = ANT_AB,
2239 .valid_rx_ant = ANT_ABC, 2240 .valid_rx_ant = ANT_ABC,
2240 .pll_cfg_val = 0, 2241 .pll_cfg_val = 0,
@@ -2246,27 +2247,11 @@ struct iwl_cfg iwl4965_agn_cfg = {
2246 .led_compensation = 61, 2247 .led_compensation = 61,
2247 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2248 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2248 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2250 .monitor_recover_period = IWL_MONITORING_PERIOD,
2251 .temperature_kelvin = true,
2252 .off_channel_workaround = true,
2249}; 2253};
2250 2254
2251/* Module firmware */ 2255/* Module firmware */
2252MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); 2256MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
2253 2257
2254module_param_named(antenna, iwl4965_mod_params.antenna, int, S_IRUGO);
2255MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
2256module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, S_IRUGO);
2257MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
2258module_param_named(
2259 disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, S_IRUGO);
2260MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
2261
2262module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, S_IRUGO);
2263MODULE_PARM_DESC(queues_num, "number of hw queues.");
2264/* 11n */
2265module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, S_IRUGO);
2266MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
2267module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K,
2268 int, S_IRUGO);
2269MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
2270
2271module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, S_IRUGO);
2272MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 714e032f6217..146e6431ae95 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -68,25 +68,6 @@
68#ifndef __iwl_5000_hw_h__ 68#ifndef __iwl_5000_hw_h__
69#define __iwl_5000_hw_h__ 69#define __iwl_5000_hw_h__
70 70
71#define IWL50_RTC_INST_LOWER_BOUND (0x000000)
72#define IWL50_RTC_INST_UPPER_BOUND (0x020000)
73
74#define IWL50_RTC_DATA_LOWER_BOUND (0x800000)
75#define IWL50_RTC_DATA_UPPER_BOUND (0x80C000)
76
77#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - \
78 IWL50_RTC_INST_LOWER_BOUND)
79#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - \
80 IWL50_RTC_DATA_LOWER_BOUND)
81
82/* EEPROM */
83#define IWL_5000_EEPROM_IMG_SIZE 2048
84
85#define IWL50_CMD_FIFO_NUM 7
86#define IWL50_NUM_QUEUES 20
87#define IWL50_NUM_AMPDU_QUEUES 10
88#define IWL50_FIRST_AMPDU_QUEUE 10
89
90/* 5150 only */ 71/* 5150 only */
91#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5) 72#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
92 73
@@ -103,19 +84,5 @@ static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
103 return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); 84 return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
104} 85}
105 86
106/* Fixed (non-configurable) rx data from phy */
107
108/**
109 * struct iwl5000_schedq_bc_tbl scheduler byte count table
110 * base physical address of iwl5000_shared
111 * is provided to SCD_DRAM_BASE_ADDR
112 * @tfd_offset 0-12 - tx command byte count
113 * 12-16 - station index
114 */
115struct iwl5000_scd_bc_tbl {
116 __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
117} __attribute__ ((packed));
118
119
120#endif /* __iwl_5000_hw_h__ */ 87#endif /* __iwl_5000_hw_h__ */
121 88
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index e476acb53aa7..ecc302e4c205 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -19,6 +19,7 @@
19 * file called LICENSE. 19 * file called LICENSE.
20 * 20 *
21 * Contact Information: 21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
22 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
23 * 24 *
24 *****************************************************************************/ 25 *****************************************************************************/
@@ -43,9 +44,10 @@
43#include "iwl-io.h" 44#include "iwl-io.h"
44#include "iwl-sta.h" 45#include "iwl-sta.h"
45#include "iwl-helpers.h" 46#include "iwl-helpers.h"
47#include "iwl-agn.h"
46#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
49#include "iwl-agn-hw.h"
47#include "iwl-5000-hw.h" 50#include "iwl-5000-hw.h"
48#include "iwl-6000-hw.h"
49 51
50/* Highest firmware API version supported */ 52/* Highest firmware API version supported */
51#define IWL5000_UCODE_API_MAX 2 53#define IWL5000_UCODE_API_MAX 2
@@ -63,18 +65,8 @@
63#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" 65#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
64#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) 66#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
65 67
66static const u16 iwl5000_default_queue_to_tx_fifo[] = {
67 IWL_TX_FIFO_AC3,
68 IWL_TX_FIFO_AC2,
69 IWL_TX_FIFO_AC1,
70 IWL_TX_FIFO_AC0,
71 IWL50_CMD_FIFO_NUM,
72 IWL_TX_FIFO_HCCA_1,
73 IWL_TX_FIFO_HCCA_2
74};
75
76/* NIC configuration for 5000 series */ 68/* NIC configuration for 5000 series */
77void iwl5000_nic_config(struct iwl_priv *priv) 69static void iwl5000_nic_config(struct iwl_priv *priv)
78{ 70{
79 unsigned long flags; 71 unsigned long flags;
80 u16 radio_cfg; 72 u16 radio_cfg;
@@ -107,162 +99,6 @@ void iwl5000_nic_config(struct iwl_priv *priv)
107 spin_unlock_irqrestore(&priv->lock, flags); 99 spin_unlock_irqrestore(&priv->lock, flags);
108} 100}
109 101
110
111/*
112 * EEPROM
113 */
114static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
115{
116 u16 offset = 0;
117
118 if ((address & INDIRECT_ADDRESS) == 0)
119 return address;
120
121 switch (address & INDIRECT_TYPE_MSK) {
122 case INDIRECT_HOST:
123 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_HOST);
124 break;
125 case INDIRECT_GENERAL:
126 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_GENERAL);
127 break;
128 case INDIRECT_REGULATORY:
129 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_REGULATORY);
130 break;
131 case INDIRECT_CALIBRATION:
132 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_CALIBRATION);
133 break;
134 case INDIRECT_PROCESS_ADJST:
135 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_PROCESS_ADJST);
136 break;
137 case INDIRECT_OTHERS:
138 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
139 break;
140 default:
141 IWL_ERR(priv, "illegal indirect type: 0x%X\n",
142 address & INDIRECT_TYPE_MSK);
143 break;
144 }
145
146 /* translate the offset from words to byte */
147 return (address & ADDRESS_MSK) + (offset << 1);
148}
149
150u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv)
151{
152 struct iwl_eeprom_calib_hdr {
153 u8 version;
154 u8 pa_type;
155 u16 voltage;
156 } *hdr;
157
158 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
159 EEPROM_5000_CALIB_ALL);
160 return hdr->version;
161
162}
163
164static void iwl5000_gain_computation(struct iwl_priv *priv,
165 u32 average_noise[NUM_RX_CHAINS],
166 u16 min_average_noise_antenna_i,
167 u32 min_average_noise,
168 u8 default_chain)
169{
170 int i;
171 s32 delta_g;
172 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
173
174 /*
175 * Find Gain Code for the chains based on "default chain"
176 */
177 for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
178 if ((data->disconn_array[i])) {
179 data->delta_gain_code[i] = 0;
180 continue;
181 }
182
183 delta_g = (priv->cfg->chain_noise_scale *
184 ((s32)average_noise[default_chain] -
185 (s32)average_noise[i])) / 1500;
186
187 /* bound gain by 2 bits value max, 3rd bit is sign */
188 data->delta_gain_code[i] =
189 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
190
191 if (delta_g < 0)
192 /*
193 * set negative sign ...
194 * note to Intel developers: This is uCode API format,
195 * not the format of any internal device registers.
196 * Do not change this format for e.g. 6050 or similar
197 * devices. Change format only if more resolution
198 * (i.e. more than 2 bits magnitude) is needed.
199 */
200 data->delta_gain_code[i] |= (1 << 2);
201 }
202
203 IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d ANT_C = %d\n",
204 data->delta_gain_code[1], data->delta_gain_code[2]);
205
206 if (!data->radio_write) {
207 struct iwl_calib_chain_noise_gain_cmd cmd;
208
209 memset(&cmd, 0, sizeof(cmd));
210
211 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
212 cmd.hdr.first_group = 0;
213 cmd.hdr.groups_num = 1;
214 cmd.hdr.data_valid = 1;
215 cmd.delta_gain_1 = data->delta_gain_code[1];
216 cmd.delta_gain_2 = data->delta_gain_code[2];
217 iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
218 sizeof(cmd), &cmd, NULL);
219
220 data->radio_write = 1;
221 data->state = IWL_CHAIN_NOISE_CALIBRATED;
222 }
223
224 data->chain_noise_a = 0;
225 data->chain_noise_b = 0;
226 data->chain_noise_c = 0;
227 data->chain_signal_a = 0;
228 data->chain_signal_b = 0;
229 data->chain_signal_c = 0;
230 data->beacon_count = 0;
231}
232
233static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
234{
235 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
236 int ret;
237
238 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
239 struct iwl_calib_chain_noise_reset_cmd cmd;
240 memset(&cmd, 0, sizeof(cmd));
241
242 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
243 cmd.hdr.first_group = 0;
244 cmd.hdr.groups_num = 1;
245 cmd.hdr.data_valid = 1;
246 ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
247 sizeof(cmd), &cmd);
248 if (ret)
249 IWL_ERR(priv,
250 "Could not send REPLY_PHY_CALIBRATION_CMD\n");
251 data->state = IWL_CHAIN_NOISE_ACCUMULATE;
252 IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
253 }
254}
255
256void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
257 __le32 *tx_flags)
258{
259 if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
260 (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
261 *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
262 else
263 *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK;
264}
265
266static struct iwl_sensitivity_ranges iwl5000_sensitivity = { 102static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
267 .min_nrg_cck = 95, 103 .min_nrg_cck = 95,
268 .max_nrg_cck = 0, /* not used, set to 0 */ 104 .max_nrg_cck = 0, /* not used, set to 0 */
@@ -314,14 +150,6 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
314 .nrg_th_cca = 62, 150 .nrg_th_cca = 62,
315}; 151};
316 152
317const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
318 size_t offset)
319{
320 u32 address = eeprom_indirect_address(priv, offset);
321 BUG_ON(address >= priv->cfg->eeprom_size);
322 return &priv->eeprom[address];
323}
324
325static void iwl5150_set_ct_threshold(struct iwl_priv *priv) 153static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
326{ 154{
327 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF; 155 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
@@ -337,356 +165,10 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
337 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; 165 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
338} 166}
339 167
340/* 168static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
341 * Calibration
342 */
343static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
344{
345 struct iwl_calib_xtal_freq_cmd cmd;
346 __le16 *xtal_calib =
347 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
348
349 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
350 cmd.hdr.first_group = 0;
351 cmd.hdr.groups_num = 1;
352 cmd.hdr.data_valid = 1;
353 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
354 cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
355 return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
356 (u8 *)&cmd, sizeof(cmd));
357}
358
359static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
360{
361 struct iwl_calib_cfg_cmd calib_cfg_cmd;
362 struct iwl_host_cmd cmd = {
363 .id = CALIBRATION_CFG_CMD,
364 .len = sizeof(struct iwl_calib_cfg_cmd),
365 .data = &calib_cfg_cmd,
366 };
367
368 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
369 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
370 calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL;
371 calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL;
372 calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL;
373
374 return iwl_send_cmd(priv, &cmd);
375}
376
377static void iwl5000_rx_calib_result(struct iwl_priv *priv,
378 struct iwl_rx_mem_buffer *rxb)
379{
380 struct iwl_rx_packet *pkt = rxb_addr(rxb);
381 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
382 int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
383 int index;
384
385 /* reduce the size of the length field itself */
386 len -= 4;
387
388 /* Define the order in which the results will be sent to the runtime
389 * uCode. iwl_send_calib_results sends them in a row according to their
390 * index. We sort them here */
391 switch (hdr->op_code) {
392 case IWL_PHY_CALIBRATE_DC_CMD:
393 index = IWL_CALIB_DC;
394 break;
395 case IWL_PHY_CALIBRATE_LO_CMD:
396 index = IWL_CALIB_LO;
397 break;
398 case IWL_PHY_CALIBRATE_TX_IQ_CMD:
399 index = IWL_CALIB_TX_IQ;
400 break;
401 case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD:
402 index = IWL_CALIB_TX_IQ_PERD;
403 break;
404 case IWL_PHY_CALIBRATE_BASE_BAND_CMD:
405 index = IWL_CALIB_BASE_BAND;
406 break;
407 default:
408 IWL_ERR(priv, "Unknown calibration notification %d\n",
409 hdr->op_code);
410 return;
411 }
412 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
413}
414
415static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
416 struct iwl_rx_mem_buffer *rxb)
417{
418 IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
419 queue_work(priv->workqueue, &priv->restart);
420}
421
422/*
423 * ucode
424 */
425static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
426 struct fw_desc *image, u32 dst_addr)
427{
428 dma_addr_t phy_addr = image->p_addr;
429 u32 byte_cnt = image->len;
430 int ret;
431
432 priv->ucode_write_complete = 0;
433
434 iwl_write_direct32(priv,
435 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
436 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
437
438 iwl_write_direct32(priv,
439 FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
440
441 iwl_write_direct32(priv,
442 FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
443 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
444
445 iwl_write_direct32(priv,
446 FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
447 (iwl_get_dma_hi_addr(phy_addr)
448 << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
449
450 iwl_write_direct32(priv,
451 FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
452 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
453 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
454 FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
455
456 iwl_write_direct32(priv,
457 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
458 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
459 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
460 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
461
462 IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
463 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
464 priv->ucode_write_complete, 5 * HZ);
465 if (ret == -ERESTARTSYS) {
466 IWL_ERR(priv, "Could not load the %s uCode section due "
467 "to interrupt\n", name);
468 return ret;
469 }
470 if (!ret) {
471 IWL_ERR(priv, "Could not load the %s uCode section\n",
472 name);
473 return -ETIMEDOUT;
474 }
475
476 return 0;
477}
478
479static int iwl5000_load_given_ucode(struct iwl_priv *priv,
480 struct fw_desc *inst_image,
481 struct fw_desc *data_image)
482{
483 int ret = 0;
484
485 ret = iwl5000_load_section(priv, "INST", inst_image,
486 IWL50_RTC_INST_LOWER_BOUND);
487 if (ret)
488 return ret;
489
490 return iwl5000_load_section(priv, "DATA", data_image,
491 IWL50_RTC_DATA_LOWER_BOUND);
492}
493
494int iwl5000_load_ucode(struct iwl_priv *priv)
495{
496 int ret = 0;
497
498 /* check whether init ucode should be loaded, or rather runtime ucode */
499 if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
500 IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
501 ret = iwl5000_load_given_ucode(priv,
502 &priv->ucode_init, &priv->ucode_init_data);
503 if (!ret) {
504 IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
505 priv->ucode_type = UCODE_INIT;
506 }
507 } else {
508 IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
509 "Loading runtime ucode...\n");
510 ret = iwl5000_load_given_ucode(priv,
511 &priv->ucode_code, &priv->ucode_data);
512 if (!ret) {
513 IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
514 priv->ucode_type = UCODE_RT;
515 }
516 }
517
518 return ret;
519}
520
521void iwl5000_init_alive_start(struct iwl_priv *priv)
522{
523 int ret = 0;
524
525 /* Check alive response for "valid" sign from uCode */
526 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
527 /* We had an error bringing up the hardware, so take it
528 * all the way back down so we can try again */
529 IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
530 goto restart;
531 }
532
533 /* initialize uCode was loaded... verify inst image.
534 * This is a paranoid check, because we would not have gotten the
535 * "initialize" alive if code weren't properly loaded. */
536 if (iwl_verify_ucode(priv)) {
537 /* Runtime instruction load was bad;
538 * take it all the way back down so we can try again */
539 IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
540 goto restart;
541 }
542
543 iwl_clear_stations_table(priv);
544 ret = priv->cfg->ops->lib->alive_notify(priv);
545 if (ret) {
546 IWL_WARN(priv,
547 "Could not complete ALIVE transition: %d\n", ret);
548 goto restart;
549 }
550
551 iwl5000_send_calib_cfg(priv);
552 return;
553
554restart:
555 /* real restart (first load init_ucode) */
556 queue_work(priv->workqueue, &priv->restart);
557}
558
559static void iwl5000_set_wr_ptrs(struct iwl_priv *priv,
560 int txq_id, u32 index)
561{
562 iwl_write_direct32(priv, HBUS_TARG_WRPTR,
563 (index & 0xff) | (txq_id << 8));
564 iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(txq_id), index);
565}
566
567static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
568 struct iwl_tx_queue *txq,
569 int tx_fifo_id, int scd_retry)
570{
571 int txq_id = txq->q.id;
572 int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
573
574 iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
575 (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
576 (tx_fifo_id << IWL50_SCD_QUEUE_STTS_REG_POS_TXF) |
577 (1 << IWL50_SCD_QUEUE_STTS_REG_POS_WSL) |
578 IWL50_SCD_QUEUE_STTS_REG_MSK);
579
580 txq->sched_retry = scd_retry;
581
582 IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
583 active ? "Activate" : "Deactivate",
584 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
585}
586
587int iwl5000_alive_notify(struct iwl_priv *priv)
588{
589 u32 a;
590 unsigned long flags;
591 int i, chan;
592 u32 reg_val;
593
594 spin_lock_irqsave(&priv->lock, flags);
595
596 priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR);
597 a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET;
598 for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET;
599 a += 4)
600 iwl_write_targ_mem(priv, a, 0);
601 for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
602 a += 4)
603 iwl_write_targ_mem(priv, a, 0);
604 for (; a < priv->scd_base_addr +
605 IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
606 iwl_write_targ_mem(priv, a, 0);
607
608 iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
609 priv->scd_bc_tbls.dma >> 10);
610
611 /* Enable DMA channel */
612 for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++)
613 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
614 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
615 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
616
617 /* Update FH chicken bits */
618 reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
619 iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
620 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
621
622 iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
623 IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
624 iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
625
626 /* initiate the queues */
627 for (i = 0; i < priv->hw_params.max_txq_num; i++) {
628 iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(i), 0);
629 iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
630 iwl_write_targ_mem(priv, priv->scd_base_addr +
631 IWL50_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
632 iwl_write_targ_mem(priv, priv->scd_base_addr +
633 IWL50_SCD_CONTEXT_QUEUE_OFFSET(i) +
634 sizeof(u32),
635 ((SCD_WIN_SIZE <<
636 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
637 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
638 ((SCD_FRAME_LIMIT <<
639 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
640 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
641 }
642
643 iwl_write_prph(priv, IWL50_SCD_INTERRUPT_MASK,
644 IWL_MASK(0, priv->hw_params.max_txq_num));
645
646 /* Activate all Tx DMA/FIFO channels */
647 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
648
649 iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
650
651 /* make sure all queue are not stopped */
652 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
653 for (i = 0; i < 4; i++)
654 atomic_set(&priv->queue_stop_count[i], 0);
655
656 /* reset to 0 to enable all the queue first */
657 priv->txq_ctx_active_msk = 0;
658 /* map qos queues to fifos one-to-one */
659 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
660 int ac = iwl5000_default_queue_to_tx_fifo[i];
661 iwl_txq_ctx_activate(priv, i);
662 iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
663 }
664
665 /*
666 * TODO - need to initialize these queues and map them to FIFOs
667 * in the loop above, not only mark them as active. We do this
668 * because we want the first aggregation queue to be queue #10,
669 * but do not use 8 or 9 otherwise yet.
670 */
671 iwl_txq_ctx_activate(priv, 7);
672 iwl_txq_ctx_activate(priv, 8);
673 iwl_txq_ctx_activate(priv, 9);
674
675 spin_unlock_irqrestore(&priv->lock, flags);
676
677
678 iwl_send_wimax_coex(priv);
679
680 iwl5000_set_Xtal_calib(priv);
681 iwl_send_calib_results(priv);
682
683 return 0;
684}
685
686int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
687{ 169{
688 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 170 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
689 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) 171 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
690 priv->cfg->num_of_queues = 172 priv->cfg->num_of_queues =
691 priv->cfg->mod_params->num_of_queues; 173 priv->cfg->mod_params->num_of_queues;
692 174
@@ -694,13 +176,13 @@ int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
694 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 176 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
695 priv->hw_params.scd_bc_tbls_size = 177 priv->hw_params.scd_bc_tbls_size =
696 priv->cfg->num_of_queues * 178 priv->cfg->num_of_queues *
697 sizeof(struct iwl5000_scd_bc_tbl); 179 sizeof(struct iwlagn_scd_bc_tbl);
698 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 180 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
699 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 181 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
700 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 182 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
701 183
702 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; 184 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
703 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE; 185 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
704 186
705 priv->hw_params.max_bsm_size = 0; 187 priv->hw_params.max_bsm_size = 0;
706 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 188 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
@@ -741,547 +223,6 @@ int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
741 return 0; 223 return 0;
742} 224}
743 225
744/**
745 * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
746 */
747void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
748 struct iwl_tx_queue *txq,
749 u16 byte_cnt)
750{
751 struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
752 int write_ptr = txq->q.write_ptr;
753 int txq_id = txq->q.id;
754 u8 sec_ctl = 0;
755 u8 sta_id = 0;
756 u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
757 __le16 bc_ent;
758
759 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
760
761 if (txq_id != IWL_CMD_QUEUE_NUM) {
762 sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
763 sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
764
765 switch (sec_ctl & TX_CMD_SEC_MSK) {
766 case TX_CMD_SEC_CCM:
767 len += CCMP_MIC_LEN;
768 break;
769 case TX_CMD_SEC_TKIP:
770 len += TKIP_ICV_LEN;
771 break;
772 case TX_CMD_SEC_WEP:
773 len += WEP_IV_LEN + WEP_ICV_LEN;
774 break;
775 }
776 }
777
778 bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
779
780 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
781
782 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
783 scd_bc_tbl[txq_id].
784 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
785}
786
787void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
788 struct iwl_tx_queue *txq)
789{
790 struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
791 int txq_id = txq->q.id;
792 int read_ptr = txq->q.read_ptr;
793 u8 sta_id = 0;
794 __le16 bc_ent;
795
796 WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
797
798 if (txq_id != IWL_CMD_QUEUE_NUM)
799 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
800
801 bc_ent = cpu_to_le16(1 | (sta_id << 12));
802 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
803
804 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
805 scd_bc_tbl[txq_id].
806 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
807}
808
809static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
810 u16 txq_id)
811{
812 u32 tbl_dw_addr;
813 u32 tbl_dw;
814 u16 scd_q2ratid;
815
816 scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
817
818 tbl_dw_addr = priv->scd_base_addr +
819 IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
820
821 tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
822
823 if (txq_id & 0x1)
824 tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
825 else
826 tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
827
828 iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
829
830 return 0;
831}
832static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
833{
834 /* Simply stop the queue, but don't change any configuration;
835 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
836 iwl_write_prph(priv,
837 IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
838 (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
839 (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
840}
841
842int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
843 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
844{
845 unsigned long flags;
846 u16 ra_tid;
847
848 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
849 (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
850 <= txq_id)) {
851 IWL_WARN(priv,
852 "queue number out of range: %d, must be %d to %d\n",
853 txq_id, IWL50_FIRST_AMPDU_QUEUE,
854 IWL50_FIRST_AMPDU_QUEUE +
855 priv->cfg->num_of_ampdu_queues - 1);
856 return -EINVAL;
857 }
858
859 ra_tid = BUILD_RAxTID(sta_id, tid);
860
861 /* Modify device's station table to Tx this TID */
862 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
863
864 spin_lock_irqsave(&priv->lock, flags);
865
866 /* Stop this Tx queue before configuring it */
867 iwl5000_tx_queue_stop_scheduler(priv, txq_id);
868
869 /* Map receiver-address / traffic-ID to this queue */
870 iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
871
872 /* Set this queue as a chain-building queue */
873 iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
874
875 /* enable aggregations for the queue */
876 iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
877
878 /* Place first TFD at index corresponding to start sequence number.
879 * Assumes that ssn_idx is valid (!= 0xFFF) */
880 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
881 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
882 iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
883
884 /* Set up Tx window size and frame limit for this queue */
885 iwl_write_targ_mem(priv, priv->scd_base_addr +
886 IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
887 sizeof(u32),
888 ((SCD_WIN_SIZE <<
889 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
890 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
891 ((SCD_FRAME_LIMIT <<
892 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
893 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
894
895 iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
896
897 /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
898 iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
899
900 spin_unlock_irqrestore(&priv->lock, flags);
901
902 return 0;
903}
904
905int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
906 u16 ssn_idx, u8 tx_fifo)
907{
908 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
909 (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
910 <= txq_id)) {
911 IWL_ERR(priv,
912 "queue number out of range: %d, must be %d to %d\n",
913 txq_id, IWL50_FIRST_AMPDU_QUEUE,
914 IWL50_FIRST_AMPDU_QUEUE +
915 priv->cfg->num_of_ampdu_queues - 1);
916 return -EINVAL;
917 }
918
919 iwl5000_tx_queue_stop_scheduler(priv, txq_id);
920
921 iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
922
923 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
924 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
925 /* supposes that ssn_idx is valid (!= 0xFFF) */
926 iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
927
928 iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
929 iwl_txq_ctx_deactivate(priv, txq_id);
930 iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
931
932 return 0;
933}
934
935u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
936{
937 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
938 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
939 memcpy(addsta, cmd, size);
940 /* resrved in 5000 */
941 addsta->rate_n_flags = cpu_to_le16(0);
942 return size;
943}
944
945
946/*
947 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
948 * must be called under priv->lock and mac access
949 */
950void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
951{
952 iwl_write_prph(priv, IWL50_SCD_TXFACT, mask);
953}
954
955
956static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
957{
958 return le32_to_cpup((__le32 *)&tx_resp->status +
959 tx_resp->frame_count) & MAX_SN;
960}
961
962static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
963 struct iwl_ht_agg *agg,
964 struct iwl5000_tx_resp *tx_resp,
965 int txq_id, u16 start_idx)
966{
967 u16 status;
968 struct agg_tx_status *frame_status = &tx_resp->status;
969 struct ieee80211_tx_info *info = NULL;
970 struct ieee80211_hdr *hdr = NULL;
971 u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
972 int i, sh, idx;
973 u16 seq;
974
975 if (agg->wait_for_ba)
976 IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
977
978 agg->frame_count = tx_resp->frame_count;
979 agg->start_idx = start_idx;
980 agg->rate_n_flags = rate_n_flags;
981 agg->bitmap = 0;
982
983 /* # frames attempted by Tx command */
984 if (agg->frame_count == 1) {
985 /* Only one frame was attempted; no block-ack will arrive */
986 status = le16_to_cpu(frame_status[0].status);
987 idx = start_idx;
988
989 /* FIXME: code repetition */
990 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
991 agg->frame_count, agg->start_idx, idx);
992
993 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
994 info->status.rates[0].count = tx_resp->failure_frame + 1;
995 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
996 info->flags |= iwl_tx_status_to_mac80211(status);
997 iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
998
999 /* FIXME: code repetition end */
1000
1001 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
1002 status & 0xff, tx_resp->failure_frame);
1003 IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
1004
1005 agg->wait_for_ba = 0;
1006 } else {
1007 /* Two or more frames were attempted; expect block-ack */
1008 u64 bitmap = 0;
1009 int start = agg->start_idx;
1010
1011 /* Construct bit-map of pending frames within Tx window */
1012 for (i = 0; i < agg->frame_count; i++) {
1013 u16 sc;
1014 status = le16_to_cpu(frame_status[i].status);
1015 seq = le16_to_cpu(frame_status[i].sequence);
1016 idx = SEQ_TO_INDEX(seq);
1017 txq_id = SEQ_TO_QUEUE(seq);
1018
1019 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
1020 AGG_TX_STATE_ABORT_MSK))
1021 continue;
1022
1023 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
1024 agg->frame_count, txq_id, idx);
1025
1026 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
1027 if (!hdr) {
1028 IWL_ERR(priv,
1029 "BUG_ON idx doesn't point to valid skb"
1030 " idx=%d, txq_id=%d\n", idx, txq_id);
1031 return -1;
1032 }
1033
1034 sc = le16_to_cpu(hdr->seq_ctrl);
1035 if (idx != (SEQ_TO_SN(sc) & 0xff)) {
1036 IWL_ERR(priv,
1037 "BUG_ON idx doesn't match seq control"
1038 " idx=%d, seq_idx=%d, seq=%d\n",
1039 idx, SEQ_TO_SN(sc),
1040 hdr->seq_ctrl);
1041 return -1;
1042 }
1043
1044 IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
1045 i, idx, SEQ_TO_SN(sc));
1046
1047 sh = idx - start;
1048 if (sh > 64) {
1049 sh = (start - idx) + 0xff;
1050 bitmap = bitmap << sh;
1051 sh = 0;
1052 start = idx;
1053 } else if (sh < -64)
1054 sh = 0xff - (start - idx);
1055 else if (sh < 0) {
1056 sh = start - idx;
1057 start = idx;
1058 bitmap = bitmap << sh;
1059 sh = 0;
1060 }
1061 bitmap |= 1ULL << sh;
1062 IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
1063 start, (unsigned long long)bitmap);
1064 }
1065
1066 agg->bitmap = bitmap;
1067 agg->start_idx = start;
1068 IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
1069 agg->frame_count, agg->start_idx,
1070 (unsigned long long)agg->bitmap);
1071
1072 if (bitmap)
1073 agg->wait_for_ba = 1;
1074 }
1075 return 0;
1076}
1077
1078static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1079 struct iwl_rx_mem_buffer *rxb)
1080{
1081 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1082 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1083 int txq_id = SEQ_TO_QUEUE(sequence);
1084 int index = SEQ_TO_INDEX(sequence);
1085 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1086 struct ieee80211_tx_info *info;
1087 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
1088 u32 status = le16_to_cpu(tx_resp->status.status);
1089 int tid;
1090 int sta_id;
1091 int freed;
1092
1093 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
1094 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
1095 "is out of range [0-%d] %d %d\n", txq_id,
1096 index, txq->q.n_bd, txq->q.write_ptr,
1097 txq->q.read_ptr);
1098 return;
1099 }
1100
1101 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
1102 memset(&info->status, 0, sizeof(info->status));
1103
1104 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
1105 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
1106
1107 if (txq->sched_retry) {
1108 const u32 scd_ssn = iwl5000_get_scd_ssn(tx_resp);
1109 struct iwl_ht_agg *agg = NULL;
1110
1111 agg = &priv->stations[sta_id].tid[tid].agg;
1112
1113 iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
1114
1115 /* check if BAR is needed */
1116 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
1117 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1118
1119 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
1120 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
1121 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim "
1122 "scd_ssn=%d idx=%d txq=%d swq=%d\n",
1123 scd_ssn , index, txq_id, txq->swq_id);
1124
1125 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1126 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1127
1128 if (priv->mac80211_registered &&
1129 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1130 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
1131 if (agg->state == IWL_AGG_OFF)
1132 iwl_wake_queue(priv, txq_id);
1133 else
1134 iwl_wake_queue(priv, txq->swq_id);
1135 }
1136 }
1137 } else {
1138 BUG_ON(txq_id != txq->swq_id);
1139
1140 info->status.rates[0].count = tx_resp->failure_frame + 1;
1141 info->flags |= iwl_tx_status_to_mac80211(status);
1142 iwl_hwrate_to_tx_control(priv,
1143 le32_to_cpu(tx_resp->rate_n_flags),
1144 info);
1145
1146 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
1147 "0x%x retries %d\n",
1148 txq_id,
1149 iwl_get_tx_fail_reason(status), status,
1150 le32_to_cpu(tx_resp->rate_n_flags),
1151 tx_resp->failure_frame);
1152
1153 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1154 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1155
1156 if (priv->mac80211_registered &&
1157 (iwl_queue_space(&txq->q) > txq->q.low_mark))
1158 iwl_wake_queue(priv, txq_id);
1159 }
1160
1161 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1162
1163 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
1164 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
1165}
1166
1167/* Currently 5000 is the superset of everything */
1168u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
1169{
1170 return len;
1171}
1172
1173void iwl5000_setup_deferred_work(struct iwl_priv *priv)
1174{
1175 /* in 5000 the tx power calibration is done in uCode */
1176 priv->disable_tx_power_cal = 1;
1177}
1178
1179void iwl5000_rx_handler_setup(struct iwl_priv *priv)
1180{
1181 /* init calibration handlers */
1182 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
1183 iwl5000_rx_calib_result;
1184 priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
1185 iwl5000_rx_calib_complete;
1186 priv->rx_handlers[REPLY_TX] = iwl5000_rx_reply_tx;
1187}
1188
1189
1190int iwl5000_hw_valid_rtc_data_addr(u32 addr)
1191{
1192 return (addr >= IWL50_RTC_DATA_LOWER_BOUND) &&
1193 (addr < IWL50_RTC_DATA_UPPER_BOUND);
1194}
1195
1196static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
1197{
1198 int ret = 0;
1199 struct iwl5000_rxon_assoc_cmd rxon_assoc;
1200 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
1201 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
1202
1203 if ((rxon1->flags == rxon2->flags) &&
1204 (rxon1->filter_flags == rxon2->filter_flags) &&
1205 (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
1206 (rxon1->ofdm_ht_single_stream_basic_rates ==
1207 rxon2->ofdm_ht_single_stream_basic_rates) &&
1208 (rxon1->ofdm_ht_dual_stream_basic_rates ==
1209 rxon2->ofdm_ht_dual_stream_basic_rates) &&
1210 (rxon1->ofdm_ht_triple_stream_basic_rates ==
1211 rxon2->ofdm_ht_triple_stream_basic_rates) &&
1212 (rxon1->acquisition_data == rxon2->acquisition_data) &&
1213 (rxon1->rx_chain == rxon2->rx_chain) &&
1214 (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
1215 IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
1216 return 0;
1217 }
1218
1219 rxon_assoc.flags = priv->staging_rxon.flags;
1220 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
1221 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
1222 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
1223 rxon_assoc.reserved1 = 0;
1224 rxon_assoc.reserved2 = 0;
1225 rxon_assoc.reserved3 = 0;
1226 rxon_assoc.ofdm_ht_single_stream_basic_rates =
1227 priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
1228 rxon_assoc.ofdm_ht_dual_stream_basic_rates =
1229 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
1230 rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
1231 rxon_assoc.ofdm_ht_triple_stream_basic_rates =
1232 priv->staging_rxon.ofdm_ht_triple_stream_basic_rates;
1233 rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data;
1234
1235 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
1236 sizeof(rxon_assoc), &rxon_assoc, NULL);
1237 if (ret)
1238 return ret;
1239
1240 return ret;
1241}
1242int iwl5000_send_tx_power(struct iwl_priv *priv)
1243{
1244 struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
1245 u8 tx_ant_cfg_cmd;
1246
1247 /* half dBm need to multiply */
1248 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
1249
1250 if (priv->tx_power_lmt_in_half_dbm &&
1251 priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) {
1252 /*
1253 * For the newer devices which using enhanced/extend tx power
1254 * table in EEPROM, the format is in half dBm. driver need to
1255 * convert to dBm format before report to mac80211.
1256 * By doing so, there is a possibility of 1/2 dBm resolution
1257 * lost. driver will perform "round-up" operation before
1258 * reporting, but it will cause 1/2 dBm tx power over the
1259 * regulatory limit. Perform the checking here, if the
1260 * "tx_power_user_lmt" is higher than EEPROM value (in
1261 * half-dBm format), lower the tx power based on EEPROM
1262 */
1263 tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
1264 }
1265 tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
1266 tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
1267
1268 if (IWL_UCODE_API(priv->ucode_ver) == 1)
1269 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
1270 else
1271 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
1272
1273 return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
1274 sizeof(tx_power_cmd), &tx_power_cmd,
1275 NULL);
1276}
1277
1278void iwl5000_temperature(struct iwl_priv *priv)
1279{
1280 /* store temperature from statistics (in Celsius) */
1281 priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
1282 iwl_tt_handler(priv);
1283}
1284
1285static void iwl5150_temperature(struct iwl_priv *priv) 226static void iwl5150_temperature(struct iwl_priv *priv)
1286{ 227{
1287 u32 vt = 0; 228 u32 vt = 0;
@@ -1294,100 +235,6 @@ static void iwl5150_temperature(struct iwl_priv *priv)
1294 iwl_tt_handler(priv); 235 iwl_tt_handler(priv);
1295} 236}
1296 237
1297/* Calc max signal level (dBm) among 3 possible receivers */
1298int iwl5000_calc_rssi(struct iwl_priv *priv,
1299 struct iwl_rx_phy_res *rx_resp)
1300{
1301 /* data from PHY/DSP regarding signal strength, etc.,
1302 * contents are always there, not configurable by host
1303 */
1304 struct iwl5000_non_cfg_phy *ncphy =
1305 (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
1306 u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
1307 u8 agc;
1308
1309 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
1310 agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
1311
1312 /* Find max rssi among 3 possible receivers.
1313 * These values are measured by the digital signal processor (DSP).
1314 * They should stay fairly constant even as the signal strength varies,
1315 * if the radio's automatic gain control (AGC) is working right.
1316 * AGC value (see below) will provide the "interesting" info.
1317 */
1318 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
1319 rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
1320 rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
1321 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
1322 rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
1323
1324 max_rssi = max_t(u32, rssi_a, rssi_b);
1325 max_rssi = max_t(u32, max_rssi, rssi_c);
1326
1327 IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
1328 rssi_a, rssi_b, rssi_c, max_rssi, agc);
1329
1330 /* dBm = max_rssi dB - agc dB - constant.
1331 * Higher AGC (higher radio gain) means lower signal. */
1332 return max_rssi - agc - IWL49_RSSI_OFFSET;
1333}
1334
1335static int iwl5000_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
1336{
1337 struct iwl_tx_ant_config_cmd tx_ant_cmd = {
1338 .valid = cpu_to_le32(valid_tx_ant),
1339 };
1340
1341 if (IWL_UCODE_API(priv->ucode_ver) > 1) {
1342 IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
1343 return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD,
1344 sizeof(struct iwl_tx_ant_config_cmd),
1345 &tx_ant_cmd);
1346 } else {
1347 IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
1348 return -EOPNOTSUPP;
1349 }
1350}
1351
1352
1353#define IWL5000_UCODE_GET(item) \
1354static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\
1355 u32 api_ver) \
1356{ \
1357 if (api_ver <= 2) \
1358 return le32_to_cpu(ucode->u.v1.item); \
1359 return le32_to_cpu(ucode->u.v2.item); \
1360}
1361
1362static u32 iwl5000_ucode_get_header_size(u32 api_ver)
1363{
1364 if (api_ver <= 2)
1365 return UCODE_HEADER_SIZE(1);
1366 return UCODE_HEADER_SIZE(2);
1367}
1368
1369static u32 iwl5000_ucode_get_build(const struct iwl_ucode_header *ucode,
1370 u32 api_ver)
1371{
1372 if (api_ver <= 2)
1373 return 0;
1374 return le32_to_cpu(ucode->u.v2.build);
1375}
1376
1377static u8 *iwl5000_ucode_get_data(const struct iwl_ucode_header *ucode,
1378 u32 api_ver)
1379{
1380 if (api_ver <= 2)
1381 return (u8 *) ucode->u.v1.data;
1382 return (u8 *) ucode->u.v2.data;
1383}
1384
1385IWL5000_UCODE_GET(inst_size);
1386IWL5000_UCODE_GET(data_size);
1387IWL5000_UCODE_GET(init_size);
1388IWL5000_UCODE_GET(init_data_size);
1389IWL5000_UCODE_GET(boot_size);
1390
1391static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel) 238static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1392{ 239{
1393 struct iwl5000_channel_switch_cmd cmd; 240 struct iwl5000_channel_switch_cmd cmd;
@@ -1420,54 +267,27 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1420 return iwl_send_cmd_sync(priv, &hcmd); 267 return iwl_send_cmd_sync(priv, &hcmd);
1421} 268}
1422 269
1423struct iwl_hcmd_ops iwl5000_hcmd = { 270static struct iwl_lib_ops iwl5000_lib = {
1424 .rxon_assoc = iwl5000_send_rxon_assoc,
1425 .commit_rxon = iwl_commit_rxon,
1426 .set_rxon_chain = iwl_set_rxon_chain,
1427 .set_tx_ant = iwl5000_send_tx_ant_config,
1428};
1429
1430struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
1431 .get_hcmd_size = iwl5000_get_hcmd_size,
1432 .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
1433 .gain_computation = iwl5000_gain_computation,
1434 .chain_noise_reset = iwl5000_chain_noise_reset,
1435 .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
1436 .calc_rssi = iwl5000_calc_rssi,
1437};
1438
1439struct iwl_ucode_ops iwl5000_ucode = {
1440 .get_header_size = iwl5000_ucode_get_header_size,
1441 .get_build = iwl5000_ucode_get_build,
1442 .get_inst_size = iwl5000_ucode_get_inst_size,
1443 .get_data_size = iwl5000_ucode_get_data_size,
1444 .get_init_size = iwl5000_ucode_get_init_size,
1445 .get_init_data_size = iwl5000_ucode_get_init_data_size,
1446 .get_boot_size = iwl5000_ucode_get_boot_size,
1447 .get_data = iwl5000_ucode_get_data,
1448};
1449
1450struct iwl_lib_ops iwl5000_lib = {
1451 .set_hw_params = iwl5000_hw_set_hw_params, 271 .set_hw_params = iwl5000_hw_set_hw_params,
1452 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 272 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
1453 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 273 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
1454 .txq_set_sched = iwl5000_txq_set_sched, 274 .txq_set_sched = iwlagn_txq_set_sched,
1455 .txq_agg_enable = iwl5000_txq_agg_enable, 275 .txq_agg_enable = iwlagn_txq_agg_enable,
1456 .txq_agg_disable = iwl5000_txq_agg_disable, 276 .txq_agg_disable = iwlagn_txq_agg_disable,
1457 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 277 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
1458 .txq_free_tfd = iwl_hw_txq_free_tfd, 278 .txq_free_tfd = iwl_hw_txq_free_tfd,
1459 .txq_init = iwl_hw_tx_queue_init, 279 .txq_init = iwl_hw_tx_queue_init,
1460 .rx_handler_setup = iwl5000_rx_handler_setup, 280 .rx_handler_setup = iwlagn_rx_handler_setup,
1461 .setup_deferred_work = iwl5000_setup_deferred_work, 281 .setup_deferred_work = iwlagn_setup_deferred_work,
1462 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 282 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
1463 .dump_nic_event_log = iwl_dump_nic_event_log, 283 .dump_nic_event_log = iwl_dump_nic_event_log,
1464 .dump_nic_error_log = iwl_dump_nic_error_log, 284 .dump_nic_error_log = iwl_dump_nic_error_log,
1465 .dump_csr = iwl_dump_csr, 285 .dump_csr = iwl_dump_csr,
1466 .dump_fh = iwl_dump_fh, 286 .dump_fh = iwl_dump_fh,
1467 .load_ucode = iwl5000_load_ucode, 287 .load_ucode = iwlagn_load_ucode,
1468 .init_alive_start = iwl5000_init_alive_start, 288 .init_alive_start = iwlagn_init_alive_start,
1469 .alive_notify = iwl5000_alive_notify, 289 .alive_notify = iwlagn_alive_notify,
1470 .send_tx_power = iwl5000_send_tx_power, 290 .send_tx_power = iwlagn_send_tx_power,
1471 .update_chain_flags = iwl_update_chain_flags, 291 .update_chain_flags = iwl_update_chain_flags,
1472 .set_channel_switch = iwl5000_hw_channel_switch, 292 .set_channel_switch = iwl5000_hw_channel_switch,
1473 .apm_ops = { 293 .apm_ops = {
@@ -1478,50 +298,53 @@ struct iwl_lib_ops iwl5000_lib = {
1478 }, 298 },
1479 .eeprom_ops = { 299 .eeprom_ops = {
1480 .regulatory_bands = { 300 .regulatory_bands = {
1481 EEPROM_5000_REG_BAND_1_CHANNELS, 301 EEPROM_REG_BAND_1_CHANNELS,
1482 EEPROM_5000_REG_BAND_2_CHANNELS, 302 EEPROM_REG_BAND_2_CHANNELS,
1483 EEPROM_5000_REG_BAND_3_CHANNELS, 303 EEPROM_REG_BAND_3_CHANNELS,
1484 EEPROM_5000_REG_BAND_4_CHANNELS, 304 EEPROM_REG_BAND_4_CHANNELS,
1485 EEPROM_5000_REG_BAND_5_CHANNELS, 305 EEPROM_REG_BAND_5_CHANNELS,
1486 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 306 EEPROM_REG_BAND_24_HT40_CHANNELS,
1487 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 307 EEPROM_REG_BAND_52_HT40_CHANNELS
1488 }, 308 },
1489 .verify_signature = iwlcore_eeprom_verify_signature, 309 .verify_signature = iwlcore_eeprom_verify_signature,
1490 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 310 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
1491 .release_semaphore = iwlcore_eeprom_release_semaphore, 311 .release_semaphore = iwlcore_eeprom_release_semaphore,
1492 .calib_version = iwl5000_eeprom_calib_version, 312 .calib_version = iwlagn_eeprom_calib_version,
1493 .query_addr = iwl5000_eeprom_query_addr, 313 .query_addr = iwlagn_eeprom_query_addr,
1494 }, 314 },
1495 .post_associate = iwl_post_associate, 315 .post_associate = iwl_post_associate,
1496 .isr = iwl_isr_ict, 316 .isr = iwl_isr_ict,
1497 .config_ap = iwl_config_ap, 317 .config_ap = iwl_config_ap,
1498 .temp_ops = { 318 .temp_ops = {
1499 .temperature = iwl5000_temperature, 319 .temperature = iwlagn_temperature,
1500 .set_ct_kill = iwl5000_set_ct_threshold, 320 .set_ct_kill = iwl5000_set_ct_threshold,
1501 }, 321 },
1502 .add_bcast_station = iwl_add_bcast_station, 322 .add_bcast_station = iwl_add_bcast_station,
323 .recover_from_tx_stall = iwl_bg_monitor_recover,
324 .check_plcp_health = iwl_good_plcp_health,
325 .check_ack_health = iwl_good_ack_health,
1503}; 326};
1504 327
1505static struct iwl_lib_ops iwl5150_lib = { 328static struct iwl_lib_ops iwl5150_lib = {
1506 .set_hw_params = iwl5000_hw_set_hw_params, 329 .set_hw_params = iwl5000_hw_set_hw_params,
1507 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 330 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
1508 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 331 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
1509 .txq_set_sched = iwl5000_txq_set_sched, 332 .txq_set_sched = iwlagn_txq_set_sched,
1510 .txq_agg_enable = iwl5000_txq_agg_enable, 333 .txq_agg_enable = iwlagn_txq_agg_enable,
1511 .txq_agg_disable = iwl5000_txq_agg_disable, 334 .txq_agg_disable = iwlagn_txq_agg_disable,
1512 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 335 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
1513 .txq_free_tfd = iwl_hw_txq_free_tfd, 336 .txq_free_tfd = iwl_hw_txq_free_tfd,
1514 .txq_init = iwl_hw_tx_queue_init, 337 .txq_init = iwl_hw_tx_queue_init,
1515 .rx_handler_setup = iwl5000_rx_handler_setup, 338 .rx_handler_setup = iwlagn_rx_handler_setup,
1516 .setup_deferred_work = iwl5000_setup_deferred_work, 339 .setup_deferred_work = iwlagn_setup_deferred_work,
1517 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 340 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
1518 .dump_nic_event_log = iwl_dump_nic_event_log, 341 .dump_nic_event_log = iwl_dump_nic_event_log,
1519 .dump_nic_error_log = iwl_dump_nic_error_log, 342 .dump_nic_error_log = iwl_dump_nic_error_log,
1520 .dump_csr = iwl_dump_csr, 343 .dump_csr = iwl_dump_csr,
1521 .load_ucode = iwl5000_load_ucode, 344 .load_ucode = iwlagn_load_ucode,
1522 .init_alive_start = iwl5000_init_alive_start, 345 .init_alive_start = iwlagn_init_alive_start,
1523 .alive_notify = iwl5000_alive_notify, 346 .alive_notify = iwlagn_alive_notify,
1524 .send_tx_power = iwl5000_send_tx_power, 347 .send_tx_power = iwlagn_send_tx_power,
1525 .update_chain_flags = iwl_update_chain_flags, 348 .update_chain_flags = iwl_update_chain_flags,
1526 .set_channel_switch = iwl5000_hw_channel_switch, 349 .set_channel_switch = iwl5000_hw_channel_switch,
1527 .apm_ops = { 350 .apm_ops = {
@@ -1532,19 +355,19 @@ static struct iwl_lib_ops iwl5150_lib = {
1532 }, 355 },
1533 .eeprom_ops = { 356 .eeprom_ops = {
1534 .regulatory_bands = { 357 .regulatory_bands = {
1535 EEPROM_5000_REG_BAND_1_CHANNELS, 358 EEPROM_REG_BAND_1_CHANNELS,
1536 EEPROM_5000_REG_BAND_2_CHANNELS, 359 EEPROM_REG_BAND_2_CHANNELS,
1537 EEPROM_5000_REG_BAND_3_CHANNELS, 360 EEPROM_REG_BAND_3_CHANNELS,
1538 EEPROM_5000_REG_BAND_4_CHANNELS, 361 EEPROM_REG_BAND_4_CHANNELS,
1539 EEPROM_5000_REG_BAND_5_CHANNELS, 362 EEPROM_REG_BAND_5_CHANNELS,
1540 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 363 EEPROM_REG_BAND_24_HT40_CHANNELS,
1541 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 364 EEPROM_REG_BAND_52_HT40_CHANNELS
1542 }, 365 },
1543 .verify_signature = iwlcore_eeprom_verify_signature, 366 .verify_signature = iwlcore_eeprom_verify_signature,
1544 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 367 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
1545 .release_semaphore = iwlcore_eeprom_release_semaphore, 368 .release_semaphore = iwlcore_eeprom_release_semaphore,
1546 .calib_version = iwl5000_eeprom_calib_version, 369 .calib_version = iwlagn_eeprom_calib_version,
1547 .query_addr = iwl5000_eeprom_query_addr, 370 .query_addr = iwlagn_eeprom_query_addr,
1548 }, 371 },
1549 .post_associate = iwl_post_associate, 372 .post_associate = iwl_post_associate,
1550 .isr = iwl_isr_ict, 373 .isr = iwl_isr_ict,
@@ -1554,44 +377,40 @@ static struct iwl_lib_ops iwl5150_lib = {
1554 .set_ct_kill = iwl5150_set_ct_threshold, 377 .set_ct_kill = iwl5150_set_ct_threshold,
1555 }, 378 },
1556 .add_bcast_station = iwl_add_bcast_station, 379 .add_bcast_station = iwl_add_bcast_station,
380 .recover_from_tx_stall = iwl_bg_monitor_recover,
381 .check_plcp_health = iwl_good_plcp_health,
382 .check_ack_health = iwl_good_ack_health,
1557}; 383};
1558 384
1559static const struct iwl_ops iwl5000_ops = { 385static const struct iwl_ops iwl5000_ops = {
1560 .ucode = &iwl5000_ucode, 386 .ucode = &iwlagn_ucode,
1561 .lib = &iwl5000_lib, 387 .lib = &iwl5000_lib,
1562 .hcmd = &iwl5000_hcmd, 388 .hcmd = &iwlagn_hcmd,
1563 .utils = &iwl5000_hcmd_utils, 389 .utils = &iwlagn_hcmd_utils,
1564 .led = &iwlagn_led_ops, 390 .led = &iwlagn_led_ops,
1565}; 391};
1566 392
1567static const struct iwl_ops iwl5150_ops = { 393static const struct iwl_ops iwl5150_ops = {
1568 .ucode = &iwl5000_ucode, 394 .ucode = &iwlagn_ucode,
1569 .lib = &iwl5150_lib, 395 .lib = &iwl5150_lib,
1570 .hcmd = &iwl5000_hcmd, 396 .hcmd = &iwlagn_hcmd,
1571 .utils = &iwl5000_hcmd_utils, 397 .utils = &iwlagn_hcmd_utils,
1572 .led = &iwlagn_led_ops, 398 .led = &iwlagn_led_ops,
1573}; 399};
1574 400
1575struct iwl_mod_params iwl50_mod_params = {
1576 .amsdu_size_8K = 1,
1577 .restart_fw = 1,
1578 /* the rest are 0 by default */
1579};
1580
1581
1582struct iwl_cfg iwl5300_agn_cfg = { 401struct iwl_cfg iwl5300_agn_cfg = {
1583 .name = "5300AGN", 402 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
1584 .fw_name_pre = IWL5000_FW_PRE, 403 .fw_name_pre = IWL5000_FW_PRE,
1585 .ucode_api_max = IWL5000_UCODE_API_MAX, 404 .ucode_api_max = IWL5000_UCODE_API_MAX,
1586 .ucode_api_min = IWL5000_UCODE_API_MIN, 405 .ucode_api_min = IWL5000_UCODE_API_MIN,
1587 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 406 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1588 .ops = &iwl5000_ops, 407 .ops = &iwl5000_ops,
1589 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 408 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1590 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 409 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1591 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 410 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1592 .num_of_queues = IWL50_NUM_QUEUES, 411 .num_of_queues = IWLAGN_NUM_QUEUES,
1593 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 412 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1594 .mod_params = &iwl50_mod_params, 413 .mod_params = &iwlagn_mod_params,
1595 .valid_tx_ant = ANT_ABC, 414 .valid_tx_ant = ANT_ABC,
1596 .valid_rx_ant = ANT_ABC, 415 .valid_rx_ant = ANT_ABC,
1597 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 416 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1603,21 +422,22 @@ struct iwl_cfg iwl5300_agn_cfg = {
1603 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 422 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1604 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 423 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1605 .chain_noise_scale = 1000, 424 .chain_noise_scale = 1000,
425 .monitor_recover_period = IWL_MONITORING_PERIOD,
1606}; 426};
1607 427
1608struct iwl_cfg iwl5100_bgn_cfg = { 428struct iwl_cfg iwl5100_bgn_cfg = {
1609 .name = "5100BGN", 429 .name = "Intel(R) WiFi Link 5100 BGN",
1610 .fw_name_pre = IWL5000_FW_PRE, 430 .fw_name_pre = IWL5000_FW_PRE,
1611 .ucode_api_max = IWL5000_UCODE_API_MAX, 431 .ucode_api_max = IWL5000_UCODE_API_MAX,
1612 .ucode_api_min = IWL5000_UCODE_API_MIN, 432 .ucode_api_min = IWL5000_UCODE_API_MIN,
1613 .sku = IWL_SKU_G|IWL_SKU_N, 433 .sku = IWL_SKU_G|IWL_SKU_N,
1614 .ops = &iwl5000_ops, 434 .ops = &iwl5000_ops,
1615 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 435 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1616 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 436 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1617 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 437 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1618 .num_of_queues = IWL50_NUM_QUEUES, 438 .num_of_queues = IWLAGN_NUM_QUEUES,
1619 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 439 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1620 .mod_params = &iwl50_mod_params, 440 .mod_params = &iwlagn_mod_params,
1621 .valid_tx_ant = ANT_B, 441 .valid_tx_ant = ANT_B,
1622 .valid_rx_ant = ANT_AB, 442 .valid_rx_ant = ANT_AB,
1623 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 443 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1629,21 +449,22 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1629 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 449 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1630 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 450 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1631 .chain_noise_scale = 1000, 451 .chain_noise_scale = 1000,
452 .monitor_recover_period = IWL_MONITORING_PERIOD,
1632}; 453};
1633 454
1634struct iwl_cfg iwl5100_abg_cfg = { 455struct iwl_cfg iwl5100_abg_cfg = {
1635 .name = "5100ABG", 456 .name = "Intel(R) WiFi Link 5100 ABG",
1636 .fw_name_pre = IWL5000_FW_PRE, 457 .fw_name_pre = IWL5000_FW_PRE,
1637 .ucode_api_max = IWL5000_UCODE_API_MAX, 458 .ucode_api_max = IWL5000_UCODE_API_MAX,
1638 .ucode_api_min = IWL5000_UCODE_API_MIN, 459 .ucode_api_min = IWL5000_UCODE_API_MIN,
1639 .sku = IWL_SKU_A|IWL_SKU_G, 460 .sku = IWL_SKU_A|IWL_SKU_G,
1640 .ops = &iwl5000_ops, 461 .ops = &iwl5000_ops,
1641 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 462 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1642 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 463 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1643 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 464 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1644 .num_of_queues = IWL50_NUM_QUEUES, 465 .num_of_queues = IWLAGN_NUM_QUEUES,
1645 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 466 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1646 .mod_params = &iwl50_mod_params, 467 .mod_params = &iwlagn_mod_params,
1647 .valid_tx_ant = ANT_B, 468 .valid_tx_ant = ANT_B,
1648 .valid_rx_ant = ANT_AB, 469 .valid_rx_ant = ANT_AB,
1649 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 470 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1653,21 +474,22 @@ struct iwl_cfg iwl5100_abg_cfg = {
1653 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 474 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1654 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 475 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1655 .chain_noise_scale = 1000, 476 .chain_noise_scale = 1000,
477 .monitor_recover_period = IWL_MONITORING_PERIOD,
1656}; 478};
1657 479
1658struct iwl_cfg iwl5100_agn_cfg = { 480struct iwl_cfg iwl5100_agn_cfg = {
1659 .name = "5100AGN", 481 .name = "Intel(R) WiFi Link 5100 AGN",
1660 .fw_name_pre = IWL5000_FW_PRE, 482 .fw_name_pre = IWL5000_FW_PRE,
1661 .ucode_api_max = IWL5000_UCODE_API_MAX, 483 .ucode_api_max = IWL5000_UCODE_API_MAX,
1662 .ucode_api_min = IWL5000_UCODE_API_MIN, 484 .ucode_api_min = IWL5000_UCODE_API_MIN,
1663 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 485 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1664 .ops = &iwl5000_ops, 486 .ops = &iwl5000_ops,
1665 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 487 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1666 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 488 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1667 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 489 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1668 .num_of_queues = IWL50_NUM_QUEUES, 490 .num_of_queues = IWLAGN_NUM_QUEUES,
1669 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 491 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1670 .mod_params = &iwl50_mod_params, 492 .mod_params = &iwlagn_mod_params,
1671 .valid_tx_ant = ANT_B, 493 .valid_tx_ant = ANT_B,
1672 .valid_rx_ant = ANT_AB, 494 .valid_rx_ant = ANT_AB,
1673 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 495 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1679,21 +501,22 @@ struct iwl_cfg iwl5100_agn_cfg = {
1679 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 501 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1680 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 502 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1681 .chain_noise_scale = 1000, 503 .chain_noise_scale = 1000,
504 .monitor_recover_period = IWL_MONITORING_PERIOD,
1682}; 505};
1683 506
1684struct iwl_cfg iwl5350_agn_cfg = { 507struct iwl_cfg iwl5350_agn_cfg = {
1685 .name = "5350AGN", 508 .name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
1686 .fw_name_pre = IWL5000_FW_PRE, 509 .fw_name_pre = IWL5000_FW_PRE,
1687 .ucode_api_max = IWL5000_UCODE_API_MAX, 510 .ucode_api_max = IWL5000_UCODE_API_MAX,
1688 .ucode_api_min = IWL5000_UCODE_API_MIN, 511 .ucode_api_min = IWL5000_UCODE_API_MIN,
1689 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 512 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1690 .ops = &iwl5000_ops, 513 .ops = &iwl5000_ops,
1691 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 514 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1692 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 515 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1693 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 516 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1694 .num_of_queues = IWL50_NUM_QUEUES, 517 .num_of_queues = IWLAGN_NUM_QUEUES,
1695 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 518 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1696 .mod_params = &iwl50_mod_params, 519 .mod_params = &iwlagn_mod_params,
1697 .valid_tx_ant = ANT_ABC, 520 .valid_tx_ant = ANT_ABC,
1698 .valid_rx_ant = ANT_ABC, 521 .valid_rx_ant = ANT_ABC,
1699 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 522 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1705,21 +528,22 @@ struct iwl_cfg iwl5350_agn_cfg = {
1705 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 528 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1706 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 529 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1707 .chain_noise_scale = 1000, 530 .chain_noise_scale = 1000,
531 .monitor_recover_period = IWL_MONITORING_PERIOD,
1708}; 532};
1709 533
1710struct iwl_cfg iwl5150_agn_cfg = { 534struct iwl_cfg iwl5150_agn_cfg = {
1711 .name = "5150AGN", 535 .name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
1712 .fw_name_pre = IWL5150_FW_PRE, 536 .fw_name_pre = IWL5150_FW_PRE,
1713 .ucode_api_max = IWL5150_UCODE_API_MAX, 537 .ucode_api_max = IWL5150_UCODE_API_MAX,
1714 .ucode_api_min = IWL5150_UCODE_API_MIN, 538 .ucode_api_min = IWL5150_UCODE_API_MIN,
1715 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 539 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1716 .ops = &iwl5150_ops, 540 .ops = &iwl5150_ops,
1717 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 541 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1718 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 542 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1719 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 543 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1720 .num_of_queues = IWL50_NUM_QUEUES, 544 .num_of_queues = IWLAGN_NUM_QUEUES,
1721 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 545 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1722 .mod_params = &iwl50_mod_params, 546 .mod_params = &iwlagn_mod_params,
1723 .valid_tx_ant = ANT_A, 547 .valid_tx_ant = ANT_A,
1724 .valid_rx_ant = ANT_AB, 548 .valid_rx_ant = ANT_AB,
1725 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 549 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1731,21 +555,22 @@ struct iwl_cfg iwl5150_agn_cfg = {
1731 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 555 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1732 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 556 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1733 .chain_noise_scale = 1000, 557 .chain_noise_scale = 1000,
558 .monitor_recover_period = IWL_MONITORING_PERIOD,
1734}; 559};
1735 560
1736struct iwl_cfg iwl5150_abg_cfg = { 561struct iwl_cfg iwl5150_abg_cfg = {
1737 .name = "5150ABG", 562 .name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
1738 .fw_name_pre = IWL5150_FW_PRE, 563 .fw_name_pre = IWL5150_FW_PRE,
1739 .ucode_api_max = IWL5150_UCODE_API_MAX, 564 .ucode_api_max = IWL5150_UCODE_API_MAX,
1740 .ucode_api_min = IWL5150_UCODE_API_MIN, 565 .ucode_api_min = IWL5150_UCODE_API_MIN,
1741 .sku = IWL_SKU_A|IWL_SKU_G, 566 .sku = IWL_SKU_A|IWL_SKU_G,
1742 .ops = &iwl5150_ops, 567 .ops = &iwl5150_ops,
1743 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 568 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1744 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 569 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1745 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 570 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1746 .num_of_queues = IWL50_NUM_QUEUES, 571 .num_of_queues = IWLAGN_NUM_QUEUES,
1747 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 572 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1748 .mod_params = &iwl50_mod_params, 573 .mod_params = &iwlagn_mod_params,
1749 .valid_tx_ant = ANT_A, 574 .valid_tx_ant = ANT_A,
1750 .valid_rx_ant = ANT_AB, 575 .valid_rx_ant = ANT_AB,
1751 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 576 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1755,20 +580,8 @@ struct iwl_cfg iwl5150_abg_cfg = {
1755 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 580 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1756 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 581 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1757 .chain_noise_scale = 1000, 582 .chain_noise_scale = 1000,
583 .monitor_recover_period = IWL_MONITORING_PERIOD,
1758}; 584};
1759 585
1760MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 586MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
1761MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); 587MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
1762
1763module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, S_IRUGO);
1764MODULE_PARM_DESC(swcrypto50,
1765 "using software crypto engine (default 0 [hardware])\n");
1766module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, S_IRUGO);
1767MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
1768module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, S_IRUGO);
1769MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality");
1770module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K,
1771 int, S_IRUGO);
1772MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series");
1773module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, S_IRUGO);
1774MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index c4844adff92a..7473518e7e0a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -42,8 +42,9 @@
42#include "iwl-core.h" 42#include "iwl-core.h"
43#include "iwl-io.h" 43#include "iwl-io.h"
44#include "iwl-sta.h" 44#include "iwl-sta.h"
45#include "iwl-agn.h"
45#include "iwl-helpers.h" 46#include "iwl-helpers.h"
46#include "iwl-5000-hw.h" 47#include "iwl-agn-hw.h"
47#include "iwl-6000-hw.h" 48#include "iwl-6000-hw.h"
48#include "iwl-agn-led.h" 49#include "iwl-agn-led.h"
49 50
@@ -56,6 +57,7 @@
56#define IWL6050_UCODE_API_MIN 4 57#define IWL6050_UCODE_API_MIN 4
57 58
58#define IWL6000_FW_PRE "iwlwifi-6000-" 59#define IWL6000_FW_PRE "iwlwifi-6000-"
60#define IWL6000_G2_FW_PRE "iwlwifi-6005-"
59#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" 61#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
60#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api) 62#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
61 63
@@ -136,7 +138,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
136static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) 138static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
137{ 139{
138 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 140 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
139 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) 141 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
140 priv->cfg->num_of_queues = 142 priv->cfg->num_of_queues =
141 priv->cfg->mod_params->num_of_queues; 143 priv->cfg->mod_params->num_of_queues;
142 144
@@ -144,7 +146,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
144 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 146 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
145 priv->hw_params.scd_bc_tbls_size = 147 priv->hw_params.scd_bc_tbls_size =
146 priv->cfg->num_of_queues * 148 priv->cfg->num_of_queues *
147 sizeof(struct iwl5000_scd_bc_tbl); 149 sizeof(struct iwlagn_scd_bc_tbl);
148 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 150 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
149 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 151 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
150 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 152 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
@@ -225,25 +227,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
225 227
226static struct iwl_lib_ops iwl6000_lib = { 228static struct iwl_lib_ops iwl6000_lib = {
227 .set_hw_params = iwl6000_hw_set_hw_params, 229 .set_hw_params = iwl6000_hw_set_hw_params,
228 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 230 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
229 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 231 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
230 .txq_set_sched = iwl5000_txq_set_sched, 232 .txq_set_sched = iwlagn_txq_set_sched,
231 .txq_agg_enable = iwl5000_txq_agg_enable, 233 .txq_agg_enable = iwlagn_txq_agg_enable,
232 .txq_agg_disable = iwl5000_txq_agg_disable, 234 .txq_agg_disable = iwlagn_txq_agg_disable,
233 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 235 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
234 .txq_free_tfd = iwl_hw_txq_free_tfd, 236 .txq_free_tfd = iwl_hw_txq_free_tfd,
235 .txq_init = iwl_hw_tx_queue_init, 237 .txq_init = iwl_hw_tx_queue_init,
236 .rx_handler_setup = iwl5000_rx_handler_setup, 238 .rx_handler_setup = iwlagn_rx_handler_setup,
237 .setup_deferred_work = iwl5000_setup_deferred_work, 239 .setup_deferred_work = iwlagn_setup_deferred_work,
238 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 240 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
239 .load_ucode = iwl5000_load_ucode, 241 .load_ucode = iwlagn_load_ucode,
240 .dump_nic_event_log = iwl_dump_nic_event_log, 242 .dump_nic_event_log = iwl_dump_nic_event_log,
241 .dump_nic_error_log = iwl_dump_nic_error_log, 243 .dump_nic_error_log = iwl_dump_nic_error_log,
242 .dump_csr = iwl_dump_csr, 244 .dump_csr = iwl_dump_csr,
243 .dump_fh = iwl_dump_fh, 245 .dump_fh = iwl_dump_fh,
244 .init_alive_start = iwl5000_init_alive_start, 246 .init_alive_start = iwlagn_init_alive_start,
245 .alive_notify = iwl5000_alive_notify, 247 .alive_notify = iwlagn_alive_notify,
246 .send_tx_power = iwl5000_send_tx_power, 248 .send_tx_power = iwlagn_send_tx_power,
247 .update_chain_flags = iwl_update_chain_flags, 249 .update_chain_flags = iwl_update_chain_flags,
248 .set_channel_switch = iwl6000_hw_channel_switch, 250 .set_channel_switch = iwl6000_hw_channel_switch,
249 .apm_ops = { 251 .apm_ops = {
@@ -254,60 +256,63 @@ static struct iwl_lib_ops iwl6000_lib = {
254 }, 256 },
255 .eeprom_ops = { 257 .eeprom_ops = {
256 .regulatory_bands = { 258 .regulatory_bands = {
257 EEPROM_5000_REG_BAND_1_CHANNELS, 259 EEPROM_REG_BAND_1_CHANNELS,
258 EEPROM_5000_REG_BAND_2_CHANNELS, 260 EEPROM_REG_BAND_2_CHANNELS,
259 EEPROM_5000_REG_BAND_3_CHANNELS, 261 EEPROM_REG_BAND_3_CHANNELS,
260 EEPROM_5000_REG_BAND_4_CHANNELS, 262 EEPROM_REG_BAND_4_CHANNELS,
261 EEPROM_5000_REG_BAND_5_CHANNELS, 263 EEPROM_REG_BAND_5_CHANNELS,
262 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 264 EEPROM_REG_BAND_24_HT40_CHANNELS,
263 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 265 EEPROM_REG_BAND_52_HT40_CHANNELS
264 }, 266 },
265 .verify_signature = iwlcore_eeprom_verify_signature, 267 .verify_signature = iwlcore_eeprom_verify_signature,
266 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 268 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
267 .release_semaphore = iwlcore_eeprom_release_semaphore, 269 .release_semaphore = iwlcore_eeprom_release_semaphore,
268 .calib_version = iwl5000_eeprom_calib_version, 270 .calib_version = iwlagn_eeprom_calib_version,
269 .query_addr = iwl5000_eeprom_query_addr, 271 .query_addr = iwlagn_eeprom_query_addr,
270 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 272 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
271 }, 273 },
272 .post_associate = iwl_post_associate, 274 .post_associate = iwl_post_associate,
273 .isr = iwl_isr_ict, 275 .isr = iwl_isr_ict,
274 .config_ap = iwl_config_ap, 276 .config_ap = iwl_config_ap,
275 .temp_ops = { 277 .temp_ops = {
276 .temperature = iwl5000_temperature, 278 .temperature = iwlagn_temperature,
277 .set_ct_kill = iwl6000_set_ct_threshold, 279 .set_ct_kill = iwl6000_set_ct_threshold,
278 }, 280 },
279 .add_bcast_station = iwl_add_bcast_station, 281 .add_bcast_station = iwl_add_bcast_station,
282 .recover_from_tx_stall = iwl_bg_monitor_recover,
283 .check_plcp_health = iwl_good_plcp_health,
284 .check_ack_health = iwl_good_ack_health,
280}; 285};
281 286
282static const struct iwl_ops iwl6000_ops = { 287static const struct iwl_ops iwl6000_ops = {
283 .ucode = &iwl5000_ucode, 288 .ucode = &iwlagn_ucode,
284 .lib = &iwl6000_lib, 289 .lib = &iwl6000_lib,
285 .hcmd = &iwl5000_hcmd, 290 .hcmd = &iwlagn_hcmd,
286 .utils = &iwl5000_hcmd_utils, 291 .utils = &iwlagn_hcmd_utils,
287 .led = &iwlagn_led_ops, 292 .led = &iwlagn_led_ops,
288}; 293};
289 294
290static struct iwl_lib_ops iwl6050_lib = { 295static struct iwl_lib_ops iwl6050_lib = {
291 .set_hw_params = iwl6000_hw_set_hw_params, 296 .set_hw_params = iwl6000_hw_set_hw_params,
292 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 297 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
293 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 298 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
294 .txq_set_sched = iwl5000_txq_set_sched, 299 .txq_set_sched = iwlagn_txq_set_sched,
295 .txq_agg_enable = iwl5000_txq_agg_enable, 300 .txq_agg_enable = iwlagn_txq_agg_enable,
296 .txq_agg_disable = iwl5000_txq_agg_disable, 301 .txq_agg_disable = iwlagn_txq_agg_disable,
297 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 302 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
298 .txq_free_tfd = iwl_hw_txq_free_tfd, 303 .txq_free_tfd = iwl_hw_txq_free_tfd,
299 .txq_init = iwl_hw_tx_queue_init, 304 .txq_init = iwl_hw_tx_queue_init,
300 .rx_handler_setup = iwl5000_rx_handler_setup, 305 .rx_handler_setup = iwlagn_rx_handler_setup,
301 .setup_deferred_work = iwl5000_setup_deferred_work, 306 .setup_deferred_work = iwlagn_setup_deferred_work,
302 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 307 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
303 .load_ucode = iwl5000_load_ucode, 308 .load_ucode = iwlagn_load_ucode,
304 .dump_nic_event_log = iwl_dump_nic_event_log, 309 .dump_nic_event_log = iwl_dump_nic_event_log,
305 .dump_nic_error_log = iwl_dump_nic_error_log, 310 .dump_nic_error_log = iwl_dump_nic_error_log,
306 .dump_csr = iwl_dump_csr, 311 .dump_csr = iwl_dump_csr,
307 .dump_fh = iwl_dump_fh, 312 .dump_fh = iwl_dump_fh,
308 .init_alive_start = iwl5000_init_alive_start, 313 .init_alive_start = iwlagn_init_alive_start,
309 .alive_notify = iwl5000_alive_notify, 314 .alive_notify = iwlagn_alive_notify,
310 .send_tx_power = iwl5000_send_tx_power, 315 .send_tx_power = iwlagn_send_tx_power,
311 .update_chain_flags = iwl_update_chain_flags, 316 .update_chain_flags = iwl_update_chain_flags,
312 .set_channel_switch = iwl6000_hw_channel_switch, 317 .set_channel_switch = iwl6000_hw_channel_switch,
313 .apm_ops = { 318 .apm_ops = {
@@ -318,45 +323,81 @@ static struct iwl_lib_ops iwl6050_lib = {
318 }, 323 },
319 .eeprom_ops = { 324 .eeprom_ops = {
320 .regulatory_bands = { 325 .regulatory_bands = {
321 EEPROM_5000_REG_BAND_1_CHANNELS, 326 EEPROM_REG_BAND_1_CHANNELS,
322 EEPROM_5000_REG_BAND_2_CHANNELS, 327 EEPROM_REG_BAND_2_CHANNELS,
323 EEPROM_5000_REG_BAND_3_CHANNELS, 328 EEPROM_REG_BAND_3_CHANNELS,
324 EEPROM_5000_REG_BAND_4_CHANNELS, 329 EEPROM_REG_BAND_4_CHANNELS,
325 EEPROM_5000_REG_BAND_5_CHANNELS, 330 EEPROM_REG_BAND_5_CHANNELS,
326 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 331 EEPROM_REG_BAND_24_HT40_CHANNELS,
327 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 332 EEPROM_REG_BAND_52_HT40_CHANNELS
328 }, 333 },
329 .verify_signature = iwlcore_eeprom_verify_signature, 334 .verify_signature = iwlcore_eeprom_verify_signature,
330 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 335 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
331 .release_semaphore = iwlcore_eeprom_release_semaphore, 336 .release_semaphore = iwlcore_eeprom_release_semaphore,
332 .calib_version = iwl5000_eeprom_calib_version, 337 .calib_version = iwlagn_eeprom_calib_version,
333 .query_addr = iwl5000_eeprom_query_addr, 338 .query_addr = iwlagn_eeprom_query_addr,
334 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 339 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
335 }, 340 },
336 .post_associate = iwl_post_associate, 341 .post_associate = iwl_post_associate,
337 .isr = iwl_isr_ict, 342 .isr = iwl_isr_ict,
338 .config_ap = iwl_config_ap, 343 .config_ap = iwl_config_ap,
339 .temp_ops = { 344 .temp_ops = {
340 .temperature = iwl5000_temperature, 345 .temperature = iwlagn_temperature,
341 .set_ct_kill = iwl6000_set_ct_threshold, 346 .set_ct_kill = iwl6000_set_ct_threshold,
342 .set_calib_version = iwl6050_set_calib_version, 347 .set_calib_version = iwl6050_set_calib_version,
343 }, 348 },
344 .add_bcast_station = iwl_add_bcast_station, 349 .add_bcast_station = iwl_add_bcast_station,
350 .recover_from_tx_stall = iwl_bg_monitor_recover,
351 .check_plcp_health = iwl_good_plcp_health,
352 .check_ack_health = iwl_good_ack_health,
345}; 353};
346 354
347static const struct iwl_ops iwl6050_ops = { 355static const struct iwl_ops iwl6050_ops = {
348 .ucode = &iwl5000_ucode, 356 .ucode = &iwlagn_ucode,
349 .lib = &iwl6050_lib, 357 .lib = &iwl6050_lib,
350 .hcmd = &iwl5000_hcmd, 358 .hcmd = &iwlagn_hcmd,
351 .utils = &iwl5000_hcmd_utils, 359 .utils = &iwlagn_hcmd_utils,
352 .led = &iwlagn_led_ops, 360 .led = &iwlagn_led_ops,
353}; 361};
354 362
355/* 363/*
356 * "i": Internal configuration, use internal Power Amplifier 364 * "i": Internal configuration, use internal Power Amplifier
357 */ 365 */
366struct iwl_cfg iwl6000i_g2_2agn_cfg = {
367 .name = "6000 Series 2x2 AGN Gen2",
368 .fw_name_pre = IWL6000_G2_FW_PRE,
369 .ucode_api_max = IWL6000_UCODE_API_MAX,
370 .ucode_api_min = IWL6000_UCODE_API_MIN,
371 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
372 .ops = &iwl6000_ops,
373 .eeprom_size = OTP_LOW_IMAGE_SIZE,
374 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
375 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
376 .num_of_queues = IWLAGN_NUM_QUEUES,
377 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
378 .mod_params = &iwlagn_mod_params,
379 .valid_tx_ant = ANT_AB,
380 .valid_rx_ant = ANT_AB,
381 .pll_cfg_val = 0,
382 .set_l0s = true,
383 .use_bsm = false,
384 .pa_type = IWL_PA_INTERNAL,
385 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
386 .shadow_ram_support = true,
387 .ht_greenfield_support = true,
388 .led_compensation = 51,
389 .use_rts_for_ht = true, /* use rts/cts protection */
390 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
391 .supports_idle = true,
392 .adv_thermal_throttle = true,
393 .support_ct_kill_exit = true,
394 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
395 .chain_noise_scale = 1000,
396 .monitor_recover_period = IWL_MONITORING_PERIOD,
397};
398
358struct iwl_cfg iwl6000i_2agn_cfg = { 399struct iwl_cfg iwl6000i_2agn_cfg = {
359 .name = "6000 Series 2x2 AGN", 400 .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
360 .fw_name_pre = IWL6000_FW_PRE, 401 .fw_name_pre = IWL6000_FW_PRE,
361 .ucode_api_max = IWL6000_UCODE_API_MAX, 402 .ucode_api_max = IWL6000_UCODE_API_MAX,
362 .ucode_api_min = IWL6000_UCODE_API_MIN, 403 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -364,10 +405,10 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
364 .ops = &iwl6000_ops, 405 .ops = &iwl6000_ops,
365 .eeprom_size = OTP_LOW_IMAGE_SIZE, 406 .eeprom_size = OTP_LOW_IMAGE_SIZE,
366 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 407 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
367 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 408 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
368 .num_of_queues = IWL50_NUM_QUEUES, 409 .num_of_queues = IWLAGN_NUM_QUEUES,
369 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 410 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
370 .mod_params = &iwl50_mod_params, 411 .mod_params = &iwlagn_mod_params,
371 .valid_tx_ant = ANT_BC, 412 .valid_tx_ant = ANT_BC,
372 .valid_rx_ant = ANT_BC, 413 .valid_rx_ant = ANT_BC,
373 .pll_cfg_val = 0, 414 .pll_cfg_val = 0,
@@ -385,10 +426,11 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
385 .support_ct_kill_exit = true, 426 .support_ct_kill_exit = true,
386 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 427 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
387 .chain_noise_scale = 1000, 428 .chain_noise_scale = 1000,
429 .monitor_recover_period = IWL_MONITORING_PERIOD,
388}; 430};
389 431
390struct iwl_cfg iwl6000i_2abg_cfg = { 432struct iwl_cfg iwl6000i_2abg_cfg = {
391 .name = "6000 Series 2x2 ABG", 433 .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
392 .fw_name_pre = IWL6000_FW_PRE, 434 .fw_name_pre = IWL6000_FW_PRE,
393 .ucode_api_max = IWL6000_UCODE_API_MAX, 435 .ucode_api_max = IWL6000_UCODE_API_MAX,
394 .ucode_api_min = IWL6000_UCODE_API_MIN, 436 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -396,10 +438,10 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
396 .ops = &iwl6000_ops, 438 .ops = &iwl6000_ops,
397 .eeprom_size = OTP_LOW_IMAGE_SIZE, 439 .eeprom_size = OTP_LOW_IMAGE_SIZE,
398 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 440 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
399 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 441 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
400 .num_of_queues = IWL50_NUM_QUEUES, 442 .num_of_queues = IWLAGN_NUM_QUEUES,
401 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 443 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
402 .mod_params = &iwl50_mod_params, 444 .mod_params = &iwlagn_mod_params,
403 .valid_tx_ant = ANT_BC, 445 .valid_tx_ant = ANT_BC,
404 .valid_rx_ant = ANT_BC, 446 .valid_rx_ant = ANT_BC,
405 .pll_cfg_val = 0, 447 .pll_cfg_val = 0,
@@ -416,10 +458,11 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
416 .support_ct_kill_exit = true, 458 .support_ct_kill_exit = true,
417 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 459 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
418 .chain_noise_scale = 1000, 460 .chain_noise_scale = 1000,
461 .monitor_recover_period = IWL_MONITORING_PERIOD,
419}; 462};
420 463
421struct iwl_cfg iwl6000i_2bg_cfg = { 464struct iwl_cfg iwl6000i_2bg_cfg = {
422 .name = "6000 Series 2x2 BG", 465 .name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
423 .fw_name_pre = IWL6000_FW_PRE, 466 .fw_name_pre = IWL6000_FW_PRE,
424 .ucode_api_max = IWL6000_UCODE_API_MAX, 467 .ucode_api_max = IWL6000_UCODE_API_MAX,
425 .ucode_api_min = IWL6000_UCODE_API_MIN, 468 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -427,10 +470,10 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
427 .ops = &iwl6000_ops, 470 .ops = &iwl6000_ops,
428 .eeprom_size = OTP_LOW_IMAGE_SIZE, 471 .eeprom_size = OTP_LOW_IMAGE_SIZE,
429 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 472 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
430 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 473 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
431 .num_of_queues = IWL50_NUM_QUEUES, 474 .num_of_queues = IWLAGN_NUM_QUEUES,
432 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 475 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
433 .mod_params = &iwl50_mod_params, 476 .mod_params = &iwlagn_mod_params,
434 .valid_tx_ant = ANT_BC, 477 .valid_tx_ant = ANT_BC,
435 .valid_rx_ant = ANT_BC, 478 .valid_rx_ant = ANT_BC,
436 .pll_cfg_val = 0, 479 .pll_cfg_val = 0,
@@ -447,10 +490,11 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
447 .support_ct_kill_exit = true, 490 .support_ct_kill_exit = true,
448 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 491 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
449 .chain_noise_scale = 1000, 492 .chain_noise_scale = 1000,
493 .monitor_recover_period = IWL_MONITORING_PERIOD,
450}; 494};
451 495
452struct iwl_cfg iwl6050_2agn_cfg = { 496struct iwl_cfg iwl6050_2agn_cfg = {
453 .name = "6050 Series 2x2 AGN", 497 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
454 .fw_name_pre = IWL6050_FW_PRE, 498 .fw_name_pre = IWL6050_FW_PRE,
455 .ucode_api_max = IWL6050_UCODE_API_MAX, 499 .ucode_api_max = IWL6050_UCODE_API_MAX,
456 .ucode_api_min = IWL6050_UCODE_API_MIN, 500 .ucode_api_min = IWL6050_UCODE_API_MIN,
@@ -458,10 +502,10 @@ struct iwl_cfg iwl6050_2agn_cfg = {
458 .ops = &iwl6050_ops, 502 .ops = &iwl6050_ops,
459 .eeprom_size = OTP_LOW_IMAGE_SIZE, 503 .eeprom_size = OTP_LOW_IMAGE_SIZE,
460 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 504 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
461 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 505 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
462 .num_of_queues = IWL50_NUM_QUEUES, 506 .num_of_queues = IWLAGN_NUM_QUEUES,
463 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 507 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
464 .mod_params = &iwl50_mod_params, 508 .mod_params = &iwlagn_mod_params,
465 .valid_tx_ant = ANT_AB, 509 .valid_tx_ant = ANT_AB,
466 .valid_rx_ant = ANT_AB, 510 .valid_rx_ant = ANT_AB,
467 .pll_cfg_val = 0, 511 .pll_cfg_val = 0,
@@ -479,10 +523,11 @@ struct iwl_cfg iwl6050_2agn_cfg = {
479 .support_ct_kill_exit = true, 523 .support_ct_kill_exit = true,
480 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 524 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
481 .chain_noise_scale = 1500, 525 .chain_noise_scale = 1500,
526 .monitor_recover_period = IWL_MONITORING_PERIOD,
482}; 527};
483 528
484struct iwl_cfg iwl6050_2abg_cfg = { 529struct iwl_cfg iwl6050_2abg_cfg = {
485 .name = "6050 Series 2x2 ABG", 530 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
486 .fw_name_pre = IWL6050_FW_PRE, 531 .fw_name_pre = IWL6050_FW_PRE,
487 .ucode_api_max = IWL6050_UCODE_API_MAX, 532 .ucode_api_max = IWL6050_UCODE_API_MAX,
488 .ucode_api_min = IWL6050_UCODE_API_MIN, 533 .ucode_api_min = IWL6050_UCODE_API_MIN,
@@ -490,10 +535,10 @@ struct iwl_cfg iwl6050_2abg_cfg = {
490 .ops = &iwl6050_ops, 535 .ops = &iwl6050_ops,
491 .eeprom_size = OTP_LOW_IMAGE_SIZE, 536 .eeprom_size = OTP_LOW_IMAGE_SIZE,
492 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 537 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
493 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 538 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
494 .num_of_queues = IWL50_NUM_QUEUES, 539 .num_of_queues = IWLAGN_NUM_QUEUES,
495 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 540 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
496 .mod_params = &iwl50_mod_params, 541 .mod_params = &iwlagn_mod_params,
497 .valid_tx_ant = ANT_AB, 542 .valid_tx_ant = ANT_AB,
498 .valid_rx_ant = ANT_AB, 543 .valid_rx_ant = ANT_AB,
499 .pll_cfg_val = 0, 544 .pll_cfg_val = 0,
@@ -510,10 +555,11 @@ struct iwl_cfg iwl6050_2abg_cfg = {
510 .support_ct_kill_exit = true, 555 .support_ct_kill_exit = true,
511 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 556 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
512 .chain_noise_scale = 1500, 557 .chain_noise_scale = 1500,
558 .monitor_recover_period = IWL_MONITORING_PERIOD,
513}; 559};
514 560
515struct iwl_cfg iwl6000_3agn_cfg = { 561struct iwl_cfg iwl6000_3agn_cfg = {
516 .name = "6000 Series 3x3 AGN", 562 .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN",
517 .fw_name_pre = IWL6000_FW_PRE, 563 .fw_name_pre = IWL6000_FW_PRE,
518 .ucode_api_max = IWL6000_UCODE_API_MAX, 564 .ucode_api_max = IWL6000_UCODE_API_MAX,
519 .ucode_api_min = IWL6000_UCODE_API_MIN, 565 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -521,10 +567,10 @@ struct iwl_cfg iwl6000_3agn_cfg = {
521 .ops = &iwl6000_ops, 567 .ops = &iwl6000_ops,
522 .eeprom_size = OTP_LOW_IMAGE_SIZE, 568 .eeprom_size = OTP_LOW_IMAGE_SIZE,
523 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 569 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
524 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 570 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
525 .num_of_queues = IWL50_NUM_QUEUES, 571 .num_of_queues = IWLAGN_NUM_QUEUES,
526 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 572 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
527 .mod_params = &iwl50_mod_params, 573 .mod_params = &iwlagn_mod_params,
528 .valid_tx_ant = ANT_ABC, 574 .valid_tx_ant = ANT_ABC,
529 .valid_rx_ant = ANT_ABC, 575 .valid_rx_ant = ANT_ABC,
530 .pll_cfg_val = 0, 576 .pll_cfg_val = 0,
@@ -542,6 +588,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
542 .support_ct_kill_exit = true, 588 .support_ct_kill_exit = true,
543 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 589 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
544 .chain_noise_scale = 1000, 590 .chain_noise_scale = 1000,
591 .monitor_recover_period = IWL_MONITORING_PERIOD,
545}; 592};
546 593
547MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 594MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
new file mode 100644
index 000000000000..28bc8f8ba981
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -0,0 +1,274 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-io.h"
38#include "iwl-agn.h"
39
40static int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
41{
42 int ret = 0;
43 struct iwl5000_rxon_assoc_cmd rxon_assoc;
44 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
45 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
46
47 if ((rxon1->flags == rxon2->flags) &&
48 (rxon1->filter_flags == rxon2->filter_flags) &&
49 (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
50 (rxon1->ofdm_ht_single_stream_basic_rates ==
51 rxon2->ofdm_ht_single_stream_basic_rates) &&
52 (rxon1->ofdm_ht_dual_stream_basic_rates ==
53 rxon2->ofdm_ht_dual_stream_basic_rates) &&
54 (rxon1->ofdm_ht_triple_stream_basic_rates ==
55 rxon2->ofdm_ht_triple_stream_basic_rates) &&
56 (rxon1->acquisition_data == rxon2->acquisition_data) &&
57 (rxon1->rx_chain == rxon2->rx_chain) &&
58 (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
59 IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
60 return 0;
61 }
62
63 rxon_assoc.flags = priv->staging_rxon.flags;
64 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
65 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
66 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
67 rxon_assoc.reserved1 = 0;
68 rxon_assoc.reserved2 = 0;
69 rxon_assoc.reserved3 = 0;
70 rxon_assoc.ofdm_ht_single_stream_basic_rates =
71 priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
72 rxon_assoc.ofdm_ht_dual_stream_basic_rates =
73 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
74 rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
75 rxon_assoc.ofdm_ht_triple_stream_basic_rates =
76 priv->staging_rxon.ofdm_ht_triple_stream_basic_rates;
77 rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data;
78
79 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
80 sizeof(rxon_assoc), &rxon_assoc, NULL);
81 if (ret)
82 return ret;
83
84 return ret;
85}
86
87static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
88{
89 struct iwl_tx_ant_config_cmd tx_ant_cmd = {
90 .valid = cpu_to_le32(valid_tx_ant),
91 };
92
93 if (IWL_UCODE_API(priv->ucode_ver) > 1) {
94 IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
95 return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD,
96 sizeof(struct iwl_tx_ant_config_cmd),
97 &tx_ant_cmd);
98 } else {
99 IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
100 return -EOPNOTSUPP;
101 }
102}
103
104/* Currently this is the superset of everything */
105static u16 iwlagn_get_hcmd_size(u8 cmd_id, u16 len)
106{
107 return len;
108}
109
110static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
111{
112 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
113 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
114 memcpy(addsta, cmd, size);
115 /* resrved in 5000 */
116 addsta->rate_n_flags = cpu_to_le16(0);
117 return size;
118}
119
120static void iwlagn_gain_computation(struct iwl_priv *priv,
121 u32 average_noise[NUM_RX_CHAINS],
122 u16 min_average_noise_antenna_i,
123 u32 min_average_noise,
124 u8 default_chain)
125{
126 int i;
127 s32 delta_g;
128 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
129
130 /*
131 * Find Gain Code for the chains based on "default chain"
132 */
133 for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
134 if ((data->disconn_array[i])) {
135 data->delta_gain_code[i] = 0;
136 continue;
137 }
138
139 delta_g = (priv->cfg->chain_noise_scale *
140 ((s32)average_noise[default_chain] -
141 (s32)average_noise[i])) / 1500;
142
143 /* bound gain by 2 bits value max, 3rd bit is sign */
144 data->delta_gain_code[i] =
145 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
146
147 if (delta_g < 0)
148 /*
149 * set negative sign ...
150 * note to Intel developers: This is uCode API format,
151 * not the format of any internal device registers.
152 * Do not change this format for e.g. 6050 or similar
153 * devices. Change format only if more resolution
154 * (i.e. more than 2 bits magnitude) is needed.
155 */
156 data->delta_gain_code[i] |= (1 << 2);
157 }
158
159 IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d ANT_C = %d\n",
160 data->delta_gain_code[1], data->delta_gain_code[2]);
161
162 if (!data->radio_write) {
163 struct iwl_calib_chain_noise_gain_cmd cmd;
164
165 memset(&cmd, 0, sizeof(cmd));
166
167 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
168 cmd.hdr.first_group = 0;
169 cmd.hdr.groups_num = 1;
170 cmd.hdr.data_valid = 1;
171 cmd.delta_gain_1 = data->delta_gain_code[1];
172 cmd.delta_gain_2 = data->delta_gain_code[2];
173 iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
174 sizeof(cmd), &cmd, NULL);
175
176 data->radio_write = 1;
177 data->state = IWL_CHAIN_NOISE_CALIBRATED;
178 }
179
180 data->chain_noise_a = 0;
181 data->chain_noise_b = 0;
182 data->chain_noise_c = 0;
183 data->chain_signal_a = 0;
184 data->chain_signal_b = 0;
185 data->chain_signal_c = 0;
186 data->beacon_count = 0;
187}
188
189static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
190{
191 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
192 int ret;
193
194 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
195 struct iwl_calib_chain_noise_reset_cmd cmd;
196 memset(&cmd, 0, sizeof(cmd));
197
198 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
199 cmd.hdr.first_group = 0;
200 cmd.hdr.groups_num = 1;
201 cmd.hdr.data_valid = 1;
202 ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
203 sizeof(cmd), &cmd);
204 if (ret)
205 IWL_ERR(priv,
206 "Could not send REPLY_PHY_CALIBRATION_CMD\n");
207 data->state = IWL_CHAIN_NOISE_ACCUMULATE;
208 IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
209 }
210}
211
212static void iwlagn_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
213 __le32 *tx_flags)
214{
215 if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
216 (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
217 *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
218 else
219 *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK;
220}
221
222/* Calc max signal level (dBm) among 3 possible receivers */
223static int iwlagn_calc_rssi(struct iwl_priv *priv,
224 struct iwl_rx_phy_res *rx_resp)
225{
226 /* data from PHY/DSP regarding signal strength, etc.,
227 * contents are always there, not configurable by host
228 */
229 struct iwl5000_non_cfg_phy *ncphy =
230 (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
231 u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
232 u8 agc;
233
234 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
235 agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
236
237 /* Find max rssi among 3 possible receivers.
238 * These values are measured by the digital signal processor (DSP).
239 * They should stay fairly constant even as the signal strength varies,
240 * if the radio's automatic gain control (AGC) is working right.
241 * AGC value (see below) will provide the "interesting" info.
242 */
243 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
244 rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
245 rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
246 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
247 rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
248
249 max_rssi = max_t(u32, rssi_a, rssi_b);
250 max_rssi = max_t(u32, max_rssi, rssi_c);
251
252 IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
253 rssi_a, rssi_b, rssi_c, max_rssi, agc);
254
255 /* dBm = max_rssi dB - agc dB - constant.
256 * Higher AGC (higher radio gain) means lower signal. */
257 return max_rssi - agc - IWLAGN_RSSI_OFFSET;
258}
259
260struct iwl_hcmd_ops iwlagn_hcmd = {
261 .rxon_assoc = iwlagn_send_rxon_assoc,
262 .commit_rxon = iwl_commit_rxon,
263 .set_rxon_chain = iwl_set_rxon_chain,
264 .set_tx_ant = iwlagn_send_tx_ant_config,
265};
266
267struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
268 .get_hcmd_size = iwlagn_get_hcmd_size,
269 .build_addsta_hcmd = iwlagn_build_addsta_hcmd,
270 .gain_computation = iwlagn_gain_computation,
271 .chain_noise_reset = iwlagn_chain_noise_reset,
272 .rts_tx_cmd_flag = iwlagn_rts_tx_cmd_flag,
273 .calc_rssi = iwlagn_calc_rssi,
274};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
new file mode 100644
index 000000000000..f9a3fbb6338f
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -0,0 +1,118 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63/*
64 * Please use this file (iwl-agn-hw.h) only for hardware-related definitions.
65 */
66
67#ifndef __iwl_agn_hw_h__
68#define __iwl_agn_hw_h__
69
70#define IWLAGN_RTC_INST_LOWER_BOUND (0x000000)
71#define IWLAGN_RTC_INST_UPPER_BOUND (0x020000)
72
73#define IWLAGN_RTC_DATA_LOWER_BOUND (0x800000)
74#define IWLAGN_RTC_DATA_UPPER_BOUND (0x80C000)
75
76#define IWLAGN_RTC_INST_SIZE (IWLAGN_RTC_INST_UPPER_BOUND - \
77 IWLAGN_RTC_INST_LOWER_BOUND)
78#define IWLAGN_RTC_DATA_SIZE (IWLAGN_RTC_DATA_UPPER_BOUND - \
79 IWLAGN_RTC_DATA_LOWER_BOUND)
80
81/* RSSI to dBm */
82#define IWLAGN_RSSI_OFFSET 44
83
84/* PCI registers */
85#define PCI_CFG_RETRY_TIMEOUT 0x041
86
87/* PCI register values */
88#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
89#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
90
91#define IWLAGN_DEFAULT_TX_RETRY 15
92
93/* Limit range of txpower output target to be between these values */
94#define IWLAGN_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm: 1 milliwatt */
95#define IWLAGN_TX_POWER_TARGET_POWER_MAX (16) /* 16 dBm */
96
97/* EEPROM */
98#define IWLAGN_EEPROM_IMG_SIZE 2048
99
100#define IWLAGN_CMD_FIFO_NUM 7
101#define IWLAGN_NUM_QUEUES 20
102#define IWLAGN_NUM_AMPDU_QUEUES 10
103#define IWLAGN_FIRST_AMPDU_QUEUE 10
104
105/* Fixed (non-configurable) rx data from phy */
106
107/**
108 * struct iwlagn_schedq_bc_tbl scheduler byte count table
109 * base physical address provided by SCD_DRAM_BASE_ADDR
110 * @tfd_offset 0-12 - tx command byte count
111 * 12-16 - station index
112 */
113struct iwlagn_scd_bc_tbl {
114 __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
115} __attribute__ ((packed));
116
117
118#endif /* __iwl_agn_hw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
new file mode 100644
index 000000000000..a273e373b7b0
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -0,0 +1,307 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/etherdevice.h>
32#include <linux/sched.h>
33#include <net/mac80211.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-agn.h"
38#include "iwl-helpers.h"
39
40#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
41
42/* Free dram table */
43void iwl_free_isr_ict(struct iwl_priv *priv)
44{
45 if (priv->_agn.ict_tbl_vir) {
46 dma_free_coherent(&priv->pci_dev->dev,
47 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
48 priv->_agn.ict_tbl_vir,
49 priv->_agn.ict_tbl_dma);
50 priv->_agn.ict_tbl_vir = NULL;
51 }
52}
53
54
55/* allocate dram shared table it is a PAGE_SIZE aligned
56 * also reset all data related to ICT table interrupt.
57 */
58int iwl_alloc_isr_ict(struct iwl_priv *priv)
59{
60
61 if (priv->cfg->use_isr_legacy)
62 return 0;
63 /* allocate shrared data table */
64 priv->_agn.ict_tbl_vir =
65 dma_alloc_coherent(&priv->pci_dev->dev,
66 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
67 &priv->_agn.ict_tbl_dma, GFP_KERNEL);
68 if (!priv->_agn.ict_tbl_vir)
69 return -ENOMEM;
70
71 /* align table to PAGE_SIZE boundry */
72 priv->_agn.aligned_ict_tbl_dma = ALIGN(priv->_agn.ict_tbl_dma, PAGE_SIZE);
73
74 IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n",
75 (unsigned long long)priv->_agn.ict_tbl_dma,
76 (unsigned long long)priv->_agn.aligned_ict_tbl_dma,
77 (int)(priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma));
78
79 priv->_agn.ict_tbl = priv->_agn.ict_tbl_vir +
80 (priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma);
81
82 IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n",
83 priv->_agn.ict_tbl, priv->_agn.ict_tbl_vir,
84 (int)(priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma));
85
86 /* reset table and index to all 0 */
87 memset(priv->_agn.ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
88 priv->_agn.ict_index = 0;
89
90 /* add periodic RX interrupt */
91 priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
92 return 0;
93}
94
95/* Device is going up inform it about using ICT interrupt table,
96 * also we need to tell the driver to start using ICT interrupt.
97 */
98int iwl_reset_ict(struct iwl_priv *priv)
99{
100 u32 val;
101 unsigned long flags;
102
103 if (!priv->_agn.ict_tbl_vir)
104 return 0;
105
106 spin_lock_irqsave(&priv->lock, flags);
107 iwl_disable_interrupts(priv);
108
109 memset(&priv->_agn.ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
110
111 val = priv->_agn.aligned_ict_tbl_dma >> PAGE_SHIFT;
112
113 val |= CSR_DRAM_INT_TBL_ENABLE;
114 val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
115
116 IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X "
117 "aligned dma address %Lx\n",
118 val, (unsigned long long)priv->_agn.aligned_ict_tbl_dma);
119
120 iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val);
121 priv->_agn.use_ict = true;
122 priv->_agn.ict_index = 0;
123 iwl_write32(priv, CSR_INT, priv->inta_mask);
124 iwl_enable_interrupts(priv);
125 spin_unlock_irqrestore(&priv->lock, flags);
126
127 return 0;
128}
129
130/* Device is going down disable ict interrupt usage */
131void iwl_disable_ict(struct iwl_priv *priv)
132{
133 unsigned long flags;
134
135 spin_lock_irqsave(&priv->lock, flags);
136 priv->_agn.use_ict = false;
137 spin_unlock_irqrestore(&priv->lock, flags);
138}
139
140static irqreturn_t iwl_isr(int irq, void *data)
141{
142 struct iwl_priv *priv = data;
143 u32 inta, inta_mask;
144 unsigned long flags;
145#ifdef CONFIG_IWLWIFI_DEBUG
146 u32 inta_fh;
147#endif
148 if (!priv)
149 return IRQ_NONE;
150
151 spin_lock_irqsave(&priv->lock, flags);
152
153 /* Disable (but don't clear!) interrupts here to avoid
154 * back-to-back ISRs and sporadic interrupts from our NIC.
155 * If we have something to service, the tasklet will re-enable ints.
156 * If we *don't* have something, we'll re-enable before leaving here. */
157 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
158 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
159
160 /* Discover which interrupts are active/pending */
161 inta = iwl_read32(priv, CSR_INT);
162
163 /* Ignore interrupt if there's nothing in NIC to service.
164 * This may be due to IRQ shared with another device,
165 * or due to sporadic interrupts thrown from our NIC. */
166 if (!inta) {
167 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
168 goto none;
169 }
170
171 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
172 /* Hardware disappeared. It might have already raised
173 * an interrupt */
174 IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
175 goto unplugged;
176 }
177
178#ifdef CONFIG_IWLWIFI_DEBUG
179 if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
180 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
181 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
182 "fh 0x%08x\n", inta, inta_mask, inta_fh);
183 }
184#endif
185
186 priv->_agn.inta |= inta;
187 /* iwl_irq_tasklet() will service interrupts and re-enable them */
188 if (likely(inta))
189 tasklet_schedule(&priv->irq_tasklet);
190 else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta)
191 iwl_enable_interrupts(priv);
192
193 unplugged:
194 spin_unlock_irqrestore(&priv->lock, flags);
195 return IRQ_HANDLED;
196
197 none:
198 /* re-enable interrupts here since we don't have anything to service. */
199 /* only Re-enable if diabled by irq and no schedules tasklet. */
200 if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta)
201 iwl_enable_interrupts(priv);
202
203 spin_unlock_irqrestore(&priv->lock, flags);
204 return IRQ_NONE;
205}
206
207/* interrupt handler using ict table, with this interrupt driver will
208 * stop using INTA register to get device's interrupt, reading this register
209 * is expensive, device will write interrupts in ICT dram table, increment
210 * index then will fire interrupt to driver, driver will OR all ICT table
211 * entries from current index up to table entry with 0 value. the result is
212 * the interrupt we need to service, driver will set the entries back to 0 and
213 * set index.
214 */
215irqreturn_t iwl_isr_ict(int irq, void *data)
216{
217 struct iwl_priv *priv = data;
218 u32 inta, inta_mask;
219 u32 val = 0;
220 unsigned long flags;
221
222 if (!priv)
223 return IRQ_NONE;
224
225 /* dram interrupt table not set yet,
226 * use legacy interrupt.
227 */
228 if (!priv->_agn.use_ict)
229 return iwl_isr(irq, data);
230
231 spin_lock_irqsave(&priv->lock, flags);
232
233 /* Disable (but don't clear!) interrupts here to avoid
234 * back-to-back ISRs and sporadic interrupts from our NIC.
235 * If we have something to service, the tasklet will re-enable ints.
236 * If we *don't* have something, we'll re-enable before leaving here.
237 */
238 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
239 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
240
241
242 /* Ignore interrupt if there's nothing in NIC to service.
243 * This may be due to IRQ shared with another device,
244 * or due to sporadic interrupts thrown from our NIC. */
245 if (!priv->_agn.ict_tbl[priv->_agn.ict_index]) {
246 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
247 goto none;
248 }
249
250 /* read all entries that not 0 start with ict_index */
251 while (priv->_agn.ict_tbl[priv->_agn.ict_index]) {
252
253 val |= le32_to_cpu(priv->_agn.ict_tbl[priv->_agn.ict_index]);
254 IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
255 priv->_agn.ict_index,
256 le32_to_cpu(priv->_agn.ict_tbl[priv->_agn.ict_index]));
257 priv->_agn.ict_tbl[priv->_agn.ict_index] = 0;
258 priv->_agn.ict_index = iwl_queue_inc_wrap(priv->_agn.ict_index,
259 ICT_COUNT);
260
261 }
262
263 /* We should not get this value, just ignore it. */
264 if (val == 0xffffffff)
265 val = 0;
266
267 /*
268 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
269 * (bit 15 before shifting it to 31) to clear when using interrupt
270 * coalescing. fortunately, bits 18 and 19 stay set when this happens
271 * so we use them to decide on the real state of the Rx bit.
272 * In order words, bit 15 is set if bit 18 or bit 19 are set.
273 */
274 if (val & 0xC0000)
275 val |= 0x8000;
276
277 inta = (0xff & val) | ((0xff00 & val) << 16);
278 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
279 inta, inta_mask, val);
280
281 inta &= priv->inta_mask;
282 priv->_agn.inta |= inta;
283
284 /* iwl_irq_tasklet() will service interrupts and re-enable them */
285 if (likely(inta))
286 tasklet_schedule(&priv->irq_tasklet);
287 else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) {
288 /* Allow interrupt if was disabled by this handler and
289 * no tasklet was schedules, We should not enable interrupt,
290 * tasklet will enable it.
291 */
292 iwl_enable_interrupts(priv);
293 }
294
295 spin_unlock_irqrestore(&priv->lock, flags);
296 return IRQ_HANDLED;
297
298 none:
299 /* re-enable interrupts here since we don't have anything to service.
300 * only Re-enable if disabled by irq.
301 */
302 if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta)
303 iwl_enable_interrupts(priv);
304
305 spin_unlock_irqrestore(&priv->lock, flags);
306 return IRQ_NONE;
307}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
new file mode 100644
index 000000000000..49e20f1acb7c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -0,0 +1,1103 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29#include <linux/etherdevice.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-io.h"
38#include "iwl-helpers.h"
39#include "iwl-agn-hw.h"
40#include "iwl-agn.h"
41
42static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
43{
44 return le32_to_cpup((__le32 *)&tx_resp->status +
45 tx_resp->frame_count) & MAX_SN;
46}
47
48static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
49 struct iwl_ht_agg *agg,
50 struct iwl5000_tx_resp *tx_resp,
51 int txq_id, u16 start_idx)
52{
53 u16 status;
54 struct agg_tx_status *frame_status = &tx_resp->status;
55 struct ieee80211_tx_info *info = NULL;
56 struct ieee80211_hdr *hdr = NULL;
57 u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
58 int i, sh, idx;
59 u16 seq;
60
61 if (agg->wait_for_ba)
62 IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
63
64 agg->frame_count = tx_resp->frame_count;
65 agg->start_idx = start_idx;
66 agg->rate_n_flags = rate_n_flags;
67 agg->bitmap = 0;
68
69 /* # frames attempted by Tx command */
70 if (agg->frame_count == 1) {
71 /* Only one frame was attempted; no block-ack will arrive */
72 status = le16_to_cpu(frame_status[0].status);
73 idx = start_idx;
74
75 /* FIXME: code repetition */
76 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
77 agg->frame_count, agg->start_idx, idx);
78
79 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
80 info->status.rates[0].count = tx_resp->failure_frame + 1;
81 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
82 info->flags |= iwl_tx_status_to_mac80211(status);
83 iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
84
85 /* FIXME: code repetition end */
86
87 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
88 status & 0xff, tx_resp->failure_frame);
89 IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
90
91 agg->wait_for_ba = 0;
92 } else {
93 /* Two or more frames were attempted; expect block-ack */
94 u64 bitmap = 0;
95 int start = agg->start_idx;
96
97 /* Construct bit-map of pending frames within Tx window */
98 for (i = 0; i < agg->frame_count; i++) {
99 u16 sc;
100 status = le16_to_cpu(frame_status[i].status);
101 seq = le16_to_cpu(frame_status[i].sequence);
102 idx = SEQ_TO_INDEX(seq);
103 txq_id = SEQ_TO_QUEUE(seq);
104
105 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
106 AGG_TX_STATE_ABORT_MSK))
107 continue;
108
109 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
110 agg->frame_count, txq_id, idx);
111
112 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
113 if (!hdr) {
114 IWL_ERR(priv,
115 "BUG_ON idx doesn't point to valid skb"
116 " idx=%d, txq_id=%d\n", idx, txq_id);
117 return -1;
118 }
119
120 sc = le16_to_cpu(hdr->seq_ctrl);
121 if (idx != (SEQ_TO_SN(sc) & 0xff)) {
122 IWL_ERR(priv,
123 "BUG_ON idx doesn't match seq control"
124 " idx=%d, seq_idx=%d, seq=%d\n",
125 idx, SEQ_TO_SN(sc),
126 hdr->seq_ctrl);
127 return -1;
128 }
129
130 IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
131 i, idx, SEQ_TO_SN(sc));
132
133 sh = idx - start;
134 if (sh > 64) {
135 sh = (start - idx) + 0xff;
136 bitmap = bitmap << sh;
137 sh = 0;
138 start = idx;
139 } else if (sh < -64)
140 sh = 0xff - (start - idx);
141 else if (sh < 0) {
142 sh = start - idx;
143 start = idx;
144 bitmap = bitmap << sh;
145 sh = 0;
146 }
147 bitmap |= 1ULL << sh;
148 IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
149 start, (unsigned long long)bitmap);
150 }
151
152 agg->bitmap = bitmap;
153 agg->start_idx = start;
154 IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
155 agg->frame_count, agg->start_idx,
156 (unsigned long long)agg->bitmap);
157
158 if (bitmap)
159 agg->wait_for_ba = 1;
160 }
161 return 0;
162}
163
164static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
165 struct iwl_rx_mem_buffer *rxb)
166{
167 struct iwl_rx_packet *pkt = rxb_addr(rxb);
168 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
169 int txq_id = SEQ_TO_QUEUE(sequence);
170 int index = SEQ_TO_INDEX(sequence);
171 struct iwl_tx_queue *txq = &priv->txq[txq_id];
172 struct ieee80211_tx_info *info;
173 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
174 u32 status = le16_to_cpu(tx_resp->status.status);
175 int tid;
176 int sta_id;
177 int freed;
178
179 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
180 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
181 "is out of range [0-%d] %d %d\n", txq_id,
182 index, txq->q.n_bd, txq->q.write_ptr,
183 txq->q.read_ptr);
184 return;
185 }
186
187 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
188 memset(&info->status, 0, sizeof(info->status));
189
190 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
191 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
192
193 if (txq->sched_retry) {
194 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
195 struct iwl_ht_agg *agg = NULL;
196
197 agg = &priv->stations[sta_id].tid[tid].agg;
198
199 iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
200
201 /* check if BAR is needed */
202 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
203 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
204
205 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
206 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
207 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim "
208 "scd_ssn=%d idx=%d txq=%d swq=%d\n",
209 scd_ssn , index, txq_id, txq->swq_id);
210
211 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
212 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
213
214 if (priv->mac80211_registered &&
215 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
216 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
217 if (agg->state == IWL_AGG_OFF)
218 iwl_wake_queue(priv, txq_id);
219 else
220 iwl_wake_queue(priv, txq->swq_id);
221 }
222 }
223 } else {
224 BUG_ON(txq_id != txq->swq_id);
225
226 info->status.rates[0].count = tx_resp->failure_frame + 1;
227 info->flags |= iwl_tx_status_to_mac80211(status);
228 iwlagn_hwrate_to_tx_control(priv,
229 le32_to_cpu(tx_resp->rate_n_flags),
230 info);
231
232 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
233 "0x%x retries %d\n",
234 txq_id,
235 iwl_get_tx_fail_reason(status), status,
236 le32_to_cpu(tx_resp->rate_n_flags),
237 tx_resp->failure_frame);
238
239 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
240 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
241
242 if (priv->mac80211_registered &&
243 (iwl_queue_space(&txq->q) > txq->q.low_mark))
244 iwl_wake_queue(priv, txq_id);
245 }
246
247 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
248
249 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
250 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
251}
252
253void iwlagn_rx_handler_setup(struct iwl_priv *priv)
254{
255 /* init calibration handlers */
256 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
257 iwlagn_rx_calib_result;
258 priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
259 iwlagn_rx_calib_complete;
260 priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
261}
262
263void iwlagn_setup_deferred_work(struct iwl_priv *priv)
264{
265 /* in agn, the tx power calibration is done in uCode */
266 priv->disable_tx_power_cal = 1;
267}
268
269int iwlagn_hw_valid_rtc_data_addr(u32 addr)
270{
271 return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) &&
272 (addr < IWLAGN_RTC_DATA_UPPER_BOUND);
273}
274
275int iwlagn_send_tx_power(struct iwl_priv *priv)
276{
277 struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
278 u8 tx_ant_cfg_cmd;
279
280 /* half dBm need to multiply */
281 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
282
283 if (priv->tx_power_lmt_in_half_dbm &&
284 priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) {
285 /*
286 * For the newer devices which using enhanced/extend tx power
287 * table in EEPROM, the format is in half dBm. driver need to
288 * convert to dBm format before report to mac80211.
289 * By doing so, there is a possibility of 1/2 dBm resolution
290 * lost. driver will perform "round-up" operation before
291 * reporting, but it will cause 1/2 dBm tx power over the
292 * regulatory limit. Perform the checking here, if the
293 * "tx_power_user_lmt" is higher than EEPROM value (in
294 * half-dBm format), lower the tx power based on EEPROM
295 */
296 tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
297 }
298 tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
299 tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
300
301 if (IWL_UCODE_API(priv->ucode_ver) == 1)
302 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
303 else
304 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
305
306 return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
307 sizeof(tx_power_cmd), &tx_power_cmd,
308 NULL);
309}
310
311void iwlagn_temperature(struct iwl_priv *priv)
312{
313 /* store temperature from statistics (in Celsius) */
314 priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
315 iwl_tt_handler(priv);
316}
317
318u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv)
319{
320 struct iwl_eeprom_calib_hdr {
321 u8 version;
322 u8 pa_type;
323 u16 voltage;
324 } *hdr;
325
326 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
327 EEPROM_5000_CALIB_ALL);
328 return hdr->version;
329
330}
331
332/*
333 * EEPROM
334 */
335static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
336{
337 u16 offset = 0;
338
339 if ((address & INDIRECT_ADDRESS) == 0)
340 return address;
341
342 switch (address & INDIRECT_TYPE_MSK) {
343 case INDIRECT_HOST:
344 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_HOST);
345 break;
346 case INDIRECT_GENERAL:
347 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_GENERAL);
348 break;
349 case INDIRECT_REGULATORY:
350 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_REGULATORY);
351 break;
352 case INDIRECT_CALIBRATION:
353 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_CALIBRATION);
354 break;
355 case INDIRECT_PROCESS_ADJST:
356 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_PROCESS_ADJST);
357 break;
358 case INDIRECT_OTHERS:
359 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
360 break;
361 default:
362 IWL_ERR(priv, "illegal indirect type: 0x%X\n",
363 address & INDIRECT_TYPE_MSK);
364 break;
365 }
366
367 /* translate the offset from words to byte */
368 return (address & ADDRESS_MSK) + (offset << 1);
369}
370
371const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
372 size_t offset)
373{
374 u32 address = eeprom_indirect_address(priv, offset);
375 BUG_ON(address >= priv->cfg->eeprom_size);
376 return &priv->eeprom[address];
377}
378
379struct iwl_mod_params iwlagn_mod_params = {
380 .amsdu_size_8K = 1,
381 .restart_fw = 1,
382 /* the rest are 0 by default */
383};
384
385void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
386{
387 unsigned long flags;
388 int i;
389 spin_lock_irqsave(&rxq->lock, flags);
390 INIT_LIST_HEAD(&rxq->rx_free);
391 INIT_LIST_HEAD(&rxq->rx_used);
392 /* Fill the rx_used queue with _all_ of the Rx buffers */
393 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
394 /* In the reset function, these buffers may have been allocated
395 * to an SKB, so we need to unmap and free potential storage */
396 if (rxq->pool[i].page != NULL) {
397 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
398 PAGE_SIZE << priv->hw_params.rx_page_order,
399 PCI_DMA_FROMDEVICE);
400 __iwl_free_pages(priv, rxq->pool[i].page);
401 rxq->pool[i].page = NULL;
402 }
403 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
404 }
405
406 for (i = 0; i < RX_QUEUE_SIZE; i++)
407 rxq->queue[i] = NULL;
408
409 /* Set us so that we have processed and used all buffers, but have
410 * not restocked the Rx queue with fresh buffers */
411 rxq->read = rxq->write = 0;
412 rxq->write_actual = 0;
413 rxq->free_count = 0;
414 spin_unlock_irqrestore(&rxq->lock, flags);
415}
416
417int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
418{
419 u32 rb_size;
420 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
421 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
422
423 if (!priv->cfg->use_isr_legacy)
424 rb_timeout = RX_RB_TIMEOUT;
425
426 if (priv->cfg->mod_params->amsdu_size_8K)
427 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
428 else
429 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
430
431 /* Stop Rx DMA */
432 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
433
434 /* Reset driver's Rx queue write index */
435 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
436
437 /* Tell device where to find RBD circular buffer in DRAM */
438 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
439 (u32)(rxq->dma_addr >> 8));
440
441 /* Tell device where in DRAM to update its Rx status */
442 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
443 rxq->rb_stts_dma >> 4);
444
445 /* Enable Rx DMA
446 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
447 * the credit mechanism in 5000 HW RX FIFO
448 * Direct rx interrupts to hosts
449 * Rx buffer size 4 or 8k
450 * RB timeout 0x10
451 * 256 RBDs
452 */
453 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
454 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
455 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
456 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
457 FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
458 rb_size|
459 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
460 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
461
462 /* Set interrupt coalescing timer to default (2048 usecs) */
463 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
464
465 return 0;
466}
467
468int iwlagn_hw_nic_init(struct iwl_priv *priv)
469{
470 unsigned long flags;
471 struct iwl_rx_queue *rxq = &priv->rxq;
472 int ret;
473
474 /* nic_init */
475 spin_lock_irqsave(&priv->lock, flags);
476 priv->cfg->ops->lib->apm_ops.init(priv);
477
478 /* Set interrupt coalescing calibration timer to default (512 usecs) */
479 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
480
481 spin_unlock_irqrestore(&priv->lock, flags);
482
483 ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
484
485 priv->cfg->ops->lib->apm_ops.config(priv);
486
487 /* Allocate the RX queue, or reset if it is already allocated */
488 if (!rxq->bd) {
489 ret = iwl_rx_queue_alloc(priv);
490 if (ret) {
491 IWL_ERR(priv, "Unable to initialize Rx queue\n");
492 return -ENOMEM;
493 }
494 } else
495 iwlagn_rx_queue_reset(priv, rxq);
496
497 iwlagn_rx_replenish(priv);
498
499 iwlagn_rx_init(priv, rxq);
500
501 spin_lock_irqsave(&priv->lock, flags);
502
503 rxq->need_update = 1;
504 iwl_rx_queue_update_write_ptr(priv, rxq);
505
506 spin_unlock_irqrestore(&priv->lock, flags);
507
508 /* Allocate and init all Tx and Command queues */
509 ret = iwlagn_txq_ctx_reset(priv);
510 if (ret)
511 return ret;
512
513 set_bit(STATUS_INIT, &priv->status);
514
515 return 0;
516}
517
518/**
519 * iwlagn_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
520 */
521static inline __le32 iwlagn_dma_addr2rbd_ptr(struct iwl_priv *priv,
522 dma_addr_t dma_addr)
523{
524 return cpu_to_le32((u32)(dma_addr >> 8));
525}
526
527/**
528 * iwlagn_rx_queue_restock - refill RX queue from pre-allocated pool
529 *
530 * If there are slots in the RX queue that need to be restocked,
531 * and we have free pre-allocated buffers, fill the ranks as much
532 * as we can, pulling from rx_free.
533 *
534 * This moves the 'write' index forward to catch up with 'processed', and
535 * also updates the memory address in the firmware to reference the new
536 * target buffer.
537 */
538void iwlagn_rx_queue_restock(struct iwl_priv *priv)
539{
540 struct iwl_rx_queue *rxq = &priv->rxq;
541 struct list_head *element;
542 struct iwl_rx_mem_buffer *rxb;
543 unsigned long flags;
544
545 spin_lock_irqsave(&rxq->lock, flags);
546 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
547 /* The overwritten rxb must be a used one */
548 rxb = rxq->queue[rxq->write];
549 BUG_ON(rxb && rxb->page);
550
551 /* Get next free Rx buffer, remove from free list */
552 element = rxq->rx_free.next;
553 rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
554 list_del(element);
555
556 /* Point to Rx buffer via next RBD in circular buffer */
557 rxq->bd[rxq->write] = iwlagn_dma_addr2rbd_ptr(priv,
558 rxb->page_dma);
559 rxq->queue[rxq->write] = rxb;
560 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
561 rxq->free_count--;
562 }
563 spin_unlock_irqrestore(&rxq->lock, flags);
564 /* If the pre-allocated buffer pool is dropping low, schedule to
565 * refill it */
566 if (rxq->free_count <= RX_LOW_WATERMARK)
567 queue_work(priv->workqueue, &priv->rx_replenish);
568
569
570 /* If we've added more space for the firmware to place data, tell it.
571 * Increment device's write pointer in multiples of 8. */
572 if (rxq->write_actual != (rxq->write & ~0x7)) {
573 spin_lock_irqsave(&rxq->lock, flags);
574 rxq->need_update = 1;
575 spin_unlock_irqrestore(&rxq->lock, flags);
576 iwl_rx_queue_update_write_ptr(priv, rxq);
577 }
578}
579
580/**
581 * iwlagn_rx_replenish - Move all used packet from rx_used to rx_free
582 *
583 * When moving to rx_free an SKB is allocated for the slot.
584 *
585 * Also restock the Rx queue via iwl_rx_queue_restock.
586 * This is called as a scheduled work item (except for during initialization)
587 */
588void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority)
589{
590 struct iwl_rx_queue *rxq = &priv->rxq;
591 struct list_head *element;
592 struct iwl_rx_mem_buffer *rxb;
593 struct page *page;
594 unsigned long flags;
595 gfp_t gfp_mask = priority;
596
597 while (1) {
598 spin_lock_irqsave(&rxq->lock, flags);
599 if (list_empty(&rxq->rx_used)) {
600 spin_unlock_irqrestore(&rxq->lock, flags);
601 return;
602 }
603 spin_unlock_irqrestore(&rxq->lock, flags);
604
605 if (rxq->free_count > RX_LOW_WATERMARK)
606 gfp_mask |= __GFP_NOWARN;
607
608 if (priv->hw_params.rx_page_order > 0)
609 gfp_mask |= __GFP_COMP;
610
611 /* Alloc a new receive buffer */
612 page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
613 if (!page) {
614 if (net_ratelimit())
615 IWL_DEBUG_INFO(priv, "alloc_pages failed, "
616 "order: %d\n",
617 priv->hw_params.rx_page_order);
618
619 if ((rxq->free_count <= RX_LOW_WATERMARK) &&
620 net_ratelimit())
621 IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n",
622 priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL",
623 rxq->free_count);
624 /* We don't reschedule replenish work here -- we will
625 * call the restock method and if it still needs
626 * more buffers it will schedule replenish */
627 return;
628 }
629
630 spin_lock_irqsave(&rxq->lock, flags);
631
632 if (list_empty(&rxq->rx_used)) {
633 spin_unlock_irqrestore(&rxq->lock, flags);
634 __free_pages(page, priv->hw_params.rx_page_order);
635 return;
636 }
637 element = rxq->rx_used.next;
638 rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
639 list_del(element);
640
641 spin_unlock_irqrestore(&rxq->lock, flags);
642
643 BUG_ON(rxb->page);
644 rxb->page = page;
645 /* Get physical address of the RB */
646 rxb->page_dma = pci_map_page(priv->pci_dev, page, 0,
647 PAGE_SIZE << priv->hw_params.rx_page_order,
648 PCI_DMA_FROMDEVICE);
649 /* dma address must be no more than 36 bits */
650 BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
651 /* and also 256 byte aligned! */
652 BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
653
654 spin_lock_irqsave(&rxq->lock, flags);
655
656 list_add_tail(&rxb->list, &rxq->rx_free);
657 rxq->free_count++;
658 priv->alloc_rxb_page++;
659
660 spin_unlock_irqrestore(&rxq->lock, flags);
661 }
662}
663
664void iwlagn_rx_replenish(struct iwl_priv *priv)
665{
666 unsigned long flags;
667
668 iwlagn_rx_allocate(priv, GFP_KERNEL);
669
670 spin_lock_irqsave(&priv->lock, flags);
671 iwlagn_rx_queue_restock(priv);
672 spin_unlock_irqrestore(&priv->lock, flags);
673}
674
675void iwlagn_rx_replenish_now(struct iwl_priv *priv)
676{
677 iwlagn_rx_allocate(priv, GFP_ATOMIC);
678
679 iwlagn_rx_queue_restock(priv);
680}
681
682/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
683 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
684 * This free routine walks the list of POOL entries and if SKB is set to
685 * non NULL it is unmapped and freed
686 */
687void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
688{
689 int i;
690 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
691 if (rxq->pool[i].page != NULL) {
692 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
693 PAGE_SIZE << priv->hw_params.rx_page_order,
694 PCI_DMA_FROMDEVICE);
695 __iwl_free_pages(priv, rxq->pool[i].page);
696 rxq->pool[i].page = NULL;
697 }
698 }
699
700 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
701 rxq->dma_addr);
702 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
703 rxq->rb_stts, rxq->rb_stts_dma);
704 rxq->bd = NULL;
705 rxq->rb_stts = NULL;
706}
707
708int iwlagn_rxq_stop(struct iwl_priv *priv)
709{
710
711 /* stop Rx DMA */
712 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
713 iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
714 FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
715
716 return 0;
717}
718
719int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
720{
721 int idx = 0;
722 int band_offset = 0;
723
724 /* HT rate format: mac80211 wants an MCS number, which is just LSB */
725 if (rate_n_flags & RATE_MCS_HT_MSK) {
726 idx = (rate_n_flags & 0xff);
727 return idx;
728 /* Legacy rate format, search for match in table */
729 } else {
730 if (band == IEEE80211_BAND_5GHZ)
731 band_offset = IWL_FIRST_OFDM_RATE;
732 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
733 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
734 return idx - band_offset;
735 }
736
737 return -1;
738}
739
740/* Calc max signal level (dBm) among 3 possible receivers */
741static inline int iwlagn_calc_rssi(struct iwl_priv *priv,
742 struct iwl_rx_phy_res *rx_resp)
743{
744 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
745}
746
747#ifdef CONFIG_IWLWIFI_DEBUG
748/**
749 * iwlagn_dbg_report_frame - dump frame to syslog during debug sessions
750 *
751 * You may hack this function to show different aspects of received frames,
752 * including selective frame dumps.
753 * group100 parameter selects whether to show 1 out of 100 good data frames.
754 * All beacon and probe response frames are printed.
755 */
756static void iwlagn_dbg_report_frame(struct iwl_priv *priv,
757 struct iwl_rx_phy_res *phy_res, u16 length,
758 struct ieee80211_hdr *header, int group100)
759{
760 u32 to_us;
761 u32 print_summary = 0;
762 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
763 u32 hundred = 0;
764 u32 dataframe = 0;
765 __le16 fc;
766 u16 seq_ctl;
767 u16 channel;
768 u16 phy_flags;
769 u32 rate_n_flags;
770 u32 tsf_low;
771 int rssi;
772
773 if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX)))
774 return;
775
776 /* MAC header */
777 fc = header->frame_control;
778 seq_ctl = le16_to_cpu(header->seq_ctrl);
779
780 /* metadata */
781 channel = le16_to_cpu(phy_res->channel);
782 phy_flags = le16_to_cpu(phy_res->phy_flags);
783 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
784
785 /* signal statistics */
786 rssi = iwlagn_calc_rssi(priv, phy_res);
787 tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
788
789 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
790
791 /* if data frame is to us and all is good,
792 * (optionally) print summary for only 1 out of every 100 */
793 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
794 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
795 dataframe = 1;
796 if (!group100)
797 print_summary = 1; /* print each frame */
798 else if (priv->framecnt_to_us < 100) {
799 priv->framecnt_to_us++;
800 print_summary = 0;
801 } else {
802 priv->framecnt_to_us = 0;
803 print_summary = 1;
804 hundred = 1;
805 }
806 } else {
807 /* print summary for all other frames */
808 print_summary = 1;
809 }
810
811 if (print_summary) {
812 char *title;
813 int rate_idx;
814 u32 bitrate;
815
816 if (hundred)
817 title = "100Frames";
818 else if (ieee80211_has_retry(fc))
819 title = "Retry";
820 else if (ieee80211_is_assoc_resp(fc))
821 title = "AscRsp";
822 else if (ieee80211_is_reassoc_resp(fc))
823 title = "RasRsp";
824 else if (ieee80211_is_probe_resp(fc)) {
825 title = "PrbRsp";
826 print_dump = 1; /* dump frame contents */
827 } else if (ieee80211_is_beacon(fc)) {
828 title = "Beacon";
829 print_dump = 1; /* dump frame contents */
830 } else if (ieee80211_is_atim(fc))
831 title = "ATIM";
832 else if (ieee80211_is_auth(fc))
833 title = "Auth";
834 else if (ieee80211_is_deauth(fc))
835 title = "DeAuth";
836 else if (ieee80211_is_disassoc(fc))
837 title = "DisAssoc";
838 else
839 title = "Frame";
840
841 rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
842 if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
843 bitrate = 0;
844 WARN_ON_ONCE(1);
845 } else {
846 bitrate = iwl_rates[rate_idx].ieee / 2;
847 }
848
849 /* print frame summary.
850 * MAC addresses show just the last byte (for brevity),
851 * but you can hack it to show more, if you'd like to. */
852 if (dataframe)
853 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
854 "len=%u, rssi=%d, chnl=%d, rate=%u,\n",
855 title, le16_to_cpu(fc), header->addr1[5],
856 length, rssi, channel, bitrate);
857 else {
858 /* src/dst addresses assume managed mode */
859 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
860 "len=%u, rssi=%d, tim=%lu usec, "
861 "phy=0x%02x, chnl=%d\n",
862 title, le16_to_cpu(fc), header->addr1[5],
863 header->addr3[5], length, rssi,
864 tsf_low - priv->scan_start_tsf,
865 phy_flags, channel);
866 }
867 }
868 if (print_dump)
869 iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
870}
871#endif
872
873static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
874{
875 u32 decrypt_out = 0;
876
877 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
878 RX_RES_STATUS_STATION_FOUND)
879 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
880 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
881
882 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
883
884 /* packet was not encrypted */
885 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
886 RX_RES_STATUS_SEC_TYPE_NONE)
887 return decrypt_out;
888
889 /* packet was encrypted with unknown alg */
890 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
891 RX_RES_STATUS_SEC_TYPE_ERR)
892 return decrypt_out;
893
894 /* decryption was not done in HW */
895 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
896 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
897 return decrypt_out;
898
899 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
900
901 case RX_RES_STATUS_SEC_TYPE_CCMP:
902 /* alg is CCM: check MIC only */
903 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
904 /* Bad MIC */
905 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
906 else
907 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
908
909 break;
910
911 case RX_RES_STATUS_SEC_TYPE_TKIP:
912 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
913 /* Bad TTAK */
914 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
915 break;
916 }
917 /* fall through if TTAK OK */
918 default:
919 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
920 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
921 else
922 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
923 break;
924 };
925
926 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
927 decrypt_in, decrypt_out);
928
929 return decrypt_out;
930}
931
932static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
933 struct ieee80211_hdr *hdr,
934 u16 len,
935 u32 ampdu_status,
936 struct iwl_rx_mem_buffer *rxb,
937 struct ieee80211_rx_status *stats)
938{
939 struct sk_buff *skb;
940 __le16 fc = hdr->frame_control;
941
942 /* We only process data packets if the interface is open */
943 if (unlikely(!priv->is_open)) {
944 IWL_DEBUG_DROP_LIMIT(priv,
945 "Dropping packet while interface is not open.\n");
946 return;
947 }
948
949 /* In case of HW accelerated crypto and bad decryption, drop */
950 if (!priv->cfg->mod_params->sw_crypto &&
951 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
952 return;
953
954 skb = dev_alloc_skb(128);
955 if (!skb) {
956 IWL_ERR(priv, "dev_alloc_skb failed\n");
957 return;
958 }
959
960 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
961
962 iwl_update_stats(priv, false, fc, len);
963 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
964
965 ieee80211_rx(priv->hw, skb);
966 priv->alloc_rxb_page--;
967 rxb->page = NULL;
968}
969
970/* Called for REPLY_RX (legacy ABG frames), or
971 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
972void iwlagn_rx_reply_rx(struct iwl_priv *priv,
973 struct iwl_rx_mem_buffer *rxb)
974{
975 struct ieee80211_hdr *header;
976 struct ieee80211_rx_status rx_status;
977 struct iwl_rx_packet *pkt = rxb_addr(rxb);
978 struct iwl_rx_phy_res *phy_res;
979 __le32 rx_pkt_status;
980 struct iwl4965_rx_mpdu_res_start *amsdu;
981 u32 len;
982 u32 ampdu_status;
983 u32 rate_n_flags;
984
985 /**
986 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
987 * REPLY_RX: physical layer info is in this buffer
988 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
989 * command and cached in priv->last_phy_res
990 *
991 * Here we set up local variables depending on which command is
992 * received.
993 */
994 if (pkt->hdr.cmd == REPLY_RX) {
995 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
996 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
997 + phy_res->cfg_phy_cnt);
998
999 len = le16_to_cpu(phy_res->byte_count);
1000 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
1001 phy_res->cfg_phy_cnt + len);
1002 ampdu_status = le32_to_cpu(rx_pkt_status);
1003 } else {
1004 if (!priv->last_phy_res[0]) {
1005 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1006 return;
1007 }
1008 phy_res = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
1009 amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
1010 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1011 len = le16_to_cpu(amsdu->byte_count);
1012 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1013 ampdu_status = iwlagn_translate_rx_status(priv,
1014 le32_to_cpu(rx_pkt_status));
1015 }
1016
1017 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1018 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1019 phy_res->cfg_phy_cnt);
1020 return;
1021 }
1022
1023 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1024 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1025 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1026 le32_to_cpu(rx_pkt_status));
1027 return;
1028 }
1029
1030 /* This will be used in several places later */
1031 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1032
1033 /* rx_status carries information about the packet to mac80211 */
1034 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1035 rx_status.freq =
1036 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
1037 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1038 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1039 rx_status.rate_idx =
1040 iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1041 rx_status.flag = 0;
1042
1043 /* TSF isn't reliable. In order to allow smooth user experience,
1044 * this W/A doesn't propagate it to the mac80211 */
1045 /*rx_status.flag |= RX_FLAG_TSFT;*/
1046
1047 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1048
1049 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1050 rx_status.signal = iwlagn_calc_rssi(priv, phy_res);
1051
1052#ifdef CONFIG_IWLWIFI_DEBUG
1053 /* Set "1" to report good data frames in groups of 100 */
1054 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
1055 iwlagn_dbg_report_frame(priv, phy_res, len, header, 1);
1056#endif
1057 iwl_dbg_log_rx_data_frame(priv, len, header);
1058 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",
1059 rx_status.signal, (unsigned long long)rx_status.mactime);
1060
1061 /*
1062 * "antenna number"
1063 *
1064 * It seems that the antenna field in the phy flags value
1065 * is actually a bit field. This is undefined by radiotap,
1066 * it wants an actual antenna number but I always get "7"
1067 * for most legacy frames I receive indicating that the
1068 * same frame was received on all three RX chains.
1069 *
1070 * I think this field should be removed in favor of a
1071 * new 802.11n radiotap field "RX chains" that is defined
1072 * as a bitmask.
1073 */
1074 rx_status.antenna =
1075 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1076 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1077
1078 /* set the preamble flag if appropriate */
1079 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1080 rx_status.flag |= RX_FLAG_SHORTPRE;
1081
1082 /* Set up the HT phy flags */
1083 if (rate_n_flags & RATE_MCS_HT_MSK)
1084 rx_status.flag |= RX_FLAG_HT;
1085 if (rate_n_flags & RATE_MCS_HT40_MSK)
1086 rx_status.flag |= RX_FLAG_40MHZ;
1087 if (rate_n_flags & RATE_MCS_SGI_MSK)
1088 rx_status.flag |= RX_FLAG_SHORT_GI;
1089
1090 iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1091 rxb, &rx_status);
1092}
1093
1094/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1095 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1096void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
1097 struct iwl_rx_mem_buffer *rxb)
1098{
1099 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1100 priv->last_phy_res[0] = 1;
1101 memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
1102 sizeof(struct iwl_rx_phy_res));
1103}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index be00cb3b1d0e..0c3c76803c5e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -610,10 +610,6 @@ static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
610 struct ieee80211_hdr *hdr, 610 struct ieee80211_hdr *hdr,
611 enum iwl_table_type rate_type) 611 enum iwl_table_type rate_type)
612{ 612{
613 if (hdr && is_multicast_ether_addr(hdr->addr1) &&
614 lq_sta->active_rate_basic)
615 return lq_sta->active_rate_basic;
616
617 if (is_legacy(rate_type)) { 613 if (is_legacy(rate_type)) {
618 return lq_sta->active_legacy_rate; 614 return lq_sta->active_legacy_rate;
619 } else { 615 } else {
@@ -774,6 +770,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
774 770
775 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 771 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
776 772
773 /* Treat uninitialized rate scaling data same as non-existing. */
774 if (!lq_sta) {
775 IWL_DEBUG_RATE(priv, "Station rate scaling not created yet.\n");
776 return;
777 } else if (!lq_sta->drv) {
778 IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n");
779 return;
780 }
781
777 if (!ieee80211_is_data(hdr->frame_control) || 782 if (!ieee80211_is_data(hdr->frame_control) ||
778 info->flags & IEEE80211_TX_CTL_NO_ACK) 783 info->flags & IEEE80211_TX_CTL_NO_ACK)
779 return; 784 return;
@@ -783,10 +788,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
783 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 788 !(info->flags & IEEE80211_TX_STAT_AMPDU))
784 return; 789 return;
785 790
786 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
787 !lq_sta->ibss_sta_added)
788 return;
789
790 /* 791 /*
791 * Ignore this Tx frame response if its initial rate doesn't match 792 * Ignore this Tx frame response if its initial rate doesn't match
792 * that of latest Link Quality command. There may be stragglers 793 * that of latest Link Quality command. There may be stragglers
@@ -832,7 +833,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
832 lq_sta->missed_rate_counter++; 833 lq_sta->missed_rate_counter++;
833 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 834 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
834 lq_sta->missed_rate_counter = 0; 835 lq_sta->missed_rate_counter = 0;
835 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 836 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
836 } 837 }
837 /* Regardless, ignore this status info for outdated rate */ 838 /* Regardless, ignore this status info for outdated rate */
838 return; 839 return;
@@ -1912,7 +1913,7 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv,
1912 /* Update uCode's rate table. */ 1913 /* Update uCode's rate table. */
1913 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 1914 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
1914 rs_fill_link_cmd(priv, lq_sta, rate); 1915 rs_fill_link_cmd(priv, lq_sta, rate);
1915 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1916 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
1916 1917
1917 return rate; 1918 return rate;
1918} 1919}
@@ -2001,7 +2002,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2001 /* rates available for this association, and for modulation mode */ 2002 /* rates available for this association, and for modulation mode */
2002 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); 2003 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
2003 2004
2004 IWL_DEBUG_RATE(priv, "mask 0x%04X \n", rate_mask); 2005 IWL_DEBUG_RATE(priv, "mask 0x%04X\n", rate_mask);
2005 2006
2006 /* mask with station rate restriction */ 2007 /* mask with station rate restriction */
2007 if (is_legacy(tbl->lq_type)) { 2008 if (is_legacy(tbl->lq_type)) {
@@ -2288,7 +2289,7 @@ lq_update:
2288 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n", 2289 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
2289 tbl->current_rate, index); 2290 tbl->current_rate, index);
2290 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); 2291 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
2291 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2292 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
2292 } else 2293 } else
2293 done_search = 1; 2294 done_search = 1;
2294 } 2295 }
@@ -2337,7 +2338,20 @@ out:
2337 return; 2338 return;
2338} 2339}
2339 2340
2340 2341/**
2342 * rs_initialize_lq - Initialize a station's hardware rate table
2343 *
2344 * The uCode's station table contains a table of fallback rates
2345 * for automatic fallback during transmission.
2346 *
2347 * NOTE: This sets up a default set of values. These will be replaced later
2348 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
2349 * rc80211_simple.
2350 *
2351 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
2352 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
2353 * which requires station table entry to exist).
2354 */
2341static void rs_initialize_lq(struct iwl_priv *priv, 2355static void rs_initialize_lq(struct iwl_priv *priv,
2342 struct ieee80211_conf *conf, 2356 struct ieee80211_conf *conf,
2343 struct ieee80211_sta *sta, 2357 struct ieee80211_sta *sta,
@@ -2356,10 +2370,6 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2356 2370
2357 i = lq_sta->last_txrate_idx; 2371 i = lq_sta->last_txrate_idx;
2358 2372
2359 if ((lq_sta->lq.sta_id == 0xff) &&
2360 (priv->iw_mode == NL80211_IFTYPE_ADHOC))
2361 goto out;
2362
2363 valid_tx_ant = priv->hw_params.valid_tx_ant; 2373 valid_tx_ant = priv->hw_params.valid_tx_ant;
2364 2374
2365 if (!lq_sta->search_better_tbl) 2375 if (!lq_sta->search_better_tbl)
@@ -2387,7 +2397,8 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2387 tbl->current_rate = rate; 2397 tbl->current_rate = rate;
2388 rs_set_expected_tpt_table(lq_sta, tbl); 2398 rs_set_expected_tpt_table(lq_sta, tbl);
2389 rs_fill_link_cmd(NULL, lq_sta, rate); 2399 rs_fill_link_cmd(NULL, lq_sta, rate);
2390 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2400 priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
2401 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true);
2391 out: 2402 out:
2392 return; 2403 return;
2393} 2404}
@@ -2399,9 +2410,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2399 struct sk_buff *skb = txrc->skb; 2410 struct sk_buff *skb = txrc->skb;
2400 struct ieee80211_supported_band *sband = txrc->sband; 2411 struct ieee80211_supported_band *sband = txrc->sband;
2401 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 2412 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
2402 struct ieee80211_conf *conf = &priv->hw->conf;
2403 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2404 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2405 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2413 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2406 struct iwl_lq_sta *lq_sta = priv_sta; 2414 struct iwl_lq_sta *lq_sta = priv_sta;
2407 int rate_idx; 2415 int rate_idx;
@@ -2419,30 +2427,18 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2419 lq_sta->max_rate_idx = -1; 2427 lq_sta->max_rate_idx = -1;
2420 } 2428 }
2421 2429
2430 /* Treat uninitialized rate scaling data same as non-existing. */
2431 if (lq_sta && !lq_sta->drv) {
2432 IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n");
2433 priv_sta = NULL;
2434 }
2435
2422 /* Send management frames and NO_ACK data using lowest rate. */ 2436 /* Send management frames and NO_ACK data using lowest rate. */
2423 if (rate_control_send_low(sta, priv_sta, txrc)) 2437 if (rate_control_send_low(sta, priv_sta, txrc))
2424 return; 2438 return;
2425 2439
2426 rate_idx = lq_sta->last_txrate_idx; 2440 rate_idx = lq_sta->last_txrate_idx;
2427 2441
2428 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
2429 !lq_sta->ibss_sta_added) {
2430 u8 sta_id = iwl_find_station(priv, hdr->addr1);
2431
2432 if (sta_id == IWL_INVALID_STATION) {
2433 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
2434 hdr->addr1);
2435 sta_id = iwl_add_station(priv, hdr->addr1,
2436 false, CMD_ASYNC, ht_cap);
2437 }
2438 if ((sta_id != IWL_INVALID_STATION)) {
2439 lq_sta->lq.sta_id = sta_id;
2440 lq_sta->lq.rs_table[0].rate_n_flags = 0;
2441 lq_sta->ibss_sta_added = 1;
2442 rs_initialize_lq(priv, conf, sta, lq_sta);
2443 }
2444 }
2445
2446 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { 2442 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
2447 rate_idx -= IWL_FIRST_OFDM_RATE; 2443 rate_idx -= IWL_FIRST_OFDM_RATE;
2448 /* 6M and 9M shared same MCS index */ 2444 /* 6M and 9M shared same MCS index */
@@ -2492,16 +2488,25 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
2492 return lq_sta; 2488 return lq_sta;
2493} 2489}
2494 2490
2495static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, 2491/*
2496 struct ieee80211_sta *sta, void *priv_sta) 2492 * Called after adding a new station to initialize rate scaling
2493 */
2494void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id)
2497{ 2495{
2498 int i, j; 2496 int i, j;
2499 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 2497 struct ieee80211_hw *hw = priv->hw;
2500 struct ieee80211_conf *conf = &priv->hw->conf; 2498 struct ieee80211_conf *conf = &priv->hw->conf;
2501 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 2499 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2502 struct iwl_lq_sta *lq_sta = priv_sta; 2500 struct iwl_station_priv *sta_priv;
2501 struct iwl_lq_sta *lq_sta;
2502 struct ieee80211_supported_band *sband;
2503
2504 sta_priv = (struct iwl_station_priv *) sta->drv_priv;
2505 lq_sta = &sta_priv->lq_sta;
2506 sband = hw->wiphy->bands[conf->channel->band];
2507
2503 2508
2504 lq_sta->lq.sta_id = 0xff; 2509 lq_sta->lq.sta_id = sta_id;
2505 2510
2506 for (j = 0; j < LQ_SIZE; j++) 2511 for (j = 0; j < LQ_SIZE; j++)
2507 for (i = 0; i < IWL_RATE_COUNT; i++) 2512 for (i = 0; i < IWL_RATE_COUNT; i++)
@@ -2513,39 +2518,18 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2513 for (i = 0; i < IWL_RATE_COUNT; i++) 2518 for (i = 0; i < IWL_RATE_COUNT; i++)
2514 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); 2519 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2515 2520
2516 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init ***\n"); 2521 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init for station %d ***\n",
2522 sta_id);
2517 /* TODO: what is a good starting rate for STA? About middle? Maybe not 2523 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2518 * the lowest or the highest rate.. Could consider using RSSI from 2524 * the lowest or the highest rate.. Could consider using RSSI from
2519 * previous packets? Need to have IEEE 802.1X auth succeed immediately 2525 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2520 * after assoc.. */ 2526 * after assoc.. */
2521 2527
2522 lq_sta->ibss_sta_added = 0;
2523 if (priv->iw_mode == NL80211_IFTYPE_AP) {
2524 u8 sta_id = iwl_find_station(priv,
2525 sta->addr);
2526
2527 /* for IBSS the call are from tasklet */
2528 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2529
2530 if (sta_id == IWL_INVALID_STATION) {
2531 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2532 sta_id = iwl_add_station(priv, sta->addr, false,
2533 CMD_ASYNC, ht_cap);
2534 }
2535 if ((sta_id != IWL_INVALID_STATION)) {
2536 lq_sta->lq.sta_id = sta_id;
2537 lq_sta->lq.rs_table[0].rate_n_flags = 0;
2538 }
2539 /* FIXME: this is w/a remove it later */
2540 priv->assoc_station_added = 1;
2541 }
2542
2543 lq_sta->is_dup = 0; 2528 lq_sta->is_dup = 0;
2544 lq_sta->max_rate_idx = -1; 2529 lq_sta->max_rate_idx = -1;
2545 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2530 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2546 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); 2531 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
2547 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); 2532 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
2548 lq_sta->active_rate_basic = priv->active_rate_basic;
2549 lq_sta->band = priv->band; 2533 lq_sta->band = priv->band;
2550 /* 2534 /*
2551 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), 2535 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
@@ -2793,7 +2777,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2793 2777
2794 if (lq_sta->dbg_fixed_rate) { 2778 if (lq_sta->dbg_fixed_rate) {
2795 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); 2779 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
2796 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); 2780 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
2797 } 2781 }
2798 2782
2799 return count; 2783 return count;
@@ -2949,12 +2933,6 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
2949 desc += sprintf(buff+desc, 2933 desc += sprintf(buff+desc,
2950 "Bit Rate= %d Mb/s\n", 2934 "Bit Rate= %d Mb/s\n",
2951 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); 2935 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
2952 desc += sprintf(buff+desc,
2953 "Signal Level= %d dBm\tNoise Level= %d dBm\n",
2954 priv->last_rx_rssi, priv->last_rx_noise);
2955 desc += sprintf(buff+desc,
2956 "Tsf= 0x%llx\tBeacon time= 0x%08X\n",
2957 priv->last_tsf, priv->last_beacon_time);
2958 2936
2959 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 2937 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2960 return ret; 2938 return ret;
@@ -2994,12 +2972,21 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
2994} 2972}
2995#endif 2973#endif
2996 2974
2975/*
2976 * Initialization of rate scaling information is done by driver after
2977 * the station is added. Since mac80211 calls this function before a
2978 * station is added we ignore it.
2979 */
2980static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,
2981 struct ieee80211_sta *sta, void *priv_sta)
2982{
2983}
2997static struct rate_control_ops rs_ops = { 2984static struct rate_control_ops rs_ops = {
2998 .module = NULL, 2985 .module = NULL,
2999 .name = RS_NAME, 2986 .name = RS_NAME,
3000 .tx_status = rs_tx_status, 2987 .tx_status = rs_tx_status,
3001 .get_rate = rs_get_rate, 2988 .get_rate = rs_get_rate,
3002 .rate_init = rs_rate_init, 2989 .rate_init = rs_rate_init_stub,
3003 .alloc = rs_alloc, 2990 .alloc = rs_alloc,
3004 .free = rs_free, 2991 .free = rs_free,
3005 .alloc_sta = rs_alloc_sta, 2992 .alloc_sta = rs_alloc_sta,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index e71923961e69..8292f6d48ec6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -403,7 +403,6 @@ struct iwl_lq_sta {
403 u8 is_green; 403 u8 is_green;
404 u8 is_dup; 404 u8 is_dup;
405 enum ieee80211_band band; 405 enum ieee80211_band band;
406 u8 ibss_sta_added;
407 406
408 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 407 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
409 u32 supp_rates; 408 u32 supp_rates;
@@ -411,7 +410,6 @@ struct iwl_lq_sta {
411 u16 active_siso_rate; 410 u16 active_siso_rate;
412 u16 active_mimo2_rate; 411 u16 active_mimo2_rate;
413 u16 active_mimo3_rate; 412 u16 active_mimo3_rate;
414 u16 active_rate_basic;
415 s8 max_rate_idx; /* Max rate set by user */ 413 s8 max_rate_idx; /* Max rate set by user */
416 u8 missed_rate_counter; 414 u8 missed_rate_counter;
417 415
@@ -479,6 +477,12 @@ static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
479 */ 477 */
480extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); 478extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
481 479
480/* Initialize station's rate scaling information after adding station */
481extern void iwl_rs_rate_init(struct iwl_priv *priv,
482 struct ieee80211_sta *sta, u8 sta_id);
483extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
484 struct ieee80211_sta *sta, u8 sta_id);
485
482/** 486/**
483 * iwl_rate_control_register - Register the rate control algorithm callbacks 487 * iwl_rate_control_register - Register the rate control algorithm callbacks
484 * 488 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
new file mode 100644
index 000000000000..a76e14351b5a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -0,0 +1,1314 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-sta.h"
38#include "iwl-io.h"
39#include "iwl-helpers.h"
40#include "iwl-agn-hw.h"
41#include "iwl-agn.h"
42
43/*
44 * mac80211 queues, ACs, hardware queues, FIFOs.
45 *
46 * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
47 *
48 * Mac80211 uses the following numbers, which we get as from it
49 * by way of skb_get_queue_mapping(skb):
50 *
51 * VO 0
52 * VI 1
53 * BE 2
54 * BK 3
55 *
56 *
57 * Regular (not A-MPDU) frames are put into hardware queues corresponding
58 * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their
59 * own queue per aggregation session (RA/TID combination), such queues are
60 * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In
61 * order to map frames to the right queue, we also need an AC->hw queue
62 * mapping. This is implemented here.
63 *
64 * Due to the way hw queues are set up (by the hw specific modules like
65 * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity
66 * mapping.
67 */
68
69static const u8 tid_to_ac[] = {
70 /* this matches the mac80211 numbers */
71 2, 3, 3, 2, 1, 1, 0, 0
72};
73
74static const u8 ac_to_fifo[] = {
75 IWL_TX_FIFO_VO,
76 IWL_TX_FIFO_VI,
77 IWL_TX_FIFO_BE,
78 IWL_TX_FIFO_BK,
79};
80
81static inline int get_fifo_from_ac(u8 ac)
82{
83 return ac_to_fifo[ac];
84}
85
86static inline int get_fifo_from_tid(u16 tid)
87{
88 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
89 return get_fifo_from_ac(tid_to_ac[tid]);
90
91 /* no support for TIDs 8-15 yet */
92 return -EINVAL;
93}
94
95/**
96 * iwlagn_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
97 */
98void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
99 struct iwl_tx_queue *txq,
100 u16 byte_cnt)
101{
102 struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
103 int write_ptr = txq->q.write_ptr;
104 int txq_id = txq->q.id;
105 u8 sec_ctl = 0;
106 u8 sta_id = 0;
107 u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
108 __le16 bc_ent;
109
110 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
111
112 if (txq_id != IWL_CMD_QUEUE_NUM) {
113 sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
114 sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
115
116 switch (sec_ctl & TX_CMD_SEC_MSK) {
117 case TX_CMD_SEC_CCM:
118 len += CCMP_MIC_LEN;
119 break;
120 case TX_CMD_SEC_TKIP:
121 len += TKIP_ICV_LEN;
122 break;
123 case TX_CMD_SEC_WEP:
124 len += WEP_IV_LEN + WEP_ICV_LEN;
125 break;
126 }
127 }
128
129 bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
130
131 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
132
133 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
134 scd_bc_tbl[txq_id].
135 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
136}
137
138void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
139 struct iwl_tx_queue *txq)
140{
141 struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
142 int txq_id = txq->q.id;
143 int read_ptr = txq->q.read_ptr;
144 u8 sta_id = 0;
145 __le16 bc_ent;
146
147 WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
148
149 if (txq_id != IWL_CMD_QUEUE_NUM)
150 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
151
152 bc_ent = cpu_to_le16(1 | (sta_id << 12));
153 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
154
155 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
156 scd_bc_tbl[txq_id].
157 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
158}
159
160static int iwlagn_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
161 u16 txq_id)
162{
163 u32 tbl_dw_addr;
164 u32 tbl_dw;
165 u16 scd_q2ratid;
166
167 scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
168
169 tbl_dw_addr = priv->scd_base_addr +
170 IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
171
172 tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
173
174 if (txq_id & 0x1)
175 tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
176 else
177 tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
178
179 iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
180
181 return 0;
182}
183
184static void iwlagn_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
185{
186 /* Simply stop the queue, but don't change any configuration;
187 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
188 iwl_write_prph(priv,
189 IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
190 (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
191 (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
192}
193
194void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
195 int txq_id, u32 index)
196{
197 iwl_write_direct32(priv, HBUS_TARG_WRPTR,
198 (index & 0xff) | (txq_id << 8));
199 iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(txq_id), index);
200}
201
202void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
203 struct iwl_tx_queue *txq,
204 int tx_fifo_id, int scd_retry)
205{
206 int txq_id = txq->q.id;
207 int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
208
209 iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
210 (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
211 (tx_fifo_id << IWL50_SCD_QUEUE_STTS_REG_POS_TXF) |
212 (1 << IWL50_SCD_QUEUE_STTS_REG_POS_WSL) |
213 IWL50_SCD_QUEUE_STTS_REG_MSK);
214
215 txq->sched_retry = scd_retry;
216
217 IWL_DEBUG_INFO(priv, "%s %s Queue %d on FIFO %d\n",
218 active ? "Activate" : "Deactivate",
219 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
220}
221
222int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
223 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
224{
225 unsigned long flags;
226 u16 ra_tid;
227
228 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
229 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
230 <= txq_id)) {
231 IWL_WARN(priv,
232 "queue number out of range: %d, must be %d to %d\n",
233 txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
234 IWLAGN_FIRST_AMPDU_QUEUE +
235 priv->cfg->num_of_ampdu_queues - 1);
236 return -EINVAL;
237 }
238
239 ra_tid = BUILD_RAxTID(sta_id, tid);
240
241 /* Modify device's station table to Tx this TID */
242 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
243
244 spin_lock_irqsave(&priv->lock, flags);
245
246 /* Stop this Tx queue before configuring it */
247 iwlagn_tx_queue_stop_scheduler(priv, txq_id);
248
249 /* Map receiver-address / traffic-ID to this queue */
250 iwlagn_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
251
252 /* Set this queue as a chain-building queue */
253 iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
254
255 /* enable aggregations for the queue */
256 iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
257
258 /* Place first TFD at index corresponding to start sequence number.
259 * Assumes that ssn_idx is valid (!= 0xFFF) */
260 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
261 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
262 iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx);
263
264 /* Set up Tx window size and frame limit for this queue */
265 iwl_write_targ_mem(priv, priv->scd_base_addr +
266 IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
267 sizeof(u32),
268 ((SCD_WIN_SIZE <<
269 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
270 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
271 ((SCD_FRAME_LIMIT <<
272 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
273 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
274
275 iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
276
277 /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
278 iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
279
280 spin_unlock_irqrestore(&priv->lock, flags);
281
282 return 0;
283}
284
285int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
286 u16 ssn_idx, u8 tx_fifo)
287{
288 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
289 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
290 <= txq_id)) {
291 IWL_ERR(priv,
292 "queue number out of range: %d, must be %d to %d\n",
293 txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
294 IWLAGN_FIRST_AMPDU_QUEUE +
295 priv->cfg->num_of_ampdu_queues - 1);
296 return -EINVAL;
297 }
298
299 iwlagn_tx_queue_stop_scheduler(priv, txq_id);
300
301 iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
302
303 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
304 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
305 /* supposes that ssn_idx is valid (!= 0xFFF) */
306 iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx);
307
308 iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
309 iwl_txq_ctx_deactivate(priv, txq_id);
310 iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
311
312 return 0;
313}
314
315/*
316 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
317 * must be called under priv->lock and mac access
318 */
319void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
320{
321 iwl_write_prph(priv, IWL50_SCD_TXFACT, mask);
322}
323
324static inline int get_queue_from_ac(u16 ac)
325{
326 return ac;
327}
328
329/*
330 * handle build REPLY_TX command notification.
331 */
332static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
333 struct iwl_tx_cmd *tx_cmd,
334 struct ieee80211_tx_info *info,
335 struct ieee80211_hdr *hdr,
336 u8 std_id)
337{
338 __le16 fc = hdr->frame_control;
339 __le32 tx_flags = tx_cmd->tx_flags;
340
341 tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
342 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
343 tx_flags |= TX_CMD_FLG_ACK_MSK;
344 if (ieee80211_is_mgmt(fc))
345 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
346 if (ieee80211_is_probe_resp(fc) &&
347 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
348 tx_flags |= TX_CMD_FLG_TSF_MSK;
349 } else {
350 tx_flags &= (~TX_CMD_FLG_ACK_MSK);
351 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
352 }
353
354 if (ieee80211_is_back_req(fc))
355 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
356
357
358 tx_cmd->sta_id = std_id;
359 if (ieee80211_has_morefrags(fc))
360 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
361
362 if (ieee80211_is_data_qos(fc)) {
363 u8 *qc = ieee80211_get_qos_ctl(hdr);
364 tx_cmd->tid_tspec = qc[0] & 0xf;
365 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
366 } else {
367 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
368 }
369
370 priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
371
372 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
373 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
374
375 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
376 if (ieee80211_is_mgmt(fc)) {
377 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
378 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
379 else
380 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
381 } else {
382 tx_cmd->timeout.pm_frame_timeout = 0;
383 }
384
385 tx_cmd->driver_txop = 0;
386 tx_cmd->tx_flags = tx_flags;
387 tx_cmd->next_frame_len = 0;
388}
389
390#define RTS_DFAULT_RETRY_LIMIT 60
391
392static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
393 struct iwl_tx_cmd *tx_cmd,
394 struct ieee80211_tx_info *info,
395 __le16 fc)
396{
397 u32 rate_flags;
398 int rate_idx;
399 u8 rts_retry_limit;
400 u8 data_retry_limit;
401 u8 rate_plcp;
402
403 /* Set retry limit on DATA packets and Probe Responses*/
404 if (ieee80211_is_probe_resp(fc))
405 data_retry_limit = 3;
406 else
407 data_retry_limit = IWLAGN_DEFAULT_TX_RETRY;
408 tx_cmd->data_retry_limit = data_retry_limit;
409
410 /* Set retry limit on RTS packets */
411 rts_retry_limit = RTS_DFAULT_RETRY_LIMIT;
412 if (data_retry_limit < rts_retry_limit)
413 rts_retry_limit = data_retry_limit;
414 tx_cmd->rts_retry_limit = rts_retry_limit;
415
416 /* DATA packets will use the uCode station table for rate/antenna
417 * selection */
418 if (ieee80211_is_data(fc)) {
419 tx_cmd->initial_rate_index = 0;
420 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
421 return;
422 }
423
424 /**
425 * If the current TX rate stored in mac80211 has the MCS bit set, it's
426 * not really a TX rate. Thus, we use the lowest supported rate for
427 * this band. Also use the lowest supported rate if the stored rate
428 * index is invalid.
429 */
430 rate_idx = info->control.rates[0].idx;
431 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS ||
432 (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY))
433 rate_idx = rate_lowest_index(&priv->bands[info->band],
434 info->control.sta);
435 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
436 if (info->band == IEEE80211_BAND_5GHZ)
437 rate_idx += IWL_FIRST_OFDM_RATE;
438 /* Get PLCP rate for tx_cmd->rate_n_flags */
439 rate_plcp = iwl_rates[rate_idx].plcp;
440 /* Zero out flags for this packet */
441 rate_flags = 0;
442
443 /* Set CCK flag as needed */
444 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
445 rate_flags |= RATE_MCS_CCK_MSK;
446
447 /* Set up RTS and CTS flags for certain packets */
448 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
449 case cpu_to_le16(IEEE80211_STYPE_AUTH):
450 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
451 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
452 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
453 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
454 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
455 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
456 }
457 break;
458 default:
459 break;
460 }
461
462 /* Set up antennas */
463 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
464 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
465
466 /* Set the rate in the TX cmd */
467 tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
468}
469
470static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
471 struct ieee80211_tx_info *info,
472 struct iwl_tx_cmd *tx_cmd,
473 struct sk_buff *skb_frag,
474 int sta_id)
475{
476 struct ieee80211_key_conf *keyconf = info->control.hw_key;
477
478 switch (keyconf->alg) {
479 case ALG_CCMP:
480 tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
481 memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
482 if (info->flags & IEEE80211_TX_CTL_AMPDU)
483 tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
484 IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
485 break;
486
487 case ALG_TKIP:
488 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
489 ieee80211_get_tkip_key(keyconf, skb_frag,
490 IEEE80211_TKIP_P2_KEY, tx_cmd->key);
491 IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
492 break;
493
494 case ALG_WEP:
495 tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP |
496 (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
497
498 if (keyconf->keylen == WEP_KEY_LEN_128)
499 tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
500
501 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
502
503 IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
504 "with key %d\n", keyconf->keyidx);
505 break;
506
507 default:
508 IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
509 break;
510 }
511}
512
513/*
514 * start REPLY_TX command process
515 */
516int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
517{
518 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
519 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
520 struct ieee80211_sta *sta = info->control.sta;
521 struct iwl_station_priv *sta_priv = NULL;
522 struct iwl_tx_queue *txq;
523 struct iwl_queue *q;
524 struct iwl_device_cmd *out_cmd;
525 struct iwl_cmd_meta *out_meta;
526 struct iwl_tx_cmd *tx_cmd;
527 int swq_id, txq_id;
528 dma_addr_t phys_addr;
529 dma_addr_t txcmd_phys;
530 dma_addr_t scratch_phys;
531 u16 len, len_org, firstlen, secondlen;
532 u16 seq_number = 0;
533 __le16 fc;
534 u8 hdr_len;
535 u8 sta_id;
536 u8 wait_write_ptr = 0;
537 u8 tid = 0;
538 u8 *qc = NULL;
539 unsigned long flags;
540
541 spin_lock_irqsave(&priv->lock, flags);
542 if (iwl_is_rfkill(priv)) {
543 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
544 goto drop_unlock;
545 }
546
547 fc = hdr->frame_control;
548
549#ifdef CONFIG_IWLWIFI_DEBUG
550 if (ieee80211_is_auth(fc))
551 IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
552 else if (ieee80211_is_assoc_req(fc))
553 IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
554 else if (ieee80211_is_reassoc_req(fc))
555 IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
556#endif
557
558 hdr_len = ieee80211_hdrlen(fc);
559
560 /* Find (or create) index into station table for destination station */
561 if (info->flags & IEEE80211_TX_CTL_INJECTED)
562 sta_id = priv->hw_params.bcast_sta_id;
563 else
564 sta_id = iwl_get_sta_id(priv, hdr);
565 if (sta_id == IWL_INVALID_STATION) {
566 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
567 hdr->addr1);
568 goto drop_unlock;
569 }
570
571 IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
572
573 if (sta)
574 sta_priv = (void *)sta->drv_priv;
575
576 if (sta_priv && sta_id != priv->hw_params.bcast_sta_id &&
577 sta_priv->asleep) {
578 WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
579 /*
580 * This sends an asynchronous command to the device,
581 * but we can rely on it being processed before the
582 * next frame is processed -- and the next frame to
583 * this station is the one that will consume this
584 * counter.
585 * For now set the counter to just 1 since we do not
586 * support uAPSD yet.
587 */
588 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
589 }
590
591 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
592 if (ieee80211_is_data_qos(fc)) {
593 qc = ieee80211_get_qos_ctl(hdr);
594 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
595 if (unlikely(tid >= MAX_TID_COUNT))
596 goto drop_unlock;
597 seq_number = priv->stations[sta_id].tid[tid].seq_number;
598 seq_number &= IEEE80211_SCTL_SEQ;
599 hdr->seq_ctrl = hdr->seq_ctrl &
600 cpu_to_le16(IEEE80211_SCTL_FRAG);
601 hdr->seq_ctrl |= cpu_to_le16(seq_number);
602 seq_number += 0x10;
603 /* aggregation is on for this <sta,tid> */
604 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
605 priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
606 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
607 }
608 }
609
610 txq = &priv->txq[txq_id];
611 swq_id = txq->swq_id;
612 q = &txq->q;
613
614 if (unlikely(iwl_queue_space(q) < q->high_mark))
615 goto drop_unlock;
616
617 if (ieee80211_is_data_qos(fc))
618 priv->stations[sta_id].tid[tid].tfds_in_queue++;
619
620 /* Set up driver data for this TFD */
621 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
622 txq->txb[q->write_ptr].skb[0] = skb;
623
624 /* Set up first empty entry in queue's array of Tx/cmd buffers */
625 out_cmd = txq->cmd[q->write_ptr];
626 out_meta = &txq->meta[q->write_ptr];
627 tx_cmd = &out_cmd->cmd.tx;
628 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
629 memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
630
631 /*
632 * Set up the Tx-command (not MAC!) header.
633 * Store the chosen Tx queue and TFD index within the sequence field;
634 * after Tx, uCode's Tx response will return this value so driver can
635 * locate the frame within the tx queue and do post-tx processing.
636 */
637 out_cmd->hdr.cmd = REPLY_TX;
638 out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
639 INDEX_TO_SEQ(q->write_ptr)));
640
641 /* Copy MAC header from skb into command buffer */
642 memcpy(tx_cmd->hdr, hdr, hdr_len);
643
644
645 /* Total # bytes to be transmitted */
646 len = (u16)skb->len;
647 tx_cmd->len = cpu_to_le16(len);
648
649 if (info->control.hw_key)
650 iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
651
652 /* TODO need this for burst mode later on */
653 iwlagn_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
654 iwl_dbg_log_tx_data_frame(priv, len, hdr);
655
656 iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc);
657
658 iwl_update_stats(priv, true, fc, len);
659 /*
660 * Use the first empty entry in this queue's command buffer array
661 * to contain the Tx command and MAC header concatenated together
662 * (payload data will be in another buffer).
663 * Size of this varies, due to varying MAC header length.
664 * If end is not dword aligned, we'll have 2 extra bytes at the end
665 * of the MAC header (device reads on dword boundaries).
666 * We'll tell device about this padding later.
667 */
668 len = sizeof(struct iwl_tx_cmd) +
669 sizeof(struct iwl_cmd_header) + hdr_len;
670
671 len_org = len;
672 firstlen = len = (len + 3) & ~3;
673
674 if (len_org != len)
675 len_org = 1;
676 else
677 len_org = 0;
678
679 /* Tell NIC about any 2-byte padding after MAC header */
680 if (len_org)
681 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
682
683 /* Physical address of this Tx command's header (not MAC header!),
684 * within command buffer array. */
685 txcmd_phys = pci_map_single(priv->pci_dev,
686 &out_cmd->hdr, len,
687 PCI_DMA_BIDIRECTIONAL);
688 pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
689 pci_unmap_len_set(out_meta, len, len);
690 /* Add buffer containing Tx command and MAC(!) header to TFD's
691 * first entry */
692 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
693 txcmd_phys, len, 1, 0);
694
695 if (!ieee80211_has_morefrags(hdr->frame_control)) {
696 txq->need_update = 1;
697 if (qc)
698 priv->stations[sta_id].tid[tid].seq_number = seq_number;
699 } else {
700 wait_write_ptr = 1;
701 txq->need_update = 0;
702 }
703
704 /* Set up TFD's 2nd entry to point directly to remainder of skb,
705 * if any (802.11 null frames have no payload). */
706 secondlen = len = skb->len - hdr_len;
707 if (len) {
708 phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
709 len, PCI_DMA_TODEVICE);
710 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
711 phys_addr, len,
712 0, 0);
713 }
714
715 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
716 offsetof(struct iwl_tx_cmd, scratch);
717
718 len = sizeof(struct iwl_tx_cmd) +
719 sizeof(struct iwl_cmd_header) + hdr_len;
720 /* take back ownership of DMA buffer to enable update */
721 pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
722 len, PCI_DMA_BIDIRECTIONAL);
723 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
724 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
725
726 IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n",
727 le16_to_cpu(out_cmd->hdr.sequence));
728 IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
729 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
730 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
731
732 /* Set up entry for this TFD in Tx byte-count array */
733 if (info->flags & IEEE80211_TX_CTL_AMPDU)
734 priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
735 le16_to_cpu(tx_cmd->len));
736
737 pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
738 len, PCI_DMA_BIDIRECTIONAL);
739
740 trace_iwlwifi_dev_tx(priv,
741 &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
742 sizeof(struct iwl_tfd),
743 &out_cmd->hdr, firstlen,
744 skb->data + hdr_len, secondlen);
745
746 /* Tell device the write index *just past* this latest filled TFD */
747 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
748 iwl_txq_update_write_ptr(priv, txq);
749 spin_unlock_irqrestore(&priv->lock, flags);
750
751 /*
752 * At this point the frame is "transmitted" successfully
753 * and we will get a TX status notification eventually,
754 * regardless of the value of ret. "ret" only indicates
755 * whether or not we should update the write pointer.
756 */
757
758 /* avoid atomic ops if it isn't an associated client */
759 if (sta_priv && sta_priv->client)
760 atomic_inc(&sta_priv->pending_frames);
761
762 if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
763 if (wait_write_ptr) {
764 spin_lock_irqsave(&priv->lock, flags);
765 txq->need_update = 1;
766 iwl_txq_update_write_ptr(priv, txq);
767 spin_unlock_irqrestore(&priv->lock, flags);
768 } else {
769 iwl_stop_queue(priv, txq->swq_id);
770 }
771 }
772
773 return 0;
774
775drop_unlock:
776 spin_unlock_irqrestore(&priv->lock, flags);
777 return -1;
778}
779
780static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv,
781 struct iwl_dma_ptr *ptr, size_t size)
782{
783 ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma,
784 GFP_KERNEL);
785 if (!ptr->addr)
786 return -ENOMEM;
787 ptr->size = size;
788 return 0;
789}
790
791static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv,
792 struct iwl_dma_ptr *ptr)
793{
794 if (unlikely(!ptr->addr))
795 return;
796
797 dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
798 memset(ptr, 0, sizeof(*ptr));
799}
800
801/**
802 * iwlagn_hw_txq_ctx_free - Free TXQ Context
803 *
804 * Destroy all TX DMA queues and structures
805 */
806void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
807{
808 int txq_id;
809
810 /* Tx queues */
811 if (priv->txq) {
812 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
813 txq_id++)
814 if (txq_id == IWL_CMD_QUEUE_NUM)
815 iwl_cmd_queue_free(priv);
816 else
817 iwl_tx_queue_free(priv, txq_id);
818 }
819 iwlagn_free_dma_ptr(priv, &priv->kw);
820
821 iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls);
822
823 /* free tx queue structure */
824 iwl_free_txq_mem(priv);
825}
826
827/**
828 * iwlagn_txq_ctx_reset - Reset TX queue context
829 * Destroys all DMA structures and initialize them again
830 *
831 * @param priv
832 * @return error code
833 */
834int iwlagn_txq_ctx_reset(struct iwl_priv *priv)
835{
836 int ret = 0;
837 int txq_id, slots_num;
838 unsigned long flags;
839
840 /* Free all tx/cmd queues and keep-warm buffer */
841 iwlagn_hw_txq_ctx_free(priv);
842
843 ret = iwlagn_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
844 priv->hw_params.scd_bc_tbls_size);
845 if (ret) {
846 IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
847 goto error_bc_tbls;
848 }
849 /* Alloc keep-warm buffer */
850 ret = iwlagn_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
851 if (ret) {
852 IWL_ERR(priv, "Keep Warm allocation failed\n");
853 goto error_kw;
854 }
855
856 /* allocate tx queue structure */
857 ret = iwl_alloc_txq_mem(priv);
858 if (ret)
859 goto error;
860
861 spin_lock_irqsave(&priv->lock, flags);
862
863 /* Turn off all Tx DMA fifos */
864 priv->cfg->ops->lib->txq_set_sched(priv, 0);
865
866 /* Tell NIC where to find the "keep warm" buffer */
867 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
868
869 spin_unlock_irqrestore(&priv->lock, flags);
870
871 /* Alloc and init all Tx queues, including the command queue (#4) */
872 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
873 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
874 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
875 ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
876 txq_id);
877 if (ret) {
878 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
879 goto error;
880 }
881 }
882
883 return ret;
884
885 error:
886 iwlagn_hw_txq_ctx_free(priv);
887 iwlagn_free_dma_ptr(priv, &priv->kw);
888 error_kw:
889 iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls);
890 error_bc_tbls:
891 return ret;
892}
893
894/**
895 * iwlagn_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
896 */
897void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
898{
899 int ch;
900 unsigned long flags;
901
902 /* Turn off all Tx DMA fifos */
903 spin_lock_irqsave(&priv->lock, flags);
904
905 priv->cfg->ops->lib->txq_set_sched(priv, 0);
906
907 /* Stop each Tx DMA channel, and wait for it to be idle */
908 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
909 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
910 iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
911 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
912 1000);
913 }
914 spin_unlock_irqrestore(&priv->lock, flags);
915
916 /* Deallocate memory for all Tx queues */
917 iwlagn_hw_txq_ctx_free(priv);
918}
919
920/*
921 * Find first available (lowest unused) Tx Queue, mark it "active".
922 * Called only when finding queue for aggregation.
923 * Should never return anything < 7, because they should already
924 * be in use as EDCA AC (0-3), Command (4), reserved (5, 6)
925 */
926static int iwlagn_txq_ctx_activate_free(struct iwl_priv *priv)
927{
928 int txq_id;
929
930 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
931 if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk))
932 return txq_id;
933 return -1;
934}
935
936int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
937{
938 int sta_id;
939 int tx_fifo;
940 int txq_id;
941 int ret;
942 unsigned long flags;
943 struct iwl_tid_data *tid_data;
944
945 tx_fifo = get_fifo_from_tid(tid);
946 if (unlikely(tx_fifo < 0))
947 return tx_fifo;
948
949 IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
950 __func__, ra, tid);
951
952 sta_id = iwl_find_station(priv, ra);
953 if (sta_id == IWL_INVALID_STATION) {
954 IWL_ERR(priv, "Start AGG on invalid station\n");
955 return -ENXIO;
956 }
957 if (unlikely(tid >= MAX_TID_COUNT))
958 return -EINVAL;
959
960 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
961 IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
962 return -ENXIO;
963 }
964
965 txq_id = iwlagn_txq_ctx_activate_free(priv);
966 if (txq_id == -1) {
967 IWL_ERR(priv, "No free aggregation queue available\n");
968 return -ENXIO;
969 }
970
971 spin_lock_irqsave(&priv->sta_lock, flags);
972 tid_data = &priv->stations[sta_id].tid[tid];
973 *ssn = SEQ_TO_SN(tid_data->seq_number);
974 tid_data->agg.txq_id = txq_id;
975 priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(tx_fifo, txq_id);
976 spin_unlock_irqrestore(&priv->sta_lock, flags);
977
978 ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
979 sta_id, tid, *ssn);
980 if (ret)
981 return ret;
982
983 if (tid_data->tfds_in_queue == 0) {
984 IWL_DEBUG_HT(priv, "HW queue is empty\n");
985 tid_data->agg.state = IWL_AGG_ON;
986 ieee80211_start_tx_ba_cb_irqsafe(priv->vif, ra, tid);
987 } else {
988 IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
989 tid_data->tfds_in_queue);
990 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
991 }
992 return ret;
993}
994
995int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
996{
997 int tx_fifo_id, txq_id, sta_id, ssn = -1;
998 struct iwl_tid_data *tid_data;
999 int write_ptr, read_ptr;
1000 unsigned long flags;
1001
1002 if (!ra) {
1003 IWL_ERR(priv, "ra = NULL\n");
1004 return -EINVAL;
1005 }
1006
1007 tx_fifo_id = get_fifo_from_tid(tid);
1008 if (unlikely(tx_fifo_id < 0))
1009 return tx_fifo_id;
1010
1011 sta_id = iwl_find_station(priv, ra);
1012
1013 if (sta_id == IWL_INVALID_STATION) {
1014 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1015 return -ENXIO;
1016 }
1017
1018 if (priv->stations[sta_id].tid[tid].agg.state ==
1019 IWL_EMPTYING_HW_QUEUE_ADDBA) {
1020 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1021 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1022 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1023 return 0;
1024 }
1025
1026 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
1027 IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
1028
1029 tid_data = &priv->stations[sta_id].tid[tid];
1030 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
1031 txq_id = tid_data->agg.txq_id;
1032 write_ptr = priv->txq[txq_id].q.write_ptr;
1033 read_ptr = priv->txq[txq_id].q.read_ptr;
1034
1035 /* The queue is not empty */
1036 if (write_ptr != read_ptr) {
1037 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
1038 priv->stations[sta_id].tid[tid].agg.state =
1039 IWL_EMPTYING_HW_QUEUE_DELBA;
1040 return 0;
1041 }
1042
1043 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1044 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1045
1046 spin_lock_irqsave(&priv->lock, flags);
1047 /*
1048 * the only reason this call can fail is queue number out of range,
1049 * which can happen if uCode is reloaded and all the station
1050 * information are lost. if it is outside the range, there is no need
1051 * to deactivate the uCode queue, just return "success" to allow
1052 * mac80211 to clean up it own data.
1053 */
1054 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
1055 tx_fifo_id);
1056 spin_unlock_irqrestore(&priv->lock, flags);
1057
1058 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1059
1060 return 0;
1061}
1062
1063int iwlagn_txq_check_empty(struct iwl_priv *priv,
1064 int sta_id, u8 tid, int txq_id)
1065{
1066 struct iwl_queue *q = &priv->txq[txq_id].q;
1067 u8 *addr = priv->stations[sta_id].sta.sta.addr;
1068 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
1069
1070 switch (priv->stations[sta_id].tid[tid].agg.state) {
1071 case IWL_EMPTYING_HW_QUEUE_DELBA:
1072 /* We are reclaiming the last packet of the */
1073 /* aggregated HW queue */
1074 if ((txq_id == tid_data->agg.txq_id) &&
1075 (q->read_ptr == q->write_ptr)) {
1076 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1077 int tx_fifo = get_fifo_from_tid(tid);
1078 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
1079 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
1080 ssn, tx_fifo);
1081 tid_data->agg.state = IWL_AGG_OFF;
1082 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid);
1083 }
1084 break;
1085 case IWL_EMPTYING_HW_QUEUE_ADDBA:
1086 /* We are reclaiming the last packet of the queue */
1087 if (tid_data->tfds_in_queue == 0) {
1088 IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
1089 tid_data->agg.state = IWL_AGG_ON;
1090 ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid);
1091 }
1092 break;
1093 }
1094 return 0;
1095}
1096
1097static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
1098{
1099 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1100 struct ieee80211_sta *sta;
1101 struct iwl_station_priv *sta_priv;
1102
1103 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
1104 if (sta) {
1105 sta_priv = (void *)sta->drv_priv;
1106 /* avoid atomic ops if this isn't a client */
1107 if (sta_priv->client &&
1108 atomic_dec_return(&sta_priv->pending_frames) == 0)
1109 ieee80211_sta_block_awake(priv->hw, sta, false);
1110 }
1111
1112 ieee80211_tx_status_irqsafe(priv->hw, skb);
1113}
1114
1115int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1116{
1117 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1118 struct iwl_queue *q = &txq->q;
1119 struct iwl_tx_info *tx_info;
1120 int nfreed = 0;
1121 struct ieee80211_hdr *hdr;
1122
1123 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
1124 IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
1125 "is out of range [0-%d] %d %d.\n", txq_id,
1126 index, q->n_bd, q->write_ptr, q->read_ptr);
1127 return 0;
1128 }
1129
1130 for (index = iwl_queue_inc_wrap(index, q->n_bd);
1131 q->read_ptr != index;
1132 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1133
1134 tx_info = &txq->txb[txq->q.read_ptr];
1135 iwlagn_tx_status(priv, tx_info->skb[0]);
1136
1137 hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data;
1138 if (hdr && ieee80211_is_data_qos(hdr->frame_control))
1139 nfreed++;
1140 tx_info->skb[0] = NULL;
1141
1142 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
1143 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
1144
1145 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
1146 }
1147 return nfreed;
1148}
1149
1150/**
1151 * iwlagn_tx_status_reply_compressed_ba - Update tx status from block-ack
1152 *
1153 * Go through block-ack's bitmap of ACK'd frames, update driver's record of
1154 * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
1155 */
1156static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1157 struct iwl_ht_agg *agg,
1158 struct iwl_compressed_ba_resp *ba_resp)
1159
1160{
1161 int i, sh, ack;
1162 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1163 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1164 u64 bitmap;
1165 int successes = 0;
1166 struct ieee80211_tx_info *info;
1167
1168 if (unlikely(!agg->wait_for_ba)) {
1169 IWL_ERR(priv, "Received BA when not expected\n");
1170 return -EINVAL;
1171 }
1172
1173 /* Mark that the expected block-ack response arrived */
1174 agg->wait_for_ba = 0;
1175 IWL_DEBUG_TX_REPLY(priv, "BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
1176
1177 /* Calculate shift to align block-ack bits with our Tx window bits */
1178 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
1179 if (sh < 0) /* tbw something is wrong with indices */
1180 sh += 0x100;
1181
1182 /* don't use 64-bit values for now */
1183 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1184
1185 if (agg->frame_count > (64 - sh)) {
1186 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
1187 return -1;
1188 }
1189
1190 /* check for success or failure according to the
1191 * transmitted bitmap and block-ack bitmap */
1192 bitmap &= agg->bitmap;
1193
1194 /* For each frame attempted in aggregation,
1195 * update driver's record of tx frame's status. */
1196 for (i = 0; i < agg->frame_count ; i++) {
1197 ack = bitmap & (1ULL << i);
1198 successes += !!ack;
1199 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
1200 ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
1201 agg->start_idx + i);
1202 }
1203
1204 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
1205 memset(&info->status, 0, sizeof(info->status));
1206 info->flags |= IEEE80211_TX_STAT_ACK;
1207 info->flags |= IEEE80211_TX_STAT_AMPDU;
1208 info->status.ampdu_ack_map = successes;
1209 info->status.ampdu_ack_len = agg->frame_count;
1210 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1211
1212 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
1213
1214 return 0;
1215}
1216
1217/**
1218 * translate ucode response to mac80211 tx status control values
1219 */
1220void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
1221 struct ieee80211_tx_info *info)
1222{
1223 struct ieee80211_tx_rate *r = &info->control.rates[0];
1224
1225 info->antenna_sel_tx =
1226 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
1227 if (rate_n_flags & RATE_MCS_HT_MSK)
1228 r->flags |= IEEE80211_TX_RC_MCS;
1229 if (rate_n_flags & RATE_MCS_GF_MSK)
1230 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
1231 if (rate_n_flags & RATE_MCS_HT40_MSK)
1232 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
1233 if (rate_n_flags & RATE_MCS_DUP_MSK)
1234 r->flags |= IEEE80211_TX_RC_DUP_DATA;
1235 if (rate_n_flags & RATE_MCS_SGI_MSK)
1236 r->flags |= IEEE80211_TX_RC_SHORT_GI;
1237 r->idx = iwlagn_hwrate_to_mac80211_idx(rate_n_flags, info->band);
1238}
1239
1240/**
1241 * iwlagn_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
1242 *
1243 * Handles block-acknowledge notification from device, which reports success
1244 * of frames sent via aggregation.
1245 */
1246void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1247 struct iwl_rx_mem_buffer *rxb)
1248{
1249 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1250 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1251 struct iwl_tx_queue *txq = NULL;
1252 struct iwl_ht_agg *agg;
1253 int index;
1254 int sta_id;
1255 int tid;
1256
1257 /* "flow" corresponds to Tx queue */
1258 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1259
1260 /* "ssn" is start of block-ack Tx window, corresponds to index
1261 * (in Tx queue's circular buffer) of first TFD/frame in window */
1262 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
1263
1264 if (scd_flow >= priv->hw_params.max_txq_num) {
1265 IWL_ERR(priv,
1266 "BUG_ON scd_flow is bigger than number of queues\n");
1267 return;
1268 }
1269
1270 txq = &priv->txq[scd_flow];
1271 sta_id = ba_resp->sta_id;
1272 tid = ba_resp->tid;
1273 agg = &priv->stations[sta_id].tid[tid].agg;
1274
1275 /* Find index just before block-ack window */
1276 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1277
1278 /* TODO: Need to get this copy more safely - now good for debug */
1279
1280 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
1281 "sta_id = %d\n",
1282 agg->wait_for_ba,
1283 (u8 *) &ba_resp->sta_addr_lo32,
1284 ba_resp->sta_id);
1285 IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
1286 "%d, scd_ssn = %d\n",
1287 ba_resp->tid,
1288 ba_resp->seq_ctl,
1289 (unsigned long long)le64_to_cpu(ba_resp->bitmap),
1290 ba_resp->scd_flow,
1291 ba_resp->scd_ssn);
1292 IWL_DEBUG_TX_REPLY(priv, "DAT start_idx = %d, bitmap = 0x%llx\n",
1293 agg->start_idx,
1294 (unsigned long long)agg->bitmap);
1295
1296 /* Update driver's record of ACK vs. not for each frame in window */
1297 iwlagn_tx_status_reply_compressed_ba(priv, agg, ba_resp);
1298
1299 /* Release all TFDs before the SSN, i.e. all TFDs in front of
1300 * block-ack window (we assume that they've been successfully
1301 * transmitted ... if not, it's too late anyway). */
1302 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1303 /* calculate mac80211 ampdu sw queue to wake */
1304 int freed = iwlagn_tx_queue_reclaim(priv, scd_flow, index);
1305 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1306
1307 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1308 priv->mac80211_registered &&
1309 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1310 iwl_wake_queue(priv, txq->swq_id);
1311
1312 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
1313 }
1314}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
new file mode 100644
index 000000000000..52ae157968b2
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -0,0 +1,416 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-io.h"
38#include "iwl-helpers.h"
39#include "iwl-agn-hw.h"
40#include "iwl-agn.h"
41
42static const s8 iwlagn_default_queue_to_tx_fifo[] = {
43 IWL_TX_FIFO_VO,
44 IWL_TX_FIFO_VI,
45 IWL_TX_FIFO_BE,
46 IWL_TX_FIFO_BK,
47 IWLAGN_CMD_FIFO_NUM,
48 IWL_TX_FIFO_UNUSED,
49 IWL_TX_FIFO_UNUSED,
50 IWL_TX_FIFO_UNUSED,
51 IWL_TX_FIFO_UNUSED,
52 IWL_TX_FIFO_UNUSED,
53};
54
55/*
56 * ucode
57 */
58static int iwlagn_load_section(struct iwl_priv *priv, const char *name,
59 struct fw_desc *image, u32 dst_addr)
60{
61 dma_addr_t phy_addr = image->p_addr;
62 u32 byte_cnt = image->len;
63 int ret;
64
65 priv->ucode_write_complete = 0;
66
67 iwl_write_direct32(priv,
68 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
69 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
70
71 iwl_write_direct32(priv,
72 FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
73
74 iwl_write_direct32(priv,
75 FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
76 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
77
78 iwl_write_direct32(priv,
79 FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
80 (iwl_get_dma_hi_addr(phy_addr)
81 << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
82
83 iwl_write_direct32(priv,
84 FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
85 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
86 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
87 FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
88
89 iwl_write_direct32(priv,
90 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
91 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
92 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
93 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
94
95 IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
96 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
97 priv->ucode_write_complete, 5 * HZ);
98 if (ret == -ERESTARTSYS) {
99 IWL_ERR(priv, "Could not load the %s uCode section due "
100 "to interrupt\n", name);
101 return ret;
102 }
103 if (!ret) {
104 IWL_ERR(priv, "Could not load the %s uCode section\n",
105 name);
106 return -ETIMEDOUT;
107 }
108
109 return 0;
110}
111
112static int iwlagn_load_given_ucode(struct iwl_priv *priv,
113 struct fw_desc *inst_image,
114 struct fw_desc *data_image)
115{
116 int ret = 0;
117
118 ret = iwlagn_load_section(priv, "INST", inst_image,
119 IWLAGN_RTC_INST_LOWER_BOUND);
120 if (ret)
121 return ret;
122
123 return iwlagn_load_section(priv, "DATA", data_image,
124 IWLAGN_RTC_DATA_LOWER_BOUND);
125}
126
127int iwlagn_load_ucode(struct iwl_priv *priv)
128{
129 int ret = 0;
130
131 /* check whether init ucode should be loaded, or rather runtime ucode */
132 if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
133 IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
134 ret = iwlagn_load_given_ucode(priv,
135 &priv->ucode_init, &priv->ucode_init_data);
136 if (!ret) {
137 IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
138 priv->ucode_type = UCODE_INIT;
139 }
140 } else {
141 IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
142 "Loading runtime ucode...\n");
143 ret = iwlagn_load_given_ucode(priv,
144 &priv->ucode_code, &priv->ucode_data);
145 if (!ret) {
146 IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
147 priv->ucode_type = UCODE_RT;
148 }
149 }
150
151 return ret;
152}
153
154#define IWL_UCODE_GET(item) \
155static u32 iwlagn_ucode_get_##item(const struct iwl_ucode_header *ucode,\
156 u32 api_ver) \
157{ \
158 if (api_ver <= 2) \
159 return le32_to_cpu(ucode->u.v1.item); \
160 return le32_to_cpu(ucode->u.v2.item); \
161}
162
163static u32 iwlagn_ucode_get_header_size(u32 api_ver)
164{
165 if (api_ver <= 2)
166 return UCODE_HEADER_SIZE(1);
167 return UCODE_HEADER_SIZE(2);
168}
169
170static u32 iwlagn_ucode_get_build(const struct iwl_ucode_header *ucode,
171 u32 api_ver)
172{
173 if (api_ver <= 2)
174 return 0;
175 return le32_to_cpu(ucode->u.v2.build);
176}
177
178static u8 *iwlagn_ucode_get_data(const struct iwl_ucode_header *ucode,
179 u32 api_ver)
180{
181 if (api_ver <= 2)
182 return (u8 *) ucode->u.v1.data;
183 return (u8 *) ucode->u.v2.data;
184}
185
186IWL_UCODE_GET(inst_size);
187IWL_UCODE_GET(data_size);
188IWL_UCODE_GET(init_size);
189IWL_UCODE_GET(init_data_size);
190IWL_UCODE_GET(boot_size);
191
192struct iwl_ucode_ops iwlagn_ucode = {
193 .get_header_size = iwlagn_ucode_get_header_size,
194 .get_build = iwlagn_ucode_get_build,
195 .get_inst_size = iwlagn_ucode_get_inst_size,
196 .get_data_size = iwlagn_ucode_get_data_size,
197 .get_init_size = iwlagn_ucode_get_init_size,
198 .get_init_data_size = iwlagn_ucode_get_init_data_size,
199 .get_boot_size = iwlagn_ucode_get_boot_size,
200 .get_data = iwlagn_ucode_get_data,
201};
202
203/*
204 * Calibration
205 */
206static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
207{
208 struct iwl_calib_xtal_freq_cmd cmd;
209 __le16 *xtal_calib =
210 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
211
212 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
213 cmd.hdr.first_group = 0;
214 cmd.hdr.groups_num = 1;
215 cmd.hdr.data_valid = 1;
216 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
217 cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
218 return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
219 (u8 *)&cmd, sizeof(cmd));
220}
221
222static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
223{
224 struct iwl_calib_cfg_cmd calib_cfg_cmd;
225 struct iwl_host_cmd cmd = {
226 .id = CALIBRATION_CFG_CMD,
227 .len = sizeof(struct iwl_calib_cfg_cmd),
228 .data = &calib_cfg_cmd,
229 };
230
231 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
232 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
233 calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL;
234 calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL;
235 calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL;
236
237 return iwl_send_cmd(priv, &cmd);
238}
239
240void iwlagn_rx_calib_result(struct iwl_priv *priv,
241 struct iwl_rx_mem_buffer *rxb)
242{
243 struct iwl_rx_packet *pkt = rxb_addr(rxb);
244 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
245 int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
246 int index;
247
248 /* reduce the size of the length field itself */
249 len -= 4;
250
251 /* Define the order in which the results will be sent to the runtime
252 * uCode. iwl_send_calib_results sends them in a row according to
253 * their index. We sort them here
254 */
255 switch (hdr->op_code) {
256 case IWL_PHY_CALIBRATE_DC_CMD:
257 index = IWL_CALIB_DC;
258 break;
259 case IWL_PHY_CALIBRATE_LO_CMD:
260 index = IWL_CALIB_LO;
261 break;
262 case IWL_PHY_CALIBRATE_TX_IQ_CMD:
263 index = IWL_CALIB_TX_IQ;
264 break;
265 case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD:
266 index = IWL_CALIB_TX_IQ_PERD;
267 break;
268 case IWL_PHY_CALIBRATE_BASE_BAND_CMD:
269 index = IWL_CALIB_BASE_BAND;
270 break;
271 default:
272 IWL_ERR(priv, "Unknown calibration notification %d\n",
273 hdr->op_code);
274 return;
275 }
276 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
277}
278
279void iwlagn_rx_calib_complete(struct iwl_priv *priv,
280 struct iwl_rx_mem_buffer *rxb)
281{
282 IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
283 queue_work(priv->workqueue, &priv->restart);
284}
285
286void iwlagn_init_alive_start(struct iwl_priv *priv)
287{
288 int ret = 0;
289
290 /* Check alive response for "valid" sign from uCode */
291 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
292 /* We had an error bringing up the hardware, so take it
293 * all the way back down so we can try again */
294 IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
295 goto restart;
296 }
297
298 /* initialize uCode was loaded... verify inst image.
299 * This is a paranoid check, because we would not have gotten the
300 * "initialize" alive if code weren't properly loaded. */
301 if (iwl_verify_ucode(priv)) {
302 /* Runtime instruction load was bad;
303 * take it all the way back down so we can try again */
304 IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
305 goto restart;
306 }
307
308 ret = priv->cfg->ops->lib->alive_notify(priv);
309 if (ret) {
310 IWL_WARN(priv,
311 "Could not complete ALIVE transition: %d\n", ret);
312 goto restart;
313 }
314
315 iwlagn_send_calib_cfg(priv);
316 return;
317
318restart:
319 /* real restart (first load init_ucode) */
320 queue_work(priv->workqueue, &priv->restart);
321}
322
323int iwlagn_alive_notify(struct iwl_priv *priv)
324{
325 u32 a;
326 unsigned long flags;
327 int i, chan;
328 u32 reg_val;
329
330 spin_lock_irqsave(&priv->lock, flags);
331
332 priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR);
333 a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET;
334 for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET;
335 a += 4)
336 iwl_write_targ_mem(priv, a, 0);
337 for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
338 a += 4)
339 iwl_write_targ_mem(priv, a, 0);
340 for (; a < priv->scd_base_addr +
341 IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
342 iwl_write_targ_mem(priv, a, 0);
343
344 iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
345 priv->scd_bc_tbls.dma >> 10);
346
347 /* Enable DMA channel */
348 for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++)
349 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
350 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
351 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
352
353 /* Update FH chicken bits */
354 reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
355 iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
356 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
357
358 iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
359 IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
360 iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
361
362 /* initiate the queues */
363 for (i = 0; i < priv->hw_params.max_txq_num; i++) {
364 iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(i), 0);
365 iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
366 iwl_write_targ_mem(priv, priv->scd_base_addr +
367 IWL50_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
368 iwl_write_targ_mem(priv, priv->scd_base_addr +
369 IWL50_SCD_CONTEXT_QUEUE_OFFSET(i) +
370 sizeof(u32),
371 ((SCD_WIN_SIZE <<
372 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
373 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
374 ((SCD_FRAME_LIMIT <<
375 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
376 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
377 }
378
379 iwl_write_prph(priv, IWL50_SCD_INTERRUPT_MASK,
380 IWL_MASK(0, priv->hw_params.max_txq_num));
381
382 /* Activate all Tx DMA/FIFO channels */
383 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
384
385 iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
386
387 /* make sure all queue are not stopped */
388 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
389 for (i = 0; i < 4; i++)
390 atomic_set(&priv->queue_stop_count[i], 0);
391
392 /* reset to 0 to enable all the queue first */
393 priv->txq_ctx_active_msk = 0;
394 /* map qos queues to fifos one-to-one */
395 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10);
396
397 for (i = 0; i < ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); i++) {
398 int ac = iwlagn_default_queue_to_tx_fifo[i];
399
400 iwl_txq_ctx_activate(priv, i);
401
402 if (ac == IWL_TX_FIFO_UNUSED)
403 continue;
404
405 iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
406 }
407
408 spin_unlock_irqrestore(&priv->lock, flags);
409
410 iwl_send_wimax_coex(priv);
411
412 iwlagn_set_Xtal_calib(priv);
413 iwl_send_calib_results(priv);
414
415 return 0;
416}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index e4c2e1e448ad..4f0cb803f732 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -54,6 +54,7 @@
54#include "iwl-helpers.h" 54#include "iwl-helpers.h"
55#include "iwl-sta.h" 55#include "iwl-sta.h"
56#include "iwl-calib.h" 56#include "iwl-calib.h"
57#include "iwl-agn.h"
57 58
58 59
59/****************************************************************************** 60/******************************************************************************
@@ -82,13 +83,6 @@ MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
82MODULE_LICENSE("GPL"); 83MODULE_LICENSE("GPL");
83MODULE_ALIAS("iwl4965"); 84MODULE_ALIAS("iwl4965");
84 85
85/*************** STATION TABLE MANAGEMENT ****
86 * mac80211 should be examined to determine if sta_info is duplicating
87 * the functionality provided here
88 */
89
90/**************************************************************/
91
92/** 86/**
93 * iwl_commit_rxon - commit staging_rxon to hardware 87 * iwl_commit_rxon - commit staging_rxon to hardware
94 * 88 *
@@ -143,9 +137,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)
143 return 0; 137 return 0;
144 } 138 }
145 139
146 /* station table will be cleared */
147 priv->assoc_station_added = 0;
148
149 /* If we are currently associated and the new config requires 140 /* If we are currently associated and the new config requires
150 * an RXON_ASSOC and the new config wants the associated mask enabled, 141 * an RXON_ASSOC and the new config wants the associated mask enabled,
151 * we must clear the associated from the active configuration 142 * we must clear the associated from the active configuration
@@ -165,6 +156,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
165 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); 156 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
166 return ret; 157 return ret;
167 } 158 }
159 iwl_clear_ucode_stations(priv, false);
160 iwl_restore_stations(priv);
168 } 161 }
169 162
170 IWL_DEBUG_INFO(priv, "Sending RXON\n" 163 IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -178,9 +171,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
178 iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); 171 iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
179 172
180 /* Apply the new configuration 173 /* Apply the new configuration
181 * RXON unassoc clears the station table in uCode, send it before 174 * RXON unassoc clears the station table in uCode so restoration of
182 * we add the bcast station. If assoc bit is set, we will send RXON 175 * stations is needed after it (the RXON command) completes
183 * after having added the bcast and bssid station.
184 */ 176 */
185 if (!new_assoc) { 177 if (!new_assoc) {
186 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 178 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -189,35 +181,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
189 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); 181 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
190 return ret; 182 return ret;
191 } 183 }
184 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
192 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 185 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
186 iwl_clear_ucode_stations(priv, false);
187 iwl_restore_stations(priv);
193 } 188 }
194 189
195 iwl_clear_stations_table(priv);
196
197 priv->start_calib = 0; 190 priv->start_calib = 0;
198
199 /* Add the broadcast address so we can send broadcast frames */
200 priv->cfg->ops->lib->add_bcast_station(priv);
201
202
203 /* If we have set the ASSOC_MSK and we are in BSS mode then
204 * add the IWL_AP_ID to the station rate table */
205 if (new_assoc) { 191 if (new_assoc) {
206 if (priv->iw_mode == NL80211_IFTYPE_STATION) {
207 ret = iwl_rxon_add_station(priv,
208 priv->active_rxon.bssid_addr, 1);
209 if (ret == IWL_INVALID_STATION) {
210 IWL_ERR(priv,
211 "Error adding AP address for TX.\n");
212 return -EIO;
213 }
214 priv->assoc_station_added = 1;
215 if (priv->default_wep_key &&
216 iwl_send_static_wepkey_cmd(priv, 0))
217 IWL_ERR(priv,
218 "Could not send WEP static key.\n");
219 }
220
221 /* 192 /*
222 * allow CTS-to-self if possible for new association. 193 * allow CTS-to-self if possible for new association.
223 * this is relevant only for 5000 series and up, 194 * this is relevant only for 5000 series and up,
@@ -906,10 +877,10 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
906 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = 877 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
907 iwl_rx_missed_beacon_notif; 878 iwl_rx_missed_beacon_notif;
908 /* Rx handlers */ 879 /* Rx handlers */
909 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; 880 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy;
910 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; 881 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx;
911 /* block ack */ 882 /* block ack */
912 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl_rx_reply_compressed_ba; 883 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba;
913 /* Set up hardware specific Rx handlers */ 884 /* Set up hardware specific Rx handlers */
914 priv->cfg->ops->lib->rx_handler_setup(priv); 885 priv->cfg->ops->lib->rx_handler_setup(priv);
915} 886}
@@ -1037,7 +1008,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
1037 count++; 1008 count++;
1038 if (count >= 8) { 1009 if (count >= 8) {
1039 rxq->read = i; 1010 rxq->read = i;
1040 iwl_rx_replenish_now(priv); 1011 iwlagn_rx_replenish_now(priv);
1041 count = 0; 1012 count = 0;
1042 } 1013 }
1043 } 1014 }
@@ -1046,9 +1017,9 @@ void iwl_rx_handle(struct iwl_priv *priv)
1046 /* Backtrack one entry */ 1017 /* Backtrack one entry */
1047 rxq->read = i; 1018 rxq->read = i;
1048 if (fill_rx) 1019 if (fill_rx)
1049 iwl_rx_replenish_now(priv); 1020 iwlagn_rx_replenish_now(priv);
1050 else 1021 else
1051 iwl_rx_queue_restock(priv); 1022 iwlagn_rx_queue_restock(priv);
1052} 1023}
1053 1024
1054/* call this function to flush any scheduled tasklet */ 1025/* call this function to flush any scheduled tasklet */
@@ -1266,9 +1237,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1266 * hardware bugs here by ACKing all the possible interrupts so that 1237 * hardware bugs here by ACKing all the possible interrupts so that
1267 * interrupt coalescing can still be achieved. 1238 * interrupt coalescing can still be achieved.
1268 */ 1239 */
1269 iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask); 1240 iwl_write32(priv, CSR_INT, priv->_agn.inta | ~priv->inta_mask);
1270 1241
1271 inta = priv->inta; 1242 inta = priv->_agn.inta;
1272 1243
1273#ifdef CONFIG_IWLWIFI_DEBUG 1244#ifdef CONFIG_IWLWIFI_DEBUG
1274 if (iwl_get_debug_level(priv) & IWL_DL_ISR) { 1245 if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
@@ -1281,8 +1252,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1281 1252
1282 spin_unlock_irqrestore(&priv->lock, flags); 1253 spin_unlock_irqrestore(&priv->lock, flags);
1283 1254
1284 /* saved interrupt in inta variable now we can reset priv->inta */ 1255 /* saved interrupt in inta variable now we can reset priv->_agn.inta */
1285 priv->inta = 0; 1256 priv->_agn.inta = 0;
1286 1257
1287 /* Now service all interrupt bits discovered above. */ 1258 /* Now service all interrupt bits discovered above. */
1288 if (inta & CSR_INT_BIT_HW_ERR) { 1259 if (inta & CSR_INT_BIT_HW_ERR) {
@@ -1447,6 +1418,60 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1447 iwl_enable_interrupts(priv); 1418 iwl_enable_interrupts(priv);
1448} 1419}
1449 1420
1421/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
1422#define ACK_CNT_RATIO (50)
1423#define BA_TIMEOUT_CNT (5)
1424#define BA_TIMEOUT_MAX (16)
1425
1426/**
1427 * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
1428 *
1429 * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding
1430 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
1431 * operation state.
1432 */
1433bool iwl_good_ack_health(struct iwl_priv *priv,
1434 struct iwl_rx_packet *pkt)
1435{
1436 bool rc = true;
1437 int actual_ack_cnt_delta, expected_ack_cnt_delta;
1438 int ba_timeout_delta;
1439
1440 actual_ack_cnt_delta =
1441 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
1442 le32_to_cpu(priv->statistics.tx.actual_ack_cnt);
1443 expected_ack_cnt_delta =
1444 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) -
1445 le32_to_cpu(priv->statistics.tx.expected_ack_cnt);
1446 ba_timeout_delta =
1447 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) -
1448 le32_to_cpu(priv->statistics.tx.agg.ba_timeout);
1449 if ((priv->_agn.agg_tids_count > 0) &&
1450 (expected_ack_cnt_delta > 0) &&
1451 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta)
1452 < ACK_CNT_RATIO) &&
1453 (ba_timeout_delta > BA_TIMEOUT_CNT)) {
1454 IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d,"
1455 " expected_ack_cnt = %d\n",
1456 actual_ack_cnt_delta, expected_ack_cnt_delta);
1457
1458#ifdef CONFIG_IWLWIFI_DEBUG
1459 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
1460 priv->delta_statistics.tx.rx_detected_cnt);
1461 IWL_DEBUG_RADIO(priv,
1462 "ack_or_ba_timeout_collision delta = %d\n",
1463 priv->delta_statistics.tx.
1464 ack_or_ba_timeout_collision);
1465#endif
1466 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
1467 ba_timeout_delta);
1468 if (!actual_ack_cnt_delta &&
1469 (ba_timeout_delta >= BA_TIMEOUT_MAX))
1470 rc = false;
1471 }
1472 return rc;
1473}
1474
1450 1475
1451/****************************************************************************** 1476/******************************************************************************
1452 * 1477 *
@@ -2094,7 +2119,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
2094 goto restart; 2119 goto restart;
2095 } 2120 }
2096 2121
2097 iwl_clear_stations_table(priv);
2098 ret = priv->cfg->ops->lib->alive_notify(priv); 2122 ret = priv->cfg->ops->lib->alive_notify(priv);
2099 if (ret) { 2123 if (ret) {
2100 IWL_WARN(priv, 2124 IWL_WARN(priv,
@@ -2105,13 +2129,19 @@ static void iwl_alive_start(struct iwl_priv *priv)
2105 /* After the ALIVE response, we can send host commands to the uCode */ 2129 /* After the ALIVE response, we can send host commands to the uCode */
2106 set_bit(STATUS_ALIVE, &priv->status); 2130 set_bit(STATUS_ALIVE, &priv->status);
2107 2131
2132 if (priv->cfg->ops->lib->recover_from_tx_stall) {
2133 /* Enable timer to monitor the driver queues */
2134 mod_timer(&priv->monitor_recover,
2135 jiffies +
2136 msecs_to_jiffies(priv->cfg->monitor_recover_period));
2137 }
2138
2108 if (iwl_is_rfkill(priv)) 2139 if (iwl_is_rfkill(priv))
2109 return; 2140 return;
2110 2141
2111 ieee80211_wake_queues(priv->hw); 2142 ieee80211_wake_queues(priv->hw);
2112 2143
2113 priv->active_rate = priv->rates_mask; 2144 priv->active_rate = IWL_RATES_MASK;
2114 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
2115 2145
2116 /* Configure Tx antenna selection based on H/W config */ 2146 /* Configure Tx antenna selection based on H/W config */
2117 if (priv->cfg->ops->hcmd->set_tx_ant) 2147 if (priv->cfg->ops->hcmd->set_tx_ant)
@@ -2151,18 +2181,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
2151 wake_up_interruptible(&priv->wait_command_queue); 2181 wake_up_interruptible(&priv->wait_command_queue);
2152 2182
2153 iwl_power_update_mode(priv, true); 2183 iwl_power_update_mode(priv, true);
2184 IWL_DEBUG_INFO(priv, "Updated power mode\n");
2154 2185
2155 /* reassociate for ADHOC mode */
2156 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
2157 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
2158 priv->vif);
2159 if (beacon)
2160 iwl_mac_beacon_update(priv->hw, beacon);
2161 }
2162
2163
2164 if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
2165 iwl_set_mode(priv, priv->iw_mode);
2166 2186
2167 return; 2187 return;
2168 2188
@@ -2182,7 +2202,7 @@ static void __iwl_down(struct iwl_priv *priv)
2182 if (!exit_pending) 2202 if (!exit_pending)
2183 set_bit(STATUS_EXIT_PENDING, &priv->status); 2203 set_bit(STATUS_EXIT_PENDING, &priv->status);
2184 2204
2185 iwl_clear_stations_table(priv); 2205 iwl_clear_ucode_stations(priv, true);
2186 2206
2187 /* Unblock any waiting calls */ 2207 /* Unblock any waiting calls */
2188 wake_up_interruptible_all(&priv->wait_command_queue); 2208 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2230,8 +2250,8 @@ static void __iwl_down(struct iwl_priv *priv)
2230 /* device going down, Stop using ICT table */ 2250 /* device going down, Stop using ICT table */
2231 iwl_disable_ict(priv); 2251 iwl_disable_ict(priv);
2232 2252
2233 iwl_txq_ctx_stop(priv); 2253 iwlagn_txq_ctx_stop(priv);
2234 iwl_rxq_stop(priv); 2254 iwlagn_rxq_stop(priv);
2235 2255
2236 /* Power-down device's busmaster DMA clocks */ 2256 /* Power-down device's busmaster DMA clocks */
2237 iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); 2257 iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
@@ -2291,7 +2311,7 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
2291{ 2311{
2292 int ret = 0; 2312 int ret = 0;
2293 2313
2294 IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter \n"); 2314 IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n");
2295 2315
2296 ret = iwl_set_hw_ready(priv); 2316 ret = iwl_set_hw_ready(priv);
2297 if (priv->hw_ready) 2317 if (priv->hw_ready)
@@ -2352,7 +2372,7 @@ static int __iwl_up(struct iwl_priv *priv)
2352 2372
2353 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 2373 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2354 2374
2355 ret = iwl_hw_nic_init(priv); 2375 ret = iwlagn_hw_nic_init(priv);
2356 if (ret) { 2376 if (ret) {
2357 IWL_ERR(priv, "Unable to init nic\n"); 2377 IWL_ERR(priv, "Unable to init nic\n");
2358 return ret; 2378 return ret;
@@ -2379,8 +2399,6 @@ static int __iwl_up(struct iwl_priv *priv)
2379 2399
2380 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2400 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2381 2401
2382 iwl_clear_stations_table(priv);
2383
2384 /* load bootstrap state machine, 2402 /* load bootstrap state machine,
2385 * load bootstrap program into processor's memory, 2403 * load bootstrap program into processor's memory,
2386 * prepare to load the "initialize" uCode */ 2404 * prepare to load the "initialize" uCode */
@@ -2504,7 +2522,7 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
2504 return; 2522 return;
2505 2523
2506 mutex_lock(&priv->mutex); 2524 mutex_lock(&priv->mutex);
2507 iwl_rx_replenish(priv); 2525 iwlagn_rx_replenish(priv);
2508 mutex_unlock(&priv->mutex); 2526 mutex_unlock(&priv->mutex);
2509} 2527}
2510 2528
@@ -2514,17 +2532,12 @@ void iwl_post_associate(struct iwl_priv *priv)
2514{ 2532{
2515 struct ieee80211_conf *conf = NULL; 2533 struct ieee80211_conf *conf = NULL;
2516 int ret = 0; 2534 int ret = 0;
2517 unsigned long flags;
2518 2535
2519 if (priv->iw_mode == NL80211_IFTYPE_AP) { 2536 if (priv->iw_mode == NL80211_IFTYPE_AP) {
2520 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 2537 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
2521 return; 2538 return;
2522 } 2539 }
2523 2540
2524 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2525 priv->assoc_id, priv->active_rxon.bssid_addr);
2526
2527
2528 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2541 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2529 return; 2542 return;
2530 2543
@@ -2576,6 +2589,9 @@ void iwl_post_associate(struct iwl_priv *priv)
2576 2589
2577 iwlcore_commit_rxon(priv); 2590 iwlcore_commit_rxon(priv);
2578 2591
2592 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2593 priv->assoc_id, priv->active_rxon.bssid_addr);
2594
2579 switch (priv->iw_mode) { 2595 switch (priv->iw_mode) {
2580 case NL80211_IFTYPE_STATION: 2596 case NL80211_IFTYPE_STATION:
2581 break; 2597 break;
@@ -2585,7 +2601,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2585 /* assume default assoc id */ 2601 /* assume default assoc id */
2586 priv->assoc_id = 1; 2602 priv->assoc_id = 1;
2587 2603
2588 iwl_rxon_add_station(priv, priv->bssid, 0); 2604 iwl_add_local_station(priv, priv->bssid, true);
2589 iwl_send_beacon_cmd(priv); 2605 iwl_send_beacon_cmd(priv);
2590 2606
2591 break; 2607 break;
@@ -2596,13 +2612,6 @@ void iwl_post_associate(struct iwl_priv *priv)
2596 break; 2612 break;
2597 } 2613 }
2598 2614
2599 if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
2600 priv->assoc_station_added = 1;
2601
2602 spin_lock_irqsave(&priv->lock, flags);
2603 iwl_activate_qos(priv, 0);
2604 spin_unlock_irqrestore(&priv->lock, flags);
2605
2606 /* the chain noise calibration will enabled PM upon completion 2615 /* the chain noise calibration will enabled PM upon completion
2607 * If chain noise has already been run, then we need to enable 2616 * If chain noise has already been run, then we need to enable
2608 * power management here */ 2617 * power management here */
@@ -2769,7 +2778,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2769 IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, 2778 IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
2770 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); 2779 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
2771 2780
2772 if (iwl_tx_skb(priv, skb)) 2781 if (iwlagn_tx_skb(priv, skb))
2773 dev_kfree_skb_any(skb); 2782 dev_kfree_skb_any(skb);
2774 2783
2775 IWL_DEBUG_MACDUMP(priv, "leave\n"); 2784 IWL_DEBUG_MACDUMP(priv, "leave\n");
@@ -2779,7 +2788,6 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2779void iwl_config_ap(struct iwl_priv *priv) 2788void iwl_config_ap(struct iwl_priv *priv)
2780{ 2789{
2781 int ret = 0; 2790 int ret = 0;
2782 unsigned long flags;
2783 2791
2784 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2792 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2785 return; 2793 return;
@@ -2831,10 +2839,6 @@ void iwl_config_ap(struct iwl_priv *priv)
2831 /* restore RXON assoc */ 2839 /* restore RXON assoc */
2832 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 2840 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
2833 iwlcore_commit_rxon(priv); 2841 iwlcore_commit_rxon(priv);
2834 iwl_reset_qos(priv);
2835 spin_lock_irqsave(&priv->lock, flags);
2836 iwl_activate_qos(priv, 1);
2837 spin_unlock_irqrestore(&priv->lock, flags);
2838 iwl_add_bcast_station(priv); 2842 iwl_add_bcast_station(priv);
2839 } 2843 }
2840 iwl_send_beacon_cmd(priv); 2844 iwl_send_beacon_cmd(priv);
@@ -2889,7 +2893,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2889 2893
2890 mutex_lock(&priv->mutex); 2894 mutex_lock(&priv->mutex);
2891 iwl_scan_cancel_timeout(priv, 100); 2895 iwl_scan_cancel_timeout(priv, 100);
2892 mutex_unlock(&priv->mutex);
2893 2896
2894 /* If we are getting WEP group key and we didn't receive any key mapping 2897 /* If we are getting WEP group key and we didn't receive any key mapping
2895 * so far, we are in legacy wep mode (group key only), otherwise we are 2898 * so far, we are in legacy wep mode (group key only), otherwise we are
@@ -2925,6 +2928,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2925 ret = -EINVAL; 2928 ret = -EINVAL;
2926 } 2929 }
2927 2930
2931 mutex_unlock(&priv->mutex);
2928 IWL_DEBUG_MAC80211(priv, "leave\n"); 2932 IWL_DEBUG_MAC80211(priv, "leave\n");
2929 2933
2930 return ret; 2934 return ret;
@@ -2957,10 +2961,21 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2957 return ret; 2961 return ret;
2958 case IEEE80211_AMPDU_TX_START: 2962 case IEEE80211_AMPDU_TX_START:
2959 IWL_DEBUG_HT(priv, "start Tx\n"); 2963 IWL_DEBUG_HT(priv, "start Tx\n");
2960 return iwl_tx_agg_start(priv, sta->addr, tid, ssn); 2964 ret = iwlagn_tx_agg_start(priv, sta->addr, tid, ssn);
2965 if (ret == 0) {
2966 priv->_agn.agg_tids_count++;
2967 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
2968 priv->_agn.agg_tids_count);
2969 }
2970 return ret;
2961 case IEEE80211_AMPDU_TX_STOP: 2971 case IEEE80211_AMPDU_TX_STOP:
2962 IWL_DEBUG_HT(priv, "stop Tx\n"); 2972 IWL_DEBUG_HT(priv, "stop Tx\n");
2963 ret = iwl_tx_agg_stop(priv, sta->addr, tid); 2973 ret = iwlagn_tx_agg_stop(priv, sta->addr, tid);
2974 if ((ret == 0) && (priv->_agn.agg_tids_count > 0)) {
2975 priv->_agn.agg_tids_count--;
2976 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
2977 priv->_agn.agg_tids_count);
2978 }
2964 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2979 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2965 return 0; 2980 return 0;
2966 else 2981 else
@@ -2997,18 +3012,7 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
2997 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 3012 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
2998 int sta_id; 3013 int sta_id;
2999 3014
3000 /*
3001 * TODO: We really should use this callback to
3002 * actually maintain the station table in
3003 * the device.
3004 */
3005
3006 switch (cmd) { 3015 switch (cmd) {
3007 case STA_NOTIFY_ADD:
3008 atomic_set(&sta_priv->pending_frames, 0);
3009 if (vif->type == NL80211_IFTYPE_AP)
3010 sta_priv->client = true;
3011 break;
3012 case STA_NOTIFY_SLEEP: 3016 case STA_NOTIFY_SLEEP:
3013 WARN_ON(!sta_priv->client); 3017 WARN_ON(!sta_priv->client);
3014 sta_priv->asleep = true; 3018 sta_priv->asleep = true;
@@ -3029,6 +3033,55 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
3029 } 3033 }
3030} 3034}
3031 3035
3036/**
3037 * iwl_restore_wepkeys - Restore WEP keys to device
3038 */
3039static void iwl_restore_wepkeys(struct iwl_priv *priv)
3040{
3041 mutex_lock(&priv->mutex);
3042 if (priv->iw_mode == NL80211_IFTYPE_STATION &&
3043 priv->default_wep_key &&
3044 iwl_send_static_wepkey_cmd(priv, 0))
3045 IWL_ERR(priv, "Could not send WEP static key\n");
3046 mutex_unlock(&priv->mutex);
3047}
3048
3049static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3050 struct ieee80211_vif *vif,
3051 struct ieee80211_sta *sta)
3052{
3053 struct iwl_priv *priv = hw->priv;
3054 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
3055 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
3056 int ret;
3057 u8 sta_id;
3058
3059 IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
3060 sta->addr);
3061
3062 atomic_set(&sta_priv->pending_frames, 0);
3063 if (vif->type == NL80211_IFTYPE_AP)
3064 sta_priv->client = true;
3065
3066 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
3067 &sta_id);
3068 if (ret) {
3069 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3070 sta->addr, ret);
3071 /* Should we return success if return code is EEXIST ? */
3072 return ret;
3073 }
3074
3075 iwl_restore_wepkeys(priv);
3076
3077 /* Initialize rate scaling */
3078 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
3079 sta->addr);
3080 iwl_rs_rate_init(priv, sta, sta_id);
3081
3082 return ret;
3083}
3084
3032/***************************************************************************** 3085/*****************************************************************************
3033 * 3086 *
3034 * sysfs attributes 3087 * sysfs attributes
@@ -3129,87 +3182,6 @@ static ssize_t store_tx_power(struct device *d,
3129 3182
3130static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); 3183static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
3131 3184
3132static ssize_t show_flags(struct device *d,
3133 struct device_attribute *attr, char *buf)
3134{
3135 struct iwl_priv *priv = dev_get_drvdata(d);
3136
3137 return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
3138}
3139
3140static ssize_t store_flags(struct device *d,
3141 struct device_attribute *attr,
3142 const char *buf, size_t count)
3143{
3144 struct iwl_priv *priv = dev_get_drvdata(d);
3145 unsigned long val;
3146 u32 flags;
3147 int ret = strict_strtoul(buf, 0, &val);
3148 if (ret)
3149 return ret;
3150 flags = (u32)val;
3151
3152 mutex_lock(&priv->mutex);
3153 if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
3154 /* Cancel any currently running scans... */
3155 if (iwl_scan_cancel_timeout(priv, 100))
3156 IWL_WARN(priv, "Could not cancel scan.\n");
3157 else {
3158 IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
3159 priv->staging_rxon.flags = cpu_to_le32(flags);
3160 iwlcore_commit_rxon(priv);
3161 }
3162 }
3163 mutex_unlock(&priv->mutex);
3164
3165 return count;
3166}
3167
3168static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
3169
3170static ssize_t show_filter_flags(struct device *d,
3171 struct device_attribute *attr, char *buf)
3172{
3173 struct iwl_priv *priv = dev_get_drvdata(d);
3174
3175 return sprintf(buf, "0x%04X\n",
3176 le32_to_cpu(priv->active_rxon.filter_flags));
3177}
3178
3179static ssize_t store_filter_flags(struct device *d,
3180 struct device_attribute *attr,
3181 const char *buf, size_t count)
3182{
3183 struct iwl_priv *priv = dev_get_drvdata(d);
3184 unsigned long val;
3185 u32 filter_flags;
3186 int ret = strict_strtoul(buf, 0, &val);
3187 if (ret)
3188 return ret;
3189 filter_flags = (u32)val;
3190
3191 mutex_lock(&priv->mutex);
3192 if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
3193 /* Cancel any currently running scans... */
3194 if (iwl_scan_cancel_timeout(priv, 100))
3195 IWL_WARN(priv, "Could not cancel scan.\n");
3196 else {
3197 IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
3198 "0x%04X\n", filter_flags);
3199 priv->staging_rxon.filter_flags =
3200 cpu_to_le32(filter_flags);
3201 iwlcore_commit_rxon(priv);
3202 }
3203 }
3204 mutex_unlock(&priv->mutex);
3205
3206 return count;
3207}
3208
3209static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3210 store_filter_flags);
3211
3212
3213static ssize_t show_statistics(struct device *d, 3185static ssize_t show_statistics(struct device *d,
3214 struct device_attribute *attr, char *buf) 3186 struct device_attribute *attr, char *buf)
3215{ 3187{
@@ -3315,6 +3287,13 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3315 priv->ucode_trace.data = (unsigned long)priv; 3287 priv->ucode_trace.data = (unsigned long)priv;
3316 priv->ucode_trace.function = iwl_bg_ucode_trace; 3288 priv->ucode_trace.function = iwl_bg_ucode_trace;
3317 3289
3290 if (priv->cfg->ops->lib->recover_from_tx_stall) {
3291 init_timer(&priv->monitor_recover);
3292 priv->monitor_recover.data = (unsigned long)priv;
3293 priv->monitor_recover.function =
3294 priv->cfg->ops->lib->recover_from_tx_stall;
3295 }
3296
3318 if (!priv->cfg->use_isr_legacy) 3297 if (!priv->cfg->use_isr_legacy)
3319 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3298 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3320 iwl_irq_tasklet, (unsigned long)priv); 3299 iwl_irq_tasklet, (unsigned long)priv);
@@ -3334,6 +3313,8 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3334 cancel_work_sync(&priv->beacon_update); 3313 cancel_work_sync(&priv->beacon_update);
3335 del_timer_sync(&priv->statistics_periodic); 3314 del_timer_sync(&priv->statistics_periodic);
3336 del_timer_sync(&priv->ucode_trace); 3315 del_timer_sync(&priv->ucode_trace);
3316 if (priv->cfg->ops->lib->recover_from_tx_stall)
3317 del_timer_sync(&priv->monitor_recover);
3337} 3318}
3338 3319
3339static void iwl_init_hw_rates(struct iwl_priv *priv, 3320static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3371,9 +3352,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
3371 mutex_init(&priv->mutex); 3352 mutex_init(&priv->mutex);
3372 mutex_init(&priv->sync_cmd_mutex); 3353 mutex_init(&priv->sync_cmd_mutex);
3373 3354
3374 /* Clear the driver's (not device's) station table */
3375 iwl_clear_stations_table(priv);
3376
3377 priv->ieee_channels = NULL; 3355 priv->ieee_channels = NULL;
3378 priv->ieee_rates = NULL; 3356 priv->ieee_rates = NULL;
3379 priv->band = IEEE80211_BAND_2GHZ; 3357 priv->band = IEEE80211_BAND_2GHZ;
@@ -3381,6 +3359,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3381 priv->iw_mode = NL80211_IFTYPE_STATION; 3359 priv->iw_mode = NL80211_IFTYPE_STATION;
3382 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; 3360 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3383 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 3361 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3362 priv->_agn.agg_tids_count = 0;
3384 3363
3385 /* initialize force reset */ 3364 /* initialize force reset */
3386 priv->force_reset[IWL_RF_RESET].reset_duration = 3365 priv->force_reset[IWL_RF_RESET].reset_duration =
@@ -3394,16 +3373,10 @@ static int iwl_init_drv(struct iwl_priv *priv)
3394 3373
3395 iwl_init_scan_params(priv); 3374 iwl_init_scan_params(priv);
3396 3375
3397 iwl_reset_qos(priv);
3398
3399 priv->qos_data.qos_active = 0;
3400 priv->qos_data.qos_cap.val = 0;
3401
3402 priv->rates_mask = IWL_RATES_MASK;
3403 /* Set the tx_power_user_lmt to the lowest power level 3376 /* Set the tx_power_user_lmt to the lowest power level
3404 * this value will get overwritten by channel max power avg 3377 * this value will get overwritten by channel max power avg
3405 * from eeprom */ 3378 * from eeprom */
3406 priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN; 3379 priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
3407 3380
3408 ret = iwl_init_channel_map(priv); 3381 ret = iwl_init_channel_map(priv);
3409 if (ret) { 3382 if (ret) {
@@ -3435,8 +3408,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
3435} 3408}
3436 3409
3437static struct attribute *iwl_sysfs_entries[] = { 3410static struct attribute *iwl_sysfs_entries[] = {
3438 &dev_attr_flags.attr,
3439 &dev_attr_filter_flags.attr,
3440 &dev_attr_statistics.attr, 3411 &dev_attr_statistics.attr,
3441 &dev_attr_temperature.attr, 3412 &dev_attr_temperature.attr,
3442 &dev_attr_tx_power.attr, 3413 &dev_attr_tx_power.attr,
@@ -3469,6 +3440,8 @@ static struct ieee80211_ops iwl_hw_ops = {
3469 .ampdu_action = iwl_mac_ampdu_action, 3440 .ampdu_action = iwl_mac_ampdu_action,
3470 .hw_scan = iwl_mac_hw_scan, 3441 .hw_scan = iwl_mac_hw_scan,
3471 .sta_notify = iwl_mac_sta_notify, 3442 .sta_notify = iwl_mac_sta_notify,
3443 .sta_add = iwlagn_mac_sta_add,
3444 .sta_remove = iwl_mac_sta_remove,
3472}; 3445};
3473 3446
3474static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3447static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -3572,7 +3545,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3572 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); 3545 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
3573 3546
3574 iwl_hw_detect(priv); 3547 iwl_hw_detect(priv);
3575 IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", 3548 IWL_INFO(priv, "Detected %s, REV=0x%X\n",
3576 priv->cfg->name, priv->hw_rev); 3549 priv->cfg->name, priv->hw_rev);
3577 3550
3578 /* We disable the RETRY_TIMEOUT register (0x41) to keep 3551 /* We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -3750,10 +3723,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3750 iwl_dealloc_ucode_pci(priv); 3723 iwl_dealloc_ucode_pci(priv);
3751 3724
3752 if (priv->rxq.bd) 3725 if (priv->rxq.bd)
3753 iwl_rx_queue_free(priv, &priv->rxq); 3726 iwlagn_rx_queue_free(priv, &priv->rxq);
3754 iwl_hw_txq_ctx_free(priv); 3727 iwlagn_hw_txq_ctx_free(priv);
3755 3728
3756 iwl_clear_stations_table(priv);
3757 iwl_eeprom_free(priv); 3729 iwl_eeprom_free(priv);
3758 3730
3759 3731
@@ -3867,6 +3839,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
3867 {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, 3839 {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)},
3868 {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, 3840 {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
3869 {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, 3841 {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
3842 {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000i_g2_2agn_cfg)},
3870 3843
3871/* 6x50 WiFi/WiMax Series */ 3844/* 6x50 WiFi/WiMax Series */
3872 {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, 3845 {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
@@ -3949,3 +3922,33 @@ module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
3949MODULE_PARM_DESC(debug, "debug output mask"); 3922MODULE_PARM_DESC(debug, "debug output mask");
3950#endif 3923#endif
3951 3924
3925module_param_named(swcrypto50, iwlagn_mod_params.sw_crypto, bool, S_IRUGO);
3926MODULE_PARM_DESC(swcrypto50,
3927 "using crypto in software (default 0 [hardware]) (deprecated)");
3928module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
3929MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
3930module_param_named(queues_num50,
3931 iwlagn_mod_params.num_of_queues, int, S_IRUGO);
3932MODULE_PARM_DESC(queues_num50,
3933 "number of hw queues in 50xx series (deprecated)");
3934module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO);
3935MODULE_PARM_DESC(queues_num, "number of hw queues.");
3936module_param_named(11n_disable50, iwlagn_mod_params.disable_11n, int, S_IRUGO);
3937MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality (deprecated)");
3938module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO);
3939MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
3940module_param_named(amsdu_size_8K50, iwlagn_mod_params.amsdu_size_8K,
3941 int, S_IRUGO);
3942MODULE_PARM_DESC(amsdu_size_8K50,
3943 "enable 8K amsdu size in 50XX series (deprecated)");
3944module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K,
3945 int, S_IRUGO);
3946MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
3947module_param_named(fw_restart50, iwlagn_mod_params.restart_fw, int, S_IRUGO);
3948MODULE_PARM_DESC(fw_restart50,
3949 "restart firmware in case of error (deprecated)");
3950module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
3951MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
3952module_param_named(
3953 disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
3954MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
new file mode 100644
index 000000000000..5ad14055eda3
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -0,0 +1,149 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __iwl_agn_h__
64#define __iwl_agn_h__
65
66#include "iwl-dev.h"
67
68extern struct iwl_mod_params iwlagn_mod_params;
69extern struct iwl_ucode_ops iwlagn_ucode;
70extern struct iwl_hcmd_ops iwlagn_hcmd;
71extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
72
73int iwl_reset_ict(struct iwl_priv *priv);
74void iwl_disable_ict(struct iwl_priv *priv);
75int iwl_alloc_isr_ict(struct iwl_priv *priv);
76void iwl_free_isr_ict(struct iwl_priv *priv);
77irqreturn_t iwl_isr_ict(int irq, void *data);
78bool iwl_good_ack_health(struct iwl_priv *priv,
79 struct iwl_rx_packet *pkt);
80
81/* tx queue */
82void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
83 int txq_id, u32 index);
84void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
85 struct iwl_tx_queue *txq,
86 int tx_fifo_id, int scd_retry);
87void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
88 struct iwl_tx_queue *txq,
89 u16 byte_cnt);
90void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
91 struct iwl_tx_queue *txq);
92int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
93 int tx_fifo, int sta_id, int tid, u16 ssn_idx);
94int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
95 u16 ssn_idx, u8 tx_fifo);
96void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
97
98/* uCode */
99int iwlagn_load_ucode(struct iwl_priv *priv);
100void iwlagn_rx_calib_result(struct iwl_priv *priv,
101 struct iwl_rx_mem_buffer *rxb);
102void iwlagn_rx_calib_complete(struct iwl_priv *priv,
103 struct iwl_rx_mem_buffer *rxb);
104void iwlagn_init_alive_start(struct iwl_priv *priv);
105int iwlagn_alive_notify(struct iwl_priv *priv);
106
107/* lib */
108void iwlagn_rx_handler_setup(struct iwl_priv *priv);
109void iwlagn_setup_deferred_work(struct iwl_priv *priv);
110int iwlagn_hw_valid_rtc_data_addr(u32 addr);
111int iwlagn_send_tx_power(struct iwl_priv *priv);
112void iwlagn_temperature(struct iwl_priv *priv);
113u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv);
114const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
115 size_t offset);
116void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
117int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
118int iwlagn_hw_nic_init(struct iwl_priv *priv);
119
120/* rx */
121void iwlagn_rx_queue_restock(struct iwl_priv *priv);
122void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority);
123void iwlagn_rx_replenish(struct iwl_priv *priv);
124void iwlagn_rx_replenish_now(struct iwl_priv *priv);
125void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
126int iwlagn_rxq_stop(struct iwl_priv *priv);
127int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
128void iwlagn_rx_reply_rx(struct iwl_priv *priv,
129 struct iwl_rx_mem_buffer *rxb);
130void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
131 struct iwl_rx_mem_buffer *rxb);
132
133/* tx */
134void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
135 struct ieee80211_tx_info *info);
136int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
137int iwlagn_tx_agg_start(struct iwl_priv *priv,
138 const u8 *ra, u16 tid, u16 *ssn);
139int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
140int iwlagn_txq_check_empty(struct iwl_priv *priv,
141 int sta_id, u8 tid, int txq_id);
142void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
143 struct iwl_rx_mem_buffer *rxb);
144int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
145void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv);
146int iwlagn_txq_ctx_reset(struct iwl_priv *priv);
147void iwlagn_txq_ctx_stop(struct iwl_priv *priv);
148
149#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 845831ac053e..dbb50a8e0ce3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -592,7 +592,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
592 IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); 592 IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time);
593 593
594 if (!rx_enable_time) { 594 if (!rx_enable_time) {
595 IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0! \n"); 595 IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0!\n");
596 return; 596 return;
597 } 597 }
598 598
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 894bcb8b8b37..f09bff823ab6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -65,7 +65,7 @@ MODULE_LICENSE("GPL");
65 */ 65 */
66static bool bt_coex_active = true; 66static bool bt_coex_active = true;
67module_param(bt_coex_active, bool, S_IRUGO); 67module_param(bt_coex_active, bool, S_IRUGO);
68MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n"); 68MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
69 69
70static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { 70static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
71 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, 71 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
@@ -114,8 +114,6 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
114u32 iwl_debug_level; 114u32 iwl_debug_level;
115EXPORT_SYMBOL(iwl_debug_level); 115EXPORT_SYMBOL(iwl_debug_level);
116 116
117static irqreturn_t iwl_isr(int irq, void *data);
118
119/* 117/*
120 * Parameter order: 118 * Parameter order:
121 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate 119 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
@@ -142,30 +140,6 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
142}; 140};
143EXPORT_SYMBOL(iwl_rates); 141EXPORT_SYMBOL(iwl_rates);
144 142
145/**
146 * translate ucode response to mac80211 tx status control values
147 */
148void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
149 struct ieee80211_tx_info *info)
150{
151 struct ieee80211_tx_rate *r = &info->control.rates[0];
152
153 info->antenna_sel_tx =
154 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
155 if (rate_n_flags & RATE_MCS_HT_MSK)
156 r->flags |= IEEE80211_TX_RC_MCS;
157 if (rate_n_flags & RATE_MCS_GF_MSK)
158 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
159 if (rate_n_flags & RATE_MCS_HT40_MSK)
160 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
161 if (rate_n_flags & RATE_MCS_DUP_MSK)
162 r->flags |= IEEE80211_TX_RC_DUP_DATA;
163 if (rate_n_flags & RATE_MCS_SGI_MSK)
164 r->flags |= IEEE80211_TX_RC_SHORT_GI;
165 r->idx = iwl_hwrate_to_mac80211_idx(rate_n_flags, info->band);
166}
167EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
168
169int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) 143int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
170{ 144{
171 int idx = 0; 145 int idx = 0;
@@ -197,27 +171,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
197} 171}
198EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); 172EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
199 173
200int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
201{
202 int idx = 0;
203 int band_offset = 0;
204
205 /* HT rate format: mac80211 wants an MCS number, which is just LSB */
206 if (rate_n_flags & RATE_MCS_HT_MSK) {
207 idx = (rate_n_flags & 0xff);
208 return idx;
209 /* Legacy rate format, search for match in table */
210 } else {
211 if (band == IEEE80211_BAND_5GHZ)
212 band_offset = IWL_FIRST_OFDM_RATE;
213 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
214 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
215 return idx - band_offset;
216 }
217
218 return -1;
219}
220
221u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) 174u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant)
222{ 175{
223 int i; 176 int i;
@@ -267,74 +220,16 @@ void iwl_hw_detect(struct iwl_priv *priv)
267} 220}
268EXPORT_SYMBOL(iwl_hw_detect); 221EXPORT_SYMBOL(iwl_hw_detect);
269 222
270int iwl_hw_nic_init(struct iwl_priv *priv)
271{
272 unsigned long flags;
273 struct iwl_rx_queue *rxq = &priv->rxq;
274 int ret;
275
276 /* nic_init */
277 spin_lock_irqsave(&priv->lock, flags);
278 priv->cfg->ops->lib->apm_ops.init(priv);
279
280 /* Set interrupt coalescing calibration timer to default (512 usecs) */
281 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
282
283 spin_unlock_irqrestore(&priv->lock, flags);
284
285 ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
286
287 priv->cfg->ops->lib->apm_ops.config(priv);
288
289 /* Allocate the RX queue, or reset if it is already allocated */
290 if (!rxq->bd) {
291 ret = iwl_rx_queue_alloc(priv);
292 if (ret) {
293 IWL_ERR(priv, "Unable to initialize Rx queue\n");
294 return -ENOMEM;
295 }
296 } else
297 iwl_rx_queue_reset(priv, rxq);
298
299 iwl_rx_replenish(priv);
300
301 iwl_rx_init(priv, rxq);
302
303 spin_lock_irqsave(&priv->lock, flags);
304
305 rxq->need_update = 1;
306 iwl_rx_queue_update_write_ptr(priv, rxq);
307
308 spin_unlock_irqrestore(&priv->lock, flags);
309
310 /* Allocate or reset and init all Tx and Command queues */
311 if (!priv->txq) {
312 ret = iwl_txq_ctx_alloc(priv);
313 if (ret)
314 return ret;
315 } else
316 iwl_txq_ctx_reset(priv);
317
318 set_bit(STATUS_INIT, &priv->status);
319
320 return 0;
321}
322EXPORT_SYMBOL(iwl_hw_nic_init);
323
324/* 223/*
325 * QoS support 224 * QoS support
326*/ 225*/
327void iwl_activate_qos(struct iwl_priv *priv, u8 force) 226static void iwl_update_qos(struct iwl_priv *priv)
328{ 227{
329 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 228 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
330 return; 229 return;
331 230
332 priv->qos_data.def_qos_parm.qos_flags = 0; 231 priv->qos_data.def_qos_parm.qos_flags = 0;
333 232
334 if (priv->qos_data.qos_cap.q_AP.queue_request &&
335 !priv->qos_data.qos_cap.q_AP.txop_request)
336 priv->qos_data.def_qos_parm.qos_flags |=
337 QOS_PARAM_FLG_TXOP_TYPE_MSK;
338 if (priv->qos_data.qos_active) 233 if (priv->qos_data.qos_active)
339 priv->qos_data.def_qos_parm.qos_flags |= 234 priv->qos_data.def_qos_parm.qos_flags |=
340 QOS_PARAM_FLG_UPDATE_EDCA_MSK; 235 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
@@ -342,118 +237,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force)
342 if (priv->current_ht_config.is_ht) 237 if (priv->current_ht_config.is_ht)
343 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; 238 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
344 239
345 if (force || iwl_is_associated(priv)) { 240 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
346 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", 241 priv->qos_data.qos_active,
347 priv->qos_data.qos_active, 242 priv->qos_data.def_qos_parm.qos_flags);
348 priv->qos_data.def_qos_parm.qos_flags);
349 243
350 iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, 244 iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
351 sizeof(struct iwl_qosparam_cmd), 245 sizeof(struct iwl_qosparam_cmd),
352 &priv->qos_data.def_qos_parm, NULL); 246 &priv->qos_data.def_qos_parm, NULL);
353 }
354} 247}
355EXPORT_SYMBOL(iwl_activate_qos);
356
357/*
358 * AC CWmin CW max AIFSN TXOP Limit TXOP Limit
359 * (802.11b) (802.11a/g)
360 * AC_BK 15 1023 7 0 0
361 * AC_BE 15 1023 3 0 0
362 * AC_VI 7 15 2 6.016ms 3.008ms
363 * AC_VO 3 7 2 3.264ms 1.504ms
364 */
365void iwl_reset_qos(struct iwl_priv *priv)
366{
367 u16 cw_min = 15;
368 u16 cw_max = 1023;
369 u8 aifs = 2;
370 bool is_legacy = false;
371 unsigned long flags;
372 int i;
373
374 spin_lock_irqsave(&priv->lock, flags);
375 /* QoS always active in AP and ADHOC mode
376 * In STA mode wait for association
377 */
378 if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
379 priv->iw_mode == NL80211_IFTYPE_AP)
380 priv->qos_data.qos_active = 1;
381 else
382 priv->qos_data.qos_active = 0;
383
384 /* check for legacy mode */
385 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
386 (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
387 (priv->iw_mode == NL80211_IFTYPE_STATION &&
388 (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
389 cw_min = 31;
390 is_legacy = 1;
391 }
392
393 if (priv->qos_data.qos_active)
394 aifs = 3;
395
396 /* AC_BE */
397 priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
398 priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
399 priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
400 priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
401 priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
402
403 if (priv->qos_data.qos_active) {
404 /* AC_BK */
405 i = 1;
406 priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
407 priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
408 priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
409 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
410 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
411
412 /* AC_VI */
413 i = 2;
414 priv->qos_data.def_qos_parm.ac[i].cw_min =
415 cpu_to_le16((cw_min + 1) / 2 - 1);
416 priv->qos_data.def_qos_parm.ac[i].cw_max =
417 cpu_to_le16(cw_min);
418 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
419 if (is_legacy)
420 priv->qos_data.def_qos_parm.ac[i].edca_txop =
421 cpu_to_le16(6016);
422 else
423 priv->qos_data.def_qos_parm.ac[i].edca_txop =
424 cpu_to_le16(3008);
425 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
426
427 /* AC_VO */
428 i = 3;
429 priv->qos_data.def_qos_parm.ac[i].cw_min =
430 cpu_to_le16((cw_min + 1) / 4 - 1);
431 priv->qos_data.def_qos_parm.ac[i].cw_max =
432 cpu_to_le16((cw_min + 1) / 2 - 1);
433 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
434 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
435 if (is_legacy)
436 priv->qos_data.def_qos_parm.ac[i].edca_txop =
437 cpu_to_le16(3264);
438 else
439 priv->qos_data.def_qos_parm.ac[i].edca_txop =
440 cpu_to_le16(1504);
441 } else {
442 for (i = 1; i < 4; i++) {
443 priv->qos_data.def_qos_parm.ac[i].cw_min =
444 cpu_to_le16(cw_min);
445 priv->qos_data.def_qos_parm.ac[i].cw_max =
446 cpu_to_le16(cw_max);
447 priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
448 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
449 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
450 }
451 }
452 IWL_DEBUG_QOS(priv, "set QoS to default \n");
453
454 spin_unlock_irqrestore(&priv->lock, flags);
455}
456EXPORT_SYMBOL(iwl_reset_qos);
457 248
458#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 249#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
459#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 250#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
@@ -902,23 +693,10 @@ EXPORT_SYMBOL(iwl_full_rxon_required);
902 693
903u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) 694u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
904{ 695{
905 int i; 696 /*
906 int rate_mask; 697 * Assign the lowest rate -- should really get this from
907 698 * the beacon skb from mac80211.
908 /* Set rate mask*/ 699 */
909 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
910 rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
911 else
912 rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
913
914 /* Find lowest valid rate */
915 for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
916 i = iwl_rates[i].next_ieee) {
917 if (rate_mask & (1 << i))
918 return iwl_rates[i].plcp;
919 }
920
921 /* No valid rate was found. Assign the lowest one */
922 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) 700 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
923 return IWL_RATE_1M_PLCP; 701 return IWL_RATE_1M_PLCP;
924 else 702 else
@@ -1106,12 +884,12 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
1106 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; 884 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
1107 885
1108 /* copied from 'iwl_bg_request_scan()' */ 886 /* copied from 'iwl_bg_request_scan()' */
1109 /* Force use of chains B and C (0x6) for Rx for 4965 887 /* Force use of chains B and C (0x6) for Rx
1110 * Avoid A (0x1) because of its off-channel reception on A-band. 888 * Avoid A (0x1) for the device has off-channel reception on A-band.
1111 * MIMO is not used here, but value is required */ 889 * MIMO is not used here, but value is required */
1112 if (iwl_is_monitor_mode(priv) && 890 if (iwl_is_monitor_mode(priv) &&
1113 !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) && 891 !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
1114 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) { 892 priv->cfg->off_channel_workaround) {
1115 rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS; 893 rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS;
1116 rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS; 894 rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS;
1117 rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; 895 rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
@@ -1243,14 +1021,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
1243 if (!ch_info) 1021 if (!ch_info)
1244 ch_info = &priv->channel_info[0]; 1022 ch_info = &priv->channel_info[0];
1245 1023
1246 /*
1247 * in some case A channels are all non IBSS
1248 * in this case force B/G channel
1249 */
1250 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
1251 !(is_channel_ibss(ch_info)))
1252 ch_info = &priv->channel_info[0];
1253
1254 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); 1024 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
1255 priv->band = ch_info->band; 1025 priv->band = ch_info->band;
1256 1026
@@ -1285,7 +1055,6 @@ static void iwl_set_rate(struct iwl_priv *priv)
1285 } 1055 }
1286 1056
1287 priv->active_rate = 0; 1057 priv->active_rate = 0;
1288 priv->active_rate_basic = 0;
1289 1058
1290 for (i = 0; i < hw->n_bitrates; i++) { 1059 for (i = 0; i < hw->n_bitrates; i++) {
1291 rate = &(hw->bitrates[i]); 1060 rate = &(hw->bitrates[i]);
@@ -1293,30 +1062,13 @@ static void iwl_set_rate(struct iwl_priv *priv)
1293 priv->active_rate |= (1 << rate->hw_value); 1062 priv->active_rate |= (1 << rate->hw_value);
1294 } 1063 }
1295 1064
1296 IWL_DEBUG_RATE(priv, "Set active_rate = %0x, active_rate_basic = %0x\n", 1065 IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate);
1297 priv->active_rate, priv->active_rate_basic);
1298 1066
1299 /* 1067 priv->staging_rxon.cck_basic_rates =
1300 * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK) 1068 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
1301 * otherwise set it to the default of all CCK rates and 6, 12, 24 for 1069
1302 * OFDM 1070 priv->staging_rxon.ofdm_basic_rates =
1303 */ 1071 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
1304 if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
1305 priv->staging_rxon.cck_basic_rates =
1306 ((priv->active_rate_basic &
1307 IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
1308 else
1309 priv->staging_rxon.cck_basic_rates =
1310 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
1311
1312 if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
1313 priv->staging_rxon.ofdm_basic_rates =
1314 ((priv->active_rate_basic &
1315 (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
1316 IWL_FIRST_OFDM_RATE) & 0xFF;
1317 else
1318 priv->staging_rxon.ofdm_basic_rates =
1319 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
1320} 1072}
1321 1073
1322void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 1074void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
@@ -1400,7 +1152,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1400} 1152}
1401EXPORT_SYMBOL(iwl_irq_handle_error); 1153EXPORT_SYMBOL(iwl_irq_handle_error);
1402 1154
1403int iwl_apm_stop_master(struct iwl_priv *priv) 1155static int iwl_apm_stop_master(struct iwl_priv *priv)
1404{ 1156{
1405 int ret = 0; 1157 int ret = 0;
1406 1158
@@ -1416,7 +1168,6 @@ int iwl_apm_stop_master(struct iwl_priv *priv)
1416 1168
1417 return ret; 1169 return ret;
1418} 1170}
1419EXPORT_SYMBOL(iwl_apm_stop_master);
1420 1171
1421void iwl_apm_stop(struct iwl_priv *priv) 1172void iwl_apm_stop(struct iwl_priv *priv)
1422{ 1173{
@@ -1625,10 +1376,11 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
1625 int ret = 0; 1376 int ret = 0;
1626 s8 prev_tx_power = priv->tx_power_user_lmt; 1377 s8 prev_tx_power = priv->tx_power_user_lmt;
1627 1378
1628 if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) { 1379 if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
1629 IWL_WARN(priv, "Requested user TXPOWER %d below lower limit %d.\n", 1380 IWL_WARN(priv,
1381 "Requested user TXPOWER %d below lower limit %d.\n",
1630 tx_power, 1382 tx_power,
1631 IWL_TX_POWER_TARGET_POWER_MIN); 1383 IWLAGN_TX_POWER_TARGET_POWER_MIN);
1632 return -EINVAL; 1384 return -EINVAL;
1633 } 1385 }
1634 1386
@@ -1667,286 +1419,16 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
1667} 1419}
1668EXPORT_SYMBOL(iwl_set_tx_power); 1420EXPORT_SYMBOL(iwl_set_tx_power);
1669 1421
1670#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
1671
1672/* Free dram table */
1673void iwl_free_isr_ict(struct iwl_priv *priv)
1674{
1675 if (priv->ict_tbl_vir) {
1676 dma_free_coherent(&priv->pci_dev->dev,
1677 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
1678 priv->ict_tbl_vir, priv->ict_tbl_dma);
1679 priv->ict_tbl_vir = NULL;
1680 }
1681}
1682EXPORT_SYMBOL(iwl_free_isr_ict);
1683
1684
1685/* allocate dram shared table it is a PAGE_SIZE aligned
1686 * also reset all data related to ICT table interrupt.
1687 */
1688int iwl_alloc_isr_ict(struct iwl_priv *priv)
1689{
1690
1691 if (priv->cfg->use_isr_legacy)
1692 return 0;
1693 /* allocate shrared data table */
1694 priv->ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev,
1695 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
1696 &priv->ict_tbl_dma, GFP_KERNEL);
1697 if (!priv->ict_tbl_vir)
1698 return -ENOMEM;
1699
1700 /* align table to PAGE_SIZE boundry */
1701 priv->aligned_ict_tbl_dma = ALIGN(priv->ict_tbl_dma, PAGE_SIZE);
1702
1703 IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n",
1704 (unsigned long long)priv->ict_tbl_dma,
1705 (unsigned long long)priv->aligned_ict_tbl_dma,
1706 (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma));
1707
1708 priv->ict_tbl = priv->ict_tbl_vir +
1709 (priv->aligned_ict_tbl_dma - priv->ict_tbl_dma);
1710
1711 IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n",
1712 priv->ict_tbl, priv->ict_tbl_vir,
1713 (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma));
1714
1715 /* reset table and index to all 0 */
1716 memset(priv->ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
1717 priv->ict_index = 0;
1718
1719 /* add periodic RX interrupt */
1720 priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
1721 return 0;
1722}
1723EXPORT_SYMBOL(iwl_alloc_isr_ict);
1724
1725/* Device is going up inform it about using ICT interrupt table,
1726 * also we need to tell the driver to start using ICT interrupt.
1727 */
1728int iwl_reset_ict(struct iwl_priv *priv)
1729{
1730 u32 val;
1731 unsigned long flags;
1732
1733 if (!priv->ict_tbl_vir)
1734 return 0;
1735
1736 spin_lock_irqsave(&priv->lock, flags);
1737 iwl_disable_interrupts(priv);
1738
1739 memset(&priv->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
1740
1741 val = priv->aligned_ict_tbl_dma >> PAGE_SHIFT;
1742
1743 val |= CSR_DRAM_INT_TBL_ENABLE;
1744 val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
1745
1746 IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X "
1747 "aligned dma address %Lx\n",
1748 val, (unsigned long long)priv->aligned_ict_tbl_dma);
1749
1750 iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val);
1751 priv->use_ict = true;
1752 priv->ict_index = 0;
1753 iwl_write32(priv, CSR_INT, priv->inta_mask);
1754 iwl_enable_interrupts(priv);
1755 spin_unlock_irqrestore(&priv->lock, flags);
1756
1757 return 0;
1758}
1759EXPORT_SYMBOL(iwl_reset_ict);
1760
1761/* Device is going down disable ict interrupt usage */
1762void iwl_disable_ict(struct iwl_priv *priv)
1763{
1764 unsigned long flags;
1765
1766 spin_lock_irqsave(&priv->lock, flags);
1767 priv->use_ict = false;
1768 spin_unlock_irqrestore(&priv->lock, flags);
1769}
1770EXPORT_SYMBOL(iwl_disable_ict);
1771
1772/* interrupt handler using ict table, with this interrupt driver will
1773 * stop using INTA register to get device's interrupt, reading this register
1774 * is expensive, device will write interrupts in ICT dram table, increment
1775 * index then will fire interrupt to driver, driver will OR all ICT table
1776 * entries from current index up to table entry with 0 value. the result is
1777 * the interrupt we need to service, driver will set the entries back to 0 and
1778 * set index.
1779 */
1780irqreturn_t iwl_isr_ict(int irq, void *data)
1781{
1782 struct iwl_priv *priv = data;
1783 u32 inta, inta_mask;
1784 u32 val = 0;
1785
1786 if (!priv)
1787 return IRQ_NONE;
1788
1789 /* dram interrupt table not set yet,
1790 * use legacy interrupt.
1791 */
1792 if (!priv->use_ict)
1793 return iwl_isr(irq, data);
1794
1795 spin_lock(&priv->lock);
1796
1797 /* Disable (but don't clear!) interrupts here to avoid
1798 * back-to-back ISRs and sporadic interrupts from our NIC.
1799 * If we have something to service, the tasklet will re-enable ints.
1800 * If we *don't* have something, we'll re-enable before leaving here.
1801 */
1802 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
1803 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
1804
1805
1806 /* Ignore interrupt if there's nothing in NIC to service.
1807 * This may be due to IRQ shared with another device,
1808 * or due to sporadic interrupts thrown from our NIC. */
1809 if (!priv->ict_tbl[priv->ict_index]) {
1810 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
1811 goto none;
1812 }
1813
1814 /* read all entries that not 0 start with ict_index */
1815 while (priv->ict_tbl[priv->ict_index]) {
1816
1817 val |= le32_to_cpu(priv->ict_tbl[priv->ict_index]);
1818 IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
1819 priv->ict_index,
1820 le32_to_cpu(priv->ict_tbl[priv->ict_index]));
1821 priv->ict_tbl[priv->ict_index] = 0;
1822 priv->ict_index = iwl_queue_inc_wrap(priv->ict_index,
1823 ICT_COUNT);
1824
1825 }
1826
1827 /* We should not get this value, just ignore it. */
1828 if (val == 0xffffffff)
1829 val = 0;
1830
1831 /*
1832 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
1833 * (bit 15 before shifting it to 31) to clear when using interrupt
1834 * coalescing. fortunately, bits 18 and 19 stay set when this happens
1835 * so we use them to decide on the real state of the Rx bit.
1836 * In order words, bit 15 is set if bit 18 or bit 19 are set.
1837 */
1838 if (val & 0xC0000)
1839 val |= 0x8000;
1840
1841 inta = (0xff & val) | ((0xff00 & val) << 16);
1842 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
1843 inta, inta_mask, val);
1844
1845 inta &= priv->inta_mask;
1846 priv->inta |= inta;
1847
1848 /* iwl_irq_tasklet() will service interrupts and re-enable them */
1849 if (likely(inta))
1850 tasklet_schedule(&priv->irq_tasklet);
1851 else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta) {
1852 /* Allow interrupt if was disabled by this handler and
1853 * no tasklet was schedules, We should not enable interrupt,
1854 * tasklet will enable it.
1855 */
1856 iwl_enable_interrupts(priv);
1857 }
1858
1859 spin_unlock(&priv->lock);
1860 return IRQ_HANDLED;
1861
1862 none:
1863 /* re-enable interrupts here since we don't have anything to service.
1864 * only Re-enable if disabled by irq.
1865 */
1866 if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
1867 iwl_enable_interrupts(priv);
1868
1869 spin_unlock(&priv->lock);
1870 return IRQ_NONE;
1871}
1872EXPORT_SYMBOL(iwl_isr_ict);
1873
1874
1875static irqreturn_t iwl_isr(int irq, void *data)
1876{
1877 struct iwl_priv *priv = data;
1878 u32 inta, inta_mask;
1879#ifdef CONFIG_IWLWIFI_DEBUG
1880 u32 inta_fh;
1881#endif
1882 if (!priv)
1883 return IRQ_NONE;
1884
1885 spin_lock(&priv->lock);
1886
1887 /* Disable (but don't clear!) interrupts here to avoid
1888 * back-to-back ISRs and sporadic interrupts from our NIC.
1889 * If we have something to service, the tasklet will re-enable ints.
1890 * If we *don't* have something, we'll re-enable before leaving here. */
1891 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
1892 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
1893
1894 /* Discover which interrupts are active/pending */
1895 inta = iwl_read32(priv, CSR_INT);
1896
1897 /* Ignore interrupt if there's nothing in NIC to service.
1898 * This may be due to IRQ shared with another device,
1899 * or due to sporadic interrupts thrown from our NIC. */
1900 if (!inta) {
1901 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
1902 goto none;
1903 }
1904
1905 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
1906 /* Hardware disappeared. It might have already raised
1907 * an interrupt */
1908 IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
1909 goto unplugged;
1910 }
1911
1912#ifdef CONFIG_IWLWIFI_DEBUG
1913 if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
1914 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
1915 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
1916 "fh 0x%08x\n", inta, inta_mask, inta_fh);
1917 }
1918#endif
1919
1920 priv->inta |= inta;
1921 /* iwl_irq_tasklet() will service interrupts and re-enable them */
1922 if (likely(inta))
1923 tasklet_schedule(&priv->irq_tasklet);
1924 else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
1925 iwl_enable_interrupts(priv);
1926
1927 unplugged:
1928 spin_unlock(&priv->lock);
1929 return IRQ_HANDLED;
1930
1931 none:
1932 /* re-enable interrupts here since we don't have anything to service. */
1933 /* only Re-enable if diabled by irq and no schedules tasklet. */
1934 if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
1935 iwl_enable_interrupts(priv);
1936
1937 spin_unlock(&priv->lock);
1938 return IRQ_NONE;
1939}
1940
1941irqreturn_t iwl_isr_legacy(int irq, void *data) 1422irqreturn_t iwl_isr_legacy(int irq, void *data)
1942{ 1423{
1943 struct iwl_priv *priv = data; 1424 struct iwl_priv *priv = data;
1944 u32 inta, inta_mask; 1425 u32 inta, inta_mask;
1945 u32 inta_fh; 1426 u32 inta_fh;
1427 unsigned long flags;
1946 if (!priv) 1428 if (!priv)
1947 return IRQ_NONE; 1429 return IRQ_NONE;
1948 1430
1949 spin_lock(&priv->lock); 1431 spin_lock_irqsave(&priv->lock, flags);
1950 1432
1951 /* Disable (but don't clear!) interrupts here to avoid 1433 /* Disable (but don't clear!) interrupts here to avoid
1952 * back-to-back ISRs and sporadic interrupts from our NIC. 1434 * back-to-back ISRs and sporadic interrupts from our NIC.
@@ -1984,7 +1466,7 @@ irqreturn_t iwl_isr_legacy(int irq, void *data)
1984 tasklet_schedule(&priv->irq_tasklet); 1466 tasklet_schedule(&priv->irq_tasklet);
1985 1467
1986 unplugged: 1468 unplugged:
1987 spin_unlock(&priv->lock); 1469 spin_unlock_irqrestore(&priv->lock, flags);
1988 return IRQ_HANDLED; 1470 return IRQ_HANDLED;
1989 1471
1990 none: 1472 none:
@@ -1992,7 +1474,7 @@ irqreturn_t iwl_isr_legacy(int irq, void *data)
1992 /* only Re-enable if diabled by irq */ 1474 /* only Re-enable if diabled by irq */
1993 if (test_bit(STATUS_INT_ENABLED, &priv->status)) 1475 if (test_bit(STATUS_INT_ENABLED, &priv->status))
1994 iwl_enable_interrupts(priv); 1476 iwl_enable_interrupts(priv);
1995 spin_unlock(&priv->lock); 1477 spin_unlock_irqrestore(&priv->lock, flags);
1996 return IRQ_NONE; 1478 return IRQ_NONE;
1997} 1479}
1998EXPORT_SYMBOL(iwl_isr_legacy); 1480EXPORT_SYMBOL(iwl_isr_legacy);
@@ -2305,12 +1787,6 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
2305 cpu_to_le16((params->txop * 32)); 1787 cpu_to_le16((params->txop * 32));
2306 1788
2307 priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; 1789 priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
2308 priv->qos_data.qos_active = 1;
2309
2310 if (priv->iw_mode == NL80211_IFTYPE_AP)
2311 iwl_activate_qos(priv, 1);
2312 else if (priv->assoc_id && iwl_is_associated(priv))
2313 iwl_activate_qos(priv, 0);
2314 1790
2315 spin_unlock_irqrestore(&priv->lock, flags); 1791 spin_unlock_irqrestore(&priv->lock, flags);
2316 1792
@@ -2325,7 +1801,7 @@ static void iwl_ht_conf(struct iwl_priv *priv,
2325 struct iwl_ht_config *ht_conf = &priv->current_ht_config; 1801 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
2326 struct ieee80211_sta *sta; 1802 struct ieee80211_sta *sta;
2327 1803
2328 IWL_DEBUG_MAC80211(priv, "enter: \n"); 1804 IWL_DEBUG_MAC80211(priv, "enter:\n");
2329 1805
2330 if (!ht_conf->is_ht) 1806 if (!ht_conf->is_ht)
2331 return; 1807 return;
@@ -2567,11 +2043,6 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
2567 return -EIO; 2043 return -EIO;
2568 } 2044 }
2569 2045
2570 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
2571 IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
2572 return -EIO;
2573 }
2574
2575 spin_lock_irqsave(&priv->lock, flags); 2046 spin_lock_irqsave(&priv->lock, flags);
2576 2047
2577 if (priv->ibss_beacon) 2048 if (priv->ibss_beacon)
@@ -2586,52 +2057,25 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
2586 IWL_DEBUG_MAC80211(priv, "leave\n"); 2057 IWL_DEBUG_MAC80211(priv, "leave\n");
2587 spin_unlock_irqrestore(&priv->lock, flags); 2058 spin_unlock_irqrestore(&priv->lock, flags);
2588 2059
2589 iwl_reset_qos(priv);
2590
2591 priv->cfg->ops->lib->post_associate(priv); 2060 priv->cfg->ops->lib->post_associate(priv);
2592 2061
2593
2594 return 0; 2062 return 0;
2595} 2063}
2596EXPORT_SYMBOL(iwl_mac_beacon_update); 2064EXPORT_SYMBOL(iwl_mac_beacon_update);
2597 2065
2598int iwl_set_mode(struct iwl_priv *priv, int mode) 2066static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
2599{ 2067{
2600 if (mode == NL80211_IFTYPE_ADHOC) { 2068 iwl_connection_init_rx_config(priv, vif->type);
2601 const struct iwl_channel_info *ch_info;
2602
2603 ch_info = iwl_get_channel_info(priv,
2604 priv->band,
2605 le16_to_cpu(priv->staging_rxon.channel));
2606
2607 if (!ch_info || !is_channel_ibss(ch_info)) {
2608 IWL_ERR(priv, "channel %d not IBSS channel\n",
2609 le16_to_cpu(priv->staging_rxon.channel));
2610 return -EINVAL;
2611 }
2612 }
2613
2614 iwl_connection_init_rx_config(priv, mode);
2615 2069
2616 if (priv->cfg->ops->hcmd->set_rxon_chain) 2070 if (priv->cfg->ops->hcmd->set_rxon_chain)
2617 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2071 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2618 2072
2619 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); 2073 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2620 2074
2621 iwl_clear_stations_table(priv); 2075 return iwlcore_commit_rxon(priv);
2622
2623 /* dont commit rxon if rf-kill is on*/
2624 if (!iwl_is_ready_rf(priv))
2625 return -EAGAIN;
2626
2627 iwlcore_commit_rxon(priv);
2628
2629 return 0;
2630} 2076}
2631EXPORT_SYMBOL(iwl_set_mode);
2632 2077
2633int iwl_mac_add_interface(struct ieee80211_hw *hw, 2078int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2634 struct ieee80211_vif *vif)
2635{ 2079{
2636 struct iwl_priv *priv = hw->priv; 2080 struct iwl_priv *priv = hw->priv;
2637 int err = 0; 2081 int err = 0;
@@ -2640,6 +2084,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2640 2084
2641 mutex_lock(&priv->mutex); 2085 mutex_lock(&priv->mutex);
2642 2086
2087 if (WARN_ON(!iwl_is_ready_rf(priv))) {
2088 err = -EINVAL;
2089 goto out;
2090 }
2091
2643 if (priv->vif) { 2092 if (priv->vif) {
2644 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); 2093 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
2645 err = -EOPNOTSUPP; 2094 err = -EOPNOTSUPP;
@@ -2649,15 +2098,21 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2649 priv->vif = vif; 2098 priv->vif = vif;
2650 priv->iw_mode = vif->type; 2099 priv->iw_mode = vif->type;
2651 2100
2652 if (vif->addr) { 2101 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
2653 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr); 2102 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
2654 memcpy(priv->mac_addr, vif->addr, ETH_ALEN); 2103
2655 } 2104 err = iwl_set_mode(priv, vif);
2105 if (err)
2106 goto out_err;
2107
2108 /* Add the broadcast address so we can send broadcast frames */
2109 priv->cfg->ops->lib->add_bcast_station(priv);
2656 2110
2657 if (iwl_set_mode(priv, vif->type) == -EAGAIN) 2111 goto out;
2658 /* we are not ready, will run again when ready */
2659 set_bit(STATUS_MODE_PENDING, &priv->status);
2660 2112
2113 out_err:
2114 priv->vif = NULL;
2115 priv->iw_mode = NL80211_IFTYPE_STATION;
2661 out: 2116 out:
2662 mutex_unlock(&priv->mutex); 2117 mutex_unlock(&priv->mutex);
2663 2118
@@ -2667,7 +2122,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2667EXPORT_SYMBOL(iwl_mac_add_interface); 2122EXPORT_SYMBOL(iwl_mac_add_interface);
2668 2123
2669void iwl_mac_remove_interface(struct ieee80211_hw *hw, 2124void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2670 struct ieee80211_vif *vif) 2125 struct ieee80211_vif *vif)
2671{ 2126{
2672 struct iwl_priv *priv = hw->priv; 2127 struct iwl_priv *priv = hw->priv;
2673 2128
@@ -2675,6 +2130,8 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2675 2130
2676 mutex_lock(&priv->mutex); 2131 mutex_lock(&priv->mutex);
2677 2132
2133 iwl_clear_ucode_stations(priv, true);
2134
2678 if (iwl_is_ready_rf(priv)) { 2135 if (iwl_is_ready_rf(priv)) {
2679 iwl_scan_cancel_timeout(priv, 100); 2136 iwl_scan_cancel_timeout(priv, 100);
2680 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2137 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -2751,15 +2208,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2751 goto set_ch_out; 2208 goto set_ch_out;
2752 } 2209 }
2753 2210
2754 if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
2755 !is_channel_ibss(ch_info)) {
2756 IWL_ERR(priv, "channel %d in band %d not "
2757 "IBSS channel\n",
2758 conf->channel->hw_value, conf->channel->band);
2759 ret = -EINVAL;
2760 goto set_ch_out;
2761 }
2762
2763 spin_lock_irqsave(&priv->lock, flags); 2211 spin_lock_irqsave(&priv->lock, flags);
2764 2212
2765 /* Configure HT40 channels */ 2213 /* Configure HT40 channels */
@@ -2832,6 +2280,15 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2832 iwl_set_tx_power(priv, conf->power_level, false); 2280 iwl_set_tx_power(priv, conf->power_level, false);
2833 } 2281 }
2834 2282
2283 if (changed & IEEE80211_CONF_CHANGE_QOS) {
2284 bool qos_active = !!(conf->flags & IEEE80211_CONF_QOS);
2285
2286 spin_lock_irqsave(&priv->lock, flags);
2287 priv->qos_data.qos_active = qos_active;
2288 iwl_update_qos(priv);
2289 spin_unlock_irqrestore(&priv->lock, flags);
2290 }
2291
2835 if (!iwl_is_ready(priv)) { 2292 if (!iwl_is_ready(priv)) {
2836 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 2293 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2837 goto out; 2294 goto out;
@@ -2866,12 +2323,9 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2866 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); 2323 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
2867 spin_unlock_irqrestore(&priv->lock, flags); 2324 spin_unlock_irqrestore(&priv->lock, flags);
2868 2325
2869 iwl_reset_qos(priv);
2870
2871 spin_lock_irqsave(&priv->lock, flags); 2326 spin_lock_irqsave(&priv->lock, flags);
2872 priv->assoc_id = 0; 2327 priv->assoc_id = 0;
2873 priv->assoc_capability = 0; 2328 priv->assoc_capability = 0;
2874 priv->assoc_station_added = 0;
2875 2329
2876 /* new association get rid of ibss beacon skb */ 2330 /* new association get rid of ibss beacon skb */
2877 if (priv->ibss_beacon) 2331 if (priv->ibss_beacon)
@@ -2881,8 +2335,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2881 2335
2882 priv->beacon_int = priv->vif->bss_conf.beacon_int; 2336 priv->beacon_int = priv->vif->bss_conf.beacon_int;
2883 priv->timestamp = 0; 2337 priv->timestamp = 0;
2884 if ((priv->iw_mode == NL80211_IFTYPE_STATION))
2885 priv->beacon_int = 0;
2886 2338
2887 spin_unlock_irqrestore(&priv->lock, flags); 2339 spin_unlock_irqrestore(&priv->lock, flags);
2888 2340
@@ -2895,17 +2347,9 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2895 /* we are restarting association process 2347 /* we are restarting association process
2896 * clear RXON_FILTER_ASSOC_MSK bit 2348 * clear RXON_FILTER_ASSOC_MSK bit
2897 */ 2349 */
2898 if (priv->iw_mode != NL80211_IFTYPE_AP) { 2350 iwl_scan_cancel_timeout(priv, 100);
2899 iwl_scan_cancel_timeout(priv, 100); 2351 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2900 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2352 iwlcore_commit_rxon(priv);
2901 iwlcore_commit_rxon(priv);
2902 }
2903
2904 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
2905 IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
2906 mutex_unlock(&priv->mutex);
2907 return;
2908 }
2909 2353
2910 iwl_set_rate(priv); 2354 iwl_set_rate(priv);
2911 2355
@@ -2922,7 +2366,7 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv)
2922 sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues, 2366 sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues,
2923 GFP_KERNEL); 2367 GFP_KERNEL);
2924 if (!priv->txq) { 2368 if (!priv->txq) {
2925 IWL_ERR(priv, "Not enough memory for txq \n"); 2369 IWL_ERR(priv, "Not enough memory for txq\n");
2926 return -ENOMEM; 2370 return -ENOMEM;
2927 } 2371 }
2928 return 0; 2372 return 0;
@@ -3403,6 +2847,99 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
3403 } 2847 }
3404 return 0; 2848 return 0;
3405} 2849}
2850EXPORT_SYMBOL(iwl_force_reset);
2851
2852/**
2853 * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
2854 *
2855 * During normal condition (no queue is stuck), the timer is continually set to
2856 * execute every monitor_recover_period milliseconds after the last timer
2857 * expired. When the queue read_ptr is at the same place, the timer is
2858 * shorten to 100mSecs. This is
2859 * 1) to reduce the chance that the read_ptr may wrap around (not stuck)
2860 * 2) to detect the stuck queues quicker before the station and AP can
2861 * disassociate each other.
2862 *
2863 * This function monitors all the tx queues and recover from it if any
2864 * of the queues are stuck.
2865 * 1. It first check the cmd queue for stuck conditions. If it is stuck,
2866 * it will recover by resetting the firmware and return.
2867 * 2. Then, it checks for station association. If it associates it will check
2868 * other queues. If any queue is stuck, it will recover by resetting
2869 * the firmware.
2870 * Note: It the number of times the queue read_ptr to be at the same place to
2871 * be MAX_REPEAT+1 in order to consider to be stuck.
2872 */
2873/*
2874 * The maximum number of times the read pointer of the tx queue at the
2875 * same place without considering to be stuck.
2876 */
2877#define MAX_REPEAT (2)
2878static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
2879{
2880 struct iwl_tx_queue *txq;
2881 struct iwl_queue *q;
2882
2883 txq = &priv->txq[cnt];
2884 q = &txq->q;
2885 /* queue is empty, skip */
2886 if (q->read_ptr != q->write_ptr) {
2887 if (q->read_ptr == q->last_read_ptr) {
2888 /* a queue has not been read from last time */
2889 if (q->repeat_same_read_ptr > MAX_REPEAT) {
2890 IWL_ERR(priv,
2891 "queue %d stuck %d time. Fw reload.\n",
2892 q->id, q->repeat_same_read_ptr);
2893 q->repeat_same_read_ptr = 0;
2894 iwl_force_reset(priv, IWL_FW_RESET);
2895 } else {
2896 q->repeat_same_read_ptr++;
2897 IWL_DEBUG_RADIO(priv,
2898 "queue %d, not read %d time\n",
2899 q->id,
2900 q->repeat_same_read_ptr);
2901 mod_timer(&priv->monitor_recover, jiffies +
2902 msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS));
2903 }
2904 return 1;
2905 } else {
2906 q->last_read_ptr = q->read_ptr;
2907 q->repeat_same_read_ptr = 0;
2908 }
2909 }
2910 return 0;
2911}
2912
2913void iwl_bg_monitor_recover(unsigned long data)
2914{
2915 struct iwl_priv *priv = (struct iwl_priv *)data;
2916 int cnt;
2917
2918 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2919 return;
2920
2921 /* monitor and check for stuck cmd queue */
2922 if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM))
2923 return;
2924
2925 /* monitor and check for other stuck queues */
2926 if (iwl_is_associated(priv)) {
2927 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
2928 /* skip as we already checked the command queue */
2929 if (cnt == IWL_CMD_QUEUE_NUM)
2930 continue;
2931 if (iwl_check_stuck_queue(priv, cnt))
2932 return;
2933 }
2934 }
2935 /*
2936 * Reschedule the timer to occur in
2937 * priv->cfg->monitor_recover_period
2938 */
2939 mod_timer(&priv->monitor_recover,
2940 jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period));
2941}
2942EXPORT_SYMBOL(iwl_bg_monitor_recover);
3406 2943
3407#ifdef CONFIG_PM 2944#ifdef CONFIG_PM
3408 2945
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 732590f5fe30..10f95724536f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -191,6 +191,14 @@ struct iwl_lib_ops {
191 struct iwl_temp_ops temp_ops; 191 struct iwl_temp_ops temp_ops;
192 /* station management */ 192 /* station management */
193 void (*add_bcast_station)(struct iwl_priv *priv); 193 void (*add_bcast_station)(struct iwl_priv *priv);
194 /* recover from tx queue stall */
195 void (*recover_from_tx_stall)(unsigned long data);
196 /* check for plcp health */
197 bool (*check_plcp_health)(struct iwl_priv *priv,
198 struct iwl_rx_packet *pkt);
199 /* check for ack health */
200 bool (*check_ack_health)(struct iwl_priv *priv,
201 struct iwl_rx_packet *pkt);
194}; 202};
195 203
196struct iwl_led_ops { 204struct iwl_led_ops {
@@ -295,6 +303,10 @@ struct iwl_cfg {
295 const bool support_wimax_coexist; 303 const bool support_wimax_coexist;
296 u8 plcp_delta_threshold; 304 u8 plcp_delta_threshold;
297 s32 chain_noise_scale; 305 s32 chain_noise_scale;
306 /* timer period for monitor the driver queues */
307 u32 monitor_recover_period;
308 bool temperature_kelvin;
309 bool off_channel_workaround;
298}; 310};
299 311
300/*************************** 312/***************************
@@ -304,8 +316,7 @@ struct iwl_cfg {
304struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, 316struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
305 struct ieee80211_ops *hw_ops); 317 struct ieee80211_ops *hw_ops);
306void iwl_hw_detect(struct iwl_priv *priv); 318void iwl_hw_detect(struct iwl_priv *priv);
307void iwl_reset_qos(struct iwl_priv *priv); 319void iwl_activate_qos(struct iwl_priv *priv);
308void iwl_activate_qos(struct iwl_priv *priv, u8 force);
309int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, 320int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
310 const struct ieee80211_tx_queue_params *params); 321 const struct ieee80211_tx_queue_params *params);
311void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); 322void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
@@ -326,7 +337,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv);
326void iwl_configure_filter(struct ieee80211_hw *hw, 337void iwl_configure_filter(struct ieee80211_hw *hw,
327 unsigned int changed_flags, 338 unsigned int changed_flags,
328 unsigned int *total_flags, u64 multicast); 339 unsigned int *total_flags, u64 multicast);
329int iwl_hw_nic_init(struct iwl_priv *priv);
330int iwl_set_hw_params(struct iwl_priv *priv); 340int iwl_set_hw_params(struct iwl_priv *priv);
331bool iwl_is_monitor_mode(struct iwl_priv *priv); 341bool iwl_is_monitor_mode(struct iwl_priv *priv);
332void iwl_post_associate(struct iwl_priv *priv); 342void iwl_post_associate(struct iwl_priv *priv);
@@ -336,7 +346,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
336 u32 changes); 346 u32 changes);
337int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); 347int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
338int iwl_commit_rxon(struct iwl_priv *priv); 348int iwl_commit_rxon(struct iwl_priv *priv);
339int iwl_set_mode(struct iwl_priv *priv, int mode);
340int iwl_mac_add_interface(struct ieee80211_hw *hw, 349int iwl_mac_add_interface(struct ieee80211_hw *hw,
341 struct ieee80211_vif *vif); 350 struct ieee80211_vif *vif);
342void iwl_mac_remove_interface(struct ieee80211_hw *hw, 351void iwl_mac_remove_interface(struct ieee80211_hw *hw,
@@ -411,26 +420,22 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
411/***************************************************** 420/*****************************************************
412* RX 421* RX
413******************************************************/ 422******************************************************/
414void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
415void iwl_cmd_queue_free(struct iwl_priv *priv); 423void iwl_cmd_queue_free(struct iwl_priv *priv);
416int iwl_rx_queue_alloc(struct iwl_priv *priv); 424int iwl_rx_queue_alloc(struct iwl_priv *priv);
417void iwl_rx_handle(struct iwl_priv *priv); 425void iwl_rx_handle(struct iwl_priv *priv);
418void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, 426void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
419 struct iwl_rx_queue *q); 427 struct iwl_rx_queue *q);
420void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
421void iwl_rx_replenish(struct iwl_priv *priv);
422void iwl_rx_replenish_now(struct iwl_priv *priv);
423int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
424void iwl_rx_queue_restock(struct iwl_priv *priv);
425int iwl_rx_queue_space(const struct iwl_rx_queue *q); 428int iwl_rx_queue_space(const struct iwl_rx_queue *q);
426void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority);
427void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 429void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
428int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
429/* Handlers */ 430/* Handlers */
430void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 431void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
431 struct iwl_rx_mem_buffer *rxb); 432 struct iwl_rx_mem_buffer *rxb);
432void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 433void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
433 struct iwl_rx_mem_buffer *rxb); 434 struct iwl_rx_mem_buffer *rxb);
435bool iwl_good_plcp_health(struct iwl_priv *priv,
436 struct iwl_rx_packet *pkt);
437bool iwl_good_ack_health(struct iwl_priv *priv,
438 struct iwl_rx_packet *pkt);
434void iwl_rx_statistics(struct iwl_priv *priv, 439void iwl_rx_statistics(struct iwl_priv *priv,
435 struct iwl_rx_mem_buffer *rxb); 440 struct iwl_rx_mem_buffer *rxb);
436void iwl_reply_statistics(struct iwl_priv *priv, 441void iwl_reply_statistics(struct iwl_priv *priv,
@@ -442,14 +447,10 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
442/***************************************************** 447/*****************************************************
443* TX 448* TX
444******************************************************/ 449******************************************************/
445int iwl_txq_ctx_alloc(struct iwl_priv *priv);
446void iwl_txq_ctx_reset(struct iwl_priv *priv);
447void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); 450void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
448int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, 451int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
449 struct iwl_tx_queue *txq, 452 struct iwl_tx_queue *txq,
450 dma_addr_t addr, u16 len, u8 reset, u8 pad); 453 dma_addr_t addr, u16 len, u8 reset, u8 pad);
451int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
452void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
453int iwl_hw_tx_queue_init(struct iwl_priv *priv, 454int iwl_hw_tx_queue_init(struct iwl_priv *priv,
454 struct iwl_tx_queue *txq); 455 struct iwl_tx_queue *txq);
455void iwl_free_tfds_in_queue(struct iwl_priv *priv, 456void iwl_free_tfds_in_queue(struct iwl_priv *priv,
@@ -460,9 +461,6 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
460void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, 461void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
461 int slots_num, u32 txq_id); 462 int slots_num, u32 txq_id);
462void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); 463void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
463int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
464int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
465int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
466/***************************************************** 464/*****************************************************
467 * TX power 465 * TX power
468 ****************************************************/ 466 ****************************************************/
@@ -472,10 +470,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
472 * Rate 470 * Rate
473 ******************************************************************************/ 471 ******************************************************************************/
474 472
475void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
476 struct ieee80211_tx_info *info);
477int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); 473int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
478int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
479 474
480u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); 475u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
481 476
@@ -563,11 +558,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
563 * PCI * 558 * PCI *
564 *****************************************************/ 559 *****************************************************/
565irqreturn_t iwl_isr_legacy(int irq, void *data); 560irqreturn_t iwl_isr_legacy(int irq, void *data);
566int iwl_reset_ict(struct iwl_priv *priv);
567void iwl_disable_ict(struct iwl_priv *priv);
568int iwl_alloc_isr_ict(struct iwl_priv *priv);
569void iwl_free_isr_ict(struct iwl_priv *priv);
570irqreturn_t iwl_isr_ict(int irq, void *data);
571 561
572static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) 562static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
573{ 563{
@@ -577,6 +567,9 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
577 pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); 567 pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
578 return pci_lnk_ctl; 568 return pci_lnk_ctl;
579} 569}
570
571void iwl_bg_monitor_recover(unsigned long data);
572
580#ifdef CONFIG_PM 573#ifdef CONFIG_PM
581int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); 574int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
582int iwl_pci_resume(struct pci_dev *pdev); 575int iwl_pci_resume(struct pci_dev *pdev);
@@ -625,7 +618,6 @@ void iwlcore_free_geos(struct iwl_priv *priv);
625#define STATUS_SCAN_HW 15 618#define STATUS_SCAN_HW 15
626#define STATUS_POWER_PMI 16 619#define STATUS_POWER_PMI 16
627#define STATUS_FW_ERROR 17 620#define STATUS_FW_ERROR 17
628#define STATUS_MODE_PENDING 18
629 621
630 622
631static inline int iwl_is_ready(struct iwl_priv *priv) 623static inline int iwl_is_ready(struct iwl_priv *priv)
@@ -677,15 +669,8 @@ extern int iwl_send_statistics_request(struct iwl_priv *priv,
677 u8 flags, bool clear); 669 u8 flags, bool clear);
678extern int iwl_verify_ucode(struct iwl_priv *priv); 670extern int iwl_verify_ucode(struct iwl_priv *priv);
679extern int iwl_send_lq_cmd(struct iwl_priv *priv, 671extern int iwl_send_lq_cmd(struct iwl_priv *priv,
680 struct iwl_link_quality_cmd *lq, u8 flags); 672 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
681extern void iwl_rx_reply_rx(struct iwl_priv *priv,
682 struct iwl_rx_mem_buffer *rxb);
683extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
684 struct iwl_rx_mem_buffer *rxb);
685void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
686 struct iwl_rx_mem_buffer *rxb);
687void iwl_apm_stop(struct iwl_priv *priv); 673void iwl_apm_stop(struct iwl_priv *priv);
688int iwl_apm_stop_master(struct iwl_priv *priv);
689int iwl_apm_init(struct iwl_priv *priv); 674int iwl_apm_init(struct iwl_priv *priv);
690 675
691void iwl_setup_rxon_timing(struct iwl_priv *priv); 676void iwl_setup_rxon_timing(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 7bf44f146799..5f5820249a29 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -560,8 +560,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
560 test_bit(STATUS_POWER_PMI, &priv->status)); 560 test_bit(STATUS_POWER_PMI, &priv->status));
561 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 561 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
562 test_bit(STATUS_FW_ERROR, &priv->status)); 562 test_bit(STATUS_FW_ERROR, &priv->status));
563 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n",
564 test_bit(STATUS_MODE_PENDING, &priv->status));
565 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 563 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
566} 564}
567 565
@@ -660,7 +658,6 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
660 int pos = 0, i; 658 int pos = 0, i;
661 char buf[256]; 659 char buf[256];
662 const size_t bufsz = sizeof(buf); 660 const size_t bufsz = sizeof(buf);
663 ssize_t ret;
664 661
665 for (i = 0; i < AC_NUM; i++) { 662 for (i = 0; i < AC_NUM; i++) {
666 pos += scnprintf(buf + pos, bufsz - pos, 663 pos += scnprintf(buf + pos, bufsz - pos,
@@ -672,8 +669,7 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
672 priv->qos_data.def_qos_parm.ac[i].aifsn, 669 priv->qos_data.def_qos_parm.ac[i].aifsn,
673 priv->qos_data.def_qos_parm.ac[i].edca_txop); 670 priv->qos_data.def_qos_parm.ac[i].edca_txop);
674 } 671 }
675 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 672 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
676 return ret;
677} 673}
678 674
679static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 675static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
@@ -683,7 +679,6 @@ static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
683 int pos = 0; 679 int pos = 0;
684 char buf[256]; 680 char buf[256];
685 const size_t bufsz = sizeof(buf); 681 const size_t bufsz = sizeof(buf);
686 ssize_t ret;
687 682
688 pos += scnprintf(buf + pos, bufsz - pos, 683 pos += scnprintf(buf + pos, bufsz - pos,
689 "allow blinking: %s\n", 684 "allow blinking: %s\n",
@@ -697,8 +692,7 @@ static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
697 priv->last_blink_time); 692 priv->last_blink_time);
698 } 693 }
699 694
700 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 695 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
701 return ret;
702} 696}
703 697
704static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 698static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
@@ -711,7 +705,6 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
711 char buf[100]; 705 char buf[100];
712 int pos = 0; 706 int pos = 0;
713 const size_t bufsz = sizeof(buf); 707 const size_t bufsz = sizeof(buf);
714 ssize_t ret;
715 708
716 pos += scnprintf(buf + pos, bufsz - pos, 709 pos += scnprintf(buf + pos, bufsz - pos,
717 "Thermal Throttling Mode: %s\n", 710 "Thermal Throttling Mode: %s\n",
@@ -731,8 +724,7 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
731 "HT mode: %d\n", 724 "HT mode: %d\n",
732 restriction->is_ht); 725 restriction->is_ht);
733 } 726 }
734 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 727 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
735 return ret;
736} 728}
737 729
738static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, 730static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
@@ -769,13 +761,11 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
769 char buf[100]; 761 char buf[100];
770 int pos = 0; 762 int pos = 0;
771 const size_t bufsz = sizeof(buf); 763 const size_t bufsz = sizeof(buf);
772 ssize_t ret;
773 764
774 pos += scnprintf(buf + pos, bufsz - pos, 765 pos += scnprintf(buf + pos, bufsz - pos,
775 "11n 40MHz Mode: %s\n", 766 "11n 40MHz Mode: %s\n",
776 priv->disable_ht40 ? "Disabled" : "Enabled"); 767 priv->disable_ht40 ? "Disabled" : "Enabled");
777 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 768 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
778 return ret;
779} 769}
780 770
781static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, 771static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
@@ -2051,7 +2041,6 @@ static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2051 int pos = 0; 2041 int pos = 0;
2052 char buf[128]; 2042 char buf[128];
2053 const size_t bufsz = sizeof(buf); 2043 const size_t bufsz = sizeof(buf);
2054 ssize_t ret;
2055 2044
2056 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", 2045 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
2057 priv->event_log.ucode_trace ? "On" : "Off"); 2046 priv->event_log.ucode_trace ? "On" : "Off");
@@ -2062,8 +2051,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2062 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", 2051 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
2063 priv->event_log.wraps_more_count); 2052 priv->event_log.wraps_more_count);
2064 2053
2065 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2054 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2066 return ret;
2067} 2055}
2068 2056
2069static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, 2057static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
@@ -2095,6 +2083,31 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
2095 return count; 2083 return count;
2096} 2084}
2097 2085
2086static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
2087 char __user *user_buf,
2088 size_t count, loff_t *ppos) {
2089
2090 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2091 int len = 0;
2092 char buf[20];
2093
2094 len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags));
2095 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2096}
2097
2098static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
2099 char __user *user_buf,
2100 size_t count, loff_t *ppos) {
2101
2102 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2103 int len = 0;
2104 char buf[20];
2105
2106 len = sprintf(buf, "0x%04X\n",
2107 le32_to_cpu(priv->active_rxon.filter_flags));
2108 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2109}
2110
2098static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, 2111static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
2099 char __user *user_buf, 2112 char __user *user_buf,
2100 size_t count, loff_t *ppos) 2113 size_t count, loff_t *ppos)
@@ -2124,13 +2137,11 @@ static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2124 int pos = 0; 2137 int pos = 0;
2125 char buf[12]; 2138 char buf[12];
2126 const size_t bufsz = sizeof(buf); 2139 const size_t bufsz = sizeof(buf);
2127 ssize_t ret;
2128 2140
2129 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", 2141 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2130 priv->missed_beacon_threshold); 2142 priv->missed_beacon_threshold);
2131 2143
2132 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2144 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2133 return ret;
2134} 2145}
2135 2146
2136static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, 2147static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
@@ -2159,27 +2170,6 @@ static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2159 return count; 2170 return count;
2160} 2171}
2161 2172
2162static ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
2163 const char __user *user_buf,
2164 size_t count, loff_t *ppos)
2165{
2166 struct iwl_priv *priv = file->private_data;
2167 char buf[8];
2168 int buf_size;
2169 int scan;
2170
2171 memset(buf, 0, sizeof(buf));
2172 buf_size = min(count, sizeof(buf) - 1);
2173 if (copy_from_user(buf, user_buf, buf_size))
2174 return -EFAULT;
2175 if (sscanf(buf, "%d", &scan) != 1)
2176 return -EINVAL;
2177
2178 iwl_internal_short_hw_scan(priv);
2179
2180 return count;
2181}
2182
2183static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, 2173static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2184 char __user *user_buf, 2174 char __user *user_buf,
2185 size_t count, loff_t *ppos) { 2175 size_t count, loff_t *ppos) {
@@ -2188,13 +2178,11 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2188 int pos = 0; 2178 int pos = 0;
2189 char buf[12]; 2179 char buf[12];
2190 const size_t bufsz = sizeof(buf); 2180 const size_t bufsz = sizeof(buf);
2191 ssize_t ret;
2192 2181
2193 pos += scnprintf(buf + pos, bufsz - pos, "%u\n", 2182 pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
2194 priv->cfg->plcp_delta_threshold); 2183 priv->cfg->plcp_delta_threshold);
2195 2184
2196 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2185 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2197 return ret;
2198} 2186}
2199 2187
2200static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, 2188static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
@@ -2295,9 +2283,10 @@ DEBUGFS_WRITE_FILE_OPS(csr);
2295DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 2283DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2296DEBUGFS_READ_FILE_OPS(fh_reg); 2284DEBUGFS_READ_FILE_OPS(fh_reg);
2297DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 2285DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2298DEBUGFS_WRITE_FILE_OPS(internal_scan);
2299DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); 2286DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
2300DEBUGFS_READ_WRITE_FILE_OPS(force_reset); 2287DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
2288DEBUGFS_READ_FILE_OPS(rxon_flags);
2289DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
2301 2290
2302/* 2291/*
2303 * Create the debugfs files and directories 2292 * Create the debugfs files and directories
@@ -2349,7 +2338,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2349 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR); 2338 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
2350 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); 2339 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
2351 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); 2340 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
2352 DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR);
2353 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); 2341 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2354 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); 2342 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
2355 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2343 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
@@ -2360,6 +2348,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2360 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); 2348 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
2361 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); 2349 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
2362 } 2350 }
2351 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
2352 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
2363 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); 2353 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
2364 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, 2354 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
2365 &priv->disable_chain_noise_cal); 2355 &priv->disable_chain_noise_cal);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 6054c5fba0c1..4319bda487d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -43,6 +43,7 @@
43#include "iwl-debug.h" 43#include "iwl-debug.h"
44#include "iwl-4965-hw.h" 44#include "iwl-4965-hw.h"
45#include "iwl-3945-hw.h" 45#include "iwl-3945-hw.h"
46#include "iwl-agn-hw.h"
46#include "iwl-led.h" 47#include "iwl-led.h"
47#include "iwl-power.h" 48#include "iwl-power.h"
48#include "iwl-agn-rs.h" 49#include "iwl-agn-rs.h"
@@ -57,6 +58,7 @@ extern struct iwl_cfg iwl5100_abg_cfg;
57extern struct iwl_cfg iwl5150_agn_cfg; 58extern struct iwl_cfg iwl5150_agn_cfg;
58extern struct iwl_cfg iwl5150_abg_cfg; 59extern struct iwl_cfg iwl5150_abg_cfg;
59extern struct iwl_cfg iwl6000i_2agn_cfg; 60extern struct iwl_cfg iwl6000i_2agn_cfg;
61extern struct iwl_cfg iwl6000i_g2_2agn_cfg;
60extern struct iwl_cfg iwl6000i_2abg_cfg; 62extern struct iwl_cfg iwl6000i_2abg_cfg;
61extern struct iwl_cfg iwl6000i_2bg_cfg; 63extern struct iwl_cfg iwl6000i_2bg_cfg;
62extern struct iwl_cfg iwl6000_3agn_cfg; 64extern struct iwl_cfg iwl6000_3agn_cfg;
@@ -67,45 +69,6 @@ extern struct iwl_cfg iwl1000_bg_cfg;
67 69
68struct iwl_tx_queue; 70struct iwl_tx_queue;
69 71
70/* shared structures from iwl-5000.c */
71extern struct iwl_mod_params iwl50_mod_params;
72extern struct iwl_ucode_ops iwl5000_ucode;
73extern struct iwl_lib_ops iwl5000_lib;
74extern struct iwl_hcmd_ops iwl5000_hcmd;
75extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
76
77/* shared functions from iwl-5000.c */
78extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len);
79extern u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd,
80 u8 *data);
81extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
82 __le32 *tx_flags);
83extern int iwl5000_calc_rssi(struct iwl_priv *priv,
84 struct iwl_rx_phy_res *rx_resp);
85extern void iwl5000_nic_config(struct iwl_priv *priv);
86extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv);
87extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
88 size_t offset);
89extern void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
90 struct iwl_tx_queue *txq,
91 u16 byte_cnt);
92extern void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
93 struct iwl_tx_queue *txq);
94extern int iwl5000_load_ucode(struct iwl_priv *priv);
95extern void iwl5000_init_alive_start(struct iwl_priv *priv);
96extern int iwl5000_alive_notify(struct iwl_priv *priv);
97extern int iwl5000_hw_set_hw_params(struct iwl_priv *priv);
98extern int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
99 int tx_fifo, int sta_id, int tid, u16 ssn_idx);
100extern int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
101 u16 ssn_idx, u8 tx_fifo);
102extern void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask);
103extern void iwl5000_setup_deferred_work(struct iwl_priv *priv);
104extern void iwl5000_rx_handler_setup(struct iwl_priv *priv);
105extern int iwl5000_hw_valid_rtc_data_addr(u32 addr);
106extern int iwl5000_send_tx_power(struct iwl_priv *priv);
107extern void iwl5000_temperature(struct iwl_priv *priv);
108
109/* CT-KILL constants */ 72/* CT-KILL constants */
110#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ 73#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */
111#define CT_KILL_THRESHOLD 114 /* in Celsius */ 74#define CT_KILL_THRESHOLD 114 /* in Celsius */
@@ -183,6 +146,10 @@ struct iwl_queue {
183 int n_bd; /* number of BDs in this queue */ 146 int n_bd; /* number of BDs in this queue */
184 int write_ptr; /* 1-st empty entry (index) host_w*/ 147 int write_ptr; /* 1-st empty entry (index) host_w*/
185 int read_ptr; /* last used entry (index) host_r*/ 148 int read_ptr; /* last used entry (index) host_r*/
149 /* use for monitoring and recovering the stuck queue */
150 int last_read_ptr; /* storing the last read_ptr */
151 /* number of time read_ptr and last_read_ptr are the same */
152 u8 repeat_same_read_ptr;
186 dma_addr_t dma_addr; /* physical addr for BD's */ 153 dma_addr_t dma_addr; /* physical addr for BD's */
187 int n_window; /* safe queue window */ 154 int n_window; /* safe queue window */
188 u32 id; 155 u32 id;
@@ -304,13 +271,11 @@ struct iwl_channel_info {
304 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; 271 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
305}; 272};
306 273
307#define IWL_TX_FIFO_AC0 0 274#define IWL_TX_FIFO_BK 0
308#define IWL_TX_FIFO_AC1 1 275#define IWL_TX_FIFO_BE 1
309#define IWL_TX_FIFO_AC2 2 276#define IWL_TX_FIFO_VI 2
310#define IWL_TX_FIFO_AC3 3 277#define IWL_TX_FIFO_VO 3
311#define IWL_TX_FIFO_HCCA_1 5 278#define IWL_TX_FIFO_UNUSED -1
312#define IWL_TX_FIFO_HCCA_2 6
313#define IWL_TX_FIFO_NONE 7
314 279
315/* Minimum number of queues. MAX_NUM is defined in hw specific files. 280/* Minimum number of queues. MAX_NUM is defined in hw specific files.
316 * Set the minimum to accommodate the 4 standard TX queues, 1 command 281 * Set the minimum to accommodate the 4 standard TX queues, 1 command
@@ -361,13 +326,6 @@ enum {
361 326
362#define DEF_CMD_PAYLOAD_SIZE 320 327#define DEF_CMD_PAYLOAD_SIZE 320
363 328
364/*
365 * IWL_LINK_HDR_MAX should include ieee80211_hdr, radiotap header,
366 * SNAP header and alignment. It should also be big enough for 802.11
367 * control frames.
368 */
369#define IWL_LINK_HDR_MAX 64
370
371/** 329/**
372 * struct iwl_device_cmd 330 * struct iwl_device_cmd
373 * 331 *
@@ -519,38 +477,24 @@ struct iwl_ht_config {
519 u8 non_GF_STA_present; 477 u8 non_GF_STA_present;
520}; 478};
521 479
522union iwl_qos_capabity {
523 struct {
524 u8 edca_count:4; /* bit 0-3 */
525 u8 q_ack:1; /* bit 4 */
526 u8 queue_request:1; /* bit 5 */
527 u8 txop_request:1; /* bit 6 */
528 u8 reserved:1; /* bit 7 */
529 } q_AP;
530 struct {
531 u8 acvo_APSD:1; /* bit 0 */
532 u8 acvi_APSD:1; /* bit 1 */
533 u8 ac_bk_APSD:1; /* bit 2 */
534 u8 ac_be_APSD:1; /* bit 3 */
535 u8 q_ack:1; /* bit 4 */
536 u8 max_len:2; /* bit 5-6 */
537 u8 more_data_ack:1; /* bit 7 */
538 } q_STA;
539 u8 val;
540};
541
542/* QoS structures */ 480/* QoS structures */
543struct iwl_qos_info { 481struct iwl_qos_info {
544 int qos_active; 482 int qos_active;
545 union iwl_qos_capabity qos_cap;
546 struct iwl_qosparam_cmd def_qos_parm; 483 struct iwl_qosparam_cmd def_qos_parm;
547}; 484};
548 485
486/*
487 * Structure should be accessed with sta_lock held. When station addition
488 * is in progress (IWL_STA_UCODE_INPROGRESS) it is possible to access only
489 * the commands (iwl_addsta_cmd and iwl_link_quality_cmd) without sta_lock
490 * held.
491 */
549struct iwl_station_entry { 492struct iwl_station_entry {
550 struct iwl_addsta_cmd sta; 493 struct iwl_addsta_cmd sta;
551 struct iwl_tid_data tid[MAX_TID_COUNT]; 494 struct iwl_tid_data tid[MAX_TID_COUNT];
552 u8 used; 495 u8 used;
553 struct iwl_hw_key keyinfo; 496 struct iwl_hw_key keyinfo;
497 struct iwl_link_quality_cmd *lq;
554}; 498};
555 499
556/* 500/*
@@ -1039,6 +983,11 @@ struct iwl_event_log {
1039#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) 983#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
1040#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) 984#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
1041 985
986/* timer constants use to monitor and recover stuck tx queues in mSecs */
987#define IWL_MONITORING_PERIOD (1000)
988#define IWL_ONE_HUNDRED_MSECS (100)
989#define IWL_SIXTY_SECS (60000)
990
1042enum iwl_reset { 991enum iwl_reset {
1043 IWL_RF_RESET = 0, 992 IWL_RF_RESET = 0,
1044 IWL_FW_RESET, 993 IWL_FW_RESET,
@@ -1092,10 +1041,6 @@ struct iwl_priv {
1092 struct iwl_channel_info *channel_info; /* channel info array */ 1041 struct iwl_channel_info *channel_info; /* channel info array */
1093 u8 channel_count; /* # of channels */ 1042 u8 channel_count; /* # of channels */
1094 1043
1095 /* each calibration channel group in the EEPROM has a derived
1096 * clip setting for each rate. 3945 only.*/
1097 const struct iwl3945_clip_group clip39_groups[5];
1098
1099 /* thermal calibration */ 1044 /* thermal calibration */
1100 s32 temperature; /* degrees Kelvin */ 1045 s32 temperature; /* degrees Kelvin */
1101 s32 last_temperature; 1046 s32 last_temperature;
@@ -1168,9 +1113,7 @@ struct iwl_priv {
1168 u64 led_tpt; 1113 u64 led_tpt;
1169 1114
1170 u16 active_rate; 1115 u16 active_rate;
1171 u16 active_rate_basic;
1172 1116
1173 u8 assoc_station_added;
1174 u8 start_calib; 1117 u8 start_calib;
1175 struct iwl_sensitivity_data sensitivity_data; 1118 struct iwl_sensitivity_data sensitivity_data;
1176 struct iwl_chain_noise_data chain_noise_data; 1119 struct iwl_chain_noise_data chain_noise_data;
@@ -1197,9 +1140,6 @@ struct iwl_priv {
1197 1140
1198 unsigned long status; 1141 unsigned long status;
1199 1142
1200 int last_rx_rssi; /* From Rx packet statistics */
1201 int last_rx_noise; /* From beacon statistics */
1202
1203 /* counts mgmt, ctl, and data packets */ 1143 /* counts mgmt, ctl, and data packets */
1204 struct traffic_stats tx_stats; 1144 struct traffic_stats tx_stats;
1205 struct traffic_stats rx_stats; 1145 struct traffic_stats rx_stats;
@@ -1218,8 +1158,6 @@ struct iwl_priv {
1218#endif 1158#endif
1219 1159
1220 /* context information */ 1160 /* context information */
1221 u16 rates_mask;
1222
1223 u8 bssid[ETH_ALEN]; 1161 u8 bssid[ETH_ALEN];
1224 u16 rts_threshold; 1162 u16 rts_threshold;
1225 u8 mac_addr[ETH_ALEN]; 1163 u8 mac_addr[ETH_ALEN];
@@ -1228,7 +1166,7 @@ struct iwl_priv {
1228 spinlock_t sta_lock; 1166 spinlock_t sta_lock;
1229 int num_stations; 1167 int num_stations;
1230 struct iwl_station_entry stations[IWL_STATION_COUNT]; 1168 struct iwl_station_entry stations[IWL_STATION_COUNT];
1231 struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; 1169 struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */
1232 u8 default_wep_key; 1170 u8 default_wep_key;
1233 u8 key_mapping_key; 1171 u8 key_mapping_key;
1234 unsigned long ucode_key_table; 1172 unsigned long ucode_key_table;
@@ -1244,10 +1182,6 @@ struct iwl_priv {
1244 1182
1245 u8 mac80211_registered; 1183 u8 mac80211_registered;
1246 1184
1247 /* Rx'd packet timing information */
1248 u32 last_beacon_time;
1249 u64 last_tsf;
1250
1251 /* eeprom -- this is in the card's little endian byte order */ 1185 /* eeprom -- this is in the card's little endian byte order */
1252 u8 *eeprom; 1186 u8 *eeprom;
1253 int nvm_device_type; 1187 int nvm_device_type;
@@ -1262,20 +1196,53 @@ struct iwl_priv {
1262 u16 beacon_int; 1196 u16 beacon_int;
1263 struct ieee80211_vif *vif; 1197 struct ieee80211_vif *vif;
1264 1198
1265 /*Added for 3945 */ 1199 union {
1266 void *shared_virt; 1200#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
1267 dma_addr_t shared_phys; 1201 struct {
1268 /*End*/ 1202 void *shared_virt;
1269 struct iwl_hw_params hw_params; 1203 dma_addr_t shared_phys;
1204
1205 struct delayed_work thermal_periodic;
1206 struct delayed_work rfkill_poll;
1207
1208 struct iwl3945_notif_statistics statistics;
1209
1210 u32 sta_supp_rates;
1211 int last_rx_rssi; /* From Rx packet statistics */
1212
1213 /* Rx'd packet timing information */
1214 u32 last_beacon_time;
1215 u64 last_tsf;
1216
1217 /*
1218 * each calibration channel group in the
1219 * EEPROM has a derived clip setting for
1220 * each rate.
1221 */
1222 const struct iwl3945_clip_group clip_groups[5];
1223
1224 } _3945;
1225#endif
1226#if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE)
1227 struct {
1228 /* INT ICT Table */
1229 __le32 *ict_tbl;
1230 void *ict_tbl_vir;
1231 dma_addr_t ict_tbl_dma;
1232 dma_addr_t aligned_ict_tbl_dma;
1233 int ict_index;
1234 u32 inta;
1235 bool use_ict;
1236 /*
1237 * reporting the number of tids has AGG on. 0 means
1238 * no AGGREGATION
1239 */
1240 u8 agg_tids_count;
1241 } _agn;
1242#endif
1243 };
1270 1244
1271 /* INT ICT Table */ 1245 struct iwl_hw_params hw_params;
1272 __le32 *ict_tbl;
1273 dma_addr_t ict_tbl_dma;
1274 dma_addr_t aligned_ict_tbl_dma;
1275 int ict_index;
1276 void *ict_tbl_vir;
1277 u32 inta;
1278 bool use_ict;
1279 1246
1280 u32 inta_mask; 1247 u32 inta_mask;
1281 /* Current association information needed to configure the 1248 /* Current association information needed to configure the
@@ -1303,10 +1270,6 @@ struct iwl_priv {
1303 struct delayed_work alive_start; 1270 struct delayed_work alive_start;
1304 struct delayed_work scan_check; 1271 struct delayed_work scan_check;
1305 1272
1306 /*For 3945 only*/
1307 struct delayed_work thermal_periodic;
1308 struct delayed_work rfkill_poll;
1309
1310 /* TX Power */ 1273 /* TX Power */
1311 s8 tx_power_user_lmt; 1274 s8 tx_power_user_lmt;
1312 s8 tx_power_device_lmt; 1275 s8 tx_power_device_lmt;
@@ -1338,13 +1301,8 @@ struct iwl_priv {
1338 struct work_struct run_time_calib_work; 1301 struct work_struct run_time_calib_work;
1339 struct timer_list statistics_periodic; 1302 struct timer_list statistics_periodic;
1340 struct timer_list ucode_trace; 1303 struct timer_list ucode_trace;
1304 struct timer_list monitor_recover;
1341 bool hw_ready; 1305 bool hw_ready;
1342 /*For 3945*/
1343#define IWL_DEFAULT_TX_POWER 0x0F
1344
1345 struct iwl3945_notif_statistics statistics_39;
1346
1347 u32 sta_supp_rates;
1348 1306
1349 struct iwl_event_log event_log; 1307 struct iwl_event_log event_log;
1350}; /*iwl_priv */ 1308}; /*iwl_priv */
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 36580d8d8b8d..f469aa92316a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -35,6 +35,7 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8);
35EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); 35EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32);
36EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); 36EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); 37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_tx);
38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); 39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); 40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); 41EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 4e1ba824dc50..cb6d50b78140 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -188,19 +188,19 @@ struct iwl_eeprom_enhanced_txpwr {
188/* 5000 regulatory - indirect access */ 188/* 5000 regulatory - indirect access */
189#define EEPROM_5000_REG_SKU_ID ((0x02)\ 189#define EEPROM_5000_REG_SKU_ID ((0x02)\
190 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 4 bytes */ 190 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 4 bytes */
191#define EEPROM_5000_REG_BAND_1_CHANNELS ((0x08)\ 191#define EEPROM_REG_BAND_1_CHANNELS ((0x08)\
192 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */ 192 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */
193#define EEPROM_5000_REG_BAND_2_CHANNELS ((0x26)\ 193#define EEPROM_REG_BAND_2_CHANNELS ((0x26)\
194 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 26 bytes */ 194 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 26 bytes */
195#define EEPROM_5000_REG_BAND_3_CHANNELS ((0x42)\ 195#define EEPROM_REG_BAND_3_CHANNELS ((0x42)\
196 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ 196 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
197#define EEPROM_5000_REG_BAND_4_CHANNELS ((0x5C)\ 197#define EEPROM_REG_BAND_4_CHANNELS ((0x5C)\
198 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ 198 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */
199#define EEPROM_5000_REG_BAND_5_CHANNELS ((0x74)\ 199#define EEPROM_REG_BAND_5_CHANNELS ((0x74)\
200 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 12 bytes */ 200 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 12 bytes */
201#define EEPROM_5000_REG_BAND_24_HT40_CHANNELS ((0x82)\ 201#define EEPROM_REG_BAND_24_HT40_CHANNELS ((0x82)\
202 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ 202 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
203#define EEPROM_5000_REG_BAND_52_HT40_CHANNELS ((0x92)\ 203#define EEPROM_REG_BAND_52_HT40_CHANNELS ((0x92)\
204 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ 204 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */
205 205
206/* 6000 and up regulatory tx power - indirect access */ 206/* 6000 and up regulatory tx power - indirect access */
@@ -261,12 +261,15 @@ struct iwl_eeprom_enhanced_txpwr {
261#define EEPROM_5050_EEPROM_VERSION (0x21E) 261#define EEPROM_5050_EEPROM_VERSION (0x21E)
262 262
263/* 1000 Specific */ 263/* 1000 Specific */
264#define EEPROM_1000_TX_POWER_VERSION (4)
264#define EEPROM_1000_EEPROM_VERSION (0x15C) 265#define EEPROM_1000_EEPROM_VERSION (0x15C)
265 266
266/* 6x00 Specific */ 267/* 6x00 Specific */
268#define EEPROM_6000_TX_POWER_VERSION (4)
267#define EEPROM_6000_EEPROM_VERSION (0x434) 269#define EEPROM_6000_EEPROM_VERSION (0x434)
268 270
269/* 6x50 Specific */ 271/* 6x50 Specific */
272#define EEPROM_6050_TX_POWER_VERSION (4)
270#define EEPROM_6050_EEPROM_VERSION (0x532) 273#define EEPROM_6050_EEPROM_VERSION (0x532)
271 274
272/* OTP */ 275/* OTP */
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 73681c4fefe7..51f89e7ba681 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -169,7 +169,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
169 mutex_lock(&priv->sync_cmd_mutex); 169 mutex_lock(&priv->sync_cmd_mutex);
170 170
171 set_bit(STATUS_HCMD_ACTIVE, &priv->status); 171 set_bit(STATUS_HCMD_ACTIVE, &priv->status);
172 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s \n", 172 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
173 get_cmd_string(cmd->id)); 173 get_cmd_string(cmd->id));
174 174
175 cmd_idx = iwl_enqueue_hcmd(priv, cmd); 175 cmd_idx = iwl_enqueue_hcmd(priv, cmd);
@@ -191,7 +191,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
191 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 191 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
192 192
193 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 193 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
194 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n", 194 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
195 get_cmd_string(cmd->id)); 195 get_cmd_string(cmd->id));
196 ret = -ETIMEDOUT; 196 ret = -ETIMEDOUT;
197 goto cancel; 197 goto cancel;
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 51a67fb2e185..3ff6b9d25a10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -31,6 +31,9 @@
31#define __iwl_helpers_h__ 31#define __iwl_helpers_h__
32 32
33#include <linux/ctype.h> 33#include <linux/ctype.h>
34#include <net/mac80211.h>
35
36#include "iwl-io.h"
34 37
35#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) 38#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
36 39
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index c719baf2585a..4f54a5f71cd5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -297,7 +297,7 @@ static inline u32 __iwl_read_direct32(const char *f, u32 l,
297 struct iwl_priv *priv, u32 reg) 297 struct iwl_priv *priv, u32 reg)
298{ 298{
299 u32 value = _iwl_read_direct32(priv, reg); 299 u32 value = _iwl_read_direct32(priv, reg);
300 IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value, 300 IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value,
301 f, l); 301 f, l);
302 return value; 302 return value;
303} 303}
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index a6f9c918aabc..db5bfcb036ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -46,7 +46,7 @@
46static int led_mode; 46static int led_mode;
47module_param(led_mode, int, S_IRUGO); 47module_param(led_mode, int, S_IRUGO);
48MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), " 48MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), "
49 "(default 0)\n"); 49 "(default 0)");
50 50
51 51
52static const struct { 52static const struct {
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 1a1a9f081cc7..2655dbdc8175 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -383,10 +383,10 @@ EXPORT_SYMBOL(iwl_ht_enabled);
383 383
384bool iwl_within_ct_kill_margin(struct iwl_priv *priv) 384bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
385{ 385{
386 s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */ 386 s32 temp = priv->temperature; /* degrees CELSIUS except specified */
387 bool within_margin = false; 387 bool within_margin = false;
388 388
389 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) 389 if (priv->cfg->temperature_kelvin)
390 temp = KELVIN_TO_CELSIUS(priv->temperature); 390 temp = KELVIN_TO_CELSIUS(priv->temperature);
391 391
392 if (!priv->thermal_throttle.advanced_tt) 392 if (!priv->thermal_throttle.advanced_tt)
@@ -839,12 +839,12 @@ EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
839static void iwl_bg_tt_work(struct work_struct *work) 839static void iwl_bg_tt_work(struct work_struct *work)
840{ 840{
841 struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); 841 struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
842 s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */ 842 s32 temp = priv->temperature; /* degrees CELSIUS except specified */
843 843
844 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 844 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
845 return; 845 return;
846 846
847 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) 847 if (priv->cfg->temperature_kelvin)
848 temp = KELVIN_TO_CELSIUS(priv->temperature); 848 temp = KELVIN_TO_CELSIUS(priv->temperature);
849 849
850 if (!priv->thermal_throttle.advanced_tt) 850 if (!priv->thermal_throttle.advanced_tt)
@@ -874,7 +874,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
874 int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); 874 int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
875 struct iwl_tt_trans *transaction; 875 struct iwl_tt_trans *transaction;
876 876
877 IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling \n"); 877 IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n");
878 878
879 memset(tt, 0, sizeof(struct iwl_tt_mgmt)); 879 memset(tt, 0, sizeof(struct iwl_tt_mgmt));
880 880
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index d2d2a9174900..5944de7a98a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -254,7 +254,7 @@
254 * device. A queue maps to only one (selectable by driver) Tx DMA channel, 254 * device. A queue maps to only one (selectable by driver) Tx DMA channel,
255 * but one DMA channel may take input from several queues. 255 * but one DMA channel may take input from several queues.
256 * 256 *
257 * Tx DMA channels have dedicated purposes. For 4965, they are used as follows 257 * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows
258 * (cf. default_queue_to_tx_fifo in iwl-4965.c): 258 * (cf. default_queue_to_tx_fifo in iwl-4965.c):
259 * 259 *
260 * 0 -- EDCA BK (background) frames, lowest priority 260 * 0 -- EDCA BK (background) frames, lowest priority
@@ -262,20 +262,20 @@
262 * 2 -- EDCA VI (video) frames, higher priority 262 * 2 -- EDCA VI (video) frames, higher priority
263 * 3 -- EDCA VO (voice) and management frames, highest priority 263 * 3 -- EDCA VO (voice) and management frames, highest priority
264 * 4 -- Commands (e.g. RXON, etc.) 264 * 4 -- Commands (e.g. RXON, etc.)
265 * 5 -- HCCA short frames 265 * 5 -- unused (HCCA)
266 * 6 -- HCCA long frames 266 * 6 -- unused (HCCA)
267 * 7 -- not used by driver (device-internal only) 267 * 7 -- not used by driver (device-internal only)
268 * 268 *
269 * For 5000 series and up, they are used slightly differently 269 * For 5000 series and up, they are used differently
270 * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): 270 * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c):
271 * 271 *
272 * 0 -- EDCA BK (background) frames, lowest priority 272 * 0 -- EDCA BK (background) frames, lowest priority
273 * 1 -- EDCA BE (best effort) frames, normal priority 273 * 1 -- EDCA BE (best effort) frames, normal priority
274 * 2 -- EDCA VI (video) frames, higher priority 274 * 2 -- EDCA VI (video) frames, higher priority
275 * 3 -- EDCA VO (voice) and management frames, highest priority 275 * 3 -- EDCA VO (voice) and management frames, highest priority
276 * 4 -- (TBD) 276 * 4 -- unused
277 * 5 -- HCCA short frames 277 * 5 -- unused
278 * 6 -- HCCA long frames 278 * 6 -- unused
279 * 7 -- Commands 279 * 7 -- Commands
280 * 280 *
281 * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. 281 * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6.
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index df257bc15f49..1dff14a67b2c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -162,197 +162,6 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
162 spin_unlock_irqrestore(&q->lock, flags); 162 spin_unlock_irqrestore(&q->lock, flags);
163} 163}
164EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); 164EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr);
165/**
166 * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
167 */
168static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv,
169 dma_addr_t dma_addr)
170{
171 return cpu_to_le32((u32)(dma_addr >> 8));
172}
173
174/**
175 * iwl_rx_queue_restock - refill RX queue from pre-allocated pool
176 *
177 * If there are slots in the RX queue that need to be restocked,
178 * and we have free pre-allocated buffers, fill the ranks as much
179 * as we can, pulling from rx_free.
180 *
181 * This moves the 'write' index forward to catch up with 'processed', and
182 * also updates the memory address in the firmware to reference the new
183 * target buffer.
184 */
185void iwl_rx_queue_restock(struct iwl_priv *priv)
186{
187 struct iwl_rx_queue *rxq = &priv->rxq;
188 struct list_head *element;
189 struct iwl_rx_mem_buffer *rxb;
190 unsigned long flags;
191 int write;
192
193 spin_lock_irqsave(&rxq->lock, flags);
194 write = rxq->write & ~0x7;
195 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
196 /* Get next free Rx buffer, remove from free list */
197 element = rxq->rx_free.next;
198 rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
199 list_del(element);
200
201 /* Point to Rx buffer via next RBD in circular buffer */
202 rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->page_dma);
203 rxq->queue[rxq->write] = rxb;
204 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
205 rxq->free_count--;
206 }
207 spin_unlock_irqrestore(&rxq->lock, flags);
208 /* If the pre-allocated buffer pool is dropping low, schedule to
209 * refill it */
210 if (rxq->free_count <= RX_LOW_WATERMARK)
211 queue_work(priv->workqueue, &priv->rx_replenish);
212
213
214 /* If we've added more space for the firmware to place data, tell it.
215 * Increment device's write pointer in multiples of 8. */
216 if (rxq->write_actual != (rxq->write & ~0x7)) {
217 spin_lock_irqsave(&rxq->lock, flags);
218 rxq->need_update = 1;
219 spin_unlock_irqrestore(&rxq->lock, flags);
220 iwl_rx_queue_update_write_ptr(priv, rxq);
221 }
222}
223EXPORT_SYMBOL(iwl_rx_queue_restock);
224
225
226/**
227 * iwl_rx_replenish - Move all used packet from rx_used to rx_free
228 *
229 * When moving to rx_free an SKB is allocated for the slot.
230 *
231 * Also restock the Rx queue via iwl_rx_queue_restock.
232 * This is called as a scheduled work item (except for during initialization)
233 */
234void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
235{
236 struct iwl_rx_queue *rxq = &priv->rxq;
237 struct list_head *element;
238 struct iwl_rx_mem_buffer *rxb;
239 struct page *page;
240 unsigned long flags;
241 gfp_t gfp_mask = priority;
242
243 while (1) {
244 spin_lock_irqsave(&rxq->lock, flags);
245 if (list_empty(&rxq->rx_used)) {
246 spin_unlock_irqrestore(&rxq->lock, flags);
247 return;
248 }
249 spin_unlock_irqrestore(&rxq->lock, flags);
250
251 if (rxq->free_count > RX_LOW_WATERMARK)
252 gfp_mask |= __GFP_NOWARN;
253
254 if (priv->hw_params.rx_page_order > 0)
255 gfp_mask |= __GFP_COMP;
256
257 /* Alloc a new receive buffer */
258 page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
259 if (!page) {
260 if (net_ratelimit())
261 IWL_DEBUG_INFO(priv, "alloc_pages failed, "
262 "order: %d\n",
263 priv->hw_params.rx_page_order);
264
265 if ((rxq->free_count <= RX_LOW_WATERMARK) &&
266 net_ratelimit())
267 IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n",
268 priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL",
269 rxq->free_count);
270 /* We don't reschedule replenish work here -- we will
271 * call the restock method and if it still needs
272 * more buffers it will schedule replenish */
273 return;
274 }
275
276 spin_lock_irqsave(&rxq->lock, flags);
277
278 if (list_empty(&rxq->rx_used)) {
279 spin_unlock_irqrestore(&rxq->lock, flags);
280 __free_pages(page, priv->hw_params.rx_page_order);
281 return;
282 }
283 element = rxq->rx_used.next;
284 rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
285 list_del(element);
286
287 spin_unlock_irqrestore(&rxq->lock, flags);
288
289 rxb->page = page;
290 /* Get physical address of the RB */
291 rxb->page_dma = pci_map_page(priv->pci_dev, page, 0,
292 PAGE_SIZE << priv->hw_params.rx_page_order,
293 PCI_DMA_FROMDEVICE);
294 /* dma address must be no more than 36 bits */
295 BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
296 /* and also 256 byte aligned! */
297 BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
298
299 spin_lock_irqsave(&rxq->lock, flags);
300
301 list_add_tail(&rxb->list, &rxq->rx_free);
302 rxq->free_count++;
303 priv->alloc_rxb_page++;
304
305 spin_unlock_irqrestore(&rxq->lock, flags);
306 }
307}
308
309void iwl_rx_replenish(struct iwl_priv *priv)
310{
311 unsigned long flags;
312
313 iwl_rx_allocate(priv, GFP_KERNEL);
314
315 spin_lock_irqsave(&priv->lock, flags);
316 iwl_rx_queue_restock(priv);
317 spin_unlock_irqrestore(&priv->lock, flags);
318}
319EXPORT_SYMBOL(iwl_rx_replenish);
320
321void iwl_rx_replenish_now(struct iwl_priv *priv)
322{
323 iwl_rx_allocate(priv, GFP_ATOMIC);
324
325 iwl_rx_queue_restock(priv);
326}
327EXPORT_SYMBOL(iwl_rx_replenish_now);
328
329
330/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
331 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
332 * This free routine walks the list of POOL entries and if SKB is set to
333 * non NULL it is unmapped and freed
334 */
335void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
336{
337 int i;
338 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
339 if (rxq->pool[i].page != NULL) {
340 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
341 PAGE_SIZE << priv->hw_params.rx_page_order,
342 PCI_DMA_FROMDEVICE);
343 __iwl_free_pages(priv, rxq->pool[i].page);
344 rxq->pool[i].page = NULL;
345 }
346 }
347
348 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
349 rxq->dma_addr);
350 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
351 rxq->rb_stts, rxq->rb_stts_dma);
352 rxq->bd = NULL;
353 rxq->rb_stts = NULL;
354}
355EXPORT_SYMBOL(iwl_rx_queue_free);
356 165
357int iwl_rx_queue_alloc(struct iwl_priv *priv) 166int iwl_rx_queue_alloc(struct iwl_priv *priv)
358{ 167{
@@ -395,98 +204,6 @@ err_bd:
395} 204}
396EXPORT_SYMBOL(iwl_rx_queue_alloc); 205EXPORT_SYMBOL(iwl_rx_queue_alloc);
397 206
398void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
399{
400 unsigned long flags;
401 int i;
402 spin_lock_irqsave(&rxq->lock, flags);
403 INIT_LIST_HEAD(&rxq->rx_free);
404 INIT_LIST_HEAD(&rxq->rx_used);
405 /* Fill the rx_used queue with _all_ of the Rx buffers */
406 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
407 /* In the reset function, these buffers may have been allocated
408 * to an SKB, so we need to unmap and free potential storage */
409 if (rxq->pool[i].page != NULL) {
410 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
411 PAGE_SIZE << priv->hw_params.rx_page_order,
412 PCI_DMA_FROMDEVICE);
413 __iwl_free_pages(priv, rxq->pool[i].page);
414 rxq->pool[i].page = NULL;
415 }
416 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
417 }
418
419 /* Set us so that we have processed and used all buffers, but have
420 * not restocked the Rx queue with fresh buffers */
421 rxq->read = rxq->write = 0;
422 rxq->write_actual = 0;
423 rxq->free_count = 0;
424 spin_unlock_irqrestore(&rxq->lock, flags);
425}
426
427int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
428{
429 u32 rb_size;
430 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
431 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
432
433 if (!priv->cfg->use_isr_legacy)
434 rb_timeout = RX_RB_TIMEOUT;
435
436 if (priv->cfg->mod_params->amsdu_size_8K)
437 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
438 else
439 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
440
441 /* Stop Rx DMA */
442 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
443
444 /* Reset driver's Rx queue write index */
445 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
446
447 /* Tell device where to find RBD circular buffer in DRAM */
448 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
449 (u32)(rxq->dma_addr >> 8));
450
451 /* Tell device where in DRAM to update its Rx status */
452 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
453 rxq->rb_stts_dma >> 4);
454
455 /* Enable Rx DMA
456 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
457 * the credit mechanism in 5000 HW RX FIFO
458 * Direct rx interrupts to hosts
459 * Rx buffer size 4 or 8k
460 * RB timeout 0x10
461 * 256 RBDs
462 */
463 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
464 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
465 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
466 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
467 FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
468 rb_size|
469 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
470 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
471
472 /* Set interrupt coalescing timer to default (2048 usecs) */
473 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
474
475 return 0;
476}
477
478int iwl_rxq_stop(struct iwl_priv *priv)
479{
480
481 /* stop Rx DMA */
482 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
483 iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
484 FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
485
486 return 0;
487}
488EXPORT_SYMBOL(iwl_rxq_stop);
489
490void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 207void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
491 struct iwl_rx_mem_buffer *rxb) 208 struct iwl_rx_mem_buffer *rxb)
492 209
@@ -542,6 +259,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
542 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; 259 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
543 int bcn_silence_c = 260 int bcn_silence_c =
544 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; 261 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
262 int last_rx_noise;
545 263
546 if (bcn_silence_a) { 264 if (bcn_silence_a) {
547 total_silence += bcn_silence_a; 265 total_silence += bcn_silence_a;
@@ -558,13 +276,13 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
558 276
559 /* Average among active antennas */ 277 /* Average among active antennas */
560 if (num_active_rx) 278 if (num_active_rx)
561 priv->last_rx_noise = (total_silence / num_active_rx) - 107; 279 last_rx_noise = (total_silence / num_active_rx) - 107;
562 else 280 else
563 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 281 last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
564 282
565 IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", 283 IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
566 bcn_silence_a, bcn_silence_b, bcn_silence_c, 284 bcn_silence_a, bcn_silence_b, bcn_silence_c,
567 priv->last_rx_noise); 285 last_rx_noise);
568} 286}
569 287
570#ifdef CONFIG_IWLWIFI_DEBUG 288#ifdef CONFIG_IWLWIFI_DEBUG
@@ -616,29 +334,20 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
616 334
617#define REG_RECALIB_PERIOD (60) 335#define REG_RECALIB_PERIOD (60)
618 336
619#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n" 337/**
620void iwl_rx_statistics(struct iwl_priv *priv, 338 * iwl_good_plcp_health - checks for plcp error.
621 struct iwl_rx_mem_buffer *rxb) 339 *
340 * When the plcp error is exceeding the thresholds, reset the radio
341 * to improve the throughput.
342 */
343bool iwl_good_plcp_health(struct iwl_priv *priv,
344 struct iwl_rx_packet *pkt)
622{ 345{
623 int change; 346 bool rc = true;
624 struct iwl_rx_packet *pkt = rxb_addr(rxb);
625 int combined_plcp_delta; 347 int combined_plcp_delta;
626 unsigned int plcp_msec; 348 unsigned int plcp_msec;
627 unsigned long plcp_received_jiffies; 349 unsigned long plcp_received_jiffies;
628 350
629 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
630 (int)sizeof(priv->statistics),
631 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
632
633 change = ((priv->statistics.general.temperature !=
634 pkt->u.stats.general.temperature) ||
635 ((priv->statistics.flag &
636 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
637 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
638
639#ifdef CONFIG_IWLWIFI_DEBUG
640 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
641#endif
642 /* 351 /*
643 * check for plcp_err and trigger radio reset if it exceeds 352 * check for plcp_err and trigger radio reset if it exceeds
644 * the plcp error threshold plcp_delta. 353 * the plcp error threshold plcp_delta.
@@ -659,11 +368,11 @@ void iwl_rx_statistics(struct iwl_priv *priv,
659 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err)); 368 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
660 369
661 if ((combined_plcp_delta > 0) && 370 if ((combined_plcp_delta > 0) &&
662 ((combined_plcp_delta * 100) / plcp_msec) > 371 ((combined_plcp_delta * 100) / plcp_msec) >
663 priv->cfg->plcp_delta_threshold) { 372 priv->cfg->plcp_delta_threshold) {
664 /* 373 /*
665 * if plcp_err exceed the threshold, the following 374 * if plcp_err exceed the threshold,
666 * data is printed in csv format: 375 * the following data is printed in csv format:
667 * Text: plcp_err exceeded %d, 376 * Text: plcp_err exceeded %d,
668 * Received ofdm.plcp_err, 377 * Received ofdm.plcp_err,
669 * Current ofdm.plcp_err, 378 * Current ofdm.plcp_err,
@@ -672,22 +381,73 @@ void iwl_rx_statistics(struct iwl_priv *priv,
672 * combined_plcp_delta, 381 * combined_plcp_delta,
673 * plcp_msec 382 * plcp_msec
674 */ 383 */
675 IWL_DEBUG_RADIO(priv, PLCP_MSG, 384 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
385 "%u, %u, %u, %u, %d, %u mSecs\n",
676 priv->cfg->plcp_delta_threshold, 386 priv->cfg->plcp_delta_threshold,
677 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), 387 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
678 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err), 388 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
679 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), 389 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
680 le32_to_cpu( 390 le32_to_cpu(
681 priv->statistics.rx.ofdm_ht.plcp_err), 391 priv->statistics.rx.ofdm_ht.plcp_err),
682 combined_plcp_delta, plcp_msec); 392 combined_plcp_delta, plcp_msec);
393 rc = false;
394 }
395 }
396 return rc;
397}
398EXPORT_SYMBOL(iwl_good_plcp_health);
683 399
684 /* 400static void iwl_recover_from_statistics(struct iwl_priv *priv,
685 * Reset the RF radio due to the high plcp 401 struct iwl_rx_packet *pkt)
686 * error rate 402{
687 */ 403 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
688 iwl_force_reset(priv, IWL_RF_RESET); 404 return;
405 if (iwl_is_associated(priv)) {
406 if (priv->cfg->ops->lib->check_ack_health) {
407 if (!priv->cfg->ops->lib->check_ack_health(
408 priv, pkt)) {
409 /*
410 * low ack count detected
411 * restart Firmware
412 */
413 IWL_ERR(priv, "low ack count detected, "
414 "restart firmware\n");
415 iwl_force_reset(priv, IWL_FW_RESET);
416 }
417 } else if (priv->cfg->ops->lib->check_plcp_health) {
418 if (!priv->cfg->ops->lib->check_plcp_health(
419 priv, pkt)) {
420 /*
421 * high plcp error detected
422 * reset Radio
423 */
424 iwl_force_reset(priv, IWL_RF_RESET);
425 }
689 } 426 }
690 } 427 }
428}
429
430void iwl_rx_statistics(struct iwl_priv *priv,
431 struct iwl_rx_mem_buffer *rxb)
432{
433 int change;
434 struct iwl_rx_packet *pkt = rxb_addr(rxb);
435
436
437 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
438 (int)sizeof(priv->statistics),
439 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
440
441 change = ((priv->statistics.general.temperature !=
442 pkt->u.stats.general.temperature) ||
443 ((priv->statistics.flag &
444 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
445 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
446
447#ifdef CONFIG_IWLWIFI_DEBUG
448 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
449#endif
450 iwl_recover_from_statistics(priv, pkt);
691 451
692 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 452 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
693 453
@@ -730,139 +490,6 @@ void iwl_reply_statistics(struct iwl_priv *priv,
730} 490}
731EXPORT_SYMBOL(iwl_reply_statistics); 491EXPORT_SYMBOL(iwl_reply_statistics);
732 492
733/* Calc max signal level (dBm) among 3 possible receivers */
734static inline int iwl_calc_rssi(struct iwl_priv *priv,
735 struct iwl_rx_phy_res *rx_resp)
736{
737 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
738}
739
740#ifdef CONFIG_IWLWIFI_DEBUG
741/**
742 * iwl_dbg_report_frame - dump frame to syslog during debug sessions
743 *
744 * You may hack this function to show different aspects of received frames,
745 * including selective frame dumps.
746 * group100 parameter selects whether to show 1 out of 100 good data frames.
747 * All beacon and probe response frames are printed.
748 */
749static void iwl_dbg_report_frame(struct iwl_priv *priv,
750 struct iwl_rx_phy_res *phy_res, u16 length,
751 struct ieee80211_hdr *header, int group100)
752{
753 u32 to_us;
754 u32 print_summary = 0;
755 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
756 u32 hundred = 0;
757 u32 dataframe = 0;
758 __le16 fc;
759 u16 seq_ctl;
760 u16 channel;
761 u16 phy_flags;
762 u32 rate_n_flags;
763 u32 tsf_low;
764 int rssi;
765
766 if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX)))
767 return;
768
769 /* MAC header */
770 fc = header->frame_control;
771 seq_ctl = le16_to_cpu(header->seq_ctrl);
772
773 /* metadata */
774 channel = le16_to_cpu(phy_res->channel);
775 phy_flags = le16_to_cpu(phy_res->phy_flags);
776 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
777
778 /* signal statistics */
779 rssi = iwl_calc_rssi(priv, phy_res);
780 tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
781
782 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
783
784 /* if data frame is to us and all is good,
785 * (optionally) print summary for only 1 out of every 100 */
786 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
787 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
788 dataframe = 1;
789 if (!group100)
790 print_summary = 1; /* print each frame */
791 else if (priv->framecnt_to_us < 100) {
792 priv->framecnt_to_us++;
793 print_summary = 0;
794 } else {
795 priv->framecnt_to_us = 0;
796 print_summary = 1;
797 hundred = 1;
798 }
799 } else {
800 /* print summary for all other frames */
801 print_summary = 1;
802 }
803
804 if (print_summary) {
805 char *title;
806 int rate_idx;
807 u32 bitrate;
808
809 if (hundred)
810 title = "100Frames";
811 else if (ieee80211_has_retry(fc))
812 title = "Retry";
813 else if (ieee80211_is_assoc_resp(fc))
814 title = "AscRsp";
815 else if (ieee80211_is_reassoc_resp(fc))
816 title = "RasRsp";
817 else if (ieee80211_is_probe_resp(fc)) {
818 title = "PrbRsp";
819 print_dump = 1; /* dump frame contents */
820 } else if (ieee80211_is_beacon(fc)) {
821 title = "Beacon";
822 print_dump = 1; /* dump frame contents */
823 } else if (ieee80211_is_atim(fc))
824 title = "ATIM";
825 else if (ieee80211_is_auth(fc))
826 title = "Auth";
827 else if (ieee80211_is_deauth(fc))
828 title = "DeAuth";
829 else if (ieee80211_is_disassoc(fc))
830 title = "DisAssoc";
831 else
832 title = "Frame";
833
834 rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
835 if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
836 bitrate = 0;
837 WARN_ON_ONCE(1);
838 } else {
839 bitrate = iwl_rates[rate_idx].ieee / 2;
840 }
841
842 /* print frame summary.
843 * MAC addresses show just the last byte (for brevity),
844 * but you can hack it to show more, if you'd like to. */
845 if (dataframe)
846 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
847 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
848 title, le16_to_cpu(fc), header->addr1[5],
849 length, rssi, channel, bitrate);
850 else {
851 /* src/dst addresses assume managed mode */
852 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
853 "len=%u, rssi=%d, tim=%lu usec, "
854 "phy=0x%02x, chnl=%d\n",
855 title, le16_to_cpu(fc), header->addr1[5],
856 header->addr3[5], length, rssi,
857 tsf_low - priv->scan_start_tsf,
858 phy_flags, channel);
859 }
860 }
861 if (print_dump)
862 iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
863}
864#endif
865
866/* 493/*
867 * returns non-zero if packet should be dropped 494 * returns non-zero if packet should be dropped
868 */ 495 */
@@ -910,305 +537,3 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
910 return 0; 537 return 0;
911} 538}
912EXPORT_SYMBOL(iwl_set_decrypted_flag); 539EXPORT_SYMBOL(iwl_set_decrypted_flag);
913
914static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
915{
916 u32 decrypt_out = 0;
917
918 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
919 RX_RES_STATUS_STATION_FOUND)
920 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
921 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
922
923 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
924
925 /* packet was not encrypted */
926 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
927 RX_RES_STATUS_SEC_TYPE_NONE)
928 return decrypt_out;
929
930 /* packet was encrypted with unknown alg */
931 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
932 RX_RES_STATUS_SEC_TYPE_ERR)
933 return decrypt_out;
934
935 /* decryption was not done in HW */
936 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
937 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
938 return decrypt_out;
939
940 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
941
942 case RX_RES_STATUS_SEC_TYPE_CCMP:
943 /* alg is CCM: check MIC only */
944 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
945 /* Bad MIC */
946 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
947 else
948 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
949
950 break;
951
952 case RX_RES_STATUS_SEC_TYPE_TKIP:
953 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
954 /* Bad TTAK */
955 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
956 break;
957 }
958 /* fall through if TTAK OK */
959 default:
960 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
961 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
962 else
963 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
964 break;
965 };
966
967 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
968 decrypt_in, decrypt_out);
969
970 return decrypt_out;
971}
972
973static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
974 struct ieee80211_hdr *hdr,
975 u16 len,
976 u32 ampdu_status,
977 struct iwl_rx_mem_buffer *rxb,
978 struct ieee80211_rx_status *stats)
979{
980 struct sk_buff *skb;
981 int ret = 0;
982 __le16 fc = hdr->frame_control;
983
984 /* We only process data packets if the interface is open */
985 if (unlikely(!priv->is_open)) {
986 IWL_DEBUG_DROP_LIMIT(priv,
987 "Dropping packet while interface is not open.\n");
988 return;
989 }
990
991 /* In case of HW accelerated crypto and bad decryption, drop */
992 if (!priv->cfg->mod_params->sw_crypto &&
993 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
994 return;
995
996 skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
997 if (!skb) {
998 IWL_ERR(priv, "alloc_skb failed\n");
999 return;
1000 }
1001
1002 skb_reserve(skb, IWL_LINK_HDR_MAX);
1003 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
1004
1005 /* mac80211 currently doesn't support paged SKB. Convert it to
1006 * linear SKB for management frame and data frame requires
1007 * software decryption or software defragementation. */
1008 if (ieee80211_is_mgmt(fc) ||
1009 ieee80211_has_protected(fc) ||
1010 ieee80211_has_morefrags(fc) ||
1011 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG ||
1012 (ieee80211_is_data_qos(fc) &&
1013 *ieee80211_get_qos_ctl(hdr) &
1014 IEEE80211_QOS_CONTROL_A_MSDU_PRESENT))
1015 ret = skb_linearize(skb);
1016 else
1017 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
1018 0 : -ENOMEM;
1019
1020 if (ret) {
1021 kfree_skb(skb);
1022 goto out;
1023 }
1024
1025 /*
1026 * XXX: We cannot touch the page and its virtual memory (hdr) after
1027 * here. It might have already been freed by the above skb change.
1028 */
1029
1030 iwl_update_stats(priv, false, fc, len);
1031 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
1032
1033 ieee80211_rx(priv->hw, skb);
1034 out:
1035 priv->alloc_rxb_page--;
1036 rxb->page = NULL;
1037}
1038
1039/* This is necessary only for a number of statistics, see the caller. */
1040static int iwl_is_network_packet(struct iwl_priv *priv,
1041 struct ieee80211_hdr *header)
1042{
1043 /* Filter incoming packets to determine if they are targeted toward
1044 * this network, discarding packets coming from ourselves */
1045 switch (priv->iw_mode) {
1046 case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */
1047 /* packets to our IBSS update information */
1048 return !compare_ether_addr(header->addr3, priv->bssid);
1049 case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */
1050 /* packets to our IBSS update information */
1051 return !compare_ether_addr(header->addr2, priv->bssid);
1052 default:
1053 return 1;
1054 }
1055}
1056
1057/* Called for REPLY_RX (legacy ABG frames), or
1058 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
1059void iwl_rx_reply_rx(struct iwl_priv *priv,
1060 struct iwl_rx_mem_buffer *rxb)
1061{
1062 struct ieee80211_hdr *header;
1063 struct ieee80211_rx_status rx_status;
1064 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1065 struct iwl_rx_phy_res *phy_res;
1066 __le32 rx_pkt_status;
1067 struct iwl4965_rx_mpdu_res_start *amsdu;
1068 u32 len;
1069 u32 ampdu_status;
1070 u32 rate_n_flags;
1071
1072 /**
1073 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
1074 * REPLY_RX: physical layer info is in this buffer
1075 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
1076 * command and cached in priv->last_phy_res
1077 *
1078 * Here we set up local variables depending on which command is
1079 * received.
1080 */
1081 if (pkt->hdr.cmd == REPLY_RX) {
1082 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
1083 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
1084 + phy_res->cfg_phy_cnt);
1085
1086 len = le16_to_cpu(phy_res->byte_count);
1087 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
1088 phy_res->cfg_phy_cnt + len);
1089 ampdu_status = le32_to_cpu(rx_pkt_status);
1090 } else {
1091 if (!priv->last_phy_res[0]) {
1092 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1093 return;
1094 }
1095 phy_res = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
1096 amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
1097 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1098 len = le16_to_cpu(amsdu->byte_count);
1099 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1100 ampdu_status = iwl_translate_rx_status(priv,
1101 le32_to_cpu(rx_pkt_status));
1102 }
1103
1104 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1105 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1106 phy_res->cfg_phy_cnt);
1107 return;
1108 }
1109
1110 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1111 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1112 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1113 le32_to_cpu(rx_pkt_status));
1114 return;
1115 }
1116
1117 /* This will be used in several places later */
1118 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1119
1120 /* rx_status carries information about the packet to mac80211 */
1121 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1122 rx_status.freq =
1123 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
1124 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1125 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1126 rx_status.rate_idx =
1127 iwl_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1128 rx_status.flag = 0;
1129
1130 /* TSF isn't reliable. In order to allow smooth user experience,
1131 * this W/A doesn't propagate it to the mac80211 */
1132 /*rx_status.flag |= RX_FLAG_TSFT;*/
1133
1134 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1135
1136 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1137 rx_status.signal = iwl_calc_rssi(priv, phy_res);
1138
1139 /* Meaningful noise values are available only from beacon statistics,
1140 * which are gathered only when associated, and indicate noise
1141 * only for the associated network channel ...
1142 * Ignore these noise values while scanning (other channels) */
1143 if (iwl_is_associated(priv) &&
1144 !test_bit(STATUS_SCANNING, &priv->status)) {
1145 rx_status.noise = priv->last_rx_noise;
1146 } else {
1147 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1148 }
1149
1150 /* Reset beacon noise level if not associated. */
1151 if (!iwl_is_associated(priv))
1152 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1153
1154#ifdef CONFIG_IWLWIFI_DEBUG
1155 /* Set "1" to report good data frames in groups of 100 */
1156 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
1157 iwl_dbg_report_frame(priv, phy_res, len, header, 1);
1158#endif
1159 iwl_dbg_log_rx_data_frame(priv, len, header);
1160 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, TSF %llu\n",
1161 rx_status.signal, rx_status.noise,
1162 (unsigned long long)rx_status.mactime);
1163
1164 /*
1165 * "antenna number"
1166 *
1167 * It seems that the antenna field in the phy flags value
1168 * is actually a bit field. This is undefined by radiotap,
1169 * it wants an actual antenna number but I always get "7"
1170 * for most legacy frames I receive indicating that the
1171 * same frame was received on all three RX chains.
1172 *
1173 * I think this field should be removed in favor of a
1174 * new 802.11n radiotap field "RX chains" that is defined
1175 * as a bitmask.
1176 */
1177 rx_status.antenna =
1178 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1179 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1180
1181 /* set the preamble flag if appropriate */
1182 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1183 rx_status.flag |= RX_FLAG_SHORTPRE;
1184
1185 /* Set up the HT phy flags */
1186 if (rate_n_flags & RATE_MCS_HT_MSK)
1187 rx_status.flag |= RX_FLAG_HT;
1188 if (rate_n_flags & RATE_MCS_HT40_MSK)
1189 rx_status.flag |= RX_FLAG_40MHZ;
1190 if (rate_n_flags & RATE_MCS_SGI_MSK)
1191 rx_status.flag |= RX_FLAG_SHORT_GI;
1192
1193 if (iwl_is_network_packet(priv, header)) {
1194 priv->last_rx_rssi = rx_status.signal;
1195 priv->last_beacon_time = priv->ucode_beacon_time;
1196 priv->last_tsf = le64_to_cpu(phy_res->timestamp);
1197 }
1198
1199 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1200 rxb, &rx_status);
1201}
1202EXPORT_SYMBOL(iwl_rx_reply_rx);
1203
1204/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1205 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1206void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
1207 struct iwl_rx_mem_buffer *rxb)
1208{
1209 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1210 priv->last_phy_res[0] = 1;
1211 memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
1212 sizeof(struct iwl_rx_phy_res));
1213}
1214EXPORT_SYMBOL(iwl_rx_reply_rx_phy);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index bd2f7c420563..d817c9c184a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -453,7 +453,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
453 added++; 453 added++;
454 } 454 }
455 455
456 IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added); 456 IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
457 return added; 457 return added;
458} 458}
459 459
@@ -580,7 +580,6 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv)
580out: 580out:
581 return ret; 581 return ret;
582} 582}
583EXPORT_SYMBOL(iwl_internal_short_hw_scan);
584 583
585#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) 584#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
586 585
@@ -665,7 +664,6 @@ static void iwl_bg_request_scan(struct work_struct *data)
665 }; 664 };
666 struct iwl_scan_cmd *scan; 665 struct iwl_scan_cmd *scan;
667 struct ieee80211_conf *conf = NULL; 666 struct ieee80211_conf *conf = NULL;
668 int ret = 0;
669 u32 rate_flags = 0; 667 u32 rate_flags = 0;
670 u16 cmd_len; 668 u16 cmd_len;
671 u16 rx_chain = 0; 669 u16 rx_chain = 0;
@@ -698,7 +696,6 @@ static void iwl_bg_request_scan(struct work_struct *data)
698 if (test_bit(STATUS_SCAN_HW, &priv->status)) { 696 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
699 IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. " 697 IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
700 "Ignoring second request.\n"); 698 "Ignoring second request.\n");
701 ret = -EIO;
702 goto done; 699 goto done;
703 } 700 }
704 701
@@ -731,7 +728,8 @@ static void iwl_bg_request_scan(struct work_struct *data)
731 priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) + 728 priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +
732 IWL_MAX_SCAN_SIZE, GFP_KERNEL); 729 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
733 if (!priv->scan) { 730 if (!priv->scan) {
734 ret = -ENOMEM; 731 IWL_DEBUG_SCAN(priv,
732 "fail to allocate memory for scan\n");
735 goto done; 733 goto done;
736 } 734 }
737 } 735 }
@@ -815,10 +813,11 @@ static void iwl_bg_request_scan(struct work_struct *data)
815 */ 813 */
816 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; 814 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
817 815
818 /* Force use of chains B and C (0x6) for scan Rx for 4965 816 /* Force use of chains B and C (0x6) for scan Rx
819 * Avoid A (0x1) because of its off-channel reception on A-band. 817 * Avoid A (0x1) for the device has off-channel reception
818 * on A-band.
820 */ 819 */
821 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) 820 if (priv->cfg->off_channel_workaround)
822 rx_ant = ANT_BC; 821 rx_ant = ANT_BC;
823 } else { 822 } else {
824 IWL_WARN(priv, "Invalid scan band count\n"); 823 IWL_WARN(priv, "Invalid scan band count\n");
@@ -892,8 +891,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
892 scan->len = cpu_to_le16(cmd.len); 891 scan->len = cpu_to_le16(cmd.len);
893 892
894 set_bit(STATUS_SCAN_HW, &priv->status); 893 set_bit(STATUS_SCAN_HW, &priv->status);
895 ret = iwl_send_cmd_sync(priv, &cmd); 894 if (iwl_send_cmd_sync(priv, &cmd))
896 if (ret)
897 goto done; 895 goto done;
898 896
899 queue_delayed_work(priv->workqueue, &priv->scan_check, 897 queue_delayed_work(priv->workqueue, &priv->scan_check,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 4a6686fa6b36..e34ac0355c75 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -29,14 +29,12 @@
29 29
30#include <net/mac80211.h> 30#include <net/mac80211.h>
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/sched.h>
32 33
33#include "iwl-dev.h" 34#include "iwl-dev.h"
34#include "iwl-core.h" 35#include "iwl-core.h"
35#include "iwl-sta.h" 36#include "iwl-sta.h"
36 37
37#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
38#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
39
40u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) 38u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
41{ 39{
42 int i; 40 int i;
@@ -64,6 +62,19 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
64 addr, priv->num_stations); 62 addr, priv->num_stations);
65 63
66 out: 64 out:
65 /*
66 * It may be possible that more commands interacting with stations
67 * arrive before we completed processing the adding of
68 * station
69 */
70 if (ret != IWL_INVALID_STATION &&
71 (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
72 ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
73 (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
74 IWL_ERR(priv, "Requested station info for sta %d before ready.\n",
75 ret);
76 ret = IWL_INVALID_STATION;
77 }
67 spin_unlock_irqrestore(&priv->sta_lock, flags); 78 spin_unlock_irqrestore(&priv->sta_lock, flags);
68 return ret; 79 return ret;
69} 80}
@@ -132,7 +143,7 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv,
132 sta_id); 143 sta_id);
133 break; 144 break;
134 case ADD_STA_MODIFY_NON_EXIST_STA: 145 case ADD_STA_MODIFY_NON_EXIST_STA:
135 IWL_ERR(priv, "Attempting to modify non-existing station %d \n", 146 IWL_ERR(priv, "Attempting to modify non-existing station %d\n",
136 sta_id); 147 sta_id);
137 break; 148 break;
138 default: 149 default:
@@ -158,13 +169,6 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv,
158 priv->stations[sta_id].sta.mode == 169 priv->stations[sta_id].sta.mode ==
159 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", 170 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
160 addsta->sta.addr); 171 addsta->sta.addr);
161
162 /*
163 * Determine if we wanted to modify or add a station,
164 * if adding a station succeeded we have some more initialization
165 * to do when using station notification. TODO
166 */
167
168 spin_unlock_irqrestore(&priv->sta_lock, flags); 172 spin_unlock_irqrestore(&priv->sta_lock, flags);
169} 173}
170 174
@@ -190,6 +194,10 @@ int iwl_send_add_sta(struct iwl_priv *priv,
190 .flags = flags, 194 .flags = flags,
191 .data = data, 195 .data = data,
192 }; 196 };
197 u8 sta_id = sta->sta.sta_id;
198
199 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
200 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
193 201
194 if (flags & CMD_ASYNC) 202 if (flags & CMD_ASYNC)
195 cmd.callback = iwl_add_sta_callback; 203 cmd.callback = iwl_add_sta_callback;
@@ -263,18 +271,19 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
263} 271}
264 272
265/** 273/**
266 * iwl_add_station - Add station to tables in driver and device 274 * iwl_prep_station - Prepare station information for addition
275 *
276 * should be called with sta_lock held
267 */ 277 */
268u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, 278static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
269 struct ieee80211_sta_ht_cap *ht_info) 279 bool is_ap,
280 struct ieee80211_sta_ht_cap *ht_info)
270{ 281{
271 struct iwl_station_entry *station; 282 struct iwl_station_entry *station;
272 unsigned long flags_spin;
273 int i; 283 int i;
274 int sta_id = IWL_INVALID_STATION; 284 u8 sta_id = IWL_INVALID_STATION;
275 u16 rate; 285 u16 rate;
276 286
277 spin_lock_irqsave(&priv->sta_lock, flags_spin);
278 if (is_ap) 287 if (is_ap)
279 sta_id = IWL_AP_ID; 288 sta_id = IWL_AP_ID;
280 else if (is_broadcast_ether_addr(addr)) 289 else if (is_broadcast_ether_addr(addr))
@@ -292,20 +301,32 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
292 sta_id = i; 301 sta_id = i;
293 } 302 }
294 303
295 /* These two conditions have the same outcome, but keep them separate 304 /*
296 since they have different meanings */ 305 * These two conditions have the same outcome, but keep them
297 if (unlikely(sta_id == IWL_INVALID_STATION)) { 306 * separate
298 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 307 */
308 if (unlikely(sta_id == IWL_INVALID_STATION))
309 return sta_id;
310
311 /*
312 * uCode is not able to deal with multiple requests to add a
313 * station. Keep track if one is in progress so that we do not send
314 * another.
315 */
316 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
317 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
318 sta_id);
299 return sta_id; 319 return sta_id;
300 } 320 }
301 321
302 if (priv->stations[sta_id].used && 322 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
323 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
303 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) { 324 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
304 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 325 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
326 sta_id, addr);
305 return sta_id; 327 return sta_id;
306 } 328 }
307 329
308
309 station = &priv->stations[sta_id]; 330 station = &priv->stations[sta_id];
310 station->used = IWL_STA_DRIVER_ACTIVE; 331 station->used = IWL_STA_DRIVER_ACTIVE;
311 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n", 332 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
@@ -330,86 +351,185 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
330 /* Turn on both antennas for the station... */ 351 /* Turn on both antennas for the station... */
331 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); 352 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
332 353
354 return sta_id;
355
356}
357
358#define STA_WAIT_TIMEOUT (HZ/2)
359
360/**
361 * iwl_add_station_common -
362 */
363int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
364 bool is_ap,
365 struct ieee80211_sta_ht_cap *ht_info,
366 u8 *sta_id_r)
367{
368 struct iwl_station_entry *station;
369 unsigned long flags_spin;
370 int ret = 0;
371 u8 sta_id;
372
373 *sta_id_r = 0;
374 spin_lock_irqsave(&priv->sta_lock, flags_spin);
375 sta_id = iwl_prep_station(priv, addr, is_ap, ht_info);
376 if (sta_id == IWL_INVALID_STATION) {
377 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
378 addr);
379 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
380 return -EINVAL;
381 }
382
383 /*
384 * uCode is not able to deal with multiple requests to add a
385 * station. Keep track if one is in progress so that we do not send
386 * another.
387 */
388 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
389 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
390 sta_id);
391 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
392 return -EEXIST;
393 }
394
395 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
396 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
397 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
398 sta_id, addr);
399 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
400 return -EEXIST;
401 }
402
403 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
404 station = &priv->stations[sta_id];
333 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 405 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
334 406
335 /* Add station to device's station table */ 407 /* Add station to device's station table */
336 iwl_send_add_sta(priv, &station->sta, flags); 408 ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC);
337 return sta_id; 409 if (ret) {
338 410 IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr);
411 spin_lock_irqsave(&priv->sta_lock, flags_spin);
412 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
413 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
414 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
415 }
416 *sta_id_r = sta_id;
417 return ret;
339} 418}
340EXPORT_SYMBOL(iwl_add_station); 419EXPORT_SYMBOL(iwl_add_station_common);
341 420
342static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const u8 *addr) 421static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
343{ 422{
344 unsigned long flags; 423 int i, r;
345 u8 sta_id = iwl_find_station(priv, addr); 424 struct iwl_link_quality_cmd link_cmd = {
425 .reserved1 = 0,
426 };
427 u32 rate_flags;
346 428
347 BUG_ON(sta_id == IWL_INVALID_STATION); 429 /* Set up the rate scaling to start at selected rate, fall back
430 * all the way down to 1M in IEEE order, and then spin on 1M */
431 if (is_ap)
432 r = IWL_RATE_54M_INDEX;
433 else if (priv->band == IEEE80211_BAND_5GHZ)
434 r = IWL_RATE_6M_INDEX;
435 else
436 r = IWL_RATE_1M_INDEX;
348 437
349 IWL_DEBUG_ASSOC(priv, "Removed STA from Ucode: %pM\n", addr); 438 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
439 rate_flags = 0;
440 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
441 rate_flags |= RATE_MCS_CCK_MSK;
350 442
351 spin_lock_irqsave(&priv->sta_lock, flags); 443 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
444 RATE_MCS_ANT_POS;
352 445
353 /* Ucode must be active and driver must be non active */ 446 link_cmd.rs_table[i].rate_n_flags =
354 if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE) 447 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
355 IWL_ERR(priv, "removed non active STA %d\n", sta_id); 448 r = iwl_get_prev_ieee_rate(r);
449 }
356 450
357 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; 451 link_cmd.general_params.single_stream_ant_msk =
452 first_antenna(priv->hw_params.valid_tx_ant);
453 link_cmd.general_params.dual_stream_ant_msk = 3;
454 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
455 link_cmd.agg_params.agg_time_limit =
456 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
358 457
359 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry)); 458 /* Update the rate scaling for control frame Tx to AP */
360 spin_unlock_irqrestore(&priv->sta_lock, flags); 459 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
460
461 iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD,
462 sizeof(link_cmd), &link_cmd);
361} 463}
362 464
363static void iwl_remove_sta_callback(struct iwl_priv *priv, 465/*
364 struct iwl_device_cmd *cmd, 466 * iwl_add_local_stations - Add stations not requested by mac80211
365 struct iwl_rx_packet *pkt) 467 *
468 * This will be either the broadcast station or the bssid station needed by
469 * ad-hoc.
470 *
471 * Function sleeps.
472 */
473int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)
366{ 474{
367 struct iwl_rem_sta_cmd *rm_sta = 475 int ret;
368 (struct iwl_rem_sta_cmd *)cmd->cmd.payload; 476 u8 sta_id;
369 const u8 *addr = rm_sta->addr;
370 477
371 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 478 ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
372 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", 479 if (ret) {
373 pkt->hdr.flags); 480 IWL_ERR(priv, "Unable to add station %pM\n", addr);
374 return; 481 return ret;
375 } 482 }
376 483
377 switch (pkt->u.rem_sta.status) { 484 if (init_rs)
378 case REM_STA_SUCCESS_MSK: 485 /* Set up default rate scaling table in device's station table */
379 iwl_sta_ucode_deactivate(priv, addr); 486 iwl_sta_init_lq(priv, addr, false);
380 break; 487 return 0;
381 default: 488}
382 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n"); 489EXPORT_SYMBOL(iwl_add_local_station);
383 break; 490
384 } 491/**
492 * iwl_sta_ucode_deactivate - deactivate ucode status for a station
493 *
494 * priv->sta_lock must be held
495 */
496static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
497{
498 /* Ucode must be active and driver must be non active */
499 if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
500 IWL_ERR(priv, "removed non active STA %u\n", sta_id);
501
502 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
503
504 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
505 IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id);
385} 506}
386 507
387static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, 508static int iwl_send_remove_station(struct iwl_priv *priv,
388 u8 flags) 509 struct iwl_station_entry *station)
389{ 510{
390 struct iwl_rx_packet *pkt; 511 struct iwl_rx_packet *pkt;
391 int ret; 512 int ret;
392 513
514 unsigned long flags_spin;
393 struct iwl_rem_sta_cmd rm_sta_cmd; 515 struct iwl_rem_sta_cmd rm_sta_cmd;
394 516
395 struct iwl_host_cmd cmd = { 517 struct iwl_host_cmd cmd = {
396 .id = REPLY_REMOVE_STA, 518 .id = REPLY_REMOVE_STA,
397 .len = sizeof(struct iwl_rem_sta_cmd), 519 .len = sizeof(struct iwl_rem_sta_cmd),
398 .flags = flags, 520 .flags = CMD_SYNC,
399 .data = &rm_sta_cmd, 521 .data = &rm_sta_cmd,
400 }; 522 };
401 523
402 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 524 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
403 rm_sta_cmd.num_sta = 1; 525 rm_sta_cmd.num_sta = 1;
404 memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN); 526 memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN);
527
528 cmd.flags |= CMD_WANT_SKB;
405 529
406 if (flags & CMD_ASYNC)
407 cmd.callback = iwl_remove_sta_callback;
408 else
409 cmd.flags |= CMD_WANT_SKB;
410 ret = iwl_send_cmd(priv, &cmd); 530 ret = iwl_send_cmd(priv, &cmd);
411 531
412 if (ret || (flags & CMD_ASYNC)) 532 if (ret)
413 return ret; 533 return ret;
414 534
415 pkt = (struct iwl_rx_packet *)cmd.reply_page; 535 pkt = (struct iwl_rx_packet *)cmd.reply_page;
@@ -422,7 +542,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
422 if (!ret) { 542 if (!ret) {
423 switch (pkt->u.rem_sta.status) { 543 switch (pkt->u.rem_sta.status) {
424 case REM_STA_SUCCESS_MSK: 544 case REM_STA_SUCCESS_MSK:
425 iwl_sta_ucode_deactivate(priv, addr); 545 spin_lock_irqsave(&priv->sta_lock, flags_spin);
546 iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id);
547 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
426 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 548 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
427 break; 549 break;
428 default: 550 default:
@@ -439,23 +561,35 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
439/** 561/**
440 * iwl_remove_station - Remove driver's knowledge of station. 562 * iwl_remove_station - Remove driver's knowledge of station.
441 */ 563 */
442int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) 564static int iwl_remove_station(struct iwl_priv *priv, struct ieee80211_sta *sta)
443{ 565{
444 int sta_id = IWL_INVALID_STATION; 566 int sta_id = IWL_INVALID_STATION;
445 int i, ret = -EINVAL; 567 int i, ret = -EINVAL;
446 unsigned long flags; 568 unsigned long flags;
569 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
570 struct iwl_station_entry *station;
571
572 if (!iwl_is_ready(priv)) {
573 IWL_DEBUG_INFO(priv,
574 "Unable to remove station %pM, device not ready.\n",
575 sta->addr);
576 /*
577 * It is typical for stations to be removed when we are
578 * going down. Return success since device will be down
579 * soon anyway
580 */
581 return 0;
582 }
447 583
448 spin_lock_irqsave(&priv->sta_lock, flags); 584 spin_lock_irqsave(&priv->sta_lock, flags);
449 585
450 if (is_ap) 586 if (is_ap)
451 sta_id = IWL_AP_ID; 587 sta_id = IWL_AP_ID;
452 else if (is_broadcast_ether_addr(addr))
453 sta_id = priv->hw_params.bcast_sta_id;
454 else 588 else
455 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) 589 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
456 if (priv->stations[i].used && 590 if (priv->stations[i].used &&
457 !compare_ether_addr(priv->stations[i].sta.sta.addr, 591 !compare_ether_addr(priv->stations[i].sta.sta.addr,
458 addr)) { 592 sta->addr)) {
459 sta_id = i; 593 sta_id = i;
460 break; 594 break;
461 } 595 }
@@ -464,17 +598,17 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
464 goto out; 598 goto out;
465 599
466 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n", 600 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
467 sta_id, addr); 601 sta_id, sta->addr);
468 602
469 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { 603 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
470 IWL_ERR(priv, "Removing %pM but non DRIVER active\n", 604 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
471 addr); 605 sta->addr);
472 goto out; 606 goto out;
473 } 607 }
474 608
475 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { 609 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
476 IWL_ERR(priv, "Removing %pM but non UCODE active\n", 610 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
477 addr); 611 sta->addr);
478 goto out; 612 goto out;
479 } 613 }
480 614
@@ -485,9 +619,10 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
485 619
486 BUG_ON(priv->num_stations < 0); 620 BUG_ON(priv->num_stations < 0);
487 621
622 station = &priv->stations[sta_id];
488 spin_unlock_irqrestore(&priv->sta_lock, flags); 623 spin_unlock_irqrestore(&priv->sta_lock, flags);
489 624
490 ret = iwl_send_remove_station(priv, addr, CMD_ASYNC); 625 ret = iwl_send_remove_station(priv, station);
491 return ret; 626 return ret;
492out: 627out:
493 spin_unlock_irqrestore(&priv->sta_lock, flags); 628 spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -495,37 +630,122 @@ out:
495} 630}
496 631
497/** 632/**
498 * iwl_clear_stations_table - Clear the driver's station table 633 * iwl_clear_ucode_stations() - clear entire station table driver and/or ucode
499 * 634 * @priv:
500 * NOTE: This does not clear or otherwise alter the device's station table. 635 * @force: If set then the uCode station table needs to be cleared here. If
636 * not set then the uCode station table has already been cleared,
637 * for example after sending it a RXON command without ASSOC bit
638 * set, and we just need to change driver state here.
501 */ 639 */
502void iwl_clear_stations_table(struct iwl_priv *priv) 640void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force)
503{ 641{
504 unsigned long flags;
505 int i; 642 int i;
643 unsigned long flags_spin;
644 bool cleared = false;
645
646 IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver%s\n",
647 force ? " and ucode" : "");
648
649 if (force) {
650 if (!iwl_is_ready(priv)) {
651 /*
652 * If device is not ready at this point the station
653 * table is likely already empty (uCode not ready
654 * to receive station requests) or will soon be
655 * due to interface going down.
656 */
657 IWL_DEBUG_INFO(priv, "Unable to remove stations from device - device not ready\n");
658 } else {
659 iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL);
660 }
661 }
506 662
507 spin_lock_irqsave(&priv->sta_lock, flags); 663 spin_lock_irqsave(&priv->sta_lock, flags_spin);
664 if (force) {
665 IWL_DEBUG_INFO(priv, "Clearing all station information in driver\n");
666 priv->num_stations = 0;
667 memset(priv->stations, 0, sizeof(priv->stations));
668 } else {
669 for (i = 0; i < priv->hw_params.max_stations; i++) {
670 if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
671 IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
672 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
673 cleared = true;
674 }
675 }
676 }
677 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
508 678
509 if (iwl_is_alive(priv) && 679 if (!cleared)
510 !test_bit(STATUS_EXIT_PENDING, &priv->status) && 680 IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n");
511 iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL)) 681}
512 IWL_ERR(priv, "Couldn't clear the station table\n"); 682EXPORT_SYMBOL(iwl_clear_ucode_stations);
683
684/**
685 * iwl_restore_stations() - Restore driver known stations to device
686 *
687 * All stations considered active by driver, but not present in ucode, is
688 * restored.
689 *
690 * Function sleeps.
691 */
692void iwl_restore_stations(struct iwl_priv *priv)
693{
694 struct iwl_station_entry *station;
695 unsigned long flags_spin;
696 int i;
697 bool found = false;
698 int ret;
513 699
514 priv->num_stations = 0; 700 if (!iwl_is_ready(priv)) {
515 memset(priv->stations, 0, sizeof(priv->stations)); 701 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
702 return;
703 }
516 704
517 /* clean ucode key table bit map */ 705 IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
518 priv->ucode_key_table = 0; 706 spin_lock_irqsave(&priv->sta_lock, flags_spin);
707 for (i = 0; i < priv->hw_params.max_stations; i++) {
708 if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
709 !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
710 IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
711 priv->stations[i].sta.sta.addr);
712 priv->stations[i].sta.mode = 0;
713 priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
714 found = true;
715 }
716 }
519 717
520 /* keep track of static keys */ 718 for (i = 0; i < priv->hw_params.max_stations; i++) {
521 for (i = 0; i < WEP_KEYS_MAX ; i++) { 719 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
522 if (priv->wep_keys[i].key_size) 720 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
523 set_bit(i, &priv->ucode_key_table); 721 station = &priv->stations[i];
722 ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC);
723 if (ret) {
724 IWL_ERR(priv, "Adding station %pM failed.\n",
725 station->sta.sta.addr);
726 spin_lock_irqsave(&priv->sta_lock, flags_spin);
727 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
728 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
729 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
730 }
731 /*
732 * Rate scaling has already been initialized, send
733 * current LQ command
734 */
735 if (station->lq)
736 iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true);
737 spin_lock_irqsave(&priv->sta_lock, flags_spin);
738 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
739 }
524 } 740 }
525 741
526 spin_unlock_irqrestore(&priv->sta_lock, flags); 742 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
743 if (!found)
744 IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n");
745 else
746 IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n");
527} 747}
528EXPORT_SYMBOL(iwl_clear_stations_table); 748EXPORT_SYMBOL(iwl_restore_stations);
529 749
530int iwl_get_free_ucode_key_index(struct iwl_priv *priv) 750int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
531{ 751{
@@ -549,9 +769,11 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
549 struct iwl_host_cmd cmd = { 769 struct iwl_host_cmd cmd = {
550 .id = REPLY_WEPKEY, 770 .id = REPLY_WEPKEY,
551 .data = wep_cmd, 771 .data = wep_cmd,
552 .flags = CMD_ASYNC, 772 .flags = CMD_SYNC,
553 }; 773 };
554 774
775 might_sleep();
776
555 memset(wep_cmd, 0, cmd_size + 777 memset(wep_cmd, 0, cmd_size +
556 (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); 778 (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
557 779
@@ -587,9 +809,9 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
587 struct ieee80211_key_conf *keyconf) 809 struct ieee80211_key_conf *keyconf)
588{ 810{
589 int ret; 811 int ret;
590 unsigned long flags;
591 812
592 spin_lock_irqsave(&priv->sta_lock, flags); 813 WARN_ON(!mutex_is_locked(&priv->mutex));
814
593 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", 815 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
594 keyconf->keyidx); 816 keyconf->keyidx);
595 817
@@ -601,13 +823,12 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
601 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); 823 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
602 if (iwl_is_rfkill(priv)) { 824 if (iwl_is_rfkill(priv)) {
603 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); 825 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
604 spin_unlock_irqrestore(&priv->sta_lock, flags); 826 /* but keys in device are clear anyway so return success */
605 return 0; 827 return 0;
606 } 828 }
607 ret = iwl_send_static_wepkey_cmd(priv, 1); 829 ret = iwl_send_static_wepkey_cmd(priv, 1);
608 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", 830 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
609 keyconf->keyidx, ret); 831 keyconf->keyidx, ret);
610 spin_unlock_irqrestore(&priv->sta_lock, flags);
611 832
612 return ret; 833 return ret;
613} 834}
@@ -617,7 +838,8 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
617 struct ieee80211_key_conf *keyconf) 838 struct ieee80211_key_conf *keyconf)
618{ 839{
619 int ret; 840 int ret;
620 unsigned long flags; 841
842 WARN_ON(!mutex_is_locked(&priv->mutex));
621 843
622 if (keyconf->keylen != WEP_KEY_LEN_128 && 844 if (keyconf->keylen != WEP_KEY_LEN_128 &&
623 keyconf->keylen != WEP_KEY_LEN_64) { 845 keyconf->keylen != WEP_KEY_LEN_64) {
@@ -629,12 +851,11 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
629 keyconf->hw_key_idx = HW_KEY_DEFAULT; 851 keyconf->hw_key_idx = HW_KEY_DEFAULT;
630 priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; 852 priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP;
631 853
632 spin_lock_irqsave(&priv->sta_lock, flags);
633 priv->default_wep_key++; 854 priv->default_wep_key++;
634 855
635 if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table)) 856 if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table))
636 IWL_ERR(priv, "index %d already used in uCode key table.\n", 857 IWL_ERR(priv, "index %d already used in uCode key table.\n",
637 keyconf->keyidx); 858 keyconf->keyidx);
638 859
639 priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; 860 priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
640 memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, 861 memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key,
@@ -643,7 +864,6 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
643 ret = iwl_send_static_wepkey_cmd(priv, 0); 864 ret = iwl_send_static_wepkey_cmd(priv, 0);
644 IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", 865 IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
645 keyconf->keylen, keyconf->keyidx, ret); 866 keyconf->keylen, keyconf->keyidx, ret);
646 spin_unlock_irqrestore(&priv->sta_lock, flags);
647 867
648 return ret; 868 return ret;
649} 869}
@@ -885,7 +1105,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
885 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1105 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
886 1106
887 if (iwl_is_rfkill(priv)) { 1107 if (iwl_is_rfkill(priv)) {
888 IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled. \n"); 1108 IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
889 spin_unlock_irqrestore(&priv->sta_lock, flags); 1109 spin_unlock_irqrestore(&priv->sta_lock, flags);
890 return 0; 1110 return 0;
891 } 1111 }
@@ -948,9 +1168,22 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
948} 1168}
949#endif 1169#endif
950 1170
1171/**
1172 * iwl_send_lq_cmd() - Send link quality command
1173 * @init: This command is sent as part of station initialization right
1174 * after station has been added.
1175 *
1176 * The link quality command is sent as the last step of station creation.
1177 * This is the special case in which init is set and we call a callback in
1178 * this case to clear the state indicating that station creation is in
1179 * progress.
1180 */
951int iwl_send_lq_cmd(struct iwl_priv *priv, 1181int iwl_send_lq_cmd(struct iwl_priv *priv,
952 struct iwl_link_quality_cmd *lq, u8 flags) 1182 struct iwl_link_quality_cmd *lq, u8 flags, bool init)
953{ 1183{
1184 int ret = 0;
1185 unsigned long flags_spin;
1186
954 struct iwl_host_cmd cmd = { 1187 struct iwl_host_cmd cmd = {
955 .id = REPLY_TX_LINK_QUALITY_CMD, 1188 .id = REPLY_TX_LINK_QUALITY_CMD,
956 .len = sizeof(struct iwl_link_quality_cmd), 1189 .len = sizeof(struct iwl_link_quality_cmd),
@@ -966,167 +1199,31 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
966 lq->sta_id = IWL_AP_ID; 1199 lq->sta_id = IWL_AP_ID;
967 1200
968 iwl_dump_lq_cmd(priv, lq); 1201 iwl_dump_lq_cmd(priv, lq);
1202 BUG_ON(init && (cmd.flags & CMD_ASYNC));
969 1203
970 if (iwl_is_associated(priv) && priv->assoc_station_added) 1204 iwl_dump_lq_cmd(priv, lq);
971 return iwl_send_cmd(priv, &cmd); 1205 ret = iwl_send_cmd(priv, &cmd);
1206 if (ret || (cmd.flags & CMD_ASYNC))
1207 return ret;
972 1208
1209 if (init) {
1210 IWL_DEBUG_INFO(priv, "init LQ command complete, clearing sta addition status for sta %d\n",
1211 lq->sta_id);
1212 spin_lock_irqsave(&priv->sta_lock, flags_spin);
1213 priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
1214 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
1215 }
973 return 0; 1216 return 0;
974} 1217}
975EXPORT_SYMBOL(iwl_send_lq_cmd); 1218EXPORT_SYMBOL(iwl_send_lq_cmd);
976 1219
977/** 1220/**
978 * iwl_sta_init_lq - Initialize a station's hardware rate table
979 *
980 * The uCode's station table contains a table of fallback rates
981 * for automatic fallback during transmission.
982 *
983 * NOTE: This sets up a default set of values. These will be replaced later
984 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
985 * rc80211_simple.
986 *
987 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
988 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
989 * which requires station table entry to exist).
990 */
991static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
992{
993 int i, r;
994 struct iwl_link_quality_cmd link_cmd = {
995 .reserved1 = 0,
996 };
997 u32 rate_flags;
998
999 /* Set up the rate scaling to start at selected rate, fall back
1000 * all the way down to 1M in IEEE order, and then spin on 1M */
1001 if (is_ap)
1002 r = IWL_RATE_54M_INDEX;
1003 else if (priv->band == IEEE80211_BAND_5GHZ)
1004 r = IWL_RATE_6M_INDEX;
1005 else
1006 r = IWL_RATE_1M_INDEX;
1007
1008 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1009 rate_flags = 0;
1010 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
1011 rate_flags |= RATE_MCS_CCK_MSK;
1012
1013 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
1014 RATE_MCS_ANT_POS;
1015
1016 link_cmd.rs_table[i].rate_n_flags =
1017 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
1018 r = iwl_get_prev_ieee_rate(r);
1019 }
1020
1021 link_cmd.general_params.single_stream_ant_msk =
1022 first_antenna(priv->hw_params.valid_tx_ant);
1023 link_cmd.general_params.dual_stream_ant_msk = 3;
1024 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1025 link_cmd.agg_params.agg_time_limit =
1026 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1027
1028 /* Update the rate scaling for control frame Tx to AP */
1029 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
1030
1031 iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
1032 sizeof(link_cmd), &link_cmd, NULL);
1033}
1034
1035/**
1036 * iwl_rxon_add_station - add station into station table.
1037 *
1038 * there is only one AP station with id= IWL_AP_ID
1039 * NOTE: mutex must be held before calling this function
1040 */
1041int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
1042{
1043 struct ieee80211_sta *sta;
1044 struct ieee80211_sta_ht_cap ht_config;
1045 struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
1046 u8 sta_id;
1047
1048 /*
1049 * Set HT capabilities. It is ok to set this struct even if not using
1050 * HT config: the priv->current_ht_config.is_ht flag will just be false
1051 */
1052 rcu_read_lock();
1053 sta = ieee80211_find_sta(priv->vif, addr);
1054 if (sta) {
1055 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
1056 cur_ht_config = &ht_config;
1057 }
1058 rcu_read_unlock();
1059
1060 /* Add station to device's station table */
1061 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
1062
1063 /* Set up default rate scaling table in device's station table */
1064 iwl_sta_init_lq(priv, addr, is_ap);
1065
1066 return sta_id;
1067}
1068EXPORT_SYMBOL(iwl_rxon_add_station);
1069
1070/**
1071 * iwl_sta_init_bcast_lq - Initialize a bcast station's hardware rate table
1072 *
1073 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
1074 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
1075 * which requires station table entry to exist).
1076 */
1077static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
1078{
1079 int i, r;
1080 struct iwl_link_quality_cmd link_cmd = {
1081 .reserved1 = 0,
1082 };
1083 u32 rate_flags;
1084
1085 /* Set up the rate scaling to start at selected rate, fall back
1086 * all the way down to 1M in IEEE order, and then spin on 1M */
1087 if (priv->band == IEEE80211_BAND_5GHZ)
1088 r = IWL_RATE_6M_INDEX;
1089 else
1090 r = IWL_RATE_1M_INDEX;
1091
1092 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1093 rate_flags = 0;
1094 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
1095 rate_flags |= RATE_MCS_CCK_MSK;
1096
1097 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
1098 RATE_MCS_ANT_POS;
1099
1100 link_cmd.rs_table[i].rate_n_flags =
1101 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
1102 r = iwl_get_prev_ieee_rate(r);
1103 }
1104
1105 link_cmd.general_params.single_stream_ant_msk =
1106 first_antenna(priv->hw_params.valid_tx_ant);
1107 link_cmd.general_params.dual_stream_ant_msk = 3;
1108 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1109 link_cmd.agg_params.agg_time_limit =
1110 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1111
1112 /* Update the rate scaling for control frame Tx to AP */
1113 link_cmd.sta_id = priv->hw_params.bcast_sta_id;
1114
1115 iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
1116 sizeof(link_cmd), &link_cmd, NULL);
1117}
1118
1119
1120/**
1121 * iwl_add_bcast_station - add broadcast station into station table. 1221 * iwl_add_bcast_station - add broadcast station into station table.
1122 */ 1222 */
1123void iwl_add_bcast_station(struct iwl_priv *priv) 1223void iwl_add_bcast_station(struct iwl_priv *priv)
1124{ 1224{
1125 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); 1225 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1126 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1226 iwl_add_local_station(priv, iwl_bcast_addr, true);
1127
1128 /* Set up default rate scaling table in device's station table */
1129 iwl_sta_init_bcast_lq(priv);
1130} 1227}
1131EXPORT_SYMBOL(iwl_add_bcast_station); 1228EXPORT_SYMBOL(iwl_add_bcast_station);
1132 1229
@@ -1136,7 +1233,14 @@ EXPORT_SYMBOL(iwl_add_bcast_station);
1136void iwl3945_add_bcast_station(struct iwl_priv *priv) 1233void iwl3945_add_bcast_station(struct iwl_priv *priv)
1137{ 1234{
1138 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); 1235 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1139 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1236 iwl_add_local_station(priv, iwl_bcast_addr, false);
1237 /*
1238 * It is assumed that when station is added more initialization
1239 * needs to be done, but for 3945 it is not the case and we can
1240 * just release station table access right here.
1241 */
1242 priv->stations[priv->hw_params.bcast_sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
1243
1140} 1244}
1141EXPORT_SYMBOL(iwl3945_add_bcast_station); 1245EXPORT_SYMBOL(iwl3945_add_bcast_station);
1142 1246
@@ -1159,6 +1263,13 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1159 /* If we are a client station in a BSS network, use the special 1263 /* If we are a client station in a BSS network, use the special
1160 * AP station entry (that's the only station we communicate with) */ 1264 * AP station entry (that's the only station we communicate with) */
1161 case NL80211_IFTYPE_STATION: 1265 case NL80211_IFTYPE_STATION:
1266 /*
1267 * If addition of station not complete yet, which means
1268 * that rate scaling has not been initialized, then return
1269 * the broadcast station.
1270 */
1271 if (!(priv->stations[IWL_AP_ID].used & IWL_STA_UCODE_ACTIVE))
1272 return priv->hw_params.bcast_sta_id;
1162 return IWL_AP_ID; 1273 return IWL_AP_ID;
1163 1274
1164 /* If we are an AP, then find the station, or use BCAST */ 1275 /* If we are an AP, then find the station, or use BCAST */
@@ -1175,13 +1286,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1175 if (sta_id != IWL_INVALID_STATION) 1286 if (sta_id != IWL_INVALID_STATION)
1176 return sta_id; 1287 return sta_id;
1177 1288
1178 /* Create new station table entry */
1179 sta_id = iwl_add_station(priv, hdr->addr1, false,
1180 CMD_ASYNC, NULL);
1181
1182 if (sta_id != IWL_INVALID_STATION)
1183 return sta_id;
1184
1185 IWL_DEBUG_DROP(priv, "Station %pM not in station map. " 1289 IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
1186 "Defaulting to broadcast...\n", 1290 "Defaulting to broadcast...\n",
1187 hdr->addr1); 1291 hdr->addr1);
@@ -1291,3 +1395,20 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1291 1395
1292 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1396 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1293} 1397}
1398EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
1399
1400int iwl_mac_sta_remove(struct ieee80211_hw *hw,
1401 struct ieee80211_vif *vif,
1402 struct ieee80211_sta *sta)
1403{
1404 int ret;
1405 struct iwl_priv *priv = hw->priv;
1406 IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
1407 sta->addr);
1408 ret = iwl_remove_station(priv, sta);
1409 if (ret)
1410 IWL_ERR(priv, "Error removing station %pM\n",
1411 sta->addr);
1412 return ret;
1413}
1414EXPORT_SYMBOL(iwl_mac_sta_remove);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 2dc35fe28f56..87a34997a758 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -32,6 +32,12 @@
32#define HW_KEY_DYNAMIC 0 32#define HW_KEY_DYNAMIC 0
33#define HW_KEY_DEFAULT 1 33#define HW_KEY_DEFAULT 1
34 34
35#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
36#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
37#define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of
38 being activated */
39
40
35/** 41/**
36 * iwl_find_station - Find station id for a given BSSID 42 * iwl_find_station - Find station id for a given BSSID
37 * @bssid: MAC address of station ID to find 43 * @bssid: MAC address of station ID to find
@@ -51,18 +57,22 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
51 struct ieee80211_key_conf *keyconf, 57 struct ieee80211_key_conf *keyconf,
52 const u8 *addr, u32 iv32, u16 *phase1key); 58 const u8 *addr, u32 iv32, u16 *phase1key);
53 59
54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
55void iwl_add_bcast_station(struct iwl_priv *priv); 60void iwl_add_bcast_station(struct iwl_priv *priv);
56void iwl3945_add_bcast_station(struct iwl_priv *priv); 61void iwl3945_add_bcast_station(struct iwl_priv *priv);
57int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 62void iwl_restore_stations(struct iwl_priv *priv);
58void iwl_clear_stations_table(struct iwl_priv *priv); 63void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force);
59int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 64int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
60int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); 65int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
61int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); 66int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
62int iwl_send_add_sta(struct iwl_priv *priv, 67int iwl_send_add_sta(struct iwl_priv *priv,
63 struct iwl_addsta_cmd *sta, u8 flags); 68 struct iwl_addsta_cmd *sta, u8 flags);
64u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, 69int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs);
65 struct ieee80211_sta_ht_cap *ht_info); 70int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
71 bool is_ap,
72 struct ieee80211_sta_ht_cap *ht_info,
73 u8 *sta_id_r);
74int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
75 struct ieee80211_sta *sta);
66void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 76void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
67int iwl_sta_rx_agg_start(struct iwl_priv *priv, 77int iwl_sta_rx_agg_start(struct iwl_priv *priv,
68 const u8 *addr, int tid, u16 ssn); 78 const u8 *addr, int tid, u16 ssn);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 343d81ad2653..a631afef5e33 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -37,47 +37,6 @@
37#include "iwl-io.h" 37#include "iwl-io.h"
38#include "iwl-helpers.h" 38#include "iwl-helpers.h"
39 39
40static const u16 default_tid_to_tx_fifo[] = {
41 IWL_TX_FIFO_AC1,
42 IWL_TX_FIFO_AC0,
43 IWL_TX_FIFO_AC0,
44 IWL_TX_FIFO_AC1,
45 IWL_TX_FIFO_AC2,
46 IWL_TX_FIFO_AC2,
47 IWL_TX_FIFO_AC3,
48 IWL_TX_FIFO_AC3,
49 IWL_TX_FIFO_NONE,
50 IWL_TX_FIFO_NONE,
51 IWL_TX_FIFO_NONE,
52 IWL_TX_FIFO_NONE,
53 IWL_TX_FIFO_NONE,
54 IWL_TX_FIFO_NONE,
55 IWL_TX_FIFO_NONE,
56 IWL_TX_FIFO_NONE,
57 IWL_TX_FIFO_AC3
58};
59
60static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
61 struct iwl_dma_ptr *ptr, size_t size)
62{
63 ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma,
64 GFP_KERNEL);
65 if (!ptr->addr)
66 return -ENOMEM;
67 ptr->size = size;
68 return 0;
69}
70
71static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
72 struct iwl_dma_ptr *ptr)
73{
74 if (unlikely(!ptr->addr))
75 return;
76
77 dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
78 memset(ptr, 0, sizeof(*ptr));
79}
80
81/** 40/**
82 * iwl_txq_update_write_ptr - Send new write index to hardware 41 * iwl_txq_update_write_ptr - Send new write index to hardware
83 */ 42 */
@@ -309,6 +268,8 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
309 q->high_mark = 2; 268 q->high_mark = 2;
310 269
311 q->write_ptr = q->read_ptr = 0; 270 q->write_ptr = q->read_ptr = 0;
271 q->last_read_ptr = 0;
272 q->repeat_same_read_ptr = 0;
312 273
313 return 0; 274 return 0;
314} 275}
@@ -433,631 +394,6 @@ out_free_arrays:
433} 394}
434EXPORT_SYMBOL(iwl_tx_queue_init); 395EXPORT_SYMBOL(iwl_tx_queue_init);
435 396
436void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
437 int slots_num, u32 txq_id)
438{
439 int actual_slots = slots_num;
440
441 if (txq_id == IWL_CMD_QUEUE_NUM)
442 actual_slots++;
443
444 memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
445
446 txq->need_update = 0;
447
448 /* Initialize queue's high/low-water marks, and head/tail indexes */
449 iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
450
451 /* Tell device where to find queue */
452 priv->cfg->ops->lib->txq_init(priv, txq);
453}
454EXPORT_SYMBOL(iwl_tx_queue_reset);
455
456/**
457 * iwl_hw_txq_ctx_free - Free TXQ Context
458 *
459 * Destroy all TX DMA queues and structures
460 */
461void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
462{
463 int txq_id;
464
465 /* Tx queues */
466 if (priv->txq) {
467 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
468 if (txq_id == IWL_CMD_QUEUE_NUM)
469 iwl_cmd_queue_free(priv);
470 else
471 iwl_tx_queue_free(priv, txq_id);
472 }
473 iwl_free_dma_ptr(priv, &priv->kw);
474
475 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
476
477 /* free tx queue structure */
478 iwl_free_txq_mem(priv);
479}
480EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
481
482/**
483 * iwl_txq_ctx_alloc - allocate TX queue context
484 * Allocate all Tx DMA structures and initialize them
485 *
486 * @param priv
487 * @return error code
488 */
489int iwl_txq_ctx_alloc(struct iwl_priv *priv)
490{
491 int ret;
492 int txq_id, slots_num;
493 unsigned long flags;
494
495 /* Free all tx/cmd queues and keep-warm buffer */
496 iwl_hw_txq_ctx_free(priv);
497
498 ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
499 priv->hw_params.scd_bc_tbls_size);
500 if (ret) {
501 IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
502 goto error_bc_tbls;
503 }
504 /* Alloc keep-warm buffer */
505 ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
506 if (ret) {
507 IWL_ERR(priv, "Keep Warm allocation failed\n");
508 goto error_kw;
509 }
510
511 /* allocate tx queue structure */
512 ret = iwl_alloc_txq_mem(priv);
513 if (ret)
514 goto error;
515
516 spin_lock_irqsave(&priv->lock, flags);
517
518 /* Turn off all Tx DMA fifos */
519 priv->cfg->ops->lib->txq_set_sched(priv, 0);
520
521 /* Tell NIC where to find the "keep warm" buffer */
522 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
523
524 spin_unlock_irqrestore(&priv->lock, flags);
525
526 /* Alloc and init all Tx queues, including the command queue (#4) */
527 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
528 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
529 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
530 ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
531 txq_id);
532 if (ret) {
533 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
534 goto error;
535 }
536 }
537
538 return ret;
539
540 error:
541 iwl_hw_txq_ctx_free(priv);
542 iwl_free_dma_ptr(priv, &priv->kw);
543 error_kw:
544 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
545 error_bc_tbls:
546 return ret;
547}
548
549void iwl_txq_ctx_reset(struct iwl_priv *priv)
550{
551 int txq_id, slots_num;
552 unsigned long flags;
553
554 spin_lock_irqsave(&priv->lock, flags);
555
556 /* Turn off all Tx DMA fifos */
557 priv->cfg->ops->lib->txq_set_sched(priv, 0);
558
559 /* Tell NIC where to find the "keep warm" buffer */
560 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
561
562 spin_unlock_irqrestore(&priv->lock, flags);
563
564 /* Alloc and init all Tx queues, including the command queue (#4) */
565 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
566 slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
567 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
568 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
569 }
570}
571
572/**
573 * iwl_txq_ctx_stop - Stop all Tx DMA channels
574 */
575void iwl_txq_ctx_stop(struct iwl_priv *priv)
576{
577 int ch;
578 unsigned long flags;
579
580 /* Turn off all Tx DMA fifos */
581 spin_lock_irqsave(&priv->lock, flags);
582
583 priv->cfg->ops->lib->txq_set_sched(priv, 0);
584
585 /* Stop each Tx DMA channel, and wait for it to be idle */
586 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
587 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
588 iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
589 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
590 1000);
591 }
592 spin_unlock_irqrestore(&priv->lock, flags);
593}
594EXPORT_SYMBOL(iwl_txq_ctx_stop);
595
596/*
597 * handle build REPLY_TX command notification.
598 */
599static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
600 struct iwl_tx_cmd *tx_cmd,
601 struct ieee80211_tx_info *info,
602 struct ieee80211_hdr *hdr,
603 u8 std_id)
604{
605 __le16 fc = hdr->frame_control;
606 __le32 tx_flags = tx_cmd->tx_flags;
607
608 tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
609 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
610 tx_flags |= TX_CMD_FLG_ACK_MSK;
611 if (ieee80211_is_mgmt(fc))
612 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
613 if (ieee80211_is_probe_resp(fc) &&
614 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
615 tx_flags |= TX_CMD_FLG_TSF_MSK;
616 } else {
617 tx_flags &= (~TX_CMD_FLG_ACK_MSK);
618 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
619 }
620
621 if (ieee80211_is_back_req(fc))
622 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
623
624
625 tx_cmd->sta_id = std_id;
626 if (ieee80211_has_morefrags(fc))
627 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
628
629 if (ieee80211_is_data_qos(fc)) {
630 u8 *qc = ieee80211_get_qos_ctl(hdr);
631 tx_cmd->tid_tspec = qc[0] & 0xf;
632 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
633 } else {
634 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
635 }
636
637 priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
638
639 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
640 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
641
642 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
643 if (ieee80211_is_mgmt(fc)) {
644 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
645 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
646 else
647 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
648 } else {
649 tx_cmd->timeout.pm_frame_timeout = 0;
650 }
651
652 tx_cmd->driver_txop = 0;
653 tx_cmd->tx_flags = tx_flags;
654 tx_cmd->next_frame_len = 0;
655}
656
657#define RTS_HCCA_RETRY_LIMIT 3
658#define RTS_DFAULT_RETRY_LIMIT 60
659
660static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
661 struct iwl_tx_cmd *tx_cmd,
662 struct ieee80211_tx_info *info,
663 __le16 fc, int is_hcca)
664{
665 u32 rate_flags;
666 int rate_idx;
667 u8 rts_retry_limit;
668 u8 data_retry_limit;
669 u8 rate_plcp;
670
671 /* Set retry limit on DATA packets and Probe Responses*/
672 if (ieee80211_is_probe_resp(fc))
673 data_retry_limit = 3;
674 else
675 data_retry_limit = IWL_DEFAULT_TX_RETRY;
676 tx_cmd->data_retry_limit = data_retry_limit;
677
678 /* Set retry limit on RTS packets */
679 rts_retry_limit = (is_hcca) ? RTS_HCCA_RETRY_LIMIT :
680 RTS_DFAULT_RETRY_LIMIT;
681 if (data_retry_limit < rts_retry_limit)
682 rts_retry_limit = data_retry_limit;
683 tx_cmd->rts_retry_limit = rts_retry_limit;
684
685 /* DATA packets will use the uCode station table for rate/antenna
686 * selection */
687 if (ieee80211_is_data(fc)) {
688 tx_cmd->initial_rate_index = 0;
689 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
690 return;
691 }
692
693 /**
694 * If the current TX rate stored in mac80211 has the MCS bit set, it's
695 * not really a TX rate. Thus, we use the lowest supported rate for
696 * this band. Also use the lowest supported rate if the stored rate
697 * index is invalid.
698 */
699 rate_idx = info->control.rates[0].idx;
700 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS ||
701 (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY))
702 rate_idx = rate_lowest_index(&priv->bands[info->band],
703 info->control.sta);
704 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
705 if (info->band == IEEE80211_BAND_5GHZ)
706 rate_idx += IWL_FIRST_OFDM_RATE;
707 /* Get PLCP rate for tx_cmd->rate_n_flags */
708 rate_plcp = iwl_rates[rate_idx].plcp;
709 /* Zero out flags for this packet */
710 rate_flags = 0;
711
712 /* Set CCK flag as needed */
713 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
714 rate_flags |= RATE_MCS_CCK_MSK;
715
716 /* Set up RTS and CTS flags for certain packets */
717 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
718 case cpu_to_le16(IEEE80211_STYPE_AUTH):
719 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
720 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
721 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
722 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
723 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
724 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
725 }
726 break;
727 default:
728 break;
729 }
730
731 /* Set up antennas */
732 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
733 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
734
735 /* Set the rate in the TX cmd */
736 tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
737}
738
739static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
740 struct ieee80211_tx_info *info,
741 struct iwl_tx_cmd *tx_cmd,
742 struct sk_buff *skb_frag,
743 int sta_id)
744{
745 struct ieee80211_key_conf *keyconf = info->control.hw_key;
746
747 switch (keyconf->alg) {
748 case ALG_CCMP:
749 tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
750 memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
751 if (info->flags & IEEE80211_TX_CTL_AMPDU)
752 tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
753 IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
754 break;
755
756 case ALG_TKIP:
757 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
758 ieee80211_get_tkip_key(keyconf, skb_frag,
759 IEEE80211_TKIP_P2_KEY, tx_cmd->key);
760 IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
761 break;
762
763 case ALG_WEP:
764 tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP |
765 (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
766
767 if (keyconf->keylen == WEP_KEY_LEN_128)
768 tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
769
770 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
771
772 IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
773 "with key %d\n", keyconf->keyidx);
774 break;
775
776 default:
777 IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
778 break;
779 }
780}
781
782/*
783 * start REPLY_TX command process
784 */
785int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
786{
787 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
788 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
789 struct ieee80211_sta *sta = info->control.sta;
790 struct iwl_station_priv *sta_priv = NULL;
791 struct iwl_tx_queue *txq;
792 struct iwl_queue *q;
793 struct iwl_device_cmd *out_cmd;
794 struct iwl_cmd_meta *out_meta;
795 struct iwl_tx_cmd *tx_cmd;
796 int swq_id, txq_id;
797 dma_addr_t phys_addr;
798 dma_addr_t txcmd_phys;
799 dma_addr_t scratch_phys;
800 u16 len, len_org, firstlen, secondlen;
801 u16 seq_number = 0;
802 __le16 fc;
803 u8 hdr_len;
804 u8 sta_id;
805 u8 wait_write_ptr = 0;
806 u8 tid = 0;
807 u8 *qc = NULL;
808 unsigned long flags;
809
810 spin_lock_irqsave(&priv->lock, flags);
811 if (iwl_is_rfkill(priv)) {
812 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
813 goto drop_unlock;
814 }
815
816 fc = hdr->frame_control;
817
818#ifdef CONFIG_IWLWIFI_DEBUG
819 if (ieee80211_is_auth(fc))
820 IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
821 else if (ieee80211_is_assoc_req(fc))
822 IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
823 else if (ieee80211_is_reassoc_req(fc))
824 IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
825#endif
826
827 /* drop all non-injected data frame if we are not associated */
828 if (ieee80211_is_data(fc) &&
829 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
830 (!iwl_is_associated(priv) ||
831 ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
832 !priv->assoc_station_added)) {
833 IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
834 goto drop_unlock;
835 }
836
837 hdr_len = ieee80211_hdrlen(fc);
838
839 /* Find (or create) index into station table for destination station */
840 if (info->flags & IEEE80211_TX_CTL_INJECTED)
841 sta_id = priv->hw_params.bcast_sta_id;
842 else
843 sta_id = iwl_get_sta_id(priv, hdr);
844 if (sta_id == IWL_INVALID_STATION) {
845 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
846 hdr->addr1);
847 goto drop_unlock;
848 }
849
850 IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
851
852 if (sta)
853 sta_priv = (void *)sta->drv_priv;
854
855 if (sta_priv && sta_id != priv->hw_params.bcast_sta_id &&
856 sta_priv->asleep) {
857 WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
858 /*
859 * This sends an asynchronous command to the device,
860 * but we can rely on it being processed before the
861 * next frame is processed -- and the next frame to
862 * this station is the one that will consume this
863 * counter.
864 * For now set the counter to just 1 since we do not
865 * support uAPSD yet.
866 */
867 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
868 }
869
870 txq_id = skb_get_queue_mapping(skb);
871 if (ieee80211_is_data_qos(fc)) {
872 qc = ieee80211_get_qos_ctl(hdr);
873 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
874 if (unlikely(tid >= MAX_TID_COUNT))
875 goto drop_unlock;
876 seq_number = priv->stations[sta_id].tid[tid].seq_number;
877 seq_number &= IEEE80211_SCTL_SEQ;
878 hdr->seq_ctrl = hdr->seq_ctrl &
879 cpu_to_le16(IEEE80211_SCTL_FRAG);
880 hdr->seq_ctrl |= cpu_to_le16(seq_number);
881 seq_number += 0x10;
882 /* aggregation is on for this <sta,tid> */
883 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
884 priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
885 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
886 }
887 }
888
889 txq = &priv->txq[txq_id];
890 swq_id = txq->swq_id;
891 q = &txq->q;
892
893 if (unlikely(iwl_queue_space(q) < q->high_mark))
894 goto drop_unlock;
895
896 if (ieee80211_is_data_qos(fc))
897 priv->stations[sta_id].tid[tid].tfds_in_queue++;
898
899 /* Set up driver data for this TFD */
900 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
901 txq->txb[q->write_ptr].skb[0] = skb;
902
903 /* Set up first empty entry in queue's array of Tx/cmd buffers */
904 out_cmd = txq->cmd[q->write_ptr];
905 out_meta = &txq->meta[q->write_ptr];
906 tx_cmd = &out_cmd->cmd.tx;
907 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
908 memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
909
910 /*
911 * Set up the Tx-command (not MAC!) header.
912 * Store the chosen Tx queue and TFD index within the sequence field;
913 * after Tx, uCode's Tx response will return this value so driver can
914 * locate the frame within the tx queue and do post-tx processing.
915 */
916 out_cmd->hdr.cmd = REPLY_TX;
917 out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
918 INDEX_TO_SEQ(q->write_ptr)));
919
920 /* Copy MAC header from skb into command buffer */
921 memcpy(tx_cmd->hdr, hdr, hdr_len);
922
923
924 /* Total # bytes to be transmitted */
925 len = (u16)skb->len;
926 tx_cmd->len = cpu_to_le16(len);
927
928 if (info->control.hw_key)
929 iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
930
931 /* TODO need this for burst mode later on */
932 iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
933 iwl_dbg_log_tx_data_frame(priv, len, hdr);
934
935 /* set is_hcca to 0; it probably will never be implemented */
936 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, 0);
937
938 iwl_update_stats(priv, true, fc, len);
939 /*
940 * Use the first empty entry in this queue's command buffer array
941 * to contain the Tx command and MAC header concatenated together
942 * (payload data will be in another buffer).
943 * Size of this varies, due to varying MAC header length.
944 * If end is not dword aligned, we'll have 2 extra bytes at the end
945 * of the MAC header (device reads on dword boundaries).
946 * We'll tell device about this padding later.
947 */
948 len = sizeof(struct iwl_tx_cmd) +
949 sizeof(struct iwl_cmd_header) + hdr_len;
950
951 len_org = len;
952 firstlen = len = (len + 3) & ~3;
953
954 if (len_org != len)
955 len_org = 1;
956 else
957 len_org = 0;
958
959 /* Tell NIC about any 2-byte padding after MAC header */
960 if (len_org)
961 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
962
963 /* Physical address of this Tx command's header (not MAC header!),
964 * within command buffer array. */
965 txcmd_phys = pci_map_single(priv->pci_dev,
966 &out_cmd->hdr, len,
967 PCI_DMA_BIDIRECTIONAL);
968 pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
969 pci_unmap_len_set(out_meta, len, len);
970 /* Add buffer containing Tx command and MAC(!) header to TFD's
971 * first entry */
972 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
973 txcmd_phys, len, 1, 0);
974
975 if (!ieee80211_has_morefrags(hdr->frame_control)) {
976 txq->need_update = 1;
977 if (qc)
978 priv->stations[sta_id].tid[tid].seq_number = seq_number;
979 } else {
980 wait_write_ptr = 1;
981 txq->need_update = 0;
982 }
983
984 /* Set up TFD's 2nd entry to point directly to remainder of skb,
985 * if any (802.11 null frames have no payload). */
986 secondlen = len = skb->len - hdr_len;
987 if (len) {
988 phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
989 len, PCI_DMA_TODEVICE);
990 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
991 phys_addr, len,
992 0, 0);
993 }
994
995 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
996 offsetof(struct iwl_tx_cmd, scratch);
997
998 len = sizeof(struct iwl_tx_cmd) +
999 sizeof(struct iwl_cmd_header) + hdr_len;
1000 /* take back ownership of DMA buffer to enable update */
1001 pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
1002 len, PCI_DMA_BIDIRECTIONAL);
1003 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1004 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1005
1006 IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
1007 le16_to_cpu(out_cmd->hdr.sequence));
1008 IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags));
1009 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
1010 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
1011
1012 /* Set up entry for this TFD in Tx byte-count array */
1013 if (info->flags & IEEE80211_TX_CTL_AMPDU)
1014 priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
1015 le16_to_cpu(tx_cmd->len));
1016
1017 pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
1018 len, PCI_DMA_BIDIRECTIONAL);
1019
1020 trace_iwlwifi_dev_tx(priv,
1021 &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
1022 sizeof(struct iwl_tfd),
1023 &out_cmd->hdr, firstlen,
1024 skb->data + hdr_len, secondlen);
1025
1026 /* Tell device the write index *just past* this latest filled TFD */
1027 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1028 iwl_txq_update_write_ptr(priv, txq);
1029 spin_unlock_irqrestore(&priv->lock, flags);
1030
1031 /*
1032 * At this point the frame is "transmitted" successfully
1033 * and we will get a TX status notification eventually,
1034 * regardless of the value of ret. "ret" only indicates
1035 * whether or not we should update the write pointer.
1036 */
1037
1038 /* avoid atomic ops if it isn't an associated client */
1039 if (sta_priv && sta_priv->client)
1040 atomic_inc(&sta_priv->pending_frames);
1041
1042 if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
1043 if (wait_write_ptr) {
1044 spin_lock_irqsave(&priv->lock, flags);
1045 txq->need_update = 1;
1046 iwl_txq_update_write_ptr(priv, txq);
1047 spin_unlock_irqrestore(&priv->lock, flags);
1048 } else {
1049 iwl_stop_queue(priv, txq->swq_id);
1050 }
1051 }
1052
1053 return 0;
1054
1055drop_unlock:
1056 spin_unlock_irqrestore(&priv->lock, flags);
1057 return -1;
1058}
1059EXPORT_SYMBOL(iwl_tx_skb);
1060
1061/*************** HOST COMMAND QUEUE FUNCTIONS *****/ 397/*************** HOST COMMAND QUEUE FUNCTIONS *****/
1062 398
1063/** 399/**
@@ -1191,61 +527,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1191 return idx; 527 return idx;
1192} 528}
1193 529
1194static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
1195{
1196 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1197 struct ieee80211_sta *sta;
1198 struct iwl_station_priv *sta_priv;
1199
1200 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
1201 if (sta) {
1202 sta_priv = (void *)sta->drv_priv;
1203 /* avoid atomic ops if this isn't a client */
1204 if (sta_priv->client &&
1205 atomic_dec_return(&sta_priv->pending_frames) == 0)
1206 ieee80211_sta_block_awake(priv->hw, sta, false);
1207 }
1208
1209 ieee80211_tx_status_irqsafe(priv->hw, skb);
1210}
1211
1212int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1213{
1214 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1215 struct iwl_queue *q = &txq->q;
1216 struct iwl_tx_info *tx_info;
1217 int nfreed = 0;
1218 struct ieee80211_hdr *hdr;
1219
1220 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
1221 IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
1222 "is out of range [0-%d] %d %d.\n", txq_id,
1223 index, q->n_bd, q->write_ptr, q->read_ptr);
1224 return 0;
1225 }
1226
1227 for (index = iwl_queue_inc_wrap(index, q->n_bd);
1228 q->read_ptr != index;
1229 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1230
1231 tx_info = &txq->txb[txq->q.read_ptr];
1232 iwl_tx_status(priv, tx_info->skb[0]);
1233
1234 hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data;
1235 if (hdr && ieee80211_is_data_qos(hdr->frame_control))
1236 nfreed++;
1237 tx_info->skb[0] = NULL;
1238
1239 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
1240 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
1241
1242 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
1243 }
1244 return nfreed;
1245}
1246EXPORT_SYMBOL(iwl_tx_queue_reclaim);
1247
1248
1249/** 530/**
1250 * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd 531 * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd
1251 * 532 *
@@ -1339,7 +620,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1339 620
1340 if (!(meta->flags & CMD_ASYNC)) { 621 if (!(meta->flags & CMD_ASYNC)) {
1341 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 622 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1342 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n", 623 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
1343 get_cmd_string(cmd->hdr.cmd)); 624 get_cmd_string(cmd->hdr.cmd));
1344 wake_up_interruptible(&priv->wait_command_queue); 625 wake_up_interruptible(&priv->wait_command_queue);
1345 } 626 }
@@ -1347,334 +628,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1347} 628}
1348EXPORT_SYMBOL(iwl_tx_cmd_complete); 629EXPORT_SYMBOL(iwl_tx_cmd_complete);
1349 630
1350/*
1351 * Find first available (lowest unused) Tx Queue, mark it "active".
1352 * Called only when finding queue for aggregation.
1353 * Should never return anything < 7, because they should already
1354 * be in use as EDCA AC (0-3), Command (4), HCCA (5, 6).
1355 */
1356static int iwl_txq_ctx_activate_free(struct iwl_priv *priv)
1357{
1358 int txq_id;
1359
1360 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
1361 if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk))
1362 return txq_id;
1363 return -1;
1364}
1365
1366int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
1367{
1368 int sta_id;
1369 int tx_fifo;
1370 int txq_id;
1371 int ret;
1372 unsigned long flags;
1373 struct iwl_tid_data *tid_data;
1374
1375 if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
1376 tx_fifo = default_tid_to_tx_fifo[tid];
1377 else
1378 return -EINVAL;
1379
1380 IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
1381 __func__, ra, tid);
1382
1383 sta_id = iwl_find_station(priv, ra);
1384 if (sta_id == IWL_INVALID_STATION) {
1385 IWL_ERR(priv, "Start AGG on invalid station\n");
1386 return -ENXIO;
1387 }
1388 if (unlikely(tid >= MAX_TID_COUNT))
1389 return -EINVAL;
1390
1391 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
1392 IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
1393 return -ENXIO;
1394 }
1395
1396 txq_id = iwl_txq_ctx_activate_free(priv);
1397 if (txq_id == -1) {
1398 IWL_ERR(priv, "No free aggregation queue available\n");
1399 return -ENXIO;
1400 }
1401
1402 spin_lock_irqsave(&priv->sta_lock, flags);
1403 tid_data = &priv->stations[sta_id].tid[tid];
1404 *ssn = SEQ_TO_SN(tid_data->seq_number);
1405 tid_data->agg.txq_id = txq_id;
1406 priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(tx_fifo, txq_id);
1407 spin_unlock_irqrestore(&priv->sta_lock, flags);
1408
1409 ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
1410 sta_id, tid, *ssn);
1411 if (ret)
1412 return ret;
1413
1414 if (tid_data->tfds_in_queue == 0) {
1415 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1416 tid_data->agg.state = IWL_AGG_ON;
1417 ieee80211_start_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1418 } else {
1419 IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
1420 tid_data->tfds_in_queue);
1421 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
1422 }
1423 return ret;
1424}
1425EXPORT_SYMBOL(iwl_tx_agg_start);
1426
1427int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
1428{
1429 int tx_fifo_id, txq_id, sta_id, ssn = -1;
1430 struct iwl_tid_data *tid_data;
1431 int write_ptr, read_ptr;
1432 unsigned long flags;
1433
1434 if (!ra) {
1435 IWL_ERR(priv, "ra = NULL\n");
1436 return -EINVAL;
1437 }
1438
1439 if (unlikely(tid >= MAX_TID_COUNT))
1440 return -EINVAL;
1441
1442 if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
1443 tx_fifo_id = default_tid_to_tx_fifo[tid];
1444 else
1445 return -EINVAL;
1446
1447 sta_id = iwl_find_station(priv, ra);
1448
1449 if (sta_id == IWL_INVALID_STATION) {
1450 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1451 return -ENXIO;
1452 }
1453
1454 if (priv->stations[sta_id].tid[tid].agg.state ==
1455 IWL_EMPTYING_HW_QUEUE_ADDBA) {
1456 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1457 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1458 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1459 return 0;
1460 }
1461
1462 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
1463 IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
1464
1465 tid_data = &priv->stations[sta_id].tid[tid];
1466 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
1467 txq_id = tid_data->agg.txq_id;
1468 write_ptr = priv->txq[txq_id].q.write_ptr;
1469 read_ptr = priv->txq[txq_id].q.read_ptr;
1470
1471 /* The queue is not empty */
1472 if (write_ptr != read_ptr) {
1473 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
1474 priv->stations[sta_id].tid[tid].agg.state =
1475 IWL_EMPTYING_HW_QUEUE_DELBA;
1476 return 0;
1477 }
1478
1479 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1480 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1481
1482 spin_lock_irqsave(&priv->lock, flags);
1483 /*
1484 * the only reason this call can fail is queue number out of range,
1485 * which can happen if uCode is reloaded and all the station
1486 * information are lost. if it is outside the range, there is no need
1487 * to deactivate the uCode queue, just return "success" to allow
1488 * mac80211 to clean up it own data.
1489 */
1490 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
1491 tx_fifo_id);
1492 spin_unlock_irqrestore(&priv->lock, flags);
1493
1494 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1495
1496 return 0;
1497}
1498EXPORT_SYMBOL(iwl_tx_agg_stop);
1499
1500int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
1501{
1502 struct iwl_queue *q = &priv->txq[txq_id].q;
1503 u8 *addr = priv->stations[sta_id].sta.sta.addr;
1504 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
1505
1506 switch (priv->stations[sta_id].tid[tid].agg.state) {
1507 case IWL_EMPTYING_HW_QUEUE_DELBA:
1508 /* We are reclaiming the last packet of the */
1509 /* aggregated HW queue */
1510 if ((txq_id == tid_data->agg.txq_id) &&
1511 (q->read_ptr == q->write_ptr)) {
1512 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1513 int tx_fifo = default_tid_to_tx_fifo[tid];
1514 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
1515 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
1516 ssn, tx_fifo);
1517 tid_data->agg.state = IWL_AGG_OFF;
1518 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid);
1519 }
1520 break;
1521 case IWL_EMPTYING_HW_QUEUE_ADDBA:
1522 /* We are reclaiming the last packet of the queue */
1523 if (tid_data->tfds_in_queue == 0) {
1524 IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
1525 tid_data->agg.state = IWL_AGG_ON;
1526 ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid);
1527 }
1528 break;
1529 }
1530 return 0;
1531}
1532EXPORT_SYMBOL(iwl_txq_check_empty);
1533
1534/**
1535 * iwl_tx_status_reply_compressed_ba - Update tx status from block-ack
1536 *
1537 * Go through block-ack's bitmap of ACK'd frames, update driver's record of
1538 * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
1539 */
1540static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1541 struct iwl_ht_agg *agg,
1542 struct iwl_compressed_ba_resp *ba_resp)
1543
1544{
1545 int i, sh, ack;
1546 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1547 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1548 u64 bitmap;
1549 int successes = 0;
1550 struct ieee80211_tx_info *info;
1551
1552 if (unlikely(!agg->wait_for_ba)) {
1553 IWL_ERR(priv, "Received BA when not expected\n");
1554 return -EINVAL;
1555 }
1556
1557 /* Mark that the expected block-ack response arrived */
1558 agg->wait_for_ba = 0;
1559 IWL_DEBUG_TX_REPLY(priv, "BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
1560
1561 /* Calculate shift to align block-ack bits with our Tx window bits */
1562 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
1563 if (sh < 0) /* tbw something is wrong with indices */
1564 sh += 0x100;
1565
1566 /* don't use 64-bit values for now */
1567 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1568
1569 if (agg->frame_count > (64 - sh)) {
1570 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
1571 return -1;
1572 }
1573
1574 /* check for success or failure according to the
1575 * transmitted bitmap and block-ack bitmap */
1576 bitmap &= agg->bitmap;
1577
1578 /* For each frame attempted in aggregation,
1579 * update driver's record of tx frame's status. */
1580 for (i = 0; i < agg->frame_count ; i++) {
1581 ack = bitmap & (1ULL << i);
1582 successes += !!ack;
1583 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
1584 ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
1585 agg->start_idx + i);
1586 }
1587
1588 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
1589 memset(&info->status, 0, sizeof(info->status));
1590 info->flags |= IEEE80211_TX_STAT_ACK;
1591 info->flags |= IEEE80211_TX_STAT_AMPDU;
1592 info->status.ampdu_ack_map = successes;
1593 info->status.ampdu_ack_len = agg->frame_count;
1594 iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1595
1596 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
1597
1598 return 0;
1599}
1600
1601/**
1602 * iwl_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
1603 *
1604 * Handles block-acknowledge notification from device, which reports success
1605 * of frames sent via aggregation.
1606 */
1607void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1608 struct iwl_rx_mem_buffer *rxb)
1609{
1610 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1611 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1612 struct iwl_tx_queue *txq = NULL;
1613 struct iwl_ht_agg *agg;
1614 int index;
1615 int sta_id;
1616 int tid;
1617
1618 /* "flow" corresponds to Tx queue */
1619 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1620
1621 /* "ssn" is start of block-ack Tx window, corresponds to index
1622 * (in Tx queue's circular buffer) of first TFD/frame in window */
1623 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
1624
1625 if (scd_flow >= priv->hw_params.max_txq_num) {
1626 IWL_ERR(priv,
1627 "BUG_ON scd_flow is bigger than number of queues\n");
1628 return;
1629 }
1630
1631 txq = &priv->txq[scd_flow];
1632 sta_id = ba_resp->sta_id;
1633 tid = ba_resp->tid;
1634 agg = &priv->stations[sta_id].tid[tid].agg;
1635
1636 /* Find index just before block-ack window */
1637 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1638
1639 /* TODO: Need to get this copy more safely - now good for debug */
1640
1641 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
1642 "sta_id = %d\n",
1643 agg->wait_for_ba,
1644 (u8 *) &ba_resp->sta_addr_lo32,
1645 ba_resp->sta_id);
1646 IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
1647 "%d, scd_ssn = %d\n",
1648 ba_resp->tid,
1649 ba_resp->seq_ctl,
1650 (unsigned long long)le64_to_cpu(ba_resp->bitmap),
1651 ba_resp->scd_flow,
1652 ba_resp->scd_ssn);
1653 IWL_DEBUG_TX_REPLY(priv, "DAT start_idx = %d, bitmap = 0x%llx \n",
1654 agg->start_idx,
1655 (unsigned long long)agg->bitmap);
1656
1657 /* Update driver's record of ACK vs. not for each frame in window */
1658 iwl_tx_status_reply_compressed_ba(priv, agg, ba_resp);
1659
1660 /* Release all TFDs before the SSN, i.e. all TFDs in front of
1661 * block-ack window (we assume that they've been successfully
1662 * transmitted ... if not, it's too late anyway). */
1663 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1664 /* calculate mac80211 ampdu sw queue to wake */
1665 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
1666 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1667
1668 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1669 priv->mac80211_registered &&
1670 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1671 iwl_wake_queue(priv, txq->swq_id);
1672
1673 iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
1674 }
1675}
1676EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);
1677
1678#ifdef CONFIG_IWLWIFI_DEBUG 631#ifdef CONFIG_IWLWIFI_DEBUG
1679#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x 632#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
1680 633
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index e276f2a4e835..c9188b9c5651 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -351,11 +351,11 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
351 351
352static void iwl3945_unset_hw_params(struct iwl_priv *priv) 352static void iwl3945_unset_hw_params(struct iwl_priv *priv)
353{ 353{
354 if (priv->shared_virt) 354 if (priv->_3945.shared_virt)
355 dma_free_coherent(&priv->pci_dev->dev, 355 dma_free_coherent(&priv->pci_dev->dev,
356 sizeof(struct iwl3945_shared), 356 sizeof(struct iwl3945_shared),
357 priv->shared_virt, 357 priv->_3945.shared_virt,
358 priv->shared_phys); 358 priv->_3945.shared_phys);
359} 359}
360 360
361static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, 361static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
@@ -504,15 +504,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
504 IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); 504 IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
505#endif 505#endif
506 506
507 /* drop all non-injected data frame if we are not associated */
508 if (ieee80211_is_data(fc) &&
509 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
510 (!iwl_is_associated(priv) ||
511 ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
512 IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
513 goto drop_unlock;
514 }
515
516 spin_unlock_irqrestore(&priv->lock, flags); 507 spin_unlock_irqrestore(&priv->lock, flags);
517 508
518 hdr_len = ieee80211_hdrlen(fc); 509 hdr_len = ieee80211_hdrlen(fc);
@@ -606,9 +597,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
606 txq->need_update = 0; 597 txq->need_update = 0;
607 } 598 }
608 599
609 IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n", 600 IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n",
610 le16_to_cpu(out_cmd->hdr.sequence)); 601 le16_to_cpu(out_cmd->hdr.sequence));
611 IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags)); 602 IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
612 iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd)); 603 iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd));
613 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, 604 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr,
614 ieee80211_hdrlen(fc)); 605 ieee80211_hdrlen(fc));
@@ -753,7 +744,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
753 if (iwl_is_associated(priv)) 744 if (iwl_is_associated(priv))
754 add_time = 745 add_time =
755 iwl3945_usecs_to_beacons( 746 iwl3945_usecs_to_beacons(
756 le64_to_cpu(params->start_time) - priv->last_tsf, 747 le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
757 le16_to_cpu(priv->rxon_timing.beacon_interval)); 748 le16_to_cpu(priv->rxon_timing.beacon_interval));
758 749
759 memset(&spectrum, 0, sizeof(spectrum)); 750 memset(&spectrum, 0, sizeof(spectrum));
@@ -767,7 +758,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
767 758
768 if (iwl_is_associated(priv)) 759 if (iwl_is_associated(priv))
769 spectrum.start_time = 760 spectrum.start_time =
770 iwl3945_add_beacon_time(priv->last_beacon_time, 761 iwl3945_add_beacon_time(priv->_3945.last_beacon_time,
771 add_time, 762 add_time,
772 le16_to_cpu(priv->rxon_timing.beacon_interval)); 763 le16_to_cpu(priv->rxon_timing.beacon_interval));
773 else 764 else
@@ -1946,7 +1937,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1946 added++; 1937 added++;
1947 } 1938 }
1948 1939
1949 IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added); 1940 IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
1950 return added; 1941 return added;
1951} 1942}
1952 1943
@@ -2489,8 +2480,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2489 goto restart; 2480 goto restart;
2490 } 2481 }
2491 2482
2492 iwl_clear_stations_table(priv);
2493
2494 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); 2483 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
2495 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); 2484 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
2496 2485
@@ -2512,13 +2501,19 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2512 /* After the ALIVE response, we can send commands to 3945 uCode */ 2501 /* After the ALIVE response, we can send commands to 3945 uCode */
2513 set_bit(STATUS_ALIVE, &priv->status); 2502 set_bit(STATUS_ALIVE, &priv->status);
2514 2503
2504 if (priv->cfg->ops->lib->recover_from_tx_stall) {
2505 /* Enable timer to monitor the driver queues */
2506 mod_timer(&priv->monitor_recover,
2507 jiffies +
2508 msecs_to_jiffies(priv->cfg->monitor_recover_period));
2509 }
2510
2515 if (iwl_is_rfkill(priv)) 2511 if (iwl_is_rfkill(priv))
2516 return; 2512 return;
2517 2513
2518 ieee80211_wake_queues(priv->hw); 2514 ieee80211_wake_queues(priv->hw);
2519 2515
2520 priv->active_rate = priv->rates_mask; 2516 priv->active_rate = IWL_RATES_MASK;
2521 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
2522 2517
2523 iwl_power_update_mode(priv, true); 2518 iwl_power_update_mode(priv, true);
2524 2519
@@ -2547,17 +2542,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2547 set_bit(STATUS_READY, &priv->status); 2542 set_bit(STATUS_READY, &priv->status);
2548 wake_up_interruptible(&priv->wait_command_queue); 2543 wake_up_interruptible(&priv->wait_command_queue);
2549 2544
2550 /* reassociate for ADHOC mode */
2551 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
2552 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
2553 priv->vif);
2554 if (beacon)
2555 iwl_mac_beacon_update(priv->hw, beacon);
2556 }
2557
2558 if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
2559 iwl_set_mode(priv, priv->iw_mode);
2560
2561 return; 2545 return;
2562 2546
2563 restart: 2547 restart:
@@ -2579,7 +2563,8 @@ static void __iwl3945_down(struct iwl_priv *priv)
2579 if (!exit_pending) 2563 if (!exit_pending)
2580 set_bit(STATUS_EXIT_PENDING, &priv->status); 2564 set_bit(STATUS_EXIT_PENDING, &priv->status);
2581 2565
2582 iwl_clear_stations_table(priv); 2566 /* Station information will now be cleared in device */
2567 iwl_clear_ucode_stations(priv, true);
2583 2568
2584 /* Unblock any waiting calls */ 2569 /* Unblock any waiting calls */
2585 wake_up_interruptible_all(&priv->wait_command_queue); 2570 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2713,12 +2698,10 @@ static int __iwl3945_up(struct iwl_priv *priv)
2713 2698
2714 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2699 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2715 2700
2716 iwl_clear_stations_table(priv);
2717
2718 /* load bootstrap state machine, 2701 /* load bootstrap state machine,
2719 * load bootstrap program into processor's memory, 2702 * load bootstrap program into processor's memory,
2720 * prepare to load the "initialize" uCode */ 2703 * prepare to load the "initialize" uCode */
2721 priv->cfg->ops->lib->load_ucode(priv); 2704 rc = priv->cfg->ops->lib->load_ucode(priv);
2722 2705
2723 if (rc) { 2706 if (rc) {
2724 IWL_ERR(priv, 2707 IWL_ERR(priv,
@@ -2786,7 +2769,7 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
2786static void iwl3945_rfkill_poll(struct work_struct *data) 2769static void iwl3945_rfkill_poll(struct work_struct *data)
2787{ 2770{
2788 struct iwl_priv *priv = 2771 struct iwl_priv *priv =
2789 container_of(data, struct iwl_priv, rfkill_poll.work); 2772 container_of(data, struct iwl_priv, _3945.rfkill_poll.work);
2790 bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); 2773 bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status);
2791 bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) 2774 bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL)
2792 & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); 2775 & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
@@ -2805,7 +2788,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
2805 2788
2806 /* Keep this running, even if radio now enabled. This will be 2789 /* Keep this running, even if radio now enabled. This will be
2807 * cancelled in mac_start() if system decides to start again */ 2790 * cancelled in mac_start() if system decides to start again */
2808 queue_delayed_work(priv->workqueue, &priv->rfkill_poll, 2791 queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll,
2809 round_jiffies_relative(2 * HZ)); 2792 round_jiffies_relative(2 * HZ));
2810 2793
2811} 2794}
@@ -2820,7 +2803,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2820 .len = sizeof(struct iwl3945_scan_cmd), 2803 .len = sizeof(struct iwl3945_scan_cmd),
2821 .flags = CMD_SIZE_HUGE, 2804 .flags = CMD_SIZE_HUGE,
2822 }; 2805 };
2823 int rc = 0;
2824 struct iwl3945_scan_cmd *scan; 2806 struct iwl3945_scan_cmd *scan;
2825 struct ieee80211_conf *conf = NULL; 2807 struct ieee80211_conf *conf = NULL;
2826 u8 n_probes = 0; 2808 u8 n_probes = 0;
@@ -2848,7 +2830,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2848 if (test_bit(STATUS_SCAN_HW, &priv->status)) { 2830 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
2849 IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests " 2831 IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests "
2850 "Ignoring second request.\n"); 2832 "Ignoring second request.\n");
2851 rc = -EIO;
2852 goto done; 2833 goto done;
2853 } 2834 }
2854 2835
@@ -2883,7 +2864,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2883 priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) + 2864 priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) +
2884 IWL_MAX_SCAN_SIZE, GFP_KERNEL); 2865 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
2885 if (!priv->scan) { 2866 if (!priv->scan) {
2886 rc = -ENOMEM; 2867 IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n");
2887 goto done; 2868 goto done;
2888 } 2869 }
2889 } 2870 }
@@ -2926,7 +2907,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2926 scan_suspend_time, interval); 2907 scan_suspend_time, interval);
2927 } 2908 }
2928 2909
2929 if (priv->scan_request->n_ssids) { 2910 if (priv->is_internal_short_scan) {
2911 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
2912 } else if (priv->scan_request->n_ssids) {
2930 int i, p = 0; 2913 int i, p = 0;
2931 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 2914 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
2932 for (i = 0; i < priv->scan_request->n_ssids; i++) { 2915 for (i = 0; i < priv->scan_request->n_ssids; i++) {
@@ -2973,13 +2956,20 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2973 goto done; 2956 goto done;
2974 } 2957 }
2975 2958
2976 scan->tx_cmd.len = cpu_to_le16( 2959 if (!priv->is_internal_short_scan) {
2960 scan->tx_cmd.len = cpu_to_le16(
2977 iwl_fill_probe_req(priv, 2961 iwl_fill_probe_req(priv,
2978 (struct ieee80211_mgmt *)scan->data, 2962 (struct ieee80211_mgmt *)scan->data,
2979 priv->scan_request->ie, 2963 priv->scan_request->ie,
2980 priv->scan_request->ie_len, 2964 priv->scan_request->ie_len,
2981 IWL_MAX_SCAN_SIZE - sizeof(*scan))); 2965 IWL_MAX_SCAN_SIZE - sizeof(*scan)));
2982 2966 } else {
2967 scan->tx_cmd.len = cpu_to_le16(
2968 iwl_fill_probe_req(priv,
2969 (struct ieee80211_mgmt *)scan->data,
2970 NULL, 0,
2971 IWL_MAX_SCAN_SIZE - sizeof(*scan)));
2972 }
2983 /* select Rx antennas */ 2973 /* select Rx antennas */
2984 scan->flags |= iwl3945_get_antenna_flags(priv); 2974 scan->flags |= iwl3945_get_antenna_flags(priv);
2985 2975
@@ -3001,8 +2991,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
3001 scan->len = cpu_to_le16(cmd.len); 2991 scan->len = cpu_to_le16(cmd.len);
3002 2992
3003 set_bit(STATUS_SCAN_HW, &priv->status); 2993 set_bit(STATUS_SCAN_HW, &priv->status);
3004 rc = iwl_send_cmd_sync(priv, &cmd); 2994 if (iwl_send_cmd_sync(priv, &cmd))
3005 if (rc)
3006 goto done; 2995 goto done;
3007 2996
3008 queue_delayed_work(priv->workqueue, &priv->scan_check, 2997 queue_delayed_work(priv->workqueue, &priv->scan_check,
@@ -3134,12 +3123,13 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3134 case NL80211_IFTYPE_ADHOC: 3123 case NL80211_IFTYPE_ADHOC:
3135 3124
3136 priv->assoc_id = 1; 3125 priv->assoc_id = 1;
3137 iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL); 3126 iwl_add_local_station(priv, priv->bssid, false);
3138 iwl3945_sync_sta(priv, IWL_STA_ID, 3127 iwl3945_sync_sta(priv, IWL_STA_ID,
3139 (priv->band == IEEE80211_BAND_5GHZ) ? 3128 (priv->band == IEEE80211_BAND_5GHZ) ?
3140 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, 3129 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
3141 CMD_ASYNC); 3130 CMD_ASYNC);
3142 iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); 3131 iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
3132
3143 iwl3945_send_beacon_cmd(priv); 3133 iwl3945_send_beacon_cmd(priv);
3144 3134
3145 break; 3135 break;
@@ -3150,8 +3140,6 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3150 break; 3140 break;
3151 } 3141 }
3152 3142
3153 iwl_activate_qos(priv, 0);
3154
3155 /* we have just associated, don't start scan too early */ 3143 /* we have just associated, don't start scan too early */
3156 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; 3144 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
3157} 3145}
@@ -3212,7 +3200,7 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
3212 3200
3213 /* ucode is running and will send rfkill notifications, 3201 /* ucode is running and will send rfkill notifications,
3214 * no need to poll the killswitch state anymore */ 3202 * no need to poll the killswitch state anymore */
3215 cancel_delayed_work(&priv->rfkill_poll); 3203 cancel_delayed_work(&priv->_3945.rfkill_poll);
3216 3204
3217 iwl_led_start(priv); 3205 iwl_led_start(priv);
3218 3206
@@ -3253,7 +3241,7 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
3253 flush_workqueue(priv->workqueue); 3241 flush_workqueue(priv->workqueue);
3254 3242
3255 /* start polling the killswitch state again */ 3243 /* start polling the killswitch state again */
3256 queue_delayed_work(priv->workqueue, &priv->rfkill_poll, 3244 queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll,
3257 round_jiffies_relative(2 * HZ)); 3245 round_jiffies_relative(2 * HZ));
3258 3246
3259 IWL_DEBUG_MAC80211(priv, "leave\n"); 3247 IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -3324,7 +3312,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3324 /* restore RXON assoc */ 3312 /* restore RXON assoc */
3325 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3313 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3326 iwlcore_commit_rxon(priv); 3314 iwlcore_commit_rxon(priv);
3327 iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL); 3315 iwl_add_local_station(priv, iwl_bcast_addr, false);
3328 } 3316 }
3329 iwl3945_send_beacon_cmd(priv); 3317 iwl3945_send_beacon_cmd(priv);
3330 3318
@@ -3365,7 +3353,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3365 3353
3366 mutex_lock(&priv->mutex); 3354 mutex_lock(&priv->mutex);
3367 iwl_scan_cancel_timeout(priv, 100); 3355 iwl_scan_cancel_timeout(priv, 100);
3368 mutex_unlock(&priv->mutex);
3369 3356
3370 switch (cmd) { 3357 switch (cmd) {
3371 case SET_KEY: 3358 case SET_KEY:
@@ -3386,11 +3373,44 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3386 ret = -EINVAL; 3373 ret = -EINVAL;
3387 } 3374 }
3388 3375
3376 mutex_unlock(&priv->mutex);
3389 IWL_DEBUG_MAC80211(priv, "leave\n"); 3377 IWL_DEBUG_MAC80211(priv, "leave\n");
3390 3378
3391 return ret; 3379 return ret;
3392} 3380}
3393 3381
3382static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
3383 struct ieee80211_vif *vif,
3384 struct ieee80211_sta *sta)
3385{
3386 struct iwl_priv *priv = hw->priv;
3387 int ret;
3388 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
3389 u8 sta_id;
3390
3391 IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
3392 sta->addr);
3393
3394 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
3395 &sta_id);
3396 if (ret) {
3397 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3398 sta->addr, ret);
3399 /* Should we return success if return code is EEXIST ? */
3400 return ret;
3401 }
3402
3403 /* Initialize rate scaling */
3404 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
3405 sta->addr);
3406 iwl3945_rs_rate_init(priv, sta, sta_id);
3407
3408 return 0;
3409
3410
3411
3412 return ret;
3413}
3394/***************************************************************************** 3414/*****************************************************************************
3395 * 3415 *
3396 * sysfs attributes 3416 * sysfs attributes
@@ -3590,7 +3610,7 @@ static ssize_t store_measurement(struct device *d,
3590 struct iwl_priv *priv = dev_get_drvdata(d); 3610 struct iwl_priv *priv = dev_get_drvdata(d);
3591 struct ieee80211_measurement_params params = { 3611 struct ieee80211_measurement_params params = {
3592 .channel = le16_to_cpu(priv->active_rxon.channel), 3612 .channel = le16_to_cpu(priv->active_rxon.channel),
3593 .start_time = cpu_to_le64(priv->last_tsf), 3613 .start_time = cpu_to_le64(priv->_3945.last_tsf),
3594 .duration = cpu_to_le16(1), 3614 .duration = cpu_to_le16(1),
3595 }; 3615 };
3596 u8 type = IWL_MEASURE_BASIC; 3616 u8 type = IWL_MEASURE_BASIC;
@@ -3660,7 +3680,7 @@ static ssize_t show_statistics(struct device *d,
3660 struct iwl_priv *priv = dev_get_drvdata(d); 3680 struct iwl_priv *priv = dev_get_drvdata(d);
3661 u32 size = sizeof(struct iwl3945_notif_statistics); 3681 u32 size = sizeof(struct iwl3945_notif_statistics);
3662 u32 len = 0, ofs = 0; 3682 u32 len = 0, ofs = 0;
3663 u8 *data = (u8 *)&priv->statistics_39; 3683 u8 *data = (u8 *)&priv->_3945.statistics;
3664 int rc = 0; 3684 int rc = 0;
3665 3685
3666 if (!iwl_is_alive(priv)) 3686 if (!iwl_is_alive(priv))
@@ -3773,7 +3793,7 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3773 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); 3793 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
3774 INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); 3794 INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
3775 INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); 3795 INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
3776 INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll); 3796 INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll);
3777 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); 3797 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
3778 INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan); 3798 INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
3779 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); 3799 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
@@ -3781,6 +3801,13 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3781 3801
3782 iwl3945_hw_setup_deferred_work(priv); 3802 iwl3945_hw_setup_deferred_work(priv);
3783 3803
3804 if (priv->cfg->ops->lib->recover_from_tx_stall) {
3805 init_timer(&priv->monitor_recover);
3806 priv->monitor_recover.data = (unsigned long)priv;
3807 priv->monitor_recover.function =
3808 priv->cfg->ops->lib->recover_from_tx_stall;
3809 }
3810
3784 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3811 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3785 iwl3945_irq_tasklet, (unsigned long)priv); 3812 iwl3945_irq_tasklet, (unsigned long)priv);
3786} 3813}
@@ -3793,6 +3820,8 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
3793 cancel_delayed_work(&priv->scan_check); 3820 cancel_delayed_work(&priv->scan_check);
3794 cancel_delayed_work(&priv->alive_start); 3821 cancel_delayed_work(&priv->alive_start);
3795 cancel_work_sync(&priv->beacon_update); 3822 cancel_work_sync(&priv->beacon_update);
3823 if (priv->cfg->ops->lib->recover_from_tx_stall)
3824 del_timer_sync(&priv->monitor_recover);
3796} 3825}
3797 3826
3798static struct attribute *iwl3945_sysfs_entries[] = { 3827static struct attribute *iwl3945_sysfs_entries[] = {
@@ -3830,7 +3859,9 @@ static struct ieee80211_ops iwl3945_hw_ops = {
3830 .conf_tx = iwl_mac_conf_tx, 3859 .conf_tx = iwl_mac_conf_tx,
3831 .reset_tsf = iwl_mac_reset_tsf, 3860 .reset_tsf = iwl_mac_reset_tsf,
3832 .bss_info_changed = iwl_bss_info_changed, 3861 .bss_info_changed = iwl_bss_info_changed,
3833 .hw_scan = iwl_mac_hw_scan 3862 .hw_scan = iwl_mac_hw_scan,
3863 .sta_add = iwl3945_mac_sta_add,
3864 .sta_remove = iwl_mac_sta_remove,
3834}; 3865};
3835 3866
3836static int iwl3945_init_drv(struct iwl_priv *priv) 3867static int iwl3945_init_drv(struct iwl_priv *priv)
@@ -3849,9 +3880,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3849 mutex_init(&priv->mutex); 3880 mutex_init(&priv->mutex);
3850 mutex_init(&priv->sync_cmd_mutex); 3881 mutex_init(&priv->sync_cmd_mutex);
3851 3882
3852 /* Clear the driver's (not device's) station table */
3853 iwl_clear_stations_table(priv);
3854
3855 priv->ieee_channels = NULL; 3883 priv->ieee_channels = NULL;
3856 priv->ieee_rates = NULL; 3884 priv->ieee_rates = NULL;
3857 priv->band = IEEE80211_BAND_2GHZ; 3885 priv->band = IEEE80211_BAND_2GHZ;
@@ -3859,12 +3887,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3859 priv->iw_mode = NL80211_IFTYPE_STATION; 3887 priv->iw_mode = NL80211_IFTYPE_STATION;
3860 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 3888 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3861 3889
3862 iwl_reset_qos(priv);
3863
3864 priv->qos_data.qos_active = 0;
3865 priv->qos_data.qos_cap.val = 0;
3866
3867 priv->rates_mask = IWL_RATES_MASK;
3868 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; 3890 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
3869 3891
3870 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { 3892 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
@@ -4129,7 +4151,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4129 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); 4151 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
4130 4152
4131 /* Start monitoring the killswitch */ 4153 /* Start monitoring the killswitch */
4132 queue_delayed_work(priv->workqueue, &priv->rfkill_poll, 4154 queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll,
4133 2 * HZ); 4155 2 * HZ);
4134 4156
4135 return 0; 4157 return 0;
@@ -4203,7 +4225,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4203 4225
4204 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); 4226 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
4205 4227
4206 cancel_delayed_work_sync(&priv->rfkill_poll); 4228 cancel_delayed_work_sync(&priv->_3945.rfkill_poll);
4207 4229
4208 iwl3945_dealloc_ucode_pci(priv); 4230 iwl3945_dealloc_ucode_pci(priv);
4209 4231
@@ -4212,7 +4234,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4212 iwl3945_hw_txq_ctx_free(priv); 4234 iwl3945_hw_txq_ctx_free(priv);
4213 4235
4214 iwl3945_unset_hw_params(priv); 4236 iwl3945_unset_hw_params(priv);
4215 iwl_clear_stations_table(priv);
4216 4237
4217 /*netif_stop_queue(dev); */ 4238 /*netif_stop_queue(dev); */
4218 flush_workqueue(priv->workqueue); 4239 flush_workqueue(priv->workqueue);
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
index b9d34a766964..03f998d098c5 100644
--- a/drivers/net/wireless/iwmc3200wifi/Kconfig
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -17,7 +17,7 @@ config IWM
17config IWM_DEBUG 17config IWM_DEBUG
18 bool "Enable full debugging output in iwmc3200wifi" 18 bool "Enable full debugging output in iwmc3200wifi"
19 depends on IWM && DEBUG_FS 19 depends on IWM && DEBUG_FS
20 ---help--- 20 help
21 This option will enable debug tracing and setting for iwm 21 This option will enable debug tracing and setting for iwm
22 22
23 You can set the debug level and module through debugfs. By 23 You can set the debug level and module through debugfs. By
@@ -30,3 +30,10 @@ config IWM_DEBUG
30 Or, if you want the full debug, for all modules: 30 Or, if you want the full debug, for all modules:
31 echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level 31 echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level
32 echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules 32 echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules
33
34config IWM_TRACING
35 bool "Enable event tracing for iwmc3200wifi"
36 depends on IWM && EVENT_TRACING
37 help
38 Say Y here to trace all the commands and responses between
39 the driver and firmware (including TX/RX frames) with ftrace.
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
index d34291b652d3..aeed5cd80819 100644
--- a/drivers/net/wireless/iwmc3200wifi/Makefile
+++ b/drivers/net/wireless/iwmc3200wifi/Makefile
@@ -3,3 +3,6 @@ iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o
3iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o 3iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o
4 4
5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o 5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
6iwmc3200wifi-$(CONFIG_IWM_TRACING) += trace.o
7
8CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 7c4f44a9c3e6..fc239a32cb6b 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -263,7 +263,7 @@ static int iwm_cfg80211_get_station(struct wiphy *wiphy,
263int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) 263int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
264{ 264{
265 struct wiphy *wiphy = iwm_to_wiphy(iwm); 265 struct wiphy *wiphy = iwm_to_wiphy(iwm);
266 struct iwm_bss_info *bss, *next; 266 struct iwm_bss_info *bss;
267 struct iwm_umac_notif_bss_info *umac_bss; 267 struct iwm_umac_notif_bss_info *umac_bss;
268 struct ieee80211_mgmt *mgmt; 268 struct ieee80211_mgmt *mgmt;
269 struct ieee80211_channel *channel; 269 struct ieee80211_channel *channel;
@@ -271,7 +271,7 @@ int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
271 s32 signal; 271 s32 signal;
272 int freq; 272 int freq;
273 273
274 list_for_each_entry_safe(bss, next, &iwm->bss_list, node) { 274 list_for_each_entry(bss, &iwm->bss_list, node) {
275 umac_bss = bss->bss; 275 umac_bss = bss->bss;
276 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf); 276 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
277 277
@@ -725,23 +725,26 @@ static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
725 CFG_POWER_INDEX, iwm->conf.power_index); 725 CFG_POWER_INDEX, iwm->conf.power_index);
726} 726}
727 727
728int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, 728static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
729 struct cfg80211_pmksa *pmksa) 729 struct net_device *netdev,
730 struct cfg80211_pmksa *pmksa)
730{ 731{
731 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 732 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
732 733
733 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD); 734 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
734} 735}
735 736
736int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, 737static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
737 struct cfg80211_pmksa *pmksa) 738 struct net_device *netdev,
739 struct cfg80211_pmksa *pmksa)
738{ 740{
739 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 741 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
740 742
741 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL); 743 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
742} 744}
743 745
744int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) 746static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
747 struct net_device *netdev)
745{ 748{
746 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 749 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
747 struct cfg80211_pmksa pmksa; 750 struct cfg80211_pmksa pmksa;
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 1e41ad0fcad5..b5cbd2bfd52a 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -506,7 +506,7 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
506 return ret; 506 return ret;
507 } 507 }
508 508
509 /* When succeding, the send_target routine returns the seq number */ 509 /* When succeeding, the send_target routine returns the seq number */
510 seq_num = ret; 510 seq_num = ret;
511 511
512 ret = wait_event_interruptible_timeout(iwm->nonwifi_queue, 512 ret = wait_event_interruptible_timeout(iwm->nonwifi_queue,
@@ -781,10 +781,9 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
781 return 0; 781 return 0;
782} 782}
783 783
784int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) 784int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
785{ 785{
786 struct iwm_umac_invalidate_profile invalid; 786 struct iwm_umac_invalidate_profile invalid;
787 int ret;
788 787
789 invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; 788 invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
790 invalid.hdr.buf_size = 789 invalid.hdr.buf_size =
@@ -793,7 +792,14 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
793 792
794 invalid.reason = WLAN_REASON_UNSPECIFIED; 793 invalid.reason = WLAN_REASON_UNSPECIFIED;
795 794
796 ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); 795 return iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
796}
797
798int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
799{
800 int ret;
801
802 ret = __iwm_invalidate_mlme_profile(iwm);
797 if (ret) 803 if (ret)
798 return ret; 804 return ret;
799 805
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index 3dfd9f0e9003..7e16bcf59978 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -488,6 +488,7 @@ int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
488 void *payload, u16 payload_size); 488 void *payload, u16 payload_size);
489int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags); 489int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags);
490int iwm_send_mlme_profile(struct iwm_priv *iwm); 490int iwm_send_mlme_profile(struct iwm_priv *iwm);
491int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
491int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); 492int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
492int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); 493int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
493int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); 494int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index be992ca41cf1..48930c1a0f76 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -265,7 +265,7 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
265 size_t count, loff_t *ppos) 265 size_t count, loff_t *ppos)
266{ 266{
267 struct iwm_priv *iwm = filp->private_data; 267 struct iwm_priv *iwm = filp->private_data;
268 struct iwm_rx_ticket_node *ticket, *next; 268 struct iwm_rx_ticket_node *ticket;
269 char *buf; 269 char *buf;
270 int buf_len = 4096, i; 270 int buf_len = 4096, i;
271 size_t len = 0; 271 size_t len = 0;
@@ -280,7 +280,8 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
280 if (!buf) 280 if (!buf)
281 return -ENOMEM; 281 return -ENOMEM;
282 282
283 list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { 283 spin_lock(&iwm->ticket_lock);
284 list_for_each_entry(ticket, &iwm->rx_tickets, node) {
284 len += snprintf(buf + len, buf_len - len, "Ticket #%d\n", 285 len += snprintf(buf + len, buf_len - len, "Ticket #%d\n",
285 ticket->ticket->id); 286 ticket->ticket->id);
286 len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n", 287 len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n",
@@ -288,14 +289,17 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
288 len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n", 289 len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n",
289 ticket->ticket->flags); 290 ticket->ticket->flags);
290 } 291 }
292 spin_unlock(&iwm->ticket_lock);
291 293
292 for (i = 0; i < IWM_RX_ID_HASH; i++) { 294 for (i = 0; i < IWM_RX_ID_HASH; i++) {
293 struct iwm_rx_packet *packet, *nxt; 295 struct iwm_rx_packet *packet;
294 struct list_head *pkt_list = &iwm->rx_packets[i]; 296 struct list_head *pkt_list = &iwm->rx_packets[i];
297
295 if (!list_empty(pkt_list)) { 298 if (!list_empty(pkt_list)) {
296 len += snprintf(buf + len, buf_len - len, 299 len += snprintf(buf + len, buf_len - len,
297 "Packet hash #%d\n", i); 300 "Packet hash #%d\n", i);
298 list_for_each_entry_safe(packet, nxt, pkt_list, node) { 301 spin_lock(&iwm->packet_lock[i]);
302 list_for_each_entry(packet, pkt_list, node) {
299 len += snprintf(buf + len, buf_len - len, 303 len += snprintf(buf + len, buf_len - len,
300 "\tPacket id: %d\n", 304 "\tPacket id: %d\n",
301 packet->id); 305 packet->id);
@@ -303,6 +307,7 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
303 "\tPacket length: %lu\n", 307 "\tPacket length: %lu\n",
304 packet->pkt_size); 308 packet->pkt_size);
305 } 309 }
310 spin_unlock(&iwm->packet_lock[i]);
306 } 311 }
307 } 312 }
308 313
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
index d13c8853ee82..373b5b5001d2 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.c
+++ b/drivers/net/wireless/iwmc3200wifi/hal.c
@@ -104,6 +104,7 @@
104#include "hal.h" 104#include "hal.h"
105#include "umac.h" 105#include "umac.h"
106#include "debug.h" 106#include "debug.h"
107#include "trace.h"
107 108
108static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm, 109static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
109 struct iwm_nonwifi_cmd *cmd, 110 struct iwm_nonwifi_cmd *cmd,
@@ -206,9 +207,9 @@ void iwm_cmd_flush(struct iwm_priv *iwm)
206 207
207struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) 208struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num)
208{ 209{
209 struct iwm_wifi_cmd *cmd, *next; 210 struct iwm_wifi_cmd *cmd;
210 211
211 list_for_each_entry_safe(cmd, next, &iwm->wifi_pending_cmd, pending) 212 list_for_each_entry(cmd, &iwm->wifi_pending_cmd, pending)
212 if (cmd->seq_num == seq_num) { 213 if (cmd->seq_num == seq_num) {
213 list_del(&cmd->pending); 214 list_del(&cmd->pending);
214 return cmd; 215 return cmd;
@@ -217,12 +218,12 @@ struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num)
217 return NULL; 218 return NULL;
218} 219}
219 220
220struct iwm_nonwifi_cmd * 221struct iwm_nonwifi_cmd *iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm,
221iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, u8 seq_num, u8 cmd_opcode) 222 u8 seq_num, u8 cmd_opcode)
222{ 223{
223 struct iwm_nonwifi_cmd *cmd, *next; 224 struct iwm_nonwifi_cmd *cmd;
224 225
225 list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending) 226 list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending)
226 if ((cmd->seq_num == seq_num) && 227 if ((cmd->seq_num == seq_num) &&
227 (cmd->udma_cmd.opcode == cmd_opcode) && 228 (cmd->udma_cmd.opcode == cmd_opcode) &&
228 (cmd->resp_received)) { 229 (cmd->resp_received)) {
@@ -276,6 +277,7 @@ static int iwm_send_udma_nonwifi_cmd(struct iwm_priv *iwm,
276 udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr, 277 udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr,
277 udma_cmd->op1_sz, udma_cmd->op2); 278 udma_cmd->op1_sz, udma_cmd->op2);
278 279
280 trace_iwm_tx_nonwifi_cmd(iwm, udma_hdr);
279 return iwm_bus_send_chunk(iwm, buf->start, buf->len); 281 return iwm_bus_send_chunk(iwm, buf->start, buf->len);
280} 282}
281 283
@@ -362,6 +364,7 @@ static int iwm_send_udma_wifi_cmd(struct iwm_priv *iwm,
362 return ret; 364 return ret;
363 } 365 }
364 366
367 trace_iwm_tx_wifi_cmd(iwm, umac_hdr);
365 return iwm_bus_send_chunk(iwm, buf->start, buf->len); 368 return iwm_bus_send_chunk(iwm, buf->start, buf->len);
366} 369}
367 370
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.h b/drivers/net/wireless/iwmc3200wifi/hal.h
index 0adfdc85765d..c20936d9b6b7 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.h
+++ b/drivers/net/wireless/iwmc3200wifi/hal.h
@@ -75,7 +75,8 @@ do { \
75 75
76 76
77/* UDMA IN OP CODE -- cmd bits [3:0] */ 77/* UDMA IN OP CODE -- cmd bits [3:0] */
78#define UDMA_IN_OPCODE_MASK 0xF 78#define UDMA_HDI_IN_NW_CMD_OPCODE_POS 0
79#define UDMA_HDI_IN_NW_CMD_OPCODE_SEED 0xF
79 80
80#define UDMA_IN_OPCODE_GENERAL_RESP 0x0 81#define UDMA_IN_OPCODE_GENERAL_RESP 0x0
81#define UDMA_IN_OPCODE_READ_RESP 0x1 82#define UDMA_IN_OPCODE_READ_RESP 0x1
@@ -130,7 +131,7 @@ do { \
130#define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \ 131#define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \
131 IWM_MAX_WIFI_HEADERS_SIZE) 132 IWM_MAX_WIFI_HEADERS_SIZE)
132 133
133#define IWM_HAL_CONCATENATE_BUF_SIZE 8192 134#define IWM_HAL_CONCATENATE_BUF_SIZE (32 * 1024)
134 135
135struct iwm_wifi_cmd_buff { 136struct iwm_wifi_cmd_buff {
136 u16 len; 137 u16 len;
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 79ffa3b98d73..13266c3842f8 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -48,6 +48,7 @@
48#include "umac.h" 48#include "umac.h"
49#include "lmac.h" 49#include "lmac.h"
50#include "eeprom.h" 50#include "eeprom.h"
51#include "trace.h"
51 52
52#define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation" 53#define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation"
53#define IWM_AUTHOR "<ilw@linux.intel.com>" 54#define IWM_AUTHOR "<ilw@linux.intel.com>"
@@ -268,7 +269,9 @@ struct iwm_priv {
268 269
269 struct sk_buff_head rx_list; 270 struct sk_buff_head rx_list;
270 struct list_head rx_tickets; 271 struct list_head rx_tickets;
272 spinlock_t ticket_lock;
271 struct list_head rx_packets[IWM_RX_ID_HASH]; 273 struct list_head rx_packets[IWM_RX_ID_HASH];
274 spinlock_t packet_lock[IWM_RX_ID_HASH];
272 struct workqueue_struct *rx_wq; 275 struct workqueue_struct *rx_wq;
273 struct work_struct rx_worker; 276 struct work_struct rx_worker;
274 277
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 7f34d6dd3c41..3a3510a6223a 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -276,8 +276,11 @@ int iwm_priv_init(struct iwm_priv *iwm)
276 276
277 skb_queue_head_init(&iwm->rx_list); 277 skb_queue_head_init(&iwm->rx_list);
278 INIT_LIST_HEAD(&iwm->rx_tickets); 278 INIT_LIST_HEAD(&iwm->rx_tickets);
279 for (i = 0; i < IWM_RX_ID_HASH; i++) 279 spin_lock_init(&iwm->ticket_lock);
280 for (i = 0; i < IWM_RX_ID_HASH; i++) {
280 INIT_LIST_HEAD(&iwm->rx_packets[i]); 281 INIT_LIST_HEAD(&iwm->rx_packets[i]);
282 spin_lock_init(&iwm->packet_lock[i]);
283 }
281 284
282 INIT_WORK(&iwm->rx_worker, iwm_rx_worker); 285 INIT_WORK(&iwm->rx_worker, iwm_rx_worker);
283 286
@@ -423,9 +426,9 @@ int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd,
423static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd, 426static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd,
424 u8 source) 427 u8 source)
425{ 428{
426 struct iwm_notif *notif, *next; 429 struct iwm_notif *notif;
427 430
428 list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) { 431 list_for_each_entry(notif, &iwm->pending_notif, pending) {
429 if ((notif->cmd_id == cmd) && (notif->src == source)) { 432 if ((notif->cmd_id == cmd) && (notif->src == source)) {
430 list_del(&notif->pending); 433 list_del(&notif->pending);
431 return notif; 434 return notif;
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index ad8f7eabb5aa..5090a8a61887 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -342,15 +342,17 @@ static void iwm_rx_ticket_node_free(struct iwm_rx_ticket_node *ticket_node)
342static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id) 342static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id)
343{ 343{
344 u8 id_hash = IWM_RX_ID_GET_HASH(id); 344 u8 id_hash = IWM_RX_ID_GET_HASH(id);
345 struct list_head *packet_list; 345 struct iwm_rx_packet *packet;
346 struct iwm_rx_packet *packet, *next;
347
348 packet_list = &iwm->rx_packets[id_hash];
349 346
350 list_for_each_entry_safe(packet, next, packet_list, node) 347 spin_lock(&iwm->packet_lock[id_hash]);
351 if (packet->id == id) 348 list_for_each_entry(packet, &iwm->rx_packets[id_hash], node)
349 if (packet->id == id) {
350 list_del(&packet->node);
351 spin_unlock(&iwm->packet_lock[id_hash]);
352 return packet; 352 return packet;
353 }
353 354
355 spin_unlock(&iwm->packet_lock[id_hash]);
354 return NULL; 356 return NULL;
355} 357}
356 358
@@ -388,18 +390,22 @@ void iwm_rx_free(struct iwm_priv *iwm)
388 struct iwm_rx_packet *packet, *np; 390 struct iwm_rx_packet *packet, *np;
389 int i; 391 int i;
390 392
393 spin_lock(&iwm->ticket_lock);
391 list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) { 394 list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) {
392 list_del(&ticket->node); 395 list_del(&ticket->node);
393 iwm_rx_ticket_node_free(ticket); 396 iwm_rx_ticket_node_free(ticket);
394 } 397 }
398 spin_unlock(&iwm->ticket_lock);
395 399
396 for (i = 0; i < IWM_RX_ID_HASH; i++) { 400 for (i = 0; i < IWM_RX_ID_HASH; i++) {
401 spin_lock(&iwm->packet_lock[i]);
397 list_for_each_entry_safe(packet, np, &iwm->rx_packets[i], 402 list_for_each_entry_safe(packet, np, &iwm->rx_packets[i],
398 node) { 403 node) {
399 list_del(&packet->node); 404 list_del(&packet->node);
400 kfree_skb(packet->skb); 405 kfree_skb(packet->skb);
401 kfree(packet); 406 kfree(packet);
402 } 407 }
408 spin_unlock(&iwm->packet_lock[i]);
403 } 409 }
404} 410}
405 411
@@ -427,7 +433,9 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
427 ticket->action == IWM_RX_TICKET_RELEASE ? 433 ticket->action == IWM_RX_TICKET_RELEASE ?
428 "RELEASE" : "DROP", 434 "RELEASE" : "DROP",
429 ticket->id); 435 ticket->id);
436 spin_lock(&iwm->ticket_lock);
430 list_add_tail(&ticket_node->node, &iwm->rx_tickets); 437 list_add_tail(&ticket_node->node, &iwm->rx_tickets);
438 spin_unlock(&iwm->ticket_lock);
431 439
432 /* 440 /*
433 * We received an Rx ticket, most likely there's 441 * We received an Rx ticket, most likely there's
@@ -460,6 +468,7 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf,
460 struct iwm_rx_packet *packet; 468 struct iwm_rx_packet *packet;
461 u16 id, buf_offset; 469 u16 id, buf_offset;
462 u32 packet_size; 470 u32 packet_size;
471 u8 id_hash;
463 472
464 IWM_DBG_RX(iwm, DBG, "\n"); 473 IWM_DBG_RX(iwm, DBG, "\n");
465 474
@@ -477,7 +486,10 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf,
477 if (IS_ERR(packet)) 486 if (IS_ERR(packet))
478 return PTR_ERR(packet); 487 return PTR_ERR(packet);
479 488
480 list_add_tail(&packet->node, &iwm->rx_packets[IWM_RX_ID_GET_HASH(id)]); 489 id_hash = IWM_RX_ID_GET_HASH(id);
490 spin_lock(&iwm->packet_lock[id_hash]);
491 list_add_tail(&packet->node, &iwm->rx_packets[id_hash]);
492 spin_unlock(&iwm->packet_lock[id_hash]);
481 493
482 /* We might (unlikely) have received the packet _after_ the ticket */ 494 /* We might (unlikely) have received the packet _after_ the ticket */
483 queue_work(iwm->rx_wq, &iwm->rx_worker); 495 queue_work(iwm->rx_wq, &iwm->rx_worker);
@@ -518,6 +530,8 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
518 unsigned long buf_size, 530 unsigned long buf_size,
519 struct iwm_wifi_cmd *cmd) 531 struct iwm_wifi_cmd *cmd)
520{ 532{
533 struct wiphy *wiphy = iwm_to_wiphy(iwm);
534 struct ieee80211_channel *chan;
521 struct iwm_umac_notif_assoc_complete *complete = 535 struct iwm_umac_notif_assoc_complete *complete =
522 (struct iwm_umac_notif_assoc_complete *)buf; 536 (struct iwm_umac_notif_assoc_complete *)buf;
523 537
@@ -526,6 +540,18 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
526 540
527 switch (le32_to_cpu(complete->status)) { 541 switch (le32_to_cpu(complete->status)) {
528 case UMAC_ASSOC_COMPLETE_SUCCESS: 542 case UMAC_ASSOC_COMPLETE_SUCCESS:
543 chan = ieee80211_get_channel(wiphy,
544 ieee80211_channel_to_frequency(complete->channel));
545 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
546 /* Associated to a unallowed channel, disassociate. */
547 __iwm_invalidate_mlme_profile(iwm);
548 IWM_WARN(iwm, "Couldn't associate with %pM due to "
549 "channel %d is disabled. Check your local "
550 "regulatory setting.\n",
551 complete->bssid, complete->channel);
552 goto failure;
553 }
554
529 set_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 555 set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
530 memcpy(iwm->bssid, complete->bssid, ETH_ALEN); 556 memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
531 iwm->channel = complete->channel; 557 iwm->channel = complete->channel;
@@ -562,6 +588,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
562 GFP_KERNEL); 588 GFP_KERNEL);
563 break; 589 break;
564 case UMAC_ASSOC_COMPLETE_FAILURE: 590 case UMAC_ASSOC_COMPLETE_FAILURE:
591 failure:
565 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 592 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
566 memset(iwm->bssid, 0, ETH_ALEN); 593 memset(iwm->bssid, 0, ETH_ALEN);
567 iwm->channel = 0; 594 iwm->channel = 0;
@@ -756,7 +783,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
756 (struct iwm_umac_notif_bss_info *)buf; 783 (struct iwm_umac_notif_bss_info *)buf;
757 struct ieee80211_channel *channel; 784 struct ieee80211_channel *channel;
758 struct ieee80211_supported_band *band; 785 struct ieee80211_supported_band *band;
759 struct iwm_bss_info *bss, *next; 786 struct iwm_bss_info *bss;
760 s32 signal; 787 s32 signal;
761 int freq; 788 int freq;
762 u16 frame_len = le16_to_cpu(umac_bss->frame_len); 789 u16 frame_len = le16_to_cpu(umac_bss->frame_len);
@@ -775,7 +802,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
775 IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi); 802 IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi);
776 IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len); 803 IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len);
777 804
778 list_for_each_entry_safe(bss, next, &iwm->bss_list, node) 805 list_for_each_entry(bss, &iwm->bss_list, node)
779 if (bss->bss->table_idx == umac_bss->table_idx) 806 if (bss->bss->table_idx == umac_bss->table_idx)
780 break; 807 break;
781 808
@@ -842,16 +869,15 @@ static int iwm_mlme_remove_bss(struct iwm_priv *iwm, u8 *buf,
842 int i; 869 int i;
843 870
844 for (i = 0; i < le32_to_cpu(bss_rm->count); i++) { 871 for (i = 0; i < le32_to_cpu(bss_rm->count); i++) {
845 table_idx = (le16_to_cpu(bss_rm->entries[i]) 872 table_idx = le16_to_cpu(bss_rm->entries[i]) &
846 & IWM_BSS_REMOVE_INDEX_MSK); 873 IWM_BSS_REMOVE_INDEX_MSK;
847 list_for_each_entry_safe(bss, next, &iwm->bss_list, node) 874 list_for_each_entry_safe(bss, next, &iwm->bss_list, node)
848 if (bss->bss->table_idx == cpu_to_le16(table_idx)) { 875 if (bss->bss->table_idx == cpu_to_le16(table_idx)) {
849 struct ieee80211_mgmt *mgmt; 876 struct ieee80211_mgmt *mgmt;
850 877
851 mgmt = (struct ieee80211_mgmt *) 878 mgmt = (struct ieee80211_mgmt *)
852 (bss->bss->frame_buf); 879 (bss->bss->frame_buf);
853 IWM_DBG_MLME(iwm, ERR, 880 IWM_DBG_MLME(iwm, ERR, "BSS removed: %pM\n",
854 "BSS removed: %pM\n",
855 mgmt->bssid); 881 mgmt->bssid);
856 list_del(&bss->node); 882 list_del(&bss->node);
857 kfree(bss->bss); 883 kfree(bss->bss);
@@ -1223,18 +1249,24 @@ static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf,
1223 u8 source, cmd_id; 1249 u8 source, cmd_id;
1224 u16 seq_num; 1250 u16 seq_num;
1225 u32 count; 1251 u32 count;
1226 u8 resp;
1227 1252
1228 wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf; 1253 wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
1229 cmd_id = wifi_hdr->sw_hdr.cmd.cmd; 1254 cmd_id = wifi_hdr->sw_hdr.cmd.cmd;
1230
1231 source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); 1255 source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
1232 if (source >= IWM_SRC_NUM) { 1256 if (source >= IWM_SRC_NUM) {
1233 IWM_CRIT(iwm, "invalid source %d\n", source); 1257 IWM_CRIT(iwm, "invalid source %d\n", source);
1234 return -EINVAL; 1258 return -EINVAL;
1235 } 1259 }
1236 1260
1237 count = (GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT)); 1261 if (cmd_id == REPLY_RX_MPDU_CMD)
1262 trace_iwm_rx_packet(iwm, buf, buf_size);
1263 else if ((cmd_id == UMAC_NOTIFY_OPCODE_RX_TICKET) &&
1264 (source == UMAC_HDI_IN_SOURCE_FW))
1265 trace_iwm_rx_ticket(iwm, buf, buf_size);
1266 else
1267 trace_iwm_rx_wifi_cmd(iwm, wifi_hdr);
1268
1269 count = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT);
1238 count += sizeof(struct iwm_umac_wifi_in_hdr) - 1270 count += sizeof(struct iwm_umac_wifi_in_hdr) -
1239 sizeof(struct iwm_dev_cmd_hdr); 1271 sizeof(struct iwm_dev_cmd_hdr);
1240 if (count > buf_size) { 1272 if (count > buf_size) {
@@ -1242,8 +1274,6 @@ static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf,
1242 return -EINVAL; 1274 return -EINVAL;
1243 } 1275 }
1244 1276
1245 resp = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_STATUS);
1246
1247 seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num); 1277 seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num);
1248 1278
1249 IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n", 1279 IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n",
@@ -1316,8 +1346,9 @@ static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf,
1316{ 1346{
1317 u8 seq_num; 1347 u8 seq_num;
1318 struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf; 1348 struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf;
1319 struct iwm_nonwifi_cmd *cmd, *next; 1349 struct iwm_nonwifi_cmd *cmd;
1320 1350
1351 trace_iwm_rx_nonwifi_cmd(iwm, buf, buf_size);
1321 seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM); 1352 seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM);
1322 1353
1323 /* 1354 /*
@@ -1328,7 +1359,7 @@ static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf,
1328 * That means we only support synchronised non wifi command response 1359 * That means we only support synchronised non wifi command response
1329 * schemes. 1360 * schemes.
1330 */ 1361 */
1331 list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending) 1362 list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending)
1332 if (cmd->seq_num == seq_num) { 1363 if (cmd->seq_num == seq_num) {
1333 cmd->resp_received = 1; 1364 cmd->resp_received = 1;
1334 cmd->buf.len = buf_size; 1365 cmd->buf.len = buf_size;
@@ -1647,6 +1678,7 @@ void iwm_rx_worker(struct work_struct *work)
1647 * We stop whenever a ticket is missing its packet, as we're 1678 * We stop whenever a ticket is missing its packet, as we're
1648 * supposed to send the packets in order. 1679 * supposed to send the packets in order.
1649 */ 1680 */
1681 spin_lock(&iwm->ticket_lock);
1650 list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { 1682 list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) {
1651 struct iwm_rx_packet *packet = 1683 struct iwm_rx_packet *packet =
1652 iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id)); 1684 iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id));
@@ -1655,12 +1687,12 @@ void iwm_rx_worker(struct work_struct *work)
1655 IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d " 1687 IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d "
1656 "to be handled first\n", 1688 "to be handled first\n",
1657 le16_to_cpu(ticket->ticket->id)); 1689 le16_to_cpu(ticket->ticket->id));
1658 return; 1690 break;
1659 } 1691 }
1660 1692
1661 list_del(&ticket->node); 1693 list_del(&ticket->node);
1662 list_del(&packet->node);
1663 iwm_rx_process_packet(iwm, packet, ticket); 1694 iwm_rx_process_packet(iwm, packet, ticket);
1664 } 1695 }
1696 spin_unlock(&iwm->ticket_lock);
1665} 1697}
1666 1698
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.c b/drivers/net/wireless/iwmc3200wifi/trace.c
new file mode 100644
index 000000000000..904d36f22311
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/trace.c
@@ -0,0 +1,3 @@
1#include "iwm.h"
2#define CREATE_TRACE_POINTS
3#include "trace.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h
new file mode 100644
index 000000000000..320e54fbb38c
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/trace.h
@@ -0,0 +1,283 @@
1#if !defined(__IWM_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ)
2#define __IWM_TRACE_H__
3
4#include <linux/tracepoint.h>
5
6#if !defined(CONFIG_IWM_TRACING)
7#undef TRACE_EVENT
8#define TRACE_EVENT(name, proto, ...) \
9static inline void trace_ ## name(proto) {}
10#endif
11
12#undef TRACE_SYSTEM
13#define TRACE_SYSTEM iwm
14
15#define IWM_ENTRY __array(char, ndev_name, 16)
16#define IWM_ASSIGN strlcpy(__entry->ndev_name, iwm_to_ndev(iwm)->name, 16)
17#define IWM_PR_FMT "%s"
18#define IWM_PR_ARG __entry->ndev_name
19
20TRACE_EVENT(iwm_tx_nonwifi_cmd,
21 TP_PROTO(struct iwm_priv *iwm, struct iwm_udma_out_nonwifi_hdr *hdr),
22
23 TP_ARGS(iwm, hdr),
24
25 TP_STRUCT__entry(
26 IWM_ENTRY
27 __field(u8, opcode)
28 __field(u8, resp)
29 __field(u8, eot)
30 __field(u8, hw)
31 __field(u16, seq)
32 __field(u32, addr)
33 __field(u32, op1)
34 __field(u32, op2)
35 ),
36
37 TP_fast_assign(
38 IWM_ASSIGN;
39 __entry->opcode = GET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_OPCODE);
40 __entry->resp = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_RESP);
41 __entry->eot = GET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT);
42 __entry->hw = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW);
43 __entry->seq = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM);
44 __entry->addr = le32_to_cpu(hdr->addr);
45 __entry->op1 = le32_to_cpu(hdr->op1_sz);
46 __entry->op2 = le32_to_cpu(hdr->op2);
47 ),
48
49 TP_printk(
50 IWM_PR_FMT " Tx TARGET CMD: opcode 0x%x, resp %d, eot %d, "
51 "hw %d, seq 0x%x, addr 0x%x, op1 0x%x, op2 0x%x",
52 IWM_PR_ARG, __entry->opcode, __entry->resp, __entry->eot,
53 __entry->hw, __entry->seq, __entry->addr, __entry->op1,
54 __entry->op2
55 )
56);
57
58TRACE_EVENT(iwm_tx_wifi_cmd,
59 TP_PROTO(struct iwm_priv *iwm, struct iwm_umac_wifi_out_hdr *hdr),
60
61 TP_ARGS(iwm, hdr),
62
63 TP_STRUCT__entry(
64 IWM_ENTRY
65 __field(u8, opcode)
66 __field(u8, lmac)
67 __field(u8, resp)
68 __field(u8, eot)
69 __field(u8, ra_tid)
70 __field(u8, credit_group)
71 __field(u8, color)
72 __field(u16, seq)
73 ),
74
75 TP_fast_assign(
76 IWM_ASSIGN;
77 __entry->opcode = hdr->sw_hdr.cmd.cmd;
78 __entry->lmac = 0;
79 __entry->seq = hdr->sw_hdr.cmd.seq_num;
80 __entry->resp = GET_VAL8(hdr->sw_hdr.cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ);
81 __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
82 __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT);
83 __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID);
84 __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP);
85 if (__entry->opcode == UMAC_CMD_OPCODE_WIFI_PASS_THROUGH ||
86 __entry->opcode == UMAC_CMD_OPCODE_WIFI_IF_WRAPPER) {
87 __entry->lmac = 1;
88 __entry->opcode = ((struct iwm_lmac_hdr *)(hdr + 1))->id;
89 }
90 ),
91
92 TP_printk(
93 IWM_PR_FMT " Tx %cMAC CMD: opcode 0x%x, resp %d, eot %d, "
94 "seq 0x%x, sta_color 0x%x, ra_tid 0x%x, credit_group 0x%x",
95 IWM_PR_ARG, __entry->lmac ? 'L' : 'U', __entry->opcode,
96 __entry->resp, __entry->eot, __entry->seq, __entry->color,
97 __entry->ra_tid, __entry->credit_group
98 )
99);
100
101TRACE_EVENT(iwm_tx_packets,
102 TP_PROTO(struct iwm_priv *iwm, u8 *buf, int len),
103
104 TP_ARGS(iwm, buf, len),
105
106 TP_STRUCT__entry(
107 IWM_ENTRY
108 __field(u8, eot)
109 __field(u8, ra_tid)
110 __field(u8, credit_group)
111 __field(u8, color)
112 __field(u16, seq)
113 __field(u8, npkt)
114 __field(u32, bytes)
115 ),
116
117 TP_fast_assign(
118 struct iwm_umac_wifi_out_hdr *hdr =
119 (struct iwm_umac_wifi_out_hdr *)buf;
120
121 IWM_ASSIGN;
122 __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT);
123 __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID);
124 __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP);
125 __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
126 __entry->seq = hdr->sw_hdr.cmd.seq_num;
127 __entry->npkt = 1;
128 __entry->bytes = len;
129
130 if (!__entry->eot) {
131 int count;
132 u8 *ptr = buf;
133
134 __entry->npkt = 0;
135 while (ptr < buf + len) {
136 count = GET_VAL32(hdr->sw_hdr.meta_data,
137 UMAC_FW_CMD_BYTE_COUNT);
138 ptr += ALIGN(sizeof(*hdr) + count, 16);
139 hdr = (struct iwm_umac_wifi_out_hdr *)ptr;
140 __entry->npkt++;
141 }
142 }
143 ),
144
145 TP_printk(
146 IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, "
147 "ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes",
148 IWM_PR_ARG, !__entry->eot ? "concatenated " : "",
149 __entry->eot, __entry->seq, __entry->color, __entry->ra_tid,
150 __entry->credit_group, __entry->npkt, __entry->bytes
151 )
152);
153
154TRACE_EVENT(iwm_rx_nonwifi_cmd,
155 TP_PROTO(struct iwm_priv *iwm, void *buf, int len),
156
157 TP_ARGS(iwm, buf, len),
158
159 TP_STRUCT__entry(
160 IWM_ENTRY
161 __field(u8, opcode)
162 __field(u16, seq)
163 __field(u32, len)
164 ),
165
166 TP_fast_assign(
167 struct iwm_udma_in_hdr *hdr = buf;
168
169 IWM_ASSIGN;
170 __entry->opcode = GET_VAL32(hdr->cmd, UDMA_HDI_IN_NW_CMD_OPCODE);
171 __entry->seq = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM);
172 __entry->len = len;
173 ),
174
175 TP_printk(
176 IWM_PR_FMT " Rx TARGET RESP: opcode 0x%x, seq 0x%x, len 0x%x",
177 IWM_PR_ARG, __entry->opcode, __entry->seq, __entry->len
178 )
179);
180
181TRACE_EVENT(iwm_rx_wifi_cmd,
182 TP_PROTO(struct iwm_priv *iwm, struct iwm_umac_wifi_in_hdr *hdr),
183
184 TP_ARGS(iwm, hdr),
185
186 TP_STRUCT__entry(
187 IWM_ENTRY
188 __field(u8, cmd)
189 __field(u8, source)
190 __field(u16, seq)
191 __field(u32, count)
192 ),
193
194 TP_fast_assign(
195 IWM_ASSIGN;
196 __entry->cmd = hdr->sw_hdr.cmd.cmd;
197 __entry->source = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
198 __entry->count = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT);
199 __entry->seq = le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
200 ),
201
202 TP_printk(
203 IWM_PR_FMT " Rx %s RESP: cmd 0x%x, seq 0x%x, count 0x%x",
204 IWM_PR_ARG, __entry->source == UMAC_HDI_IN_SOURCE_FHRX ? "LMAC" :
205 __entry->source == UMAC_HDI_IN_SOURCE_FW ? "UMAC" : "UDMA",
206 __entry->cmd, __entry->seq, __entry->count
207 )
208);
209
210#define iwm_ticket_action_symbol \
211 { IWM_RX_TICKET_DROP, "DROP" }, \
212 { IWM_RX_TICKET_RELEASE, "RELEASE" }, \
213 { IWM_RX_TICKET_SNIFFER, "SNIFFER" }, \
214 { IWM_RX_TICKET_ENQUEUE, "ENQUEUE" }
215
216TRACE_EVENT(iwm_rx_ticket,
217 TP_PROTO(struct iwm_priv *iwm, void *buf, int len),
218
219 TP_ARGS(iwm, buf, len),
220
221 TP_STRUCT__entry(
222 IWM_ENTRY
223 __field(u8, action)
224 __field(u8, reason)
225 __field(u16, id)
226 __field(u16, flags)
227 ),
228
229 TP_fast_assign(
230 struct iwm_rx_ticket *ticket =
231 ((struct iwm_umac_notif_rx_ticket *)buf)->tickets;
232
233 IWM_ASSIGN;
234 __entry->id = le16_to_cpu(ticket->id);
235 __entry->action = le16_to_cpu(ticket->action);
236 __entry->flags = le16_to_cpu(ticket->flags);
237 __entry->reason = (__entry->flags & IWM_RX_TICKET_DROP_REASON_MSK) >> IWM_RX_TICKET_DROP_REASON_POS;
238 ),
239
240 TP_printk(
241 IWM_PR_FMT " Rx ticket: id 0x%x, action %s, %s 0x%x%s",
242 IWM_PR_ARG, __entry->id,
243 __print_symbolic(__entry->action, iwm_ticket_action_symbol),
244 __entry->reason ? "reason" : "flags",
245 __entry->reason ? __entry->reason : __entry->flags,
246 __entry->flags & IWM_RX_TICKET_AMSDU_MSK ? ", AMSDU frame" : ""
247 )
248);
249
250TRACE_EVENT(iwm_rx_packet,
251 TP_PROTO(struct iwm_priv *iwm, void *buf, int len),
252
253 TP_ARGS(iwm, buf, len),
254
255 TP_STRUCT__entry(
256 IWM_ENTRY
257 __field(u8, source)
258 __field(u16, id)
259 __field(u32, len)
260 ),
261
262 TP_fast_assign(
263 struct iwm_umac_wifi_in_hdr *hdr = buf;
264
265 IWM_ASSIGN;
266 __entry->source = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
267 __entry->id = le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
268 __entry->len = len - sizeof(*hdr);
269 ),
270
271 TP_printk(
272 IWM_PR_FMT " Rx %s packet: id 0x%x, %d bytes",
273 IWM_PR_ARG, __entry->source == UMAC_HDI_IN_SOURCE_FHRX ?
274 "LMAC" : "UMAC", __entry->id, __entry->len
275 )
276);
277#endif
278
279#undef TRACE_INCLUDE_PATH
280#define TRACE_INCLUDE_PATH .
281#undef TRACE_INCLUDE_FILE
282#define TRACE_INCLUDE_FILE trace
283#include <trace/define_trace.h>
diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c
index 55905f02309c..a20b936ae21f 100644
--- a/drivers/net/wireless/iwmc3200wifi/tx.c
+++ b/drivers/net/wireless/iwmc3200wifi/tx.c
@@ -346,6 +346,7 @@ static int iwm_tx_send_concat_packets(struct iwm_priv *iwm,
346 /* mark EOP for the last packet */ 346 /* mark EOP for the last packet */
347 iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1); 347 iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1);
348 348
349 trace_iwm_tx_packets(iwm, txq->concat_buf, txq->concat_count);
349 ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count); 350 ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count);
350 351
351 txq->concat_count = 0; 352 txq->concat_count = 0;
@@ -450,7 +451,6 @@ void iwm_tx_worker(struct work_struct *work)
450int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) 451int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
451{ 452{
452 struct iwm_priv *iwm = ndev_to_iwm(netdev); 453 struct iwm_priv *iwm = ndev_to_iwm(netdev);
453 struct net_device *ndev = iwm_to_ndev(iwm);
454 struct wireless_dev *wdev = iwm_to_wdev(iwm); 454 struct wireless_dev *wdev = iwm_to_wdev(iwm);
455 struct iwm_tx_info *tx_info; 455 struct iwm_tx_info *tx_info;
456 struct iwm_tx_queue *txq; 456 struct iwm_tx_queue *txq;
@@ -517,12 +517,12 @@ int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
517 517
518 queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker); 518 queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);
519 519
520 ndev->stats.tx_packets++; 520 netdev->stats.tx_packets++;
521 ndev->stats.tx_bytes += skb->len; 521 netdev->stats.tx_bytes += skb->len;
522 return NETDEV_TX_OK; 522 return NETDEV_TX_OK;
523 523
524 drop: 524 drop:
525 ndev->stats.tx_dropped++; 525 netdev->stats.tx_dropped++;
526 dev_kfree_skb_any(skb); 526 dev_kfree_skb_any(skb);
527 return NETDEV_TX_OK; 527 return NETDEV_TX_OK;
528} 528}
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h
index 7f54a145ca65..0cbba3ecc813 100644
--- a/drivers/net/wireless/iwmc3200wifi/umac.h
+++ b/drivers/net/wireless/iwmc3200wifi/umac.h
@@ -362,7 +362,7 @@ struct iwm_udma_out_wifi_hdr {
362#define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4 362#define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4
363#define IWM_RX_TICKET_AMSDU_MSK 0x8 363#define IWM_RX_TICKET_AMSDU_MSK 0x8
364#define IWM_RX_TICKET_DROP_REASON_POS 4 364#define IWM_RX_TICKET_DROP_REASON_POS 4
365#define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << RX_TICKET_FLAGS_DROP_REASON_POS) 365#define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << IWM_RX_TICKET_DROP_REASON_POS)
366 366
367#define IWM_RX_DROP_NO_DROP 0x0 367#define IWM_RX_DROP_NO_DROP 0x0
368#define IWM_RX_DROP_BAD_CRC 0x1 368#define IWM_RX_DROP_BAD_CRC 0x1
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index f03d5e4e59c3..95d3d4c5e08b 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -31,6 +31,9 @@ u8 lbs_bg_rates[MAX_RATES] =
310x00, 0x00 }; 310x00, 0x00 };
32 32
33 33
34static int assoc_helper_wep_keys(struct lbs_private *priv,
35 struct assoc_request *assoc_req);
36
34/** 37/**
35 * @brief This function finds common rates between rates and card rates. 38 * @brief This function finds common rates between rates and card rates.
36 * 39 *
@@ -610,7 +613,7 @@ static int lbs_assoc_post(struct lbs_private *priv,
610 613
611 if (status_code) { 614 if (status_code) {
612 lbs_mac_event_disconnected(priv); 615 lbs_mac_event_disconnected(priv);
613 ret = -1; 616 ret = status_code;
614 goto done; 617 goto done;
615 } 618 }
616 619
@@ -813,7 +816,24 @@ static int lbs_try_associate(struct lbs_private *priv,
813 goto out; 816 goto out;
814 817
815 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE); 818 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
819 /* If the association fails with current auth mode, let's
820 * try by changing the auth mode
821 */
822 if ((priv->authtype_auto) &&
823 (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) &&
824 (assoc_req->secinfo.wep_enabled) &&
825 (priv->connect_status != LBS_CONNECTED)) {
826 if (priv->secinfo.auth_mode == IW_AUTH_ALG_OPEN_SYSTEM)
827 priv->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
828 else
829 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
830 if (!assoc_helper_wep_keys(priv, assoc_req))
831 ret = lbs_associate(priv, assoc_req,
832 CMD_802_11_ASSOCIATE);
833 }
816 834
835 if (ret)
836 ret = -1;
817out: 837out:
818 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 838 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
819 return ret; 839 return ret;
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 587b0cb0088d..9c3c2f82f033 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -74,7 +74,7 @@ static ssize_t lbs_getscantable(struct file *file, char __user *userbuf,
74 return -ENOMEM; 74 return -ENOMEM;
75 75
76 pos += snprintf(buf+pos, len-pos, 76 pos += snprintf(buf+pos, len-pos,
77 "# | ch | rssi | bssid | cap | Qual | SSID \n"); 77 "# | ch | rssi | bssid | cap | Qual | SSID\n");
78 78
79 mutex_lock(&priv->lock); 79 mutex_lock(&priv->lock);
80 list_for_each_entry (iter_bss, &priv->network_list, list) { 80 list_for_each_entry (iter_bss, &priv->network_list, list) {
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 6875e1498bd5..a54880e4ad2b 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -134,6 +134,7 @@ struct lbs_private {
134 u8 wpa_ie_len; 134 u8 wpa_ie_len;
135 u16 wep_tx_keyidx; 135 u16 wep_tx_keyidx;
136 struct enc_key wep_keys[4]; 136 struct enc_key wep_keys[4];
137 u8 authtype_auto;
137 138
138 /* Wake On LAN */ 139 /* Wake On LAN */
139 uint32_t wol_criteria; 140 uint32_t wol_criteria;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 7a73f625273b..33206a98a572 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -34,6 +34,8 @@
34#include <linux/mmc/card.h> 34#include <linux/mmc/card.h>
35#include <linux/mmc/sdio_func.h> 35#include <linux/mmc/sdio_func.h>
36#include <linux/mmc/sdio_ids.h> 36#include <linux/mmc/sdio_ids.h>
37#include <linux/mmc/sdio.h>
38#include <linux/mmc/host.h>
37 39
38#include "host.h" 40#include "host.h"
39#include "decl.h" 41#include "decl.h"
@@ -942,6 +944,7 @@ static int if_sdio_probe(struct sdio_func *func,
942 int ret, i; 944 int ret, i;
943 unsigned int model; 945 unsigned int model;
944 struct if_sdio_packet *packet; 946 struct if_sdio_packet *packet;
947 struct mmc_host *host = func->card->host;
945 948
946 lbs_deb_enter(LBS_DEB_SDIO); 949 lbs_deb_enter(LBS_DEB_SDIO);
947 950
@@ -1022,6 +1025,25 @@ static int if_sdio_probe(struct sdio_func *func,
1022 if (ret) 1025 if (ret)
1023 goto disable; 1026 goto disable;
1024 1027
1028 /* For 1-bit transfers to the 8686 model, we need to enable the
1029 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
1030 * bit to allow access to non-vendor registers. */
1031 if ((card->model == IF_SDIO_MODEL_8686) &&
1032 (host->caps & MMC_CAP_SDIO_IRQ) &&
1033 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
1034 u8 reg;
1035
1036 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
1037 reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
1038 if (ret)
1039 goto release_int;
1040
1041 reg |= SDIO_BUS_ECSI;
1042 sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
1043 if (ret)
1044 goto release_int;
1045 }
1046
1025 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret); 1047 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
1026 if (ret) 1048 if (ret)
1027 goto release_int; 1049 goto release_int;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 28a1c9d1627a..3c889f43d909 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -835,6 +835,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
835 priv->is_auto_deep_sleep_enabled = 0; 835 priv->is_auto_deep_sleep_enabled = 0;
836 priv->wakeup_dev_required = 0; 836 priv->wakeup_dev_required = 0;
837 init_waitqueue_head(&priv->ds_awake_q); 837 init_waitqueue_head(&priv->ds_awake_q);
838 priv->authtype_auto = 1;
838 839
839 mutex_init(&priv->lock); 840 mutex_init(&priv->lock);
840 841
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 2daf8ffdb7e1..7a867e31ca5a 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -38,10 +38,10 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
38 struct sk_buff *skb); 38 struct sk_buff *skb);
39 39
40/** 40/**
41 * @brief This function computes the avgSNR . 41 * @brief This function computes the avgSNR .
42 * 42 *
43 * @param priv A pointer to struct lbs_private structure 43 * @param priv A pointer to struct lbs_private structure
44 * @return avgSNR 44 * @return avgSNR
45 */ 45 */
46static u8 lbs_getavgsnr(struct lbs_private *priv) 46static u8 lbs_getavgsnr(struct lbs_private *priv)
47{ 47{
@@ -56,10 +56,10 @@ static u8 lbs_getavgsnr(struct lbs_private *priv)
56} 56}
57 57
58/** 58/**
59 * @brief This function computes the AvgNF 59 * @brief This function computes the AvgNF
60 * 60 *
61 * @param priv A pointer to struct lbs_private structure 61 * @param priv A pointer to struct lbs_private structure
62 * @return AvgNF 62 * @return AvgNF
63 */ 63 */
64static u8 lbs_getavgnf(struct lbs_private *priv) 64static u8 lbs_getavgnf(struct lbs_private *priv)
65{ 65{
@@ -74,11 +74,11 @@ static u8 lbs_getavgnf(struct lbs_private *priv)
74} 74}
75 75
76/** 76/**
77 * @brief This function save the raw SNR/NF to our internel buffer 77 * @brief This function save the raw SNR/NF to our internel buffer
78 * 78 *
79 * @param priv A pointer to struct lbs_private structure 79 * @param priv A pointer to struct lbs_private structure
80 * @param prxpd A pointer to rxpd structure of received packet 80 * @param prxpd A pointer to rxpd structure of received packet
81 * @return n/a 81 * @return n/a
82 */ 82 */
83static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) 83static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
84{ 84{
@@ -93,11 +93,11 @@ static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
93} 93}
94 94
95/** 95/**
96 * @brief This function computes the RSSI in received packet. 96 * @brief This function computes the RSSI in received packet.
97 * 97 *
98 * @param priv A pointer to struct lbs_private structure 98 * @param priv A pointer to struct lbs_private structure
99 * @param prxpd A pointer to rxpd structure of received packet 99 * @param prxpd A pointer to rxpd structure of received packet
100 * @return n/a 100 * @return n/a
101 */ 101 */
102static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) 102static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
103{ 103{
@@ -134,9 +134,9 @@ static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
134 * @brief This function processes received packet and forwards it 134 * @brief This function processes received packet and forwards it
135 * to kernel/upper layer 135 * to kernel/upper layer
136 * 136 *
137 * @param priv A pointer to struct lbs_private 137 * @param priv A pointer to struct lbs_private
138 * @param skb A pointer to skb which includes the received packet 138 * @param skb A pointer to skb which includes the received packet
139 * @return 0 or -1 139 * @return 0 or -1
140 */ 140 */
141int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) 141int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
142{ 142{
@@ -196,7 +196,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
196 * before the snap_type. 196 * before the snap_type.
197 */ 197 */
198 p_ethhdr = (struct ethhdr *) 198 p_ethhdr = (struct ethhdr *)
199 ((u8 *) & p_rx_pkt->eth803_hdr 199 ((u8 *) &p_rx_pkt->eth803_hdr
200 + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr) 200 + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr)
201 - sizeof(p_rx_pkt->eth803_hdr.dest_addr) 201 - sizeof(p_rx_pkt->eth803_hdr.dest_addr)
202 - sizeof(p_rx_pkt->eth803_hdr.src_addr) 202 - sizeof(p_rx_pkt->eth803_hdr.src_addr)
@@ -213,7 +213,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
213 hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd; 213 hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd;
214 } else { 214 } else {
215 lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP", 215 lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP",
216 (u8 *) & p_rx_pkt->rfc1042_hdr, 216 (u8 *) &p_rx_pkt->rfc1042_hdr,
217 sizeof(p_rx_pkt->rfc1042_hdr)); 217 sizeof(p_rx_pkt->rfc1042_hdr));
218 218
219 /* Chop off the rxpd */ 219 /* Chop off the rxpd */
@@ -254,8 +254,8 @@ EXPORT_SYMBOL_GPL(lbs_process_rxed_packet);
254 * @brief This function converts Tx/Rx rates from the Marvell WLAN format 254 * @brief This function converts Tx/Rx rates from the Marvell WLAN format
255 * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) 255 * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
256 * 256 *
257 * @param rate Input rate 257 * @param rate Input rate
258 * @return Output Rate (0 if invalid) 258 * @return Output Rate (0 if invalid)
259 */ 259 */
260static u8 convert_mv_rate_to_radiotap(u8 rate) 260static u8 convert_mv_rate_to_radiotap(u8 rate)
261{ 261{
@@ -294,9 +294,9 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
294 * @brief This function processes a received 802.11 packet and forwards it 294 * @brief This function processes a received 802.11 packet and forwards it
295 * to kernel/upper layer 295 * to kernel/upper layer
296 * 296 *
297 * @param priv A pointer to struct lbs_private 297 * @param priv A pointer to struct lbs_private
298 * @param skb A pointer to skb which includes the received packet 298 * @param skb A pointer to skb which includes the received packet
299 * @return 0 or -1 299 * @return 0 or -1
300 */ 300 */
301static int process_rxed_802_11_packet(struct lbs_private *priv, 301static int process_rxed_802_11_packet(struct lbs_private *priv,
302 struct sk_buff *skb) 302 struct sk_buff *skb)
@@ -313,7 +313,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
313 p_rx_pkt = (struct rx80211packethdr *) skb->data; 313 p_rx_pkt = (struct rx80211packethdr *) skb->data;
314 prxpd = &p_rx_pkt->rx_pd; 314 prxpd = &p_rx_pkt->rx_pd;
315 315
316 // lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); 316 /* lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); */
317 317
318 if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { 318 if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
319 lbs_deb_rx("rx err: frame received with bad length\n"); 319 lbs_deb_rx("rx err: frame received with bad length\n");
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 71f88a08e090..aad6263dee6d 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1440,8 +1440,10 @@ static int lbs_set_encode(struct net_device *dev,
1440 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); 1440 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
1441 1441
1442 if (dwrq->flags & IW_ENCODE_RESTRICTED) { 1442 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
1443 priv->authtype_auto = 0;
1443 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1444 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1444 } else if (dwrq->flags & IW_ENCODE_OPEN) { 1445 } else if (dwrq->flags & IW_ENCODE_OPEN) {
1446 priv->authtype_auto = 0;
1445 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1447 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1446 } 1448 }
1447 1449
@@ -1620,8 +1622,10 @@ static int lbs_set_encodeext(struct net_device *dev,
1620 goto out; 1622 goto out;
1621 1623
1622 if (dwrq->flags & IW_ENCODE_RESTRICTED) { 1624 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
1625 priv->authtype_auto = 0;
1623 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1626 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1624 } else if (dwrq->flags & IW_ENCODE_OPEN) { 1627 } else if (dwrq->flags & IW_ENCODE_OPEN) {
1628 priv->authtype_auto = 0;
1625 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1629 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1626 } 1630 }
1627 1631
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
index e2a2c18920aa..6116b546861d 100644
--- a/drivers/net/wireless/orinoco/Kconfig
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -27,6 +27,17 @@ config HERMES
27 configure your card and that /etc/pcmcia/wireless.opts works : 27 configure your card and that /etc/pcmcia/wireless.opts works :
28 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html> 28 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
29 29
30config HERMES_PRISM
31 bool "Support Prism 2/2.5 chipset"
32 depends on HERMES
33 ---help---
34
35 Say Y to enable support for Prism 2 and 2.5 chipsets. These
36 chipsets are better handled by the hostap driver. This driver
37 would not support WPA or firmware download for Prism chipset.
38
39 If you are not sure, say N.
40
30config HERMES_CACHE_FW_ON_INIT 41config HERMES_CACHE_FW_ON_INIT
31 bool "Cache Hermes firmware on driver initialisation" 42 bool "Cache Hermes firmware on driver initialisation"
32 depends on HERMES 43 depends on HERMES
@@ -86,7 +97,7 @@ config NORTEL_HERMES
86 97
87config PCI_HERMES 98config PCI_HERMES
88 tristate "Prism 2.5 PCI 802.11b adaptor support" 99 tristate "Prism 2.5 PCI 802.11b adaptor support"
89 depends on PCI && HERMES 100 depends on PCI && HERMES && HERMES_PRISM
90 help 101 help
91 Enable support for PCI and mini-PCI 802.11b wireless NICs based on 102 Enable support for PCI and mini-PCI 802.11b wireless NICs based on
92 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b 103 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index e6369242e49c..883b8f868626 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -262,6 +262,13 @@ int determine_fw_capabilities(struct orinoco_private *priv,
262 if (fw_name) 262 if (fw_name)
263 dev_info(dev, "Firmware determined as %s\n", fw_name); 263 dev_info(dev, "Firmware determined as %s\n", fw_name);
264 264
265#ifndef CONFIG_HERMES_PRISM
266 if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
267 dev_err(dev, "Support for Prism chipset is not enabled\n");
268 return -ENODEV;
269 }
270#endif
271
265 return 0; 272 return 0;
266} 273}
267 274
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 1d4ada188eda..fdc961379170 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -374,87 +374,90 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
374 "Pavel Roskin <proski@gnu.org>, et al)"; 374 "Pavel Roskin <proski@gnu.org>, et al)";
375 375
376static struct pcmcia_device_id orinoco_cs_ids[] = { 376static struct pcmcia_device_id orinoco_cs_ids[] = {
377 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
378 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
379 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
380 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ 377 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
381 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
382 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
383 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ 378 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
384 PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ 379 PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
385 PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ 380 PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
386 PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
387 PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
388 PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ 381 PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
389 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ 382 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
390 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */ 383 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */
391 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ 384 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
392 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
393 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
394 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
395 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
396 PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ 385 PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
397 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ 386 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
398 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ 387 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */
399 PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ 388 PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
389 PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
390 PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
391 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
392 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
393 PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
394 PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
395 PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
396 PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
397 PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
398 PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
399 PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
400 PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
401 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
402 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
403 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
404 PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
405 PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
406 PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
407 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
408 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
409 PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
410 PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
411#ifdef CONFIG_HERMES_PRISM
412 /* Only entries that certainly identify Prism chipset */
413 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
414 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
415 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
416 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
417 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
418 PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
419 PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
420 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
421 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
422 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
423 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
400 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ 424 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
401 PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ 425 PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
402 PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ 426 PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
403 PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ 427 PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
404 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ 428 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
405 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ 429 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
406 PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), 430 PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
407 PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
408 PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), 431 PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
409 PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), 432 PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
410 PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
411 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
412 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
413 PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
414 PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
415 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
416 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), 433 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
417 PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), 434 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
418 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), 435 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
419 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), 436 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
420 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), 437 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
421 PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), 438 PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
439 PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
422 PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), 440 PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
423 PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), 441 PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
424 PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), 442 PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
425 PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
426 PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
427 PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
428 PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
429 PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
430 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), 443 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
431 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), 444 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
432 PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), 445 PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
433 PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
434 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), 446 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
435 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
436 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
437 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
438 PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01), 447 PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
439 PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
440 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
441 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1), 448 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
442 PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767), 449 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
443 PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6), 450 PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
444 PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
445 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264), 451 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
446 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), 452 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
447 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
448 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
449 PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
450 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), 453 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757),
451 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), 454 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
452 PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
453 PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), 455 PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
454 PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092), 456 PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092),
455 PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2), 457 PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),
456 PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b), 458 PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),
457 PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39), 459 PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39),
460#endif
458 PCMCIA_DEVICE_NULL, 461 PCMCIA_DEVICE_NULL,
459}; 462};
460MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); 463MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 31ca241f7753..29f9bc03190a 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -1505,46 +1505,44 @@ static const struct iw_priv_args orinoco_privtab[] = {
1505 * Structures to export the Wireless Handlers 1505 * Structures to export the Wireless Handlers
1506 */ 1506 */
1507 1507
1508#define STD_IW_HANDLER(id, func) \
1509 [IW_IOCTL_IDX(id)] = (iw_handler) func
1510static const iw_handler orinoco_handler[] = { 1508static const iw_handler orinoco_handler[] = {
1511 STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit), 1509 IW_HANDLER(SIOCSIWCOMMIT, (iw_handler)orinoco_ioctl_commit),
1512 STD_IW_HANDLER(SIOCGIWNAME, cfg80211_wext_giwname), 1510 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
1513 STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq), 1511 IW_HANDLER(SIOCSIWFREQ, (iw_handler)orinoco_ioctl_setfreq),
1514 STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq), 1512 IW_HANDLER(SIOCGIWFREQ, (iw_handler)orinoco_ioctl_getfreq),
1515 STD_IW_HANDLER(SIOCSIWMODE, cfg80211_wext_siwmode), 1513 IW_HANDLER(SIOCSIWMODE, (iw_handler)cfg80211_wext_siwmode),
1516 STD_IW_HANDLER(SIOCGIWMODE, cfg80211_wext_giwmode), 1514 IW_HANDLER(SIOCGIWMODE, (iw_handler)cfg80211_wext_giwmode),
1517 STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens), 1515 IW_HANDLER(SIOCSIWSENS, (iw_handler)orinoco_ioctl_setsens),
1518 STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens), 1516 IW_HANDLER(SIOCGIWSENS, (iw_handler)orinoco_ioctl_getsens),
1519 STD_IW_HANDLER(SIOCGIWRANGE, cfg80211_wext_giwrange), 1517 IW_HANDLER(SIOCGIWRANGE, (iw_handler)cfg80211_wext_giwrange),
1520 STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy), 1518 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1521 STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy), 1519 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1522 STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy), 1520 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1523 STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy), 1521 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1524 STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap), 1522 IW_HANDLER(SIOCSIWAP, (iw_handler)orinoco_ioctl_setwap),
1525 STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap), 1523 IW_HANDLER(SIOCGIWAP, (iw_handler)orinoco_ioctl_getwap),
1526 STD_IW_HANDLER(SIOCSIWSCAN, cfg80211_wext_siwscan), 1524 IW_HANDLER(SIOCSIWSCAN, (iw_handler)cfg80211_wext_siwscan),
1527 STD_IW_HANDLER(SIOCGIWSCAN, cfg80211_wext_giwscan), 1525 IW_HANDLER(SIOCGIWSCAN, (iw_handler)cfg80211_wext_giwscan),
1528 STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid), 1526 IW_HANDLER(SIOCSIWESSID, (iw_handler)orinoco_ioctl_setessid),
1529 STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid), 1527 IW_HANDLER(SIOCGIWESSID, (iw_handler)orinoco_ioctl_getessid),
1530 STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate), 1528 IW_HANDLER(SIOCSIWRATE, (iw_handler)orinoco_ioctl_setrate),
1531 STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate), 1529 IW_HANDLER(SIOCGIWRATE, (iw_handler)orinoco_ioctl_getrate),
1532 STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts), 1530 IW_HANDLER(SIOCSIWRTS, (iw_handler)orinoco_ioctl_setrts),
1533 STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts), 1531 IW_HANDLER(SIOCGIWRTS, (iw_handler)orinoco_ioctl_getrts),
1534 STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag), 1532 IW_HANDLER(SIOCSIWFRAG, (iw_handler)orinoco_ioctl_setfrag),
1535 STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag), 1533 IW_HANDLER(SIOCGIWFRAG, (iw_handler)orinoco_ioctl_getfrag),
1536 STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry), 1534 IW_HANDLER(SIOCGIWRETRY, (iw_handler)orinoco_ioctl_getretry),
1537 STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode), 1535 IW_HANDLER(SIOCSIWENCODE, (iw_handler)orinoco_ioctl_setiwencode),
1538 STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode), 1536 IW_HANDLER(SIOCGIWENCODE, (iw_handler)orinoco_ioctl_getiwencode),
1539 STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower), 1537 IW_HANDLER(SIOCSIWPOWER, (iw_handler)orinoco_ioctl_setpower),
1540 STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower), 1538 IW_HANDLER(SIOCGIWPOWER, (iw_handler)orinoco_ioctl_getpower),
1541 STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie), 1539 IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
1542 STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie), 1540 IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
1543 STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme), 1541 IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
1544 STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth), 1542 IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
1545 STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth), 1543 IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
1546 STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext), 1544 IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
1547 STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext), 1545 IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
1548}; 1546};
1549 1547
1550 1548
@@ -1552,15 +1550,15 @@ static const iw_handler orinoco_handler[] = {
1552 Added typecasting since we no longer use iwreq_data -- Moustafa 1550 Added typecasting since we no longer use iwreq_data -- Moustafa
1553 */ 1551 */
1554static const iw_handler orinoco_private_handler[] = { 1552static const iw_handler orinoco_private_handler[] = {
1555 [0] = (iw_handler) orinoco_ioctl_reset, 1553 [0] = (iw_handler)orinoco_ioctl_reset,
1556 [1] = (iw_handler) orinoco_ioctl_reset, 1554 [1] = (iw_handler)orinoco_ioctl_reset,
1557 [2] = (iw_handler) orinoco_ioctl_setport3, 1555 [2] = (iw_handler)orinoco_ioctl_setport3,
1558 [3] = (iw_handler) orinoco_ioctl_getport3, 1556 [3] = (iw_handler)orinoco_ioctl_getport3,
1559 [4] = (iw_handler) orinoco_ioctl_setpreamble, 1557 [4] = (iw_handler)orinoco_ioctl_setpreamble,
1560 [5] = (iw_handler) orinoco_ioctl_getpreamble, 1558 [5] = (iw_handler)orinoco_ioctl_getpreamble,
1561 [6] = (iw_handler) orinoco_ioctl_setibssport, 1559 [6] = (iw_handler)orinoco_ioctl_setibssport,
1562 [7] = (iw_handler) orinoco_ioctl_getibssport, 1560 [7] = (iw_handler)orinoco_ioctl_getibssport,
1563 [9] = (iw_handler) orinoco_ioctl_getrid, 1561 [9] = (iw_handler)orinoco_ioctl_getrid,
1564}; 1562};
1565 1563
1566const struct iw_handler_def orinoco_handler_def = { 1564const struct iw_handler_def orinoco_handler_def = {
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 4f752a21495f..36f4c820ad01 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -545,6 +545,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
545 IEEE80211_HW_SUPPORTS_PS | 545 IEEE80211_HW_SUPPORTS_PS |
546 IEEE80211_HW_PS_NULLFUNC_STACK | 546 IEEE80211_HW_PS_NULLFUNC_STACK |
547 IEEE80211_HW_BEACON_FILTER | 547 IEEE80211_HW_BEACON_FILTER |
548 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
548 IEEE80211_HW_NOISE_DBM; 549 IEEE80211_HW_NOISE_DBM;
549 550
550 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 551 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 66057999a93c..2ceff5480355 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -38,7 +38,7 @@ static void p54_dump_tx_queue(struct p54_common *priv)
38 u32 largest_hole = 0, free; 38 u32 largest_hole = 0, free;
39 39
40 spin_lock_irqsave(&priv->tx_queue.lock, flags); 40 spin_lock_irqsave(&priv->tx_queue.lock, flags);
41 printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) --- \n", 41 printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) ---\n",
42 wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue)); 42 wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue));
43 43
44 prev_addr = priv->rx_start; 44 prev_addr = priv->rx_start;
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index a3ba3539db02..7c82e432cca7 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -227,14 +227,14 @@ islpci_interrupt(int irq, void *config)
227 227
228#if VERBOSE > SHOW_ERROR_MESSAGES 228#if VERBOSE > SHOW_ERROR_MESSAGES
229 DEBUG(SHOW_FUNCTION_CALLS, 229 DEBUG(SHOW_FUNCTION_CALLS,
230 "IRQ: Identification register 0x%p 0x%x \n", device, reg); 230 "IRQ: Identification register 0x%p 0x%x\n", device, reg);
231#endif 231#endif
232 232
233 /* check for each bit in the register separately */ 233 /* check for each bit in the register separately */
234 if (reg & ISL38XX_INT_IDENT_UPDATE) { 234 if (reg & ISL38XX_INT_IDENT_UPDATE) {
235#if VERBOSE > SHOW_ERROR_MESSAGES 235#if VERBOSE > SHOW_ERROR_MESSAGES
236 /* Queue has been updated */ 236 /* Queue has been updated */
237 DEBUG(SHOW_TRACING, "IRQ: Update flag \n"); 237 DEBUG(SHOW_TRACING, "IRQ: Update flag\n");
238 238
239 DEBUG(SHOW_QUEUE_INDEXES, 239 DEBUG(SHOW_QUEUE_INDEXES,
240 "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n", 240 "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n",
@@ -300,7 +300,7 @@ islpci_interrupt(int irq, void *config)
300 ISL38XX_CB_RX_DATA_LQ) != 0) { 300 ISL38XX_CB_RX_DATA_LQ) != 0) {
301#if VERBOSE > SHOW_ERROR_MESSAGES 301#if VERBOSE > SHOW_ERROR_MESSAGES
302 DEBUG(SHOW_TRACING, 302 DEBUG(SHOW_TRACING,
303 "Received frame in Data Low Queue \n"); 303 "Received frame in Data Low Queue\n");
304#endif 304#endif
305 islpci_eth_receive(priv); 305 islpci_eth_receive(priv);
306 } 306 }
@@ -325,7 +325,7 @@ islpci_interrupt(int irq, void *config)
325 /* Device has been initialized */ 325 /* Device has been initialized */
326#if VERBOSE > SHOW_ERROR_MESSAGES 326#if VERBOSE > SHOW_ERROR_MESSAGES
327 DEBUG(SHOW_TRACING, 327 DEBUG(SHOW_TRACING,
328 "IRQ: Init flag, device initialized \n"); 328 "IRQ: Init flag, device initialized\n");
329#endif 329#endif
330 wake_up(&priv->reset_done); 330 wake_up(&priv->reset_done);
331 } 331 }
@@ -333,7 +333,7 @@ islpci_interrupt(int irq, void *config)
333 if (reg & ISL38XX_INT_IDENT_SLEEP) { 333 if (reg & ISL38XX_INT_IDENT_SLEEP) {
334 /* Device intends to move to powersave state */ 334 /* Device intends to move to powersave state */
335#if VERBOSE > SHOW_ERROR_MESSAGES 335#if VERBOSE > SHOW_ERROR_MESSAGES
336 DEBUG(SHOW_TRACING, "IRQ: Sleep flag \n"); 336 DEBUG(SHOW_TRACING, "IRQ: Sleep flag\n");
337#endif 337#endif
338 isl38xx_handle_sleep_request(priv->control_block, 338 isl38xx_handle_sleep_request(priv->control_block,
339 &powerstate, 339 &powerstate,
@@ -343,7 +343,7 @@ islpci_interrupt(int irq, void *config)
343 if (reg & ISL38XX_INT_IDENT_WAKEUP) { 343 if (reg & ISL38XX_INT_IDENT_WAKEUP) {
344 /* Device has been woken up to active state */ 344 /* Device has been woken up to active state */
345#if VERBOSE > SHOW_ERROR_MESSAGES 345#if VERBOSE > SHOW_ERROR_MESSAGES
346 DEBUG(SHOW_TRACING, "IRQ: Wakeup flag \n"); 346 DEBUG(SHOW_TRACING, "IRQ: Wakeup flag\n");
347#endif 347#endif
348 348
349 isl38xx_handle_wakeup(priv->control_block, 349 isl38xx_handle_wakeup(priv->control_block,
@@ -634,7 +634,7 @@ islpci_alloc_memory(islpci_private *priv)
634 ioremap(pci_resource_start(priv->pdev, 0), 634 ioremap(pci_resource_start(priv->pdev, 0),
635 ISL38XX_PCI_MEM_SIZE))) { 635 ISL38XX_PCI_MEM_SIZE))) {
636 /* error in remapping the PCI device memory address range */ 636 /* error in remapping the PCI device memory address range */
637 printk(KERN_ERR "PCI memory remapping failed \n"); 637 printk(KERN_ERR "PCI memory remapping failed\n");
638 return -1; 638 return -1;
639 } 639 }
640 640
@@ -901,7 +901,7 @@ islpci_setup(struct pci_dev *pdev)
901 901
902 if (register_netdev(ndev)) { 902 if (register_netdev(ndev)) {
903 DEBUG(SHOW_ERROR_MESSAGES, 903 DEBUG(SHOW_ERROR_MESSAGES,
904 "ERROR: register_netdev() failed \n"); 904 "ERROR: register_netdev() failed\n");
905 goto do_islpci_free_memory; 905 goto do_islpci_free_memory;
906 } 906 }
907 907
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 872b64783e78..af9e7fbd7640 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -89,7 +89,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
89 u32 curr_frag; 89 u32 curr_frag;
90 90
91#if VERBOSE > SHOW_ERROR_MESSAGES 91#if VERBOSE > SHOW_ERROR_MESSAGES
92 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n"); 92 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit\n");
93#endif 93#endif
94 94
95 /* lock the driver code */ 95 /* lock the driver code */
@@ -140,7 +140,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
140 } 140 }
141 141
142#if VERBOSE > SHOW_ERROR_MESSAGES 142#if VERBOSE > SHOW_ERROR_MESSAGES
143 DEBUG(SHOW_TRACING, "memmove %p %p %i \n", skb->data, 143 DEBUG(SHOW_TRACING, "memmove %p %p %i\n", skb->data,
144 src, skb->len); 144 src, skb->len);
145#endif 145#endif
146 } else { 146 } else {
@@ -319,7 +319,7 @@ islpci_eth_receive(islpci_private *priv)
319 int discard = 0; 319 int discard = 0;
320 320
321#if VERBOSE > SHOW_ERROR_MESSAGES 321#if VERBOSE > SHOW_ERROR_MESSAGES
322 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive \n"); 322 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive\n");
323#endif 323#endif
324 324
325 /* the device has written an Ethernet frame in the data area 325 /* the device has written an Ethernet frame in the data area
@@ -431,7 +431,7 @@ islpci_eth_receive(islpci_private *priv)
431 skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2); 431 skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2);
432 if (unlikely(skb == NULL)) { 432 if (unlikely(skb == NULL)) {
433 /* error allocating an sk_buff structure elements */ 433 /* error allocating an sk_buff structure elements */
434 DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n"); 434 DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb\n");
435 break; 435 break;
436 } 436 }
437 skb_reserve(skb, (4 - (long) skb->data) & 0x03); 437 skb_reserve(skb, (4 - (long) skb->data) & 0x03);
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 69d2f882fd06..89b0278eb7e8 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -113,7 +113,7 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
113 u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]); 113 u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]);
114 114
115#if VERBOSE > SHOW_ERROR_MESSAGES 115#if VERBOSE > SHOW_ERROR_MESSAGES
116 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill \n"); 116 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill\n");
117#endif 117#endif
118 118
119 while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) { 119 while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) {
@@ -211,7 +211,7 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
211 { 211 {
212 pimfor_header_t *h = buf.mem; 212 pimfor_header_t *h = buf.mem;
213 DEBUG(SHOW_PIMFOR_FRAMES, 213 DEBUG(SHOW_PIMFOR_FRAMES,
214 "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x \n", 214 "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x\n",
215 h->operation, oid, h->device_id, h->flags, length); 215 h->operation, oid, h->device_id, h->flags, length);
216 216
217 /* display the buffer contents for debugging */ 217 /* display the buffer contents for debugging */
@@ -279,7 +279,7 @@ islpci_mgt_receive(struct net_device *ndev)
279 u32 curr_frag; 279 u32 curr_frag;
280 280
281#if VERBOSE > SHOW_ERROR_MESSAGES 281#if VERBOSE > SHOW_ERROR_MESSAGES
282 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n"); 282 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive\n");
283#endif 283#endif
284 284
285 /* Only once per interrupt, determine fragment range to 285 /* Only once per interrupt, determine fragment range to
@@ -338,7 +338,7 @@ islpci_mgt_receive(struct net_device *ndev)
338 338
339#if VERBOSE > SHOW_ERROR_MESSAGES 339#if VERBOSE > SHOW_ERROR_MESSAGES
340 DEBUG(SHOW_PIMFOR_FRAMES, 340 DEBUG(SHOW_PIMFOR_FRAMES,
341 "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n", 341 "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x\n",
342 header->operation, header->oid, header->device_id, 342 header->operation, header->oid, header->device_id,
343 header->flags, header->length); 343 header->flags, header->length);
344 344
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 1187e6112a64..07df70a10071 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -819,7 +819,7 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
819 k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr); 819 k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr);
820 for (i = 0; i < list->nr; i++) 820 for (i = 0; i < list->nr; i++)
821 k += snprintf(str + k, PRIV_STR_SIZE - k, 821 k += snprintf(str + k, PRIV_STR_SIZE - k,
822 "bss[%u] : \nage=%u\nchannel=%u\n" 822 "bss[%u] :\nage=%u\nchannel=%u\n"
823 "capinfo=0x%X\nrates=0x%X\n" 823 "capinfo=0x%X\nrates=0x%X\n"
824 "basic_rates=0x%X\n", 824 "basic_rates=0x%X\n",
825 i, list->bsslist[i].age, 825 i, list->bsslist[i].age,
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 84c530aa52f9..f1e916a31668 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -556,7 +556,7 @@ static int ray_init(struct net_device *dev)
556 local->fw_ver = local->startup_res.firmware_version[0]; 556 local->fw_ver = local->startup_res.firmware_version[0];
557 local->fw_bld = local->startup_res.firmware_version[1]; 557 local->fw_bld = local->startup_res.firmware_version[1];
558 local->fw_var = local->startup_res.firmware_version[2]; 558 local->fw_var = local->startup_res.firmware_version[2];
559 dev_dbg(&link->dev, "ray_init firmware version %d.%d \n", local->fw_ver, 559 dev_dbg(&link->dev, "ray_init firmware version %d.%d\n", local->fw_ver,
560 local->fw_bld); 560 local->fw_bld);
561 561
562 local->tib_length = 0x20; 562 local->tib_length = 0x20;
@@ -1113,10 +1113,10 @@ static const struct ethtool_ops netdev_ethtool_ops = {
1113/* 1113/*
1114 * Wireless Handler : get protocol name 1114 * Wireless Handler : get protocol name
1115 */ 1115 */
1116static int ray_get_name(struct net_device *dev, 1116static int ray_get_name(struct net_device *dev, struct iw_request_info *info,
1117 struct iw_request_info *info, char *cwrq, char *extra) 1117 union iwreq_data *wrqu, char *extra)
1118{ 1118{
1119 strcpy(cwrq, "IEEE 802.11-FH"); 1119 strcpy(wrqu->name, "IEEE 802.11-FH");
1120 return 0; 1120 return 0;
1121} 1121}
1122 1122
@@ -1124,9 +1124,8 @@ static int ray_get_name(struct net_device *dev,
1124/* 1124/*
1125 * Wireless Handler : set frequency 1125 * Wireless Handler : set frequency
1126 */ 1126 */
1127static int ray_set_freq(struct net_device *dev, 1127static int ray_set_freq(struct net_device *dev, struct iw_request_info *info,
1128 struct iw_request_info *info, 1128 union iwreq_data *wrqu, char *extra)
1129 struct iw_freq *fwrq, char *extra)
1130{ 1129{
1131 ray_dev_t *local = netdev_priv(dev); 1130 ray_dev_t *local = netdev_priv(dev);
1132 int err = -EINPROGRESS; /* Call commit handler */ 1131 int err = -EINPROGRESS; /* Call commit handler */
@@ -1136,10 +1135,10 @@ static int ray_set_freq(struct net_device *dev,
1136 return -EBUSY; 1135 return -EBUSY;
1137 1136
1138 /* Setting by channel number */ 1137 /* Setting by channel number */
1139 if ((fwrq->m > USA_HOP_MOD) || (fwrq->e > 0)) 1138 if ((wrqu->freq.m > USA_HOP_MOD) || (wrqu->freq.e > 0))
1140 err = -EOPNOTSUPP; 1139 err = -EOPNOTSUPP;
1141 else 1140 else
1142 local->sparm.b5.a_hop_pattern = fwrq->m; 1141 local->sparm.b5.a_hop_pattern = wrqu->freq.m;
1143 1142
1144 return err; 1143 return err;
1145} 1144}
@@ -1148,14 +1147,13 @@ static int ray_set_freq(struct net_device *dev,
1148/* 1147/*
1149 * Wireless Handler : get frequency 1148 * Wireless Handler : get frequency
1150 */ 1149 */
1151static int ray_get_freq(struct net_device *dev, 1150static int ray_get_freq(struct net_device *dev, struct iw_request_info *info,
1152 struct iw_request_info *info, 1151 union iwreq_data *wrqu, char *extra)
1153 struct iw_freq *fwrq, char *extra)
1154{ 1152{
1155 ray_dev_t *local = netdev_priv(dev); 1153 ray_dev_t *local = netdev_priv(dev);
1156 1154
1157 fwrq->m = local->sparm.b5.a_hop_pattern; 1155 wrqu->freq.m = local->sparm.b5.a_hop_pattern;
1158 fwrq->e = 0; 1156 wrqu->freq.e = 0;
1159 return 0; 1157 return 0;
1160} 1158}
1161 1159
@@ -1163,9 +1161,8 @@ static int ray_get_freq(struct net_device *dev,
1163/* 1161/*
1164 * Wireless Handler : set ESSID 1162 * Wireless Handler : set ESSID
1165 */ 1163 */
1166static int ray_set_essid(struct net_device *dev, 1164static int ray_set_essid(struct net_device *dev, struct iw_request_info *info,
1167 struct iw_request_info *info, 1165 union iwreq_data *wrqu, char *extra)
1168 struct iw_point *dwrq, char *extra)
1169{ 1166{
1170 ray_dev_t *local = netdev_priv(dev); 1167 ray_dev_t *local = netdev_priv(dev);
1171 1168
@@ -1174,19 +1171,17 @@ static int ray_set_essid(struct net_device *dev,
1174 return -EBUSY; 1171 return -EBUSY;
1175 1172
1176 /* Check if we asked for `any' */ 1173 /* Check if we asked for `any' */
1177 if (dwrq->flags == 0) { 1174 if (wrqu->essid.flags == 0)
1178 /* Corey : can you do that ? */ 1175 /* Corey : can you do that ? */
1179 return -EOPNOTSUPP; 1176 return -EOPNOTSUPP;
1180 } else {
1181 /* Check the size of the string */
1182 if (dwrq->length > IW_ESSID_MAX_SIZE) {
1183 return -E2BIG;
1184 }
1185 1177
1186 /* Set the ESSID in the card */ 1178 /* Check the size of the string */
1187 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE); 1179 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1188 memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length); 1180 return -E2BIG;
1189 } 1181
1182 /* Set the ESSID in the card */
1183 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE);
1184 memcpy(local->sparm.b5.a_current_ess_id, extra, wrqu->essid.length);
1190 1185
1191 return -EINPROGRESS; /* Call commit handler */ 1186 return -EINPROGRESS; /* Call commit handler */
1192} 1187}
@@ -1195,9 +1190,8 @@ static int ray_set_essid(struct net_device *dev,
1195/* 1190/*
1196 * Wireless Handler : get ESSID 1191 * Wireless Handler : get ESSID
1197 */ 1192 */
1198static int ray_get_essid(struct net_device *dev, 1193static int ray_get_essid(struct net_device *dev, struct iw_request_info *info,
1199 struct iw_request_info *info, 1194 union iwreq_data *wrqu, char *extra)
1200 struct iw_point *dwrq, char *extra)
1201{ 1195{
1202 ray_dev_t *local = netdev_priv(dev); 1196 ray_dev_t *local = netdev_priv(dev);
1203 1197
@@ -1205,8 +1199,8 @@ static int ray_get_essid(struct net_device *dev,
1205 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); 1199 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1206 1200
1207 /* Push it out ! */ 1201 /* Push it out ! */
1208 dwrq->length = strlen(extra); 1202 wrqu->essid.length = strlen(extra);
1209 dwrq->flags = 1; /* active */ 1203 wrqu->essid.flags = 1; /* active */
1210 1204
1211 return 0; 1205 return 0;
1212} 1206}
@@ -1215,14 +1209,13 @@ static int ray_get_essid(struct net_device *dev,
1215/* 1209/*
1216 * Wireless Handler : get AP address 1210 * Wireless Handler : get AP address
1217 */ 1211 */
1218static int ray_get_wap(struct net_device *dev, 1212static int ray_get_wap(struct net_device *dev, struct iw_request_info *info,
1219 struct iw_request_info *info, 1213 union iwreq_data *wrqu, char *extra)
1220 struct sockaddr *awrq, char *extra)
1221{ 1214{
1222 ray_dev_t *local = netdev_priv(dev); 1215 ray_dev_t *local = netdev_priv(dev);
1223 1216
1224 memcpy(awrq->sa_data, local->bss_id, ETH_ALEN); 1217 memcpy(wrqu->ap_addr.sa_data, local->bss_id, ETH_ALEN);
1225 awrq->sa_family = ARPHRD_ETHER; 1218 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1226 1219
1227 return 0; 1220 return 0;
1228} 1221}
@@ -1231,9 +1224,8 @@ static int ray_get_wap(struct net_device *dev,
1231/* 1224/*
1232 * Wireless Handler : set Bit-Rate 1225 * Wireless Handler : set Bit-Rate
1233 */ 1226 */
1234static int ray_set_rate(struct net_device *dev, 1227static int ray_set_rate(struct net_device *dev, struct iw_request_info *info,
1235 struct iw_request_info *info, 1228 union iwreq_data *wrqu, char *extra)
1236 struct iw_param *vwrq, char *extra)
1237{ 1229{
1238 ray_dev_t *local = netdev_priv(dev); 1230 ray_dev_t *local = netdev_priv(dev);
1239 1231
@@ -1242,15 +1234,15 @@ static int ray_set_rate(struct net_device *dev,
1242 return -EBUSY; 1234 return -EBUSY;
1243 1235
1244 /* Check if rate is in range */ 1236 /* Check if rate is in range */
1245 if ((vwrq->value != 1000000) && (vwrq->value != 2000000)) 1237 if ((wrqu->bitrate.value != 1000000) && (wrqu->bitrate.value != 2000000))
1246 return -EINVAL; 1238 return -EINVAL;
1247 1239
1248 /* Hack for 1.5 Mb/s instead of 2 Mb/s */ 1240 /* Hack for 1.5 Mb/s instead of 2 Mb/s */
1249 if ((local->fw_ver == 0x55) && /* Please check */ 1241 if ((local->fw_ver == 0x55) && /* Please check */
1250 (vwrq->value == 2000000)) 1242 (wrqu->bitrate.value == 2000000))
1251 local->net_default_tx_rate = 3; 1243 local->net_default_tx_rate = 3;
1252 else 1244 else
1253 local->net_default_tx_rate = vwrq->value / 500000; 1245 local->net_default_tx_rate = wrqu->bitrate.value / 500000;
1254 1246
1255 return 0; 1247 return 0;
1256} 1248}
@@ -1259,17 +1251,16 @@ static int ray_set_rate(struct net_device *dev,
1259/* 1251/*
1260 * Wireless Handler : get Bit-Rate 1252 * Wireless Handler : get Bit-Rate
1261 */ 1253 */
1262static int ray_get_rate(struct net_device *dev, 1254static int ray_get_rate(struct net_device *dev, struct iw_request_info *info,
1263 struct iw_request_info *info, 1255 union iwreq_data *wrqu, char *extra)
1264 struct iw_param *vwrq, char *extra)
1265{ 1256{
1266 ray_dev_t *local = netdev_priv(dev); 1257 ray_dev_t *local = netdev_priv(dev);
1267 1258
1268 if (local->net_default_tx_rate == 3) 1259 if (local->net_default_tx_rate == 3)
1269 vwrq->value = 2000000; /* Hum... */ 1260 wrqu->bitrate.value = 2000000; /* Hum... */
1270 else 1261 else
1271 vwrq->value = local->net_default_tx_rate * 500000; 1262 wrqu->bitrate.value = local->net_default_tx_rate * 500000;
1272 vwrq->fixed = 0; /* We are in auto mode */ 1263 wrqu->bitrate.fixed = 0; /* We are in auto mode */
1273 1264
1274 return 0; 1265 return 0;
1275} 1266}
@@ -1278,19 +1269,18 @@ static int ray_get_rate(struct net_device *dev,
1278/* 1269/*
1279 * Wireless Handler : set RTS threshold 1270 * Wireless Handler : set RTS threshold
1280 */ 1271 */
1281static int ray_set_rts(struct net_device *dev, 1272static int ray_set_rts(struct net_device *dev, struct iw_request_info *info,
1282 struct iw_request_info *info, 1273 union iwreq_data *wrqu, char *extra)
1283 struct iw_param *vwrq, char *extra)
1284{ 1274{
1285 ray_dev_t *local = netdev_priv(dev); 1275 ray_dev_t *local = netdev_priv(dev);
1286 int rthr = vwrq->value; 1276 int rthr = wrqu->rts.value;
1287 1277
1288 /* Reject if card is already initialised */ 1278 /* Reject if card is already initialised */
1289 if (local->card_status != CARD_AWAITING_PARAM) 1279 if (local->card_status != CARD_AWAITING_PARAM)
1290 return -EBUSY; 1280 return -EBUSY;
1291 1281
1292 /* if(wrq->u.rts.fixed == 0) we should complain */ 1282 /* if(wrq->u.rts.fixed == 0) we should complain */
1293 if (vwrq->disabled) 1283 if (wrqu->rts.disabled)
1294 rthr = 32767; 1284 rthr = 32767;
1295 else { 1285 else {
1296 if ((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ 1286 if ((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
@@ -1306,16 +1296,15 @@ static int ray_set_rts(struct net_device *dev,
1306/* 1296/*
1307 * Wireless Handler : get RTS threshold 1297 * Wireless Handler : get RTS threshold
1308 */ 1298 */
1309static int ray_get_rts(struct net_device *dev, 1299static int ray_get_rts(struct net_device *dev, struct iw_request_info *info,
1310 struct iw_request_info *info, 1300 union iwreq_data *wrqu, char *extra)
1311 struct iw_param *vwrq, char *extra)
1312{ 1301{
1313 ray_dev_t *local = netdev_priv(dev); 1302 ray_dev_t *local = netdev_priv(dev);
1314 1303
1315 vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8) 1304 wrqu->rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1316 + local->sparm.b5.a_rts_threshold[1]; 1305 + local->sparm.b5.a_rts_threshold[1];
1317 vwrq->disabled = (vwrq->value == 32767); 1306 wrqu->rts.disabled = (wrqu->rts.value == 32767);
1318 vwrq->fixed = 1; 1307 wrqu->rts.fixed = 1;
1319 1308
1320 return 0; 1309 return 0;
1321} 1310}
@@ -1324,19 +1313,18 @@ static int ray_get_rts(struct net_device *dev,
1324/* 1313/*
1325 * Wireless Handler : set Fragmentation threshold 1314 * Wireless Handler : set Fragmentation threshold
1326 */ 1315 */
1327static int ray_set_frag(struct net_device *dev, 1316static int ray_set_frag(struct net_device *dev, struct iw_request_info *info,
1328 struct iw_request_info *info, 1317 union iwreq_data *wrqu, char *extra)
1329 struct iw_param *vwrq, char *extra)
1330{ 1318{
1331 ray_dev_t *local = netdev_priv(dev); 1319 ray_dev_t *local = netdev_priv(dev);
1332 int fthr = vwrq->value; 1320 int fthr = wrqu->frag.value;
1333 1321
1334 /* Reject if card is already initialised */ 1322 /* Reject if card is already initialised */
1335 if (local->card_status != CARD_AWAITING_PARAM) 1323 if (local->card_status != CARD_AWAITING_PARAM)
1336 return -EBUSY; 1324 return -EBUSY;
1337 1325
1338 /* if(wrq->u.frag.fixed == 0) should complain */ 1326 /* if(wrq->u.frag.fixed == 0) should complain */
1339 if (vwrq->disabled) 1327 if (wrqu->frag.disabled)
1340 fthr = 32767; 1328 fthr = 32767;
1341 else { 1329 else {
1342 if ((fthr < 256) || (fthr > 2347)) /* To check out ! */ 1330 if ((fthr < 256) || (fthr > 2347)) /* To check out ! */
@@ -1352,16 +1340,15 @@ static int ray_set_frag(struct net_device *dev,
1352/* 1340/*
1353 * Wireless Handler : get Fragmentation threshold 1341 * Wireless Handler : get Fragmentation threshold
1354 */ 1342 */
1355static int ray_get_frag(struct net_device *dev, 1343static int ray_get_frag(struct net_device *dev, struct iw_request_info *info,
1356 struct iw_request_info *info, 1344 union iwreq_data *wrqu, char *extra)
1357 struct iw_param *vwrq, char *extra)
1358{ 1345{
1359 ray_dev_t *local = netdev_priv(dev); 1346 ray_dev_t *local = netdev_priv(dev);
1360 1347
1361 vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8) 1348 wrqu->frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1362 + local->sparm.b5.a_frag_threshold[1]; 1349 + local->sparm.b5.a_frag_threshold[1];
1363 vwrq->disabled = (vwrq->value == 32767); 1350 wrqu->frag.disabled = (wrqu->frag.value == 32767);
1364 vwrq->fixed = 1; 1351 wrqu->frag.fixed = 1;
1365 1352
1366 return 0; 1353 return 0;
1367} 1354}
@@ -1370,8 +1357,8 @@ static int ray_get_frag(struct net_device *dev,
1370/* 1357/*
1371 * Wireless Handler : set Mode of Operation 1358 * Wireless Handler : set Mode of Operation
1372 */ 1359 */
1373static int ray_set_mode(struct net_device *dev, 1360static int ray_set_mode(struct net_device *dev, struct iw_request_info *info,
1374 struct iw_request_info *info, __u32 *uwrq, char *extra) 1361 union iwreq_data *wrqu, char *extra)
1375{ 1362{
1376 ray_dev_t *local = netdev_priv(dev); 1363 ray_dev_t *local = netdev_priv(dev);
1377 int err = -EINPROGRESS; /* Call commit handler */ 1364 int err = -EINPROGRESS; /* Call commit handler */
@@ -1381,7 +1368,7 @@ static int ray_set_mode(struct net_device *dev,
1381 if (local->card_status != CARD_AWAITING_PARAM) 1368 if (local->card_status != CARD_AWAITING_PARAM)
1382 return -EBUSY; 1369 return -EBUSY;
1383 1370
1384 switch (*uwrq) { 1371 switch (wrqu->mode) {
1385 case IW_MODE_ADHOC: 1372 case IW_MODE_ADHOC:
1386 card_mode = 0; 1373 card_mode = 0;
1387 /* Fall through */ 1374 /* Fall through */
@@ -1399,15 +1386,15 @@ static int ray_set_mode(struct net_device *dev,
1399/* 1386/*
1400 * Wireless Handler : get Mode of Operation 1387 * Wireless Handler : get Mode of Operation
1401 */ 1388 */
1402static int ray_get_mode(struct net_device *dev, 1389static int ray_get_mode(struct net_device *dev, struct iw_request_info *info,
1403 struct iw_request_info *info, __u32 *uwrq, char *extra) 1390 union iwreq_data *wrqu, char *extra)
1404{ 1391{
1405 ray_dev_t *local = netdev_priv(dev); 1392 ray_dev_t *local = netdev_priv(dev);
1406 1393
1407 if (local->sparm.b5.a_network_type) 1394 if (local->sparm.b5.a_network_type)
1408 *uwrq = IW_MODE_INFRA; 1395 wrqu->mode = IW_MODE_INFRA;
1409 else 1396 else
1410 *uwrq = IW_MODE_ADHOC; 1397 wrqu->mode = IW_MODE_ADHOC;
1411 1398
1412 return 0; 1399 return 0;
1413} 1400}
@@ -1416,16 +1403,15 @@ static int ray_get_mode(struct net_device *dev,
1416/* 1403/*
1417 * Wireless Handler : get range info 1404 * Wireless Handler : get range info
1418 */ 1405 */
1419static int ray_get_range(struct net_device *dev, 1406static int ray_get_range(struct net_device *dev, struct iw_request_info *info,
1420 struct iw_request_info *info, 1407 union iwreq_data *wrqu, char *extra)
1421 struct iw_point *dwrq, char *extra)
1422{ 1408{
1423 struct iw_range *range = (struct iw_range *)extra; 1409 struct iw_range *range = (struct iw_range *)extra;
1424 1410
1425 memset((char *)range, 0, sizeof(struct iw_range)); 1411 memset(range, 0, sizeof(struct iw_range));
1426 1412
1427 /* Set the length (very important for backward compatibility) */ 1413 /* Set the length (very important for backward compatibility) */
1428 dwrq->length = sizeof(struct iw_range); 1414 wrqu->data.length = sizeof(struct iw_range);
1429 1415
1430 /* Set the Wireless Extension versions */ 1416 /* Set the Wireless Extension versions */
1431 range->we_version_compiled = WIRELESS_EXT; 1417 range->we_version_compiled = WIRELESS_EXT;
@@ -1448,8 +1434,7 @@ static int ray_get_range(struct net_device *dev,
1448/* 1434/*
1449 * Wireless Private Handler : set framing mode 1435 * Wireless Private Handler : set framing mode
1450 */ 1436 */
1451static int ray_set_framing(struct net_device *dev, 1437static int ray_set_framing(struct net_device *dev, struct iw_request_info *info,
1452 struct iw_request_info *info,
1453 union iwreq_data *wrqu, char *extra) 1438 union iwreq_data *wrqu, char *extra)
1454{ 1439{
1455 translate = *(extra); /* Set framing mode */ 1440 translate = *(extra); /* Set framing mode */
@@ -1461,8 +1446,7 @@ static int ray_set_framing(struct net_device *dev,
1461/* 1446/*
1462 * Wireless Private Handler : get framing mode 1447 * Wireless Private Handler : get framing mode
1463 */ 1448 */
1464static int ray_get_framing(struct net_device *dev, 1449static int ray_get_framing(struct net_device *dev, struct iw_request_info *info,
1465 struct iw_request_info *info,
1466 union iwreq_data *wrqu, char *extra) 1450 union iwreq_data *wrqu, char *extra)
1467{ 1451{
1468 *(extra) = translate; 1452 *(extra) = translate;
@@ -1474,8 +1458,7 @@ static int ray_get_framing(struct net_device *dev,
1474/* 1458/*
1475 * Wireless Private Handler : get country 1459 * Wireless Private Handler : get country
1476 */ 1460 */
1477static int ray_get_country(struct net_device *dev, 1461static int ray_get_country(struct net_device *dev, struct iw_request_info *info,
1478 struct iw_request_info *info,
1479 union iwreq_data *wrqu, char *extra) 1462 union iwreq_data *wrqu, char *extra)
1480{ 1463{
1481 *(extra) = country; 1464 *(extra) = country;
@@ -1487,10 +1470,9 @@ static int ray_get_country(struct net_device *dev,
1487/* 1470/*
1488 * Commit handler : called after a bunch of SET operations 1471 * Commit handler : called after a bunch of SET operations
1489 */ 1472 */
1490static int ray_commit(struct net_device *dev, struct iw_request_info *info, /* NULL */ 1473static int ray_commit(struct net_device *dev, struct iw_request_info *info,
1491 void *zwrq, /* NULL */ 1474 union iwreq_data *wrqu, char *extra)
1492 char *extra) 1475{
1493{ /* NULL */
1494 return 0; 1476 return 0;
1495} 1477}
1496 1478
@@ -1531,28 +1513,28 @@ static iw_stats *ray_get_wireless_stats(struct net_device *dev)
1531 */ 1513 */
1532 1514
1533static const iw_handler ray_handler[] = { 1515static const iw_handler ray_handler[] = {
1534 [SIOCSIWCOMMIT - SIOCIWFIRST] = (iw_handler) ray_commit, 1516 IW_HANDLER(SIOCSIWCOMMIT, ray_commit),
1535 [SIOCGIWNAME - SIOCIWFIRST] = (iw_handler) ray_get_name, 1517 IW_HANDLER(SIOCGIWNAME, ray_get_name),
1536 [SIOCSIWFREQ - SIOCIWFIRST] = (iw_handler) ray_set_freq, 1518 IW_HANDLER(SIOCSIWFREQ, ray_set_freq),
1537 [SIOCGIWFREQ - SIOCIWFIRST] = (iw_handler) ray_get_freq, 1519 IW_HANDLER(SIOCGIWFREQ, ray_get_freq),
1538 [SIOCSIWMODE - SIOCIWFIRST] = (iw_handler) ray_set_mode, 1520 IW_HANDLER(SIOCSIWMODE, ray_set_mode),
1539 [SIOCGIWMODE - SIOCIWFIRST] = (iw_handler) ray_get_mode, 1521 IW_HANDLER(SIOCGIWMODE, ray_get_mode),
1540 [SIOCGIWRANGE - SIOCIWFIRST] = (iw_handler) ray_get_range, 1522 IW_HANDLER(SIOCGIWRANGE, ray_get_range),
1541#ifdef WIRELESS_SPY 1523#ifdef WIRELESS_SPY
1542 [SIOCSIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_spy, 1524 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1543 [SIOCGIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_spy, 1525 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1544 [SIOCSIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy, 1526 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1545 [SIOCGIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy, 1527 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1546#endif /* WIRELESS_SPY */ 1528#endif /* WIRELESS_SPY */
1547 [SIOCGIWAP - SIOCIWFIRST] = (iw_handler) ray_get_wap, 1529 IW_HANDLER(SIOCGIWAP, ray_get_wap),
1548 [SIOCSIWESSID - SIOCIWFIRST] = (iw_handler) ray_set_essid, 1530 IW_HANDLER(SIOCSIWESSID, ray_set_essid),
1549 [SIOCGIWESSID - SIOCIWFIRST] = (iw_handler) ray_get_essid, 1531 IW_HANDLER(SIOCGIWESSID, ray_get_essid),
1550 [SIOCSIWRATE - SIOCIWFIRST] = (iw_handler) ray_set_rate, 1532 IW_HANDLER(SIOCSIWRATE, ray_set_rate),
1551 [SIOCGIWRATE - SIOCIWFIRST] = (iw_handler) ray_get_rate, 1533 IW_HANDLER(SIOCGIWRATE, ray_get_rate),
1552 [SIOCSIWRTS - SIOCIWFIRST] = (iw_handler) ray_set_rts, 1534 IW_HANDLER(SIOCSIWRTS, ray_set_rts),
1553 [SIOCGIWRTS - SIOCIWFIRST] = (iw_handler) ray_get_rts, 1535 IW_HANDLER(SIOCGIWRTS, ray_get_rts),
1554 [SIOCSIWFRAG - SIOCIWFIRST] = (iw_handler) ray_set_frag, 1536 IW_HANDLER(SIOCSIWFRAG, ray_set_frag),
1555 [SIOCGIWFRAG - SIOCIWFIRST] = (iw_handler) ray_get_frag, 1537 IW_HANDLER(SIOCGIWFRAG, ray_get_frag),
1556}; 1538};
1557 1539
1558#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ 1540#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
@@ -1560,9 +1542,9 @@ static const iw_handler ray_handler[] = {
1560#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ 1542#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
1561 1543
1562static const iw_handler ray_private_handler[] = { 1544static const iw_handler ray_private_handler[] = {
1563 [0] = (iw_handler) ray_set_framing, 1545 [0] = ray_set_framing,
1564 [1] = (iw_handler) ray_get_framing, 1546 [1] = ray_get_framing,
1565 [3] = (iw_handler) ray_get_country, 1547 [3] = ray_get_country,
1566}; 1548};
1567 1549
1568static const struct iw_priv_args ray_private_args[] = { 1550static const struct iw_priv_args ray_private_args[] = {
@@ -2252,7 +2234,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
2252 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + 2234 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2253 FCS_LEN)) { 2235 FCS_LEN)) {
2254 pr_debug( 2236 pr_debug(
2255 "ray_cs invalid packet length %d received \n", 2237 "ray_cs invalid packet length %d received\n",
2256 rx_len); 2238 rx_len);
2257 return; 2239 return;
2258 } 2240 }
@@ -2263,7 +2245,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
2263 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + 2245 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2264 FCS_LEN)) { 2246 FCS_LEN)) {
2265 pr_debug( 2247 pr_debug(
2266 "ray_cs invalid packet length %d received \n", 2248 "ray_cs invalid packet length %d received\n",
2267 rx_len); 2249 rx_len);
2268 return; 2250 return;
2269 } 2251 }
@@ -2771,11 +2753,11 @@ static int ray_cs_proc_show(struct seq_file *m, void *v)
2771 seq_printf(m, "Hop dwell = %d Kus\n", 2753 seq_printf(m, "Hop dwell = %d Kus\n",
2772 pfh->dwell_time[0] + 2754 pfh->dwell_time[0] +
2773 256 * pfh->dwell_time[1]); 2755 256 * pfh->dwell_time[1]);
2774 seq_printf(m, "Hop set = %d \n", 2756 seq_printf(m, "Hop set = %d\n",
2775 pfh->hop_set); 2757 pfh->hop_set);
2776 seq_printf(m, "Hop pattern = %d \n", 2758 seq_printf(m, "Hop pattern = %d\n",
2777 pfh->hop_pattern); 2759 pfh->hop_pattern);
2778 seq_printf(m, "Hop index = %d \n", 2760 seq_printf(m, "Hop index = %d\n",
2779 pfh->hop_index); 2761 pfh->hop_index);
2780 p += p[1] + 2; 2762 p += p[1] + 2;
2781 } else { 2763 } else {
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 2887047069f2..aceb95ef7274 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -117,6 +117,7 @@ MODULE_PARM_DESC(workaround_interval,
117#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d) 117#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d)
118#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e) 118#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e)
119#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f) 119#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f)
120#define OID_802_11_CAPABILITY cpu_to_le32(0x0d010122)
120#define OID_802_11_PMKID cpu_to_le32(0x0d010123) 121#define OID_802_11_PMKID cpu_to_le32(0x0d010123)
121#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203) 122#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203)
122#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204) 123#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204)
@@ -358,6 +359,30 @@ struct ndis_80211_assoc_info {
358 __le32 offset_resp_ies; 359 __le32 offset_resp_ies;
359} __attribute__((packed)); 360} __attribute__((packed));
360 361
362struct ndis_80211_auth_encr_pair {
363 __le32 auth_mode;
364 __le32 encr_mode;
365} __attribute__((packed));
366
367struct ndis_80211_capability {
368 __le32 length;
369 __le32 version;
370 __le32 num_pmkids;
371 __le32 num_auth_encr_pair;
372 struct ndis_80211_auth_encr_pair auth_encr_pair[0];
373} __attribute__((packed));
374
375struct ndis_80211_bssid_info {
376 u8 bssid[6];
377 u8 pmkid[16];
378};
379
380struct ndis_80211_pmkid {
381 __le32 length;
382 __le32 bssid_info_count;
383 struct ndis_80211_bssid_info bssid_info[0];
384};
385
361/* 386/*
362 * private data 387 * private data
363 */ 388 */
@@ -476,13 +501,7 @@ struct rndis_wlan_private {
476 /* encryption stuff */ 501 /* encryption stuff */
477 int encr_tx_key_index; 502 int encr_tx_key_index;
478 struct rndis_wlan_encr_key encr_keys[4]; 503 struct rndis_wlan_encr_key encr_keys[4];
479 enum nl80211_auth_type wpa_auth_type;
480 int wpa_version; 504 int wpa_version;
481 int wpa_keymgmt;
482 int wpa_ie_len;
483 u8 *wpa_ie;
484 int wpa_cipher_pair;
485 int wpa_cipher_group;
486 505
487 u8 command_buffer[COMMAND_BUFFER_SIZE]; 506 u8 command_buffer[COMMAND_BUFFER_SIZE];
488}; 507};
@@ -534,6 +553,14 @@ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
534static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev, 553static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev,
535 int idx, u8 *mac, struct station_info *sinfo); 554 int idx, u8 *mac, struct station_info *sinfo);
536 555
556static int rndis_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
557 struct cfg80211_pmksa *pmksa);
558
559static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
560 struct cfg80211_pmksa *pmksa);
561
562static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev);
563
537static struct cfg80211_ops rndis_config_ops = { 564static struct cfg80211_ops rndis_config_ops = {
538 .change_virtual_intf = rndis_change_virtual_intf, 565 .change_virtual_intf = rndis_change_virtual_intf,
539 .scan = rndis_scan, 566 .scan = rndis_scan,
@@ -550,6 +577,9 @@ static struct cfg80211_ops rndis_config_ops = {
550 .set_default_key = rndis_set_default_key, 577 .set_default_key = rndis_set_default_key,
551 .get_station = rndis_get_station, 578 .get_station = rndis_get_station,
552 .dump_station = rndis_dump_station, 579 .dump_station = rndis_dump_station,
580 .set_pmksa = rndis_set_pmksa,
581 .del_pmksa = rndis_del_pmksa,
582 .flush_pmksa = rndis_flush_pmksa,
553}; 583};
554 584
555static void *rndis_wiphy_privid = &rndis_wiphy_privid; 585static void *rndis_wiphy_privid = &rndis_wiphy_privid;
@@ -704,6 +734,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
704 struct rndis_query_c *get_c; 734 struct rndis_query_c *get_c;
705 } u; 735 } u;
706 int ret, buflen; 736 int ret, buflen;
737 int resplen, respoffs, copylen;
707 738
708 buflen = *len + sizeof(*u.get); 739 buflen = *len + sizeof(*u.get);
709 if (buflen < CONTROL_BUFFER_SIZE) 740 if (buflen < CONTROL_BUFFER_SIZE)
@@ -733,11 +764,34 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
733 le32_to_cpu(u.get_c->status)); 764 le32_to_cpu(u.get_c->status));
734 765
735 if (ret == 0) { 766 if (ret == 0) {
736 memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); 767 resplen = le32_to_cpu(u.get_c->len);
768 respoffs = le32_to_cpu(u.get_c->offset) + 8;
737 769
738 ret = le32_to_cpu(u.get_c->len); 770 if (respoffs > buflen) {
739 if (ret > *len) 771 /* Device returned data offset outside buffer, error. */
740 *len = ret; 772 netdev_dbg(dev->net, "%s(%s): received invalid "
773 "data offset: %d > %d\n", __func__,
774 oid_to_string(oid), respoffs, buflen);
775
776 ret = -EINVAL;
777 goto exit_unlock;
778 }
779
780 if ((resplen + respoffs) > buflen) {
781 /* Device would have returned more data if buffer would
782 * have been big enough. Copy just the bits that we got.
783 */
784 copylen = buflen - respoffs;
785 } else {
786 copylen = resplen;
787 }
788
789 if (copylen > *len)
790 copylen = *len;
791
792 memcpy(data, u.buf + respoffs, copylen);
793
794 *len = resplen;
741 795
742 ret = rndis_error_status(u.get_c->status); 796 ret = rndis_error_status(u.get_c->status);
743 if (ret < 0) 797 if (ret < 0)
@@ -746,6 +800,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
746 le32_to_cpu(u.get_c->status), ret); 800 le32_to_cpu(u.get_c->status), ret);
747 } 801 }
748 802
803exit_unlock:
749 mutex_unlock(&priv->command_lock); 804 mutex_unlock(&priv->command_lock);
750 805
751 if (u.buf != priv->command_buffer) 806 if (u.buf != priv->command_buffer)
@@ -1091,8 +1146,6 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
1091 } 1146 }
1092 1147
1093 priv->wpa_version = wpa_version; 1148 priv->wpa_version = wpa_version;
1094 priv->wpa_auth_type = auth_type;
1095 priv->wpa_keymgmt = keymgmt;
1096 1149
1097 return 0; 1150 return 0;
1098} 1151}
@@ -1117,7 +1170,6 @@ static int set_priv_filter(struct usbnet *usbdev)
1117 1170
1118static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) 1171static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
1119{ 1172{
1120 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1121 __le32 tmp; 1173 __le32 tmp;
1122 int encr_mode, ret; 1174 int encr_mode, ret;
1123 1175
@@ -1146,8 +1198,6 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
1146 return ret; 1198 return ret;
1147 } 1199 }
1148 1200
1149 priv->wpa_cipher_pair = pairwise;
1150 priv->wpa_cipher_group = groupwise;
1151 return 0; 1201 return 0;
1152} 1202}
1153 1203
@@ -1568,6 +1618,194 @@ set_filter:
1568 le32_to_cpu(filter), ret); 1618 le32_to_cpu(filter), ret);
1569} 1619}
1570 1620
1621#ifdef DEBUG
1622static void debug_print_pmkids(struct usbnet *usbdev,
1623 struct ndis_80211_pmkid *pmkids,
1624 const char *func_str)
1625{
1626 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1627 int i, len, count, max_pmkids, entry_len;
1628
1629 max_pmkids = priv->wdev.wiphy->max_num_pmkids;
1630 len = le32_to_cpu(pmkids->length);
1631 count = le32_to_cpu(pmkids->bssid_info_count);
1632
1633 entry_len = (count > 0) ? (len - sizeof(*pmkids)) / count : -1;
1634
1635 netdev_dbg(usbdev->net, "%s(): %d PMKIDs (data len: %d, entry len: "
1636 "%d)\n", func_str, count, len, entry_len);
1637
1638 if (count > max_pmkids)
1639 count = max_pmkids;
1640
1641 for (i = 0; i < count; i++) {
1642 u32 *tmp = (u32 *)pmkids->bssid_info[i].pmkid;
1643
1644 netdev_dbg(usbdev->net, "%s(): bssid: %pM, "
1645 "pmkid: %08X:%08X:%08X:%08X\n",
1646 func_str, pmkids->bssid_info[i].bssid,
1647 cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]),
1648 cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3]));
1649 }
1650}
1651#else
1652static void debug_print_pmkids(struct usbnet *usbdev,
1653 struct ndis_80211_pmkid *pmkids,
1654 const char *func_str)
1655{
1656 return;
1657}
1658#endif
1659
1660static struct ndis_80211_pmkid *get_device_pmkids(struct usbnet *usbdev)
1661{
1662 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1663 struct ndis_80211_pmkid *pmkids;
1664 int len, ret, max_pmkids;
1665
1666 max_pmkids = priv->wdev.wiphy->max_num_pmkids;
1667 len = sizeof(*pmkids) + max_pmkids * sizeof(pmkids->bssid_info[0]);
1668
1669 pmkids = kzalloc(len, GFP_KERNEL);
1670 if (!pmkids)
1671 return ERR_PTR(-ENOMEM);
1672
1673 pmkids->length = cpu_to_le32(len);
1674 pmkids->bssid_info_count = cpu_to_le32(max_pmkids);
1675
1676 ret = rndis_query_oid(usbdev, OID_802_11_PMKID, pmkids, &len);
1677 if (ret < 0) {
1678 netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d)"
1679 " -> %d\n", __func__, len, max_pmkids, ret);
1680
1681 kfree(pmkids);
1682 return ERR_PTR(ret);
1683 }
1684
1685 if (le32_to_cpu(pmkids->bssid_info_count) > max_pmkids)
1686 pmkids->bssid_info_count = cpu_to_le32(max_pmkids);
1687
1688 debug_print_pmkids(usbdev, pmkids, __func__);
1689
1690 return pmkids;
1691}
1692
1693static int set_device_pmkids(struct usbnet *usbdev,
1694 struct ndis_80211_pmkid *pmkids)
1695{
1696 int ret, len, num_pmkids;
1697
1698 num_pmkids = le32_to_cpu(pmkids->bssid_info_count);
1699 len = sizeof(*pmkids) + num_pmkids * sizeof(pmkids->bssid_info[0]);
1700 pmkids->length = cpu_to_le32(len);
1701
1702 debug_print_pmkids(usbdev, pmkids, __func__);
1703
1704 ret = rndis_set_oid(usbdev, OID_802_11_PMKID, pmkids,
1705 le32_to_cpu(pmkids->length));
1706 if (ret < 0) {
1707 netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d) -> %d"
1708 "\n", __func__, len, num_pmkids, ret);
1709 }
1710
1711 kfree(pmkids);
1712 return ret;
1713}
1714
1715static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev,
1716 struct ndis_80211_pmkid *pmkids,
1717 struct cfg80211_pmksa *pmksa,
1718 int max_pmkids)
1719{
1720 int i, len, count, newlen, err;
1721
1722 len = le32_to_cpu(pmkids->length);
1723 count = le32_to_cpu(pmkids->bssid_info_count);
1724
1725 if (count > max_pmkids)
1726 count = max_pmkids;
1727
1728 for (i = 0; i < count; i++)
1729 if (!compare_ether_addr(pmkids->bssid_info[i].bssid,
1730 pmksa->bssid))
1731 break;
1732
1733 /* pmkid not found */
1734 if (i == count) {
1735 netdev_dbg(usbdev->net, "%s(): bssid not found (%pM)\n",
1736 __func__, pmksa->bssid);
1737 err = -ENOENT;
1738 goto error;
1739 }
1740
1741 for (; i + 1 < count; i++)
1742 pmkids->bssid_info[i] = pmkids->bssid_info[i + 1];
1743
1744 count--;
1745 newlen = sizeof(*pmkids) + count * sizeof(pmkids->bssid_info[0]);
1746
1747 pmkids->length = cpu_to_le32(newlen);
1748 pmkids->bssid_info_count = cpu_to_le32(count);
1749
1750 return pmkids;
1751error:
1752 kfree(pmkids);
1753 return ERR_PTR(err);
1754}
1755
1756static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
1757 struct ndis_80211_pmkid *pmkids,
1758 struct cfg80211_pmksa *pmksa,
1759 int max_pmkids)
1760{
1761 int i, err, len, count, newlen;
1762
1763 len = le32_to_cpu(pmkids->length);
1764 count = le32_to_cpu(pmkids->bssid_info_count);
1765
1766 if (count > max_pmkids)
1767 count = max_pmkids;
1768
1769 /* update with new pmkid */
1770 for (i = 0; i < count; i++) {
1771 if (compare_ether_addr(pmkids->bssid_info[i].bssid,
1772 pmksa->bssid))
1773 continue;
1774
1775 memcpy(pmkids->bssid_info[i].pmkid, pmksa->pmkid,
1776 WLAN_PMKID_LEN);
1777
1778 return pmkids;
1779 }
1780
1781 /* out of space, return error */
1782 if (i == max_pmkids) {
1783 netdev_dbg(usbdev->net, "%s(): out of space\n", __func__);
1784 err = -ENOSPC;
1785 goto error;
1786 }
1787
1788 /* add new pmkid */
1789 newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]);
1790
1791 pmkids = krealloc(pmkids, newlen, GFP_KERNEL);
1792 if (!pmkids) {
1793 err = -ENOMEM;
1794 goto error;
1795 }
1796
1797 pmkids->length = cpu_to_le32(newlen);
1798 pmkids->bssid_info_count = cpu_to_le32(count + 1);
1799
1800 memcpy(pmkids->bssid_info[count].bssid, pmksa->bssid, ETH_ALEN);
1801 memcpy(pmkids->bssid_info[count].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
1802
1803 return pmkids;
1804error:
1805 kfree(pmkids);
1806 return ERR_PTR(err);
1807}
1808
1571/* 1809/*
1572 * cfg80211 ops 1810 * cfg80211 ops
1573 */ 1811 */
@@ -2178,6 +2416,78 @@ static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev,
2178 return 0; 2416 return 0;
2179} 2417}
2180 2418
2419static int rndis_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
2420 struct cfg80211_pmksa *pmksa)
2421{
2422 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2423 struct usbnet *usbdev = priv->usbdev;
2424 struct ndis_80211_pmkid *pmkids;
2425 u32 *tmp = (u32 *)pmksa->pmkid;
2426
2427 netdev_dbg(usbdev->net, "%s(%pM, %08X:%08X:%08X:%08X)\n", __func__,
2428 pmksa->bssid,
2429 cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]),
2430 cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3]));
2431
2432 pmkids = get_device_pmkids(usbdev);
2433 if (IS_ERR(pmkids)) {
2434 /* couldn't read PMKID cache from device */
2435 return PTR_ERR(pmkids);
2436 }
2437
2438 pmkids = update_pmkid(usbdev, pmkids, pmksa, wiphy->max_num_pmkids);
2439 if (IS_ERR(pmkids)) {
2440 /* not found, list full, etc */
2441 return PTR_ERR(pmkids);
2442 }
2443
2444 return set_device_pmkids(usbdev, pmkids);
2445}
2446
2447static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
2448 struct cfg80211_pmksa *pmksa)
2449{
2450 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2451 struct usbnet *usbdev = priv->usbdev;
2452 struct ndis_80211_pmkid *pmkids;
2453 u32 *tmp = (u32 *)pmksa->pmkid;
2454
2455 netdev_dbg(usbdev->net, "%s(%pM, %08X:%08X:%08X:%08X)\n", __func__,
2456 pmksa->bssid,
2457 cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]),
2458 cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3]));
2459
2460 pmkids = get_device_pmkids(usbdev);
2461 if (IS_ERR(pmkids)) {
2462 /* Couldn't read PMKID cache from device */
2463 return PTR_ERR(pmkids);
2464 }
2465
2466 pmkids = remove_pmkid(usbdev, pmkids, pmksa, wiphy->max_num_pmkids);
2467 if (IS_ERR(pmkids)) {
2468 /* not found, etc */
2469 return PTR_ERR(pmkids);
2470 }
2471
2472 return set_device_pmkids(usbdev, pmkids);
2473}
2474
2475static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
2476{
2477 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2478 struct usbnet *usbdev = priv->usbdev;
2479 struct ndis_80211_pmkid pmkid;
2480
2481 netdev_dbg(usbdev->net, "%s()\n", __func__);
2482
2483 memset(&pmkid, 0, sizeof(pmkid));
2484
2485 pmkid.length = cpu_to_le32(sizeof(pmkid));
2486 pmkid.bssid_info_count = cpu_to_le32(0);
2487
2488 return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid));
2489}
2490
2181/* 2491/*
2182 * workers, indication handlers, device poller 2492 * workers, indication handlers, device poller
2183 */ 2493 */
@@ -2522,12 +2832,14 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
2522 } 2832 }
2523} 2833}
2524 2834
2525static int rndis_wlan_get_caps(struct usbnet *usbdev) 2835static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy)
2526{ 2836{
2527 struct { 2837 struct {
2528 __le32 num_items; 2838 __le32 num_items;
2529 __le32 items[8]; 2839 __le32 items[8];
2530 } networks_supported; 2840 } networks_supported;
2841 struct ndis_80211_capability *caps;
2842 u8 caps_buf[sizeof(*caps) + sizeof(caps->auth_encr_pair) * 16];
2531 int len, retval, i, n; 2843 int len, retval, i, n;
2532 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2844 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2533 2845
@@ -2555,6 +2867,21 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev)
2555 } 2867 }
2556 } 2868 }
2557 2869
2870 /* get device 802.11 capabilities, number of PMKIDs */
2871 caps = (struct ndis_80211_capability *)caps_buf;
2872 len = sizeof(caps_buf);
2873 retval = rndis_query_oid(usbdev, OID_802_11_CAPABILITY, caps, &len);
2874 if (retval >= 0) {
2875 netdev_dbg(usbdev->net, "OID_802_11_CAPABILITY -> len %d, "
2876 "ver %d, pmkids %d, auth-encr-pairs %d\n",
2877 le32_to_cpu(caps->length),
2878 le32_to_cpu(caps->version),
2879 le32_to_cpu(caps->num_pmkids),
2880 le32_to_cpu(caps->num_auth_encr_pair));
2881 wiphy->max_num_pmkids = le32_to_cpu(caps->num_pmkids);
2882 } else
2883 wiphy->max_num_pmkids = 0;
2884
2558 return retval; 2885 return retval;
2559} 2886}
2560 2887
@@ -2802,7 +3129,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
2802 wiphy->max_scan_ssids = 1; 3129 wiphy->max_scan_ssids = 1;
2803 3130
2804 /* TODO: fill-out band/encr information based on priv->caps */ 3131 /* TODO: fill-out band/encr information based on priv->caps */
2805 rndis_wlan_get_caps(usbdev); 3132 rndis_wlan_get_caps(usbdev, wiphy);
2806 3133
2807 memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); 3134 memcpy(priv->channels, rndis_channels, sizeof(rndis_channels));
2808 memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); 3135 memcpy(priv->rates, rndis_rates, sizeof(rndis_rates));
@@ -2862,9 +3189,6 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
2862 flush_workqueue(priv->workqueue); 3189 flush_workqueue(priv->workqueue);
2863 destroy_workqueue(priv->workqueue); 3190 destroy_workqueue(priv->workqueue);
2864 3191
2865 if (priv && priv->wpa_ie_len)
2866 kfree(priv->wpa_ie);
2867
2868 rndis_unbind(usbdev, intf); 3192 rndis_unbind(usbdev, intf);
2869 3193
2870 wiphy_unregister(priv->wdev.wiphy); 3194 wiphy_unregister(priv->wdev.wiphy);
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index c22b04042d5c..08a4789fc2d8 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -525,6 +525,10 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
525 525
526 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1); 526 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
527 rt2x00pci_register_write(rt2x00dev, CSR20, reg); 527 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
528 } else {
529 rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
530 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
531 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
528 } 532 }
529 533
530 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); 534 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 52bbcf1bd17c..d084d70e5fe2 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -573,6 +573,10 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
573 573
574 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1); 574 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
575 rt2x00pci_register_write(rt2x00dev, CSR20, reg); 575 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
576 } else {
577 rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
578 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
579 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
576 } 580 }
577 581
578 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); 582 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index dbaa78138437..54d2716e389c 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -648,6 +648,10 @@ static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
648 648
649 rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 1); 649 rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 1);
650 rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg); 650 rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
651 } else {
652 rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
653 rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 0);
654 rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
651 } 655 }
652 656
653 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); 657 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 326fce78489d..68d0cfee3f20 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1014,13 +1014,13 @@ static void rt2800_config_ps(struct rt2x00_dev *rt2x00dev,
1014 1014
1015 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); 1015 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
1016 } else { 1016 } else {
1017 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
1018
1019 rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg); 1017 rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
1020 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0); 1018 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
1021 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0); 1019 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
1022 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0); 1020 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0);
1023 rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg); 1021 rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
1022
1023 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
1024 } 1024 }
1025} 1025}
1026 1026
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 91cce2d0f6db..a2b37d38d400 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -60,6 +60,12 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
60 unsigned int i; 60 unsigned int i;
61 u32 reg; 61 u32 reg;
62 62
63 /*
64 * SOC devices don't support MCU requests.
65 */
66 if (rt2x00_is_soc(rt2x00dev))
67 return;
68
63 for (i = 0; i < 200; i++) { 69 for (i = 0; i < 200; i++) {
64 rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg); 70 rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
65 71
@@ -907,14 +913,12 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
907{ 913{
908 struct data_queue *queue; 914 struct data_queue *queue;
909 struct queue_entry *entry; 915 struct queue_entry *entry;
910 struct queue_entry *entry_done; 916 __le32 *txwi;
911 struct queue_entry_priv_pci *entry_priv;
912 struct txdone_entry_desc txdesc; 917 struct txdone_entry_desc txdesc;
913 u32 word; 918 u32 word;
914 u32 reg; 919 u32 reg;
915 u32 old_reg; 920 u32 old_reg;
916 unsigned int type; 921 int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
917 unsigned int index;
918 u16 mcs, real_mcs; 922 u16 mcs, real_mcs;
919 923
920 /* 924 /*
@@ -936,76 +940,89 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
936 break; 940 break;
937 old_reg = reg; 941 old_reg = reg;
938 942
943 wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
944 ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
945 pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
946
939 /* 947 /*
940 * Skip this entry when it contains an invalid 948 * Skip this entry when it contains an invalid
941 * queue identication number. 949 * queue identication number.
942 */ 950 */
943 type = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; 951 if (pid <= 0 || pid > QID_RX)
944 if (type >= QID_RX)
945 continue; 952 continue;
946 953
947 queue = rt2x00queue_get_queue(rt2x00dev, type); 954 queue = rt2x00queue_get_queue(rt2x00dev, pid - 1);
948 if (unlikely(!queue)) 955 if (unlikely(!queue))
949 continue; 956 continue;
950 957
951 /* 958 /*
952 * Skip this entry when it contains an invalid 959 * Inside each queue, we process each entry in a chronological
953 * index number. 960 * order. We first check that the queue is not empty.
954 */ 961 */
955 index = rt2x00_get_field32(reg, TX_STA_FIFO_WCID) - 1; 962 if (rt2x00queue_empty(queue))
956 if (unlikely(index >= queue->limit))
957 continue; 963 continue;
964 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
958 965
959 entry = &queue->entries[index]; 966 /* Check if we got a match by looking at WCID/ACK/PID
960 entry_priv = entry->priv_data; 967 * fields */
961 rt2x00_desc_read((__le32 *)entry->skb->data, 0, &word); 968 txwi = (__le32 *)(entry->skb->data -
969 rt2x00dev->ops->extra_tx_headroom);
962 970
963 entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 971 rt2x00_desc_read(txwi, 1, &word);
964 while (entry != entry_done) { 972 tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
965 /* 973 tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
966 * Catch up. 974 tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
967 * Just report any entries we missed as failed.
968 */
969 WARNING(rt2x00dev,
970 "TX status report missed for entry %d\n",
971 entry_done->entry_idx);
972
973 txdesc.flags = 0;
974 __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
975 txdesc.retry = 0;
976 975
977 rt2x00lib_txdone(entry_done, &txdesc); 976 if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid))
978 entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 977 WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n");
979 }
980 978
981 /* 979 /*
982 * Obtain the status about this packet. 980 * Obtain the status about this packet.
983 */ 981 */
984 txdesc.flags = 0; 982 txdesc.flags = 0;
985 if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) 983 rt2x00_desc_read(txwi, 0, &word);
986 __set_bit(TXDONE_SUCCESS, &txdesc.flags); 984 mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
987 else 985 real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
988 __set_bit(TXDONE_FAILURE, &txdesc.flags);
989 986
990 /* 987 /*
991 * Ralink has a retry mechanism using a global fallback 988 * Ralink has a retry mechanism using a global fallback
992 * table. We setup this fallback table to try immediate 989 * table. We setup this fallback table to try the immediate
993 * lower rate for all rates. In the TX_STA_FIFO, 990 * lower rate for all rates. In the TX_STA_FIFO, the MCS field
994 * the MCS field contains the MCS used for the successfull 991 * always contains the MCS used for the last transmission, be
995 * transmission. If the first transmission succeed, 992 * it successful or not.
996 * we have mcs == tx_mcs. On the second transmission,
997 * we have mcs = tx_mcs - 1. So the number of
998 * retry is (tx_mcs - mcs).
999 */ 993 */
1000 mcs = rt2x00_get_field32(word, TXWI_W0_MCS); 994 if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) {
1001 real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); 995 /*
996 * Transmission succeeded. The number of retries is
997 * mcs - real_mcs
998 */
999 __set_bit(TXDONE_SUCCESS, &txdesc.flags);
1000 txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
1001 } else {
1002 /*
1003 * Transmission failed. The number of retries is
1004 * always 7 in this case (for a total number of 8
1005 * frames sent).
1006 */
1007 __set_bit(TXDONE_FAILURE, &txdesc.flags);
1008 txdesc.retry = 7;
1009 }
1010
1002 __set_bit(TXDONE_FALLBACK, &txdesc.flags); 1011 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
1003 txdesc.retry = mcs - min(mcs, real_mcs); 1012
1004 1013
1005 rt2x00lib_txdone(entry, &txdesc); 1014 rt2x00lib_txdone(entry, &txdesc);
1006 } 1015 }
1007} 1016}
1008 1017
1018static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
1019{
1020 struct ieee80211_conf conf = { .flags = 0 };
1021 struct rt2x00lib_conf libconf = { .conf = &conf };
1022
1023 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
1024}
1025
1009static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) 1026static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
1010{ 1027{
1011 struct rt2x00_dev *rt2x00dev = dev_instance; 1028 struct rt2x00_dev *rt2x00dev = dev_instance;
@@ -1030,6 +1047,9 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
1030 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) 1047 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
1031 rt2800pci_txdone(rt2x00dev); 1048 rt2800pci_txdone(rt2x00dev);
1032 1049
1050 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))
1051 rt2800pci_wakeup(rt2x00dev);
1052
1033 return IRQ_HANDLED; 1053 return IRQ_HANDLED;
1034} 1054}
1035 1055
@@ -1184,6 +1204,7 @@ static const struct rt2x00_ops rt2800pci_ops = {
1184/* 1204/*
1185 * RT2800pci module information. 1205 * RT2800pci module information.
1186 */ 1206 */
1207#ifdef CONFIG_RT2800PCI_PCI
1187static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { 1208static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
1188 { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1209 { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
1189 { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1210 { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
@@ -1208,9 +1229,11 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
1208 { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1229 { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
1209 { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1230 { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
1210 { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1231 { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
1232 { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) },
1211#endif 1233#endif
1212 { 0, } 1234 { 0, }
1213}; 1235};
1236#endif /* CONFIG_RT2800PCI_PCI */
1214 1237
1215MODULE_AUTHOR(DRV_PROJECT); 1238MODULE_AUTHOR(DRV_PROJECT);
1216MODULE_VERSION(DRV_VERSION); 1239MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 5e4ee2023fcf..39877880869a 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -905,8 +905,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
905 { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, 905 { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
906 /* AirTies */ 906 /* AirTies */
907 { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) }, 907 { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
908 /* ASUS */
909 { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
908 /* AzureWave */ 910 /* AzureWave */
909 { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, 911 { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
912 { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
913 { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) },
914 { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) },
910 /* Conceptronic */ 915 /* Conceptronic */
911 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, 916 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
912 /* Corega */ 917 /* Corega */
@@ -916,20 +921,46 @@ static struct usb_device_id rt2800usb_device_table[] = {
916 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, 921 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
917 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, 922 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
918 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, 923 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
924 { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
925 /* Draytek */
926 { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) },
919 /* Edimax */ 927 /* Edimax */
920 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, 928 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
921 /* Encore */ 929 /* Encore */
922 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, 930 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
931 { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
923 /* EnGenius */ 932 /* EnGenius */
924 { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, 933 { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
925 { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, 934 { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
926 { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, 935 { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
936 { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
937 { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
938 { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
927 /* Gigabyte */ 939 /* Gigabyte */
928 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, 940 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
929 /* I-O DATA */ 941 /* I-O DATA */
930 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, 942 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
943 { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
944 { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
945 /* Logitec */
946 { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) },
931 /* MSI */ 947 /* MSI */
932 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, 948 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
949 { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
950 { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
951 { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
952 { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
953 { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
954 { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
955 { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) },
956 { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) },
957 { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
958 { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
959 { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) },
960 { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) },
961 { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
962 /* Para */
963 { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
933 /* Pegatron */ 964 /* Pegatron */
934 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, 965 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
935 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, 966 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -945,8 +976,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
945 /* Sitecom */ 976 /* Sitecom */
946 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, 977 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
947 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, 978 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
979 { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
980 { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
948 /* SMC */ 981 /* SMC */
949 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, 982 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
983 { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
984 { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
985 { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) },
950 /* Zinwell */ 986 /* Zinwell */
951 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, 987 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
952 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, 988 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -985,18 +1021,14 @@ static struct usb_device_id rt2800usb_device_table[] = {
985 /* Amigo */ 1021 /* Amigo */
986 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, 1022 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
987 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, 1023 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
988 /* Askey */
989 { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
990 /* ASUS */ 1024 /* ASUS */
991 { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) }, 1025 { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
992 { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) }, 1026 { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
993 { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
994 { USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) }, 1027 { USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) },
995 { USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) }, 1028 { USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) },
996 /* AzureWave */ 1029 /* AzureWave */
997 { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, 1030 { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
998 { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, 1031 { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
999 { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
1000 /* Belkin */ 1032 /* Belkin */
1001 { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) }, 1033 { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
1002 /* Buffalo */ 1034 /* Buffalo */
@@ -1015,14 +1047,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
1015 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, 1047 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
1016 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, 1048 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
1017 { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) }, 1049 { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) },
1018 { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
1019 /* Encore */ 1050 /* Encore */
1020 { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) }, 1051 { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
1021 { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
1022 /* EnGenius */
1023 { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
1024 { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
1025 { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
1026 /* Gemtek */ 1052 /* Gemtek */
1027 { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, 1053 { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
1028 /* Gigabyte */ 1054 /* Gigabyte */
@@ -1030,9 +1056,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
1030 /* Hawking */ 1056 /* Hawking */
1031 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, 1057 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
1032 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, 1058 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
1033 /* I-O DATA */
1034 { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
1035 { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
1036 /* LevelOne */ 1059 /* LevelOne */
1037 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, 1060 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
1038 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, 1061 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -1042,20 +1065,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
1042 { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, 1065 { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) },
1043 /* Motorola */ 1066 /* Motorola */
1044 { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, 1067 { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
1045 /* MSI */
1046 { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
1047 { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
1048 { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
1049 { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
1050 { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
1051 { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
1052 { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
1053 { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
1054 { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
1055 /* Ovislink */ 1068 /* Ovislink */
1056 { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, 1069 { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
1057 /* Para */
1058 { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
1059 /* Pegatron */ 1070 /* Pegatron */
1060 { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, 1071 { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) },
1061 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, 1072 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -1069,14 +1080,10 @@ static struct usb_device_id rt2800usb_device_table[] = {
1069 { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, 1080 { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
1070 { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) }, 1081 { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
1071 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, 1082 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
1072 { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
1073 { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
1074 { USB_DEVICE(0x0df6, 0x004a), USB_DEVICE_DATA(&rt2800usb_ops) }, 1083 { USB_DEVICE(0x0df6, 0x004a), USB_DEVICE_DATA(&rt2800usb_ops) },
1075 { USB_DEVICE(0x0df6, 0x004d), USB_DEVICE_DATA(&rt2800usb_ops) }, 1084 { USB_DEVICE(0x0df6, 0x004d), USB_DEVICE_DATA(&rt2800usb_ops) },
1076 /* SMC */ 1085 /* SMC */
1077 { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, 1086 { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
1078 { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
1079 { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
1080 { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, 1087 { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
1081 { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) }, 1088 { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) },
1082 /* Sweex */ 1089 /* Sweex */
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index e2da928dd9f0..ac69dbe5719b 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2117,6 +2117,14 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2117 } 2117 }
2118} 2118}
2119 2119
2120static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev)
2121{
2122 struct ieee80211_conf conf = { .flags = 0 };
2123 struct rt2x00lib_conf libconf = { .conf = &conf };
2124
2125 rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
2126}
2127
2120static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) 2128static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
2121{ 2129{
2122 struct rt2x00_dev *rt2x00dev = dev_instance; 2130 struct rt2x00_dev *rt2x00dev = dev_instance;
@@ -2164,6 +2172,12 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
2164 rt2x00pci_register_write(rt2x00dev, 2172 rt2x00pci_register_write(rt2x00dev,
2165 M2H_CMD_DONE_CSR, 0xffffffff); 2173 M2H_CMD_DONE_CSR, 0xffffffff);
2166 2174
2175 /*
2176 * 4 - MCU Autowakeup interrupt.
2177 */
2178 if (rt2x00_get_field32(reg_mcu, MCU_INT_SOURCE_CSR_TWAKEUP))
2179 rt61pci_wakeup(rt2x00dev);
2180
2167 return IRQ_HANDLED; 2181 return IRQ_HANDLED;
2168} 2182}
2169 2183
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 47f3e4a26d77..7ebe14b64fe8 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -860,15 +860,15 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
860 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, 860 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
861 USB_MODE_SLEEP, REGISTER_TIMEOUT); 861 USB_MODE_SLEEP, REGISTER_TIMEOUT);
862 } else { 862 } else {
863 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
864 USB_MODE_WAKEUP, REGISTER_TIMEOUT);
865
866 rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg); 863 rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
867 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0); 864 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
868 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0); 865 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
869 rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0); 866 rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
870 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0); 867 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
871 rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg); 868 rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
869
870 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
871 USB_MODE_WAKEUP, REGISTER_TIMEOUT);
872 } 872 }
873} 873}
874 874
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 785e0244e305..337fc7bec5a5 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -51,3 +51,27 @@ config WL1271
51 51
52 If you choose to build a module, it'll be called wl1271. Say N if 52 If you choose to build a module, it'll be called wl1271. Say N if
53 unsure. 53 unsure.
54
55config WL1271_SPI
56 tristate "TI wl1271 SPI support"
57 depends on WL1271 && SPI_MASTER
58 ---help---
59 This module adds support for the SPI interface of adapters using
60 TI wl1271 chipset. Select this if your platform is using
61 the SPI bus.
62
63 If you choose to build a module, it'll be called wl1251_spi.
64 Say N if unsure.
65
66config WL1271_SDIO
67 tristate "TI wl1271 SDIO support"
68 depends on WL1271 && MMC && ARM
69 ---help---
70 This module adds support for the SDIO interface of adapters using
71 TI wl1271 chipset. Select this if your platform is using
72 the SDIO bus.
73
74 If you choose to build a module, it'll be called
75 wl1271_sdio. Say N if unsure.
76
77
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index f47ec94c16dc..27ddd2be0a91 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -7,10 +7,12 @@ obj-$(CONFIG_WL1251) += wl1251.o
7obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o 7obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o
8obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o 8obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o
9 9
10wl1271-objs = wl1271_main.o wl1271_spi.o wl1271_cmd.o \ 10wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \
11 wl1271_event.o wl1271_tx.o wl1271_rx.o \ 11 wl1271_event.o wl1271_tx.o wl1271_rx.o \
12 wl1271_ps.o wl1271_acx.o wl1271_boot.o \ 12 wl1271_ps.o wl1271_acx.o wl1271_boot.o \
13 wl1271_init.o wl1271_debugfs.o wl1271_io.o 13 wl1271_init.o wl1271_debugfs.o
14 14
15wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o 15wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o
16obj-$(CONFIG_WL1271) += wl1271.o 16obj-$(CONFIG_WL1271) += wl1271.o
17obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o
18obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 37c61c19cae5..4f5f02a26e62 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -256,6 +256,8 @@ struct wl1251_debugfs {
256struct wl1251_if_operations { 256struct wl1251_if_operations {
257 void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len); 257 void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len);
258 void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len); 258 void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
259 void (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
260 void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
259 void (*reset)(struct wl1251 *wl); 261 void (*reset)(struct wl1251 *wl);
260 void (*enable_irq)(struct wl1251 *wl); 262 void (*enable_irq)(struct wl1251 *wl);
261 void (*disable_irq)(struct wl1251 *wl); 263 void (*disable_irq)(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 28a808674080..acb334184d70 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -496,7 +496,8 @@ int wl1251_boot(struct wl1251 *wl)
496 /* 2. start processing NVS file */ 496 /* 2. start processing NVS file */
497 if (wl->use_eeprom) { 497 if (wl->use_eeprom) {
498 wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR); 498 wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
499 msleep(4000); 499 /* Wait for EEPROM NVS burst read to complete */
500 msleep(40);
500 wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM); 501 wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
501 } else { 502 } else {
502 ret = wl1251_boot_upload_nvs(wl); 503 ret = wl1251_boot_upload_nvs(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
index b89d2ac62efb..c545e9d5f512 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ b/drivers/net/wireless/wl12xx/wl1251_io.h
@@ -48,6 +48,26 @@ static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
48 wl->if_ops->write(wl, addr, &val, sizeof(u32)); 48 wl->if_ops->write(wl, addr, &val, sizeof(u32));
49} 49}
50 50
51static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr)
52{
53 u32 response;
54
55 if (wl->if_ops->read_elp)
56 wl->if_ops->read_elp(wl, addr, &response);
57 else
58 wl->if_ops->read(wl, addr, &response, sizeof(u32));
59
60 return response;
61}
62
63static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val)
64{
65 if (wl->if_ops->write_elp)
66 wl->if_ops->write_elp(wl, addr, val);
67 else
68 wl->if_ops->write(wl, addr, &val, sizeof(u32));
69}
70
51/* Memory target IO, address is translated to partition 0 */ 71/* Memory target IO, address is translated to partition 0 */
52void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len); 72void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
53void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len); 73void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len);
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 24ae6a360ac8..0155653b7105 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -146,8 +146,8 @@ static void wl1251_fw_wakeup(struct wl1251 *wl)
146 u32 elp_reg; 146 u32 elp_reg;
147 147
148 elp_reg = ELPCTRL_WAKE_UP; 148 elp_reg = ELPCTRL_WAKE_UP;
149 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); 149 wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
150 elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); 150 elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
151 151
152 if (!(elp_reg & ELPCTRL_WLAN_READY)) 152 if (!(elp_reg & ELPCTRL_WLAN_READY))
153 wl1251_warning("WLAN not ready"); 153 wl1251_warning("WLAN not ready");
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
index 851dfb65e474..b55cb2bd459a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -45,7 +45,7 @@ void wl1251_elp_work(struct work_struct *work)
45 goto out; 45 goto out;
46 46
47 wl1251_debug(DEBUG_PSM, "chip to elp"); 47 wl1251_debug(DEBUG_PSM, "chip to elp");
48 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); 48 wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
49 wl->elp = true; 49 wl->elp = true;
50 50
51out: 51out:
@@ -79,9 +79,9 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
79 start = jiffies; 79 start = jiffies;
80 timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); 80 timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
81 81
82 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); 82 wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
83 83
84 elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); 84 elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
85 85
86 /* 86 /*
87 * FIXME: we should wait for irq from chip but, as a temporary 87 * FIXME: we should wait for irq from chip but, as a temporary
@@ -93,7 +93,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
93 return -ETIMEDOUT; 93 return -ETIMEDOUT;
94 } 94 }
95 msleep(1); 95 msleep(1);
96 elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); 96 elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
97 } 97 }
98 98
99 wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", 99 wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
index 9423f22bdced..2051ef06e9ec 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -20,20 +20,11 @@
20 * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com) 20 * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
21 */ 21 */
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/crc7.h>
24#include <linux/mod_devicetable.h> 23#include <linux/mod_devicetable.h>
25#include <linux/irq.h>
26#include <linux/mmc/sdio_func.h> 24#include <linux/mmc/sdio_func.h>
27#include <linux/mmc/sdio_ids.h> 25#include <linux/mmc/sdio_ids.h>
28#include <linux/platform_device.h>
29 26
30#include "wl1251.h" 27#include "wl1251.h"
31#include "wl12xx_80211.h"
32#include "wl1251_reg.h"
33#include "wl1251_ps.h"
34#include "wl1251_io.h"
35#include "wl1251_tx.h"
36#include "wl1251_debugfs.h"
37 28
38#ifndef SDIO_VENDOR_ID_TI 29#ifndef SDIO_VENDOR_ID_TI
39#define SDIO_VENDOR_ID_TI 0x104c 30#define SDIO_VENDOR_ID_TI 0x104c
@@ -65,7 +56,8 @@ static const struct sdio_device_id wl1251_devices[] = {
65MODULE_DEVICE_TABLE(sdio, wl1251_devices); 56MODULE_DEVICE_TABLE(sdio, wl1251_devices);
66 57
67 58
68void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len) 59static void wl1251_sdio_read(struct wl1251 *wl, int addr,
60 void *buf, size_t len)
69{ 61{
70 int ret; 62 int ret;
71 struct sdio_func *func = wl_to_func(wl); 63 struct sdio_func *func = wl_to_func(wl);
@@ -77,7 +69,8 @@ void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len)
77 sdio_release_host(func); 69 sdio_release_host(func);
78} 70}
79 71
80void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len) 72static void wl1251_sdio_write(struct wl1251 *wl, int addr,
73 void *buf, size_t len)
81{ 74{
82 int ret; 75 int ret;
83 struct sdio_func *func = wl_to_func(wl); 76 struct sdio_func *func = wl_to_func(wl);
@@ -89,7 +82,33 @@ void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len)
89 sdio_release_host(func); 82 sdio_release_host(func);
90} 83}
91 84
92void wl1251_sdio_reset(struct wl1251 *wl) 85static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
86{
87 int ret = 0;
88 struct sdio_func *func = wl_to_func(wl);
89
90 sdio_claim_host(func);
91 *val = sdio_readb(func, addr, &ret);
92 sdio_release_host(func);
93
94 if (ret)
95 wl1251_error("sdio_readb failed (%d)", ret);
96}
97
98static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
99{
100 int ret = 0;
101 struct sdio_func *func = wl_to_func(wl);
102
103 sdio_claim_host(func);
104 sdio_writeb(func, val, addr, &ret);
105 sdio_release_host(func);
106
107 if (ret)
108 wl1251_error("sdio_writeb failed (%d)", ret);
109}
110
111static void wl1251_sdio_reset(struct wl1251 *wl)
93{ 112{
94} 113}
95 114
@@ -111,19 +130,22 @@ static void wl1251_sdio_disable_irq(struct wl1251 *wl)
111 sdio_release_host(func); 130 sdio_release_host(func);
112} 131}
113 132
114void wl1251_sdio_set_power(bool enable) 133static void wl1251_sdio_set_power(bool enable)
115{ 134{
116} 135}
117 136
118struct wl1251_if_operations wl1251_sdio_ops = { 137static const struct wl1251_if_operations wl1251_sdio_ops = {
119 .read = wl1251_sdio_read, 138 .read = wl1251_sdio_read,
120 .write = wl1251_sdio_write, 139 .write = wl1251_sdio_write,
140 .write_elp = wl1251_sdio_write_elp,
141 .read_elp = wl1251_sdio_read_elp,
121 .reset = wl1251_sdio_reset, 142 .reset = wl1251_sdio_reset,
122 .enable_irq = wl1251_sdio_enable_irq, 143 .enable_irq = wl1251_sdio_enable_irq,
123 .disable_irq = wl1251_sdio_disable_irq, 144 .disable_irq = wl1251_sdio_disable_irq,
124}; 145};
125 146
126int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) 147static int wl1251_sdio_probe(struct sdio_func *func,
148 const struct sdio_device_id *id)
127{ 149{
128 int ret; 150 int ret;
129 struct wl1251 *wl; 151 struct wl1251 *wl;
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 9cc8c323830f..df2ff8bc8ef4 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -309,7 +309,7 @@ static int __devexit wl1251_spi_remove(struct spi_device *spi)
309 309
310static struct spi_driver wl1251_spi_driver = { 310static struct spi_driver wl1251_spi_driver = {
311 .driver = { 311 .driver = {
312 .name = "wl1251", 312 .name = DRIVER_NAME,
313 .bus = &spi_bus_type, 313 .bus = &spi_bus_type,
314 .owner = THIS_MODULE, 314 .owner = THIS_MODULE,
315 }, 315 },
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 97ea5096bc8c..a29969efc861 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -53,6 +53,9 @@ enum {
53 DEBUG_MAC80211 = BIT(11), 53 DEBUG_MAC80211 = BIT(11),
54 DEBUG_CMD = BIT(12), 54 DEBUG_CMD = BIT(12),
55 DEBUG_ACX = BIT(13), 55 DEBUG_ACX = BIT(13),
56 DEBUG_SDIO = BIT(14),
57 DEBUG_FILTERS = BIT(15),
58 DEBUG_ADHOC = BIT(16),
56 DEBUG_ALL = ~0, 59 DEBUG_ALL = ~0,
57}; 60};
58 61
@@ -110,6 +113,9 @@ enum {
110#define WL1271_FW_NAME "wl1271-fw.bin" 113#define WL1271_FW_NAME "wl1271-fw.bin"
111#define WL1271_NVS_NAME "wl1271-nvs.bin" 114#define WL1271_NVS_NAME "wl1271-nvs.bin"
112 115
116#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
117#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
118
113/* NVS data structure */ 119/* NVS data structure */
114#define WL1271_NVS_SECTION_SIZE 468 120#define WL1271_NVS_SECTION_SIZE 468
115 121
@@ -142,14 +148,7 @@ struct wl1271_nvs_file {
142 */ 148 */
143#undef WL1271_80211A_ENABLED 149#undef WL1271_80211A_ENABLED
144 150
145/* 151#define WL1271_BUSY_WORD_CNT 1
146 * FIXME: for the wl1271, a busy word count of 1 here will result in a more
147 * optimal SPI interface. There is some SPI bug however, causing RXS time outs
148 * with this mode occasionally on boot, so lets have three for now. A value of
149 * three should make sure, that the chipset will always be ready, though this
150 * will impact throughput and latencies slightly.
151 */
152#define WL1271_BUSY_WORD_CNT 3
153#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) 152#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
154 153
155#define WL1271_ELP_HW_STATE_ASLEEP 0 154#define WL1271_ELP_HW_STATE_ASLEEP 0
@@ -334,11 +333,27 @@ struct wl1271_scan {
334 u8 probe_requests; 333 u8 probe_requests;
335}; 334};
336 335
336struct wl1271_if_operations {
337 void (*read)(struct wl1271 *wl, int addr, void *buf, size_t len,
338 bool fixed);
339 void (*write)(struct wl1271 *wl, int addr, void *buf, size_t len,
340 bool fixed);
341 void (*reset)(struct wl1271 *wl);
342 void (*init)(struct wl1271 *wl);
343 void (*power)(struct wl1271 *wl, bool enable);
344 struct device* (*dev)(struct wl1271 *wl);
345 void (*enable_irq)(struct wl1271 *wl);
346 void (*disable_irq)(struct wl1271 *wl);
347};
348
337struct wl1271 { 349struct wl1271 {
350 struct platform_device *plat_dev;
338 struct ieee80211_hw *hw; 351 struct ieee80211_hw *hw;
339 bool mac80211_registered; 352 bool mac80211_registered;
340 353
341 struct spi_device *spi; 354 void *if_priv;
355
356 struct wl1271_if_operations *if_ops;
342 357
343 void (*set_power)(bool enable); 358 void (*set_power)(bool enable);
344 int irq; 359 int irq;
@@ -357,6 +372,8 @@ struct wl1271 {
357#define WL1271_FLAG_IN_ELP (6) 372#define WL1271_FLAG_IN_ELP (6)
358#define WL1271_FLAG_PSM (7) 373#define WL1271_FLAG_PSM (7)
359#define WL1271_FLAG_PSM_REQUESTED (8) 374#define WL1271_FLAG_PSM_REQUESTED (8)
375#define WL1271_FLAG_IRQ_PENDING (9)
376#define WL1271_FLAG_IRQ_RUNNING (10)
360 unsigned long flags; 377 unsigned long flags;
361 378
362 struct wl1271_partition_set part; 379 struct wl1271_partition_set part;
@@ -373,6 +390,7 @@ struct wl1271 {
373 u8 bssid[ETH_ALEN]; 390 u8 bssid[ETH_ALEN];
374 u8 mac_addr[ETH_ALEN]; 391 u8 mac_addr[ETH_ALEN];
375 u8 bss_type; 392 u8 bss_type;
393 u8 set_bss_type;
376 u8 ssid[IW_ESSID_MAX_SIZE + 1]; 394 u8 ssid[IW_ESSID_MAX_SIZE + 1];
377 u8 ssid_len; 395 u8 ssid_len;
378 int channel; 396 int channel;
@@ -382,13 +400,13 @@ struct wl1271 {
382 /* Accounting for allocated / available TX blocks on HW */ 400 /* Accounting for allocated / available TX blocks on HW */
383 u32 tx_blocks_freed[NUM_TX_QUEUES]; 401 u32 tx_blocks_freed[NUM_TX_QUEUES];
384 u32 tx_blocks_available; 402 u32 tx_blocks_available;
385 u8 tx_results_count; 403 u32 tx_results_count;
386 404
387 /* Transmitted TX packets counter for chipset interface */ 405 /* Transmitted TX packets counter for chipset interface */
388 int tx_packets_count; 406 u32 tx_packets_count;
389 407
390 /* Time-offset between host and chipset clocks */ 408 /* Time-offset between host and chipset clocks */
391 int time_offset; 409 s64 time_offset;
392 410
393 /* Session counter for the chipset */ 411 /* Session counter for the chipset */
394 int session_counter; 412 int session_counter;
@@ -403,8 +421,7 @@ struct wl1271 {
403 421
404 /* Security sequence number counters */ 422 /* Security sequence number counters */
405 u8 tx_security_last_seq; 423 u8 tx_security_last_seq;
406 u16 tx_security_seq_16; 424 s64 tx_security_seq;
407 u32 tx_security_seq_32;
408 425
409 /* FW Rx counter */ 426 /* FW Rx counter */
410 u32 rx_counter; 427 u32 rx_counter;
@@ -430,14 +447,19 @@ struct wl1271 {
430 /* currently configured rate set */ 447 /* currently configured rate set */
431 u32 sta_rate_set; 448 u32 sta_rate_set;
432 u32 basic_rate_set; 449 u32 basic_rate_set;
450 u32 basic_rate;
433 u32 rate_set; 451 u32 rate_set;
434 452
435 /* The current band */ 453 /* The current band */
436 enum ieee80211_band band; 454 enum ieee80211_band band;
437 455
456 /* Beaconing interval (needed for ad-hoc) */
457 u32 beacon_int;
458
438 /* Default key (for WEP) */ 459 /* Default key (for WEP) */
439 u32 default_key; 460 u32 default_key;
440 461
462 unsigned int filters;
441 unsigned int rx_config; 463 unsigned int rx_config;
442 unsigned int rx_filter; 464 unsigned int rx_filter;
443 465
@@ -465,6 +487,8 @@ struct wl1271 {
465 /* Current chipset configuration */ 487 /* Current chipset configuration */
466 struct conf_drv_settings conf; 488 struct conf_drv_settings conf;
467 489
490 bool sg_enabled;
491
468 struct list_head list; 492 struct list_head list;
469}; 493};
470 494
@@ -477,7 +501,8 @@ int wl1271_plt_stop(struct wl1271 *wl);
477 501
478#define WL1271_DEFAULT_POWER_LEVEL 0 502#define WL1271_DEFAULT_POWER_LEVEL 0
479 503
480#define WL1271_TX_QUEUE_MAX_LENGTH 20 504#define WL1271_TX_QUEUE_LOW_WATERMARK 10
505#define WL1271_TX_QUEUE_HIGH_WATERMARK 25
481 506
482/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power 507/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power
483 on in case is has been shut down shortly before */ 508 on in case is has been shut down shortly before */
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 60f10dce4800..621c94691e7e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -31,7 +31,6 @@
31#include "wl1271.h" 31#include "wl1271.h"
32#include "wl12xx_80211.h" 32#include "wl12xx_80211.h"
33#include "wl1271_reg.h" 33#include "wl1271_reg.h"
34#include "wl1271_spi.h"
35#include "wl1271_ps.h" 34#include "wl1271_ps.h"
36 35
37int wl1271_acx_wake_up_conditions(struct wl1271 *wl) 36int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
@@ -136,12 +135,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power)
136 goto out; 135 goto out;
137 } 136 }
138 137
139 /* 138 acx->current_tx_power = power * 10;
140 * FIXME: This is a workaround needed while we don't the correct
141 * calibration, to avoid distortions
142 */
143 /* acx->current_tx_power = power * 10; */
144 acx->current_tx_power = 120;
145 139
146 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); 140 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
147 if (ret < 0) { 141 if (ret < 0) {
@@ -510,12 +504,17 @@ out:
510 return ret; 504 return ret;
511} 505}
512 506
513int wl1271_acx_conn_monit_params(struct wl1271 *wl) 507#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff
508
509int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable)
514{ 510{
515 struct acx_conn_monit_params *acx; 511 struct acx_conn_monit_params *acx;
512 u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
513 u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
516 int ret; 514 int ret;
517 515
518 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters"); 516 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
517 enable ? "enabled" : "disabled");
519 518
520 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 519 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
521 if (!acx) { 520 if (!acx) {
@@ -523,8 +522,13 @@ int wl1271_acx_conn_monit_params(struct wl1271 *wl)
523 goto out; 522 goto out;
524 } 523 }
525 524
526 acx->synch_fail_thold = cpu_to_le32(wl->conf.conn.synch_fail_thold); 525 if (enable) {
527 acx->bss_lose_timeout = cpu_to_le32(wl->conf.conn.bss_lose_timeout); 526 threshold = wl->conf.conn.synch_fail_thold;
527 timeout = wl->conf.conn.bss_lose_timeout;
528 }
529
530 acx->synch_fail_thold = cpu_to_le32(threshold);
531 acx->bss_lose_timeout = cpu_to_le32(timeout);
528 532
529 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, 533 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
530 acx, sizeof(*acx)); 534 acx, sizeof(*acx));
@@ -540,7 +544,7 @@ out:
540} 544}
541 545
542 546
543int wl1271_acx_sg_enable(struct wl1271 *wl) 547int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
544{ 548{
545 struct acx_bt_wlan_coex *pta; 549 struct acx_bt_wlan_coex *pta;
546 int ret; 550 int ret;
@@ -553,7 +557,10 @@ int wl1271_acx_sg_enable(struct wl1271 *wl)
553 goto out; 557 goto out;
554 } 558 }
555 559
556 pta->enable = SG_ENABLE; 560 if (enable)
561 pta->enable = wl->conf.sg.state;
562 else
563 pta->enable = CONF_SG_DISABLE;
557 564
558 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); 565 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
559 if (ret < 0) { 566 if (ret < 0) {
@@ -570,7 +577,7 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
570{ 577{
571 struct acx_bt_wlan_coex_param *param; 578 struct acx_bt_wlan_coex_param *param;
572 struct conf_sg_settings *c = &wl->conf.sg; 579 struct conf_sg_settings *c = &wl->conf.sg;
573 int ret; 580 int i, ret;
574 581
575 wl1271_debug(DEBUG_ACX, "acx sg cfg"); 582 wl1271_debug(DEBUG_ACX, "acx sg cfg");
576 583
@@ -581,19 +588,9 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
581 } 588 }
582 589
583 /* BT-WLAN coext parameters */ 590 /* BT-WLAN coext parameters */
584 param->per_threshold = cpu_to_le32(c->per_threshold); 591 for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
585 param->max_scan_compensation_time = 592 param->params[i] = c->params[i];
586 cpu_to_le32(c->max_scan_compensation_time); 593 param->param_idx = CONF_SG_PARAMS_ALL;
587 param->nfs_sample_interval = cpu_to_le16(c->nfs_sample_interval);
588 param->load_ratio = c->load_ratio;
589 param->auto_ps_mode = c->auto_ps_mode;
590 param->probe_req_compensation = c->probe_req_compensation;
591 param->scan_window_compensation = c->scan_window_compensation;
592 param->antenna_config = c->antenna_config;
593 param->beacon_miss_threshold = c->beacon_miss_threshold;
594 param->rate_adaptation_threshold =
595 cpu_to_le32(c->rate_adaptation_threshold);
596 param->rate_adaptation_snr = c->rate_adaptation_snr;
597 594
598 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); 595 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
599 if (ret < 0) { 596 if (ret < 0) {
@@ -805,7 +802,7 @@ int wl1271_acx_rate_policies(struct wl1271 *wl)
805 802
806 /* configure one basic rate class */ 803 /* configure one basic rate class */
807 idx = ACX_TX_BASIC_RATE; 804 idx = ACX_TX_BASIC_RATE;
808 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set); 805 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate);
809 acx->rate_class[idx].short_retry_limit = c->short_retry_limit; 806 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
810 acx->rate_class[idx].long_retry_limit = c->long_retry_limit; 807 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
811 acx->rate_class[idx].aflags = c->aflags; 808 acx->rate_class[idx].aflags = c->aflags;
@@ -1142,3 +1139,58 @@ out:
1142 kfree(acx); 1139 kfree(acx);
1143 return ret; 1140 return ret;
1144} 1141}
1142
1143int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
1144{
1145 struct wl1271_acx_keep_alive_mode *acx = NULL;
1146 int ret = 0;
1147
1148 wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
1149
1150 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1151 if (!acx) {
1152 ret = -ENOMEM;
1153 goto out;
1154 }
1155
1156 acx->enabled = enable;
1157
1158 ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
1159 if (ret < 0) {
1160 wl1271_warning("acx keep alive mode failed: %d", ret);
1161 goto out;
1162 }
1163
1164out:
1165 kfree(acx);
1166 return ret;
1167}
1168int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
1169{
1170 struct wl1271_acx_keep_alive_config *acx = NULL;
1171 int ret = 0;
1172
1173 wl1271_debug(DEBUG_ACX, "acx keep alive config");
1174
1175 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1176 if (!acx) {
1177 ret = -ENOMEM;
1178 goto out;
1179 }
1180
1181 acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
1182 acx->index = index;
1183 acx->tpl_validation = tpl_valid;
1184 acx->trigger = ACX_KEEP_ALIVE_NO_TX;
1185
1186 ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
1187 acx, sizeof(*acx));
1188 if (ret < 0) {
1189 wl1271_warning("acx keep alive config failed: %d", ret);
1190 goto out;
1191 }
1192
1193out:
1194 kfree(acx);
1195 return ret;
1196}
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index aeccc98581eb..15cc56192de9 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -392,81 +392,27 @@ struct acx_conn_monit_params {
392 __le32 bss_lose_timeout; /* number of TU's from synch fail */ 392 __le32 bss_lose_timeout; /* number of TU's from synch fail */
393} __attribute__ ((packed)); 393} __attribute__ ((packed));
394 394
395enum {
396 SG_ENABLE = 0,
397 SG_DISABLE,
398 SG_SENSE_NO_ACTIVITY,
399 SG_SENSE_ACTIVE
400};
401
402struct acx_bt_wlan_coex { 395struct acx_bt_wlan_coex {
403 struct acx_header header; 396 struct acx_header header;
404 397
405 /*
406 * 0 -> PTA enabled
407 * 1 -> PTA disabled
408 * 2 -> sense no active mode, i.e.
409 * an interrupt is sent upon
410 * BT activity.
411 * 3 -> PTA is switched on in response
412 * to the interrupt sending.
413 */
414 u8 enable; 398 u8 enable;
415 u8 pad[3]; 399 u8 pad[3];
416} __attribute__ ((packed)); 400} __attribute__ ((packed));
417 401
418struct acx_dco_itrim_params { 402struct acx_bt_wlan_coex_param {
419 struct acx_header header; 403 struct acx_header header;
420 404
421 u8 enable; 405 __le32 params[CONF_SG_PARAMS_MAX];
406 u8 param_idx;
422 u8 padding[3]; 407 u8 padding[3];
423 __le32 timeout;
424} __attribute__ ((packed)); 408} __attribute__ ((packed));
425 409
426#define PTA_ANTENNA_TYPE_DEF (0) 410struct acx_dco_itrim_params {
427#define PTA_BT_HP_MAXTIME_DEF (2000)
428#define PTA_WLAN_HP_MAX_TIME_DEF (5000)
429#define PTA_SENSE_DISABLE_TIMER_DEF (1350)
430#define PTA_PROTECTIVE_RX_TIME_DEF (1500)
431#define PTA_PROTECTIVE_TX_TIME_DEF (1500)
432#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
433#define PTA_SIGNALING_TYPE_DEF (1)
434#define PTA_AFH_LEVERAGE_ON_DEF (0)
435#define PTA_NUMBER_QUIET_CYCLE_DEF (0)
436#define PTA_MAX_NUM_CTS_DEF (3)
437#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2)
438#define PTA_NUMBER_OF_BT_PACKETS_DEF (2)
439#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500)
440#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000)
441#define PTA_CYCLE_TIME_FAST_DEF (8700)
442#define PTA_RX_FOR_AVALANCHE_DEF (5)
443#define PTA_ELP_HP_DEF (0)
444#define PTA_ANTI_STARVE_PERIOD_DEF (500)
445#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4)
446#define PTA_ALLOW_PA_SD_DEF (1)
447#define PTA_TIME_BEFORE_BEACON_DEF (6300)
448#define PTA_HPDM_MAX_TIME_DEF (1600)
449#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550)
450#define PTA_AUTO_MODE_NO_CTS_DEF (0)
451#define PTA_BT_HP_RESPECTED_DEF (3)
452#define PTA_WLAN_RX_MIN_RATE_DEF (24)
453#define PTA_ACK_MODE_DEF (1)
454
455struct acx_bt_wlan_coex_param {
456 struct acx_header header; 411 struct acx_header header;
457 412
458 __le32 per_threshold; 413 u8 enable;
459 __le32 max_scan_compensation_time;
460 __le16 nfs_sample_interval;
461 u8 load_ratio;
462 u8 auto_ps_mode;
463 u8 probe_req_compensation;
464 u8 scan_window_compensation;
465 u8 antenna_config;
466 u8 beacon_miss_threshold;
467 __le32 rate_adaptation_threshold;
468 s8 rate_adaptation_snr;
469 u8 padding[3]; 414 u8 padding[3];
415 __le32 timeout;
470} __attribute__ ((packed)); 416} __attribute__ ((packed));
471 417
472struct acx_energy_detection { 418struct acx_energy_detection {
@@ -969,6 +915,33 @@ struct wl1271_acx_pm_config {
969 u8 padding[3]; 915 u8 padding[3];
970} __attribute__ ((packed)); 916} __attribute__ ((packed));
971 917
918struct wl1271_acx_keep_alive_mode {
919 struct acx_header header;
920
921 u8 enabled;
922 u8 padding[3];
923} __attribute__ ((packed));
924
925enum {
926 ACX_KEEP_ALIVE_NO_TX = 0,
927 ACX_KEEP_ALIVE_PERIOD_ONLY
928};
929
930enum {
931 ACX_KEEP_ALIVE_TPL_INVALID = 0,
932 ACX_KEEP_ALIVE_TPL_VALID
933};
934
935struct wl1271_acx_keep_alive_config {
936 struct acx_header header;
937
938 __le32 period;
939 u8 index;
940 u8 tpl_validation;
941 u8 trigger;
942 u8 padding;
943} __attribute__ ((packed));
944
972enum { 945enum {
973 ACX_WAKE_UP_CONDITIONS = 0x0002, 946 ACX_WAKE_UP_CONDITIONS = 0x0002,
974 ACX_MEM_CFG = 0x0003, 947 ACX_MEM_CFG = 0x0003,
@@ -1018,7 +991,7 @@ enum {
1018 ACX_BET_ENABLE = 0x0050, 991 ACX_BET_ENABLE = 0x0050,
1019 ACX_RSSI_SNR_TRIGGER = 0x0051, 992 ACX_RSSI_SNR_TRIGGER = 0x0051,
1020 ACX_RSSI_SNR_WEIGHTS = 0x0051, 993 ACX_RSSI_SNR_WEIGHTS = 0x0051,
1021 ACX_KEEP_ALIVE_MODE = 0x0052, 994 ACX_KEEP_ALIVE_MODE = 0x0053,
1022 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, 995 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054,
1023 ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, 996 ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
1024 ACX_BA_SESSION_INITIATOR_POLICY = 0x0056, 997 ACX_BA_SESSION_INITIATOR_POLICY = 0x0056,
@@ -1058,8 +1031,8 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
1058int wl1271_acx_dco_itrim_params(struct wl1271 *wl); 1031int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
1059int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); 1032int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
1060int wl1271_acx_beacon_filter_table(struct wl1271 *wl); 1033int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
1061int wl1271_acx_conn_monit_params(struct wl1271 *wl); 1034int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable);
1062int wl1271_acx_sg_enable(struct wl1271 *wl); 1035int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable);
1063int wl1271_acx_sg_cfg(struct wl1271 *wl); 1036int wl1271_acx_sg_cfg(struct wl1271 *wl);
1064int wl1271_acx_cca_threshold(struct wl1271 *wl); 1037int wl1271_acx_cca_threshold(struct wl1271 *wl);
1065int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); 1038int wl1271_acx_bcn_dtim_options(struct wl1271 *wl);
@@ -1085,5 +1058,7 @@ int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
1085int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, 1058int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
1086 u8 version); 1059 u8 version);
1087int wl1271_acx_pm_config(struct wl1271 *wl); 1060int wl1271_acx_pm_config(struct wl1271 *wl);
1061int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable);
1062int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
1088 1063
1089#endif /* __WL1271_ACX_H__ */ 1064#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 2be76ee42bb9..7acef88df1fe 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file is part of wl1271 2 * This file is part of wl1271
3 * 3 *
4 * Copyright (C) 2008-2009 Nokia Corporation 4 * Copyright (C) 2008-2010 Nokia Corporation
5 * 5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 * 7 *
@@ -26,7 +26,6 @@
26#include "wl1271_acx.h" 26#include "wl1271_acx.h"
27#include "wl1271_reg.h" 27#include "wl1271_reg.h"
28#include "wl1271_boot.h" 28#include "wl1271_boot.h"
29#include "wl1271_spi.h"
30#include "wl1271_io.h" 29#include "wl1271_io.h"
31#include "wl1271_event.h" 30#include "wl1271_event.h"
32 31
@@ -229,6 +228,14 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
229 nvs_len = sizeof(wl->nvs->nvs); 228 nvs_len = sizeof(wl->nvs->nvs);
230 nvs_ptr = (u8 *)wl->nvs->nvs; 229 nvs_ptr = (u8 *)wl->nvs->nvs;
231 230
231 /* update current MAC address to NVS */
232 nvs_ptr[11] = wl->mac_addr[0];
233 nvs_ptr[10] = wl->mac_addr[1];
234 nvs_ptr[6] = wl->mac_addr[2];
235 nvs_ptr[5] = wl->mac_addr[3];
236 nvs_ptr[4] = wl->mac_addr[4];
237 nvs_ptr[3] = wl->mac_addr[5];
238
232 /* 239 /*
233 * Layout before the actual NVS tables: 240 * Layout before the actual NVS tables:
234 * 1 byte : burst length. 241 * 1 byte : burst length.
@@ -299,7 +306,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
299 306
300static void wl1271_boot_enable_interrupts(struct wl1271 *wl) 307static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
301{ 308{
302 enable_irq(wl->irq); 309 wl1271_enable_interrupts(wl);
303 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, 310 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
304 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); 311 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
305 wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL); 312 wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
@@ -403,7 +410,9 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
403 /* unmask required mbox events */ 410 /* unmask required mbox events */
404 wl->event_mask = BSS_LOSE_EVENT_ID | 411 wl->event_mask = BSS_LOSE_EVENT_ID |
405 SCAN_COMPLETE_EVENT_ID | 412 SCAN_COMPLETE_EVENT_ID |
406 PS_REPORT_EVENT_ID; 413 PS_REPORT_EVENT_ID |
414 JOIN_EVENT_COMPLETE_ID |
415 DISCONNECT_EVENT_COMPLETE_ID;
407 416
408 ret = wl1271_event_unmask(wl); 417 ret = wl1271_event_unmask(wl);
409 if (ret < 0) { 418 if (ret < 0) {
@@ -444,11 +453,15 @@ int wl1271_boot(struct wl1271 *wl)
444 453
445 if (REF_CLOCK != 0) { 454 if (REF_CLOCK != 0) {
446 u16 val; 455 u16 val;
447 /* Set clock type */ 456 /* Set clock type (open drain) */
448 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); 457 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
449 val &= FREF_CLK_TYPE_BITS; 458 val &= FREF_CLK_TYPE_BITS;
450 val |= CLK_REQ_PRCM;
451 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val); 459 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
460
461 /* Set clock pull mode (no pull) */
462 val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL);
463 val |= NO_PULL;
464 wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val);
452 } else { 465 } else {
453 u16 val; 466 u16 val;
454 /* Set clock polarity */ 467 /* Set clock polarity */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index 412443ee655a..95ecc5241959 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -53,10 +53,13 @@ struct wl1271_static_data {
53#define OCP_REG_POLARITY 0x0064 53#define OCP_REG_POLARITY 0x0064
54#define OCP_REG_CLK_TYPE 0x0448 54#define OCP_REG_CLK_TYPE 0x0448
55#define OCP_REG_CLK_POLARITY 0x0cb2 55#define OCP_REG_CLK_POLARITY 0x0cb2
56#define OCP_REG_CLK_PULL 0x0cb4
56 57
57#define CMD_MBOX_ADDRESS 0x407B4
58 58
59#define POLARITY_LOW BIT(1) 59#define CMD_MBOX_ADDRESS 0x407B4
60
61#define POLARITY_LOW BIT(1)
62#define NO_PULL (BIT(14) | BIT(15))
60 63
61#define FREF_CLK_TYPE_BITS 0xfffffe7f 64#define FREF_CLK_TYPE_BITS 0xfffffe7f
62#define CLK_REQ_PRCM 0x100 65#define CLK_REQ_PRCM 0x100
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 36a64e06f290..b19090334bc0 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file is part of wl1271 2 * This file is part of wl1271
3 * 3 *
4 * Copyright (C) 2009 Nokia Corporation 4 * Copyright (C) 2009-2010 Nokia Corporation
5 * 5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 * 7 *
@@ -26,14 +26,17 @@
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
29#include <linux/ieee80211.h>
29 30
30#include "wl1271.h" 31#include "wl1271.h"
31#include "wl1271_reg.h" 32#include "wl1271_reg.h"
32#include "wl1271_spi.h"
33#include "wl1271_io.h" 33#include "wl1271_io.h"
34#include "wl1271_acx.h" 34#include "wl1271_acx.h"
35#include "wl12xx_80211.h" 35#include "wl12xx_80211.h"
36#include "wl1271_cmd.h" 36#include "wl1271_cmd.h"
37#include "wl1271_event.h"
38
39#define WL1271_CMD_POLL_COUNT 5
37 40
38/* 41/*
39 * send command to firmware 42 * send command to firmware
@@ -51,6 +54,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
51 u32 intr; 54 u32 intr;
52 int ret = 0; 55 int ret = 0;
53 u16 status; 56 u16 status;
57 u16 poll_count = 0;
54 58
55 cmd = buf; 59 cmd = buf;
56 cmd->id = cpu_to_le16(id); 60 cmd->id = cpu_to_le16(id);
@@ -72,7 +76,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
72 goto out; 76 goto out;
73 } 77 }
74 78
75 msleep(1); 79 udelay(10);
80 poll_count++;
81 if (poll_count == WL1271_CMD_POLL_COUNT)
82 wl1271_info("cmd polling took over %d cycles",
83 poll_count);
76 84
77 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 85 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
78 } 86 }
@@ -248,7 +256,36 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
248 return ret; 256 return ret;
249} 257}
250 258
251int wl1271_cmd_join(struct wl1271 *wl) 259/*
260 * Poll the mailbox event field until any of the bits in the mask is set or a
261 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
262 */
263static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
264{
265 u32 events_vector, event;
266 unsigned long timeout;
267
268 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
269
270 do {
271 if (time_after(jiffies, timeout))
272 return -ETIMEDOUT;
273
274 msleep(1);
275
276 /* read from both event fields */
277 wl1271_read(wl, wl->mbox_ptr[0], &events_vector,
278 sizeof(events_vector), false);
279 event = events_vector & mask;
280 wl1271_read(wl, wl->mbox_ptr[1], &events_vector,
281 sizeof(events_vector), false);
282 event |= events_vector & mask;
283 } while (!event);
284
285 return 0;
286}
287
288int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
252{ 289{
253 static bool do_cal = true; 290 static bool do_cal = true;
254 struct wl1271_cmd_join *join; 291 struct wl1271_cmd_join *join;
@@ -279,30 +316,13 @@ int wl1271_cmd_join(struct wl1271 *wl)
279 316
280 join->rx_config_options = cpu_to_le32(wl->rx_config); 317 join->rx_config_options = cpu_to_le32(wl->rx_config);
281 join->rx_filter_options = cpu_to_le32(wl->rx_filter); 318 join->rx_filter_options = cpu_to_le32(wl->rx_filter);
282 join->bss_type = wl->bss_type; 319 join->bss_type = bss_type;
320 join->basic_rate_set = wl->basic_rate_set;
283 321
284 /* 322 if (wl->band == IEEE80211_BAND_5GHZ)
285 * FIXME: disable temporarily all filters because after commit
286 * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
287 * association. The filter logic needs to be implemented properly
288 * and once that is done, this hack can be removed.
289 */
290 join->rx_config_options = cpu_to_le32(0);
291 join->rx_filter_options = cpu_to_le32(WL1271_DEFAULT_RX_FILTER);
292
293 if (wl->band == IEEE80211_BAND_2GHZ)
294 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS |
295 CONF_HW_BIT_RATE_2MBPS |
296 CONF_HW_BIT_RATE_5_5MBPS |
297 CONF_HW_BIT_RATE_11MBPS);
298 else {
299 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; 323 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
300 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_6MBPS |
301 CONF_HW_BIT_RATE_12MBPS |
302 CONF_HW_BIT_RATE_24MBPS);
303 }
304 324
305 join->beacon_interval = cpu_to_le16(WL1271_DEFAULT_BEACON_INT); 325 join->beacon_interval = cpu_to_le16(wl->beacon_int);
306 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; 326 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD;
307 327
308 join->channel = wl->channel; 328 join->channel = wl->channel;
@@ -319,8 +339,7 @@ int wl1271_cmd_join(struct wl1271 *wl)
319 339
320 /* reset TX security counters */ 340 /* reset TX security counters */
321 wl->tx_security_last_seq = 0; 341 wl->tx_security_last_seq = 0;
322 wl->tx_security_seq_16 = 0; 342 wl->tx_security_seq = 0;
323 wl->tx_security_seq_32 = 0;
324 343
325 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); 344 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
326 if (ret < 0) { 345 if (ret < 0) {
@@ -328,11 +347,9 @@ int wl1271_cmd_join(struct wl1271 *wl)
328 goto out_free; 347 goto out_free;
329 } 348 }
330 349
331 /* 350 ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID);
332 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to 351 if (ret < 0)
333 * simplify locking we just sleep instead, for now 352 wl1271_error("cmd join event completion error");
334 */
335 msleep(10);
336 353
337out_free: 354out_free:
338 kfree(join); 355 kfree(join);
@@ -464,7 +481,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
464 if (ret < 0) { 481 if (ret < 0) {
465 wl1271_error("tx %s cmd for channel %d failed", 482 wl1271_error("tx %s cmd for channel %d failed",
466 enable ? "start" : "stop", cmd->channel); 483 enable ? "start" : "stop", cmd->channel);
467 return ret; 484 goto out;
468 } 485 }
469 486
470 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", 487 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
@@ -548,25 +565,29 @@ out:
548 return ret; 565 return ret;
549} 566}
550 567
551int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 568int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
552 u8 active_scan, u8 high_prio, u8 band, 569 const u8 *ie, size_t ie_len, u8 active_scan,
553 u8 probe_requests) 570 u8 high_prio, u8 band, u8 probe_requests)
554{ 571{
555 572
556 struct wl1271_cmd_trigger_scan_to *trigger = NULL; 573 struct wl1271_cmd_trigger_scan_to *trigger = NULL;
557 struct wl1271_cmd_scan *params = NULL; 574 struct wl1271_cmd_scan *params = NULL;
558 struct ieee80211_channel *channels; 575 struct ieee80211_channel *channels;
576 u32 rate;
559 int i, j, n_ch, ret; 577 int i, j, n_ch, ret;
560 u16 scan_options = 0; 578 u16 scan_options = 0;
561 u8 ieee_band; 579 u8 ieee_band;
562 580
563 if (band == WL1271_SCAN_BAND_2_4_GHZ) 581 if (band == WL1271_SCAN_BAND_2_4_GHZ) {
564 ieee_band = IEEE80211_BAND_2GHZ; 582 ieee_band = IEEE80211_BAND_2GHZ;
565 else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) 583 rate = wl->conf.tx.basic_rate;
584 } else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) {
566 ieee_band = IEEE80211_BAND_2GHZ; 585 ieee_band = IEEE80211_BAND_2GHZ;
567 else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) 586 rate = wl->conf.tx.basic_rate;
587 } else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) {
568 ieee_band = IEEE80211_BAND_5GHZ; 588 ieee_band = IEEE80211_BAND_5GHZ;
569 else 589 rate = wl->conf.tx.basic_rate_5;
590 } else
570 return -EINVAL; 591 return -EINVAL;
571 592
572 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL) 593 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL)
@@ -593,8 +614,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
593 params->params.scan_options = cpu_to_le16(scan_options); 614 params->params.scan_options = cpu_to_le16(scan_options);
594 615
595 params->params.num_probe_requests = probe_requests; 616 params->params.num_probe_requests = probe_requests;
596 /* Let the fw autodetect suitable tx_rate for probes */ 617 params->params.tx_rate = rate;
597 params->params.tx_rate = 0;
598 params->params.tid_trigger = 0; 618 params->params.tid_trigger = 0;
599 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; 619 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
600 620
@@ -621,12 +641,13 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
621 641
622 params->params.num_channels = j; 642 params->params.num_channels = j;
623 643
624 if (len && ssid) { 644 if (ssid_len && ssid) {
625 params->params.ssid_len = len; 645 params->params.ssid_len = ssid_len;
626 memcpy(params->params.ssid, ssid, len); 646 memcpy(params->params.ssid, ssid, ssid_len);
627 } 647 }
628 648
629 ret = wl1271_cmd_build_probe_req(wl, ssid, len, ieee_band); 649 ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len,
650 ie, ie_len, ieee_band);
630 if (ret < 0) { 651 if (ret < 0) {
631 wl1271_error("PROBE request template failed"); 652 wl1271_error("PROBE request template failed");
632 goto out; 653 goto out;
@@ -657,9 +678,9 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
657 wl->scan.active = active_scan; 678 wl->scan.active = active_scan;
658 wl->scan.high_prio = high_prio; 679 wl->scan.high_prio = high_prio;
659 wl->scan.probe_requests = probe_requests; 680 wl->scan.probe_requests = probe_requests;
660 if (len && ssid) { 681 if (ssid_len && ssid) {
661 wl->scan.ssid_len = len; 682 wl->scan.ssid_len = ssid_len;
662 memcpy(wl->scan.ssid, ssid, len); 683 memcpy(wl->scan.ssid, ssid, ssid_len);
663 } else 684 } else
664 wl->scan.ssid_len = 0; 685 wl->scan.ssid_len = 0;
665 } 686 }
@@ -674,11 +695,12 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
674 695
675out: 696out:
676 kfree(params); 697 kfree(params);
698 kfree(trigger);
677 return ret; 699 return ret;
678} 700}
679 701
680int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 702int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
681 void *buf, size_t buf_len) 703 void *buf, size_t buf_len, int index, u32 rates)
682{ 704{
683 struct wl1271_cmd_template_set *cmd; 705 struct wl1271_cmd_template_set *cmd;
684 int ret = 0; 706 int ret = 0;
@@ -696,9 +718,10 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
696 718
697 cmd->len = cpu_to_le16(buf_len); 719 cmd->len = cpu_to_le16(buf_len);
698 cmd->template_type = template_id; 720 cmd->template_type = template_id;
699 cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates); 721 cmd->enabled_rates = cpu_to_le32(rates);
700 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; 722 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit;
701 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; 723 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit;
724 cmd->index = index;
702 725
703 if (buf) 726 if (buf)
704 memcpy(cmd->template_data, buf, buf_len); 727 memcpy(cmd->template_data, buf, buf_len);
@@ -716,155 +739,129 @@ out:
716 return ret; 739 return ret;
717} 740}
718 741
719static int wl1271_build_basic_rates(u8 *rates, u8 band) 742int wl1271_cmd_build_null_data(struct wl1271 *wl)
720{ 743{
721 u8 index = 0; 744 struct sk_buff *skb = NULL;
722 745 int size;
723 if (band == IEEE80211_BAND_2GHZ) { 746 void *ptr;
724 rates[index++] = 747 int ret = -ENOMEM;
725 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
726 rates[index++] =
727 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
728 rates[index++] =
729 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
730 rates[index++] =
731 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
732 } else if (band == IEEE80211_BAND_5GHZ) {
733 rates[index++] =
734 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
735 rates[index++] =
736 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
737 rates[index++] =
738 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
739 } else {
740 wl1271_error("build_basic_rates invalid band: %d", band);
741 }
742 748
743 return index;
744}
745 749
746static int wl1271_build_extended_rates(u8 *rates, u8 band) 750 if (wl->bss_type == BSS_TYPE_IBSS) {
747{ 751 size = sizeof(struct wl12xx_null_data_template);
748 u8 index = 0; 752 ptr = NULL;
749
750 if (band == IEEE80211_BAND_2GHZ) {
751 rates[index++] = IEEE80211_OFDM_RATE_6MB;
752 rates[index++] = IEEE80211_OFDM_RATE_9MB;
753 rates[index++] = IEEE80211_OFDM_RATE_12MB;
754 rates[index++] = IEEE80211_OFDM_RATE_18MB;
755 rates[index++] = IEEE80211_OFDM_RATE_24MB;
756 rates[index++] = IEEE80211_OFDM_RATE_36MB;
757 rates[index++] = IEEE80211_OFDM_RATE_48MB;
758 rates[index++] = IEEE80211_OFDM_RATE_54MB;
759 } else if (band == IEEE80211_BAND_5GHZ) {
760 rates[index++] =
761 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
762 rates[index++] =
763 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
764 rates[index++] =
765 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
766 rates[index++] =
767 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
768 rates[index++] =
769 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
770 rates[index++] =
771 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
772 } else { 753 } else {
773 wl1271_error("build_basic_rates invalid band: %d", band); 754 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
755 if (!skb)
756 goto out;
757 size = skb->len;
758 ptr = skb->data;
774 } 759 }
775 760
776 return index; 761 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
762 WL1271_RATE_AUTOMATIC);
763
764out:
765 dev_kfree_skb(skb);
766 if (ret)
767 wl1271_warning("cmd buld null data failed %d", ret);
768
769 return ret;
770
777} 771}
778 772
779int wl1271_cmd_build_null_data(struct wl1271 *wl) 773int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
780{ 774{
781 struct wl12xx_null_data_template template; 775 struct sk_buff *skb = NULL;
776 int ret = -ENOMEM;
782 777
783 if (!is_zero_ether_addr(wl->bssid)) { 778 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
784 memcpy(template.header.da, wl->bssid, ETH_ALEN); 779 if (!skb)
785 memcpy(template.header.bssid, wl->bssid, ETH_ALEN); 780 goto out;
786 } else { 781
787 memset(template.header.da, 0xff, ETH_ALEN); 782 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
788 memset(template.header.bssid, 0xff, ETH_ALEN); 783 skb->data, skb->len,
789 } 784 CMD_TEMPL_KLV_IDX_NULL_DATA,
785 WL1271_RATE_AUTOMATIC);
790 786
791 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); 787out:
792 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | 788 dev_kfree_skb(skb);
793 IEEE80211_STYPE_NULLFUNC | 789 if (ret)
794 IEEE80211_FCTL_TODS); 790 wl1271_warning("cmd build klv null data failed %d", ret);
795 791
796 return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template, 792 return ret;
797 sizeof(template));
798 793
799} 794}
800 795
801int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) 796int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
802{ 797{
803 struct wl12xx_ps_poll_template template; 798 struct sk_buff *skb;
804 799 int ret = 0;
805 memcpy(template.bssid, wl->bssid, ETH_ALEN);
806 memcpy(template.ta, wl->mac_addr, ETH_ALEN);
807
808 /* aid in PS-Poll has its two MSBs each set to 1 */
809 template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid);
810 800
811 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); 801 skb = ieee80211_pspoll_get(wl->hw, wl->vif);
802 if (!skb)
803 goto out;
812 804
813 return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template, 805 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
814 sizeof(template)); 806 skb->len, 0, wl->basic_rate);
815 807
808out:
809 dev_kfree_skb(skb);
810 return ret;
816} 811}
817 812
818int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len, 813int wl1271_cmd_build_probe_req(struct wl1271 *wl,
819 u8 band) 814 const u8 *ssid, size_t ssid_len,
815 const u8 *ie, size_t ie_len, u8 band)
820{ 816{
821 struct wl12xx_probe_req_template template; 817 struct sk_buff *skb;
822 struct wl12xx_ie_rates *rates;
823 char *ptr;
824 u16 size;
825 int ret; 818 int ret;
826 819
827 ptr = (char *)&template; 820 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
828 size = sizeof(struct ieee80211_header); 821 ie, ie_len);
829 822 if (!skb) {
830 memset(template.header.da, 0xff, ETH_ALEN); 823 ret = -ENOMEM;
831 memset(template.header.bssid, 0xff, ETH_ALEN); 824 goto out;
832 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); 825 }
833 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); 826
834 827 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
835 /* IEs */
836 /* SSID */
837 template.ssid.header.id = WLAN_EID_SSID;
838 template.ssid.header.len = ssid_len;
839 if (ssid_len && ssid)
840 memcpy(template.ssid.ssid, ssid, ssid_len);
841 size += sizeof(struct wl12xx_ie_header) + ssid_len;
842 ptr += size;
843
844 /* Basic Rates */
845 rates = (struct wl12xx_ie_rates *)ptr;
846 rates->header.id = WLAN_EID_SUPP_RATES;
847 rates->header.len = wl1271_build_basic_rates(rates->rates, band);
848 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
849 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
850
851 /* Extended rates */
852 rates = (struct wl12xx_ie_rates *)ptr;
853 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
854 rates->header.len = wl1271_build_extended_rates(rates->rates, band);
855 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
856
857 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
858 828
859 if (band == IEEE80211_BAND_2GHZ) 829 if (band == IEEE80211_BAND_2GHZ)
860 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 830 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
861 &template, size); 831 skb->data, skb->len, 0,
832 wl->conf.tx.basic_rate);
862 else 833 else
863 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 834 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
864 &template, size); 835 skb->data, skb->len, 0,
836 wl->conf.tx.basic_rate_5);
837
838out:
839 dev_kfree_skb(skb);
865 return ret; 840 return ret;
866} 841}
867 842
843int wl1271_build_qos_null_data(struct wl1271 *wl)
844{
845 struct ieee80211_qos_hdr template;
846
847 memset(&template, 0, sizeof(template));
848
849 memcpy(template.addr1, wl->bssid, ETH_ALEN);
850 memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
851 memcpy(template.addr3, wl->bssid, ETH_ALEN);
852
853 template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
854 IEEE80211_STYPE_QOS_NULLFUNC |
855 IEEE80211_FCTL_TODS);
856
857 /* FIXME: not sure what priority to use here */
858 template.qos_ctrl = cpu_to_le16(0);
859
860 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
861 sizeof(template), 0,
862 WL1271_RATE_AUTOMATIC);
863}
864
868int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) 865int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
869{ 866{
870 struct wl1271_cmd_set_keys *cmd; 867 struct wl1271_cmd_set_keys *cmd;
@@ -975,6 +972,10 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
975 goto out_free; 972 goto out_free;
976 } 973 }
977 974
975 ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
976 if (ret < 0)
977 wl1271_error("cmd disconnect event completion error");
978
978out_free: 979out_free:
979 kfree(cmd); 980 kfree(cmd);
980 981
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index 2dc06c73532b..00f78b7aa384 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -33,7 +33,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
33 size_t res_len); 33 size_t res_len);
34int wl1271_cmd_general_parms(struct wl1271 *wl); 34int wl1271_cmd_general_parms(struct wl1271 *wl);
35int wl1271_cmd_radio_parms(struct wl1271 *wl); 35int wl1271_cmd_radio_parms(struct wl1271 *wl);
36int wl1271_cmd_join(struct wl1271 *wl); 36int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type);
37int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); 37int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); 38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
@@ -41,15 +41,18 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); 41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, 42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
43 size_t len); 43 size_t len);
44int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 44int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
45 u8 active_scan, u8 high_prio, u8 band, 45 const u8 *ie, size_t ie_len, u8 active_scan,
46 u8 probe_requests); 46 u8 high_prio, u8 band, u8 probe_requests);
47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
48 void *buf, size_t buf_len); 48 void *buf, size_t buf_len, int index, u32 rates);
49int wl1271_cmd_build_null_data(struct wl1271 *wl); 49int wl1271_cmd_build_null_data(struct wl1271 *wl);
50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); 50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
51int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len, 51int wl1271_cmd_build_probe_req(struct wl1271 *wl,
52 u8 band); 52 const u8 *ssid, size_t ssid_len,
53 const u8 *ie, size_t ie_len, u8 band);
54int wl1271_build_qos_null_data(struct wl1271 *wl);
55int wl1271_cmd_build_klv_null_data(struct wl1271 *wl);
53int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); 56int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
54int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 57int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
55 u8 key_size, const u8 *key, const u8 *addr, 58 u8 key_size, const u8 *key, const u8 *addr,
@@ -99,6 +102,11 @@ enum wl1271_commands {
99 102
100#define MAX_CMD_PARAMS 572 103#define MAX_CMD_PARAMS 572
101 104
105enum {
106 CMD_TEMPL_KLV_IDX_NULL_DATA = 0,
107 CMD_TEMPL_KLV_IDX_MAX = 4
108};
109
102enum cmd_templ { 110enum cmd_templ {
103 CMD_TEMPL_NULL_DATA = 0, 111 CMD_TEMPL_NULL_DATA = 0,
104 CMD_TEMPL_BEACON, 112 CMD_TEMPL_BEACON,
@@ -121,6 +129,7 @@ enum cmd_templ {
121/* unit ms */ 129/* unit ms */
122#define WL1271_COMMAND_TIMEOUT 2000 130#define WL1271_COMMAND_TIMEOUT 2000
123#define WL1271_CMD_TEMPL_MAX_SIZE 252 131#define WL1271_CMD_TEMPL_MAX_SIZE 252
132#define WL1271_EVENT_TIMEOUT 100
124 133
125struct wl1271_cmd_header { 134struct wl1271_cmd_header {
126 __le16 id; 135 __le16 id;
@@ -243,6 +252,8 @@ struct cmd_enabledisable_path {
243 u8 padding[3]; 252 u8 padding[3];
244} __attribute__ ((packed)); 253} __attribute__ ((packed));
245 254
255#define WL1271_RATE_AUTOMATIC 0
256
246struct wl1271_cmd_template_set { 257struct wl1271_cmd_template_set {
247 struct wl1271_cmd_header header; 258 struct wl1271_cmd_header header;
248 259
@@ -509,6 +520,8 @@ enum wl1271_disconnect_type {
509}; 520};
510 521
511struct wl1271_cmd_disconnect { 522struct wl1271_cmd_disconnect {
523 struct wl1271_cmd_header header;
524
512 __le32 rx_config_options; 525 __le32 rx_config_options;
513 __le32 rx_filter_options; 526 __le32 rx_filter_options;
514 527
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 6f9e75cc5640..d76ae03762a3 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -65,110 +65,344 @@ enum {
65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, 65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS,
66}; 66};
67 67
68struct conf_sg_settings { 68enum {
69 CONF_HW_RXTX_RATE_MCS7 = 0,
70 CONF_HW_RXTX_RATE_MCS6,
71 CONF_HW_RXTX_RATE_MCS5,
72 CONF_HW_RXTX_RATE_MCS4,
73 CONF_HW_RXTX_RATE_MCS3,
74 CONF_HW_RXTX_RATE_MCS2,
75 CONF_HW_RXTX_RATE_MCS1,
76 CONF_HW_RXTX_RATE_MCS0,
77 CONF_HW_RXTX_RATE_54,
78 CONF_HW_RXTX_RATE_48,
79 CONF_HW_RXTX_RATE_36,
80 CONF_HW_RXTX_RATE_24,
81 CONF_HW_RXTX_RATE_22,
82 CONF_HW_RXTX_RATE_18,
83 CONF_HW_RXTX_RATE_12,
84 CONF_HW_RXTX_RATE_11,
85 CONF_HW_RXTX_RATE_9,
86 CONF_HW_RXTX_RATE_6,
87 CONF_HW_RXTX_RATE_5_5,
88 CONF_HW_RXTX_RATE_2,
89 CONF_HW_RXTX_RATE_1,
90 CONF_HW_RXTX_RATE_MAX,
91 CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff
92};
93
94enum {
95 CONF_SG_DISABLE = 0,
96 CONF_SG_PROTECTIVE,
97 CONF_SG_OPPORTUNISTIC
98};
99
100enum {
69 /* 101 /*
70 * Defines the PER threshold in PPM of the BT voice of which reaching 102 * PER threshold in PPM of the BT voice
71 * this value will trigger raising the priority of the BT voice by
72 * the BT IP until next NFS sample interval time as defined in
73 * nfs_sample_interval.
74 * 103 *
75 * Unit: PER value in PPM (parts per million) 104 * Range: 0 - 10000000
76 * #Error_packets / #Total_packets 105 */
106 CONF_SG_BT_PER_THRESHOLD = 0,
77 107
78 * Range: u32 108 /*
109 * Number of consequent RX_ACTIVE activities to override BT voice
110 * frames to ensure WLAN connection
111 *
112 * Range: 0 - 100
113 */
114 CONF_SG_HV3_MAX_OVERRIDE,
115
116 /*
117 * Defines the PER threshold of the BT voice
118 *
119 * Range: 0 - 65000
120 */
121 CONF_SG_BT_NFS_SAMPLE_INTERVAL,
122
123 /*
124 * Defines the load ratio of BT
125 *
126 * Range: 0 - 100 (%)
127 */
128 CONF_SG_BT_LOAD_RATIO,
129
130 /*
131 * Defines whether the SG will force WLAN host to enter/exit PSM
132 *
133 * Range: 1 - SG can force, 0 - host handles PSM
134 */
135 CONF_SG_AUTO_PS_MODE,
136
137 /*
138 * Compensation percentage of probe requests when scan initiated
139 * during BT voice/ACL link.
140 *
141 * Range: 0 - 255 (%)
142 */
143 CONF_SG_AUTO_SCAN_PROBE_REQ,
144
145 /*
146 * Compensation percentage of probe requests when active scan initiated
147 * during BT voice
148 *
149 * Range: 0 - 255 (%)
150 */
151 CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3,
152
153 /*
154 * Defines antenna configuration (single/dual antenna)
155 *
156 * Range: 0 - single antenna, 1 - dual antenna
157 */
158 CONF_SG_ANTENNA_CONFIGURATION,
159
160 /*
161 * The threshold (percent) of max consequtive beacon misses before
162 * increasing priority of beacon reception.
163 *
164 * Range: 0 - 100 (%)
165 */
166 CONF_SG_BEACON_MISS_PERCENT,
167
168 /*
169 * The rate threshold below which receiving a data frame from the AP
170 * will increase the priority of the data frame above BT traffic.
171 *
172 * Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54
173 */
174 CONF_SG_RATE_ADAPT_THRESH,
175
176 /*
177 * Not used currently.
178 *
179 * Range: 0
180 */
181 CONF_SG_RATE_ADAPT_SNR,
182
183 /*
184 * Configure the min and max time BT gains the antenna
185 * in WLAN PSM / BT master basic rate
186 *
187 * Range: 0 - 255 (ms)
79 */ 188 */
80 u32 per_threshold; 189 CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR,
190 CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR,
81 191
82 /* 192 /*
83 * This value is an absolute time in micro-seconds to limit the 193 * The time after it expires no new WLAN trigger frame is trasmitted
84 * maximum scan duration compensation while in SG 194 * in WLAN PSM / BT master basic rate
195 *
196 * Range: 0 - 255 (ms)
85 */ 197 */
86 u32 max_scan_compensation_time; 198 CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR,
87 199
88 /* Defines the PER threshold of the BT voice of which reaching this 200 /*
89 * value will trigger raising the priority of the BT voice until next 201 * Configure the min and max time BT gains the antenna
90 * NFS sample interval time as defined in sample_interval. 202 * in WLAN PSM / BT slave basic rate
91 * 203 *
92 * Unit: msec 204 * Range: 0 - 255 (ms)
93 * Range: 1-65000
94 */ 205 */
95 u16 nfs_sample_interval; 206 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR,
207 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR,
96 208
97 /* 209 /*
98 * Defines the load ratio for the BT. 210 * The time after it expires no new WLAN trigger frame is trasmitted
99 * The WLAN ratio is: 100 - load_ratio 211 * in WLAN PSM / BT slave basic rate
100 * 212 *
101 * Unit: Percent 213 * Range: 0 - 255 (ms)
102 * Range: 0-100
103 */ 214 */
104 u8 load_ratio; 215 CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR,
105 216
106 /* 217 /*
107 * true - Co-ex is allowed to enter/exit P.S automatically and 218 * Configure the min and max time BT gains the antenna
108 * transparently to the host 219 * in WLAN PSM / BT master EDR
109 * 220 *
110 * false - Co-ex is disallowed to enter/exit P.S and will trigger an 221 * Range: 0 - 255 (ms)
111 * event to the host to notify for the need to enter/exit P.S 222 */
112 * due to BT change state 223 CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR,
224 CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR,
225
226 /*
227 * The time after it expires no new WLAN trigger frame is trasmitted
228 * in WLAN PSM / BT master EDR
113 * 229 *
230 * Range: 0 - 255 (ms)
114 */ 231 */
115 u8 auto_ps_mode; 232 CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR,
116 233
117 /* 234 /*
118 * This parameter defines the compensation percentage of num of probe 235 * Configure the min and max time BT gains the antenna
119 * requests in case scan is initiated during BT voice/BT ACL 236 * in WLAN PSM / BT slave EDR
120 * guaranteed link.
121 * 237 *
122 * Unit: Percent 238 * Range: 0 - 255 (ms)
123 * Range: 0-255 (0 - No compensation)
124 */ 239 */
125 u8 probe_req_compensation; 240 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR,
241 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR,
126 242
127 /* 243 /*
128 * This parameter defines the compensation percentage of scan window 244 * The time after it expires no new WLAN trigger frame is trasmitted
129 * size in case scan is initiated during BT voice/BT ACL Guaranteed 245 * in WLAN PSM / BT slave EDR
130 * link.
131 * 246 *
132 * Unit: Percent 247 * Range: 0 - 255 (ms)
133 * Range: 0-255 (0 - No compensation)
134 */ 248 */
135 u8 scan_window_compensation; 249 CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR,
136 250
137 /* 251 /*
138 * Defines the antenna configuration. 252 * RX guard time before the beginning of a new BT voice frame during
253 * which no new WLAN trigger frame is transmitted.
139 * 254 *
140 * Range: 0 - Single Antenna; 1 - Dual Antenna 255 * Range: 0 - 100000 (us)
141 */ 256 */
142 u8 antenna_config; 257 CONF_SG_RXT,
143 258
144 /* 259 /*
145 * The percent out of the Max consecutive beacon miss roaming trigger 260 * TX guard time before the beginning of a new BT voice frame during
146 * which is the threshold for raising the priority of beacon 261 * which no new WLAN frame is transmitted.
147 * reception.
148 * 262 *
149 * Range: 1-100 263 * Range: 0 - 100000 (us)
150 * N = MaxConsecutiveBeaconMiss
151 * P = coexMaxConsecutiveBeaconMissPrecent
152 * Threshold = MIN( N-1, round(N * P / 100))
153 */ 264 */
154 u8 beacon_miss_threshold; 265
266 CONF_SG_TXT,
155 267
156 /* 268 /*
157 * The RX rate threshold below which rate adaptation is assumed to be 269 * Enable adaptive RXT/TXT algorithm. If disabled, the host values
158 * occurring at the AP which will raise priority for ACTIVE_RX and RX 270 * will be utilized.
159 * SP.
160 * 271 *
161 * Range: HW_BIT_RATE_* 272 * Range: 0 - disable, 1 - enable
162 */ 273 */
163 u32 rate_adaptation_threshold; 274 CONF_SG_ADAPTIVE_RXT_TXT,
164 275
165 /* 276 /*
166 * The SNR above which the RX rate threshold indicating AP rate 277 * The used WLAN legacy service period during active BT ACL link
167 * adaptation is valid
168 * 278 *
169 * Range: -128 - 127 279 * Range: 0 - 255 (ms)
170 */ 280 */
171 s8 rate_adaptation_snr; 281 CONF_SG_PS_POLL_TIMEOUT,
282
283 /*
284 * The used WLAN UPSD service period during active BT ACL link
285 *
286 * Range: 0 - 255 (ms)
287 */
288 CONF_SG_UPSD_TIMEOUT,
289
290 /*
291 * Configure the min and max time BT gains the antenna
292 * in WLAN Active / BT master EDR
293 *
294 * Range: 0 - 255 (ms)
295 */
296 CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR,
297 CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR,
298
299 /*
300 * The maximum time WLAN can gain the antenna for
301 * in WLAN Active / BT master EDR
302 *
303 * Range: 0 - 255 (ms)
304 */
305 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR,
306
307 /*
308 * Configure the min and max time BT gains the antenna
309 * in WLAN Active / BT slave EDR
310 *
311 * Range: 0 - 255 (ms)
312 */
313 CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR,
314 CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR,
315
316 /*
317 * The maximum time WLAN can gain the antenna for
318 * in WLAN Active / BT slave EDR
319 *
320 * Range: 0 - 255 (ms)
321 */
322 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR,
323
324 /*
325 * Configure the min and max time BT gains the antenna
326 * in WLAN Active / BT basic rate
327 *
328 * Range: 0 - 255 (ms)
329 */
330 CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR,
331 CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR,
332
333 /*
334 * The maximum time WLAN can gain the antenna for
335 * in WLAN Active / BT basic rate
336 *
337 * Range: 0 - 255 (ms)
338 */
339 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR,
340
341 /*
342 * Compensation percentage of WLAN passive scan window if initiated
343 * during BT voice
344 *
345 * Range: 0 - 1000 (%)
346 */
347 CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3,
348
349 /*
350 * Compensation percentage of WLAN passive scan window if initiated
351 * during BT A2DP
352 *
353 * Range: 0 - 1000 (%)
354 */
355 CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP,
356
357 /*
358 * Fixed time ensured for BT traffic to gain the antenna during WLAN
359 * passive scan.
360 *
361 * Range: 0 - 1000 ms
362 */
363 CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME,
364
365 /*
366 * Fixed time ensured for WLAN traffic to gain the antenna during WLAN
367 * passive scan.
368 *
369 * Range: 0 - 1000 ms
370 */
371 CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME,
372
373 /*
374 * Number of consequent BT voice frames not interrupted by WLAN
375 *
376 * Range: 0 - 100
377 */
378 CONF_SG_HV3_MAX_SERVED,
379
380 /*
381 * Protection time of the DHCP procedure.
382 *
383 * Range: 0 - 100000 (ms)
384 */
385 CONF_SG_DHCP_TIME,
386
387 /*
388 * Compensation percentage of WLAN active scan window if initiated
389 * during BT A2DP
390 *
391 * Range: 0 - 1000 (%)
392 */
393 CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP,
394 CONF_SG_TEMP_PARAM_1,
395 CONF_SG_TEMP_PARAM_2,
396 CONF_SG_TEMP_PARAM_3,
397 CONF_SG_TEMP_PARAM_4,
398 CONF_SG_TEMP_PARAM_5,
399 CONF_SG_PARAMS_MAX,
400 CONF_SG_PARAMS_ALL = 0xff
401};
402
403struct conf_sg_settings {
404 __le32 params[CONF_SG_PARAMS_MAX];
405 u8 state;
172}; 406};
173 407
174enum conf_rx_queue_type { 408enum conf_rx_queue_type {
@@ -440,6 +674,19 @@ struct conf_tx_settings {
440 */ 674 */
441 u16 tx_compl_threshold; 675 u16 tx_compl_threshold;
442 676
677 /*
678 * The rate used for control messages and scanning on the 2.4GHz band
679 *
680 * Range: CONF_HW_BIT_RATE_* bit mask
681 */
682 u32 basic_rate;
683
684 /*
685 * The rate used for control messages and scanning on the 5GHz band
686 *
687 * Range: CONF_HW_BIT_RATE_* bit mask
688 */
689 u32 basic_rate_5;
443}; 690};
444 691
445enum { 692enum {
@@ -721,6 +968,22 @@ struct conf_conn_settings {
721 * Range 0 - 255 968 * Range 0 - 255
722 */ 969 */
723 u8 psm_entry_retries; 970 u8 psm_entry_retries;
971
972 /*
973 *
974 * Specifies the interval of the connection keep-alive null-func
975 * frame in ms.
976 *
977 * Range: 1000 - 3600000
978 */
979 u32 keep_alive_interval;
980
981 /*
982 * Maximum listen interval supported by the driver in units of beacons.
983 *
984 * Range: u16
985 */
986 u8 max_listen_interval;
724}; 987};
725 988
726enum { 989enum {
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index 8d7588ca68fd..3c0f5b1ac272 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -28,6 +28,7 @@
28#include "wl1271.h" 28#include "wl1271.h"
29#include "wl1271_acx.h" 29#include "wl1271_acx.h"
30#include "wl1271_ps.h" 30#include "wl1271_ps.h"
31#include "wl1271_io.h"
31 32
32/* ms */ 33/* ms */
33#define WL1271_DEBUGFS_STATS_LIFETIME 1000 34#define WL1271_DEBUGFS_STATS_LIFETIME 1000
@@ -276,13 +277,10 @@ static ssize_t gpio_power_write(struct file *file,
276 goto out; 277 goto out;
277 } 278 }
278 279
279 if (value) { 280 if (value)
280 wl->set_power(true); 281 wl1271_power_on(wl);
281 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); 282 else
282 } else { 283 wl1271_power_off(wl);
283 wl->set_power(false);
284 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
285 }
286 284
287out: 285out:
288 mutex_unlock(&wl->mutex); 286 mutex_unlock(&wl->mutex);
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 7468ef10194b..daacf176cf09 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -23,7 +23,6 @@
23 23
24#include "wl1271.h" 24#include "wl1271.h"
25#include "wl1271_reg.h" 25#include "wl1271_reg.h"
26#include "wl1271_spi.h"
27#include "wl1271_io.h" 26#include "wl1271_io.h"
28#include "wl1271_event.h" 27#include "wl1271_event.h"
29#include "wl1271_ps.h" 28#include "wl1271_ps.h"
@@ -32,34 +31,24 @@
32static int wl1271_event_scan_complete(struct wl1271 *wl, 31static int wl1271_event_scan_complete(struct wl1271 *wl,
33 struct event_mailbox *mbox) 32 struct event_mailbox *mbox)
34{ 33{
35 int size = sizeof(struct wl12xx_probe_req_template);
36 wl1271_debug(DEBUG_EVENT, "status: 0x%x", 34 wl1271_debug(DEBUG_EVENT, "status: 0x%x",
37 mbox->scheduled_scan_status); 35 mbox->scheduled_scan_status);
38 36
39 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) { 37 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
40 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) { 38 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) {
41 wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
42 NULL, size);
43 /* 2.4 GHz band scanned, scan 5 GHz band, pretend 39 /* 2.4 GHz band scanned, scan 5 GHz band, pretend
44 * to the wl1271_cmd_scan function that we are not 40 * to the wl1271_cmd_scan function that we are not
45 * scanning as it checks that. 41 * scanning as it checks that.
46 */ 42 */
47 clear_bit(WL1271_FLAG_SCANNING, &wl->flags); 43 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
44 /* FIXME: ie missing! */
48 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, 45 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
46 NULL, 0,
49 wl->scan.active, 47 wl->scan.active,
50 wl->scan.high_prio, 48 wl->scan.high_prio,
51 WL1271_SCAN_BAND_5_GHZ, 49 WL1271_SCAN_BAND_5_GHZ,
52 wl->scan.probe_requests); 50 wl->scan.probe_requests);
53 } else { 51 } else {
54 if (wl->scan.state == WL1271_SCAN_BAND_2_4_GHZ)
55 wl1271_cmd_template_set(wl,
56 CMD_TEMPL_CFG_PROBE_REQ_2_4,
57 NULL, size);
58 else
59 wl1271_cmd_template_set(wl,
60 CMD_TEMPL_CFG_PROBE_REQ_5,
61 NULL, size);
62
63 mutex_unlock(&wl->mutex); 52 mutex_unlock(&wl->mutex);
64 ieee80211_scan_completed(wl->hw, false); 53 ieee80211_scan_completed(wl->hw, false);
65 mutex_lock(&wl->mutex); 54 mutex_lock(&wl->mutex);
@@ -92,16 +81,9 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
92 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, 81 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
93 true); 82 true);
94 } else { 83 } else {
95 wl1271_error("PSM entry failed, giving up.\n"); 84 wl1271_info("No ack to nullfunc from AP.");
96 /* FIXME: this may need to be reconsidered. for now it
97 is not possible to indicate to the mac80211
98 afterwards that PSM entry failed. To maximize
99 functionality (receiving data and remaining
100 associated) make sure that we are in sync with the
101 AP in regard of PSM mode. */
102 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
103 false);
104 wl->psm_entry_retry = 0; 85 wl->psm_entry_retry = 0;
86 *beacon_loss = true;
105 } 87 }
106 break; 88 break;
107 case EVENT_ENTER_POWER_SAVE_SUCCESS: 89 case EVENT_ENTER_POWER_SAVE_SUCCESS:
@@ -172,10 +154,13 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
172 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon 154 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
173 * filtering) is enabled. Without PSM, the stack will receive all 155 * filtering) is enabled. Without PSM, the stack will receive all
174 * beacons and can detect beacon loss by itself. 156 * beacons and can detect beacon loss by itself.
157 *
158 * As there's possibility that the driver disables PSM before receiving
159 * BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
160 *
175 */ 161 */
176 if (vector & BSS_LOSE_EVENT_ID && 162 if (vector & BSS_LOSE_EVENT_ID) {
177 test_bit(WL1271_FLAG_PSM, &wl->flags)) { 163 wl1271_info("Beacon loss detected.");
178 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
179 164
180 /* indicate to the stack, that beacons have been lost */ 165 /* indicate to the stack, that beacons have been lost */
181 beacon_loss = true; 166 beacon_loss = true;
@@ -188,16 +173,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
188 return ret; 173 return ret;
189 } 174 }
190 175
191 if (wl->vif && beacon_loss) { 176 if (wl->vif && beacon_loss)
192 /* Obviously, it's dangerous to release the mutex while 177 ieee80211_connection_loss(wl->vif);
193 we are holding many of the variables in the wl struct.
194 That's why it's done last in the function, and care must
195 be taken that nothing more is done after this function
196 returns. */
197 mutex_unlock(&wl->mutex);
198 ieee80211_beacon_loss(wl->vif);
199 mutex_lock(&wl->mutex);
200 }
201 178
202 return 0; 179 return 0;
203} 180}
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 86c30a86a456..9ab336829044 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -51,50 +51,65 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
51 51
52int wl1271_init_templates_config(struct wl1271 *wl) 52int wl1271_init_templates_config(struct wl1271 *wl)
53{ 53{
54 int ret; 54 int ret, i;
55 55
56 /* send empty templates for fw memory reservation */ 56 /* send empty templates for fw memory reservation */
57 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 57 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
58 sizeof(struct wl12xx_probe_req_template)); 58 sizeof(struct wl12xx_probe_req_template),
59 0, WL1271_RATE_AUTOMATIC);
59 if (ret < 0) 60 if (ret < 0)
60 return ret; 61 return ret;
61 62
62 if (wl1271_11a_enabled()) { 63 if (wl1271_11a_enabled()) {
64 size_t size = sizeof(struct wl12xx_probe_req_template);
63 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 65 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
64 NULL, 66 NULL, size, 0,
65 sizeof(struct wl12xx_probe_req_template)); 67 WL1271_RATE_AUTOMATIC);
66 if (ret < 0) 68 if (ret < 0)
67 return ret; 69 return ret;
68 } 70 }
69 71
70 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, 72 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
71 sizeof(struct wl12xx_null_data_template)); 73 sizeof(struct wl12xx_null_data_template),
74 0, WL1271_RATE_AUTOMATIC);
72 if (ret < 0) 75 if (ret < 0)
73 return ret; 76 return ret;
74 77
75 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, 78 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
76 sizeof(struct wl12xx_ps_poll_template)); 79 sizeof(struct wl12xx_ps_poll_template),
80 0, WL1271_RATE_AUTOMATIC);
77 if (ret < 0) 81 if (ret < 0)
78 return ret; 82 return ret;
79 83
80 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, 84 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
81 sizeof 85 sizeof
82 (struct wl12xx_qos_null_data_template)); 86 (struct wl12xx_qos_null_data_template),
87 0, WL1271_RATE_AUTOMATIC);
83 if (ret < 0) 88 if (ret < 0)
84 return ret; 89 return ret;
85 90
86 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, 91 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
87 sizeof 92 sizeof
88 (struct wl12xx_probe_resp_template)); 93 (struct wl12xx_probe_resp_template),
94 0, WL1271_RATE_AUTOMATIC);
89 if (ret < 0) 95 if (ret < 0)
90 return ret; 96 return ret;
91 97
92 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, 98 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
93 sizeof 99 sizeof
94 (struct wl12xx_beacon_template)); 100 (struct wl12xx_beacon_template),
101 0, WL1271_RATE_AUTOMATIC);
95 if (ret < 0) 102 if (ret < 0)
96 return ret; 103 return ret;
97 104
105 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
106 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
107 WL1271_CMD_TEMPL_MAX_SIZE, i,
108 WL1271_RATE_AUTOMATIC);
109 if (ret < 0)
110 return ret;
111 }
112
98 return 0; 113 return 0;
99} 114}
100 115
@@ -160,11 +175,11 @@ int wl1271_init_pta(struct wl1271 *wl)
160{ 175{
161 int ret; 176 int ret;
162 177
163 ret = wl1271_acx_sg_enable(wl); 178 ret = wl1271_acx_sg_cfg(wl);
164 if (ret < 0) 179 if (ret < 0)
165 return ret; 180 return ret;
166 181
167 ret = wl1271_acx_sg_cfg(wl); 182 ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
168 if (ret < 0) 183 if (ret < 0)
169 return ret; 184 return ret;
170 185
@@ -236,7 +251,7 @@ int wl1271_hw_init(struct wl1271 *wl)
236 goto out_free_memmap; 251 goto out_free_memmap;
237 252
238 /* Initialize connection monitoring thresholds */ 253 /* Initialize connection monitoring thresholds */
239 ret = wl1271_acx_conn_monit_params(wl); 254 ret = wl1271_acx_conn_monit_params(wl, false);
240 if (ret < 0) 255 if (ret < 0)
241 goto out_free_memmap; 256 goto out_free_memmap;
242 257
@@ -324,6 +339,19 @@ int wl1271_hw_init(struct wl1271 *wl)
324 if (ret < 0) 339 if (ret < 0)
325 goto out_free_memmap; 340 goto out_free_memmap;
326 341
342 /* disable all keep-alive templates */
343 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
344 ret = wl1271_acx_keep_alive_config(wl, i,
345 ACX_KEEP_ALIVE_TPL_INVALID);
346 if (ret < 0)
347 goto out_free_memmap;
348 }
349
350 /* disable the keep-alive feature */
351 ret = wl1271_acx_keep_alive_mode(wl, false);
352 if (ret < 0)
353 goto out_free_memmap;
354
327 return 0; 355 return 0;
328 356
329 out_free_memmap: 357 out_free_memmap:
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.c b/drivers/net/wireless/wl12xx/wl1271_io.c
index 5cd94d5666c2..c8759acef131 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.c
+++ b/drivers/net/wireless/wl12xx/wl1271_io.c
@@ -28,30 +28,29 @@
28 28
29#include "wl1271.h" 29#include "wl1271.h"
30#include "wl12xx_80211.h" 30#include "wl12xx_80211.h"
31#include "wl1271_spi.h"
32#include "wl1271_io.h" 31#include "wl1271_io.h"
33 32
34static int wl1271_translate_addr(struct wl1271 *wl, int addr) 33#define OCP_CMD_LOOP 32
34
35#define OCP_CMD_WRITE 0x1
36#define OCP_CMD_READ 0x2
37
38#define OCP_READY_MASK BIT(18)
39#define OCP_STATUS_MASK (BIT(16) | BIT(17))
40
41#define OCP_STATUS_NO_RESP 0x00000
42#define OCP_STATUS_OK 0x10000
43#define OCP_STATUS_REQ_FAILED 0x20000
44#define OCP_STATUS_RESP_ERROR 0x30000
45
46void wl1271_disable_interrupts(struct wl1271 *wl)
35{ 47{
36 /* 48 wl->if_ops->disable_irq(wl);
37 * To translate, first check to which window of addresses the 49}
38 * particular address belongs. Then subtract the starting address 50
39 * of that window from the address. Then, add offset of the 51void wl1271_enable_interrupts(struct wl1271 *wl)
40 * translated region. 52{
41 * 53 wl->if_ops->enable_irq(wl);
42 * The translated regions occur next to each other in physical device
43 * memory, so just add the sizes of the preceeding address regions to
44 * get the offset to the new region.
45 *
46 * Currently, only the two first regions are addressed, and the
47 * assumption is that all addresses will fall into either of those
48 * two.
49 */
50 if ((addr >= wl->part.reg.start) &&
51 (addr < wl->part.reg.start + wl->part.reg.size))
52 return addr - wl->part.reg.start + wl->part.mem.size;
53 else
54 return addr - wl->part.mem.start;
55} 54}
56 55
57/* Set the SPI partitions to access the chip addresses 56/* Set the SPI partitions to access the chip addresses
@@ -117,54 +116,12 @@ int wl1271_set_partition(struct wl1271 *wl,
117 116
118void wl1271_io_reset(struct wl1271 *wl) 117void wl1271_io_reset(struct wl1271 *wl)
119{ 118{
120 wl1271_spi_reset(wl); 119 wl->if_ops->reset(wl);
121} 120}
122 121
123void wl1271_io_init(struct wl1271 *wl) 122void wl1271_io_init(struct wl1271 *wl)
124{ 123{
125 wl1271_spi_init(wl); 124 wl->if_ops->init(wl);
126}
127
128void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
129 size_t len, bool fixed)
130{
131 wl1271_spi_raw_write(wl, addr, buf, len, fixed);
132}
133
134void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
135 size_t len, bool fixed)
136{
137 wl1271_spi_raw_read(wl, addr, buf, len, fixed);
138}
139
140void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,
141 bool fixed)
142{
143 int physical;
144
145 physical = wl1271_translate_addr(wl, addr);
146
147 wl1271_spi_raw_read(wl, physical, buf, len, fixed);
148}
149
150void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,
151 bool fixed)
152{
153 int physical;
154
155 physical = wl1271_translate_addr(wl, addr);
156
157 wl1271_spi_raw_write(wl, physical, buf, len, fixed);
158}
159
160u32 wl1271_read32(struct wl1271 *wl, int addr)
161{
162 return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
163}
164
165void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
166{
167 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
168} 125}
169 126
170void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) 127void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h
index fa9a0b35788f..d8837ef0bb40 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/wl1271_io.h
@@ -25,31 +25,49 @@
25#ifndef __WL1271_IO_H__ 25#ifndef __WL1271_IO_H__
26#define __WL1271_IO_H__ 26#define __WL1271_IO_H__
27 27
28#include "wl1271_reg.h"
29
30#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
31
32#define HW_PARTITION_REGISTERS_ADDR 0x1FFC0
33#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR)
34#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4)
35#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8)
36#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12)
37#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16)
38#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20)
39#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24)
40
41#define HW_ACCESS_REGISTER_SIZE 4
42
43#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
44
28struct wl1271; 45struct wl1271;
29 46
47void wl1271_disable_interrupts(struct wl1271 *wl);
48void wl1271_enable_interrupts(struct wl1271 *wl);
49
30void wl1271_io_reset(struct wl1271 *wl); 50void wl1271_io_reset(struct wl1271 *wl);
31void wl1271_io_init(struct wl1271 *wl); 51void wl1271_io_init(struct wl1271 *wl);
32 52
33/* Raw target IO, address is not translated */ 53static inline struct device *wl1271_wl_to_dev(struct wl1271 *wl)
34void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, 54{
35 size_t len, bool fixed); 55 return wl->if_ops->dev(wl);
36void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, 56}
37 size_t len, bool fixed);
38 57
39/* Translated target IO */
40void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,
41 bool fixed);
42void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,
43 bool fixed);
44u32 wl1271_read32(struct wl1271 *wl, int addr);
45void wl1271_write32(struct wl1271 *wl, int addr, u32 val);
46 58
47/* Top Register IO */ 59/* Raw target IO, address is not translated */
48void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); 60static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
49u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); 61 size_t len, bool fixed)
62{
63 wl->if_ops->write(wl, addr, buf, len, fixed);
64}
50 65
51int wl1271_set_partition(struct wl1271 *wl, 66static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
52 struct wl1271_partition_set *p); 67 size_t len, bool fixed)
68{
69 wl->if_ops->read(wl, addr, buf, len, fixed);
70}
53 71
54static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) 72static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
55{ 73{
@@ -65,4 +83,87 @@ static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
65 wl1271_raw_write(wl, addr, &wl->buffer_32, 83 wl1271_raw_write(wl, addr, &wl->buffer_32,
66 sizeof(wl->buffer_32), false); 84 sizeof(wl->buffer_32), false);
67} 85}
86
87/* Translated target IO */
88static inline int wl1271_translate_addr(struct wl1271 *wl, int addr)
89{
90 /*
91 * To translate, first check to which window of addresses the
92 * particular address belongs. Then subtract the starting address
93 * of that window from the address. Then, add offset of the
94 * translated region.
95 *
96 * The translated regions occur next to each other in physical device
97 * memory, so just add the sizes of the preceeding address regions to
98 * get the offset to the new region.
99 *
100 * Currently, only the two first regions are addressed, and the
101 * assumption is that all addresses will fall into either of those
102 * two.
103 */
104 if ((addr >= wl->part.reg.start) &&
105 (addr < wl->part.reg.start + wl->part.reg.size))
106 return addr - wl->part.reg.start + wl->part.mem.size;
107 else
108 return addr - wl->part.mem.start;
109}
110
111static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf,
112 size_t len, bool fixed)
113{
114 int physical;
115
116 physical = wl1271_translate_addr(wl, addr);
117
118 wl1271_raw_read(wl, physical, buf, len, fixed);
119}
120
121static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf,
122 size_t len, bool fixed)
123{
124 int physical;
125
126 physical = wl1271_translate_addr(wl, addr);
127
128 wl1271_raw_write(wl, physical, buf, len, fixed);
129}
130
131static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
132{
133 return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
134}
135
136static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
137{
138 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
139}
140
141static inline void wl1271_power_off(struct wl1271 *wl)
142{
143 wl->if_ops->power(wl, false);
144 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
145}
146
147static inline void wl1271_power_on(struct wl1271 *wl)
148{
149 wl->if_ops->power(wl, true);
150 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
151}
152
153
154/* Top Register IO */
155void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
156u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
157
158int wl1271_set_partition(struct wl1271 *wl,
159 struct wl1271_partition_set *p);
160
161/* Functions from wl1271_main.c */
162
163int wl1271_register_hw(struct wl1271 *wl);
164void wl1271_unregister_hw(struct wl1271 *wl);
165int wl1271_init_ieee80211(struct wl1271 *wl);
166struct ieee80211_hw *wl1271_alloc_hw(void);
167int wl1271_free_hw(struct wl1271 *wl);
168
68#endif 169#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 2a864b24291d..5c32d8d72361 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -22,22 +22,18 @@
22 */ 22 */
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/interrupt.h>
27#include <linux/firmware.h> 25#include <linux/firmware.h>
28#include <linux/delay.h> 26#include <linux/delay.h>
29#include <linux/irq.h>
30#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
31#include <linux/crc32.h> 28#include <linux/crc32.h>
32#include <linux/etherdevice.h> 29#include <linux/etherdevice.h>
33#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
34#include <linux/spi/wl12xx.h>
35#include <linux/inetdevice.h> 31#include <linux/inetdevice.h>
32#include <linux/platform_device.h>
36 33
37#include "wl1271.h" 34#include "wl1271.h"
38#include "wl12xx_80211.h" 35#include "wl12xx_80211.h"
39#include "wl1271_reg.h" 36#include "wl1271_reg.h"
40#include "wl1271_spi.h"
41#include "wl1271_io.h" 37#include "wl1271_io.h"
42#include "wl1271_event.h" 38#include "wl1271_event.h"
43#include "wl1271_tx.h" 39#include "wl1271_tx.h"
@@ -53,17 +49,57 @@
53 49
54static struct conf_drv_settings default_conf = { 50static struct conf_drv_settings default_conf = {
55 .sg = { 51 .sg = {
56 .per_threshold = 7500, 52 .params = {
57 .max_scan_compensation_time = 120000, 53 [CONF_SG_BT_PER_THRESHOLD] = 7500,
58 .nfs_sample_interval = 400, 54 [CONF_SG_HV3_MAX_OVERRIDE] = 0,
59 .load_ratio = 50, 55 [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400,
60 .auto_ps_mode = 0, 56 [CONF_SG_BT_LOAD_RATIO] = 50,
61 .probe_req_compensation = 170, 57 [CONF_SG_AUTO_PS_MODE] = 0,
62 .scan_window_compensation = 50, 58 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
63 .antenna_config = 0, 59 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
64 .beacon_miss_threshold = 60, 60 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
65 .rate_adaptation_threshold = CONF_HW_BIT_RATE_12MBPS, 61 [CONF_SG_BEACON_MISS_PERCENT] = 60,
66 .rate_adaptation_snr = 0 62 [CONF_SG_RATE_ADAPT_THRESH] = 12,
63 [CONF_SG_RATE_ADAPT_SNR] = 0,
64 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10,
65 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 30,
66 [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 8,
67 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20,
68 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 50,
69 /* Note: with UPSD, this should be 4 */
70 [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 8,
71 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7,
72 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25,
73 [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 20,
74 /* Note: with UPDS, this should be 15 */
75 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8,
76 /* Note: with UPDS, this should be 50 */
77 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 40,
78 /* Note: with UPDS, this should be 10 */
79 [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 20,
80 [CONF_SG_RXT] = 1200,
81 [CONF_SG_TXT] = 1000,
82 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
83 [CONF_SG_PS_POLL_TIMEOUT] = 10,
84 [CONF_SG_UPSD_TIMEOUT] = 10,
85 [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7,
86 [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15,
87 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15,
88 [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8,
89 [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20,
90 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15,
91 [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20,
92 [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50,
93 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10,
94 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
95 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800,
96 [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75,
97 [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15,
98 [CONF_SG_HV3_MAX_SERVED] = 6,
99 [CONF_SG_DHCP_TIME] = 5000,
100 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
101 },
102 .state = CONF_SG_PROTECTIVE,
67 }, 103 },
68 .rx = { 104 .rx = {
69 .rx_msdu_life_time = 512000, 105 .rx_msdu_life_time = 512000,
@@ -80,8 +116,7 @@ static struct conf_drv_settings default_conf = {
80 .tx = { 116 .tx = {
81 .tx_energy_detection = 0, 117 .tx_energy_detection = 0,
82 .rc_conf = { 118 .rc_conf = {
83 .enabled_rates = CONF_HW_BIT_RATE_1MBPS | 119 .enabled_rates = 0,
84 CONF_HW_BIT_RATE_2MBPS,
85 .short_retry_limit = 10, 120 .short_retry_limit = 10,
86 .long_retry_limit = 10, 121 .long_retry_limit = 10,
87 .aflags = 0 122 .aflags = 0
@@ -178,11 +213,13 @@ static struct conf_drv_settings default_conf = {
178 }, 213 },
179 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, 214 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
180 .tx_compl_timeout = 700, 215 .tx_compl_timeout = 700,
181 .tx_compl_threshold = 4 216 .tx_compl_threshold = 4,
217 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
218 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
182 }, 219 },
183 .conn = { 220 .conn = {
184 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 221 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
185 .listen_interval = 0, 222 .listen_interval = 1,
186 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, 223 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
187 .bcn_filt_ie_count = 1, 224 .bcn_filt_ie_count = 1,
188 .bcn_filt_ie = { 225 .bcn_filt_ie = {
@@ -228,7 +265,9 @@ static struct conf_drv_settings default_conf = {
228 }, 265 },
229 .bet_enable = CONF_BET_MODE_ENABLE, 266 .bet_enable = CONF_BET_MODE_ENABLE,
230 .bet_max_consecutive = 10, 267 .bet_max_consecutive = 10,
231 .psm_entry_retries = 3 268 .psm_entry_retries = 3,
269 .keep_alive_interval = 55000,
270 .max_listen_interval = 20,
232 }, 271 },
233 .init = { 272 .init = {
234 .radioparam = { 273 .radioparam = {
@@ -245,6 +284,21 @@ static struct conf_drv_settings default_conf = {
245 } 284 }
246}; 285};
247 286
287static void wl1271_device_release(struct device *dev)
288{
289
290}
291
292static struct platform_device wl1271_device = {
293 .name = "wl1271",
294 .id = -1,
295
296 /* device model insists to have a release function */
297 .dev = {
298 .release = wl1271_device_release,
299 },
300};
301
248static LIST_HEAD(wl_list); 302static LIST_HEAD(wl_list);
249 303
250static void wl1271_conf_init(struct wl1271 *wl) 304static void wl1271_conf_init(struct wl1271 *wl)
@@ -297,7 +351,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
297 goto out_free_memmap; 351 goto out_free_memmap;
298 352
299 /* Initialize connection monitoring thresholds */ 353 /* Initialize connection monitoring thresholds */
300 ret = wl1271_acx_conn_monit_params(wl); 354 ret = wl1271_acx_conn_monit_params(wl, false);
301 if (ret < 0) 355 if (ret < 0)
302 goto out_free_memmap; 356 goto out_free_memmap;
303 357
@@ -364,30 +418,14 @@ static int wl1271_plt_init(struct wl1271 *wl)
364 return ret; 418 return ret;
365} 419}
366 420
367static void wl1271_disable_interrupts(struct wl1271 *wl)
368{
369 disable_irq(wl->irq);
370}
371
372static void wl1271_power_off(struct wl1271 *wl)
373{
374 wl->set_power(false);
375 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
376}
377
378static void wl1271_power_on(struct wl1271 *wl)
379{
380 wl->set_power(true);
381 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
382}
383
384static void wl1271_fw_status(struct wl1271 *wl, 421static void wl1271_fw_status(struct wl1271 *wl,
385 struct wl1271_fw_status *status) 422 struct wl1271_fw_status *status)
386{ 423{
424 struct timespec ts;
387 u32 total = 0; 425 u32 total = 0;
388 int i; 426 int i;
389 427
390 wl1271_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); 428 wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
391 429
392 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " 430 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
393 "drv_rx_counter = %d, tx_results_counter = %d)", 431 "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -412,14 +450,19 @@ static void wl1271_fw_status(struct wl1271 *wl,
412 ieee80211_queue_work(wl->hw, &wl->tx_work); 450 ieee80211_queue_work(wl->hw, &wl->tx_work);
413 451
414 /* update the host-chipset time offset */ 452 /* update the host-chipset time offset */
415 wl->time_offset = jiffies_to_usecs(jiffies) - 453 getnstimeofday(&ts);
416 le32_to_cpu(status->fw_localtime); 454 wl->time_offset = (timespec_to_ns(&ts) >> 10) -
455 (s64)le32_to_cpu(status->fw_localtime);
417} 456}
418 457
458#define WL1271_IRQ_MAX_LOOPS 10
459
419static void wl1271_irq_work(struct work_struct *work) 460static void wl1271_irq_work(struct work_struct *work)
420{ 461{
421 int ret; 462 int ret;
422 u32 intr; 463 u32 intr;
464 int loopcount = WL1271_IRQ_MAX_LOOPS;
465 unsigned long flags;
423 struct wl1271 *wl = 466 struct wl1271 *wl =
424 container_of(work, struct wl1271, irq_work); 467 container_of(work, struct wl1271, irq_work);
425 468
@@ -427,91 +470,77 @@ static void wl1271_irq_work(struct work_struct *work)
427 470
428 wl1271_debug(DEBUG_IRQ, "IRQ work"); 471 wl1271_debug(DEBUG_IRQ, "IRQ work");
429 472
430 if (wl->state == WL1271_STATE_OFF) 473 if (unlikely(wl->state == WL1271_STATE_OFF))
431 goto out; 474 goto out;
432 475
433 ret = wl1271_ps_elp_wakeup(wl, true); 476 ret = wl1271_ps_elp_wakeup(wl, true);
434 if (ret < 0) 477 if (ret < 0)
435 goto out; 478 goto out;
436 479
437 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); 480 spin_lock_irqsave(&wl->wl_lock, flags);
438 481 while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) {
439 wl1271_fw_status(wl, wl->fw_status); 482 clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
440 intr = le32_to_cpu(wl->fw_status->intr); 483 spin_unlock_irqrestore(&wl->wl_lock, flags);
441 if (!intr) { 484 loopcount--;
442 wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); 485
443 goto out_sleep; 486 wl1271_fw_status(wl, wl->fw_status);
444 } 487 intr = le32_to_cpu(wl->fw_status->intr);
488 if (!intr) {
489 wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
490 continue;
491 }
445 492
446 intr &= WL1271_INTR_MASK; 493 intr &= WL1271_INTR_MASK;
447 494
448 if (intr & WL1271_ACX_INTR_EVENT_A) { 495 if (intr & WL1271_ACX_INTR_DATA) {
449 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); 496 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
450 wl1271_event_handle(wl, 0);
451 }
452 497
453 if (intr & WL1271_ACX_INTR_EVENT_B) { 498 /* check for tx results */
454 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); 499 if (wl->fw_status->tx_results_counter !=
455 wl1271_event_handle(wl, 1); 500 (wl->tx_results_count & 0xff))
456 } 501 wl1271_tx_complete(wl);
457 502
458 if (intr & WL1271_ACX_INTR_INIT_COMPLETE) 503 wl1271_rx(wl, wl->fw_status);
459 wl1271_debug(DEBUG_IRQ, 504 }
460 "WL1271_ACX_INTR_INIT_COMPLETE");
461 505
462 if (intr & WL1271_ACX_INTR_HW_AVAILABLE) 506 if (intr & WL1271_ACX_INTR_EVENT_A) {
463 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); 507 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
508 wl1271_event_handle(wl, 0);
509 }
464 510
465 if (intr & WL1271_ACX_INTR_DATA) { 511 if (intr & WL1271_ACX_INTR_EVENT_B) {
466 u8 tx_res_cnt = wl->fw_status->tx_results_counter - 512 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
467 wl->tx_results_count; 513 wl1271_event_handle(wl, 1);
514 }
468 515
469 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); 516 if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
517 wl1271_debug(DEBUG_IRQ,
518 "WL1271_ACX_INTR_INIT_COMPLETE");
470 519
471 /* check for tx results */ 520 if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
472 if (tx_res_cnt) 521 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
473 wl1271_tx_complete(wl, tx_res_cnt);
474 522
475 wl1271_rx(wl, wl->fw_status); 523 spin_lock_irqsave(&wl->wl_lock, flags);
476 } 524 }
477 525
478out_sleep: 526 if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags))
479 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, 527 ieee80211_queue_work(wl->hw, &wl->irq_work);
480 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); 528 else
529 clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
530 spin_unlock_irqrestore(&wl->wl_lock, flags);
531
481 wl1271_ps_elp_sleep(wl); 532 wl1271_ps_elp_sleep(wl);
482 533
483out: 534out:
484 mutex_unlock(&wl->mutex); 535 mutex_unlock(&wl->mutex);
485} 536}
486 537
487static irqreturn_t wl1271_irq(int irq, void *cookie)
488{
489 struct wl1271 *wl;
490 unsigned long flags;
491
492 wl1271_debug(DEBUG_IRQ, "IRQ");
493
494 wl = cookie;
495
496 /* complete the ELP completion */
497 spin_lock_irqsave(&wl->wl_lock, flags);
498 if (wl->elp_compl) {
499 complete(wl->elp_compl);
500 wl->elp_compl = NULL;
501 }
502
503 ieee80211_queue_work(wl->hw, &wl->irq_work);
504 spin_unlock_irqrestore(&wl->wl_lock, flags);
505
506 return IRQ_HANDLED;
507}
508
509static int wl1271_fetch_firmware(struct wl1271 *wl) 538static int wl1271_fetch_firmware(struct wl1271 *wl)
510{ 539{
511 const struct firmware *fw; 540 const struct firmware *fw;
512 int ret; 541 int ret;
513 542
514 ret = request_firmware(&fw, WL1271_FW_NAME, &wl->spi->dev); 543 ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl));
515 544
516 if (ret < 0) { 545 if (ret < 0) {
517 wl1271_error("could not get firmware: %d", ret); 546 wl1271_error("could not get firmware: %d", ret);
@@ -544,46 +573,12 @@ out:
544 return ret; 573 return ret;
545} 574}
546 575
547static int wl1271_update_mac_addr(struct wl1271 *wl)
548{
549 int ret = 0;
550 u8 *nvs_ptr = (u8 *)wl->nvs->nvs;
551
552 /* get mac address from the NVS */
553 wl->mac_addr[0] = nvs_ptr[11];
554 wl->mac_addr[1] = nvs_ptr[10];
555 wl->mac_addr[2] = nvs_ptr[6];
556 wl->mac_addr[3] = nvs_ptr[5];
557 wl->mac_addr[4] = nvs_ptr[4];
558 wl->mac_addr[5] = nvs_ptr[3];
559
560 /* FIXME: if it is a zero-address, we should bail out. Now, instead,
561 we randomize an address */
562 if (is_zero_ether_addr(wl->mac_addr)) {
563 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
564 memcpy(wl->mac_addr, nokia_oui, 3);
565 get_random_bytes(wl->mac_addr + 3, 3);
566
567 /* update this address to the NVS */
568 nvs_ptr[11] = wl->mac_addr[0];
569 nvs_ptr[10] = wl->mac_addr[1];
570 nvs_ptr[6] = wl->mac_addr[2];
571 nvs_ptr[5] = wl->mac_addr[3];
572 nvs_ptr[4] = wl->mac_addr[4];
573 nvs_ptr[3] = wl->mac_addr[5];
574 }
575
576 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
577
578 return ret;
579}
580
581static int wl1271_fetch_nvs(struct wl1271 *wl) 576static int wl1271_fetch_nvs(struct wl1271 *wl)
582{ 577{
583 const struct firmware *fw; 578 const struct firmware *fw;
584 int ret; 579 int ret;
585 580
586 ret = request_firmware(&fw, WL1271_NVS_NAME, &wl->spi->dev); 581 ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));
587 582
588 if (ret < 0) { 583 if (ret < 0) {
589 wl1271_error("could not get nvs file: %d", ret); 584 wl1271_error("could not get nvs file: %d", ret);
@@ -607,8 +602,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
607 602
608 memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file)); 603 memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file));
609 604
610 ret = wl1271_update_mac_addr(wl);
611
612out: 605out:
613 release_firmware(fw); 606 release_firmware(fw);
614 607
@@ -825,15 +818,13 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
825 * The workqueue is slow to process the tx_queue and we need stop 818 * The workqueue is slow to process the tx_queue and we need stop
826 * the queue here, otherwise the queue will get too long. 819 * the queue here, otherwise the queue will get too long.
827 */ 820 */
828 if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_MAX_LENGTH) { 821 if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
829 ieee80211_stop_queues(wl->hw); 822 wl1271_debug(DEBUG_TX, "op_tx: stopping queues");
830 823
831 /* 824 spin_lock_irqsave(&wl->wl_lock, flags);
832 * FIXME: this is racy, the variable is not properly 825 ieee80211_stop_queues(wl->hw);
833 * protected. Maybe fix this by removing the stupid
834 * variable altogether and checking the real queue state?
835 */
836 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); 826 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
827 spin_unlock_irqrestore(&wl->wl_lock, flags);
837 } 828 }
838 829
839 return NETDEV_TX_OK; 830 return NETDEV_TX_OK;
@@ -928,13 +919,60 @@ static struct notifier_block wl1271_dev_notifier = {
928 919
929static int wl1271_op_start(struct ieee80211_hw *hw) 920static int wl1271_op_start(struct ieee80211_hw *hw)
930{ 921{
922 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
923
924 /*
925 * We have to delay the booting of the hardware because
926 * we need to know the local MAC address before downloading and
927 * initializing the firmware. The MAC address cannot be changed
928 * after boot, and without the proper MAC address, the firmware
929 * will not function properly.
930 *
931 * The MAC address is first known when the corresponding interface
932 * is added. That is where we will initialize the hardware.
933 */
934
935 return 0;
936}
937
938static void wl1271_op_stop(struct ieee80211_hw *hw)
939{
940 wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
941}
942
943static int wl1271_op_add_interface(struct ieee80211_hw *hw,
944 struct ieee80211_vif *vif)
945{
931 struct wl1271 *wl = hw->priv; 946 struct wl1271 *wl = hw->priv;
932 int retries = WL1271_BOOT_RETRIES; 947 int retries = WL1271_BOOT_RETRIES;
933 int ret = 0; 948 int ret = 0;
934 949
935 wl1271_debug(DEBUG_MAC80211, "mac80211 start"); 950 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
951 vif->type, vif->addr);
936 952
937 mutex_lock(&wl->mutex); 953 mutex_lock(&wl->mutex);
954 if (wl->vif) {
955 ret = -EBUSY;
956 goto out;
957 }
958
959 wl->vif = vif;
960
961 switch (vif->type) {
962 case NL80211_IFTYPE_STATION:
963 wl->bss_type = BSS_TYPE_STA_BSS;
964 wl->set_bss_type = BSS_TYPE_STA_BSS;
965 break;
966 case NL80211_IFTYPE_ADHOC:
967 wl->bss_type = BSS_TYPE_IBSS;
968 wl->set_bss_type = BSS_TYPE_STA_BSS;
969 break;
970 default:
971 ret = -EOPNOTSUPP;
972 goto out;
973 }
974
975 memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
938 976
939 if (wl->state != WL1271_STATE_OFF) { 977 if (wl->state != WL1271_STATE_OFF) {
940 wl1271_error("cannot start because not in off state: %d", 978 wl1271_error("cannot start because not in off state: %d",
@@ -990,19 +1028,20 @@ out:
990 return ret; 1028 return ret;
991} 1029}
992 1030
993static void wl1271_op_stop(struct ieee80211_hw *hw) 1031static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1032 struct ieee80211_vif *vif)
994{ 1033{
995 struct wl1271 *wl = hw->priv; 1034 struct wl1271 *wl = hw->priv;
996 int i; 1035 int i;
997 1036
998 wl1271_info("down");
999
1000 wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
1001
1002 unregister_inetaddr_notifier(&wl1271_dev_notifier); 1037 unregister_inetaddr_notifier(&wl1271_dev_notifier);
1003 list_del(&wl->list);
1004 1038
1005 mutex_lock(&wl->mutex); 1039 mutex_lock(&wl->mutex);
1040 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
1041
1042 wl1271_info("down");
1043
1044 list_del(&wl->list);
1006 1045
1007 WARN_ON(wl->state != WL1271_STATE_ON); 1046 WARN_ON(wl->state != WL1271_STATE_ON);
1008 1047
@@ -1031,6 +1070,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1031 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1); 1070 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1);
1032 wl->ssid_len = 0; 1071 wl->ssid_len = 0;
1033 wl->bss_type = MAX_BSS_TYPE; 1072 wl->bss_type = MAX_BSS_TYPE;
1073 wl->set_bss_type = MAX_BSS_TYPE;
1034 wl->band = IEEE80211_BAND_2GHZ; 1074 wl->band = IEEE80211_BAND_2GHZ;
1035 1075
1036 wl->rx_counter = 0; 1076 wl->rx_counter = 0;
@@ -1040,13 +1080,14 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1040 wl->tx_results_count = 0; 1080 wl->tx_results_count = 0;
1041 wl->tx_packets_count = 0; 1081 wl->tx_packets_count = 0;
1042 wl->tx_security_last_seq = 0; 1082 wl->tx_security_last_seq = 0;
1043 wl->tx_security_seq_16 = 0; 1083 wl->tx_security_seq = 0;
1044 wl->tx_security_seq_32 = 0;
1045 wl->time_offset = 0; 1084 wl->time_offset = 0;
1046 wl->session_counter = 0; 1085 wl->session_counter = 0;
1047 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1086 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1048 wl->sta_rate_set = 0; 1087 wl->sta_rate_set = 0;
1049 wl->flags = 0; 1088 wl->flags = 0;
1089 wl->vif = NULL;
1090 wl->filters = 0;
1050 1091
1051 for (i = 0; i < NUM_TX_QUEUES; i++) 1092 for (i = 0; i < NUM_TX_QUEUES; i++)
1052 wl->tx_blocks_freed[i] = 0; 1093 wl->tx_blocks_freed[i] = 0;
@@ -1055,119 +1096,39 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1055 mutex_unlock(&wl->mutex); 1096 mutex_unlock(&wl->mutex);
1056} 1097}
1057 1098
1058static int wl1271_op_add_interface(struct ieee80211_hw *hw, 1099static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
1059 struct ieee80211_vif *vif)
1060{ 1100{
1061 struct wl1271 *wl = hw->priv; 1101 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1062 int ret = 0; 1102 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
1063
1064 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
1065 vif->type, vif->addr);
1066 1103
1067 mutex_lock(&wl->mutex); 1104 /* combine requested filters with current filter config */
1068 if (wl->vif) { 1105 filters = wl->filters | filters;
1069 ret = -EBUSY;
1070 goto out;
1071 }
1072 1106
1073 wl->vif = vif; 1107 wl1271_debug(DEBUG_FILTERS, "RX filters set: ");
1074 1108
1075 switch (vif->type) { 1109 if (filters & FIF_PROMISC_IN_BSS) {
1076 case NL80211_IFTYPE_STATION: 1110 wl1271_debug(DEBUG_FILTERS, " - FIF_PROMISC_IN_BSS");
1077 wl->bss_type = BSS_TYPE_STA_BSS; 1111 wl->rx_config &= ~CFG_UNI_FILTER_EN;
1078 break; 1112 wl->rx_config |= CFG_BSSID_FILTER_EN;
1079 case NL80211_IFTYPE_ADHOC:
1080 wl->bss_type = BSS_TYPE_IBSS;
1081 break;
1082 default:
1083 ret = -EOPNOTSUPP;
1084 goto out;
1085 } 1113 }
1086 1114 if (filters & FIF_BCN_PRBRESP_PROMISC) {
1087 /* FIXME: what if conf->mac_addr changes? */ 1115 wl1271_debug(DEBUG_FILTERS, " - FIF_BCN_PRBRESP_PROMISC");
1088 1116 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1089out: 1117 wl->rx_config &= ~CFG_SSID_FILTER_EN;
1090 mutex_unlock(&wl->mutex);
1091 return ret;
1092}
1093
1094static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1095 struct ieee80211_vif *vif)
1096{
1097 struct wl1271 *wl = hw->priv;
1098
1099 mutex_lock(&wl->mutex);
1100 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
1101 wl->vif = NULL;
1102 mutex_unlock(&wl->mutex);
1103}
1104
1105#if 0
1106static int wl1271_op_config_interface(struct ieee80211_hw *hw,
1107 struct ieee80211_vif *vif,
1108 struct ieee80211_if_conf *conf)
1109{
1110 struct wl1271 *wl = hw->priv;
1111 struct sk_buff *beacon;
1112 int ret;
1113
1114 wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM",
1115 conf->bssid);
1116 wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid,
1117 conf->ssid_len);
1118
1119 mutex_lock(&wl->mutex);
1120
1121 ret = wl1271_ps_elp_wakeup(wl, false);
1122 if (ret < 0)
1123 goto out;
1124
1125 if (memcmp(wl->bssid, conf->bssid, ETH_ALEN)) {
1126 wl1271_debug(DEBUG_MAC80211, "bssid changed");
1127
1128 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
1129
1130 ret = wl1271_cmd_join(wl);
1131 if (ret < 0)
1132 goto out_sleep;
1133
1134 ret = wl1271_cmd_build_null_data(wl);
1135 if (ret < 0)
1136 goto out_sleep;
1137 } 1118 }
1138 1119 if (filters & FIF_OTHER_BSS) {
1139 wl->ssid_len = conf->ssid_len; 1120 wl1271_debug(DEBUG_FILTERS, " - FIF_OTHER_BSS");
1140 if (wl->ssid_len) 1121 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1141 memcpy(wl->ssid, conf->ssid, wl->ssid_len); 1122 }
1142 1123 if (filters & FIF_CONTROL) {
1143 if (conf->changed & IEEE80211_IFCC_BEACON) { 1124 wl1271_debug(DEBUG_FILTERS, " - FIF_CONTROL");
1144 beacon = ieee80211_beacon_get(hw, vif); 1125 wl->rx_filter |= CFG_RX_CTL_EN;
1145 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, 1126 }
1146 beacon->data, beacon->len); 1127 if (filters & FIF_FCSFAIL) {
1147 1128 wl1271_debug(DEBUG_FILTERS, " - FIF_FCSFAIL");
1148 if (ret < 0) { 1129 wl->rx_filter |= CFG_RX_FCS_ERROR;
1149 dev_kfree_skb(beacon);
1150 goto out_sleep;
1151 }
1152
1153 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE,
1154 beacon->data, beacon->len);
1155
1156 dev_kfree_skb(beacon);
1157
1158 if (ret < 0)
1159 goto out_sleep;
1160 } 1130 }
1161
1162out_sleep:
1163 wl1271_ps_elp_sleep(wl);
1164
1165out:
1166 mutex_unlock(&wl->mutex);
1167
1168 return ret;
1169} 1131}
1170#endif
1171 1132
1172static int wl1271_join_channel(struct wl1271 *wl, int channel) 1133static int wl1271_join_channel(struct wl1271 *wl, int channel)
1173{ 1134{
@@ -1176,17 +1137,13 @@ static int wl1271_join_channel(struct wl1271 *wl, int channel)
1176 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, 1137 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde,
1177 0xad, 0xbe, 0xef }; 1138 0xad, 0xbe, 0xef };
1178 1139
1179 /* the dummy join is not required for ad-hoc */
1180 if (wl->bss_type == BSS_TYPE_IBSS)
1181 goto out;
1182
1183 /* disable mac filter, so we hear everything */
1184 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1185
1186 wl->channel = channel; 1140 wl->channel = channel;
1187 memcpy(wl->bssid, dummy_bssid, ETH_ALEN); 1141 memcpy(wl->bssid, dummy_bssid, ETH_ALEN);
1188 1142
1189 ret = wl1271_cmd_join(wl); 1143 /* pass through frames from all BSS */
1144 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1145
1146 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1190 if (ret < 0) 1147 if (ret < 0)
1191 goto out; 1148 goto out;
1192 1149
@@ -1208,12 +1165,40 @@ static int wl1271_unjoin_channel(struct wl1271 *wl)
1208 clear_bit(WL1271_FLAG_JOINED, &wl->flags); 1165 clear_bit(WL1271_FLAG_JOINED, &wl->flags);
1209 wl->channel = 0; 1166 wl->channel = 0;
1210 memset(wl->bssid, 0, ETH_ALEN); 1167 memset(wl->bssid, 0, ETH_ALEN);
1211 wl->rx_config = WL1271_DEFAULT_RX_CONFIG; 1168
1169 /* stop filterting packets based on bssid */
1170 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1212 1171
1213out: 1172out:
1214 return ret; 1173 return ret;
1215} 1174}
1216 1175
1176static void wl1271_set_band_rate(struct wl1271 *wl)
1177{
1178 if (wl->band == IEEE80211_BAND_2GHZ)
1179 wl->basic_rate_set = wl->conf.tx.basic_rate;
1180 else
1181 wl->basic_rate_set = wl->conf.tx.basic_rate_5;
1182}
1183
1184static u32 wl1271_min_rate_get(struct wl1271 *wl)
1185{
1186 int i;
1187 u32 rate = 0;
1188
1189 if (!wl->basic_rate_set) {
1190 WARN_ON(1);
1191 wl->basic_rate_set = wl->conf.tx.basic_rate;
1192 }
1193
1194 for (i = 0; !rate; i++) {
1195 if ((wl->basic_rate_set >> i) & 0x1)
1196 rate = 1 << i;
1197 }
1198
1199 return rate;
1200}
1201
1217static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) 1202static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1218{ 1203{
1219 struct wl1271 *wl = hw->priv; 1204 struct wl1271 *wl = hw->priv;
@@ -1230,12 +1215,38 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1230 1215
1231 mutex_lock(&wl->mutex); 1216 mutex_lock(&wl->mutex);
1232 1217
1233 wl->band = conf->channel->band;
1234
1235 ret = wl1271_ps_elp_wakeup(wl, false); 1218 ret = wl1271_ps_elp_wakeup(wl, false);
1236 if (ret < 0) 1219 if (ret < 0)
1237 goto out; 1220 goto out;
1238 1221
1222 /* if the channel changes while joined, join again */
1223 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1224 wl->band = conf->channel->band;
1225 wl->channel = channel;
1226
1227 /*
1228 * FIXME: the mac80211 should really provide a fixed rate
1229 * to use here. for now, just use the smallest possible rate
1230 * for the band as a fixed rate for association frames and
1231 * other control messages.
1232 */
1233 if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
1234 wl1271_set_band_rate(wl);
1235
1236 wl->basic_rate = wl1271_min_rate_get(wl);
1237 ret = wl1271_acx_rate_policies(wl);
1238 if (ret < 0)
1239 wl1271_warning("rate policy for update channel "
1240 "failed %d", ret);
1241
1242 if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1243 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1244 if (ret < 0)
1245 wl1271_warning("cmd join to update channel "
1246 "failed %d", ret);
1247 }
1248 }
1249
1239 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 1250 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1240 if (conf->flags & IEEE80211_CONF_IDLE && 1251 if (conf->flags & IEEE80211_CONF_IDLE &&
1241 test_bit(WL1271_FLAG_JOINED, &wl->flags)) 1252 test_bit(WL1271_FLAG_JOINED, &wl->flags))
@@ -1244,24 +1255,15 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1244 wl1271_join_channel(wl, channel); 1255 wl1271_join_channel(wl, channel);
1245 1256
1246 if (conf->flags & IEEE80211_CONF_IDLE) { 1257 if (conf->flags & IEEE80211_CONF_IDLE) {
1247 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1258 wl->rate_set = wl1271_min_rate_get(wl);
1248 wl->sta_rate_set = 0; 1259 wl->sta_rate_set = 0;
1249 wl1271_acx_rate_policies(wl); 1260 wl1271_acx_rate_policies(wl);
1261 wl1271_acx_keep_alive_config(
1262 wl, CMD_TEMPL_KLV_IDX_NULL_DATA,
1263 ACX_KEEP_ALIVE_TPL_INVALID);
1250 } 1264 }
1251 } 1265 }
1252 1266
1253 /* if the channel changes while joined, join again */
1254 if (channel != wl->channel &&
1255 test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1256 wl->channel = channel;
1257 /* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */
1258 ret = wl1271_cmd_join(wl);
1259 if (ret < 0)
1260 wl1271_warning("cmd join to update channel failed %d",
1261 ret);
1262 } else
1263 wl->channel = channel;
1264
1265 if (conf->flags & IEEE80211_CONF_PS && 1267 if (conf->flags & IEEE80211_CONF_PS &&
1266 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { 1268 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
1267 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); 1269 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
@@ -1272,13 +1274,13 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1272 * through the bss_info_changed() hook. 1274 * through the bss_info_changed() hook.
1273 */ 1275 */
1274 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { 1276 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
1275 wl1271_info("psm enabled"); 1277 wl1271_debug(DEBUG_PSM, "psm enabled");
1276 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, 1278 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
1277 true); 1279 true);
1278 } 1280 }
1279 } else if (!(conf->flags & IEEE80211_CONF_PS) && 1281 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
1280 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { 1282 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
1281 wl1271_info("psm disabled"); 1283 wl1271_debug(DEBUG_PSM, "psm disabled");
1282 1284
1283 clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); 1285 clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
1284 1286
@@ -1381,14 +1383,14 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
1381 if (ret < 0) 1383 if (ret < 0)
1382 goto out_sleep; 1384 goto out_sleep;
1383 1385
1384 kfree(fp);
1385
1386 /* FIXME: We still need to set our filters properly */
1387
1388 /* determine, whether supported filter values have changed */ 1386 /* determine, whether supported filter values have changed */
1389 if (changed == 0) 1387 if (changed == 0)
1390 goto out_sleep; 1388 goto out_sleep;
1391 1389
1390 /* configure filters */
1391 wl->filters = *total;
1392 wl1271_configure_filters(wl, 0);
1393
1392 /* apply configured filters */ 1394 /* apply configured filters */
1393 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); 1395 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
1394 if (ret < 0) 1396 if (ret < 0)
@@ -1399,6 +1401,7 @@ out_sleep:
1399 1401
1400out: 1402out:
1401 mutex_unlock(&wl->mutex); 1403 mutex_unlock(&wl->mutex);
1404 kfree(fp);
1402} 1405}
1403 1406
1404static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 1407static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -1449,15 +1452,15 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1449 key_type = KEY_TKIP; 1452 key_type = KEY_TKIP;
1450 1453
1451 key_conf->hw_key_idx = key_conf->keyidx; 1454 key_conf->hw_key_idx = key_conf->keyidx;
1452 tx_seq_32 = wl->tx_security_seq_32; 1455 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
1453 tx_seq_16 = wl->tx_security_seq_16; 1456 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
1454 break; 1457 break;
1455 case ALG_CCMP: 1458 case ALG_CCMP:
1456 key_type = KEY_AES; 1459 key_type = KEY_AES;
1457 1460
1458 key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 1461 key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1459 tx_seq_32 = wl->tx_security_seq_32; 1462 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
1460 tx_seq_16 = wl->tx_security_seq_16; 1463 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
1461 break; 1464 break;
1462 default: 1465 default:
1463 wl1271_error("Unknown key algo 0x%x", key_conf->alg); 1466 wl1271_error("Unknown key algo 0x%x", key_conf->alg);
@@ -1544,10 +1547,12 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1544 goto out; 1547 goto out;
1545 1548
1546 if (wl1271_11a_enabled()) 1549 if (wl1271_11a_enabled())
1547 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0, 1550 ret = wl1271_cmd_scan(hw->priv, ssid, len,
1551 req->ie, req->ie_len, 1, 0,
1548 WL1271_SCAN_BAND_DUAL, 3); 1552 WL1271_SCAN_BAND_DUAL, 3);
1549 else 1553 else
1550 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0, 1554 ret = wl1271_cmd_scan(hw->priv, ssid, len,
1555 req->ie, req->ie_len, 1, 0,
1551 WL1271_SCAN_BAND_2_4_GHZ, 3); 1556 WL1271_SCAN_BAND_2_4_GHZ, 3);
1552 1557
1553 wl1271_ps_elp_sleep(wl); 1558 wl1271_ps_elp_sleep(wl);
@@ -1606,6 +1611,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1606 enum wl1271_cmd_ps_mode mode; 1611 enum wl1271_cmd_ps_mode mode;
1607 struct wl1271 *wl = hw->priv; 1612 struct wl1271 *wl = hw->priv;
1608 bool do_join = false; 1613 bool do_join = false;
1614 bool do_keepalive = false;
1609 int ret; 1615 int ret;
1610 1616
1611 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 1617 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1616,20 +1622,29 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1616 if (ret < 0) 1622 if (ret < 0)
1617 goto out; 1623 goto out;
1618 1624
1619 if (wl->bss_type == BSS_TYPE_IBSS) { 1625 if ((changed && BSS_CHANGED_BEACON_INT) &&
1620 /* FIXME: This implements rudimentary ad-hoc support - 1626 (wl->bss_type == BSS_TYPE_IBSS)) {
1621 proper templates are on the wish list and notification 1627 wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d",
1622 on when they change. This patch will update the templates 1628 bss_conf->beacon_int);
1623 on every call to this function. */ 1629
1630 wl->beacon_int = bss_conf->beacon_int;
1631 do_join = true;
1632 }
1633
1634 if ((changed && BSS_CHANGED_BEACON) &&
1635 (wl->bss_type == BSS_TYPE_IBSS)) {
1624 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 1636 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
1625 1637
1638 wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon updated");
1639
1626 if (beacon) { 1640 if (beacon) {
1627 struct ieee80211_hdr *hdr; 1641 struct ieee80211_hdr *hdr;
1628 1642
1629 wl1271_ssid_set(wl, beacon); 1643 wl1271_ssid_set(wl, beacon);
1630 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, 1644 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
1631 beacon->data, 1645 beacon->data,
1632 beacon->len); 1646 beacon->len, 0,
1647 wl1271_min_rate_get(wl));
1633 1648
1634 if (ret < 0) { 1649 if (ret < 0) {
1635 dev_kfree_skb(beacon); 1650 dev_kfree_skb(beacon);
@@ -1644,7 +1659,8 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1644 ret = wl1271_cmd_template_set(wl, 1659 ret = wl1271_cmd_template_set(wl,
1645 CMD_TEMPL_PROBE_RESPONSE, 1660 CMD_TEMPL_PROBE_RESPONSE,
1646 beacon->data, 1661 beacon->data,
1647 beacon->len); 1662 beacon->len, 0,
1663 wl1271_min_rate_get(wl));
1648 dev_kfree_skb(beacon); 1664 dev_kfree_skb(beacon);
1649 if (ret < 0) 1665 if (ret < 0)
1650 goto out_sleep; 1666 goto out_sleep;
@@ -1654,20 +1670,32 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1654 } 1670 }
1655 } 1671 }
1656 1672
1673 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1674 (wl->bss_type == BSS_TYPE_IBSS)) {
1675 wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s",
1676 bss_conf->enable_beacon ? "enabled" : "disabled");
1677
1678 if (bss_conf->enable_beacon)
1679 wl->set_bss_type = BSS_TYPE_IBSS;
1680 else
1681 wl->set_bss_type = BSS_TYPE_STA_BSS;
1682 do_join = true;
1683 }
1684
1657 if ((changed & BSS_CHANGED_BSSID) && 1685 if ((changed & BSS_CHANGED_BSSID) &&
1658 /* 1686 /*
1659 * Now we know the correct bssid, so we send a new join command 1687 * Now we know the correct bssid, so we send a new join command
1660 * and enable the BSSID filter 1688 * and enable the BSSID filter
1661 */ 1689 */
1662 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { 1690 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
1663 wl->rx_config |= CFG_BSSID_FILTER_EN;
1664 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); 1691 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1692
1665 ret = wl1271_cmd_build_null_data(wl); 1693 ret = wl1271_cmd_build_null_data(wl);
1666 if (ret < 0) { 1694 if (ret < 0)
1667 wl1271_warning("cmd buld null data failed %d",
1668 ret);
1669 goto out_sleep; 1695 goto out_sleep;
1670 } 1696
1697 /* filter out all packets not from this BSSID */
1698 wl1271_configure_filters(wl, 0);
1671 1699
1672 /* Need to update the BSSID (for filtering etc) */ 1700 /* Need to update the BSSID (for filtering etc) */
1673 do_join = true; 1701 do_join = true;
@@ -1675,10 +1703,23 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1675 1703
1676 if (changed & BSS_CHANGED_ASSOC) { 1704 if (changed & BSS_CHANGED_ASSOC) {
1677 if (bss_conf->assoc) { 1705 if (bss_conf->assoc) {
1706 u32 rates;
1678 wl->aid = bss_conf->aid; 1707 wl->aid = bss_conf->aid;
1679 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1708 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1680 1709
1681 /* 1710 /*
1711 * use basic rates from AP, and determine lowest rate
1712 * to use with control frames.
1713 */
1714 rates = bss_conf->basic_rates;
1715 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
1716 rates);
1717 wl->basic_rate = wl1271_min_rate_get(wl);
1718 ret = wl1271_acx_rate_policies(wl);
1719 if (ret < 0)
1720 goto out_sleep;
1721
1722 /*
1682 * with wl1271, we don't need to update the 1723 * with wl1271, we don't need to update the
1683 * beacon_int and dtim_period, because the firmware 1724 * beacon_int and dtim_period, because the firmware
1684 * updates it by itself when the first beacon is 1725 * updates it by itself when the first beacon is
@@ -1688,7 +1729,30 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1688 if (ret < 0) 1729 if (ret < 0)
1689 goto out_sleep; 1730 goto out_sleep;
1690 1731
1691 ret = wl1271_acx_aid(wl, wl->aid); 1732 /*
1733 * The SSID is intentionally set to NULL here - the
1734 * firmware will set the probe request with a
1735 * broadcast SSID regardless of what we set in the
1736 * template.
1737 */
1738 ret = wl1271_cmd_build_probe_req(wl, NULL, 0,
1739 NULL, 0, wl->band);
1740
1741 /* Enable the keep-alive feature */
1742 ret = wl1271_acx_keep_alive_mode(wl, true);
1743 if (ret < 0)
1744 goto out_sleep;
1745
1746 /*
1747 * This is awkward. The keep-alive configs must be done
1748 * *after* the join command, because otherwise it will
1749 * not work, but it must only be done *once* because
1750 * otherwise the firmware will start complaining.
1751 */
1752 do_keepalive = true;
1753
1754 /* enable the connection monitoring feature */
1755 ret = wl1271_acx_conn_monit_params(wl, true);
1692 if (ret < 0) 1756 if (ret < 0)
1693 goto out_sleep; 1757 goto out_sleep;
1694 1758
@@ -1704,6 +1768,22 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1704 /* use defaults when not associated */ 1768 /* use defaults when not associated */
1705 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1769 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1706 wl->aid = 0; 1770 wl->aid = 0;
1771
1772 /* revert back to minimum rates for the current band */
1773 wl1271_set_band_rate(wl);
1774 wl->basic_rate = wl1271_min_rate_get(wl);
1775 ret = wl1271_acx_rate_policies(wl);
1776 if (ret < 0)
1777 goto out_sleep;
1778
1779 /* disable connection monitor features */
1780 ret = wl1271_acx_conn_monit_params(wl, false);
1781
1782 /* Disable the keep-alive feature */
1783 ret = wl1271_acx_keep_alive_mode(wl, false);
1784
1785 if (ret < 0)
1786 goto out_sleep;
1707 } 1787 }
1708 1788
1709 } 1789 }
@@ -1738,7 +1818,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1738 } 1818 }
1739 1819
1740 if (do_join) { 1820 if (do_join) {
1741 ret = wl1271_cmd_join(wl); 1821 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1742 if (ret < 0) { 1822 if (ret < 0) {
1743 wl1271_warning("cmd join failed %d", ret); 1823 wl1271_warning("cmd join failed %d", ret);
1744 goto out_sleep; 1824 goto out_sleep;
@@ -1746,6 +1826,29 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1746 set_bit(WL1271_FLAG_JOINED, &wl->flags); 1826 set_bit(WL1271_FLAG_JOINED, &wl->flags);
1747 } 1827 }
1748 1828
1829 /*
1830 * The JOIN operation shuts down the firmware keep-alive as a side
1831 * effect, and the ACX_AID will start the keep-alive as a side effect.
1832 * Hence, for non-IBSS, the ACX_AID must always happen *after* the
1833 * JOIN operation, and the template config after the ACX_AID.
1834 */
1835 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
1836 ret = wl1271_acx_aid(wl, wl->aid);
1837 if (ret < 0)
1838 goto out_sleep;
1839 }
1840
1841 if (do_keepalive) {
1842 ret = wl1271_cmd_build_klv_null_data(wl);
1843 if (ret < 0)
1844 goto out_sleep;
1845 ret = wl1271_acx_keep_alive_config(
1846 wl, CMD_TEMPL_KLV_IDX_NULL_DATA,
1847 ACX_KEEP_ALIVE_TPL_VALID);
1848 if (ret < 0)
1849 goto out_sleep;
1850 }
1851
1749out_sleep: 1852out_sleep:
1750 wl1271_ps_elp_sleep(wl); 1853 wl1271_ps_elp_sleep(wl);
1751 1854
@@ -1757,6 +1860,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1757 const struct ieee80211_tx_queue_params *params) 1860 const struct ieee80211_tx_queue_params *params)
1758{ 1861{
1759 struct wl1271 *wl = hw->priv; 1862 struct wl1271 *wl = hw->priv;
1863 u8 ps_scheme;
1760 int ret; 1864 int ret;
1761 1865
1762 mutex_lock(&wl->mutex); 1866 mutex_lock(&wl->mutex);
@@ -1767,17 +1871,22 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1767 if (ret < 0) 1871 if (ret < 0)
1768 goto out; 1872 goto out;
1769 1873
1874 /* the txop is confed in units of 32us by the mac80211, we need us */
1770 ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), 1875 ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
1771 params->cw_min, params->cw_max, 1876 params->cw_min, params->cw_max,
1772 params->aifs, params->txop); 1877 params->aifs, params->txop << 5);
1773 if (ret < 0) 1878 if (ret < 0)
1774 goto out_sleep; 1879 goto out_sleep;
1775 1880
1881 if (params->uapsd)
1882 ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER;
1883 else
1884 ps_scheme = CONF_PS_SCHEME_LEGACY;
1885
1776 ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), 1886 ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),
1777 CONF_CHANNEL_TYPE_EDCF, 1887 CONF_CHANNEL_TYPE_EDCF,
1778 wl1271_tx_get_queue(queue), 1888 wl1271_tx_get_queue(queue),
1779 CONF_PS_SCHEME_LEGACY_PSPOLL, 1889 ps_scheme, CONF_ACK_POLICY_LEGACY, 0, 0);
1780 CONF_ACK_POLICY_LEGACY, 0, 0);
1781 if (ret < 0) 1890 if (ret < 0)
1782 goto out_sleep; 1891 goto out_sleep;
1783 1892
@@ -1851,6 +1960,36 @@ static struct ieee80211_channel wl1271_channels[] = {
1851 { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, 1960 { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
1852}; 1961};
1853 1962
1963/* mapping to indexes for wl1271_rates */
1964const static u8 wl1271_rate_to_idx_2ghz[] = {
1965 /* MCS rates are used only with 11n */
1966 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
1967 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
1968 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
1969 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
1970 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
1971 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
1972 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
1973 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
1974
1975 11, /* CONF_HW_RXTX_RATE_54 */
1976 10, /* CONF_HW_RXTX_RATE_48 */
1977 9, /* CONF_HW_RXTX_RATE_36 */
1978 8, /* CONF_HW_RXTX_RATE_24 */
1979
1980 /* TI-specific rate */
1981 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
1982
1983 7, /* CONF_HW_RXTX_RATE_18 */
1984 6, /* CONF_HW_RXTX_RATE_12 */
1985 3, /* CONF_HW_RXTX_RATE_11 */
1986 5, /* CONF_HW_RXTX_RATE_9 */
1987 4, /* CONF_HW_RXTX_RATE_6 */
1988 2, /* CONF_HW_RXTX_RATE_5_5 */
1989 1, /* CONF_HW_RXTX_RATE_2 */
1990 0 /* CONF_HW_RXTX_RATE_1 */
1991};
1992
1854/* can't be const, mac80211 writes to this */ 1993/* can't be const, mac80211 writes to this */
1855static struct ieee80211_supported_band wl1271_band_2ghz = { 1994static struct ieee80211_supported_band wl1271_band_2ghz = {
1856 .channels = wl1271_channels, 1995 .channels = wl1271_channels,
@@ -1933,6 +2072,35 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
1933 { .hw_value = 165, .center_freq = 5825}, 2072 { .hw_value = 165, .center_freq = 5825},
1934}; 2073};
1935 2074
2075/* mapping to indexes for wl1271_rates_5ghz */
2076const static u8 wl1271_rate_to_idx_5ghz[] = {
2077 /* MCS rates are used only with 11n */
2078 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
2079 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
2080 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
2081 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
2082 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
2083 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
2084 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
2085 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
2086
2087 7, /* CONF_HW_RXTX_RATE_54 */
2088 6, /* CONF_HW_RXTX_RATE_48 */
2089 5, /* CONF_HW_RXTX_RATE_36 */
2090 4, /* CONF_HW_RXTX_RATE_24 */
2091
2092 /* TI-specific rate */
2093 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
2094
2095 3, /* CONF_HW_RXTX_RATE_18 */
2096 2, /* CONF_HW_RXTX_RATE_12 */
2097 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */
2098 1, /* CONF_HW_RXTX_RATE_9 */
2099 0, /* CONF_HW_RXTX_RATE_6 */
2100 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */
2101 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */
2102 CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */
2103};
1936 2104
1937static struct ieee80211_supported_band wl1271_band_5ghz = { 2105static struct ieee80211_supported_band wl1271_band_5ghz = {
1938 .channels = wl1271_channels_5ghz, 2106 .channels = wl1271_channels_5ghz,
@@ -1941,13 +2109,17 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
1941 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), 2109 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
1942}; 2110};
1943 2111
2112const static u8 *wl1271_band_rate_to_idx[] = {
2113 [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz,
2114 [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz
2115};
2116
1944static const struct ieee80211_ops wl1271_ops = { 2117static const struct ieee80211_ops wl1271_ops = {
1945 .start = wl1271_op_start, 2118 .start = wl1271_op_start,
1946 .stop = wl1271_op_stop, 2119 .stop = wl1271_op_stop,
1947 .add_interface = wl1271_op_add_interface, 2120 .add_interface = wl1271_op_add_interface,
1948 .remove_interface = wl1271_op_remove_interface, 2121 .remove_interface = wl1271_op_remove_interface,
1949 .config = wl1271_op_config, 2122 .config = wl1271_op_config,
1950/* .config_interface = wl1271_op_config_interface, */
1951 .prepare_multicast = wl1271_op_prepare_multicast, 2123 .prepare_multicast = wl1271_op_prepare_multicast,
1952 .configure_filter = wl1271_op_configure_filter, 2124 .configure_filter = wl1271_op_configure_filter,
1953 .tx = wl1271_op_tx, 2125 .tx = wl1271_op_tx,
@@ -1959,7 +2131,90 @@ static const struct ieee80211_ops wl1271_ops = {
1959 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 2131 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
1960}; 2132};
1961 2133
1962static int wl1271_register_hw(struct wl1271 *wl) 2134
2135u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate)
2136{
2137 u8 idx;
2138
2139 BUG_ON(wl->band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
2140
2141 if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) {
2142 wl1271_error("Illegal RX rate from HW: %d", rate);
2143 return 0;
2144 }
2145
2146 idx = wl1271_band_rate_to_idx[wl->band][rate];
2147 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
2148 wl1271_error("Unsupported RX rate from HW: %d", rate);
2149 return 0;
2150 }
2151
2152 return idx;
2153}
2154
2155static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
2156 struct device_attribute *attr,
2157 char *buf)
2158{
2159 struct wl1271 *wl = dev_get_drvdata(dev);
2160 ssize_t len;
2161
2162 /* FIXME: what's the maximum length of buf? page size?*/
2163 len = 500;
2164
2165 mutex_lock(&wl->mutex);
2166 len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
2167 wl->sg_enabled);
2168 mutex_unlock(&wl->mutex);
2169
2170 return len;
2171
2172}
2173
2174static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
2175 struct device_attribute *attr,
2176 const char *buf, size_t count)
2177{
2178 struct wl1271 *wl = dev_get_drvdata(dev);
2179 unsigned long res;
2180 int ret;
2181
2182 ret = strict_strtoul(buf, 10, &res);
2183
2184 if (ret < 0) {
2185 wl1271_warning("incorrect value written to bt_coex_mode");
2186 return count;
2187 }
2188
2189 mutex_lock(&wl->mutex);
2190
2191 res = !!res;
2192
2193 if (res == wl->sg_enabled)
2194 goto out;
2195
2196 wl->sg_enabled = res;
2197
2198 if (wl->state == WL1271_STATE_OFF)
2199 goto out;
2200
2201 ret = wl1271_ps_elp_wakeup(wl, false);
2202 if (ret < 0)
2203 goto out;
2204
2205 wl1271_acx_sg_enable(wl, wl->sg_enabled);
2206 wl1271_ps_elp_sleep(wl);
2207
2208 out:
2209 mutex_unlock(&wl->mutex);
2210 return count;
2211}
2212
2213static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR,
2214 wl1271_sysfs_show_bt_coex_state,
2215 wl1271_sysfs_store_bt_coex_state);
2216
2217int wl1271_register_hw(struct wl1271 *wl)
1963{ 2218{
1964 int ret; 2219 int ret;
1965 2220
@@ -1980,8 +2235,17 @@ static int wl1271_register_hw(struct wl1271 *wl)
1980 2235
1981 return 0; 2236 return 0;
1982} 2237}
2238EXPORT_SYMBOL_GPL(wl1271_register_hw);
1983 2239
1984static int wl1271_init_ieee80211(struct wl1271 *wl) 2240void wl1271_unregister_hw(struct wl1271 *wl)
2241{
2242 ieee80211_unregister_hw(wl->hw);
2243 wl->mac80211_registered = false;
2244
2245}
2246EXPORT_SYMBOL_GPL(wl1271_unregister_hw);
2247
2248int wl1271_init_ieee80211(struct wl1271 *wl)
1985{ 2249{
1986 /* The tx descriptor buffer and the TKIP space. */ 2250 /* The tx descriptor buffer and the TKIP space. */
1987 wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + 2251 wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
@@ -1990,11 +2254,15 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
1990 /* unit us */ 2254 /* unit us */
1991 /* FIXME: find a proper value */ 2255 /* FIXME: find a proper value */
1992 wl->hw->channel_change_time = 10000; 2256 wl->hw->channel_change_time = 10000;
2257 wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
1993 2258
1994 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 2259 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1995 IEEE80211_HW_NOISE_DBM | 2260 IEEE80211_HW_NOISE_DBM |
1996 IEEE80211_HW_BEACON_FILTER | 2261 IEEE80211_HW_BEACON_FILTER |
1997 IEEE80211_HW_SUPPORTS_PS; 2262 IEEE80211_HW_SUPPORTS_PS |
2263 IEEE80211_HW_SUPPORTS_UAPSD |
2264 IEEE80211_HW_HAS_RATE_CONTROL |
2265 IEEE80211_HW_CONNECTION_MONITOR;
1998 2266
1999 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2267 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2000 BIT(NL80211_IFTYPE_ADHOC); 2268 BIT(NL80211_IFTYPE_ADHOC);
@@ -2004,51 +2272,53 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
2004 if (wl1271_11a_enabled()) 2272 if (wl1271_11a_enabled())
2005 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; 2273 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
2006 2274
2007 SET_IEEE80211_DEV(wl->hw, &wl->spi->dev); 2275 wl->hw->queues = 4;
2276 wl->hw->max_rates = 1;
2008 2277
2009 return 0; 2278 SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl));
2010}
2011
2012static void wl1271_device_release(struct device *dev)
2013{
2014 2279
2280 return 0;
2015} 2281}
2016 2282EXPORT_SYMBOL_GPL(wl1271_init_ieee80211);
2017static struct platform_device wl1271_device = {
2018 .name = "wl1271",
2019 .id = -1,
2020
2021 /* device model insists to have a release function */
2022 .dev = {
2023 .release = wl1271_device_release,
2024 },
2025};
2026 2283
2027#define WL1271_DEFAULT_CHANNEL 0 2284#define WL1271_DEFAULT_CHANNEL 0
2028 2285
2029static struct ieee80211_hw *wl1271_alloc_hw(void) 2286struct ieee80211_hw *wl1271_alloc_hw(void)
2030{ 2287{
2031 struct ieee80211_hw *hw; 2288 struct ieee80211_hw *hw;
2289 struct platform_device *plat_dev = NULL;
2032 struct wl1271 *wl; 2290 struct wl1271 *wl;
2033 int i; 2291 int i, ret;
2034 2292
2035 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); 2293 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
2036 if (!hw) { 2294 if (!hw) {
2037 wl1271_error("could not alloc ieee80211_hw"); 2295 wl1271_error("could not alloc ieee80211_hw");
2038 return ERR_PTR(-ENOMEM); 2296 ret = -ENOMEM;
2297 goto err_hw_alloc;
2298 }
2299
2300 plat_dev = kmalloc(sizeof(wl1271_device), GFP_KERNEL);
2301 if (!plat_dev) {
2302 wl1271_error("could not allocate platform_device");
2303 ret = -ENOMEM;
2304 goto err_plat_alloc;
2039 } 2305 }
2040 2306
2307 memcpy(plat_dev, &wl1271_device, sizeof(wl1271_device));
2308
2041 wl = hw->priv; 2309 wl = hw->priv;
2042 memset(wl, 0, sizeof(*wl)); 2310 memset(wl, 0, sizeof(*wl));
2043 2311
2044 INIT_LIST_HEAD(&wl->list); 2312 INIT_LIST_HEAD(&wl->list);
2045 2313
2046 wl->hw = hw; 2314 wl->hw = hw;
2315 wl->plat_dev = plat_dev;
2047 2316
2048 skb_queue_head_init(&wl->tx_queue); 2317 skb_queue_head_init(&wl->tx_queue);
2049 2318
2050 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); 2319 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
2051 wl->channel = WL1271_DEFAULT_CHANNEL; 2320 wl->channel = WL1271_DEFAULT_CHANNEL;
2321 wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
2052 wl->default_key = 0; 2322 wl->default_key = 0;
2053 wl->rx_counter = 0; 2323 wl->rx_counter = 0;
2054 wl->rx_config = WL1271_DEFAULT_RX_CONFIG; 2324 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
@@ -2056,11 +2326,13 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
2056 wl->psm_entry_retry = 0; 2326 wl->psm_entry_retry = 0;
2057 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 2327 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
2058 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; 2328 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
2329 wl->basic_rate = CONF_TX_RATE_MASK_BASIC;
2059 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 2330 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
2060 wl->sta_rate_set = 0; 2331 wl->sta_rate_set = 0;
2061 wl->band = IEEE80211_BAND_2GHZ; 2332 wl->band = IEEE80211_BAND_2GHZ;
2062 wl->vif = NULL; 2333 wl->vif = NULL;
2063 wl->flags = 0; 2334 wl->flags = 0;
2335 wl->sg_enabled = true;
2064 2336
2065 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 2337 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
2066 wl->tx_frames[i] = NULL; 2338 wl->tx_frames[i] = NULL;
@@ -2073,12 +2345,45 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
2073 /* Apply default driver configuration. */ 2345 /* Apply default driver configuration. */
2074 wl1271_conf_init(wl); 2346 wl1271_conf_init(wl);
2075 2347
2348 wl1271_debugfs_init(wl);
2349
2350 /* Register platform device */
2351 ret = platform_device_register(wl->plat_dev);
2352 if (ret) {
2353 wl1271_error("couldn't register platform device");
2354 goto err_hw;
2355 }
2356 dev_set_drvdata(&wl->plat_dev->dev, wl);
2357
2358 /* Create sysfs file to control bt coex state */
2359 ret = device_create_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state);
2360 if (ret < 0) {
2361 wl1271_error("failed to create sysfs file bt_coex_state");
2362 goto err_platform;
2363 }
2364
2076 return hw; 2365 return hw;
2366
2367err_platform:
2368 platform_device_unregister(wl->plat_dev);
2369
2370err_hw:
2371 wl1271_debugfs_exit(wl);
2372 kfree(plat_dev);
2373
2374err_plat_alloc:
2375 ieee80211_free_hw(hw);
2376
2377err_hw_alloc:
2378
2379 return ERR_PTR(ret);
2077} 2380}
2381EXPORT_SYMBOL_GPL(wl1271_alloc_hw);
2078 2382
2079int wl1271_free_hw(struct wl1271 *wl) 2383int wl1271_free_hw(struct wl1271 *wl)
2080{ 2384{
2081 ieee80211_unregister_hw(wl->hw); 2385 platform_device_unregister(wl->plat_dev);
2386 kfree(wl->plat_dev);
2082 2387
2083 wl1271_debugfs_exit(wl); 2388 wl1271_debugfs_exit(wl);
2084 2389
@@ -2095,145 +2400,8 @@ int wl1271_free_hw(struct wl1271 *wl)
2095 2400
2096 return 0; 2401 return 0;
2097} 2402}
2098 2403EXPORT_SYMBOL_GPL(wl1271_free_hw);
2099static int __devinit wl1271_probe(struct spi_device *spi)
2100{
2101 struct wl12xx_platform_data *pdata;
2102 struct ieee80211_hw *hw;
2103 struct wl1271 *wl;
2104 int ret;
2105
2106 pdata = spi->dev.platform_data;
2107 if (!pdata) {
2108 wl1271_error("no platform data");
2109 return -ENODEV;
2110 }
2111
2112 hw = wl1271_alloc_hw();
2113 if (IS_ERR(hw))
2114 return PTR_ERR(hw);
2115
2116 wl = hw->priv;
2117
2118 dev_set_drvdata(&spi->dev, wl);
2119 wl->spi = spi;
2120
2121 /* This is the only SPI value that we need to set here, the rest
2122 * comes from the board-peripherals file */
2123 spi->bits_per_word = 32;
2124
2125 ret = spi_setup(spi);
2126 if (ret < 0) {
2127 wl1271_error("spi_setup failed");
2128 goto out_free;
2129 }
2130
2131 wl->set_power = pdata->set_power;
2132 if (!wl->set_power) {
2133 wl1271_error("set power function missing in platform data");
2134 ret = -ENODEV;
2135 goto out_free;
2136 }
2137
2138 wl->irq = spi->irq;
2139 if (wl->irq < 0) {
2140 wl1271_error("irq missing in platform data");
2141 ret = -ENODEV;
2142 goto out_free;
2143 }
2144
2145 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
2146 if (ret < 0) {
2147 wl1271_error("request_irq() failed: %d", ret);
2148 goto out_free;
2149 }
2150
2151 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
2152
2153 disable_irq(wl->irq);
2154
2155 ret = platform_device_register(&wl1271_device);
2156 if (ret) {
2157 wl1271_error("couldn't register platform device");
2158 goto out_irq;
2159 }
2160 dev_set_drvdata(&wl1271_device.dev, wl);
2161
2162 ret = wl1271_init_ieee80211(wl);
2163 if (ret)
2164 goto out_platform;
2165
2166 ret = wl1271_register_hw(wl);
2167 if (ret)
2168 goto out_platform;
2169
2170 wl1271_debugfs_init(wl);
2171
2172 wl1271_notice("initialized");
2173
2174 return 0;
2175
2176 out_platform:
2177 platform_device_unregister(&wl1271_device);
2178
2179 out_irq:
2180 free_irq(wl->irq, wl);
2181
2182 out_free:
2183 ieee80211_free_hw(hw);
2184
2185 return ret;
2186}
2187
2188static int __devexit wl1271_remove(struct spi_device *spi)
2189{
2190 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
2191
2192 platform_device_unregister(&wl1271_device);
2193 free_irq(wl->irq, wl);
2194
2195 wl1271_free_hw(wl);
2196
2197 return 0;
2198}
2199
2200
2201static struct spi_driver wl1271_spi_driver = {
2202 .driver = {
2203 .name = "wl1271",
2204 .bus = &spi_bus_type,
2205 .owner = THIS_MODULE,
2206 },
2207
2208 .probe = wl1271_probe,
2209 .remove = __devexit_p(wl1271_remove),
2210};
2211
2212static int __init wl1271_init(void)
2213{
2214 int ret;
2215
2216 ret = spi_register_driver(&wl1271_spi_driver);
2217 if (ret < 0) {
2218 wl1271_error("failed to register spi driver: %d", ret);
2219 goto out;
2220 }
2221
2222out:
2223 return ret;
2224}
2225
2226static void __exit wl1271_exit(void)
2227{
2228 spi_unregister_driver(&wl1271_spi_driver);
2229
2230 wl1271_notice("unloaded");
2231}
2232
2233module_init(wl1271_init);
2234module_exit(wl1271_exit);
2235 2404
2236MODULE_LICENSE("GPL"); 2405MODULE_LICENSE("GPL");
2237MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); 2406MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
2238MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 2407MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
2239MODULE_FIRMWARE(WL1271_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index e2b1ebf096e8..5a04482b9353 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -23,7 +23,6 @@
23 23
24#include "wl1271_reg.h" 24#include "wl1271_reg.h"
25#include "wl1271_ps.h" 25#include "wl1271_ps.h"
26#include "wl1271_spi.h"
27#include "wl1271_io.h" 26#include "wl1271_io.h"
28 27
29#define WL1271_WAKEUP_TIMEOUT 500 28#define WL1271_WAKEUP_TIMEOUT 500
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index 6730f5b96e76..ca442703d1ab 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -25,7 +25,6 @@
25#include "wl1271_acx.h" 25#include "wl1271_acx.h"
26#include "wl1271_reg.h" 26#include "wl1271_reg.h"
27#include "wl1271_rx.h" 27#include "wl1271_rx.h"
28#include "wl1271_spi.h"
29#include "wl1271_io.h" 28#include "wl1271_io.h"
30 29
31static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, 30static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
@@ -42,66 +41,6 @@ static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status,
42 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; 41 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
43} 42}
44 43
45/* The values of this table must match the wl1271_rates[] array */
46static u8 wl1271_rx_rate_to_idx[] = {
47 /* MCS rates are used only with 11n */
48 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
49 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
50 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
51 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
52 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
53 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
54 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
55 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
56
57 11, /* WL1271_RATE_54 */
58 10, /* WL1271_RATE_48 */
59 9, /* WL1271_RATE_36 */
60 8, /* WL1271_RATE_24 */
61
62 /* TI-specific rate */
63 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22 */
64
65 7, /* WL1271_RATE_18 */
66 6, /* WL1271_RATE_12 */
67 3, /* WL1271_RATE_11 */
68 5, /* WL1271_RATE_9 */
69 4, /* WL1271_RATE_6 */
70 2, /* WL1271_RATE_5_5 */
71 1, /* WL1271_RATE_2 */
72 0 /* WL1271_RATE_1 */
73};
74
75/* The values of this table must match the wl1271_rates[] array */
76static u8 wl1271_5_ghz_rx_rate_to_idx[] = {
77 /* MCS rates are used only with 11n */
78 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
79 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
80 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
81 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
82 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
83 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
84 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
85 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
86
87 7, /* WL1271_RATE_54 */
88 6, /* WL1271_RATE_48 */
89 5, /* WL1271_RATE_36 */
90 4, /* WL1271_RATE_24 */
91
92 /* TI-specific rate */
93 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22 */
94
95 3, /* WL1271_RATE_18 */
96 2, /* WL1271_RATE_12 */
97 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_11 */
98 1, /* WL1271_RATE_9 */
99 0, /* WL1271_RATE_6 */
100 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_5_5 */
101 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_2 */
102 WL1271_RX_RATE_UNSUPPORTED /* WL1271_RATE_1 */
103};
104
105static void wl1271_rx_status(struct wl1271 *wl, 44static void wl1271_rx_status(struct wl1271 *wl,
106 struct wl1271_rx_descriptor *desc, 45 struct wl1271_rx_descriptor *desc,
107 struct ieee80211_rx_status *status, 46 struct ieee80211_rx_status *status,
@@ -109,20 +48,8 @@ static void wl1271_rx_status(struct wl1271 *wl,
109{ 48{
110 memset(status, 0, sizeof(struct ieee80211_rx_status)); 49 memset(status, 0, sizeof(struct ieee80211_rx_status));
111 50
112 if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == 51 status->band = wl->band;
113 WL1271_RX_DESC_BAND_BG) { 52 status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
114 status->band = IEEE80211_BAND_2GHZ;
115 status->rate_idx = wl1271_rx_rate_to_idx[desc->rate];
116 } else if ((desc->flags & WL1271_RX_DESC_BAND_MASK) ==
117 WL1271_RX_DESC_BAND_A) {
118 status->band = IEEE80211_BAND_5GHZ;
119 status->rate_idx = wl1271_5_ghz_rx_rate_to_idx[desc->rate];
120 } else
121 wl1271_warning("unsupported band 0x%x",
122 desc->flags & WL1271_RX_DESC_BAND_MASK);
123
124 if (unlikely(status->rate_idx == WL1271_RX_RATE_UNSUPPORTED))
125 wl1271_warning("unsupported rate");
126 53
127 /* 54 /*
128 * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the 55 * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the
@@ -132,13 +59,6 @@ static void wl1271_rx_status(struct wl1271 *wl,
132 */ 59 */
133 status->signal = desc->rssi; 60 status->signal = desc->rssi;
134 61
135 /*
136 * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we
137 * need to divide by two for now, but TI has been discussing about
138 * changing it. This needs to be rechecked.
139 */
140 status->noise = desc->rssi - (desc->snr >> 1);
141
142 status->freq = ieee80211_channel_to_frequency(desc->channel); 62 status->freq = ieee80211_channel_to_frequency(desc->channel);
143 63
144 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { 64 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
@@ -160,6 +80,13 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
160 u8 *buf; 80 u8 *buf;
161 u8 beacon = 0; 81 u8 beacon = 0;
162 82
83 /*
84 * In PLT mode we seem to get frames and mac80211 warns about them,
85 * workaround this by not retrieving them at all.
86 */
87 if (unlikely(wl->state == WL1271_STATE_PLT))
88 return;
89
163 skb = __dev_alloc_skb(length, GFP_KERNEL); 90 skb = __dev_alloc_skb(length, GFP_KERNEL);
164 if (!skb) { 91 if (!skb) {
165 wl1271_error("Couldn't allocate RX frame"); 92 wl1271_error("Couldn't allocate RX frame");
@@ -218,6 +145,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
218 145
219 wl->rx_counter++; 146 wl->rx_counter++;
220 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 147 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
221 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
222 } 148 }
149
150 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
223} 151}
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h
index 1ae6d1783ed4..b89be4758e78 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.h
@@ -43,7 +43,6 @@
43#define RX_MAX_PACKET_ID 3 43#define RX_MAX_PACKET_ID 3
44 44
45#define NUM_RX_PKT_DESC_MOD_MASK 7 45#define NUM_RX_PKT_DESC_MOD_MASK 7
46#define WL1271_RX_RATE_UNSUPPORTED 0xFF
47 46
48#define RX_DESC_VALID_FCS 0x0001 47#define RX_DESC_VALID_FCS 0x0001
49#define RX_DESC_MATCH_RXADDR1 0x0002 48#define RX_DESC_MATCH_RXADDR1 0x0002
@@ -117,5 +116,6 @@ struct wl1271_rx_descriptor {
117} __attribute__ ((packed)); 116} __attribute__ ((packed));
118 117
119void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); 118void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
119u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
120 120
121#endif 121#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
new file mode 100644
index 000000000000..d3d6f302f705
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -0,0 +1,291 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009-2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/irq.h>
25#include <linux/module.h>
26#include <linux/crc7.h>
27#include <linux/vmalloc.h>
28#include <linux/mmc/sdio_func.h>
29#include <linux/mmc/sdio_ids.h>
30#include <linux/mmc/card.h>
31#include <plat/gpio.h>
32
33#include "wl1271.h"
34#include "wl12xx_80211.h"
35#include "wl1271_io.h"
36
37
38#define RX71_WL1271_IRQ_GPIO 42
39
40#ifndef SDIO_VENDOR_ID_TI
41#define SDIO_VENDOR_ID_TI 0x0097
42#endif
43
44#ifndef SDIO_DEVICE_ID_TI_WL1271
45#define SDIO_DEVICE_ID_TI_WL1271 0x4076
46#endif
47
48static const struct sdio_device_id wl1271_devices[] = {
49 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
50 {}
51};
52MODULE_DEVICE_TABLE(sdio, wl1271_devices);
53
54static inline struct sdio_func *wl_to_func(struct wl1271 *wl)
55{
56 return wl->if_priv;
57}
58
59static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl)
60{
61 return &(wl_to_func(wl)->dev);
62}
63
64static irqreturn_t wl1271_irq(int irq, void *cookie)
65{
66 struct wl1271 *wl = cookie;
67 unsigned long flags;
68
69 wl1271_debug(DEBUG_IRQ, "IRQ");
70
71 /* complete the ELP completion */
72 spin_lock_irqsave(&wl->wl_lock, flags);
73 if (wl->elp_compl) {
74 complete(wl->elp_compl);
75 wl->elp_compl = NULL;
76 }
77
78 if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
79 ieee80211_queue_work(wl->hw, &wl->irq_work);
80 set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
81 spin_unlock_irqrestore(&wl->wl_lock, flags);
82
83 return IRQ_HANDLED;
84}
85
86static void wl1271_sdio_disable_interrupts(struct wl1271 *wl)
87{
88 disable_irq(wl->irq);
89}
90
91static void wl1271_sdio_enable_interrupts(struct wl1271 *wl)
92{
93 enable_irq(wl->irq);
94}
95
96static void wl1271_sdio_reset(struct wl1271 *wl)
97{
98}
99
100static void wl1271_sdio_init(struct wl1271 *wl)
101{
102}
103
104static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
105 size_t len, bool fixed)
106{
107 int ret;
108 struct sdio_func *func = wl_to_func(wl);
109
110 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
111 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
112 wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
113 addr, ((u8 *)buf)[0]);
114 } else {
115 if (fixed)
116 ret = sdio_readsb(func, buf, addr, len);
117 else
118 ret = sdio_memcpy_fromio(func, buf, addr, len);
119
120 wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes",
121 addr, len);
122 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
123 }
124
125 if (ret)
126 wl1271_error("sdio read failed (%d)", ret);
127
128}
129
130static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
131 size_t len, bool fixed)
132{
133 int ret;
134 struct sdio_func *func = wl_to_func(wl);
135
136 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
137 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
138 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
139 addr, ((u8 *)buf)[0]);
140 } else {
141 wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes",
142 addr, len);
143 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
144
145 if (fixed)
146 ret = sdio_writesb(func, addr, buf, len);
147 else
148 ret = sdio_memcpy_toio(func, addr, buf, len);
149 }
150 if (ret)
151 wl1271_error("sdio write failed (%d)", ret);
152
153}
154
155static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
156{
157 struct sdio_func *func = wl_to_func(wl);
158
159 /* Let the SDIO stack handle wlan_enable control, so we
160 * keep host claimed while wlan is in use to keep wl1271
161 * alive.
162 */
163 if (enable) {
164 sdio_claim_host(func);
165 sdio_enable_func(func);
166 } else {
167 sdio_disable_func(func);
168 sdio_release_host(func);
169 }
170}
171
172static struct wl1271_if_operations sdio_ops = {
173 .read = wl1271_sdio_raw_read,
174 .write = wl1271_sdio_raw_write,
175 .reset = wl1271_sdio_reset,
176 .init = wl1271_sdio_init,
177 .power = wl1271_sdio_set_power,
178 .dev = wl1271_sdio_wl_to_dev,
179 .enable_irq = wl1271_sdio_enable_interrupts,
180 .disable_irq = wl1271_sdio_disable_interrupts
181};
182
183static int __devinit wl1271_probe(struct sdio_func *func,
184 const struct sdio_device_id *id)
185{
186 struct ieee80211_hw *hw;
187 struct wl1271 *wl;
188 int ret;
189
190 /* We are only able to handle the wlan function */
191 if (func->num != 0x02)
192 return -ENODEV;
193
194 hw = wl1271_alloc_hw();
195 if (IS_ERR(hw))
196 return PTR_ERR(hw);
197
198 wl = hw->priv;
199
200 wl->if_priv = func;
201 wl->if_ops = &sdio_ops;
202
203 /* Grab access to FN0 for ELP reg. */
204 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
205
206 wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO);
207 if (wl->irq < 0) {
208 ret = wl->irq;
209 wl1271_error("could not get irq!");
210 goto out_free;
211 }
212
213 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
214 if (ret < 0) {
215 wl1271_error("request_irq() failed: %d", ret);
216 goto out_free;
217 }
218
219 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
220
221 disable_irq(wl->irq);
222
223 ret = wl1271_init_ieee80211(wl);
224 if (ret)
225 goto out_irq;
226
227 ret = wl1271_register_hw(wl);
228 if (ret)
229 goto out_irq;
230
231 sdio_set_drvdata(func, wl);
232
233 wl1271_notice("initialized");
234
235 return 0;
236
237 out_irq:
238 free_irq(wl->irq, wl);
239
240
241 out_free:
242 wl1271_free_hw(wl);
243
244 return ret;
245}
246
247static void __devexit wl1271_remove(struct sdio_func *func)
248{
249 struct wl1271 *wl = sdio_get_drvdata(func);
250
251 free_irq(wl->irq, wl);
252
253 wl1271_unregister_hw(wl);
254 wl1271_free_hw(wl);
255}
256
257static struct sdio_driver wl1271_sdio_driver = {
258 .name = "wl1271_sdio",
259 .id_table = wl1271_devices,
260 .probe = wl1271_probe,
261 .remove = __devexit_p(wl1271_remove),
262};
263
264static int __init wl1271_init(void)
265{
266 int ret;
267
268 ret = sdio_register_driver(&wl1271_sdio_driver);
269 if (ret < 0) {
270 wl1271_error("failed to register sdio driver: %d", ret);
271 goto out;
272 }
273
274out:
275 return ret;
276}
277
278static void __exit wl1271_exit(void)
279{
280 sdio_unregister_driver(&wl1271_sdio_driver);
281
282 wl1271_notice("unloaded");
283}
284
285module_init(wl1271_init);
286module_exit(wl1271_exit);
287
288MODULE_LICENSE("GPL");
289MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
290MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
291MODULE_FIRMWARE(WL1271_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 67a82934f36e..7a7db011a797 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -21,17 +21,68 @@
21 * 21 *
22 */ 22 */
23 23
24#include <linux/irq.h>
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/spi/wl12xx.h>
28 29
29#include "wl1271.h" 30#include "wl1271.h"
30#include "wl12xx_80211.h" 31#include "wl12xx_80211.h"
31#include "wl1271_spi.h" 32#include "wl1271_io.h"
33
34#include "wl1271_reg.h"
35
36#define WSPI_CMD_READ 0x40000000
37#define WSPI_CMD_WRITE 0x00000000
38#define WSPI_CMD_FIXED 0x20000000
39#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
40#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
41#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
42
43#define WSPI_INIT_CMD_CRC_LEN 5
44
45#define WSPI_INIT_CMD_START 0x00
46#define WSPI_INIT_CMD_TX 0x40
47/* the extra bypass bit is sampled by the TNET as '1' */
48#define WSPI_INIT_CMD_BYPASS_BIT 0x80
49#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
50#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
51#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
52#define WSPI_INIT_CMD_IOD 0x40
53#define WSPI_INIT_CMD_IP 0x20
54#define WSPI_INIT_CMD_CS 0x10
55#define WSPI_INIT_CMD_WS 0x08
56#define WSPI_INIT_CMD_WSPI 0x01
57#define WSPI_INIT_CMD_END 0x01
58
59#define WSPI_INIT_CMD_LEN 8
60
61#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
62 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
63#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
64
65static inline struct spi_device *wl_to_spi(struct wl1271 *wl)
66{
67 return wl->if_priv;
68}
32 69
70static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl)
71{
72 return &(wl_to_spi(wl)->dev);
73}
33 74
34void wl1271_spi_reset(struct wl1271 *wl) 75static void wl1271_spi_disable_interrupts(struct wl1271 *wl)
76{
77 disable_irq(wl->irq);
78}
79
80static void wl1271_spi_enable_interrupts(struct wl1271 *wl)
81{
82 enable_irq(wl->irq);
83}
84
85static void wl1271_spi_reset(struct wl1271 *wl)
35{ 86{
36 u8 *cmd; 87 u8 *cmd;
37 struct spi_transfer t; 88 struct spi_transfer t;
@@ -52,12 +103,13 @@ void wl1271_spi_reset(struct wl1271 *wl)
52 t.len = WSPI_INIT_CMD_LEN; 103 t.len = WSPI_INIT_CMD_LEN;
53 spi_message_add_tail(&t, &m); 104 spi_message_add_tail(&t, &m);
54 105
55 spi_sync(wl->spi, &m); 106 spi_sync(wl_to_spi(wl), &m);
107 kfree(cmd);
56 108
57 wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); 109 wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
58} 110}
59 111
60void wl1271_spi_init(struct wl1271 *wl) 112static void wl1271_spi_init(struct wl1271 *wl)
61{ 113{
62 u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; 114 u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
63 struct spi_transfer t; 115 struct spi_transfer t;
@@ -106,48 +158,25 @@ void wl1271_spi_init(struct wl1271 *wl)
106 t.len = WSPI_INIT_CMD_LEN; 158 t.len = WSPI_INIT_CMD_LEN;
107 spi_message_add_tail(&t, &m); 159 spi_message_add_tail(&t, &m);
108 160
109 spi_sync(wl->spi, &m); 161 spi_sync(wl_to_spi(wl), &m);
162 kfree(cmd);
110 163
111 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); 164 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
112} 165}
113 166
114#define WL1271_BUSY_WORD_TIMEOUT 1000 167#define WL1271_BUSY_WORD_TIMEOUT 1000
115 168
116/* FIXME: Check busy words, removed due to SPI bug */ 169static int wl1271_spi_read_busy(struct wl1271 *wl)
117#if 0
118static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
119{ 170{
120 struct spi_transfer t[1]; 171 struct spi_transfer t[1];
121 struct spi_message m; 172 struct spi_message m;
122 u32 *busy_buf; 173 u32 *busy_buf;
123 int num_busy_bytes = 0; 174 int num_busy_bytes = 0;
124 175
125 wl1271_info("spi read BUSY!");
126
127 /*
128 * Look for the non-busy word in the read buffer, and if found,
129 * read in the remaining data into the buffer.
130 */
131 busy_buf = (u32 *)buf;
132 for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
133 num_busy_bytes += sizeof(u32);
134 if (*busy_buf & 0x1) {
135 spi_message_init(&m);
136 memset(t, 0, sizeof(t));
137 memmove(buf, busy_buf, len - num_busy_bytes);
138 t[0].rx_buf = buf + (len - num_busy_bytes);
139 t[0].len = num_busy_bytes;
140 spi_message_add_tail(&t[0], &m);
141 spi_sync(wl->spi, &m);
142 return;
143 }
144 }
145
146 /* 176 /*
147 * Read further busy words from SPI until a non-busy word is 177 * Read further busy words from SPI until a non-busy word is
148 * encountered, then read the data itself into the buffer. 178 * encountered, then read the data itself into the buffer.
149 */ 179 */
150 wl1271_info("spi read BUSY-polling needed!");
151 180
152 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT; 181 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
153 busy_buf = wl->buffer_busyword; 182 busy_buf = wl->buffer_busyword;
@@ -157,28 +186,21 @@ static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
157 memset(t, 0, sizeof(t)); 186 memset(t, 0, sizeof(t));
158 t[0].rx_buf = busy_buf; 187 t[0].rx_buf = busy_buf;
159 t[0].len = sizeof(u32); 188 t[0].len = sizeof(u32);
189 t[0].cs_change = true;
160 spi_message_add_tail(&t[0], &m); 190 spi_message_add_tail(&t[0], &m);
161 spi_sync(wl->spi, &m); 191 spi_sync(wl_to_spi(wl), &m);
162 192
163 if (*busy_buf & 0x1) { 193 if (*busy_buf & 0x1)
164 spi_message_init(&m); 194 return 0;
165 memset(t, 0, sizeof(t));
166 t[0].rx_buf = buf;
167 t[0].len = len;
168 spi_message_add_tail(&t[0], &m);
169 spi_sync(wl->spi, &m);
170 return;
171 }
172 } 195 }
173 196
174 /* The SPI bus is unresponsive, the read failed. */ 197 /* The SPI bus is unresponsive, the read failed. */
175 memset(buf, 0, len);
176 wl1271_error("SPI read busy-word timeout!\n"); 198 wl1271_error("SPI read busy-word timeout!\n");
199 return -ETIMEDOUT;
177} 200}
178#endif
179 201
180void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, 202static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
181 size_t len, bool fixed) 203 size_t len, bool fixed)
182{ 204{
183 struct spi_transfer t[3]; 205 struct spi_transfer t[3];
184 struct spi_message m; 206 struct spi_message m;
@@ -201,28 +223,38 @@ void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
201 223
202 t[0].tx_buf = cmd; 224 t[0].tx_buf = cmd;
203 t[0].len = 4; 225 t[0].len = 4;
226 t[0].cs_change = true;
204 spi_message_add_tail(&t[0], &m); 227 spi_message_add_tail(&t[0], &m);
205 228
206 /* Busy and non busy words read */ 229 /* Busy and non busy words read */
207 t[1].rx_buf = busy_buf; 230 t[1].rx_buf = busy_buf;
208 t[1].len = WL1271_BUSY_WORD_LEN; 231 t[1].len = WL1271_BUSY_WORD_LEN;
232 t[1].cs_change = true;
209 spi_message_add_tail(&t[1], &m); 233 spi_message_add_tail(&t[1], &m);
210 234
211 t[2].rx_buf = buf; 235 spi_sync(wl_to_spi(wl), &m);
212 t[2].len = len;
213 spi_message_add_tail(&t[2], &m);
214 236
215 spi_sync(wl->spi, &m); 237 if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
238 wl1271_spi_read_busy(wl)) {
239 memset(buf, 0, len);
240 return;
241 }
216 242
217 /* FIXME: Check busy words, removed due to SPI bug */ 243 spi_message_init(&m);
218 /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1)) 244 memset(t, 0, sizeof(t));
219 wl1271_spi_read_busy(wl, buf, len); */ 245
246 t[0].rx_buf = buf;
247 t[0].len = len;
248 t[0].cs_change = true;
249 spi_message_add_tail(&t[0], &m);
250
251 spi_sync(wl_to_spi(wl), &m);
220 252
221 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); 253 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
222 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); 254 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
223} 255}
224 256
225void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, 257static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
226 size_t len, bool fixed) 258 size_t len, bool fixed)
227{ 259{
228 struct spi_transfer t[2]; 260 struct spi_transfer t[2];
@@ -250,8 +282,181 @@ void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
250 t[1].len = len; 282 t[1].len = len;
251 spi_message_add_tail(&t[1], &m); 283 spi_message_add_tail(&t[1], &m);
252 284
253 spi_sync(wl->spi, &m); 285 spi_sync(wl_to_spi(wl), &m);
254 286
255 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); 287 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
256 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); 288 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
257} 289}
290
291static irqreturn_t wl1271_irq(int irq, void *cookie)
292{
293 struct wl1271 *wl;
294 unsigned long flags;
295
296 wl1271_debug(DEBUG_IRQ, "IRQ");
297
298 wl = cookie;
299
300 /* complete the ELP completion */
301 spin_lock_irqsave(&wl->wl_lock, flags);
302 if (wl->elp_compl) {
303 complete(wl->elp_compl);
304 wl->elp_compl = NULL;
305 }
306
307 if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
308 ieee80211_queue_work(wl->hw, &wl->irq_work);
309 set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
310 spin_unlock_irqrestore(&wl->wl_lock, flags);
311
312 return IRQ_HANDLED;
313}
314
315static void wl1271_spi_set_power(struct wl1271 *wl, bool enable)
316{
317 if (wl->set_power)
318 wl->set_power(enable);
319}
320
321static struct wl1271_if_operations spi_ops = {
322 .read = wl1271_spi_raw_read,
323 .write = wl1271_spi_raw_write,
324 .reset = wl1271_spi_reset,
325 .init = wl1271_spi_init,
326 .power = wl1271_spi_set_power,
327 .dev = wl1271_spi_wl_to_dev,
328 .enable_irq = wl1271_spi_enable_interrupts,
329 .disable_irq = wl1271_spi_disable_interrupts
330};
331
332static int __devinit wl1271_probe(struct spi_device *spi)
333{
334 struct wl12xx_platform_data *pdata;
335 struct ieee80211_hw *hw;
336 struct wl1271 *wl;
337 int ret;
338
339 pdata = spi->dev.platform_data;
340 if (!pdata) {
341 wl1271_error("no platform data");
342 return -ENODEV;
343 }
344
345 hw = wl1271_alloc_hw();
346 if (IS_ERR(hw))
347 return PTR_ERR(hw);
348
349 wl = hw->priv;
350
351 dev_set_drvdata(&spi->dev, wl);
352 wl->if_priv = spi;
353
354 wl->if_ops = &spi_ops;
355
356 /* This is the only SPI value that we need to set here, the rest
357 * comes from the board-peripherals file */
358 spi->bits_per_word = 32;
359
360 ret = spi_setup(spi);
361 if (ret < 0) {
362 wl1271_error("spi_setup failed");
363 goto out_free;
364 }
365
366 wl->set_power = pdata->set_power;
367 if (!wl->set_power) {
368 wl1271_error("set power function missing in platform data");
369 ret = -ENODEV;
370 goto out_free;
371 }
372
373 wl->irq = spi->irq;
374 if (wl->irq < 0) {
375 wl1271_error("irq missing in platform data");
376 ret = -ENODEV;
377 goto out_free;
378 }
379
380 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
381 if (ret < 0) {
382 wl1271_error("request_irq() failed: %d", ret);
383 goto out_free;
384 }
385
386 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
387
388 disable_irq(wl->irq);
389
390 ret = wl1271_init_ieee80211(wl);
391 if (ret)
392 goto out_irq;
393
394 ret = wl1271_register_hw(wl);
395 if (ret)
396 goto out_irq;
397
398 wl1271_notice("initialized");
399
400 return 0;
401
402 out_irq:
403 free_irq(wl->irq, wl);
404
405 out_free:
406 wl1271_free_hw(wl);
407
408 return ret;
409}
410
411static int __devexit wl1271_remove(struct spi_device *spi)
412{
413 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
414
415 free_irq(wl->irq, wl);
416
417 wl1271_unregister_hw(wl);
418 wl1271_free_hw(wl);
419
420 return 0;
421}
422
423
424static struct spi_driver wl1271_spi_driver = {
425 .driver = {
426 .name = "wl1271_spi",
427 .bus = &spi_bus_type,
428 .owner = THIS_MODULE,
429 },
430
431 .probe = wl1271_probe,
432 .remove = __devexit_p(wl1271_remove),
433};
434
435static int __init wl1271_init(void)
436{
437 int ret;
438
439 ret = spi_register_driver(&wl1271_spi_driver);
440 if (ret < 0) {
441 wl1271_error("failed to register spi driver: %d", ret);
442 goto out;
443 }
444
445out:
446 return ret;
447}
448
449static void __exit wl1271_exit(void)
450{
451 spi_unregister_driver(&wl1271_spi_driver);
452
453 wl1271_notice("unloaded");
454}
455
456module_init(wl1271_init);
457module_exit(wl1271_exit);
458
459MODULE_LICENSE("GPL");
460MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
461MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
462MODULE_FIRMWARE(WL1271_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h
deleted file mode 100644
index a803596dad4a..000000000000
--- a/drivers/net/wireless/wl12xx/wl1271_spi.h
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL1271_SPI_H__
26#define __WL1271_SPI_H__
27
28#include "wl1271_reg.h"
29
30#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
31
32#define HW_PARTITION_REGISTERS_ADDR 0x1ffc0
33#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR)
34#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4)
35#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8)
36#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12)
37#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16)
38#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20)
39#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24)
40
41#define HW_ACCESS_REGISTER_SIZE 4
42
43#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
44
45#define WSPI_CMD_READ 0x40000000
46#define WSPI_CMD_WRITE 0x00000000
47#define WSPI_CMD_FIXED 0x20000000
48#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
49#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
50#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
51
52#define WSPI_INIT_CMD_CRC_LEN 5
53
54#define WSPI_INIT_CMD_START 0x00
55#define WSPI_INIT_CMD_TX 0x40
56/* the extra bypass bit is sampled by the TNET as '1' */
57#define WSPI_INIT_CMD_BYPASS_BIT 0x80
58#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
59#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
60#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
61#define WSPI_INIT_CMD_IOD 0x40
62#define WSPI_INIT_CMD_IP 0x20
63#define WSPI_INIT_CMD_CS 0x10
64#define WSPI_INIT_CMD_WS 0x08
65#define WSPI_INIT_CMD_WSPI 0x01
66#define WSPI_INIT_CMD_END 0x01
67
68#define WSPI_INIT_CMD_LEN 8
69
70#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
71 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
72#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
73
74#define OCP_CMD_LOOP 32
75
76#define OCP_CMD_WRITE 0x1
77#define OCP_CMD_READ 0x2
78
79#define OCP_READY_MASK BIT(18)
80#define OCP_STATUS_MASK (BIT(16) | BIT(17))
81
82#define OCP_STATUS_NO_RESP 0x00000
83#define OCP_STATUS_OK 0x10000
84#define OCP_STATUS_REQ_FAILED 0x20000
85#define OCP_STATUS_RESP_ERROR 0x30000
86
87/* Raw target IO, address is not translated */
88void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
89 size_t len, bool fixed);
90void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
91 size_t len, bool fixed);
92
93/* INIT and RESET words */
94void wl1271_spi_reset(struct wl1271 *wl);
95void wl1271_spi_init(struct wl1271 *wl);
96#endif /* __WL1271_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
index 3919102e942e..2401e6035d51 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -25,7 +25,6 @@
25#include <net/genetlink.h> 25#include <net/genetlink.h>
26 26
27#include "wl1271.h" 27#include "wl1271.h"
28#include "wl1271_spi.h"
29#include "wl1271_acx.h" 28#include "wl1271_acx.h"
30 29
31#define WL1271_TM_MAX_DATA_LENGTH 1024 30#define WL1271_TM_MAX_DATA_LENGTH 1024
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index 811e739d05bf..62db79508ddf 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -25,7 +25,6 @@
25#include <linux/module.h> 25#include <linux/module.h>
26 26
27#include "wl1271.h" 27#include "wl1271.h"
28#include "wl1271_spi.h"
29#include "wl1271_io.h" 28#include "wl1271_io.h"
30#include "wl1271_reg.h" 29#include "wl1271_reg.h"
31#include "wl1271_ps.h" 30#include "wl1271_ps.h"
@@ -47,7 +46,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
47{ 46{
48 struct wl1271_tx_hw_descr *desc; 47 struct wl1271_tx_hw_descr *desc;
49 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; 48 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
50 u32 total_blocks, excluded; 49 u32 total_blocks;
51 int id, ret = -EBUSY; 50 int id, ret = -EBUSY;
52 51
53 /* allocate free identifier for the packet */ 52 /* allocate free identifier for the packet */
@@ -57,12 +56,8 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
57 56
58 /* approximate the number of blocks required for this packet 57 /* approximate the number of blocks required for this packet
59 in the firmware */ 58 in the firmware */
60 /* FIXME: try to figure out what is done here and make it cleaner */ 59 total_blocks = total_len + TX_HW_BLOCK_SIZE - 1;
61 total_blocks = (total_len + 20) >> TX_HW_BLOCK_SHIFT_DIV; 60 total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE;
62 excluded = (total_blocks << 2) + ((total_len + 20) & 0xff) + 34;
63 total_blocks += (excluded > 252) ? 2 : 1;
64 total_blocks += TX_HW_BLOCK_SPARE;
65
66 if (total_blocks <= wl->tx_blocks_available) { 61 if (total_blocks <= wl->tx_blocks_available) {
67 desc = (struct wl1271_tx_hw_descr *)skb_push( 62 desc = (struct wl1271_tx_hw_descr *)skb_push(
68 skb, total_len - skb->len); 63 skb, total_len - skb->len);
@@ -87,8 +82,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
87static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, 82static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
88 u32 extra, struct ieee80211_tx_info *control) 83 u32 extra, struct ieee80211_tx_info *control)
89{ 84{
85 struct timespec ts;
90 struct wl1271_tx_hw_descr *desc; 86 struct wl1271_tx_hw_descr *desc;
91 int pad, ac; 87 int pad, ac;
88 s64 hosttime;
92 u16 tx_attr; 89 u16 tx_attr;
93 90
94 desc = (struct wl1271_tx_hw_descr *) skb->data; 91 desc = (struct wl1271_tx_hw_descr *) skb->data;
@@ -102,8 +99,9 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
102 } 99 }
103 100
104 /* configure packet life time */ 101 /* configure packet life time */
105 desc->start_time = cpu_to_le32(jiffies_to_usecs(jiffies) - 102 getnstimeofday(&ts);
106 wl->time_offset); 103 hosttime = (timespec_to_ns(&ts) >> 10);
104 desc->start_time = cpu_to_le32(hosttime - wl->time_offset);
107 desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); 105 desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU);
108 106
109 /* configure the tx attributes */ 107 /* configure the tx attributes */
@@ -170,7 +168,6 @@ static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
170 168
171 /* write packet new counter into the write access register */ 169 /* write packet new counter into the write access register */
172 wl->tx_packets_count++; 170 wl->tx_packets_count++;
173 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
174 171
175 desc = (struct wl1271_tx_hw_descr *) skb->data; 172 desc = (struct wl1271_tx_hw_descr *) skb->data;
176 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)", 173 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
@@ -223,7 +220,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
223 return ret; 220 return ret;
224} 221}
225 222
226static u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) 223u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
227{ 224{
228 struct ieee80211_supported_band *band; 225 struct ieee80211_supported_band *band;
229 u32 enabled_rates = 0; 226 u32 enabled_rates = 0;
@@ -245,6 +242,7 @@ void wl1271_tx_work(struct work_struct *work)
245 struct sk_buff *skb; 242 struct sk_buff *skb;
246 bool woken_up = false; 243 bool woken_up = false;
247 u32 sta_rates = 0; 244 u32 sta_rates = 0;
245 u32 prev_tx_packets_count;
248 int ret; 246 int ret;
249 247
250 /* check if the rates supported by the AP have changed */ 248 /* check if the rates supported by the AP have changed */
@@ -261,6 +259,8 @@ void wl1271_tx_work(struct work_struct *work)
261 if (unlikely(wl->state == WL1271_STATE_OFF)) 259 if (unlikely(wl->state == WL1271_STATE_OFF))
262 goto out; 260 goto out;
263 261
262 prev_tx_packets_count = wl->tx_packets_count;
263
264 /* if rates have changed, re-configure the rate policy */ 264 /* if rates have changed, re-configure the rate policy */
265 if (unlikely(sta_rates)) { 265 if (unlikely(sta_rates)) {
266 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); 266 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
@@ -271,31 +271,26 @@ void wl1271_tx_work(struct work_struct *work)
271 if (!woken_up) { 271 if (!woken_up) {
272 ret = wl1271_ps_elp_wakeup(wl, false); 272 ret = wl1271_ps_elp_wakeup(wl, false);
273 if (ret < 0) 273 if (ret < 0)
274 goto out; 274 goto out_ack;
275 woken_up = true; 275 woken_up = true;
276 } 276 }
277 277
278 ret = wl1271_tx_frame(wl, skb); 278 ret = wl1271_tx_frame(wl, skb);
279 if (ret == -EBUSY) { 279 if (ret == -EBUSY) {
280 /* firmware buffer is full, stop queues */ 280 /* firmware buffer is full, lets stop transmitting. */
281 wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, "
282 "stop queues");
283 ieee80211_stop_queues(wl->hw);
284 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
285 skb_queue_head(&wl->tx_queue, skb); 281 skb_queue_head(&wl->tx_queue, skb);
286 goto out; 282 goto out_ack;
287 } else if (ret < 0) { 283 } else if (ret < 0) {
288 dev_kfree_skb(skb); 284 dev_kfree_skb(skb);
289 goto out; 285 goto out_ack;
290 } else if (test_and_clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED,
291 &wl->flags)) {
292 /* firmware buffer has space, restart queues */
293 wl1271_debug(DEBUG_TX,
294 "complete_packet: waking queues");
295 ieee80211_wake_queues(wl->hw);
296 } 286 }
297 } 287 }
298 288
289out_ack:
290 /* interrupt the firmware with the new packets */
291 if (prev_tx_packets_count != wl->tx_packets_count)
292 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
293
299out: 294out:
300 if (woken_up) 295 if (woken_up)
301 wl1271_ps_elp_sleep(wl); 296 wl1271_ps_elp_sleep(wl);
@@ -308,11 +303,12 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
308{ 303{
309 struct ieee80211_tx_info *info; 304 struct ieee80211_tx_info *info;
310 struct sk_buff *skb; 305 struct sk_buff *skb;
311 u16 seq;
312 int id = result->id; 306 int id = result->id;
307 int rate = -1;
308 u8 retries = 0;
313 309
314 /* check for id legality */ 310 /* check for id legality */
315 if (id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL) { 311 if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) {
316 wl1271_warning("TX result illegal id: %d", id); 312 wl1271_warning("TX result illegal id: %d", id);
317 return; 313 return;
318 } 314 }
@@ -320,31 +316,29 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
320 skb = wl->tx_frames[id]; 316 skb = wl->tx_frames[id];
321 info = IEEE80211_SKB_CB(skb); 317 info = IEEE80211_SKB_CB(skb);
322 318
323 /* update packet status */ 319 /* update the TX status info */
324 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { 320 if (result->status == TX_SUCCESS) {
325 if (result->status == TX_SUCCESS) 321 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
326 info->flags |= IEEE80211_TX_STAT_ACK; 322 info->flags |= IEEE80211_TX_STAT_ACK;
327 if (result->status & TX_RETRY_EXCEEDED) { 323 rate = wl1271_rate_to_idx(wl, result->rate_class_index);
328 /* FIXME */ 324 retries = result->ack_failures;
329 /* info->status.excessive_retries = 1; */ 325 } else if (result->status == TX_RETRY_EXCEEDED) {
330 wl->stats.excessive_retries++; 326 wl->stats.excessive_retries++;
331 } 327 retries = result->ack_failures;
332 } 328 }
333 329
334 /* FIXME */ 330 info->status.rates[0].idx = rate;
335 /* info->status.retry_count = result->ack_failures; */ 331 info->status.rates[0].count = retries;
332 info->status.rates[0].flags = 0;
333 info->status.ack_signal = -1;
334
336 wl->stats.retry_count += result->ack_failures; 335 wl->stats.retry_count += result->ack_failures;
337 336
338 /* update security sequence number */ 337 /* update security sequence number */
339 seq = wl->tx_security_seq_16 + 338 wl->tx_security_seq += (result->lsb_security_sequence_number -
340 (result->lsb_security_sequence_number - 339 wl->tx_security_last_seq);
341 wl->tx_security_last_seq);
342 wl->tx_security_last_seq = result->lsb_security_sequence_number; 340 wl->tx_security_last_seq = result->lsb_security_sequence_number;
343 341
344 if (seq < wl->tx_security_seq_16)
345 wl->tx_security_seq_32++;
346 wl->tx_security_seq_16 = seq;
347
348 /* remove private header from packet */ 342 /* remove private header from packet */
349 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); 343 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
350 344
@@ -367,23 +361,29 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
367} 361}
368 362
369/* Called upon reception of a TX complete interrupt */ 363/* Called upon reception of a TX complete interrupt */
370void wl1271_tx_complete(struct wl1271 *wl, u32 count) 364void wl1271_tx_complete(struct wl1271 *wl)
371{ 365{
372 struct wl1271_acx_mem_map *memmap = 366 struct wl1271_acx_mem_map *memmap =
373 (struct wl1271_acx_mem_map *)wl->target_mem_map; 367 (struct wl1271_acx_mem_map *)wl->target_mem_map;
368 u32 count, fw_counter;
374 u32 i; 369 u32 i;
375 370
376 wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
377
378 /* read the tx results from the chipset */ 371 /* read the tx results from the chipset */
379 wl1271_read(wl, le32_to_cpu(memmap->tx_result), 372 wl1271_read(wl, le32_to_cpu(memmap->tx_result),
380 wl->tx_res_if, sizeof(*wl->tx_res_if), false); 373 wl->tx_res_if, sizeof(*wl->tx_res_if), false);
374 fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter);
375
376 /* write host counter to chipset (to ack) */
377 wl1271_write32(wl, le32_to_cpu(memmap->tx_result) +
378 offsetof(struct wl1271_tx_hw_res_if,
379 tx_result_host_counter), fw_counter);
380
381 count = fw_counter - wl->tx_results_count;
382 wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
381 383
382 /* verify that the result buffer is not getting overrun */ 384 /* verify that the result buffer is not getting overrun */
383 if (count > TX_HW_RESULT_QUEUE_LEN) { 385 if (unlikely(count > TX_HW_RESULT_QUEUE_LEN))
384 wl1271_warning("TX result overflow from chipset: %d", count); 386 wl1271_warning("TX result overflow from chipset: %d", count);
385 count = TX_HW_RESULT_QUEUE_LEN;
386 }
387 387
388 /* process the results */ 388 /* process the results */
389 for (i = 0; i < count; i++) { 389 for (i = 0; i < count; i++) {
@@ -397,11 +397,18 @@ void wl1271_tx_complete(struct wl1271 *wl, u32 count)
397 wl->tx_results_count++; 397 wl->tx_results_count++;
398 } 398 }
399 399
400 /* write host counter to chipset (to ack) */ 400 if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
401 wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + 401 skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) {
402 offsetof(struct wl1271_tx_hw_res_if, 402 unsigned long flags;
403 tx_result_host_counter), 403
404 le32_to_cpu(wl->tx_res_if->tx_result_fw_counter)); 404 /* firmware buffer has space, restart queues */
405 wl1271_debug(DEBUG_TX, "tx_complete: waking queues");
406 spin_lock_irqsave(&wl->wl_lock, flags);
407 ieee80211_wake_queues(wl->hw);
408 clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
409 spin_unlock_irqrestore(&wl->wl_lock, flags);
410 ieee80211_queue_work(wl->hw, &wl->tx_work);
411 }
405} 412}
406 413
407/* caller must hold wl->mutex */ 414/* caller must hold wl->mutex */
@@ -409,31 +416,19 @@ void wl1271_tx_flush(struct wl1271 *wl)
409{ 416{
410 int i; 417 int i;
411 struct sk_buff *skb; 418 struct sk_buff *skb;
412 struct ieee80211_tx_info *info;
413 419
414 /* TX failure */ 420 /* TX failure */
415/* control->flags = 0; FIXME */ 421/* control->flags = 0; FIXME */
416 422
417 while ((skb = skb_dequeue(&wl->tx_queue))) { 423 while ((skb = skb_dequeue(&wl->tx_queue))) {
418 info = IEEE80211_SKB_CB(skb);
419
420 wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb); 424 wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb);
421
422 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
423 continue;
424
425 ieee80211_tx_status(wl->hw, skb); 425 ieee80211_tx_status(wl->hw, skb);
426 } 426 }
427 427
428 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 428 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
429 if (wl->tx_frames[i] != NULL) { 429 if (wl->tx_frames[i] != NULL) {
430 skb = wl->tx_frames[i]; 430 skb = wl->tx_frames[i];
431 info = IEEE80211_SKB_CB(skb);
432
433 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
434 continue;
435
436 ieee80211_tx_status(wl->hw, skb);
437 wl->tx_frames[i] = NULL; 431 wl->tx_frames[i] = NULL;
432 ieee80211_tx_status(wl->hw, skb);
438 } 433 }
439} 434}
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 17e405a09caa..3b8b7ac253fd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -26,7 +26,7 @@
26#define __WL1271_TX_H__ 26#define __WL1271_TX_H__
27 27
28#define TX_HW_BLOCK_SPARE 2 28#define TX_HW_BLOCK_SPARE 2
29#define TX_HW_BLOCK_SHIFT_DIV 8 29#define TX_HW_BLOCK_SIZE 252
30 30
31#define TX_HW_MGMT_PKT_LIFETIME_TU 2000 31#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
32/* The chipset reference driver states, that the "aid" value 1 32/* The chipset reference driver states, that the "aid" value 1
@@ -125,9 +125,6 @@ struct wl1271_tx_hw_res_if {
125 125
126static inline int wl1271_tx_get_queue(int queue) 126static inline int wl1271_tx_get_queue(int queue)
127{ 127{
128 /* FIXME: use best effort until WMM is enabled */
129 return CONF_TX_AC_BE;
130
131 switch (queue) { 128 switch (queue) {
132 case 0: 129 case 0:
133 return CONF_TX_AC_VO; 130 return CONF_TX_AC_VO;
@@ -160,7 +157,9 @@ static inline int wl1271_tx_ac_to_tid(int ac)
160} 157}
161 158
162void wl1271_tx_work(struct work_struct *work); 159void wl1271_tx_work(struct work_struct *work);
163void wl1271_tx_complete(struct wl1271 *wl, u32 count); 160void wl1271_tx_complete(struct wl1271 *wl);
164void wl1271_tx_flush(struct wl1271 *wl); 161void wl1271_tx_flush(struct wl1271 *wl);
162u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
163u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
165 164
166#endif 165#endif
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 7b9621de239f..65dd502eab0d 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1834,32 +1834,32 @@ out:
1834} 1834}
1835 1835
1836static const iw_handler wl3501_handler[] = { 1836static const iw_handler wl3501_handler[] = {
1837 [SIOCGIWNAME - SIOCIWFIRST] = wl3501_get_name, 1837 IW_HANDLER(SIOCGIWNAME, wl3501_get_name),
1838 [SIOCSIWFREQ - SIOCIWFIRST] = wl3501_set_freq, 1838 IW_HANDLER(SIOCSIWFREQ, wl3501_set_freq),
1839 [SIOCGIWFREQ - SIOCIWFIRST] = wl3501_get_freq, 1839 IW_HANDLER(SIOCGIWFREQ, wl3501_get_freq),
1840 [SIOCSIWMODE - SIOCIWFIRST] = wl3501_set_mode, 1840 IW_HANDLER(SIOCSIWMODE, wl3501_set_mode),
1841 [SIOCGIWMODE - SIOCIWFIRST] = wl3501_get_mode, 1841 IW_HANDLER(SIOCGIWMODE, wl3501_get_mode),
1842 [SIOCGIWSENS - SIOCIWFIRST] = wl3501_get_sens, 1842 IW_HANDLER(SIOCGIWSENS, wl3501_get_sens),
1843 [SIOCGIWRANGE - SIOCIWFIRST] = wl3501_get_range, 1843 IW_HANDLER(SIOCGIWRANGE, wl3501_get_range),
1844 [SIOCSIWSPY - SIOCIWFIRST] = iw_handler_set_spy, 1844 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1845 [SIOCGIWSPY - SIOCIWFIRST] = iw_handler_get_spy, 1845 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1846 [SIOCSIWTHRSPY - SIOCIWFIRST] = iw_handler_set_thrspy, 1846 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1847 [SIOCGIWTHRSPY - SIOCIWFIRST] = iw_handler_get_thrspy, 1847 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1848 [SIOCSIWAP - SIOCIWFIRST] = wl3501_set_wap, 1848 IW_HANDLER(SIOCSIWAP, wl3501_set_wap),
1849 [SIOCGIWAP - SIOCIWFIRST] = wl3501_get_wap, 1849 IW_HANDLER(SIOCGIWAP, wl3501_get_wap),
1850 [SIOCSIWSCAN - SIOCIWFIRST] = wl3501_set_scan, 1850 IW_HANDLER(SIOCSIWSCAN, wl3501_set_scan),
1851 [SIOCGIWSCAN - SIOCIWFIRST] = wl3501_get_scan, 1851 IW_HANDLER(SIOCGIWSCAN, wl3501_get_scan),
1852 [SIOCSIWESSID - SIOCIWFIRST] = wl3501_set_essid, 1852 IW_HANDLER(SIOCSIWESSID, wl3501_set_essid),
1853 [SIOCGIWESSID - SIOCIWFIRST] = wl3501_get_essid, 1853 IW_HANDLER(SIOCGIWESSID, wl3501_get_essid),
1854 [SIOCSIWNICKN - SIOCIWFIRST] = wl3501_set_nick, 1854 IW_HANDLER(SIOCSIWNICKN, wl3501_set_nick),
1855 [SIOCGIWNICKN - SIOCIWFIRST] = wl3501_get_nick, 1855 IW_HANDLER(SIOCGIWNICKN, wl3501_get_nick),
1856 [SIOCGIWRATE - SIOCIWFIRST] = wl3501_get_rate, 1856 IW_HANDLER(SIOCGIWRATE, wl3501_get_rate),
1857 [SIOCGIWRTS - SIOCIWFIRST] = wl3501_get_rts_threshold, 1857 IW_HANDLER(SIOCGIWRTS, wl3501_get_rts_threshold),
1858 [SIOCGIWFRAG - SIOCIWFIRST] = wl3501_get_frag_threshold, 1858 IW_HANDLER(SIOCGIWFRAG, wl3501_get_frag_threshold),
1859 [SIOCGIWTXPOW - SIOCIWFIRST] = wl3501_get_txpow, 1859 IW_HANDLER(SIOCGIWTXPOW, wl3501_get_txpow),
1860 [SIOCGIWRETRY - SIOCIWFIRST] = wl3501_get_retry, 1860 IW_HANDLER(SIOCGIWRETRY, wl3501_get_retry),
1861 [SIOCGIWENCODE - SIOCIWFIRST] = wl3501_get_encode, 1861 IW_HANDLER(SIOCGIWENCODE, wl3501_get_encode),
1862 [SIOCGIWPOWER - SIOCIWFIRST] = wl3501_get_power, 1862 IW_HANDLER(SIOCGIWPOWER, wl3501_get_power),
1863}; 1863};
1864 1864
1865static const struct iw_handler_def wl3501_handler_def = { 1865static const struct iw_handler_def wl3501_handler_def = {
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 9681536163ca..59c3c0fdbecd 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -370,6 +370,7 @@ u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)
370{ 370{
371 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); 371 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
372} 372}
373EXPORT_SYMBOL(ssb_chipco_gpio_control);
373 374
374u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) 375u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
375{ 376{
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 19984958ab7b..e9e03b02cb08 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1324,7 +1324,6 @@ enum ieee80211_back_actioncode {
1324enum ieee80211_back_parties { 1324enum ieee80211_back_parties {
1325 WLAN_BACK_RECIPIENT = 0, 1325 WLAN_BACK_RECIPIENT = 0,
1326 WLAN_BACK_INITIATOR = 1, 1326 WLAN_BACK_INITIATOR = 1,
1327 WLAN_BACK_TIMER = 2,
1328}; 1327};
1329 1328
1330/* SA Query action */ 1329/* SA Query action */
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 47ba464f5170..118f0295a575 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -94,6 +94,8 @@
94 94
95#define SDIO_BUS_WIDTH_1BIT 0x00 95#define SDIO_BUS_WIDTH_1BIT 0x00
96#define SDIO_BUS_WIDTH_4BIT 0x02 96#define SDIO_BUS_WIDTH_4BIT 0x02
97#define SDIO_BUS_ECSI 0x20 /* Enable continuous SPI interrupt */
98#define SDIO_BUS_SCSI 0x40 /* Support continuous SPI interrupt */
97 99
98#define SDIO_BUS_CD_DISABLE 0x80 /* disable pull-up on DAT3 (pin 1) */ 100#define SDIO_BUS_CD_DISABLE 0x80 /* disable pull-up on DAT3 (pin 1) */
99 101
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 28ba20fda3e2..2ea3edeee7aa 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -323,6 +323,12 @@
323 * the TX command and %NL80211_ATTR_FRAME includes the contents of the 323 * the TX command and %NL80211_ATTR_FRAME includes the contents of the
324 * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged 324 * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged
325 * the frame. 325 * the frame.
326 * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command
327 * is used to configure connection quality monitoring notification trigger
328 * levels.
329 * @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This
330 * command is used as an event to indicate the that a trigger level was
331 * reached.
326 * 332 *
327 * @NL80211_CMD_MAX: highest used command number 333 * @NL80211_CMD_MAX: highest used command number
328 * @__NL80211_CMD_AFTER_LAST: internal use 334 * @__NL80211_CMD_AFTER_LAST: internal use
@@ -419,6 +425,9 @@ enum nl80211_commands {
419 NL80211_CMD_SET_POWER_SAVE, 425 NL80211_CMD_SET_POWER_SAVE,
420 NL80211_CMD_GET_POWER_SAVE, 426 NL80211_CMD_GET_POWER_SAVE,
421 427
428 NL80211_CMD_SET_CQM,
429 NL80211_CMD_NOTIFY_CQM,
430
422 /* add new commands above here */ 431 /* add new commands above here */
423 432
424 /* used to define NL80211_CMD_MAX below */ 433 /* used to define NL80211_CMD_MAX below */
@@ -691,6 +700,15 @@ enum nl80211_commands {
691 * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was 700 * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was
692 * acknowledged by the recipient. 701 * acknowledged by the recipient.
693 * 702 *
703 * @NL80211_ATTR_CQM: connection quality monitor configuration in a
704 * nested attribute with %NL80211_ATTR_CQM_* sub-attributes.
705 *
706 * @NL80211_ATTR_LOCAL_STATE_CHANGE: Flag attribute to indicate that a command
707 * is requesting a local authentication/association state change without
708 * invoking actual management frame exchange. This can be used with
709 * NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE,
710 * NL80211_CMD_DISASSOCIATE.
711 *
694 * @NL80211_ATTR_MAX: highest attribute number currently defined 712 * @NL80211_ATTR_MAX: highest attribute number currently defined
695 * @__NL80211_ATTR_AFTER_LAST: internal use 713 * @__NL80211_ATTR_AFTER_LAST: internal use
696 */ 714 */
@@ -842,6 +860,10 @@ enum nl80211_attrs {
842 860
843 NL80211_ATTR_PS_STATE, 861 NL80211_ATTR_PS_STATE,
844 862
863 NL80211_ATTR_CQM,
864
865 NL80211_ATTR_LOCAL_STATE_CHANGE,
866
845 /* add attributes here, update the policy in nl80211.c */ 867 /* add attributes here, update the policy in nl80211.c */
846 868
847 __NL80211_ATTR_AFTER_LAST, 869 __NL80211_ATTR_AFTER_LAST,
@@ -1583,4 +1605,40 @@ enum nl80211_ps_state {
1583 NL80211_PS_ENABLED, 1605 NL80211_PS_ENABLED,
1584}; 1606};
1585 1607
1608/**
1609 * enum nl80211_attr_cqm - connection quality monitor attributes
1610 * @__NL80211_ATTR_CQM_INVALID: invalid
1611 * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies
1612 * the threshold for the RSSI level at which an event will be sent. Zero
1613 * to disable.
1614 * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies
1615 * the minimum amount the RSSI level must change after an event before a
1616 * new event may be issued (to reduce effects of RSSI oscillation).
1617 * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event
1618 * @__NL80211_ATTR_CQM_AFTER_LAST: internal
1619 * @NL80211_ATTR_CQM_MAX: highest key attribute
1620 */
1621enum nl80211_attr_cqm {
1622 __NL80211_ATTR_CQM_INVALID,
1623 NL80211_ATTR_CQM_RSSI_THOLD,
1624 NL80211_ATTR_CQM_RSSI_HYST,
1625 NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
1626
1627 /* keep last */
1628 __NL80211_ATTR_CQM_AFTER_LAST,
1629 NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1
1630};
1631
1632/**
1633 * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event
1634 * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW - The RSSI level is lower than the
1635 * configured threshold
1636 * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH - The RSSI is higher than the
1637 * configured threshold
1638 */
1639enum nl80211_cqm_rssi_threshold_event {
1640 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
1641 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
1642};
1643
1586#endif /* __LINUX_NL80211_H */ 1644#endif /* __LINUX_NL80211_H */
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 5b4c6c772a9b..e6827eedf18b 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -346,6 +346,8 @@
346#define SIOCIWFIRST 0x8B00 346#define SIOCIWFIRST 0x8B00
347#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */ 347#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
348#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) 348#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
349#define IW_HANDLER(id, func) \
350 [IW_IOCTL_IDX(id)] = func
349 351
350/* Odd : get (world access), even : set (root access) */ 352/* Odd : get (world access), even : set (root access) */
351#define IW_IS_SET(cmd) (!((cmd) & 0x1)) 353#define IW_IS_SET(cmd) (!((cmd) & 0x1))
@@ -648,7 +650,7 @@
648 * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */ 650 * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
649#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \ 651#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \
650 (cmd - SIOCIWFIRSTPRIV + 0x60) : \ 652 (cmd - SIOCIWFIRSTPRIV + 0x60) : \
651 (cmd - SIOCSIWCOMMIT)) 653 (cmd - SIOCIWFIRST))
652#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5) 654#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5)
653#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F)) 655#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F))
654/* Event capability constants - event autogenerated by the kernel 656/* Event capability constants - event autogenerated by the kernel
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3d134a1fb96b..37cebd3aa0f7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -704,6 +704,10 @@ struct cfg80211_crypto_settings {
704 * @key_len: length of WEP key for shared key authentication 704 * @key_len: length of WEP key for shared key authentication
705 * @key_idx: index of WEP key for shared key authentication 705 * @key_idx: index of WEP key for shared key authentication
706 * @key: WEP key for shared key authentication 706 * @key: WEP key for shared key authentication
707 * @local_state_change: This is a request for a local state only, i.e., no
708 * Authentication frame is to be transmitted and authentication state is
709 * to be changed without having to wait for a response from the peer STA
710 * (AP).
707 */ 711 */
708struct cfg80211_auth_request { 712struct cfg80211_auth_request {
709 struct cfg80211_bss *bss; 713 struct cfg80211_bss *bss;
@@ -712,6 +716,7 @@ struct cfg80211_auth_request {
712 enum nl80211_auth_type auth_type; 716 enum nl80211_auth_type auth_type;
713 const u8 *key; 717 const u8 *key;
714 u8 key_len, key_idx; 718 u8 key_len, key_idx;
719 bool local_state_change;
715}; 720};
716 721
717/** 722/**
@@ -744,12 +749,15 @@ struct cfg80211_assoc_request {
744 * @ie: Extra IEs to add to Deauthentication frame or %NULL 749 * @ie: Extra IEs to add to Deauthentication frame or %NULL
745 * @ie_len: Length of ie buffer in octets 750 * @ie_len: Length of ie buffer in octets
746 * @reason_code: The reason code for the deauthentication 751 * @reason_code: The reason code for the deauthentication
752 * @local_state_change: This is a request for a local state only, i.e., no
753 * Deauthentication frame is to be transmitted.
747 */ 754 */
748struct cfg80211_deauth_request { 755struct cfg80211_deauth_request {
749 struct cfg80211_bss *bss; 756 struct cfg80211_bss *bss;
750 const u8 *ie; 757 const u8 *ie;
751 size_t ie_len; 758 size_t ie_len;
752 u16 reason_code; 759 u16 reason_code;
760 bool local_state_change;
753}; 761};
754 762
755/** 763/**
@@ -762,12 +770,15 @@ struct cfg80211_deauth_request {
762 * @ie: Extra IEs to add to Disassociation frame or %NULL 770 * @ie: Extra IEs to add to Disassociation frame or %NULL
763 * @ie_len: Length of ie buffer in octets 771 * @ie_len: Length of ie buffer in octets
764 * @reason_code: The reason code for the disassociation 772 * @reason_code: The reason code for the disassociation
773 * @local_state_change: This is a request for a local state only, i.e., no
774 * Disassociation frame is to be transmitted.
765 */ 775 */
766struct cfg80211_disassoc_request { 776struct cfg80211_disassoc_request {
767 struct cfg80211_bss *bss; 777 struct cfg80211_bss *bss;
768 const u8 *ie; 778 const u8 *ie;
769 size_t ie_len; 779 size_t ie_len;
770 u16 reason_code; 780 u16 reason_code;
781 bool local_state_change;
771}; 782};
772 783
773/** 784/**
@@ -1007,6 +1018,7 @@ struct cfg80211_pmksa {
1007 * RSN IE. It allows for faster roaming between WPA2 BSSIDs. 1018 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1008 * @del_pmksa: Delete a cached PMKID. 1019 * @del_pmksa: Delete a cached PMKID.
1009 * @flush_pmksa: Flush all cached PMKIDs. 1020 * @flush_pmksa: Flush all cached PMKIDs.
1021 * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
1010 * 1022 *
1011 */ 1023 */
1012struct cfg80211_ops { 1024struct cfg80211_ops {
@@ -1152,6 +1164,10 @@ struct cfg80211_ops {
1152 1164
1153 int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, 1165 int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
1154 bool enabled, int timeout); 1166 bool enabled, int timeout);
1167
1168 int (*set_cqm_rssi_config)(struct wiphy *wiphy,
1169 struct net_device *dev,
1170 s32 rssi_thold, u32 rssi_hyst);
1155}; 1171};
1156 1172
1157/* 1173/*
@@ -2337,4 +2353,18 @@ bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf,
2337void cfg80211_action_tx_status(struct net_device *dev, u64 cookie, 2353void cfg80211_action_tx_status(struct net_device *dev, u64 cookie,
2338 const u8 *buf, size_t len, bool ack, gfp_t gfp); 2354 const u8 *buf, size_t len, bool ack, gfp_t gfp);
2339 2355
2356
2357/**
2358 * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event
2359 * @dev: network device
2360 * @rssi_event: the triggered RSSI event
2361 * @gfp: context flags
2362 *
2363 * This function is called when a configured connection quality monitoring
2364 * rssi threshold reached event occurs.
2365 */
2366void cfg80211_cqm_rssi_notify(struct net_device *dev,
2367 enum nl80211_cqm_rssi_threshold_event rssi_event,
2368 gfp_t gfp);
2369
2340#endif /* __NET_CFG80211_H */ 2370#endif /* __NET_CFG80211_H */
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index b2b98f3fa265..3afdb21cc31d 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -323,7 +323,7 @@ typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
323struct iw_handler_def { 323struct iw_handler_def {
324 324
325 /* Array of handlers for standard ioctls 325 /* Array of handlers for standard ioctls
326 * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWCOMMIT] 326 * We will call dev->wireless_handlers->standard[ioctl - SIOCIWFIRST]
327 */ 327 */
328 const iw_handler * standard; 328 const iw_handler * standard;
329 /* Number of handlers defined (more precisely, index of the 329 /* Number of handlers defined (more precisely, index of the
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 45d7d44d7cbe..dcf3c5f23c96 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -144,6 +144,7 @@ struct ieee80211_low_level_stats {
144 * new beacon (beaconing modes) 144 * new beacon (beaconing modes)
145 * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be 145 * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be
146 * enabled/disabled (beaconing modes) 146 * enabled/disabled (beaconing modes)
147 * @BSS_CHANGED_CQM: Connection quality monitor config changed
147 */ 148 */
148enum ieee80211_bss_change { 149enum ieee80211_bss_change {
149 BSS_CHANGED_ASSOC = 1<<0, 150 BSS_CHANGED_ASSOC = 1<<0,
@@ -156,6 +157,7 @@ enum ieee80211_bss_change {
156 BSS_CHANGED_BSSID = 1<<7, 157 BSS_CHANGED_BSSID = 1<<7,
157 BSS_CHANGED_BEACON = 1<<8, 158 BSS_CHANGED_BEACON = 1<<8,
158 BSS_CHANGED_BEACON_ENABLED = 1<<9, 159 BSS_CHANGED_BEACON_ENABLED = 1<<9,
160 BSS_CHANGED_CQM = 1<<10,
159}; 161};
160 162
161/** 163/**
@@ -185,6 +187,9 @@ enum ieee80211_bss_change {
185 * @enable_beacon: whether beaconing should be enabled or not 187 * @enable_beacon: whether beaconing should be enabled or not
186 * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info). 188 * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info).
187 * This field is only valid when the channel type is one of the HT types. 189 * This field is only valid when the channel type is one of the HT types.
190 * @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value
191 * implies disabled
192 * @cqm_rssi_hyst: Connection quality monitor RSSI hysteresis
188 */ 193 */
189struct ieee80211_bss_conf { 194struct ieee80211_bss_conf {
190 const u8 *bssid; 195 const u8 *bssid;
@@ -202,6 +207,8 @@ struct ieee80211_bss_conf {
202 u64 timestamp; 207 u64 timestamp;
203 u32 basic_rates; 208 u32 basic_rates;
204 u16 ht_operation_mode; 209 u16 ht_operation_mode;
210 s32 cqm_rssi_thold;
211 u32 cqm_rssi_hyst;
205}; 212};
206 213
207/** 214/**
@@ -543,7 +550,7 @@ enum mac80211_rx_flags {
543 * @signal: signal strength when receiving this frame, either in dBm, in dB or 550 * @signal: signal strength when receiving this frame, either in dBm, in dB or
544 * unspecified depending on the hardware capabilities flags 551 * unspecified depending on the hardware capabilities flags
545 * @IEEE80211_HW_SIGNAL_* 552 * @IEEE80211_HW_SIGNAL_*
546 * @noise: noise when receiving this frame, in dBm. 553 * @noise: noise when receiving this frame, in dBm (DEPRECATED).
547 * @antenna: antenna used 554 * @antenna: antenna used
548 * @rate_idx: index of data rate into band's supported rates or MCS index if 555 * @rate_idx: index of data rate into band's supported rates or MCS index if
549 * HT rates are use (RX_FLAG_HT) 556 * HT rates are use (RX_FLAG_HT)
@@ -554,7 +561,7 @@ struct ieee80211_rx_status {
554 enum ieee80211_band band; 561 enum ieee80211_band band;
555 int freq; 562 int freq;
556 int signal; 563 int signal;
557 int noise; 564 int noise __deprecated;
558 int antenna; 565 int antenna;
559 int rate_idx; 566 int rate_idx;
560 int flag; 567 int flag;
@@ -580,11 +587,15 @@ struct ieee80211_rx_status {
580 * may turn the device off as much as possible. Typically, this flag will 587 * may turn the device off as much as possible. Typically, this flag will
581 * be set when an interface is set UP but not associated or scanning, but 588 * be set when an interface is set UP but not associated or scanning, but
582 * it can also be unset in that case when monitor interfaces are active. 589 * it can also be unset in that case when monitor interfaces are active.
590 * @IEEE80211_CONF_QOS: Enable 802.11e QoS also know as WMM (Wireless
591 * Multimedia). On some drivers (iwlwifi is one of know) we have
592 * to enable/disable QoS explicitly.
583 */ 593 */
584enum ieee80211_conf_flags { 594enum ieee80211_conf_flags {
585 IEEE80211_CONF_MONITOR = (1<<0), 595 IEEE80211_CONF_MONITOR = (1<<0),
586 IEEE80211_CONF_PS = (1<<1), 596 IEEE80211_CONF_PS = (1<<1),
587 IEEE80211_CONF_IDLE = (1<<2), 597 IEEE80211_CONF_IDLE = (1<<2),
598 IEEE80211_CONF_QOS = (1<<3),
588}; 599};
589 600
590 601
@@ -609,6 +620,7 @@ enum ieee80211_conf_changed {
609 IEEE80211_CONF_CHANGE_CHANNEL = BIT(6), 620 IEEE80211_CONF_CHANGE_CHANNEL = BIT(6),
610 IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(7), 621 IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(7),
611 IEEE80211_CONF_CHANGE_IDLE = BIT(8), 622 IEEE80211_CONF_CHANGE_IDLE = BIT(8),
623 IEEE80211_CONF_CHANGE_QOS = BIT(9),
612}; 624};
613 625
614/** 626/**
@@ -954,6 +966,17 @@ enum ieee80211_tkip_key_type {
954 * Hardware can provide ack status reports of Tx frames to 966 * Hardware can provide ack status reports of Tx frames to
955 * the stack. 967 * the stack.
956 * 968 *
969 * @IEEE80211_HW_CONNECTION_MONITOR:
970 * The hardware performs its own connection monitoring, including
971 * periodic keep-alives to the AP and probing the AP on beacon loss.
972 * When this flag is set, signaling beacon-loss will cause an immediate
973 * change to disassociated state.
974 *
975 * @IEEE80211_HW_SUPPORTS_CQM_RSSI:
976 * Hardware can do connection quality monitoring - i.e. it can monitor
977 * connection quality related parameters, such as the RSSI level and
978 * provide notifications if configured trigger levels are reached.
979 *
957 */ 980 */
958enum ieee80211_hw_flags { 981enum ieee80211_hw_flags {
959 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, 982 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -975,6 +998,8 @@ enum ieee80211_hw_flags {
975 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16, 998 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16,
976 IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, 999 IEEE80211_HW_SUPPORTS_UAPSD = 1<<17,
977 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, 1000 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18,
1001 IEEE80211_HW_CONNECTION_MONITOR = 1<<19,
1002 IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20,
978}; 1003};
979 1004
980/** 1005/**
@@ -1802,7 +1827,10 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);
1802 * ieee80211_rx - receive frame 1827 * ieee80211_rx - receive frame
1803 * 1828 *
1804 * Use this function to hand received frames to mac80211. The receive 1829 * Use this function to hand received frames to mac80211. The receive
1805 * buffer in @skb must start with an IEEE 802.11 header. 1830 * buffer in @skb must start with an IEEE 802.11 header. In case of a
1831 * paged @skb is used, the driver is recommended to put the ieee80211
1832 * header of the frame on the linear part of the @skb to avoid memory
1833 * allocation and/or memcpy by the stack.
1806 * 1834 *
1807 * This function may not be called in IRQ context. Calls to this function 1835 * This function may not be called in IRQ context. Calls to this function
1808 * for a single hardware must be synchronized against each other. Calls to 1836 * for a single hardware must be synchronized against each other. Calls to
@@ -2364,12 +2392,42 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
2364 * 2392 *
2365 * @vif: &struct ieee80211_vif pointer from the add_interface callback. 2393 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
2366 * 2394 *
2367 * When beacon filtering is enabled with IEEE80211_HW_BEACON_FILTERING and 2395 * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING and
2368 * IEEE80211_CONF_PS is set, the driver needs to inform whenever the 2396 * %IEEE80211_CONF_PS is set, the driver needs to inform whenever the
2369 * hardware is not receiving beacons with this function. 2397 * hardware is not receiving beacons with this function.
2370 */ 2398 */
2371void ieee80211_beacon_loss(struct ieee80211_vif *vif); 2399void ieee80211_beacon_loss(struct ieee80211_vif *vif);
2372 2400
2401/**
2402 * ieee80211_connection_loss - inform hardware has lost connection to the AP
2403 *
2404 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
2405 *
2406 * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING, and
2407 * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver
2408 * needs to inform if the connection to the AP has been lost.
2409 *
2410 * This function will cause immediate change to disassociated state,
2411 * without connection recovery attempts.
2412 */
2413void ieee80211_connection_loss(struct ieee80211_vif *vif);
2414
2415/**
2416 * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring
2417 * rssi threshold triggered
2418 *
2419 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
2420 * @rssi_event: the RSSI trigger event type
2421 * @gfp: context flags
2422 *
2423 * When the %IEEE80211_HW_SUPPORTS_CQM_RSSI is set, and a connection quality
2424 * monitoring is configured with an rssi threshold, the driver will inform
2425 * whenever the rssi level reaches the threshold.
2426 */
2427void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
2428 enum nl80211_cqm_rssi_threshold_event rssi_event,
2429 gfp_t gfp);
2430
2373/* Rate control API */ 2431/* Rate control API */
2374 2432
2375/** 2433/**
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index a952b7f8c648..334c359da5e8 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -15,8 +15,12 @@ comment "CFG80211 needs to be enabled for MAC80211"
15 15
16if MAC80211 != n 16if MAC80211 != n
17 17
18config MAC80211_HAS_RC
19 def_bool n
20
18config MAC80211_RC_PID 21config MAC80211_RC_PID
19 bool "PID controller based rate control algorithm" if EMBEDDED 22 bool "PID controller based rate control algorithm" if EMBEDDED
23 select MAC80211_HAS_RC
20 ---help--- 24 ---help---
21 This option enables a TX rate control algorithm for 25 This option enables a TX rate control algorithm for
22 mac80211 that uses a PID controller to select the TX 26 mac80211 that uses a PID controller to select the TX
@@ -24,12 +28,14 @@ config MAC80211_RC_PID
24 28
25config MAC80211_RC_MINSTREL 29config MAC80211_RC_MINSTREL
26 bool "Minstrel" if EMBEDDED 30 bool "Minstrel" if EMBEDDED
31 select MAC80211_HAS_RC
27 default y 32 default y
28 ---help--- 33 ---help---
29 This option enables the 'minstrel' TX rate control algorithm 34 This option enables the 'minstrel' TX rate control algorithm
30 35
31choice 36choice
32 prompt "Default rate control algorithm" 37 prompt "Default rate control algorithm"
38 depends on MAC80211_HAS_RC
33 default MAC80211_RC_DEFAULT_MINSTREL 39 default MAC80211_RC_DEFAULT_MINSTREL
34 ---help--- 40 ---help---
35 This option selects the default rate control algorithm 41 This option selects the default rate control algorithm
@@ -62,6 +68,9 @@ config MAC80211_RC_DEFAULT
62 68
63endif 69endif
64 70
71comment "Some wireless drivers require a rate control algorithm"
72 depends on MAC80211_HAS_RC=n
73
65config MAC80211_MESH 74config MAC80211_MESH
66 bool "Enable mac80211 mesh networking (pre-802.11s) support" 75 bool "Enable mac80211 mesh networking (pre-802.11s) support"
67 depends on MAC80211 && EXPERIMENTAL 76 depends on MAC80211 && EXPERIMENTAL
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index a978e666ed6f..53233ab50f65 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -22,19 +22,20 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
22 u16 initiator, u16 reason) 22 u16 initiator, u16 reason)
23{ 23{
24 struct ieee80211_local *local = sta->local; 24 struct ieee80211_local *local = sta->local;
25 struct tid_ampdu_rx *tid_rx;
25 int i; 26 int i;
26 27
27 /* check if TID is in operational state */
28 spin_lock_bh(&sta->lock); 28 spin_lock_bh(&sta->lock);
29 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) { 29
30 /* check if TID is in operational state */
31 if (!sta->ampdu_mlme.tid_active_rx[tid]) {
30 spin_unlock_bh(&sta->lock); 32 spin_unlock_bh(&sta->lock);
31 return; 33 return;
32 } 34 }
33 35
34 sta->ampdu_mlme.tid_state_rx[tid] = 36 sta->ampdu_mlme.tid_active_rx[tid] = false;
35 HT_AGG_STATE_REQ_STOP_BA_MSK | 37
36 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 38 tid_rx = sta->ampdu_mlme.tid_rx[tid];
37 spin_unlock_bh(&sta->lock);
38 39
39#ifdef CONFIG_MAC80211_HT_DEBUG 40#ifdef CONFIG_MAC80211_HT_DEBUG
40 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", 41 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
@@ -46,61 +47,35 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
46 printk(KERN_DEBUG "HW problem - can not stop rx " 47 printk(KERN_DEBUG "HW problem - can not stop rx "
47 "aggregation for tid %d\n", tid); 48 "aggregation for tid %d\n", tid);
48 49
49 /* shutdown timer has not expired */
50 if (initiator != WLAN_BACK_TIMER)
51 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
52
53 /* check if this is a self generated aggregation halt */ 50 /* check if this is a self generated aggregation halt */
54 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER) 51 if (initiator == WLAN_BACK_RECIPIENT)
55 ieee80211_send_delba(sta->sdata, sta->sta.addr, 52 ieee80211_send_delba(sta->sdata, sta->sta.addr,
56 tid, 0, reason); 53 tid, 0, reason);
57 54
58 /* free the reordering buffer */ 55 /* free the reordering buffer */
59 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) { 56 for (i = 0; i < tid_rx->buf_size; i++) {
60 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) { 57 if (tid_rx->reorder_buf[i]) {
61 /* release the reordered frames */ 58 /* release the reordered frames */
62 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]); 59 dev_kfree_skb(tid_rx->reorder_buf[i]);
63 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--; 60 tid_rx->stored_mpdu_num--;
64 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL; 61 tid_rx->reorder_buf[i] = NULL;
65 } 62 }
66 } 63 }
67 64
68 spin_lock_bh(&sta->lock);
69 /* free resources */ 65 /* free resources */
70 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf); 66 kfree(tid_rx->reorder_buf);
71 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_time); 67 kfree(tid_rx->reorder_time);
68 sta->ampdu_mlme.tid_rx[tid] = NULL;
72 69
73 if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) {
74 kfree(sta->ampdu_mlme.tid_rx[tid]);
75 sta->ampdu_mlme.tid_rx[tid] = NULL;
76 }
77
78 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
79 spin_unlock_bh(&sta->lock); 70 spin_unlock_bh(&sta->lock);
80}
81
82void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
83 u16 initiator, u16 reason)
84{
85 struct sta_info *sta;
86
87 rcu_read_lock();
88
89 sta = sta_info_get(sdata, ra);
90 if (!sta) {
91 rcu_read_unlock();
92 return;
93 }
94
95 __ieee80211_stop_rx_ba_session(sta, tid, initiator, reason);
96 71
97 rcu_read_unlock(); 72 del_timer_sync(&tid_rx->session_timer);
73 kfree(tid_rx);
98} 74}
99 75
100/* 76/*
101 * After accepting the AddBA Request we activated a timer, 77 * After accepting the AddBA Request we activated a timer,
102 * resetting it after each frame that arrives from the originator. 78 * resetting it after each frame that arrives from the originator.
103 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
104 */ 79 */
105static void sta_rx_agg_session_timer_expired(unsigned long data) 80static void sta_rx_agg_session_timer_expired(unsigned long data)
106{ 81{
@@ -116,9 +91,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
116#ifdef CONFIG_MAC80211_HT_DEBUG 91#ifdef CONFIG_MAC80211_HT_DEBUG
117 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); 92 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
118#endif 93#endif
119 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, 94 __ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT,
120 (u16)*ptid, WLAN_BACK_TIMER, 95 WLAN_REASON_QSTA_TIMEOUT);
121 WLAN_REASON_QSTA_TIMEOUT);
122} 96}
123 97
124static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, 98static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
@@ -193,7 +167,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
193 167
194 status = WLAN_STATUS_REQUEST_DECLINED; 168 status = WLAN_STATUS_REQUEST_DECLINED;
195 169
196 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 170 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
197#ifdef CONFIG_MAC80211_HT_DEBUG 171#ifdef CONFIG_MAC80211_HT_DEBUG
198 printk(KERN_DEBUG "Suspend in progress. " 172 printk(KERN_DEBUG "Suspend in progress. "
199 "Denying ADDBA request\n"); 173 "Denying ADDBA request\n");
@@ -231,7 +205,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
231 /* examine state machine */ 205 /* examine state machine */
232 spin_lock_bh(&sta->lock); 206 spin_lock_bh(&sta->lock);
233 207
234 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { 208 if (sta->ampdu_mlme.tid_active_rx[tid]) {
235#ifdef CONFIG_MAC80211_HT_DEBUG 209#ifdef CONFIG_MAC80211_HT_DEBUG
236 if (net_ratelimit()) 210 if (net_ratelimit())
237 printk(KERN_DEBUG "unexpected AddBA Req from " 211 printk(KERN_DEBUG "unexpected AddBA Req from "
@@ -293,7 +267,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
293 } 267 }
294 268
295 /* change state and send addba resp */ 269 /* change state and send addba resp */
296 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL; 270 sta->ampdu_mlme.tid_active_rx[tid] = true;
297 tid_agg_rx->dialog_token = dialog_token; 271 tid_agg_rx->dialog_token = dialog_token;
298 tid_agg_rx->ssn = start_seq_num; 272 tid_agg_rx->ssn = start_seq_num;
299 tid_agg_rx->head_seq_num = start_seq_num; 273 tid_agg_rx->head_seq_num = start_seq_num;
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 5538e1b4a697..32d2148b5b98 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -245,7 +245,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
245 return -EINVAL; 245 return -EINVAL;
246 } 246 }
247 247
248 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 248 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
249#ifdef CONFIG_MAC80211_HT_DEBUG 249#ifdef CONFIG_MAC80211_HT_DEBUG
250 printk(KERN_DEBUG "Suspend in progress. " 250 printk(KERN_DEBUG "Suspend in progress. "
251 "Denying BA session request\n"); 251 "Denying BA session request\n");
@@ -414,7 +414,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
414 struct sta_info *sta, u16 tid) 414 struct sta_info *sta, u16 tid)
415{ 415{
416#ifdef CONFIG_MAC80211_HT_DEBUG 416#ifdef CONFIG_MAC80211_HT_DEBUG
417 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); 417 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid);
418#endif 418#endif
419 419
420 spin_lock(&local->ampdu_lock); 420 spin_lock(&local->ampdu_lock);
@@ -674,7 +674,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
674 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 674 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
675 675
676#ifdef CONFIG_MAC80211_HT_DEBUG 676#ifdef CONFIG_MAC80211_HT_DEBUG
677 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 677 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
678#endif /* CONFIG_MAC80211_HT_DEBUG */ 678#endif /* CONFIG_MAC80211_HT_DEBUG */
679 679
680 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 680 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b7116ef84a3b..4edd73cbf052 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1136,6 +1136,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1136 return -EINVAL; 1136 return -EINVAL;
1137 } 1137 }
1138 1138
1139 /* enable WMM or activate new settings */
1140 local->hw.conf.flags |= IEEE80211_CONF_QOS;
1141 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
1142
1139 return 0; 1143 return 0;
1140} 1144}
1141 1145
@@ -1402,6 +1406,35 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1402 return 0; 1406 return 0;
1403} 1407}
1404 1408
1409static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
1410 struct net_device *dev,
1411 s32 rssi_thold, u32 rssi_hyst)
1412{
1413 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1414 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1415 struct ieee80211_vif *vif = &sdata->vif;
1416 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1417
1418 if (rssi_thold == bss_conf->cqm_rssi_thold &&
1419 rssi_hyst == bss_conf->cqm_rssi_hyst)
1420 return 0;
1421
1422 bss_conf->cqm_rssi_thold = rssi_thold;
1423 bss_conf->cqm_rssi_hyst = rssi_hyst;
1424
1425 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
1426 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1427 return -EOPNOTSUPP;
1428 return 0;
1429 }
1430
1431 /* tell the driver upon association, unless already associated */
1432 if (sdata->u.mgd.associated)
1433 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
1434
1435 return 0;
1436}
1437
1405static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, 1438static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1406 struct net_device *dev, 1439 struct net_device *dev,
1407 const u8 *addr, 1440 const u8 *addr,
@@ -1506,4 +1539,5 @@ struct cfg80211_ops mac80211_config_ops = {
1506 .remain_on_channel = ieee80211_remain_on_channel, 1539 .remain_on_channel = ieee80211_remain_on_channel,
1507 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, 1540 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1508 .action = ieee80211_action, 1541 .action = ieee80211_action,
1542 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
1509}; 1543};
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index b4ddb2f83914..623e6644b80c 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -99,6 +99,14 @@ static ssize_t ieee80211_if_fmt_##name( \
99 return scnprintf(buf, buflen, "%pM\n", sdata->field); \ 99 return scnprintf(buf, buflen, "%pM\n", sdata->field); \
100} 100}
101 101
102#define IEEE80211_IF_FMT_DEC_DIV_16(name, field) \
103static ssize_t ieee80211_if_fmt_##name( \
104 const struct ieee80211_sub_if_data *sdata, \
105 char *buf, int buflen) \
106{ \
107 return scnprintf(buf, buflen, "%d\n", sdata->field / 16); \
108}
109
102#define __IEEE80211_IF_FILE(name, _write) \ 110#define __IEEE80211_IF_FILE(name, _write) \
103static ssize_t ieee80211_if_read_##name(struct file *file, \ 111static ssize_t ieee80211_if_read_##name(struct file *file, \
104 char __user *userbuf, \ 112 char __user *userbuf, \
@@ -139,6 +147,8 @@ IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
139/* STA attributes */ 147/* STA attributes */
140IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 148IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
141IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); 149IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
150IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC);
151IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16);
142 152
143static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, 153static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
144 enum ieee80211_smps_mode smps_mode) 154 enum ieee80211_smps_mode smps_mode)
@@ -275,6 +285,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
275 285
276 DEBUGFS_ADD(bssid); 286 DEBUGFS_ADD(bssid);
277 DEBUGFS_ADD(aid); 287 DEBUGFS_ADD(aid);
288 DEBUGFS_ADD(last_beacon);
289 DEBUGFS_ADD(ave_beacon);
278 DEBUGFS_ADD_MODE(smps, 0600); 290 DEBUGFS_ADD_MODE(smps, 0600);
279} 291}
280 292
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index d92800bb2d2f..740ff6c5b92c 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -57,7 +57,6 @@ STA_FILE(tx_filtered, tx_filtered_count, LU);
57STA_FILE(tx_retry_failed, tx_retry_failed, LU); 57STA_FILE(tx_retry_failed, tx_retry_failed, LU);
58STA_FILE(tx_retry_count, tx_retry_count, LU); 58STA_FILE(tx_retry_count, tx_retry_count, LU);
59STA_FILE(last_signal, last_signal, D); 59STA_FILE(last_signal, last_signal, D);
60STA_FILE(last_noise, last_noise, D);
61STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); 60STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU);
62 61
63static ssize_t sta_flags_read(struct file *file, char __user *userbuf, 62static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
@@ -120,7 +119,7 @@ STA_OPS(last_seq_ctrl);
120static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, 119static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
121 size_t count, loff_t *ppos) 120 size_t count, loff_t *ppos)
122{ 121{
123 char buf[64 + STA_TID_NUM * 40], *p = buf; 122 char buf[71 + STA_TID_NUM * 40], *p = buf;
124 int i; 123 int i;
125 struct sta_info *sta = file->private_data; 124 struct sta_info *sta = file->private_data;
126 125
@@ -128,16 +127,16 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
128 p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n", 127 p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
129 sta->ampdu_mlme.dialog_token_allocator + 1); 128 sta->ampdu_mlme.dialog_token_allocator + 1);
130 p += scnprintf(p, sizeof(buf) + buf - p, 129 p += scnprintf(p, sizeof(buf) + buf - p,
131 "TID\t\tRX\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n"); 130 "TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n");
132 for (i = 0; i < STA_TID_NUM; i++) { 131 for (i = 0; i < STA_TID_NUM; i++) {
133 p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i); 132 p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
134 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", 133 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
135 sta->ampdu_mlme.tid_state_rx[i]); 134 sta->ampdu_mlme.tid_active_rx[i]);
136 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x", 135 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
137 sta->ampdu_mlme.tid_state_rx[i] ? 136 sta->ampdu_mlme.tid_active_rx[i] ?
138 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0); 137 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
139 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x", 138 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
140 sta->ampdu_mlme.tid_state_rx[i] ? 139 sta->ampdu_mlme.tid_active_rx[i] ?
141 sta->ampdu_mlme.tid_rx[i]->ssn : 0); 140 sta->ampdu_mlme.tid_rx[i]->ssn : 0);
142 141
143 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", 142 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
@@ -289,7 +288,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
289 DEBUGFS_ADD(tx_retry_failed); 288 DEBUGFS_ADD(tx_retry_failed);
290 DEBUGFS_ADD(tx_retry_count); 289 DEBUGFS_ADD(tx_retry_count);
291 DEBUGFS_ADD(last_signal); 290 DEBUGFS_ADD(last_signal);
292 DEBUGFS_ADD(last_noise);
293 DEBUGFS_ADD(wep_weak_iv_count); 291 DEBUGFS_ADD(wep_weak_iv_count);
294 DEBUGFS_ADD(ht_capa); 292 DEBUGFS_ADD(ht_capa);
295} 293}
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index bb677a73b7c9..2ab106a0a491 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -175,8 +175,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
175#endif /* CONFIG_MAC80211_HT_DEBUG */ 175#endif /* CONFIG_MAC80211_HT_DEBUG */
176 176
177 if (initiator == WLAN_BACK_INITIATOR) 177 if (initiator == WLAN_BACK_INITIATOR)
178 ieee80211_sta_stop_rx_ba_session(sdata, sta->sta.addr, tid, 178 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0);
179 WLAN_BACK_INITIATOR, 0);
180 else { /* WLAN_BACK_RECIPIENT */ 179 else { /* WLAN_BACK_RECIPIENT */
181 spin_lock_bh(&sta->lock); 180 spin_lock_bh(&sta->lock);
182 if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK) 181 if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f3e942486749..01974c2510a8 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -264,17 +264,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
264 sta->sta.supp_rates[band] = supp_rates | 264 sta->sta.supp_rates[band] = supp_rates |
265 ieee80211_mandatory_rates(local, band); 265 ieee80211_mandatory_rates(local, band);
266 266
267 if (sta->sta.supp_rates[band] != prev_rates) {
267#ifdef CONFIG_MAC80211_IBSS_DEBUG 268#ifdef CONFIG_MAC80211_IBSS_DEBUG
268 if (sta->sta.supp_rates[band] != prev_rates)
269 printk(KERN_DEBUG "%s: updated supp_rates set " 269 printk(KERN_DEBUG "%s: updated supp_rates set "
270 "for %pM based on beacon info (0x%llx | " 270 "for %pM based on beacon/probe_response "
271 "0x%llx -> 0x%llx)\n", 271 "(0x%x -> 0x%x)\n",
272 sdata->name, 272 sdata->name, sta->sta.addr,
273 sta->sta.addr, 273 prev_rates, sta->sta.supp_rates[band]);
274 (unsigned long long) prev_rates,
275 (unsigned long long) supp_rates,
276 (unsigned long long) sta->sta.supp_rates[band]);
277#endif 274#endif
275 rate_control_rate_init(sta);
276 }
278 rcu_read_unlock(); 277 rcu_read_unlock();
279 } else { 278 } else {
280 rcu_read_unlock(); 279 rcu_read_unlock();
@@ -370,6 +369,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
370 sdata->name, mgmt->bssid); 369 sdata->name, mgmt->bssid);
371#endif 370#endif
372 ieee80211_sta_join_ibss(sdata, bss); 371 ieee80211_sta_join_ibss(sdata, bss);
372 supp_rates = ieee80211_sta_get_rates(local, elems, band);
373 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 373 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
374 supp_rates, GFP_KERNEL); 374 supp_rates, GFP_KERNEL);
375 } 375 }
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 241533e1bc03..4e73660ebe99 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -317,6 +317,7 @@ enum ieee80211_sta_flags {
317 IEEE80211_STA_MFP_ENABLED = BIT(6), 317 IEEE80211_STA_MFP_ENABLED = BIT(6),
318 IEEE80211_STA_UAPSD_ENABLED = BIT(7), 318 IEEE80211_STA_UAPSD_ENABLED = BIT(7),
319 IEEE80211_STA_NULLFUNC_ACKED = BIT(8), 319 IEEE80211_STA_NULLFUNC_ACKED = BIT(8),
320 IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
320}; 321};
321 322
322struct ieee80211_if_managed { 323struct ieee80211_if_managed {
@@ -327,7 +328,7 @@ struct ieee80211_if_managed {
327 struct work_struct work; 328 struct work_struct work;
328 struct work_struct monitor_work; 329 struct work_struct monitor_work;
329 struct work_struct chswitch_work; 330 struct work_struct chswitch_work;
330 struct work_struct beacon_loss_work; 331 struct work_struct beacon_connection_loss_work;
331 332
332 unsigned long probe_timeout; 333 unsigned long probe_timeout;
333 int probe_send_count; 334 int probe_send_count;
@@ -359,6 +360,24 @@ struct ieee80211_if_managed {
359 int wmm_last_param_set; 360 int wmm_last_param_set;
360 361
361 u8 use_4addr; 362 u8 use_4addr;
363
364 /* Signal strength from the last Beacon frame in the current BSS. */
365 int last_beacon_signal;
366
367 /*
368 * Weighted average of the signal strength from Beacon frames in the
369 * current BSS. This is in units of 1/16 of the signal unit to maintain
370 * accuracy and to speed up calculations, i.e., the value need to be
371 * divided by 16 to get the actual value.
372 */
373 int ave_beacon_signal;
374
375 /*
376 * Last Beacon frame signal strength average (ave_beacon_signal / 16)
377 * that triggered a cqm event. 0 indicates that no event has been
378 * generated for the current association.
379 */
380 int last_cqm_event_signal;
362}; 381};
363 382
364enum ieee80211_ibss_request { 383enum ieee80211_ibss_request {
@@ -745,6 +764,7 @@ struct ieee80211_local {
745 int scan_channel_idx; 764 int scan_channel_idx;
746 int scan_ies_len; 765 int scan_ies_len;
747 766
767 unsigned long leave_oper_channel_time;
748 enum mac80211_scan_state next_scan_state; 768 enum mac80211_scan_state next_scan_state;
749 struct delayed_work scan_work; 769 struct delayed_work scan_work;
750 struct ieee80211_sub_if_data *scan_sdata; 770 struct ieee80211_sub_if_data *scan_sdata;
@@ -1078,8 +1098,6 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
1078 enum ieee80211_smps_mode smps, const u8 *da, 1098 enum ieee80211_smps_mode smps, const u8 *da,
1079 const u8 *bssid); 1099 const u8 *bssid);
1080 1100
1081void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
1082 u16 tid, u16 initiator, u16 reason);
1083void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 1101void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1084 u16 initiator, u16 reason); 1102 u16 initiator, u16 reason);
1085void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); 1103void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta);
@@ -1155,7 +1173,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
1155 int powersave); 1173 int powersave);
1156void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1174void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1157 struct ieee80211_hdr *hdr); 1175 struct ieee80211_hdr *hdr);
1158void ieee80211_beacon_loss_work(struct work_struct *work); 1176void ieee80211_beacon_connection_loss_work(struct work_struct *work);
1159 1177
1160void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1178void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1161 enum queue_stop_reason reason); 1179 enum queue_stop_reason reason);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0793d7a8d743..b4ec59a8dc03 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -486,7 +486,7 @@ static int ieee80211_stop(struct net_device *dev)
486 cancel_work_sync(&sdata->u.mgd.work); 486 cancel_work_sync(&sdata->u.mgd.work);
487 cancel_work_sync(&sdata->u.mgd.chswitch_work); 487 cancel_work_sync(&sdata->u.mgd.chswitch_work);
488 cancel_work_sync(&sdata->u.mgd.monitor_work); 488 cancel_work_sync(&sdata->u.mgd.monitor_work);
489 cancel_work_sync(&sdata->u.mgd.beacon_loss_work); 489 cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work);
490 490
491 /* 491 /*
492 * When we get here, the interface is marked down. 492 * When we get here, the interface is marked down.
@@ -815,6 +815,118 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
815 return 0; 815 return 0;
816} 816}
817 817
818static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
819 struct net_device *dev,
820 enum nl80211_iftype type)
821{
822 struct ieee80211_sub_if_data *sdata;
823 u64 mask, start, addr, val, inc;
824 u8 *m;
825 u8 tmp_addr[ETH_ALEN];
826 int i;
827
828 /* default ... something at least */
829 memcpy(dev->perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
830
831 if (is_zero_ether_addr(local->hw.wiphy->addr_mask) &&
832 local->hw.wiphy->n_addresses <= 1)
833 return;
834
835
836 mutex_lock(&local->iflist_mtx);
837
838 switch (type) {
839 case NL80211_IFTYPE_MONITOR:
840 /* doesn't matter */
841 break;
842 case NL80211_IFTYPE_WDS:
843 case NL80211_IFTYPE_AP_VLAN:
844 /* match up with an AP interface */
845 list_for_each_entry(sdata, &local->interfaces, list) {
846 if (sdata->vif.type != NL80211_IFTYPE_AP)
847 continue;
848 memcpy(dev->perm_addr, sdata->vif.addr, ETH_ALEN);
849 break;
850 }
851 /* keep default if no AP interface present */
852 break;
853 default:
854 /* assign a new address if possible -- try n_addresses first */
855 for (i = 0; i < local->hw.wiphy->n_addresses; i++) {
856 bool used = false;
857
858 list_for_each_entry(sdata, &local->interfaces, list) {
859 if (memcmp(local->hw.wiphy->addresses[i].addr,
860 sdata->vif.addr, ETH_ALEN) == 0) {
861 used = true;
862 break;
863 }
864 }
865
866 if (!used) {
867 memcpy(dev->perm_addr,
868 local->hw.wiphy->addresses[i].addr,
869 ETH_ALEN);
870 break;
871 }
872 }
873
874 /* try mask if available */
875 if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
876 break;
877
878 m = local->hw.wiphy->addr_mask;
879 mask = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
880 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
881 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
882
883 if (__ffs64(mask) + hweight64(mask) != fls64(mask)) {
884 /* not a contiguous mask ... not handled now! */
885 printk(KERN_DEBUG "not contiguous\n");
886 break;
887 }
888
889 m = local->hw.wiphy->perm_addr;
890 start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
891 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
892 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
893
894 inc = 1ULL<<__ffs64(mask);
895 val = (start & mask);
896 addr = (start & ~mask) | (val & mask);
897 do {
898 bool used = false;
899
900 tmp_addr[5] = addr >> 0*8;
901 tmp_addr[4] = addr >> 1*8;
902 tmp_addr[3] = addr >> 2*8;
903 tmp_addr[2] = addr >> 3*8;
904 tmp_addr[1] = addr >> 4*8;
905 tmp_addr[0] = addr >> 5*8;
906
907 val += inc;
908
909 list_for_each_entry(sdata, &local->interfaces, list) {
910 if (memcmp(tmp_addr, sdata->vif.addr,
911 ETH_ALEN) == 0) {
912 used = true;
913 break;
914 }
915 }
916
917 if (!used) {
918 memcpy(dev->perm_addr, tmp_addr, ETH_ALEN);
919 break;
920 }
921 addr = (start & ~mask) | (val & mask);
922 } while (addr != start);
923
924 break;
925 }
926
927 mutex_unlock(&local->iflist_mtx);
928}
929
818int ieee80211_if_add(struct ieee80211_local *local, const char *name, 930int ieee80211_if_add(struct ieee80211_local *local, const char *name,
819 struct net_device **new_dev, enum nl80211_iftype type, 931 struct net_device **new_dev, enum nl80211_iftype type,
820 struct vif_params *params) 932 struct vif_params *params)
@@ -844,8 +956,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
844 if (ret < 0) 956 if (ret < 0)
845 goto fail; 957 goto fail;
846 958
847 memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); 959 ieee80211_assign_perm_addr(local, ndev, type);
848 memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN); 960 memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
849 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 961 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
850 962
851 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ 963 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index be5f723d643a..461167dfa42c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -46,6 +46,13 @@
46 */ 46 */
47#define IEEE80211_PROBE_WAIT (HZ / 2) 47#define IEEE80211_PROBE_WAIT (HZ / 2)
48 48
49/*
50 * Weight given to the latest Beacon frame when calculating average signal
51 * strength for Beacon frames received in the current BSS. This must be
52 * between 1 and 15.
53 */
54#define IEEE80211_SIGNAL_AVE_WEIGHT 3
55
49#define TMR_RUNNING_TIMER 0 56#define TMR_RUNNING_TIMER 0
50#define TMR_RUNNING_CHANSW 1 57#define TMR_RUNNING_CHANSW 1
51 58
@@ -203,7 +210,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
203 210
204static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 211static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
205 const u8 *bssid, u16 stype, u16 reason, 212 const u8 *bssid, u16 stype, u16 reason,
206 void *cookie) 213 void *cookie, bool send_frame)
207{ 214{
208 struct ieee80211_local *local = sdata->local; 215 struct ieee80211_local *local = sdata->local;
209 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 216 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -240,7 +247,11 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
240 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); 247 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
241 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) 248 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
242 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 249 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
243 ieee80211_tx_skb(sdata, skb); 250
251 if (send_frame)
252 ieee80211_tx_skb(sdata, skb);
253 else
254 kfree_skb(skb);
244} 255}
245 256
246void ieee80211_send_pspoll(struct ieee80211_local *local, 257void ieee80211_send_pspoll(struct ieee80211_local *local,
@@ -589,6 +600,9 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
589 int count; 600 int count;
590 u8 *pos, uapsd_queues = 0; 601 u8 *pos, uapsd_queues = 0;
591 602
603 if (!local->ops->conf_tx)
604 return;
605
592 if (local->hw.queues < 4) 606 if (local->hw.queues < 4)
593 return; 607 return;
594 608
@@ -663,11 +677,15 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
663 params.aifs, params.cw_min, params.cw_max, params.txop, 677 params.aifs, params.cw_min, params.cw_max, params.txop,
664 params.uapsd); 678 params.uapsd);
665#endif 679#endif
666 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx) 680 if (drv_conf_tx(local, queue, &params))
667 printk(KERN_DEBUG "%s: failed to set TX queue " 681 printk(KERN_DEBUG "%s: failed to set TX queue "
668 "parameters for queue %d\n", 682 "parameters for queue %d\n",
669 wiphy_name(local->hw.wiphy), queue); 683 wiphy_name(local->hw.wiphy), queue);
670 } 684 }
685
686 /* enable WMM or activate new settings */
687 local->hw.conf.flags |= IEEE80211_CONF_QOS;
688 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
671} 689}
672 690
673static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 691static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
@@ -728,6 +746,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
728 sdata->u.mgd.associated = cbss; 746 sdata->u.mgd.associated = cbss;
729 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); 747 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
730 748
749 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
750
731 /* just to be sure */ 751 /* just to be sure */
732 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 752 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
733 IEEE80211_STA_BEACON_POLL); 753 IEEE80211_STA_BEACON_POLL);
@@ -753,6 +773,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
753 /* And the BSSID changed - we're associated now */ 773 /* And the BSSID changed - we're associated now */
754 bss_info_changed |= BSS_CHANGED_BSSID; 774 bss_info_changed |= BSS_CHANGED_BSSID;
755 775
776 /* Tell the driver to monitor connection quality (if supported) */
777 if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
778 sdata->vif.bss_conf.cqm_rssi_thold)
779 bss_info_changed |= BSS_CHANGED_CQM;
780
756 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 781 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
757 782
758 mutex_lock(&local->iflist_mtx); 783 mutex_lock(&local->iflist_mtx);
@@ -764,7 +789,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
764 netif_carrier_on(sdata->dev); 789 netif_carrier_on(sdata->dev);
765} 790}
766 791
767static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata) 792static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
793 bool remove_sta)
768{ 794{
769 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 795 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
770 struct ieee80211_local *local = sdata->local; 796 struct ieee80211_local *local = sdata->local;
@@ -837,7 +863,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
837 changed |= BSS_CHANGED_BSSID; 863 changed |= BSS_CHANGED_BSSID;
838 ieee80211_bss_info_change_notify(sdata, changed); 864 ieee80211_bss_info_change_notify(sdata, changed);
839 865
840 sta_info_destroy_addr(sdata, bssid); 866 if (remove_sta)
867 sta_info_destroy_addr(sdata, bssid);
841} 868}
842 869
843void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 870void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -854,6 +881,9 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
854 if (is_multicast_ether_addr(hdr->addr1)) 881 if (is_multicast_ether_addr(hdr->addr1))
855 return; 882 return;
856 883
884 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
885 return;
886
857 mod_timer(&sdata->u.mgd.conn_mon_timer, 887 mod_timer(&sdata->u.mgd.conn_mon_timer,
858 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); 888 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
859} 889}
@@ -931,23 +961,68 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
931 mutex_unlock(&ifmgd->mtx); 961 mutex_unlock(&ifmgd->mtx);
932} 962}
933 963
934void ieee80211_beacon_loss_work(struct work_struct *work) 964static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
965{
966 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
967 struct ieee80211_local *local = sdata->local;
968 u8 bssid[ETH_ALEN];
969
970 mutex_lock(&ifmgd->mtx);
971 if (!ifmgd->associated) {
972 mutex_unlock(&ifmgd->mtx);
973 return;
974 }
975
976 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
977
978 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
979
980 ieee80211_set_disassoc(sdata, true);
981 ieee80211_recalc_idle(local);
982 mutex_unlock(&ifmgd->mtx);
983 /*
984 * must be outside lock due to cfg80211,
985 * but that's not a problem.
986 */
987 ieee80211_send_deauth_disassoc(sdata, bssid,
988 IEEE80211_STYPE_DEAUTH,
989 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
990 NULL, true);
991}
992
993void ieee80211_beacon_connection_loss_work(struct work_struct *work)
935{ 994{
936 struct ieee80211_sub_if_data *sdata = 995 struct ieee80211_sub_if_data *sdata =
937 container_of(work, struct ieee80211_sub_if_data, 996 container_of(work, struct ieee80211_sub_if_data,
938 u.mgd.beacon_loss_work); 997 u.mgd.beacon_connection_loss_work);
939 998
940 ieee80211_mgd_probe_ap(sdata, true); 999 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
1000 __ieee80211_connection_loss(sdata);
1001 else
1002 ieee80211_mgd_probe_ap(sdata, true);
941} 1003}
942 1004
943void ieee80211_beacon_loss(struct ieee80211_vif *vif) 1005void ieee80211_beacon_loss(struct ieee80211_vif *vif)
944{ 1006{
945 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1007 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1008 struct ieee80211_hw *hw = &sdata->local->hw;
946 1009
947 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); 1010 WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR);
1011 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
948} 1012}
949EXPORT_SYMBOL(ieee80211_beacon_loss); 1013EXPORT_SYMBOL(ieee80211_beacon_loss);
950 1014
1015void ieee80211_connection_loss(struct ieee80211_vif *vif)
1016{
1017 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1018 struct ieee80211_hw *hw = &sdata->local->hw;
1019
1020 WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR));
1021 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
1022}
1023EXPORT_SYMBOL(ieee80211_connection_loss);
1024
1025
951static enum rx_mgmt_action __must_check 1026static enum rx_mgmt_action __must_check
952ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 1027ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
953 struct ieee80211_mgmt *mgmt, size_t len) 1028 struct ieee80211_mgmt *mgmt, size_t len)
@@ -968,7 +1043,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
968 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 1043 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
969 sdata->name, bssid, reason_code); 1044 sdata->name, bssid, reason_code);
970 1045
971 ieee80211_set_disassoc(sdata); 1046 ieee80211_set_disassoc(sdata, true);
972 ieee80211_recalc_idle(sdata->local); 1047 ieee80211_recalc_idle(sdata->local);
973 1048
974 return RX_MGMT_CFG80211_DEAUTH; 1049 return RX_MGMT_CFG80211_DEAUTH;
@@ -998,7 +1073,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
998 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 1073 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
999 sdata->name, mgmt->sa, reason_code); 1074 sdata->name, mgmt->sa, reason_code);
1000 1075
1001 ieee80211_set_disassoc(sdata); 1076 ieee80211_set_disassoc(sdata, true);
1002 ieee80211_recalc_idle(sdata->local); 1077 ieee80211_recalc_idle(sdata->local);
1003 return RX_MGMT_CFG80211_DISASSOC; 1078 return RX_MGMT_CFG80211_DISASSOC;
1004} 1079}
@@ -1290,6 +1365,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1290 struct ieee80211_rx_status *rx_status) 1365 struct ieee80211_rx_status *rx_status)
1291{ 1366{
1292 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1367 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1368 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1293 size_t baselen; 1369 size_t baselen;
1294 struct ieee802_11_elems elems; 1370 struct ieee802_11_elems elems;
1295 struct ieee80211_local *local = sdata->local; 1371 struct ieee80211_local *local = sdata->local;
@@ -1325,6 +1401,41 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1325 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) 1401 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
1326 return; 1402 return;
1327 1403
1404 /* Track average RSSI from the Beacon frames of the current AP */
1405 ifmgd->last_beacon_signal = rx_status->signal;
1406 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
1407 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
1408 ifmgd->ave_beacon_signal = rx_status->signal;
1409 ifmgd->last_cqm_event_signal = 0;
1410 } else {
1411 ifmgd->ave_beacon_signal =
1412 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
1413 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
1414 ifmgd->ave_beacon_signal) / 16;
1415 }
1416 if (bss_conf->cqm_rssi_thold &&
1417 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
1418 int sig = ifmgd->ave_beacon_signal / 16;
1419 int last_event = ifmgd->last_cqm_event_signal;
1420 int thold = bss_conf->cqm_rssi_thold;
1421 int hyst = bss_conf->cqm_rssi_hyst;
1422 if (sig < thold &&
1423 (last_event == 0 || sig < last_event - hyst)) {
1424 ifmgd->last_cqm_event_signal = sig;
1425 ieee80211_cqm_rssi_notify(
1426 &sdata->vif,
1427 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
1428 GFP_KERNEL);
1429 } else if (sig > thold &&
1430 (last_event == 0 || sig > last_event + hyst)) {
1431 ifmgd->last_cqm_event_signal = sig;
1432 ieee80211_cqm_rssi_notify(
1433 &sdata->vif,
1434 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
1435 GFP_KERNEL);
1436 }
1437 }
1438
1328 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { 1439 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
1329#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1440#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1330 if (net_ratelimit()) { 1441 if (net_ratelimit()) {
@@ -1610,7 +1721,7 @@ static void ieee80211_sta_work(struct work_struct *work)
1610 printk(KERN_DEBUG "No probe response from AP %pM" 1721 printk(KERN_DEBUG "No probe response from AP %pM"
1611 " after %dms, disconnecting.\n", 1722 " after %dms, disconnecting.\n",
1612 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1723 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1613 ieee80211_set_disassoc(sdata); 1724 ieee80211_set_disassoc(sdata, true);
1614 ieee80211_recalc_idle(local); 1725 ieee80211_recalc_idle(local);
1615 mutex_unlock(&ifmgd->mtx); 1726 mutex_unlock(&ifmgd->mtx);
1616 /* 1727 /*
@@ -1620,7 +1731,7 @@ static void ieee80211_sta_work(struct work_struct *work)
1620 ieee80211_send_deauth_disassoc(sdata, bssid, 1731 ieee80211_send_deauth_disassoc(sdata, bssid,
1621 IEEE80211_STYPE_DEAUTH, 1732 IEEE80211_STYPE_DEAUTH,
1622 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, 1733 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
1623 NULL); 1734 NULL, true);
1624 mutex_lock(&ifmgd->mtx); 1735 mutex_lock(&ifmgd->mtx);
1625 } 1736 }
1626 } 1737 }
@@ -1637,7 +1748,8 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
1637 if (local->quiescing) 1748 if (local->quiescing)
1638 return; 1749 return;
1639 1750
1640 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); 1751 ieee80211_queue_work(&sdata->local->hw,
1752 &sdata->u.mgd.beacon_connection_loss_work);
1641} 1753}
1642 1754
1643static void ieee80211_sta_conn_mon_timer(unsigned long data) 1755static void ieee80211_sta_conn_mon_timer(unsigned long data)
@@ -1689,7 +1801,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
1689 */ 1801 */
1690 1802
1691 cancel_work_sync(&ifmgd->work); 1803 cancel_work_sync(&ifmgd->work);
1692 cancel_work_sync(&ifmgd->beacon_loss_work); 1804 cancel_work_sync(&ifmgd->beacon_connection_loss_work);
1693 if (del_timer_sync(&ifmgd->timer)) 1805 if (del_timer_sync(&ifmgd->timer))
1694 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); 1806 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
1695 1807
@@ -1723,7 +1835,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1723 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 1835 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
1724 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); 1836 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
1725 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 1837 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
1726 INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work); 1838 INIT_WORK(&ifmgd->beacon_connection_loss_work,
1839 ieee80211_beacon_connection_loss_work);
1727 setup_timer(&ifmgd->timer, ieee80211_sta_timer, 1840 setup_timer(&ifmgd->timer, ieee80211_sta_timer,
1728 (unsigned long) sdata); 1841 (unsigned long) sdata);
1729 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 1842 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
@@ -1802,6 +1915,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
1802 struct ieee80211_work *wk; 1915 struct ieee80211_work *wk;
1803 u16 auth_alg; 1916 u16 auth_alg;
1804 1917
1918 if (req->local_state_change)
1919 return 0; /* no need to update mac80211 state */
1920
1805 switch (req->auth_type) { 1921 switch (req->auth_type) {
1806 case NL80211_AUTHTYPE_OPEN_SYSTEM: 1922 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1807 auth_alg = WLAN_AUTH_OPEN; 1923 auth_alg = WLAN_AUTH_OPEN;
@@ -1910,7 +2026,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1910 } 2026 }
1911 2027
1912 /* Trying to reassociate - clear previous association state */ 2028 /* Trying to reassociate - clear previous association state */
1913 ieee80211_set_disassoc(sdata); 2029 ieee80211_set_disassoc(sdata, true);
1914 } 2030 }
1915 mutex_unlock(&ifmgd->mtx); 2031 mutex_unlock(&ifmgd->mtx);
1916 2032
@@ -2014,7 +2130,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2014 2130
2015 if (ifmgd->associated == req->bss) { 2131 if (ifmgd->associated == req->bss) {
2016 bssid = req->bss->bssid; 2132 bssid = req->bss->bssid;
2017 ieee80211_set_disassoc(sdata); 2133 ieee80211_set_disassoc(sdata, true);
2018 mutex_unlock(&ifmgd->mtx); 2134 mutex_unlock(&ifmgd->mtx);
2019 } else { 2135 } else {
2020 bool not_auth_yet = false; 2136 bool not_auth_yet = false;
@@ -2057,9 +2173,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2057 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", 2173 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2058 sdata->name, bssid, req->reason_code); 2174 sdata->name, bssid, req->reason_code);
2059 2175
2060 ieee80211_send_deauth_disassoc(sdata, bssid, 2176 ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
2061 IEEE80211_STYPE_DEAUTH, req->reason_code, 2177 req->reason_code, cookie,
2062 cookie); 2178 !req->local_state_change);
2063 2179
2064 ieee80211_recalc_idle(sdata->local); 2180 ieee80211_recalc_idle(sdata->local);
2065 2181
@@ -2071,6 +2187,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2071 void *cookie) 2187 void *cookie)
2072{ 2188{
2073 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2189 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2190 u8 bssid[ETH_ALEN];
2074 2191
2075 mutex_lock(&ifmgd->mtx); 2192 mutex_lock(&ifmgd->mtx);
2076 2193
@@ -2088,13 +2205,15 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2088 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", 2205 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
2089 sdata->name, req->bss->bssid, req->reason_code); 2206 sdata->name, req->bss->bssid, req->reason_code);
2090 2207
2091 ieee80211_set_disassoc(sdata); 2208 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2209 ieee80211_set_disassoc(sdata, false);
2092 2210
2093 mutex_unlock(&ifmgd->mtx); 2211 mutex_unlock(&ifmgd->mtx);
2094 2212
2095 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, 2213 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
2096 IEEE80211_STYPE_DISASSOC, req->reason_code, 2214 IEEE80211_STYPE_DISASSOC, req->reason_code,
2097 cookie); 2215 cookie, !req->local_state_change);
2216 sta_info_destroy_addr(sdata, bssid);
2098 2217
2099 ieee80211_recalc_idle(sdata->local); 2218 ieee80211_recalc_idle(sdata->local);
2100 2219
@@ -2135,3 +2254,13 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
2135 *cookie = (unsigned long) skb; 2254 *cookie = (unsigned long) skb;
2136 return 0; 2255 return 0;
2137} 2256}
2257
2258void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
2259 enum nl80211_cqm_rssi_threshold_event rssi_event,
2260 gfp_t gfp)
2261{
2262 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2263
2264 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp);
2265}
2266EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 0e64484e861c..75202b295a4e 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -46,7 +46,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
46 46
47 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 47 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
48 list_for_each_entry_rcu(sta, &local->sta_list, list) { 48 list_for_each_entry_rcu(sta, &local->sta_list, list) {
49 set_sta_flags(sta, WLAN_STA_SUSPEND); 49 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
50 ieee80211_sta_tear_down_BA_sessions(sta); 50 ieee80211_sta_tear_down_BA_sessions(sta);
51 } 51 }
52 } 52 }
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 6e5d68b4e427..4926d929fd9f 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -541,7 +541,7 @@ minstrel_free(void *priv)
541 kfree(priv); 541 kfree(priv);
542} 542}
543 543
544static struct rate_control_ops mac80211_minstrel = { 544struct rate_control_ops mac80211_minstrel = {
545 .name = "minstrel", 545 .name = "minstrel",
546 .tx_status = minstrel_tx_status, 546 .tx_status = minstrel_tx_status,
547 .get_rate = minstrel_get_rate, 547 .get_rate = minstrel_get_rate,
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 38bf4168fc3a..0f5a83370aa6 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -80,7 +80,18 @@ struct minstrel_priv {
80 unsigned int lookaround_rate_mrr; 80 unsigned int lookaround_rate_mrr;
81}; 81};
82 82
83struct minstrel_debugfs_info {
84 size_t len;
85 char buf[];
86};
87
88extern struct rate_control_ops mac80211_minstrel;
83void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); 89void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
84void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); 90void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
85 91
92/* debugfs */
93int minstrel_stats_open(struct inode *inode, struct file *file);
94ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos);
95int minstrel_stats_release(struct inode *inode, struct file *file);
96
86#endif 97#endif
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index a715d9454f64..56d0f24957d9 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -52,21 +52,15 @@
52#include <net/mac80211.h> 52#include <net/mac80211.h>
53#include "rc80211_minstrel.h" 53#include "rc80211_minstrel.h"
54 54
55struct minstrel_stats_info { 55int
56 struct minstrel_sta_info *mi;
57 char buf[4096];
58 size_t len;
59};
60
61static int
62minstrel_stats_open(struct inode *inode, struct file *file) 56minstrel_stats_open(struct inode *inode, struct file *file)
63{ 57{
64 struct minstrel_sta_info *mi = inode->i_private; 58 struct minstrel_sta_info *mi = inode->i_private;
65 struct minstrel_stats_info *ms; 59 struct minstrel_debugfs_info *ms;
66 unsigned int i, tp, prob, eprob; 60 unsigned int i, tp, prob, eprob;
67 char *p; 61 char *p;
68 62
69 ms = kmalloc(sizeof(*ms), GFP_KERNEL); 63 ms = kmalloc(sizeof(*ms) + 4096, GFP_KERNEL);
70 if (!ms) 64 if (!ms)
71 return -ENOMEM; 65 return -ENOMEM;
72 66
@@ -106,36 +100,19 @@ minstrel_stats_open(struct inode *inode, struct file *file)
106 return 0; 100 return 0;
107} 101}
108 102
109static ssize_t 103ssize_t
110minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *o) 104minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos)
111{ 105{
112 struct minstrel_stats_info *ms; 106 struct minstrel_debugfs_info *ms;
113 char *src;
114 107
115 ms = file->private_data; 108 ms = file->private_data;
116 src = ms->buf; 109 return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len);
117
118 len = min(len, ms->len);
119 if (len <= *o)
120 return 0;
121
122 src += *o;
123 len -= *o;
124 *o += len;
125
126 if (copy_to_user(buf, src, len))
127 return -EFAULT;
128
129 return len;
130} 110}
131 111
132static int 112int
133minstrel_stats_release(struct inode *inode, struct file *file) 113minstrel_stats_release(struct inode *inode, struct file *file)
134{ 114{
135 struct minstrel_stats_info *ms = file->private_data; 115 kfree(file->private_data);
136
137 kfree(ms);
138
139 return 0; 116 return 0;
140} 117}
141 118
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 13fcd2d17c6b..c0ad7e879a6e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -38,7 +38,7 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
38{ 38{
39 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { 39 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
40 if (likely(skb->len > FCS_LEN)) 40 if (likely(skb->len > FCS_LEN))
41 skb_trim(skb, skb->len - FCS_LEN); 41 __pskb_trim(skb, skb->len - FCS_LEN);
42 else { 42 else {
43 /* driver bug */ 43 /* driver bug */
44 WARN_ON(1); 44 WARN_ON(1);
@@ -178,14 +178,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
178 pos++; 178 pos++;
179 } 179 }
180 180
181 /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
182 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
183 *pos = status->noise;
184 rthdr->it_present |=
185 cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
186 pos++;
187 }
188
189 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ 181 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */
190 182
191 /* IEEE80211_RADIOTAP_ANTENNA */ 183 /* IEEE80211_RADIOTAP_ANTENNA */
@@ -235,6 +227,12 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
235 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 227 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
236 present_fcs_len = FCS_LEN; 228 present_fcs_len = FCS_LEN;
237 229
230 /* make sure hdr->frame_control is on the linear part */
231 if (!pskb_may_pull(origskb, 2)) {
232 dev_kfree_skb(origskb);
233 return NULL;
234 }
235
238 if (!local->monitors) { 236 if (!local->monitors) {
239 if (should_drop_frame(origskb, present_fcs_len)) { 237 if (should_drop_frame(origskb, present_fcs_len)) {
240 dev_kfree_skb(origskb); 238 dev_kfree_skb(origskb);
@@ -722,14 +720,16 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
722 720
723 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 721 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
724 722
725 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) 723 spin_lock(&sta->lock);
726 goto dont_reorder; 724
725 if (!sta->ampdu_mlme.tid_active_rx[tid])
726 goto dont_reorder_unlock;
727 727
728 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; 728 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
729 729
730 /* qos null data frames are excluded */ 730 /* qos null data frames are excluded */
731 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) 731 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
732 goto dont_reorder; 732 goto dont_reorder_unlock;
733 733
734 /* new, potentially un-ordered, ampdu frame - process it */ 734 /* new, potentially un-ordered, ampdu frame - process it */
735 735
@@ -741,15 +741,20 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
741 /* if this mpdu is fragmented - terminate rx aggregation session */ 741 /* if this mpdu is fragmented - terminate rx aggregation session */
742 sc = le16_to_cpu(hdr->seq_ctrl); 742 sc = le16_to_cpu(hdr->seq_ctrl);
743 if (sc & IEEE80211_SCTL_FRAG) { 743 if (sc & IEEE80211_SCTL_FRAG) {
744 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, 744 spin_unlock(&sta->lock);
745 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); 745 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
746 WLAN_REASON_QSTA_REQUIRE_SETUP);
746 dev_kfree_skb(skb); 747 dev_kfree_skb(skb);
747 return; 748 return;
748 } 749 }
749 750
750 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) 751 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) {
752 spin_unlock(&sta->lock);
751 return; 753 return;
754 }
752 755
756 dont_reorder_unlock:
757 spin_unlock(&sta->lock);
753 dont_reorder: 758 dont_reorder:
754 __skb_queue_tail(frames, skb); 759 __skb_queue_tail(frames, skb);
755} 760}
@@ -815,7 +820,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
815{ 820{
816 struct sk_buff *skb = rx->skb; 821 struct sk_buff *skb = rx->skb;
817 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 822 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
818 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 823 struct ieee80211_hdr *hdr;
819 int keyidx; 824 int keyidx;
820 int hdrlen; 825 int hdrlen;
821 ieee80211_rx_result result = RX_DROP_UNUSABLE; 826 ieee80211_rx_result result = RX_DROP_UNUSABLE;
@@ -856,6 +861,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
856 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 861 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
857 return RX_CONTINUE; 862 return RX_CONTINUE;
858 863
864 if (skb_linearize(rx->skb))
865 return RX_DROP_UNUSABLE;
866
867 hdr = (struct ieee80211_hdr *)skb->data;
868
859 /* start without a key */ 869 /* start without a key */
860 rx->key = NULL; 870 rx->key = NULL;
861 871
@@ -1077,7 +1087,6 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1077 sta->rx_fragments++; 1087 sta->rx_fragments++;
1078 sta->rx_bytes += rx->skb->len; 1088 sta->rx_bytes += rx->skb->len;
1079 sta->last_signal = status->signal; 1089 sta->last_signal = status->signal;
1080 sta->last_noise = status->noise;
1081 1090
1082 /* 1091 /*
1083 * Change STA power saving mode only at the end of a frame 1092 * Change STA power saving mode only at the end of a frame
@@ -1240,6 +1249,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1240 } 1249 }
1241 I802_DEBUG_INC(rx->local->rx_handlers_fragments); 1250 I802_DEBUG_INC(rx->local->rx_handlers_fragments);
1242 1251
1252 if (skb_linearize(rx->skb))
1253 return RX_DROP_UNUSABLE;
1254
1243 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; 1255 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
1244 1256
1245 if (frag == 0) { 1257 if (frag == 0) {
@@ -1405,21 +1417,24 @@ static int
1405ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) 1417ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1406{ 1418{
1407 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1419 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1420 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1408 __le16 fc = hdr->frame_control; 1421 __le16 fc = hdr->frame_control;
1409 int res;
1410 1422
1411 res = ieee80211_drop_unencrypted(rx, fc); 1423 /*
1412 if (unlikely(res)) 1424 * Pass through unencrypted frames if the hardware has
1413 return res; 1425 * decrypted them already.
1426 */
1427 if (status->flag & RX_FLAG_DECRYPTED)
1428 return 0;
1414 1429
1415 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { 1430 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
1416 if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1431 if (unlikely(!ieee80211_has_protected(fc) &&
1432 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1417 rx->key)) 1433 rx->key))
1418 return -EACCES; 1434 return -EACCES;
1419 /* BIP does not use Protected field, so need to check MMIE */ 1435 /* BIP does not use Protected field, so need to check MMIE */
1420 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1436 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1421 ieee80211_get_mmie_keyidx(rx->skb) < 0 && 1437 ieee80211_get_mmie_keyidx(rx->skb) < 0))
1422 rx->key))
1423 return -EACCES; 1438 return -EACCES;
1424 /* 1439 /*
1425 * When using MFP, Action frames are not allowed prior to 1440 * When using MFP, Action frames are not allowed prior to
@@ -1597,6 +1612,9 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1597 skb->dev = dev; 1612 skb->dev = dev;
1598 __skb_queue_head_init(&frame_list); 1613 __skb_queue_head_init(&frame_list);
1599 1614
1615 if (skb_linearize(skb))
1616 return RX_DROP_UNUSABLE;
1617
1600 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, 1618 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
1601 rx->sdata->vif.type, 1619 rx->sdata->vif.type,
1602 rx->local->hw.extra_tx_headroom); 1620 rx->local->hw.extra_tx_headroom);
@@ -1795,10 +1813,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1795 if (ieee80211_is_back_req(bar->frame_control)) { 1813 if (ieee80211_is_back_req(bar->frame_control)) {
1796 if (!rx->sta) 1814 if (!rx->sta)
1797 return RX_DROP_MONITOR; 1815 return RX_DROP_MONITOR;
1816 spin_lock(&rx->sta->lock);
1798 tid = le16_to_cpu(bar->control) >> 12; 1817 tid = le16_to_cpu(bar->control) >> 12;
1799 if (rx->sta->ampdu_mlme.tid_state_rx[tid] 1818 if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) {
1800 != HT_AGG_STATE_OPERATIONAL) 1819 spin_unlock(&rx->sta->lock);
1801 return RX_DROP_MONITOR; 1820 return RX_DROP_MONITOR;
1821 }
1802 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; 1822 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
1803 1823
1804 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; 1824 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
@@ -1812,6 +1832,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1812 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num, 1832 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
1813 frames); 1833 frames);
1814 kfree_skb(skb); 1834 kfree_skb(skb);
1835 spin_unlock(&rx->sta->lock);
1815 return RX_QUEUED; 1836 return RX_QUEUED;
1816 } 1837 }
1817 1838
@@ -2371,29 +2392,42 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2371 struct ieee80211_local *local = hw_to_local(hw); 2392 struct ieee80211_local *local = hw_to_local(hw);
2372 struct ieee80211_sub_if_data *sdata; 2393 struct ieee80211_sub_if_data *sdata;
2373 struct ieee80211_hdr *hdr; 2394 struct ieee80211_hdr *hdr;
2395 __le16 fc;
2374 struct ieee80211_rx_data rx; 2396 struct ieee80211_rx_data rx;
2375 int prepares; 2397 int prepares;
2376 struct ieee80211_sub_if_data *prev = NULL; 2398 struct ieee80211_sub_if_data *prev = NULL;
2377 struct sk_buff *skb_new; 2399 struct sk_buff *skb_new;
2378 struct sta_info *sta, *tmp; 2400 struct sta_info *sta, *tmp;
2379 bool found_sta = false; 2401 bool found_sta = false;
2402 int err = 0;
2380 2403
2381 hdr = (struct ieee80211_hdr *)skb->data; 2404 fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
2382 memset(&rx, 0, sizeof(rx)); 2405 memset(&rx, 0, sizeof(rx));
2383 rx.skb = skb; 2406 rx.skb = skb;
2384 rx.local = local; 2407 rx.local = local;
2385 2408
2386 if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) 2409 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
2387 local->dot11ReceivedFragmentCount++; 2410 local->dot11ReceivedFragmentCount++;
2388 2411
2389 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || 2412 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2390 test_bit(SCAN_OFF_CHANNEL, &local->scanning))) 2413 test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
2391 rx.flags |= IEEE80211_RX_IN_SCAN; 2414 rx.flags |= IEEE80211_RX_IN_SCAN;
2392 2415
2416 if (ieee80211_is_mgmt(fc))
2417 err = skb_linearize(skb);
2418 else
2419 err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
2420
2421 if (err) {
2422 dev_kfree_skb(skb);
2423 return;
2424 }
2425
2426 hdr = (struct ieee80211_hdr *)skb->data;
2393 ieee80211_parse_qos(&rx); 2427 ieee80211_parse_qos(&rx);
2394 ieee80211_verify_alignment(&rx); 2428 ieee80211_verify_alignment(&rx);
2395 2429
2396 if (ieee80211_is_data(hdr->frame_control)) { 2430 if (ieee80211_is_data(fc)) {
2397 for_each_sta_info(local, hdr->addr2, sta, tmp) { 2431 for_each_sta_info(local, hdr->addr2, sta, tmp) {
2398 rx.sta = sta; 2432 rx.sta = sta;
2399 found_sta = true; 2433 found_sta = true;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index b822dce97867..75a85978c3b3 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -14,6 +14,8 @@
14 14
15#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/pm_qos_params.h>
18#include <net/sch_generic.h>
17#include <net/mac80211.h> 19#include <net/mac80211.h>
18 20
19#include "ieee80211_i.h" 21#include "ieee80211_i.h"
@@ -321,6 +323,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
321 323
322 ieee80211_offchannel_stop_beaconing(local); 324 ieee80211_offchannel_stop_beaconing(local);
323 325
326 local->leave_oper_channel_time = 0;
324 local->next_scan_state = SCAN_DECISION; 327 local->next_scan_state = SCAN_DECISION;
325 local->scan_channel_idx = 0; 328 local->scan_channel_idx = 0;
326 329
@@ -425,11 +428,28 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
425 return rc; 428 return rc;
426} 429}
427 430
431static unsigned long
432ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
433{
434 /*
435 * TODO: channel switching also consumes quite some time,
436 * add that delay as well to get a better estimation
437 */
438 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
439 return IEEE80211_PASSIVE_CHANNEL_TIME;
440 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
441}
442
428static int ieee80211_scan_state_decision(struct ieee80211_local *local, 443static int ieee80211_scan_state_decision(struct ieee80211_local *local,
429 unsigned long *next_delay) 444 unsigned long *next_delay)
430{ 445{
431 bool associated = false; 446 bool associated = false;
447 bool tx_empty = true;
448 bool bad_latency;
449 bool listen_int_exceeded;
450 unsigned long min_beacon_int = 0;
432 struct ieee80211_sub_if_data *sdata; 451 struct ieee80211_sub_if_data *sdata;
452 struct ieee80211_channel *next_chan;
433 453
434 /* if no more bands/channels left, complete scan and advance to the idle state */ 454 /* if no more bands/channels left, complete scan and advance to the idle state */
435 if (local->scan_channel_idx >= local->scan_req->n_channels) { 455 if (local->scan_channel_idx >= local->scan_req->n_channels) {
@@ -437,7 +457,11 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
437 return 1; 457 return 1;
438 } 458 }
439 459
440 /* check if at least one STA interface is associated */ 460 /*
461 * check if at least one STA interface is associated,
462 * check if at least one STA interface has pending tx frames
463 * and grab the lowest used beacon interval
464 */
441 mutex_lock(&local->iflist_mtx); 465 mutex_lock(&local->iflist_mtx);
442 list_for_each_entry(sdata, &local->interfaces, list) { 466 list_for_each_entry(sdata, &local->interfaces, list) {
443 if (!ieee80211_sdata_running(sdata)) 467 if (!ieee80211_sdata_running(sdata))
@@ -446,7 +470,16 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
446 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 470 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
447 if (sdata->u.mgd.associated) { 471 if (sdata->u.mgd.associated) {
448 associated = true; 472 associated = true;
449 break; 473
474 if (sdata->vif.bss_conf.beacon_int <
475 min_beacon_int || min_beacon_int == 0)
476 min_beacon_int =
477 sdata->vif.bss_conf.beacon_int;
478
479 if (!qdisc_all_tx_empty(sdata->dev)) {
480 tx_empty = false;
481 break;
482 }
450 } 483 }
451 } 484 }
452 } 485 }
@@ -455,11 +488,34 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
455 if (local->scan_channel) { 488 if (local->scan_channel) {
456 /* 489 /*
457 * we're currently scanning a different channel, let's 490 * we're currently scanning a different channel, let's
458 * switch back to the operating channel now if at least 491 * see if we can scan another channel without interfering
459 * one interface is associated. Otherwise just scan the 492 * with the current traffic situation.
460 * next channel 493 *
494 * Since we don't know if the AP has pending frames for us
495 * we can only check for our tx queues and use the current
496 * pm_qos requirements for rx. Hence, if no tx traffic occurs
497 * at all we will scan as many channels in a row as the pm_qos
498 * latency allows us to. Additionally we also check for the
499 * currently negotiated listen interval to prevent losing
500 * frames unnecessarily.
501 *
502 * Otherwise switch back to the operating channel.
461 */ 503 */
462 if (associated) 504 next_chan = local->scan_req->channels[local->scan_channel_idx];
505
506 bad_latency = time_after(jiffies +
507 ieee80211_scan_get_channel_time(next_chan),
508 local->leave_oper_channel_time +
509 usecs_to_jiffies(pm_qos_requirement(PM_QOS_NETWORK_LATENCY)));
510
511 listen_int_exceeded = time_after(jiffies +
512 ieee80211_scan_get_channel_time(next_chan),
513 local->leave_oper_channel_time +
514 usecs_to_jiffies(min_beacon_int * 1024) *
515 local->hw.conf.listen_interval);
516
517 if (associated && ( !tx_empty || bad_latency ||
518 listen_int_exceeded))
463 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL; 519 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
464 else 520 else
465 local->next_scan_state = SCAN_SET_CHANNEL; 521 local->next_scan_state = SCAN_SET_CHANNEL;
@@ -491,6 +547,9 @@ static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *loca
491 else 547 else
492 *next_delay = HZ / 10; 548 *next_delay = HZ / 10;
493 549
550 /* remember when we left the operating channel */
551 local->leave_oper_channel_time = jiffies;
552
494 /* advance to the next channel to be scanned */ 553 /* advance to the next channel to be scanned */
495 local->next_scan_state = SCAN_SET_CHANNEL; 554 local->next_scan_state = SCAN_SET_CHANNEL;
496} 555}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index fb12cec4d333..4de987cbda1c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -250,9 +250,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
250 * enable session_timer's data differentiation. refer to 250 * enable session_timer's data differentiation. refer to
251 * sta_rx_agg_session_timer_expired for useage */ 251 * sta_rx_agg_session_timer_expired for useage */
252 sta->timer_to_tid[i] = i; 252 sta->timer_to_tid[i] = i;
253 /* rx */
254 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
255 sta->ampdu_mlme.tid_rx[i] = NULL;
256 /* tx */ 253 /* tx */
257 sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE; 254 sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE;
258 sta->ampdu_mlme.tid_tx[i] = NULL; 255 sta->ampdu_mlme.tid_tx[i] = NULL;
@@ -619,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
619 struct ieee80211_sub_if_data *sdata; 616 struct ieee80211_sub_if_data *sdata;
620 struct sk_buff *skb; 617 struct sk_buff *skb;
621 unsigned long flags; 618 unsigned long flags;
622 int ret, i; 619 int ret;
623 620
624 might_sleep(); 621 might_sleep();
625 622
@@ -629,6 +626,15 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
629 local = sta->local; 626 local = sta->local;
630 sdata = sta->sdata; 627 sdata = sta->sdata;
631 628
629 /*
630 * Before removing the station from the driver and
631 * rate control, it might still start new aggregation
632 * sessions -- block that to make sure the tear-down
633 * will be sufficient.
634 */
635 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
636 ieee80211_sta_tear_down_BA_sessions(sta);
637
632 spin_lock_irqsave(&local->sta_lock, flags); 638 spin_lock_irqsave(&local->sta_lock, flags);
633 ret = sta_info_hash_del(local, sta); 639 ret = sta_info_hash_del(local, sta);
634 /* this might still be the pending list ... which is fine */ 640 /* this might still be the pending list ... which is fine */
@@ -645,9 +651,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
645 * may mean it is removed from hardware which requires that 651 * may mean it is removed from hardware which requires that
646 * the key->sta pointer is still valid, so flush the key todo 652 * the key->sta pointer is still valid, so flush the key todo
647 * list here. 653 * list here.
648 *
649 * ieee80211_key_todo() will synchronize_rcu() so after this
650 * nothing can reference this sta struct any more.
651 */ 654 */
652 ieee80211_key_todo(); 655 ieee80211_key_todo();
653 656
@@ -679,11 +682,17 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
679 sdata = sta->sdata; 682 sdata = sta->sdata;
680 } 683 }
681 684
685 /*
686 * At this point, after we wait for an RCU grace period,
687 * neither mac80211 nor the driver can reference this
688 * sta struct any more except by still existing timers
689 * associated with this station that we clean up below.
690 */
691 synchronize_rcu();
692
682#ifdef CONFIG_MAC80211_MESH 693#ifdef CONFIG_MAC80211_MESH
683 if (ieee80211_vif_is_mesh(&sdata->vif)) { 694 if (ieee80211_vif_is_mesh(&sdata->vif))
684 mesh_accept_plinks_update(sdata); 695 mesh_accept_plinks_update(sdata);
685 del_timer(&sta->plink_timer);
686 }
687#endif 696#endif
688 697
689#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 698#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -710,50 +719,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
710 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) 719 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL)
711 dev_kfree_skb_any(skb); 720 dev_kfree_skb_any(skb);
712 721
713 for (i = 0; i < STA_TID_NUM; i++) {
714 struct tid_ampdu_rx *tid_rx;
715 struct tid_ampdu_tx *tid_tx;
716
717 spin_lock_bh(&sta->lock);
718 tid_rx = sta->ampdu_mlme.tid_rx[i];
719 /* Make sure timer won't free the tid_rx struct, see below */
720 if (tid_rx)
721 tid_rx->shutdown = true;
722
723 spin_unlock_bh(&sta->lock);
724
725 /*
726 * Outside spinlock - shutdown is true now so that the timer
727 * won't free tid_rx, we have to do that now. Can't let the
728 * timer do it because we have to sync the timer outside the
729 * lock that it takes itself.
730 */
731 if (tid_rx) {
732 del_timer_sync(&tid_rx->session_timer);
733 kfree(tid_rx);
734 }
735
736 /*
737 * No need to do such complications for TX agg sessions, the
738 * path leading to freeing the tid_tx struct goes via a call
739 * from the driver, and thus needs to look up the sta struct
740 * again, which cannot be found when we get here. Hence, we
741 * just need to delete the timer and free the aggregation
742 * info; we won't be telling the peer about it then but that
743 * doesn't matter if we're not talking to it again anyway.
744 */
745 tid_tx = sta->ampdu_mlme.tid_tx[i];
746 if (tid_tx) {
747 del_timer_sync(&tid_tx->addba_resp_timer);
748 /*
749 * STA removed while aggregation session being
750 * started? Bit odd, but purge frames anyway.
751 */
752 skb_queue_purge(&tid_tx->pending);
753 kfree(tid_tx);
754 }
755 }
756
757 __sta_info_free(local, sta); 722 __sta_info_free(local, sta);
758 723
759 return 0; 724 return 0;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 822d84522937..48a5e80957f0 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -35,8 +35,8 @@
35 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next 35 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
36 * frame to this station is transmitted. 36 * frame to this station is transmitted.
37 * @WLAN_STA_MFP: Management frame protection is used with this STA. 37 * @WLAN_STA_MFP: Management frame protection is used with this STA.
38 * @WLAN_STA_SUSPEND: Set/cleared during a suspend/resume cycle. 38 * @WLAN_STA_BLOCK_BA: Used to deny ADDBA requests (both TX and RX)
39 * Used to deny ADDBA requests (both TX and RX). 39 * during suspend/resume and station removal.
40 * @WLAN_STA_PS_DRIVER: driver requires keeping this station in 40 * @WLAN_STA_PS_DRIVER: driver requires keeping this station in
41 * power-save mode logically to flush frames that might still 41 * power-save mode logically to flush frames that might still
42 * be in the queues 42 * be in the queues
@@ -57,7 +57,7 @@ enum ieee80211_sta_info_flags {
57 WLAN_STA_WDS = 1<<7, 57 WLAN_STA_WDS = 1<<7,
58 WLAN_STA_CLEAR_PS_FILT = 1<<9, 58 WLAN_STA_CLEAR_PS_FILT = 1<<9,
59 WLAN_STA_MFP = 1<<10, 59 WLAN_STA_MFP = 1<<10,
60 WLAN_STA_SUSPEND = 1<<11, 60 WLAN_STA_BLOCK_BA = 1<<11,
61 WLAN_STA_PS_DRIVER = 1<<12, 61 WLAN_STA_PS_DRIVER = 1<<12,
62 WLAN_STA_PSPOLL = 1<<13, 62 WLAN_STA_PSPOLL = 1<<13,
63 WLAN_STA_DISASSOC = 1<<14, 63 WLAN_STA_DISASSOC = 1<<14,
@@ -106,7 +106,6 @@ struct tid_ampdu_tx {
106 * @buf_size: buffer size for incoming A-MPDUs 106 * @buf_size: buffer size for incoming A-MPDUs
107 * @timeout: reset timer value (in TUs). 107 * @timeout: reset timer value (in TUs).
108 * @dialog_token: dialog token for aggregation session 108 * @dialog_token: dialog token for aggregation session
109 * @shutdown: this session is being shut down due to STA removal
110 */ 109 */
111struct tid_ampdu_rx { 110struct tid_ampdu_rx {
112 struct sk_buff **reorder_buf; 111 struct sk_buff **reorder_buf;
@@ -118,7 +117,6 @@ struct tid_ampdu_rx {
118 u16 buf_size; 117 u16 buf_size;
119 u16 timeout; 118 u16 timeout;
120 u8 dialog_token; 119 u8 dialog_token;
121 bool shutdown;
122}; 120};
123 121
124/** 122/**
@@ -156,7 +154,7 @@ enum plink_state {
156 */ 154 */
157struct sta_ampdu_mlme { 155struct sta_ampdu_mlme {
158 /* rx */ 156 /* rx */
159 u8 tid_state_rx[STA_TID_NUM]; 157 bool tid_active_rx[STA_TID_NUM];
160 struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; 158 struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
161 /* tx */ 159 /* tx */
162 u8 tid_state_tx[STA_TID_NUM]; 160 u8 tid_state_tx[STA_TID_NUM];
@@ -200,7 +198,6 @@ struct sta_ampdu_mlme {
200 * @rx_fragments: number of received MPDUs 198 * @rx_fragments: number of received MPDUs
201 * @rx_dropped: number of dropped MPDUs from this STA 199 * @rx_dropped: number of dropped MPDUs from this STA
202 * @last_signal: signal of last received frame from this STA 200 * @last_signal: signal of last received frame from this STA
203 * @last_noise: noise of last received frame from this STA
204 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) 201 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
205 * @tx_filtered_count: number of frames the hardware filtered for this STA 202 * @tx_filtered_count: number of frames the hardware filtered for this STA
206 * @tx_retry_failed: number of frames that failed retry 203 * @tx_retry_failed: number of frames that failed retry
@@ -267,7 +264,6 @@ struct sta_info {
267 unsigned long rx_fragments; 264 unsigned long rx_fragments;
268 unsigned long rx_dropped; 265 unsigned long rx_dropped;
269 int last_signal; 266 int last_signal;
270 int last_noise;
271 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; 267 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
272 268
273 /* Updated from TX status path only, no locking requirements */ 269 /* Updated from TX status path only, no locking requirements */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 56d5b9a6ec5b..11805a3a626f 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -171,7 +171,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
171 struct net_device *prev_dev = NULL; 171 struct net_device *prev_dev = NULL;
172 struct sta_info *sta, *tmp; 172 struct sta_info *sta, *tmp;
173 int retry_count = -1, i; 173 int retry_count = -1, i;
174 bool injected; 174 bool send_to_cooked;
175 175
176 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 176 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
177 /* the HW cannot have attempted that rate */ 177 /* the HW cannot have attempted that rate */
@@ -296,11 +296,15 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
296 /* this was a transmitted frame, but now we want to reuse it */ 296 /* this was a transmitted frame, but now we want to reuse it */
297 skb_orphan(skb); 297 skb_orphan(skb);
298 298
299 /* Need to make a copy before skb->cb gets cleared */
300 send_to_cooked = !!(info->flags & IEEE80211_TX_CTL_INJECTED) ||
301 (type != IEEE80211_FTYPE_DATA);
302
299 /* 303 /*
300 * This is a bit racy but we can avoid a lot of work 304 * This is a bit racy but we can avoid a lot of work
301 * with this test... 305 * with this test...
302 */ 306 */
303 if (!local->monitors && !local->cooked_mntrs) { 307 if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
304 dev_kfree_skb(skb); 308 dev_kfree_skb(skb);
305 return; 309 return;
306 } 310 }
@@ -345,9 +349,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
345 /* for now report the total retry_count */ 349 /* for now report the total retry_count */
346 rthdr->data_retries = retry_count; 350 rthdr->data_retries = retry_count;
347 351
348 /* Need to make a copy before skb->cb gets cleared */
349 injected = !!(info->flags & IEEE80211_TX_CTL_INJECTED);
350
351 /* XXX: is this sufficient for BPF? */ 352 /* XXX: is this sufficient for BPF? */
352 skb_set_mac_header(skb, 0); 353 skb_set_mac_header(skb, 0);
353 skb->ip_summed = CHECKSUM_UNNECESSARY; 354 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -362,8 +363,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
362 continue; 363 continue;
363 364
364 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) && 365 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
365 !injected && 366 !send_to_cooked)
366 (type == IEEE80211_FTYPE_DATA))
367 continue; 367 continue;
368 368
369 if (prev_dev) { 369 if (prev_dev) {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cfc473e1b050..2cb77267f733 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -513,6 +513,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
513 else if (tx->sta && (key = rcu_dereference(tx->sta->key))) 513 else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
514 tx->key = key; 514 tx->key = key;
515 else if (ieee80211_is_mgmt(hdr->frame_control) && 515 else if (ieee80211_is_mgmt(hdr->frame_control) &&
516 is_multicast_ether_addr(hdr->addr1) &&
517 ieee80211_is_robust_mgmt_frame(hdr) &&
516 (key = rcu_dereference(tx->sdata->default_mgmt_key))) 518 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
517 tx->key = key; 519 tx->key = key;
518 else if ((key = rcu_dereference(tx->sdata->default_key))) 520 else if ((key = rcu_dereference(tx->sdata->default_key)))
@@ -1142,13 +1144,12 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1142 1144
1143 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && 1145 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
1144 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { 1146 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
1145 unsigned long flags;
1146 struct tid_ampdu_tx *tid_tx; 1147 struct tid_ampdu_tx *tid_tx;
1147 1148
1148 qc = ieee80211_get_qos_ctl(hdr); 1149 qc = ieee80211_get_qos_ctl(hdr);
1149 tid = *qc & IEEE80211_QOS_CTL_TID_MASK; 1150 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
1150 1151
1151 spin_lock_irqsave(&tx->sta->lock, flags); 1152 spin_lock(&tx->sta->lock);
1152 /* 1153 /*
1153 * XXX: This spinlock could be fairly expensive, but see the 1154 * XXX: This spinlock could be fairly expensive, but see the
1154 * comment in agg-tx.c:ieee80211_agg_tx_operational(). 1155 * comment in agg-tx.c:ieee80211_agg_tx_operational().
@@ -1173,7 +1174,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1173 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1174 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1174 __skb_queue_tail(&tid_tx->pending, skb); 1175 __skb_queue_tail(&tid_tx->pending, skb);
1175 } 1176 }
1176 spin_unlock_irqrestore(&tx->sta->lock, flags); 1177 spin_unlock(&tx->sta->lock);
1177 1178
1178 if (unlikely(queued)) 1179 if (unlikely(queued))
1179 return TX_QUEUED; 1180 return TX_QUEUED;
@@ -2011,14 +2012,12 @@ void ieee80211_tx_pending(unsigned long data)
2011 while (!skb_queue_empty(&local->pending[i])) { 2012 while (!skb_queue_empty(&local->pending[i])) {
2012 struct sk_buff *skb = __skb_dequeue(&local->pending[i]); 2013 struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
2013 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2014 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2014 struct ieee80211_sub_if_data *sdata;
2015 2015
2016 if (WARN_ON(!info->control.vif)) { 2016 if (WARN_ON(!info->control.vif)) {
2017 kfree_skb(skb); 2017 kfree_skb(skb);
2018 continue; 2018 continue;
2019 } 2019 }
2020 2020
2021 sdata = vif_to_sdata(info->control.vif);
2022 spin_unlock_irqrestore(&local->queue_stop_reason_lock, 2021 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
2023 flags); 2022 flags);
2024 2023
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 53af57047435..ad9009f717ed 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -796,6 +796,11 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
796 796
797 drv_conf_tx(local, queue, &qparam); 797 drv_conf_tx(local, queue, &qparam);
798 } 798 }
799
800 /* after reinitialize QoS TX queues setting to default,
801 * disable QoS at all */
802 local->hw.conf.flags &= ~IEEE80211_CONF_QOS;
803 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
799} 804}
800 805
801void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 806void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
@@ -1135,7 +1140,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1135 1140
1136 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 1141 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1137 list_for_each_entry_rcu(sta, &local->sta_list, list) { 1142 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1138 clear_sta_flags(sta, WLAN_STA_SUSPEND); 1143 clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
1139 } 1144 }
1140 } 1145 }
1141 1146
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index c218e07e5caf..7ae58b5b5a08 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -628,6 +628,49 @@ static ssize_t rfkill_persistent_show(struct device *dev,
628 return sprintf(buf, "%d\n", rfkill->persistent); 628 return sprintf(buf, "%d\n", rfkill->persistent);
629} 629}
630 630
631static ssize_t rfkill_hard_show(struct device *dev,
632 struct device_attribute *attr,
633 char *buf)
634{
635 struct rfkill *rfkill = to_rfkill(dev);
636
637 return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_HW) ? 1 : 0 );
638}
639
640static ssize_t rfkill_soft_show(struct device *dev,
641 struct device_attribute *attr,
642 char *buf)
643{
644 struct rfkill *rfkill = to_rfkill(dev);
645
646 return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0 );
647}
648
649static ssize_t rfkill_soft_store(struct device *dev,
650 struct device_attribute *attr,
651 const char *buf, size_t count)
652{
653 struct rfkill *rfkill = to_rfkill(dev);
654 unsigned long state;
655 int err;
656
657 if (!capable(CAP_NET_ADMIN))
658 return -EPERM;
659
660 err = strict_strtoul(buf, 0, &state);
661 if (err)
662 return err;
663
664 if (state > 1 )
665 return -EINVAL;
666
667 mutex_lock(&rfkill_global_mutex);
668 rfkill_set_block(rfkill, state);
669 mutex_unlock(&rfkill_global_mutex);
670
671 return err ?: count;
672}
673
631static u8 user_state_from_blocked(unsigned long state) 674static u8 user_state_from_blocked(unsigned long state)
632{ 675{
633 if (state & RFKILL_BLOCK_HW) 676 if (state & RFKILL_BLOCK_HW)
@@ -643,14 +686,8 @@ static ssize_t rfkill_state_show(struct device *dev,
643 char *buf) 686 char *buf)
644{ 687{
645 struct rfkill *rfkill = to_rfkill(dev); 688 struct rfkill *rfkill = to_rfkill(dev);
646 unsigned long flags;
647 u32 state;
648
649 spin_lock_irqsave(&rfkill->lock, flags);
650 state = rfkill->state;
651 spin_unlock_irqrestore(&rfkill->lock, flags);
652 689
653 return sprintf(buf, "%d\n", user_state_from_blocked(state)); 690 return sprintf(buf, "%d\n", user_state_from_blocked(rfkill->state));
654} 691}
655 692
656static ssize_t rfkill_state_store(struct device *dev, 693static ssize_t rfkill_state_store(struct device *dev,
@@ -700,6 +737,8 @@ static struct device_attribute rfkill_dev_attrs[] = {
700 __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), 737 __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL),
701 __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), 738 __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
702 __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), 739 __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
740 __ATTR(soft, S_IRUGO|S_IWUSR, rfkill_soft_show, rfkill_soft_store),
741 __ATTR(hard, S_IRUGO, rfkill_hard_show, NULL),
703 __ATTR_NULL 742 __ATTR_NULL
704}; 743};
705 744
diff --git a/net/wireless/core.h b/net/wireless/core.h
index d52da913145a..b2234b436ead 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -293,13 +293,15 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
293 const u8 *bssid, 293 const u8 *bssid,
294 const u8 *ssid, int ssid_len, 294 const u8 *ssid, int ssid_len,
295 const u8 *ie, int ie_len, 295 const u8 *ie, int ie_len,
296 const u8 *key, int key_len, int key_idx); 296 const u8 *key, int key_len, int key_idx,
297 bool local_state_change);
297int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 298int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
298 struct net_device *dev, struct ieee80211_channel *chan, 299 struct net_device *dev, struct ieee80211_channel *chan,
299 enum nl80211_auth_type auth_type, const u8 *bssid, 300 enum nl80211_auth_type auth_type, const u8 *bssid,
300 const u8 *ssid, int ssid_len, 301 const u8 *ssid, int ssid_len,
301 const u8 *ie, int ie_len, 302 const u8 *ie, int ie_len,
302 const u8 *key, int key_len, int key_idx); 303 const u8 *key, int key_len, int key_idx,
304 bool local_state_change);
303int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 305int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
304 struct net_device *dev, 306 struct net_device *dev,
305 struct ieee80211_channel *chan, 307 struct ieee80211_channel *chan,
@@ -315,13 +317,16 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
315 struct cfg80211_crypto_settings *crypt); 317 struct cfg80211_crypto_settings *crypt);
316int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 318int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
317 struct net_device *dev, const u8 *bssid, 319 struct net_device *dev, const u8 *bssid,
318 const u8 *ie, int ie_len, u16 reason); 320 const u8 *ie, int ie_len, u16 reason,
321 bool local_state_change);
319int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 322int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
320 struct net_device *dev, const u8 *bssid, 323 struct net_device *dev, const u8 *bssid,
321 const u8 *ie, int ie_len, u16 reason); 324 const u8 *ie, int ie_len, u16 reason,
325 bool local_state_change);
322int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, 326int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
323 struct net_device *dev, const u8 *bssid, 327 struct net_device *dev, const u8 *bssid,
324 const u8 *ie, int ie_len, u16 reason); 328 const u8 *ie, int ie_len, u16 reason,
329 bool local_state_change);
325void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 330void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
326 struct net_device *dev); 331 struct net_device *dev);
327void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 332void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 62bc8855e123..387dd2a27d2f 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -377,7 +377,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
377 const u8 *bssid, 377 const u8 *bssid,
378 const u8 *ssid, int ssid_len, 378 const u8 *ssid, int ssid_len,
379 const u8 *ie, int ie_len, 379 const u8 *ie, int ie_len,
380 const u8 *key, int key_len, int key_idx) 380 const u8 *key, int key_len, int key_idx,
381 bool local_state_change)
381{ 382{
382 struct wireless_dev *wdev = dev->ieee80211_ptr; 383 struct wireless_dev *wdev = dev->ieee80211_ptr;
383 struct cfg80211_auth_request req; 384 struct cfg80211_auth_request req;
@@ -407,6 +408,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
407 408
408 memset(&req, 0, sizeof(req)); 409 memset(&req, 0, sizeof(req));
409 410
411 req.local_state_change = local_state_change;
410 req.ie = ie; 412 req.ie = ie;
411 req.ie_len = ie_len; 413 req.ie_len = ie_len;
412 req.auth_type = auth_type; 414 req.auth_type = auth_type;
@@ -433,12 +435,18 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
433 goto out; 435 goto out;
434 } 436 }
435 437
436 wdev->authtry_bsses[slot] = bss; 438 if (local_state_change)
439 wdev->auth_bsses[slot] = bss;
440 else
441 wdev->authtry_bsses[slot] = bss;
437 cfg80211_hold_bss(bss); 442 cfg80211_hold_bss(bss);
438 443
439 err = rdev->ops->auth(&rdev->wiphy, dev, &req); 444 err = rdev->ops->auth(&rdev->wiphy, dev, &req);
440 if (err) { 445 if (err) {
441 wdev->authtry_bsses[slot] = NULL; 446 if (local_state_change)
447 wdev->auth_bsses[slot] = NULL;
448 else
449 wdev->authtry_bsses[slot] = NULL;
442 cfg80211_unhold_bss(bss); 450 cfg80211_unhold_bss(bss);
443 } 451 }
444 452
@@ -453,14 +461,15 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
453 enum nl80211_auth_type auth_type, const u8 *bssid, 461 enum nl80211_auth_type auth_type, const u8 *bssid,
454 const u8 *ssid, int ssid_len, 462 const u8 *ssid, int ssid_len,
455 const u8 *ie, int ie_len, 463 const u8 *ie, int ie_len,
456 const u8 *key, int key_len, int key_idx) 464 const u8 *key, int key_len, int key_idx,
465 bool local_state_change)
457{ 466{
458 int err; 467 int err;
459 468
460 wdev_lock(dev->ieee80211_ptr); 469 wdev_lock(dev->ieee80211_ptr);
461 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 470 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
462 ssid, ssid_len, ie, ie_len, 471 ssid, ssid_len, ie, ie_len,
463 key, key_len, key_idx); 472 key, key_len, key_idx, local_state_change);
464 wdev_unlock(dev->ieee80211_ptr); 473 wdev_unlock(dev->ieee80211_ptr);
465 474
466 return err; 475 return err;
@@ -554,7 +563,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
554 563
555int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 564int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
556 struct net_device *dev, const u8 *bssid, 565 struct net_device *dev, const u8 *bssid,
557 const u8 *ie, int ie_len, u16 reason) 566 const u8 *ie, int ie_len, u16 reason,
567 bool local_state_change)
558{ 568{
559 struct wireless_dev *wdev = dev->ieee80211_ptr; 569 struct wireless_dev *wdev = dev->ieee80211_ptr;
560 struct cfg80211_deauth_request req; 570 struct cfg80211_deauth_request req;
@@ -564,6 +574,7 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
564 574
565 memset(&req, 0, sizeof(req)); 575 memset(&req, 0, sizeof(req));
566 req.reason_code = reason; 576 req.reason_code = reason;
577 req.local_state_change = local_state_change;
567 req.ie = ie; 578 req.ie = ie;
568 req.ie_len = ie_len; 579 req.ie_len = ie_len;
569 if (wdev->current_bss && 580 if (wdev->current_bss &&
@@ -590,13 +601,15 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
590 601
591int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 602int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
592 struct net_device *dev, const u8 *bssid, 603 struct net_device *dev, const u8 *bssid,
593 const u8 *ie, int ie_len, u16 reason) 604 const u8 *ie, int ie_len, u16 reason,
605 bool local_state_change)
594{ 606{
595 struct wireless_dev *wdev = dev->ieee80211_ptr; 607 struct wireless_dev *wdev = dev->ieee80211_ptr;
596 int err; 608 int err;
597 609
598 wdev_lock(wdev); 610 wdev_lock(wdev);
599 err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason); 611 err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
612 local_state_change);
600 wdev_unlock(wdev); 613 wdev_unlock(wdev);
601 614
602 return err; 615 return err;
@@ -604,7 +617,8 @@ int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
604 617
605static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, 618static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
606 struct net_device *dev, const u8 *bssid, 619 struct net_device *dev, const u8 *bssid,
607 const u8 *ie, int ie_len, u16 reason) 620 const u8 *ie, int ie_len, u16 reason,
621 bool local_state_change)
608{ 622{
609 struct wireless_dev *wdev = dev->ieee80211_ptr; 623 struct wireless_dev *wdev = dev->ieee80211_ptr;
610 struct cfg80211_disassoc_request req; 624 struct cfg80211_disassoc_request req;
@@ -619,6 +633,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
619 633
620 memset(&req, 0, sizeof(req)); 634 memset(&req, 0, sizeof(req));
621 req.reason_code = reason; 635 req.reason_code = reason;
636 req.local_state_change = local_state_change;
622 req.ie = ie; 637 req.ie = ie;
623 req.ie_len = ie_len; 638 req.ie_len = ie_len;
624 if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) 639 if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
@@ -631,13 +646,15 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
631 646
632int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, 647int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
633 struct net_device *dev, const u8 *bssid, 648 struct net_device *dev, const u8 *bssid,
634 const u8 *ie, int ie_len, u16 reason) 649 const u8 *ie, int ie_len, u16 reason,
650 bool local_state_change)
635{ 651{
636 struct wireless_dev *wdev = dev->ieee80211_ptr; 652 struct wireless_dev *wdev = dev->ieee80211_ptr;
637 int err; 653 int err;
638 654
639 wdev_lock(wdev); 655 wdev_lock(wdev);
640 err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason); 656 err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
657 local_state_change);
641 wdev_unlock(wdev); 658 wdev_unlock(wdev);
642 659
643 return err; 660 return err;
@@ -894,3 +911,16 @@ void cfg80211_action_tx_status(struct net_device *dev, u64 cookie,
894 nl80211_send_action_tx_status(rdev, dev, cookie, buf, len, ack, gfp); 911 nl80211_send_action_tx_status(rdev, dev, cookie, buf, len, ack, gfp);
895} 912}
896EXPORT_SYMBOL(cfg80211_action_tx_status); 913EXPORT_SYMBOL(cfg80211_action_tx_status);
914
915void cfg80211_cqm_rssi_notify(struct net_device *dev,
916 enum nl80211_cqm_rssi_threshold_event rssi_event,
917 gfp_t gfp)
918{
919 struct wireless_dev *wdev = dev->ieee80211_ptr;
920 struct wiphy *wiphy = wdev->wiphy;
921 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
922
923 /* Indicate roaming trigger event to user space */
924 nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
925}
926EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e447db04cf76..df5505b3930c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -149,6 +149,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
149 .len = IEEE80211_MAX_DATA_LEN }, 149 .len = IEEE80211_MAX_DATA_LEN },
150 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, }, 150 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
151 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, 151 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
152 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
153 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
152}; 154};
153 155
154/* policy for the attributes */ 156/* policy for the attributes */
@@ -2095,7 +2097,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
2095 goto out_rtnl; 2097 goto out_rtnl;
2096 2098
2097 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2099 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2098 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { 2100 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2101 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2099 err = -EINVAL; 2102 err = -EINVAL;
2100 goto out; 2103 goto out;
2101 } 2104 }
@@ -3391,6 +3394,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3391 int err, ssid_len, ie_len = 0; 3394 int err, ssid_len, ie_len = 0;
3392 enum nl80211_auth_type auth_type; 3395 enum nl80211_auth_type auth_type;
3393 struct key_parse key; 3396 struct key_parse key;
3397 bool local_state_change;
3394 3398
3395 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 3399 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3396 return -EINVAL; 3400 return -EINVAL;
@@ -3469,9 +3473,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3469 goto out; 3473 goto out;
3470 } 3474 }
3471 3475
3476 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3477
3472 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 3478 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
3473 ssid, ssid_len, ie, ie_len, 3479 ssid, ssid_len, ie, ie_len,
3474 key.p.key, key.p.key_len, key.idx); 3480 key.p.key, key.p.key_len, key.idx,
3481 local_state_change);
3475 3482
3476out: 3483out:
3477 cfg80211_unlock_rdev(rdev); 3484 cfg80211_unlock_rdev(rdev);
@@ -3648,6 +3655,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3648 const u8 *ie = NULL, *bssid; 3655 const u8 *ie = NULL, *bssid;
3649 int err, ie_len = 0; 3656 int err, ie_len = 0;
3650 u16 reason_code; 3657 u16 reason_code;
3658 bool local_state_change;
3651 3659
3652 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 3660 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3653 return -EINVAL; 3661 return -EINVAL;
@@ -3693,7 +3701,10 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3693 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3701 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3694 } 3702 }
3695 3703
3696 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code); 3704 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3705
3706 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
3707 local_state_change);
3697 3708
3698out: 3709out:
3699 cfg80211_unlock_rdev(rdev); 3710 cfg80211_unlock_rdev(rdev);
@@ -3710,6 +3721,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3710 const u8 *ie = NULL, *bssid; 3721 const u8 *ie = NULL, *bssid;
3711 int err, ie_len = 0; 3722 int err, ie_len = 0;
3712 u16 reason_code; 3723 u16 reason_code;
3724 bool local_state_change;
3713 3725
3714 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 3726 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3715 return -EINVAL; 3727 return -EINVAL;
@@ -3755,7 +3767,10 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3755 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3767 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3756 } 3768 }
3757 3769
3758 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code); 3770 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3771
3772 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
3773 local_state_change);
3759 3774
3760out: 3775out:
3761 cfg80211_unlock_rdev(rdev); 3776 cfg80211_unlock_rdev(rdev);
@@ -4778,6 +4793,84 @@ unlock_rtnl:
4778 return err; 4793 return err;
4779} 4794}
4780 4795
4796static struct nla_policy
4797nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = {
4798 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
4799 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
4800 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
4801};
4802
4803static int nl80211_set_cqm_rssi(struct genl_info *info,
4804 s32 threshold, u32 hysteresis)
4805{
4806 struct cfg80211_registered_device *rdev;
4807 struct wireless_dev *wdev;
4808 struct net_device *dev;
4809 int err;
4810
4811 if (threshold > 0)
4812 return -EINVAL;
4813
4814 rtnl_lock();
4815
4816 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4817 if (err)
4818 goto unlock_rdev;
4819
4820 wdev = dev->ieee80211_ptr;
4821
4822 if (!rdev->ops->set_cqm_rssi_config) {
4823 err = -EOPNOTSUPP;
4824 goto unlock_rdev;
4825 }
4826
4827 if (wdev->iftype != NL80211_IFTYPE_STATION) {
4828 err = -EOPNOTSUPP;
4829 goto unlock_rdev;
4830 }
4831
4832 err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
4833 threshold, hysteresis);
4834
4835unlock_rdev:
4836 cfg80211_unlock_rdev(rdev);
4837 dev_put(dev);
4838 rtnl_unlock();
4839
4840 return err;
4841}
4842
4843static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
4844{
4845 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
4846 struct nlattr *cqm;
4847 int err;
4848
4849 cqm = info->attrs[NL80211_ATTR_CQM];
4850 if (!cqm) {
4851 err = -EINVAL;
4852 goto out;
4853 }
4854
4855 err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
4856 nl80211_attr_cqm_policy);
4857 if (err)
4858 goto out;
4859
4860 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
4861 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
4862 s32 threshold;
4863 u32 hysteresis;
4864 threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
4865 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
4866 err = nl80211_set_cqm_rssi(info, threshold, hysteresis);
4867 } else
4868 err = -EINVAL;
4869
4870out:
4871 return err;
4872}
4873
4781static struct genl_ops nl80211_ops[] = { 4874static struct genl_ops nl80211_ops[] = {
4782 { 4875 {
4783 .cmd = NL80211_CMD_GET_WIPHY, 4876 .cmd = NL80211_CMD_GET_WIPHY,
@@ -5082,6 +5175,12 @@ static struct genl_ops nl80211_ops[] = {
5082 .policy = nl80211_policy, 5175 .policy = nl80211_policy,
5083 /* can be retrieved by unprivileged users */ 5176 /* can be retrieved by unprivileged users */
5084 }, 5177 },
5178 {
5179 .cmd = NL80211_CMD_SET_CQM,
5180 .doit = nl80211_set_cqm,
5181 .policy = nl80211_policy,
5182 .flags = GENL_ADMIN_PERM,
5183 },
5085}; 5184};
5086 5185
5087static struct genl_multicast_group nl80211_mlme_mcgrp = { 5186static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -5832,6 +5931,52 @@ void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev,
5832 nlmsg_free(msg); 5931 nlmsg_free(msg);
5833} 5932}
5834 5933
5934void
5935nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
5936 struct net_device *netdev,
5937 enum nl80211_cqm_rssi_threshold_event rssi_event,
5938 gfp_t gfp)
5939{
5940 struct sk_buff *msg;
5941 struct nlattr *pinfoattr;
5942 void *hdr;
5943
5944 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
5945 if (!msg)
5946 return;
5947
5948 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
5949 if (!hdr) {
5950 nlmsg_free(msg);
5951 return;
5952 }
5953
5954 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5955 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5956
5957 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
5958 if (!pinfoattr)
5959 goto nla_put_failure;
5960
5961 NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
5962 rssi_event);
5963
5964 nla_nest_end(msg, pinfoattr);
5965
5966 if (genlmsg_end(msg, hdr) < 0) {
5967 nlmsg_free(msg);
5968 return;
5969 }
5970
5971 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5972 nl80211_mlme_mcgrp.id, gfp);
5973 return;
5974
5975 nla_put_failure:
5976 genlmsg_cancel(msg, hdr);
5977 nlmsg_free(msg);
5978}
5979
5835static int nl80211_netlink_notify(struct notifier_block * nb, 5980static int nl80211_netlink_notify(struct notifier_block * nb,
5836 unsigned long state, 5981 unsigned long state,
5837 void *_notify) 5982 void *_notify)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 4ca511102c6c..2ad7fbc7d9f1 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -82,4 +82,10 @@ void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev,
82 const u8 *buf, size_t len, bool ack, 82 const u8 *buf, size_t len, bool ack,
83 gfp_t gfp); 83 gfp_t gfp);
84 84
85void
86nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
87 struct net_device *netdev,
88 enum nl80211_cqm_rssi_threshold_event rssi_event,
89 gfp_t gfp);
90
85#endif /* __NET_WIRELESS_NL80211_H */ 91#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 81fcafc60150..496348c48506 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2355,10 +2355,10 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
2355 rdev->country_ie_alpha2[1]); 2355 rdev->country_ie_alpha2[1]);
2356 } else 2356 } else
2357 printk(KERN_INFO "cfg80211: Current regulatory " 2357 printk(KERN_INFO "cfg80211: Current regulatory "
2358 "domain intersected: \n"); 2358 "domain intersected:\n");
2359 } else 2359 } else
2360 printk(KERN_INFO "cfg80211: Current regulatory " 2360 printk(KERN_INFO "cfg80211: Current regulatory "
2361 "domain intersected: \n"); 2361 "domain intersected:\n");
2362 } else if (is_world_regdom(rd->alpha2)) 2362 } else if (is_world_regdom(rd->alpha2))
2363 printk(KERN_INFO "cfg80211: World regulatory " 2363 printk(KERN_INFO "cfg80211: World regulatory "
2364 "domain updated:\n"); 2364 "domain updated:\n");
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 17fde0da1b08..17465777eb47 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -170,7 +170,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
170 params->ssid, params->ssid_len, 170 params->ssid, params->ssid_len,
171 NULL, 0, 171 NULL, 0,
172 params->key, params->key_len, 172 params->key, params->key_len,
173 params->key_idx); 173 params->key_idx, false);
174 case CFG80211_CONN_ASSOCIATE_NEXT: 174 case CFG80211_CONN_ASSOCIATE_NEXT:
175 BUG_ON(!rdev->ops->assoc); 175 BUG_ON(!rdev->ops->assoc);
176 wdev->conn->state = CFG80211_CONN_ASSOCIATING; 176 wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -185,12 +185,13 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
185 if (err) 185 if (err)
186 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 186 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
187 NULL, 0, 187 NULL, 0,
188 WLAN_REASON_DEAUTH_LEAVING); 188 WLAN_REASON_DEAUTH_LEAVING,
189 false);
189 return err; 190 return err;
190 case CFG80211_CONN_DEAUTH_ASSOC_FAIL: 191 case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
191 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 192 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
192 NULL, 0, 193 NULL, 0,
193 WLAN_REASON_DEAUTH_LEAVING); 194 WLAN_REASON_DEAUTH_LEAVING, false);
194 /* return an error so that we call __cfg80211_connect_result() */ 195 /* return an error so that we call __cfg80211_connect_result() */
195 return -EINVAL; 196 return -EINVAL;
196 default: 197 default:
@@ -675,7 +676,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
675 continue; 676 continue;
676 bssid = wdev->auth_bsses[i]->pub.bssid; 677 bssid = wdev->auth_bsses[i]->pub.bssid;
677 ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, 678 ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
678 WLAN_REASON_DEAUTH_LEAVING); 679 WLAN_REASON_DEAUTH_LEAVING,
680 false);
679 WARN(ret, "deauth failed: %d\n", ret); 681 WARN(ret, "deauth failed: %d\n", ret);
680 } 682 }
681 } 683 }
@@ -934,7 +936,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
934 /* wdev->conn->params.bssid must be set if > SCANNING */ 936 /* wdev->conn->params.bssid must be set if > SCANNING */
935 err = __cfg80211_mlme_deauth(rdev, dev, 937 err = __cfg80211_mlme_deauth(rdev, dev,
936 wdev->conn->params.bssid, 938 wdev->conn->params.bssid,
937 NULL, 0, reason); 939 NULL, 0, reason, false);
938 if (err) 940 if (err)
939 return err; 941 return err;
940 } else { 942 } else {
@@ -990,7 +992,8 @@ void cfg80211_sme_disassoc(struct net_device *dev, int idx)
990 992
991 memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN); 993 memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
992 if (__cfg80211_mlme_deauth(rdev, dev, bssid, 994 if (__cfg80211_mlme_deauth(rdev, dev, bssid,
993 NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) { 995 NULL, 0, WLAN_REASON_DEAUTH_LEAVING,
996 false)) {
994 /* whatever -- assume gone anyway */ 997 /* whatever -- assume gone anyway */
995 cfg80211_unhold_bss(wdev->auth_bsses[idx]); 998 cfg80211_unhold_bss(wdev->auth_bsses[idx]);
996 cfg80211_put_bss(&wdev->auth_bsses[idx]->pub); 999 cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index be2ab8c59e3a..7acb81b9675d 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -330,11 +330,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
330 if (iftype == NL80211_IFTYPE_MESH_POINT) { 330 if (iftype == NL80211_IFTYPE_MESH_POINT) {
331 struct ieee80211s_hdr *meshdr = 331 struct ieee80211s_hdr *meshdr =
332 (struct ieee80211s_hdr *) (skb->data + hdrlen); 332 (struct ieee80211s_hdr *) (skb->data + hdrlen);
333 hdrlen += ieee80211_get_mesh_hdrlen(meshdr); 333 /* make sure meshdr->flags is on the linear part */
334 if (!pskb_may_pull(skb, hdrlen + 1))
335 return -1;
334 if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { 336 if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
335 memcpy(dst, meshdr->eaddr1, ETH_ALEN); 337 skb_copy_bits(skb, hdrlen +
336 memcpy(src, meshdr->eaddr2, ETH_ALEN); 338 offsetof(struct ieee80211s_hdr, eaddr1),
339 dst, ETH_ALEN);
340 skb_copy_bits(skb, hdrlen +
341 offsetof(struct ieee80211s_hdr, eaddr2),
342 src, ETH_ALEN);
337 } 343 }
344 hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
338 } 345 }
339 break; 346 break;
340 case cpu_to_le16(IEEE80211_FCTL_FROMDS): 347 case cpu_to_le16(IEEE80211_FCTL_FROMDS):
@@ -346,9 +353,14 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
346 if (iftype == NL80211_IFTYPE_MESH_POINT) { 353 if (iftype == NL80211_IFTYPE_MESH_POINT) {
347 struct ieee80211s_hdr *meshdr = 354 struct ieee80211s_hdr *meshdr =
348 (struct ieee80211s_hdr *) (skb->data + hdrlen); 355 (struct ieee80211s_hdr *) (skb->data + hdrlen);
349 hdrlen += ieee80211_get_mesh_hdrlen(meshdr); 356 /* make sure meshdr->flags is on the linear part */
357 if (!pskb_may_pull(skb, hdrlen + 1))
358 return -1;
350 if (meshdr->flags & MESH_FLAGS_AE_A4) 359 if (meshdr->flags & MESH_FLAGS_AE_A4)
351 memcpy(src, meshdr->eaddr1, ETH_ALEN); 360 skb_copy_bits(skb, hdrlen +
361 offsetof(struct ieee80211s_hdr, eaddr1),
362 src, ETH_ALEN);
363 hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
352 } 364 }
353 break; 365 break;
354 case cpu_to_le16(0): 366 case cpu_to_le16(0):
@@ -357,7 +369,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
357 break; 369 break;
358 } 370 }
359 371
360 if (unlikely(skb->len - hdrlen < 8)) 372 if (!pskb_may_pull(skb, hdrlen + 8))
361 return -1; 373 return -1;
362 374
363 payload = skb->data + hdrlen; 375 payload = skb->data + hdrlen;
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 5e1656bdf23b..bfcbeee23f9c 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -28,226 +28,226 @@ typedef int (*wext_ioctl_func)(struct net_device *, struct iwreq *,
28 * know about. 28 * know about.
29 */ 29 */
30static const struct iw_ioctl_description standard_ioctl[] = { 30static const struct iw_ioctl_description standard_ioctl[] = {
31 [SIOCSIWCOMMIT - SIOCIWFIRST] = { 31 [IW_IOCTL_IDX(SIOCSIWCOMMIT)] = {
32 .header_type = IW_HEADER_TYPE_NULL, 32 .header_type = IW_HEADER_TYPE_NULL,
33 }, 33 },
34 [SIOCGIWNAME - SIOCIWFIRST] = { 34 [IW_IOCTL_IDX(SIOCGIWNAME)] = {
35 .header_type = IW_HEADER_TYPE_CHAR, 35 .header_type = IW_HEADER_TYPE_CHAR,
36 .flags = IW_DESCR_FLAG_DUMP, 36 .flags = IW_DESCR_FLAG_DUMP,
37 }, 37 },
38 [SIOCSIWNWID - SIOCIWFIRST] = { 38 [IW_IOCTL_IDX(SIOCSIWNWID)] = {
39 .header_type = IW_HEADER_TYPE_PARAM, 39 .header_type = IW_HEADER_TYPE_PARAM,
40 .flags = IW_DESCR_FLAG_EVENT, 40 .flags = IW_DESCR_FLAG_EVENT,
41 }, 41 },
42 [SIOCGIWNWID - SIOCIWFIRST] = { 42 [IW_IOCTL_IDX(SIOCGIWNWID)] = {
43 .header_type = IW_HEADER_TYPE_PARAM, 43 .header_type = IW_HEADER_TYPE_PARAM,
44 .flags = IW_DESCR_FLAG_DUMP, 44 .flags = IW_DESCR_FLAG_DUMP,
45 }, 45 },
46 [SIOCSIWFREQ - SIOCIWFIRST] = { 46 [IW_IOCTL_IDX(SIOCSIWFREQ)] = {
47 .header_type = IW_HEADER_TYPE_FREQ, 47 .header_type = IW_HEADER_TYPE_FREQ,
48 .flags = IW_DESCR_FLAG_EVENT, 48 .flags = IW_DESCR_FLAG_EVENT,
49 }, 49 },
50 [SIOCGIWFREQ - SIOCIWFIRST] = { 50 [IW_IOCTL_IDX(SIOCGIWFREQ)] = {
51 .header_type = IW_HEADER_TYPE_FREQ, 51 .header_type = IW_HEADER_TYPE_FREQ,
52 .flags = IW_DESCR_FLAG_DUMP, 52 .flags = IW_DESCR_FLAG_DUMP,
53 }, 53 },
54 [SIOCSIWMODE - SIOCIWFIRST] = { 54 [IW_IOCTL_IDX(SIOCSIWMODE)] = {
55 .header_type = IW_HEADER_TYPE_UINT, 55 .header_type = IW_HEADER_TYPE_UINT,
56 .flags = IW_DESCR_FLAG_EVENT, 56 .flags = IW_DESCR_FLAG_EVENT,
57 }, 57 },
58 [SIOCGIWMODE - SIOCIWFIRST] = { 58 [IW_IOCTL_IDX(SIOCGIWMODE)] = {
59 .header_type = IW_HEADER_TYPE_UINT, 59 .header_type = IW_HEADER_TYPE_UINT,
60 .flags = IW_DESCR_FLAG_DUMP, 60 .flags = IW_DESCR_FLAG_DUMP,
61 }, 61 },
62 [SIOCSIWSENS - SIOCIWFIRST] = { 62 [IW_IOCTL_IDX(SIOCSIWSENS)] = {
63 .header_type = IW_HEADER_TYPE_PARAM, 63 .header_type = IW_HEADER_TYPE_PARAM,
64 }, 64 },
65 [SIOCGIWSENS - SIOCIWFIRST] = { 65 [IW_IOCTL_IDX(SIOCGIWSENS)] = {
66 .header_type = IW_HEADER_TYPE_PARAM, 66 .header_type = IW_HEADER_TYPE_PARAM,
67 }, 67 },
68 [SIOCSIWRANGE - SIOCIWFIRST] = { 68 [IW_IOCTL_IDX(SIOCSIWRANGE)] = {
69 .header_type = IW_HEADER_TYPE_NULL, 69 .header_type = IW_HEADER_TYPE_NULL,
70 }, 70 },
71 [SIOCGIWRANGE - SIOCIWFIRST] = { 71 [IW_IOCTL_IDX(SIOCGIWRANGE)] = {
72 .header_type = IW_HEADER_TYPE_POINT, 72 .header_type = IW_HEADER_TYPE_POINT,
73 .token_size = 1, 73 .token_size = 1,
74 .max_tokens = sizeof(struct iw_range), 74 .max_tokens = sizeof(struct iw_range),
75 .flags = IW_DESCR_FLAG_DUMP, 75 .flags = IW_DESCR_FLAG_DUMP,
76 }, 76 },
77 [SIOCSIWPRIV - SIOCIWFIRST] = { 77 [IW_IOCTL_IDX(SIOCSIWPRIV)] = {
78 .header_type = IW_HEADER_TYPE_NULL, 78 .header_type = IW_HEADER_TYPE_NULL,
79 }, 79 },
80 [SIOCGIWPRIV - SIOCIWFIRST] = { /* (handled directly by us) */ 80 [IW_IOCTL_IDX(SIOCGIWPRIV)] = { /* (handled directly by us) */
81 .header_type = IW_HEADER_TYPE_POINT, 81 .header_type = IW_HEADER_TYPE_POINT,
82 .token_size = sizeof(struct iw_priv_args), 82 .token_size = sizeof(struct iw_priv_args),
83 .max_tokens = 16, 83 .max_tokens = 16,
84 .flags = IW_DESCR_FLAG_NOMAX, 84 .flags = IW_DESCR_FLAG_NOMAX,
85 }, 85 },
86 [SIOCSIWSTATS - SIOCIWFIRST] = { 86 [IW_IOCTL_IDX(SIOCSIWSTATS)] = {
87 .header_type = IW_HEADER_TYPE_NULL, 87 .header_type = IW_HEADER_TYPE_NULL,
88 }, 88 },
89 [SIOCGIWSTATS - SIOCIWFIRST] = { /* (handled directly by us) */ 89 [IW_IOCTL_IDX(SIOCGIWSTATS)] = { /* (handled directly by us) */
90 .header_type = IW_HEADER_TYPE_POINT, 90 .header_type = IW_HEADER_TYPE_POINT,
91 .token_size = 1, 91 .token_size = 1,
92 .max_tokens = sizeof(struct iw_statistics), 92 .max_tokens = sizeof(struct iw_statistics),
93 .flags = IW_DESCR_FLAG_DUMP, 93 .flags = IW_DESCR_FLAG_DUMP,
94 }, 94 },
95 [SIOCSIWSPY - SIOCIWFIRST] = { 95 [IW_IOCTL_IDX(SIOCSIWSPY)] = {
96 .header_type = IW_HEADER_TYPE_POINT, 96 .header_type = IW_HEADER_TYPE_POINT,
97 .token_size = sizeof(struct sockaddr), 97 .token_size = sizeof(struct sockaddr),
98 .max_tokens = IW_MAX_SPY, 98 .max_tokens = IW_MAX_SPY,
99 }, 99 },
100 [SIOCGIWSPY - SIOCIWFIRST] = { 100 [IW_IOCTL_IDX(SIOCGIWSPY)] = {
101 .header_type = IW_HEADER_TYPE_POINT, 101 .header_type = IW_HEADER_TYPE_POINT,
102 .token_size = sizeof(struct sockaddr) + 102 .token_size = sizeof(struct sockaddr) +
103 sizeof(struct iw_quality), 103 sizeof(struct iw_quality),
104 .max_tokens = IW_MAX_SPY, 104 .max_tokens = IW_MAX_SPY,
105 }, 105 },
106 [SIOCSIWTHRSPY - SIOCIWFIRST] = { 106 [IW_IOCTL_IDX(SIOCSIWTHRSPY)] = {
107 .header_type = IW_HEADER_TYPE_POINT, 107 .header_type = IW_HEADER_TYPE_POINT,
108 .token_size = sizeof(struct iw_thrspy), 108 .token_size = sizeof(struct iw_thrspy),
109 .min_tokens = 1, 109 .min_tokens = 1,
110 .max_tokens = 1, 110 .max_tokens = 1,
111 }, 111 },
112 [SIOCGIWTHRSPY - SIOCIWFIRST] = { 112 [IW_IOCTL_IDX(SIOCGIWTHRSPY)] = {
113 .header_type = IW_HEADER_TYPE_POINT, 113 .header_type = IW_HEADER_TYPE_POINT,
114 .token_size = sizeof(struct iw_thrspy), 114 .token_size = sizeof(struct iw_thrspy),
115 .min_tokens = 1, 115 .min_tokens = 1,
116 .max_tokens = 1, 116 .max_tokens = 1,
117 }, 117 },
118 [SIOCSIWAP - SIOCIWFIRST] = { 118 [IW_IOCTL_IDX(SIOCSIWAP)] = {
119 .header_type = IW_HEADER_TYPE_ADDR, 119 .header_type = IW_HEADER_TYPE_ADDR,
120 }, 120 },
121 [SIOCGIWAP - SIOCIWFIRST] = { 121 [IW_IOCTL_IDX(SIOCGIWAP)] = {
122 .header_type = IW_HEADER_TYPE_ADDR, 122 .header_type = IW_HEADER_TYPE_ADDR,
123 .flags = IW_DESCR_FLAG_DUMP, 123 .flags = IW_DESCR_FLAG_DUMP,
124 }, 124 },
125 [SIOCSIWMLME - SIOCIWFIRST] = { 125 [IW_IOCTL_IDX(SIOCSIWMLME)] = {
126 .header_type = IW_HEADER_TYPE_POINT, 126 .header_type = IW_HEADER_TYPE_POINT,
127 .token_size = 1, 127 .token_size = 1,
128 .min_tokens = sizeof(struct iw_mlme), 128 .min_tokens = sizeof(struct iw_mlme),
129 .max_tokens = sizeof(struct iw_mlme), 129 .max_tokens = sizeof(struct iw_mlme),
130 }, 130 },
131 [SIOCGIWAPLIST - SIOCIWFIRST] = { 131 [IW_IOCTL_IDX(SIOCGIWAPLIST)] = {
132 .header_type = IW_HEADER_TYPE_POINT, 132 .header_type = IW_HEADER_TYPE_POINT,
133 .token_size = sizeof(struct sockaddr) + 133 .token_size = sizeof(struct sockaddr) +
134 sizeof(struct iw_quality), 134 sizeof(struct iw_quality),
135 .max_tokens = IW_MAX_AP, 135 .max_tokens = IW_MAX_AP,
136 .flags = IW_DESCR_FLAG_NOMAX, 136 .flags = IW_DESCR_FLAG_NOMAX,
137 }, 137 },
138 [SIOCSIWSCAN - SIOCIWFIRST] = { 138 [IW_IOCTL_IDX(SIOCSIWSCAN)] = {
139 .header_type = IW_HEADER_TYPE_POINT, 139 .header_type = IW_HEADER_TYPE_POINT,
140 .token_size = 1, 140 .token_size = 1,
141 .min_tokens = 0, 141 .min_tokens = 0,
142 .max_tokens = sizeof(struct iw_scan_req), 142 .max_tokens = sizeof(struct iw_scan_req),
143 }, 143 },
144 [SIOCGIWSCAN - SIOCIWFIRST] = { 144 [IW_IOCTL_IDX(SIOCGIWSCAN)] = {
145 .header_type = IW_HEADER_TYPE_POINT, 145 .header_type = IW_HEADER_TYPE_POINT,
146 .token_size = 1, 146 .token_size = 1,
147 .max_tokens = IW_SCAN_MAX_DATA, 147 .max_tokens = IW_SCAN_MAX_DATA,
148 .flags = IW_DESCR_FLAG_NOMAX, 148 .flags = IW_DESCR_FLAG_NOMAX,
149 }, 149 },
150 [SIOCSIWESSID - SIOCIWFIRST] = { 150 [IW_IOCTL_IDX(SIOCSIWESSID)] = {
151 .header_type = IW_HEADER_TYPE_POINT, 151 .header_type = IW_HEADER_TYPE_POINT,
152 .token_size = 1, 152 .token_size = 1,
153 .max_tokens = IW_ESSID_MAX_SIZE, 153 .max_tokens = IW_ESSID_MAX_SIZE,
154 .flags = IW_DESCR_FLAG_EVENT, 154 .flags = IW_DESCR_FLAG_EVENT,
155 }, 155 },
156 [SIOCGIWESSID - SIOCIWFIRST] = { 156 [IW_IOCTL_IDX(SIOCGIWESSID)] = {
157 .header_type = IW_HEADER_TYPE_POINT, 157 .header_type = IW_HEADER_TYPE_POINT,
158 .token_size = 1, 158 .token_size = 1,
159 .max_tokens = IW_ESSID_MAX_SIZE, 159 .max_tokens = IW_ESSID_MAX_SIZE,
160 .flags = IW_DESCR_FLAG_DUMP, 160 .flags = IW_DESCR_FLAG_DUMP,
161 }, 161 },
162 [SIOCSIWNICKN - SIOCIWFIRST] = { 162 [IW_IOCTL_IDX(SIOCSIWNICKN)] = {
163 .header_type = IW_HEADER_TYPE_POINT, 163 .header_type = IW_HEADER_TYPE_POINT,
164 .token_size = 1, 164 .token_size = 1,
165 .max_tokens = IW_ESSID_MAX_SIZE, 165 .max_tokens = IW_ESSID_MAX_SIZE,
166 }, 166 },
167 [SIOCGIWNICKN - SIOCIWFIRST] = { 167 [IW_IOCTL_IDX(SIOCGIWNICKN)] = {
168 .header_type = IW_HEADER_TYPE_POINT, 168 .header_type = IW_HEADER_TYPE_POINT,
169 .token_size = 1, 169 .token_size = 1,
170 .max_tokens = IW_ESSID_MAX_SIZE, 170 .max_tokens = IW_ESSID_MAX_SIZE,
171 }, 171 },
172 [SIOCSIWRATE - SIOCIWFIRST] = { 172 [IW_IOCTL_IDX(SIOCSIWRATE)] = {
173 .header_type = IW_HEADER_TYPE_PARAM, 173 .header_type = IW_HEADER_TYPE_PARAM,
174 }, 174 },
175 [SIOCGIWRATE - SIOCIWFIRST] = { 175 [IW_IOCTL_IDX(SIOCGIWRATE)] = {
176 .header_type = IW_HEADER_TYPE_PARAM, 176 .header_type = IW_HEADER_TYPE_PARAM,
177 }, 177 },
178 [SIOCSIWRTS - SIOCIWFIRST] = { 178 [IW_IOCTL_IDX(SIOCSIWRTS)] = {
179 .header_type = IW_HEADER_TYPE_PARAM, 179 .header_type = IW_HEADER_TYPE_PARAM,
180 }, 180 },
181 [SIOCGIWRTS - SIOCIWFIRST] = { 181 [IW_IOCTL_IDX(SIOCGIWRTS)] = {
182 .header_type = IW_HEADER_TYPE_PARAM, 182 .header_type = IW_HEADER_TYPE_PARAM,
183 }, 183 },
184 [SIOCSIWFRAG - SIOCIWFIRST] = { 184 [IW_IOCTL_IDX(SIOCSIWFRAG)] = {
185 .header_type = IW_HEADER_TYPE_PARAM, 185 .header_type = IW_HEADER_TYPE_PARAM,
186 }, 186 },
187 [SIOCGIWFRAG - SIOCIWFIRST] = { 187 [IW_IOCTL_IDX(SIOCGIWFRAG)] = {
188 .header_type = IW_HEADER_TYPE_PARAM, 188 .header_type = IW_HEADER_TYPE_PARAM,
189 }, 189 },
190 [SIOCSIWTXPOW - SIOCIWFIRST] = { 190 [IW_IOCTL_IDX(SIOCSIWTXPOW)] = {
191 .header_type = IW_HEADER_TYPE_PARAM, 191 .header_type = IW_HEADER_TYPE_PARAM,
192 }, 192 },
193 [SIOCGIWTXPOW - SIOCIWFIRST] = { 193 [IW_IOCTL_IDX(SIOCGIWTXPOW)] = {
194 .header_type = IW_HEADER_TYPE_PARAM, 194 .header_type = IW_HEADER_TYPE_PARAM,
195 }, 195 },
196 [SIOCSIWRETRY - SIOCIWFIRST] = { 196 [IW_IOCTL_IDX(SIOCSIWRETRY)] = {
197 .header_type = IW_HEADER_TYPE_PARAM, 197 .header_type = IW_HEADER_TYPE_PARAM,
198 }, 198 },
199 [SIOCGIWRETRY - SIOCIWFIRST] = { 199 [IW_IOCTL_IDX(SIOCGIWRETRY)] = {
200 .header_type = IW_HEADER_TYPE_PARAM, 200 .header_type = IW_HEADER_TYPE_PARAM,
201 }, 201 },
202 [SIOCSIWENCODE - SIOCIWFIRST] = { 202 [IW_IOCTL_IDX(SIOCSIWENCODE)] = {
203 .header_type = IW_HEADER_TYPE_POINT, 203 .header_type = IW_HEADER_TYPE_POINT,
204 .token_size = 1, 204 .token_size = 1,
205 .max_tokens = IW_ENCODING_TOKEN_MAX, 205 .max_tokens = IW_ENCODING_TOKEN_MAX,
206 .flags = IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT, 206 .flags = IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT,
207 }, 207 },
208 [SIOCGIWENCODE - SIOCIWFIRST] = { 208 [IW_IOCTL_IDX(SIOCGIWENCODE)] = {
209 .header_type = IW_HEADER_TYPE_POINT, 209 .header_type = IW_HEADER_TYPE_POINT,
210 .token_size = 1, 210 .token_size = 1,
211 .max_tokens = IW_ENCODING_TOKEN_MAX, 211 .max_tokens = IW_ENCODING_TOKEN_MAX,
212 .flags = IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT, 212 .flags = IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT,
213 }, 213 },
214 [SIOCSIWPOWER - SIOCIWFIRST] = { 214 [IW_IOCTL_IDX(SIOCSIWPOWER)] = {
215 .header_type = IW_HEADER_TYPE_PARAM, 215 .header_type = IW_HEADER_TYPE_PARAM,
216 }, 216 },
217 [SIOCGIWPOWER - SIOCIWFIRST] = { 217 [IW_IOCTL_IDX(SIOCGIWPOWER)] = {
218 .header_type = IW_HEADER_TYPE_PARAM, 218 .header_type = IW_HEADER_TYPE_PARAM,
219 }, 219 },
220 [SIOCSIWGENIE - SIOCIWFIRST] = { 220 [IW_IOCTL_IDX(SIOCSIWGENIE)] = {
221 .header_type = IW_HEADER_TYPE_POINT, 221 .header_type = IW_HEADER_TYPE_POINT,
222 .token_size = 1, 222 .token_size = 1,
223 .max_tokens = IW_GENERIC_IE_MAX, 223 .max_tokens = IW_GENERIC_IE_MAX,
224 }, 224 },
225 [SIOCGIWGENIE - SIOCIWFIRST] = { 225 [IW_IOCTL_IDX(SIOCGIWGENIE)] = {
226 .header_type = IW_HEADER_TYPE_POINT, 226 .header_type = IW_HEADER_TYPE_POINT,
227 .token_size = 1, 227 .token_size = 1,
228 .max_tokens = IW_GENERIC_IE_MAX, 228 .max_tokens = IW_GENERIC_IE_MAX,
229 }, 229 },
230 [SIOCSIWAUTH - SIOCIWFIRST] = { 230 [IW_IOCTL_IDX(SIOCSIWAUTH)] = {
231 .header_type = IW_HEADER_TYPE_PARAM, 231 .header_type = IW_HEADER_TYPE_PARAM,
232 }, 232 },
233 [SIOCGIWAUTH - SIOCIWFIRST] = { 233 [IW_IOCTL_IDX(SIOCGIWAUTH)] = {
234 .header_type = IW_HEADER_TYPE_PARAM, 234 .header_type = IW_HEADER_TYPE_PARAM,
235 }, 235 },
236 [SIOCSIWENCODEEXT - SIOCIWFIRST] = { 236 [IW_IOCTL_IDX(SIOCSIWENCODEEXT)] = {
237 .header_type = IW_HEADER_TYPE_POINT, 237 .header_type = IW_HEADER_TYPE_POINT,
238 .token_size = 1, 238 .token_size = 1,
239 .min_tokens = sizeof(struct iw_encode_ext), 239 .min_tokens = sizeof(struct iw_encode_ext),
240 .max_tokens = sizeof(struct iw_encode_ext) + 240 .max_tokens = sizeof(struct iw_encode_ext) +
241 IW_ENCODING_TOKEN_MAX, 241 IW_ENCODING_TOKEN_MAX,
242 }, 242 },
243 [SIOCGIWENCODEEXT - SIOCIWFIRST] = { 243 [IW_IOCTL_IDX(SIOCGIWENCODEEXT)] = {
244 .header_type = IW_HEADER_TYPE_POINT, 244 .header_type = IW_HEADER_TYPE_POINT,
245 .token_size = 1, 245 .token_size = 1,
246 .min_tokens = sizeof(struct iw_encode_ext), 246 .min_tokens = sizeof(struct iw_encode_ext),
247 .max_tokens = sizeof(struct iw_encode_ext) + 247 .max_tokens = sizeof(struct iw_encode_ext) +
248 IW_ENCODING_TOKEN_MAX, 248 IW_ENCODING_TOKEN_MAX,
249 }, 249 },
250 [SIOCSIWPMKSA - SIOCIWFIRST] = { 250 [IW_IOCTL_IDX(SIOCSIWPMKSA)] = {
251 .header_type = IW_HEADER_TYPE_POINT, 251 .header_type = IW_HEADER_TYPE_POINT,
252 .token_size = 1, 252 .token_size = 1,
253 .min_tokens = sizeof(struct iw_pmksa), 253 .min_tokens = sizeof(struct iw_pmksa),
@@ -261,44 +261,44 @@ static const unsigned standard_ioctl_num = ARRAY_SIZE(standard_ioctl);
261 * we know about. 261 * we know about.
262 */ 262 */
263static const struct iw_ioctl_description standard_event[] = { 263static const struct iw_ioctl_description standard_event[] = {
264 [IWEVTXDROP - IWEVFIRST] = { 264 [IW_EVENT_IDX(IWEVTXDROP)] = {
265 .header_type = IW_HEADER_TYPE_ADDR, 265 .header_type = IW_HEADER_TYPE_ADDR,
266 }, 266 },
267 [IWEVQUAL - IWEVFIRST] = { 267 [IW_EVENT_IDX(IWEVQUAL)] = {
268 .header_type = IW_HEADER_TYPE_QUAL, 268 .header_type = IW_HEADER_TYPE_QUAL,
269 }, 269 },
270 [IWEVCUSTOM - IWEVFIRST] = { 270 [IW_EVENT_IDX(IWEVCUSTOM)] = {
271 .header_type = IW_HEADER_TYPE_POINT, 271 .header_type = IW_HEADER_TYPE_POINT,
272 .token_size = 1, 272 .token_size = 1,
273 .max_tokens = IW_CUSTOM_MAX, 273 .max_tokens = IW_CUSTOM_MAX,
274 }, 274 },
275 [IWEVREGISTERED - IWEVFIRST] = { 275 [IW_EVENT_IDX(IWEVREGISTERED)] = {
276 .header_type = IW_HEADER_TYPE_ADDR, 276 .header_type = IW_HEADER_TYPE_ADDR,
277 }, 277 },
278 [IWEVEXPIRED - IWEVFIRST] = { 278 [IW_EVENT_IDX(IWEVEXPIRED)] = {
279 .header_type = IW_HEADER_TYPE_ADDR, 279 .header_type = IW_HEADER_TYPE_ADDR,
280 }, 280 },
281 [IWEVGENIE - IWEVFIRST] = { 281 [IW_EVENT_IDX(IWEVGENIE)] = {
282 .header_type = IW_HEADER_TYPE_POINT, 282 .header_type = IW_HEADER_TYPE_POINT,
283 .token_size = 1, 283 .token_size = 1,
284 .max_tokens = IW_GENERIC_IE_MAX, 284 .max_tokens = IW_GENERIC_IE_MAX,
285 }, 285 },
286 [IWEVMICHAELMICFAILURE - IWEVFIRST] = { 286 [IW_EVENT_IDX(IWEVMICHAELMICFAILURE)] = {
287 .header_type = IW_HEADER_TYPE_POINT, 287 .header_type = IW_HEADER_TYPE_POINT,
288 .token_size = 1, 288 .token_size = 1,
289 .max_tokens = sizeof(struct iw_michaelmicfailure), 289 .max_tokens = sizeof(struct iw_michaelmicfailure),
290 }, 290 },
291 [IWEVASSOCREQIE - IWEVFIRST] = { 291 [IW_EVENT_IDX(IWEVASSOCREQIE)] = {
292 .header_type = IW_HEADER_TYPE_POINT, 292 .header_type = IW_HEADER_TYPE_POINT,
293 .token_size = 1, 293 .token_size = 1,
294 .max_tokens = IW_GENERIC_IE_MAX, 294 .max_tokens = IW_GENERIC_IE_MAX,
295 }, 295 },
296 [IWEVASSOCRESPIE - IWEVFIRST] = { 296 [IW_EVENT_IDX(IWEVASSOCRESPIE)] = {
297 .header_type = IW_HEADER_TYPE_POINT, 297 .header_type = IW_HEADER_TYPE_POINT,
298 .token_size = 1, 298 .token_size = 1,
299 .max_tokens = IW_GENERIC_IE_MAX, 299 .max_tokens = IW_GENERIC_IE_MAX,
300 }, 300 },
301 [IWEVPMKIDCAND - IWEVFIRST] = { 301 [IW_EVENT_IDX(IWEVPMKIDCAND)] = {
302 .header_type = IW_HEADER_TYPE_POINT, 302 .header_type = IW_HEADER_TYPE_POINT,
303 .token_size = 1, 303 .token_size = 1,
304 .max_tokens = sizeof(struct iw_pmkid_cand), 304 .max_tokens = sizeof(struct iw_pmkid_cand),
@@ -449,11 +449,11 @@ void wireless_send_event(struct net_device * dev,
449 449
450 /* Get the description of the Event */ 450 /* Get the description of the Event */
451 if (cmd <= SIOCIWLAST) { 451 if (cmd <= SIOCIWLAST) {
452 cmd_index = cmd - SIOCIWFIRST; 452 cmd_index = IW_IOCTL_IDX(cmd);
453 if (cmd_index < standard_ioctl_num) 453 if (cmd_index < standard_ioctl_num)
454 descr = &(standard_ioctl[cmd_index]); 454 descr = &(standard_ioctl[cmd_index]);
455 } else { 455 } else {
456 cmd_index = cmd - IWEVFIRST; 456 cmd_index = IW_EVENT_IDX(cmd);
457 if (cmd_index < standard_event_num) 457 if (cmd_index < standard_event_num)
458 descr = &(standard_event[cmd_index]); 458 descr = &(standard_event[cmd_index]);
459 } 459 }
@@ -662,7 +662,7 @@ static iw_handler get_handler(struct net_device *dev, unsigned int cmd)
662 return NULL; 662 return NULL;
663 663
664 /* Try as a standard command */ 664 /* Try as a standard command */
665 index = cmd - SIOCIWFIRST; 665 index = IW_IOCTL_IDX(cmd);
666 if (index < handlers->num_standard) 666 if (index < handlers->num_standard)
667 return handlers->standard[index]; 667 return handlers->standard[index];
668 668
@@ -954,9 +954,9 @@ static int ioctl_standard_call(struct net_device * dev,
954 int ret = -EINVAL; 954 int ret = -EINVAL;
955 955
956 /* Get the description of the IOCTL */ 956 /* Get the description of the IOCTL */
957 if ((cmd - SIOCIWFIRST) >= standard_ioctl_num) 957 if (IW_IOCTL_IDX(cmd) >= standard_ioctl_num)
958 return -EOPNOTSUPP; 958 return -EOPNOTSUPP;
959 descr = &(standard_ioctl[cmd - SIOCIWFIRST]); 959 descr = &(standard_ioctl[IW_IOCTL_IDX(cmd)]);
960 960
961 /* Check if we have a pointer to user space data or not */ 961 /* Check if we have a pointer to user space data or not */
962 if (descr->header_type != IW_HEADER_TYPE_POINT) { 962 if (descr->header_type != IW_HEADER_TYPE_POINT) {
@@ -1012,7 +1012,7 @@ static int compat_standard_call(struct net_device *dev,
1012 struct iw_point iwp; 1012 struct iw_point iwp;
1013 int err; 1013 int err;
1014 1014
1015 descr = standard_ioctl + (cmd - SIOCIWFIRST); 1015 descr = standard_ioctl + IW_IOCTL_IDX(cmd);
1016 1016
1017 if (descr->header_type != IW_HEADER_TYPE_POINT) 1017 if (descr->header_type != IW_HEADER_TYPE_POINT)
1018 return ioctl_standard_call(dev, iwr, cmd, info, handler); 1018 return ioctl_standard_call(dev, iwr, cmd, info, handler);