aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-27 20:35:07 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-27 20:35:07 -0400
commit0870352bc6e0dee485c86a0c99dd60e7089c8917 (patch)
tree0c6259b663350594bff4f128e12f8bd6d4c769c1
parentc44a4366649aca4f5b4a51ff71d4c9cde3b7c9da (diff)
parent8a5117d80fe93de5df5b56480054f7df1fd20755 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
-rw-r--r--Documentation/DocBook/mac80211.tmpl6
-rw-r--r--Documentation/feature-removal-schedule.txt37
-rw-r--r--MAINTAINERS10
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/ar9170/Kconfig17
-rw-r--r--drivers/net/wireless/ar9170/Makefile3
-rw-r--r--drivers/net/wireless/ar9170/ar9170.h209
-rw-r--r--drivers/net/wireless/ar9170/cmd.c129
-rw-r--r--drivers/net/wireless/ar9170/cmd.h91
-rw-r--r--drivers/net/wireless/ar9170/eeprom.h179
-rw-r--r--drivers/net/wireless/ar9170/hw.h417
-rw-r--r--drivers/net/wireless/ar9170/led.c171
-rw-r--r--drivers/net/wireless/ar9170/mac.c452
-rw-r--r--drivers/net/wireless/ar9170/main.c1671
-rw-r--r--drivers/net/wireless/ar9170/phy.c1240
-rw-r--r--drivers/net/wireless/ar9170/usb.c748
-rw-r--r--drivers/net/wireless/ar9170/usb.h74
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h35
-rw-r--r--drivers/net/wireless/ath5k/attach.c2
-rw-r--r--drivers/net/wireless/ath5k/base.c46
-rw-r--r--drivers/net/wireless/ath5k/base.h2
-rw-r--r--drivers/net/wireless/ath5k/desc.c4
-rw-r--r--drivers/net/wireless/ath5k/eeprom.c774
-rw-r--r--drivers/net/wireless/ath5k/eeprom.h128
-rw-r--r--drivers/net/wireless/ath5k/initvals.c4
-rw-r--r--drivers/net/wireless/ath5k/led.c2
-rw-r--r--drivers/net/wireless/ath5k/phy.c1170
-rw-r--r--drivers/net/wireless/ath5k/reg.h19
-rw-r--r--drivers/net/wireless/ath5k/reset.c35
-rw-r--r--drivers/net/wireless/ath9k/ahb.c2
-rw-r--r--drivers/net/wireless/ath9k/ani.c2
-rw-r--r--drivers/net/wireless/ath9k/ani.h2
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h9
-rw-r--r--drivers/net/wireless/ath9k/beacon.c56
-rw-r--r--drivers/net/wireless/ath9k/calib.c2
-rw-r--r--drivers/net/wireless/ath9k/calib.h2
-rw-r--r--drivers/net/wireless/ath9k/debug.c2
-rw-r--r--drivers/net/wireless/ath9k/debug.h2
-rw-r--r--drivers/net/wireless/ath9k/eeprom.c308
-rw-r--r--drivers/net/wireless/ath9k/eeprom.h5
-rw-r--r--drivers/net/wireless/ath9k/hw.c14
-rw-r--r--drivers/net/wireless/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath9k/initvals.h2
-rw-r--r--drivers/net/wireless/ath9k/mac.c2
-rw-r--r--drivers/net/wireless/ath9k/mac.h2
-rw-r--r--drivers/net/wireless/ath9k/main.c47
-rw-r--r--drivers/net/wireless/ath9k/pci.c20
-rw-r--r--drivers/net/wireless/ath9k/phy.c2
-rw-r--r--drivers/net/wireless/ath9k/phy.h2
-rw-r--r--drivers/net/wireless/ath9k/rc.c23
-rw-r--r--drivers/net/wireless/ath9k/rc.h2
-rw-r--r--drivers/net/wireless/ath9k/recv.c9
-rw-r--r--drivers/net/wireless/ath9k/reg.h2
-rw-r--r--drivers/net/wireless/ath9k/regd.c2
-rw-r--r--drivers/net/wireless/ath9k/regd.h2
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h2
-rw-r--r--drivers/net/wireless/ath9k/xmit.c78
-rw-r--r--drivers/net/wireless/b43/main.c2
-rw-r--r--drivers/net/wireless/b43/xmit.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c179
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c38
-rw-r--r--drivers/net/wireless/libertas/radiotap.h10
-rw-r--r--drivers/net/wireless/libertas/rx.c12
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c4
-rw-r--r--drivers/net/wireless/p54/Kconfig39
-rw-r--r--drivers/net/wireless/p54/p54common.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/ssb/Kconfig16
-rw-r--r--drivers/ssb/b43_pci_bridge.c1
-rw-r--r--include/linux/ieee80211.h17
-rw-r--r--include/linux/nl80211.h88
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/net/cfg80211.h203
-rw-r--r--include/net/ieee80211_radiotap.h4
-rw-r--r--include/net/mac80211.h84
-rw-r--r--net/mac80211/agg-rx.c8
-rw-r--r--net/mac80211/agg-tx.c232
-rw-r--r--net/mac80211/cfg.c245
-rw-r--r--net/mac80211/debugfs.c24
-rw-r--r--net/mac80211/ibss.c3
-rw-r--r--net/mac80211/ieee80211_i.h78
-rw-r--r--net/mac80211/iface.c14
-rw-r--r--net/mac80211/main.c25
-rw-r--r--net/mac80211/mlme.c259
-rw-r--r--net/mac80211/pm.c78
-rw-r--r--net/mac80211/rate.c6
-rw-r--r--net/mac80211/rate.h4
-rw-r--r--net/mac80211/rx.c29
-rw-r--r--net/mac80211/scan.c77
-rw-r--r--net/mac80211/sta_info.c17
-rw-r--r--net/mac80211/sta_info.h7
-rw-r--r--net/mac80211/tx.c579
-rw-r--r--net/mac80211/util.c126
-rw-r--r--net/mac80211/wep.c21
-rw-r--r--net/mac80211/wext.c33
-rw-r--r--net/mac80211/wpa.c28
-rw-r--r--net/wireless/Kconfig50
-rw-r--r--net/wireless/Makefile3
-rw-r--r--net/wireless/core.c30
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/mlme.c46
-rw-r--r--net/wireless/nl80211.c824
-rw-r--r--net/wireless/nl80211.h38
-rw-r--r--net/wireless/reg.c65
-rw-r--r--net/wireless/scan.c27
-rw-r--r--net/wireless/wext-compat.c11
120 files changed, 10099 insertions, 2094 deletions
diff --git a/Documentation/DocBook/mac80211.tmpl b/Documentation/DocBook/mac80211.tmpl
index 8af6d9626878..fbeaffc1dcc3 100644
--- a/Documentation/DocBook/mac80211.tmpl
+++ b/Documentation/DocBook/mac80211.tmpl
@@ -227,6 +227,12 @@ usage should require reading the full document.
227!Pinclude/net/mac80211.h Powersave support 227!Pinclude/net/mac80211.h Powersave support
228 </chapter> 228 </chapter>
229 229
230 <chapter id="beacon-filter">
231 <title>Beacon filter support</title>
232!Pinclude/net/mac80211.h Beacon filter support
233!Finclude/net/mac80211.h ieee80211_beacon_loss
234 </chapter>
235
230 <chapter id="qos"> 236 <chapter id="qos">
231 <title>Multiple queues and QoS support</title> 237 <title>Multiple queues and QoS support</title>
232 <para>TBD</para> 238 <para>TBD</para>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index e47c0ff8ba7a..02ea3773535e 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,20 +6,47 @@ be removed from this file.
6 6
7--------------------------- 7---------------------------
8 8
9What: old static regulatory information and ieee80211_regdom module parameter 9What: The ieee80211_regdom module parameter
10When: 2.6.29 10When: March 2010 / desktop catchup
11
12Why: This was inherited by the CONFIG_WIRELESS_OLD_REGULATORY code,
13 and currently serves as an option for users to define an
14 ISO / IEC 3166 alpha2 code for the country they are currently
15 present in. Although there are userspace API replacements for this
16 through nl80211 distributions haven't yet caught up with implementing
17 decent alternatives through standard GUIs. Although available as an
18 option through iw or wpa_supplicant its just a matter of time before
19 distributions pick up good GUI options for this. The ideal solution
20 would actually consist of intelligent designs which would do this for
21 the user automatically even when travelling through different countries.
22 Until then we leave this module parameter as a compromise.
23
24 When userspace improves with reasonable widely-available alternatives for
25 this we will no longer need this module parameter. This entry hopes that
26 by the super-futuristically looking date of "March 2010" we will have
27 such replacements widely available.
28
29Who: Luis R. Rodriguez <lrodriguez@atheros.com>
30
31---------------------------
32
33What: CONFIG_WIRELESS_OLD_REGULATORY - old static regulatory information
34When: March 2010 / desktop catchup
35
11Why: The old regulatory infrastructure has been replaced with a new one 36Why: The old regulatory infrastructure has been replaced with a new one
12 which does not require statically defined regulatory domains. We do 37 which does not require statically defined regulatory domains. We do
13 not want to keep static regulatory domains in the kernel due to the 38 not want to keep static regulatory domains in the kernel due to the
14 the dynamic nature of regulatory law and localization. We kept around 39 the dynamic nature of regulatory law and localization. We kept around
15 the old static definitions for the regulatory domains of: 40 the old static definitions for the regulatory domains of:
41
16 * US 42 * US
17 * JP 43 * JP
18 * EU 44 * EU
45
19 and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was 46 and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was
20 set. We also kept around the ieee80211_regdom module parameter in case 47 set. We will remove this option once the standard Linux desktop catches
21 some applications were relying on it. Changing regulatory domains 48 up with the new userspace APIs we have implemented.
22 can now be done instead by using nl80211, as is done with iw. 49
23Who: Luis R. Rodriguez <lrodriguez@atheros.com> 50Who: Luis R. Rodriguez <lrodriguez@atheros.com>
24 51
25--------------------------- 52---------------------------
diff --git a/MAINTAINERS b/MAINTAINERS
index fa7be04b0cf0..64c89c215b01 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -765,6 +765,14 @@ L: linux-wireless@vger.kernel.org
765L: ath9k-devel@lists.ath9k.org 765L: ath9k-devel@lists.ath9k.org
766S: Supported 766S: Supported
767 767
768ATHEROS AR9170 WIRELESS DRIVER
769P: Christian Lamparter
770M: chunkeey@web.de
771L: linux-wireless@vger.kernel.org
772W: http://wireless.kernel.org/en/users/Drivers/ar9170
773S: Maintained
774F: drivers/net/wireless/ar9170/
775
768ATI_REMOTE2 DRIVER 776ATI_REMOTE2 DRIVER
769P: Ville Syrjala 777P: Ville Syrjala
770M: syrjala@sci.fi 778M: syrjala@sci.fi
@@ -3602,7 +3610,7 @@ S: Maintained
3602RALINK RT2X00 WIRELESS LAN DRIVER 3610RALINK RT2X00 WIRELESS LAN DRIVER
3603P: rt2x00 project 3611P: rt2x00 project
3604L: linux-wireless@vger.kernel.org 3612L: linux-wireless@vger.kernel.org
3605L: rt2400-devel@lists.sourceforge.net 3613L: users@rt2x00.serialmonkey.com
3606W: http://rt2x00.serialmonkey.com/ 3614W: http://rt2x00.serialmonkey.com/
3607S: Maintained 3615S: Maintained
3608T: git kernel.org:/pub/scm/linux/kernel/git/ivd/rt2x00.git 3616T: git kernel.org:/pub/scm/linux/kernel/git/ivd/rt2x00.git
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 612fffe100a6..8a0823588c51 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -485,6 +485,7 @@ config MWL8K
485source "drivers/net/wireless/p54/Kconfig" 485source "drivers/net/wireless/p54/Kconfig"
486source "drivers/net/wireless/ath5k/Kconfig" 486source "drivers/net/wireless/ath5k/Kconfig"
487source "drivers/net/wireless/ath9k/Kconfig" 487source "drivers/net/wireless/ath9k/Kconfig"
488source "drivers/net/wireless/ar9170/Kconfig"
488source "drivers/net/wireless/ipw2x00/Kconfig" 489source "drivers/net/wireless/ipw2x00/Kconfig"
489source "drivers/net/wireless/iwlwifi/Kconfig" 490source "drivers/net/wireless/iwlwifi/Kconfig"
490source "drivers/net/wireless/hostap/Kconfig" 491source "drivers/net/wireless/hostap/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index d780487c420f..50e7fba7f0ea 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -57,5 +57,6 @@ obj-$(CONFIG_P54_COMMON) += p54/
57 57
58obj-$(CONFIG_ATH5K) += ath5k/ 58obj-$(CONFIG_ATH5K) += ath5k/
59obj-$(CONFIG_ATH9K) += ath9k/ 59obj-$(CONFIG_ATH9K) += ath9k/
60obj-$(CONFIG_AR9170_USB) += ar9170/
60 61
61obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o 62obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
diff --git a/drivers/net/wireless/ar9170/Kconfig b/drivers/net/wireless/ar9170/Kconfig
new file mode 100644
index 000000000000..de4281fda129
--- /dev/null
+++ b/drivers/net/wireless/ar9170/Kconfig
@@ -0,0 +1,17 @@
1config AR9170_USB
2 tristate "Atheros AR9170 802.11n USB support"
3 depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
4 select FW_LOADER
5 help
6 This is a driver for the Atheros "otus" 802.11n USB devices.
7
8 These devices require additional firmware (2 files).
9 For now, these files can be downloaded from here:
10 http://wireless.kernel.org/en/users/Drivers/ar9170
11
12 If you choose to build a module, it'll be called ar9170usb.
13
14config AR9170_LEDS
15 bool
16 depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
17 default y
diff --git a/drivers/net/wireless/ar9170/Makefile b/drivers/net/wireless/ar9170/Makefile
new file mode 100644
index 000000000000..8d91c7ee3215
--- /dev/null
+++ b/drivers/net/wireless/ar9170/Makefile
@@ -0,0 +1,3 @@
1ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
2
3obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ar9170/ar9170.h
new file mode 100644
index 000000000000..f4fb2e94aea0
--- /dev/null
+++ b/drivers/net/wireless/ar9170/ar9170.h
@@ -0,0 +1,209 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * Driver specific definitions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#ifndef __AR9170_H
39#define __AR9170_H
40
41#include <linux/completion.h>
42#include <linux/spinlock.h>
43#include <net/wireless.h>
44#include <net/mac80211.h>
45#ifdef CONFIG_AR9170_LEDS
46#include <linux/leds.h>
47#endif /* CONFIG_AR9170_LEDS */
48#include "eeprom.h"
49#include "hw.h"
50
51#define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1)
52
53enum ar9170_bw {
54 AR9170_BW_20,
55 AR9170_BW_40_BELOW,
56 AR9170_BW_40_ABOVE,
57
58 __AR9170_NUM_BW,
59};
60
61enum ar9170_rf_init_mode {
62 AR9170_RFI_NONE,
63 AR9170_RFI_WARM,
64 AR9170_RFI_COLD,
65};
66
67#define AR9170_MAX_RX_BUFFER_SIZE 8192
68
69#ifdef CONFIG_AR9170_LEDS
70struct ar9170;
71
72struct ar9170_led {
73 struct ar9170 *ar;
74 struct led_classdev l;
75 char name[32];
76 unsigned int toggled;
77 bool registered;
78};
79
80#endif /* CONFIG_AR9170_LEDS */
81
82enum ar9170_device_state {
83 AR9170_UNKNOWN_STATE,
84 AR9170_STOPPED,
85 AR9170_IDLE,
86 AR9170_STARTED,
87 AR9170_ASSOCIATED,
88};
89
90struct ar9170 {
91 struct ieee80211_hw *hw;
92 struct mutex mutex;
93 enum ar9170_device_state state;
94
95 int (*open)(struct ar9170 *);
96 void (*stop)(struct ar9170 *);
97 int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int);
98 int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
99 void *, u32 , void *);
100 void (*callback_cmd)(struct ar9170 *, u32 , void *);
101
102 /* interface mode settings */
103 struct ieee80211_vif *vif;
104 u8 mac_addr[ETH_ALEN];
105 u8 bssid[ETH_ALEN];
106
107 /* beaconing */
108 struct sk_buff *beacon;
109 struct work_struct beacon_work;
110
111 /* cryptographic engine */
112 u64 usedkeys;
113 bool rx_software_decryption;
114 bool disable_offload;
115
116 /* filter settings */
117 struct work_struct filter_config_work;
118 u64 cur_mc_hash, want_mc_hash;
119 u32 cur_filter, want_filter;
120 unsigned int filter_changed;
121 bool sniffer_enabled;
122
123 /* PHY */
124 struct ieee80211_channel *channel;
125 int noise[4];
126
127 /* power calibration data */
128 u8 power_5G_leg[4];
129 u8 power_2G_cck[4];
130 u8 power_2G_ofdm[4];
131 u8 power_5G_ht20[8];
132 u8 power_5G_ht40[8];
133 u8 power_2G_ht20[8];
134 u8 power_2G_ht40[8];
135
136#ifdef CONFIG_AR9170_LEDS
137 struct delayed_work led_work;
138 struct ar9170_led leds[AR9170_NUM_LEDS];
139#endif /* CONFIG_AR9170_LEDS */
140
141 /* qos queue settings */
142 spinlock_t tx_stats_lock;
143 struct ieee80211_tx_queue_stats tx_stats[5];
144 struct ieee80211_tx_queue_params edcf[5];
145
146 spinlock_t cmdlock;
147 __le32 cmdbuf[PAYLOAD_MAX + 1];
148
149 /* MAC statistics */
150 struct ieee80211_low_level_stats stats;
151
152 /* EEPROM */
153 struct ar9170_eeprom eeprom;
154
155 /* global tx status for unregistered Stations. */
156 struct sk_buff_head global_tx_status;
157 struct sk_buff_head global_tx_status_waste;
158 struct delayed_work tx_status_janitor;
159};
160
161struct ar9170_sta_info {
162 struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
163};
164
165#define IS_STARTED(a) (a->state >= AR9170_STARTED)
166#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE)
167
168#define AR9170_FILTER_CHANGED_PROMISC BIT(0)
169#define AR9170_FILTER_CHANGED_MULTICAST BIT(1)
170#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2)
171
172/* exported interface */
173void *ar9170_alloc(size_t priv_size);
174int ar9170_register(struct ar9170 *ar, struct device *pdev);
175void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
176void ar9170_unregister(struct ar9170 *ar);
177void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
178 bool update_statistics, u16 tx_status);
179
180/* MAC */
181int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
182int ar9170_init_mac(struct ar9170 *ar);
183int ar9170_set_qos(struct ar9170 *ar);
184int ar9170_update_multicast(struct ar9170 *ar);
185int ar9170_update_frame_filter(struct ar9170 *ar);
186int ar9170_set_operating_mode(struct ar9170 *ar);
187int ar9170_set_beacon_timers(struct ar9170 *ar);
188int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
189int ar9170_update_beacon(struct ar9170 *ar);
190void ar9170_new_beacon(struct work_struct *work);
191int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
192 u8 keyidx, u8 *keydata, int keylen);
193int ar9170_disable_key(struct ar9170 *ar, u8 id);
194
195/* LEDs */
196#ifdef CONFIG_AR9170_LEDS
197int ar9170_register_leds(struct ar9170 *ar);
198void ar9170_unregister_leds(struct ar9170 *ar);
199#endif /* CONFIG_AR9170_LEDS */
200int ar9170_init_leds(struct ar9170 *ar);
201int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
202
203/* PHY / RF */
204int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
205int ar9170_init_rf(struct ar9170 *ar);
206int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
207 enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
208
209#endif /* __AR9170_H */
diff --git a/drivers/net/wireless/ar9170/cmd.c b/drivers/net/wireless/ar9170/cmd.c
new file mode 100644
index 000000000000..f57a6200167b
--- /dev/null
+++ b/drivers/net/wireless/ar9170/cmd.c
@@ -0,0 +1,129 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * Basic HW register/memory/command access functions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38
39#include "ar9170.h"
40#include "cmd.h"
41
42int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
43{
44 int err;
45
46 if (unlikely(!IS_ACCEPTING_CMD(ar)))
47 return 0;
48
49 err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
50 if (err)
51 printk(KERN_DEBUG "%s: writing memory failed\n",
52 wiphy_name(ar->hw->wiphy));
53 return err;
54}
55
56int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
57{
58 __le32 buf[2] = {
59 cpu_to_le32(reg),
60 cpu_to_le32(val),
61 };
62 int err;
63
64 if (unlikely(!IS_ACCEPTING_CMD(ar)))
65 return 0;
66
67 err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
68 (u8 *) buf, 0, NULL);
69 if (err)
70 printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
71 wiphy_name(ar->hw->wiphy), reg, val);
72 return err;
73}
74
75static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
76 const u32 *regs, u32 *out)
77{
78 int i, err;
79 __le32 *offs, *res;
80
81 if (unlikely(!IS_ACCEPTING_CMD(ar)))
82 return 0;
83
84 /* abuse "out" for the register offsets, must be same length */
85 offs = (__le32 *)out;
86 for (i = 0; i < nregs; i++)
87 offs[i] = cpu_to_le32(regs[i]);
88
89 /* also use the same buffer for the input */
90 res = (__le32 *)out;
91
92 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
93 4 * nregs, (u8 *)offs,
94 4 * nregs, (u8 *)res);
95 if (err)
96 return err;
97
98 /* convert result to cpu endian */
99 for (i = 0; i < nregs; i++)
100 out[i] = le32_to_cpu(res[i]);
101
102 return 0;
103}
104
105int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
106{
107 return ar9170_read_mreg(ar, 1, &reg, val);
108}
109
110int ar9170_echo_test(struct ar9170 *ar, u32 v)
111{
112 __le32 echobuf = cpu_to_le32(v);
113 __le32 echores;
114 int err;
115
116 if (unlikely(!IS_ACCEPTING_CMD(ar)))
117 return -ENODEV;
118
119 err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
120 4, (u8 *)&echobuf,
121 4, (u8 *)&echores);
122 if (err)
123 return err;
124
125 if (echobuf != echores)
126 return -EINVAL;
127
128 return 0;
129}
diff --git a/drivers/net/wireless/ar9170/cmd.h b/drivers/net/wireless/ar9170/cmd.h
new file mode 100644
index 000000000000..a4f0e50e52b4
--- /dev/null
+++ b/drivers/net/wireless/ar9170/cmd.h
@@ -0,0 +1,91 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * Basic HW register/memory/command access functions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#ifndef __CMD_H
39#define __CMD_H
40
41#include "ar9170.h"
42
43/* basic HW access */
44int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
45int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
46int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
47int ar9170_echo_test(struct ar9170 *ar, u32 v);
48
49/*
50 * Macros to facilitate writing multiple registers in a single
51 * write-combining USB command. Note that when the first group
52 * fails the whole thing will fail without any others attempted,
53 * but you won't know which write in the group failed.
54 */
55#define ar9170_regwrite_begin(ar) \
56do { \
57 int __nreg = 0, __err = 0; \
58 struct ar9170 *__ar = ar;
59
60#define ar9170_regwrite(r, v) do { \
61 __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r); \
62 __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v); \
63 __nreg++; \
64 if ((__nreg >= PAYLOAD_MAX/2)) { \
65 if (IS_ACCEPTING_CMD(__ar)) \
66 __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
67 8 * __nreg, \
68 (u8 *) &__ar->cmdbuf[1], \
69 0, NULL); \
70 __nreg = 0; \
71 if (__err) \
72 goto __regwrite_out; \
73 } \
74} while (0)
75
76#define ar9170_regwrite_finish() \
77__regwrite_out : \
78 if (__nreg) { \
79 if (IS_ACCEPTING_CMD(__ar)) \
80 __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
81 8 * __nreg, \
82 (u8 *) &__ar->cmdbuf[1], \
83 0, NULL); \
84 __nreg = 0; \
85 }
86
87#define ar9170_regwrite_result() \
88 __err; \
89} while (0);
90
91#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ar9170/eeprom.h b/drivers/net/wireless/ar9170/eeprom.h
new file mode 100644
index 000000000000..d2c8cc83f1dd
--- /dev/null
+++ b/drivers/net/wireless/ar9170/eeprom.h
@@ -0,0 +1,179 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * EEPROM layout
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#ifndef __AR9170_EEPROM_H
39#define __AR9170_EEPROM_H
40
41#define AR5416_MAX_CHAINS 2
42#define AR5416_MODAL_SPURS 5
43
44struct ar9170_eeprom_modal {
45 __le32 antCtrlChain[AR5416_MAX_CHAINS];
46 __le32 antCtrlCommon;
47 s8 antennaGainCh[AR5416_MAX_CHAINS];
48 u8 switchSettling;
49 u8 txRxAttenCh[AR5416_MAX_CHAINS];
50 u8 rxTxMarginCh[AR5416_MAX_CHAINS];
51 s8 adcDesiredSize;
52 s8 pgaDesiredSize;
53 u8 xlnaGainCh[AR5416_MAX_CHAINS];
54 u8 txEndToXpaOff;
55 u8 txEndToRxOn;
56 u8 txFrameToXpaOn;
57 u8 thresh62;
58 s8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
59 u8 xpdGain;
60 u8 xpd;
61 s8 iqCalICh[AR5416_MAX_CHAINS];
62 s8 iqCalQCh[AR5416_MAX_CHAINS];
63 u8 pdGainOverlap;
64 u8 ob;
65 u8 db;
66 u8 xpaBiasLvl;
67 u8 pwrDecreaseFor2Chain;
68 u8 pwrDecreaseFor3Chain;
69 u8 txFrameToDataStart;
70 u8 txFrameToPaOn;
71 u8 ht40PowerIncForPdadc;
72 u8 bswAtten[AR5416_MAX_CHAINS];
73 u8 bswMargin[AR5416_MAX_CHAINS];
74 u8 swSettleHt40;
75 u8 reserved[22];
76 struct spur_channel {
77 __le16 spurChan;
78 u8 spurRangeLow;
79 u8 spurRangeHigh;
80 } __packed spur_channels[AR5416_MODAL_SPURS];
81} __packed;
82
83#define AR5416_NUM_PD_GAINS 4
84#define AR5416_PD_GAIN_ICEPTS 5
85
86struct ar9170_calibration_data_per_freq {
87 u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
88 u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
89} __packed;
90
91#define AR5416_NUM_5G_CAL_PIERS 8
92#define AR5416_NUM_2G_CAL_PIERS 4
93
94#define AR5416_NUM_5G_TARGET_PWRS 8
95#define AR5416_NUM_2G_CCK_TARGET_PWRS 3
96#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
97#define AR5416_MAX_NUM_TGT_PWRS 8
98
99struct ar9170_calibration_target_power_legacy {
100 u8 freq;
101 u8 power[4];
102} __packed;
103
104struct ar9170_calibration_target_power_ht {
105 u8 freq;
106 u8 power[8];
107} __packed;
108
109#define AR5416_NUM_CTLS 24
110
111struct ar9170_calctl_edges {
112 u8 channel;
113#define AR9170_CALCTL_EDGE_FLAGS 0xC0
114 u8 power_flags;
115} __packed;
116
117#define AR5416_NUM_BAND_EDGES 8
118
119struct ar9170_calctl_data {
120 struct ar9170_calctl_edges
121 control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
122} __packed;
123
124
125struct ar9170_eeprom {
126 __le16 length;
127 __le16 checksum;
128 __le16 version;
129 u8 operating_flags;
130#define AR9170_OPFLAG_5GHZ 1
131#define AR9170_OPFLAG_2GHZ 2
132 u8 misc;
133 __le16 reg_domain[2];
134 u8 mac_address[6];
135 u8 rx_mask;
136 u8 tx_mask;
137 __le16 rf_silent;
138 __le16 bluetooth_options;
139 __le16 device_capabilities;
140 __le32 build_number;
141 u8 deviceType;
142 u8 reserved[33];
143
144 u8 customer_data[64];
145
146 struct ar9170_eeprom_modal
147 modal_header[2];
148
149 u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
150 u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
151
152 struct ar9170_calibration_data_per_freq
153 cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
154 cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
155
156 /* power calibration data */
157 struct ar9170_calibration_target_power_legacy
158 cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
159 struct ar9170_calibration_target_power_ht
160 cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
161 cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
162
163 struct ar9170_calibration_target_power_legacy
164 cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
165 cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
166 struct ar9170_calibration_target_power_ht
167 cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
168 cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
169
170 /* conformance testing limits */
171 u8 ctl_index[AR5416_NUM_CTLS];
172 struct ar9170_calctl_data
173 ctl_data[AR5416_NUM_CTLS];
174
175 u8 pad;
176 __le16 subsystem_id;
177} __packed;
178
179#endif /* __AR9170_EEPROM_H */
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h
new file mode 100644
index 000000000000..13091bd9d815
--- /dev/null
+++ b/drivers/net/wireless/ar9170/hw.h
@@ -0,0 +1,417 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * Hardware-specific definitions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#ifndef __AR9170_HW_H
39#define __AR9170_HW_H
40
41#define AR9170_MAX_CMD_LEN 64
42
43enum ar9170_cmd {
44 AR9170_CMD_RREG = 0x00,
45 AR9170_CMD_WREG = 0x01,
46 AR9170_CMD_RMEM = 0x02,
47 AR9170_CMD_WMEM = 0x03,
48 AR9170_CMD_BITAND = 0x04,
49 AR9170_CMD_BITOR = 0x05,
50 AR9170_CMD_EKEY = 0x28,
51 AR9170_CMD_DKEY = 0x29,
52 AR9170_CMD_FREQUENCY = 0x30,
53 AR9170_CMD_RF_INIT = 0x31,
54 AR9170_CMD_SYNTH = 0x32,
55 AR9170_CMD_FREQ_START = 0x33,
56 AR9170_CMD_ECHO = 0x80,
57 AR9170_CMD_TALLY = 0x81,
58 AR9170_CMD_TALLY_APD = 0x82,
59 AR9170_CMD_CONFIG = 0x83,
60 AR9170_CMD_RESET = 0x90,
61 AR9170_CMD_DKRESET = 0x91,
62 AR9170_CMD_DKTX_STATUS = 0x92,
63 AR9170_CMD_FDC = 0xA0,
64 AR9170_CMD_WREEPROM = 0xB0,
65 AR9170_CMD_WFLASH = 0xB0,
66 AR9170_CMD_FLASH_ERASE = 0xB1,
67 AR9170_CMD_FLASH_PROG = 0xB2,
68 AR9170_CMD_FLASH_CHKSUM = 0xB3,
69 AR9170_CMD_FLASH_READ = 0xB4,
70 AR9170_CMD_FW_DL_INIT = 0xB5,
71 AR9170_CMD_MEM_WREEPROM = 0xBB,
72};
73
74/* endpoints */
75#define AR9170_EP_TX 1
76#define AR9170_EP_RX 2
77#define AR9170_EP_IRQ 3
78#define AR9170_EP_CMD 4
79
80#define AR9170_EEPROM_START 0x1600
81
82#define AR9170_GPIO_REG_BASE 0x1d0100
83#define AR9170_GPIO_REG_PORT_TYPE AR9170_GPIO_REG_BASE
84#define AR9170_GPIO_REG_DATA (AR9170_GPIO_REG_BASE + 4)
85#define AR9170_NUM_LEDS 2
86
87
88#define AR9170_USB_REG_BASE 0x1e1000
89#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108)
90#define AR9170_DMA_CTL_ENABLE_TO_DEVICE 0x1
91#define AR9170_DMA_CTL_ENABLE_FROM_DEVICE 0x2
92#define AR9170_DMA_CTL_HIGH_SPEED 0x4
93#define AR9170_DMA_CTL_PACKET_MODE 0x8
94
95#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110)
96#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114)
97
98
99
100#define AR9170_MAC_REG_BASE 0x1c3000
101
102#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514)
103#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518)
104
105#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51C)
106#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520)
107#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524)
108
109#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610)
110#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614)
111#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618)
112#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c)
113
114#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624)
115#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628)
116
117#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62C)
118
119#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630)
120#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634)
121#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638)
122#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c)
123#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640)
124#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64C)
125
126#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658)
127#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674)
128#define AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC BIT(0)
129#define AR9170_MAC_REG_SNIFFER_DEFAULTS 0x02000000
130#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678)
131#define AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE BIT(3)
132#define AR9170_MAC_REG_ENCRYPTION_DEFAULTS 0x70
133
134#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680)
135#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688)
136
137#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c)
138#define AR9170_MAC_REG_FTF_ASSOC_REQ BIT(0)
139#define AR9170_MAC_REG_FTF_ASSOC_RESP BIT(1)
140#define AR9170_MAC_REG_FTF_REASSOC_REQ BIT(2)
141#define AR9170_MAC_REG_FTF_REASSOC_RESP BIT(3)
142#define AR9170_MAC_REG_FTF_PRB_REQ BIT(4)
143#define AR9170_MAC_REG_FTF_PRB_RESP BIT(5)
144#define AR9170_MAC_REG_FTF_BIT6 BIT(6)
145#define AR9170_MAC_REG_FTF_BIT7 BIT(7)
146#define AR9170_MAC_REG_FTF_BEACON BIT(8)
147#define AR9170_MAC_REG_FTF_ATIM BIT(9)
148#define AR9170_MAC_REG_FTF_DEASSOC BIT(10)
149#define AR9170_MAC_REG_FTF_AUTH BIT(11)
150#define AR9170_MAC_REG_FTF_DEAUTH BIT(12)
151#define AR9170_MAC_REG_FTF_BIT13 BIT(13)
152#define AR9170_MAC_REG_FTF_BIT14 BIT(14)
153#define AR9170_MAC_REG_FTF_BIT15 BIT(15)
154#define AR9170_MAC_REG_FTF_BAR BIT(24)
155#define AR9170_MAC_REG_FTF_BIT25 BIT(25)
156#define AR9170_MAC_REG_FTF_PSPOLL BIT(26)
157#define AR9170_MAC_REG_FTF_RTS BIT(27)
158#define AR9170_MAC_REG_FTF_CTS BIT(28)
159#define AR9170_MAC_REG_FTF_ACK BIT(29)
160#define AR9170_MAC_REG_FTF_CFE BIT(30)
161#define AR9170_MAC_REG_FTF_CFE_ACK BIT(31)
162#define AR9170_MAC_REG_FTF_DEFAULTS 0x0500ffff
163#define AR9170_MAC_REG_FTF_MONITOR 0xfd00ffff
164
165#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6A0)
166#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6A4)
167#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6A8)
168#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6AC)
169#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6B0)
170#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6BC)
171#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6CC)
172#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6F4)
173
174
175#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690)
176#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698)
177
178#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6F0)
179
180#define AR9170_MAC_REG_POWERMANAGEMENT (AR9170_MAC_REG_BASE + 0x700)
181#define AR9170_MAC_REG_POWERMGT_IBSS 0xe0
182#define AR9170_MAC_REG_POWERMGT_AP 0xa1
183#define AR9170_MAC_REG_POWERMGT_STA 0x2
184#define AR9170_MAC_REG_POWERMGT_AP_WDS 0x3
185#define AR9170_MAC_REG_POWERMGT_DEFAULTS (0xf << 24)
186
187#define AR9170_MAC_REG_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704)
188#define AR9170_MAC_REG_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708)
189
190#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xB00)
191#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xB04)
192#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xB08)
193#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xB0C)
194#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xB10)
195#define AR9170_MAC_REG_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xB14)
196#define AR9170_MAC_REG_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xB18)
197
198#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xB28)
199
200#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xBB0)
201#define AR9170_MAC_FCS_SWFCS 0x1
202#define AR9170_MAC_FCS_FIFO_PROT 0x4
203
204
205#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xB30)
206
207#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
208#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
209
210#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
211#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
212
213#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xD7C)
214#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
215#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0
216#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
217#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000
218
219#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xD84)
220#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xD88)
221#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xD90)
222#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xD94)
223#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xDA0)
224#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xDA4)
225
226
227#define AR9170_PWR_REG_BASE 0x1D4000
228
229#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008)
230#define AR9170_PWR_CLK_AHB_40MHZ 0
231#define AR9170_PWR_CLK_AHB_20_22MHZ 1
232#define AR9170_PWR_CLK_AHB_40_44MHZ 2
233#define AR9170_PWR_CLK_AHB_80_88MHZ 3
234#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70
235
236
237/* put beacon here in memory */
238#define AR9170_BEACON_BUFFER_ADDRESS 0x117900
239
240
241struct ar9170_tx_control {
242 __le16 length;
243 __le16 mac_control;
244 __le32 phy_control;
245 u8 frame_data[0];
246} __packed;
247
248/* these are either-or */
249#define AR9170_TX_MAC_PROT_RTS 0x0001
250#define AR9170_TX_MAC_PROT_CTS 0x0002
251
252#define AR9170_TX_MAC_NO_ACK 0x0004
253/* if unset, MAC will only do SIFS space before frame */
254#define AR9170_TX_MAC_BACKOFF 0x0008
255#define AR9170_TX_MAC_BURST 0x0010
256#define AR9170_TX_MAC_AGGR 0x0020
257
258/* encryption is a two-bit field */
259#define AR9170_TX_MAC_ENCR_NONE 0x0000
260#define AR9170_TX_MAC_ENCR_RC4 0x0040
261#define AR9170_TX_MAC_ENCR_CENC 0x0080
262#define AR9170_TX_MAC_ENCR_AES 0x00c0
263
264#define AR9170_TX_MAC_MMIC 0x0100
265#define AR9170_TX_MAC_HW_DURATION 0x0200
266#define AR9170_TX_MAC_QOS_SHIFT 10
267#define AR9170_TX_MAC_QOS_MASK (3 << AR9170_TX_MAC_QOS_SHIFT)
268#define AR9170_TX_MAC_AGGR_QOS_BIT1 0x0400
269#define AR9170_TX_MAC_AGGR_QOS_BIT2 0x0800
270#define AR9170_TX_MAC_DISABLE_TXOP 0x1000
271#define AR9170_TX_MAC_TXOP_RIFS 0x2000
272#define AR9170_TX_MAC_IMM_AMPDU 0x4000
273#define AR9170_TX_MAC_RATE_PROBE 0x8000
274
275/* either-or */
276#define AR9170_TX_PHY_MOD_CCK 0x00000000
277#define AR9170_TX_PHY_MOD_OFDM 0x00000001
278#define AR9170_TX_PHY_MOD_HT 0x00000002
279
280/* depends on modulation */
281#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004
282#define AR9170_TX_PHY_GREENFIELD 0x00000004
283
284#define AR9170_TX_PHY_BW_SHIFT 3
285#define AR9170_TX_PHY_BW_MASK (3 << AR9170_TX_PHY_BW_SHIFT)
286#define AR9170_TX_PHY_BW_20MHZ 0
287#define AR9170_TX_PHY_BW_40MHZ 2
288#define AR9170_TX_PHY_BW_40MHZ_DUP 3
289
290#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT 6
291#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
292
293#define AR9170_TX_PHY_TX_PWR_SHIFT 9
294#define AR9170_TX_PHY_TX_PWR_MASK (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
295
296/* not part of the hw-spec */
297#define AR9170_TX_PHY_QOS_SHIFT 25
298#define AR9170_TX_PHY_QOS_MASK (3 << AR9170_TX_PHY_QOS_SHIFT)
299
300#define AR9170_TX_PHY_TXCHAIN_SHIFT 15
301#define AR9170_TX_PHY_TXCHAIN_MASK (7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
302#define AR9170_TX_PHY_TXCHAIN_1 1
303/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
304#define AR9170_TX_PHY_TXCHAIN_2 5
305
306#define AR9170_TX_PHY_MCS_SHIFT 18
307#define AR9170_TX_PHY_MCS_MASK (0x7f << AR9170_TX_PHY_MCS_SHIFT)
308
309#define AR9170_TX_PHY_SHORT_GI 0x80000000
310
311struct ar9170_rx_head {
312 u8 plcp[12];
313};
314
315struct ar9170_rx_tail {
316 union {
317 struct {
318 u8 rssi_ant0, rssi_ant1, rssi_ant2,
319 rssi_ant0x, rssi_ant1x, rssi_ant2x,
320 rssi_combined;
321 };
322 u8 rssi[7];
323 };
324
325 u8 evm_stream0[6], evm_stream1[6];
326 u8 phy_err;
327 u8 SAidx, DAidx;
328 u8 error;
329 u8 status;
330};
331
332#define AR9170_ENC_ALG_NONE 0x0
333#define AR9170_ENC_ALG_WEP64 0x1
334#define AR9170_ENC_ALG_TKIP 0x2
335#define AR9170_ENC_ALG_AESCCMP 0x4
336#define AR9170_ENC_ALG_WEP128 0x5
337#define AR9170_ENC_ALG_WEP256 0x6
338#define AR9170_ENC_ALG_CENC 0x7
339
340#define AR9170_RX_ENC_SOFTWARE 0x8
341
342static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
343{
344 return (t->SAidx & 0xc0) >> 4 |
345 (t->DAidx & 0xc0) >> 6;
346}
347
348#define AR9170_RX_STATUS_MODULATION_MASK 0x03
349#define AR9170_RX_STATUS_MODULATION_CCK 0x00
350#define AR9170_RX_STATUS_MODULATION_OFDM 0x01
351#define AR9170_RX_STATUS_MODULATION_HT 0x02
352#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03
353
354/* depends on modulation */
355#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08
356#define AR9170_RX_STATUS_GREENFIELD 0x08
357
358#define AR9170_RX_STATUS_MPDU_MASK 0x30
359#define AR9170_RX_STATUS_MPDU_SINGLE 0x00
360#define AR9170_RX_STATUS_MPDU_FIRST 0x10
361#define AR9170_RX_STATUS_MPDU_MIDDLE 0x20
362#define AR9170_RX_STATUS_MPDU_LAST 0x30
363
364
365#define AR9170_RX_ERROR_RXTO 0x01
366#define AR9170_RX_ERROR_OVERRUN 0x02
367#define AR9170_RX_ERROR_DECRYPT 0x04
368#define AR9170_RX_ERROR_FCS 0x08
369#define AR9170_RX_ERROR_WRONG_RA 0x10
370#define AR9170_RX_ERROR_PLCP 0x20
371#define AR9170_RX_ERROR_MMIC 0x40
372
373struct ar9170_cmd_tx_status {
374 __le16 unkn;
375 u8 dst[ETH_ALEN];
376 __le32 rate;
377 __le16 status;
378} __packed;
379
380#define AR9170_TX_STATUS_COMPLETE 0x00
381#define AR9170_TX_STATUS_RETRY 0x01
382#define AR9170_TX_STATUS_FAILED 0x02
383
384struct ar9170_cmd_ba_failed_count {
385 __le16 failed;
386 __le16 rate;
387} __packed;
388
389struct ar9170_cmd_response {
390 u8 flag;
391 u8 type;
392
393 union {
394 struct ar9170_cmd_tx_status tx_status;
395 struct ar9170_cmd_ba_failed_count ba_fail_cnt;
396 u8 data[0];
397 };
398} __packed;
399
400/* QoS */
401
402/* mac80211 queue to HW/FW map */
403static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
404
405/* HW/FW queue to mac80211 map */
406static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
407
408enum ar9170_txq {
409 AR9170_TXQ_BE,
410 AR9170_TXQ_BK,
411 AR9170_TXQ_VI,
412 AR9170_TXQ_VO,
413
414 __AR9170_NUM_TXQ,
415};
416
417#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ar9170/led.c b/drivers/net/wireless/ar9170/led.c
new file mode 100644
index 000000000000..341cead7f606
--- /dev/null
+++ b/drivers/net/wireless/ar9170/led.c
@@ -0,0 +1,171 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * LED handling
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38
39#include "ar9170.h"
40#include "cmd.h"
41
42int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
43{
44 return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
45}
46
47int ar9170_init_leds(struct ar9170 *ar)
48{
49 int err;
50
51 /* disable LEDs */
52 /* GPIO [0/1 mode: output, 2/3: input] */
53 err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
54 if (err)
55 goto out;
56
57 /* GPIO 0/1 value: off */
58 err = ar9170_set_leds_state(ar, 0);
59
60out:
61 return err;
62}
63
64#ifdef CONFIG_AR9170_LEDS
65static void ar9170_update_leds(struct work_struct *work)
66{
67 struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
68 int i, tmp, blink_delay = 1000;
69 u32 led_val = 0;
70 bool rerun = false;
71
72 if (unlikely(!IS_ACCEPTING_CMD(ar)))
73 return ;
74
75 mutex_lock(&ar->mutex);
76 for (i = 0; i < AR9170_NUM_LEDS; i++)
77 if (ar->leds[i].toggled) {
78 led_val |= 1 << i;
79
80 tmp = 70 + 200 / (ar->leds[i].toggled);
81 if (tmp < blink_delay)
82 blink_delay = tmp;
83
84 if (ar->leds[i].toggled > 1)
85 ar->leds[i].toggled = 0;
86
87 rerun = true;
88 }
89
90 ar9170_set_leds_state(ar, led_val);
91 mutex_unlock(&ar->mutex);
92
93 if (rerun)
94 queue_delayed_work(ar->hw->workqueue, &ar->led_work,
95 msecs_to_jiffies(blink_delay));
96}
97
98static void ar9170_led_brightness_set(struct led_classdev *led,
99 enum led_brightness brightness)
100{
101 struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
102 struct ar9170 *ar = arl->ar;
103
104 arl->toggled++;
105
106 if (likely(IS_ACCEPTING_CMD(ar) && brightness))
107 queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
108}
109
110static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
111 char *trigger)
112{
113 int err;
114
115 snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
116 "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
117
118 ar->leds[i].ar = ar;
119 ar->leds[i].l.name = ar->leds[i].name;
120 ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
121 ar->leds[i].l.brightness = 0;
122 ar->leds[i].l.default_trigger = trigger;
123
124 err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
125 &ar->leds[i].l);
126 if (err)
127 printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
128 wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
129 else
130 ar->leds[i].registered = true;
131
132 return err;
133}
134
135void ar9170_unregister_leds(struct ar9170 *ar)
136{
137 int i;
138
139 cancel_delayed_work_sync(&ar->led_work);
140
141 for (i = 0; i < AR9170_NUM_LEDS; i++)
142 if (ar->leds[i].registered) {
143 led_classdev_unregister(&ar->leds[i].l);
144 ar->leds[i].registered = false;
145 }
146}
147
148int ar9170_register_leds(struct ar9170 *ar)
149{
150 int err;
151
152 INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
153
154 err = ar9170_register_led(ar, 0, "tx",
155 ieee80211_get_tx_led_name(ar->hw));
156 if (err)
157 goto fail;
158
159 err = ar9170_register_led(ar, 1, "assoc",
160 ieee80211_get_assoc_led_name(ar->hw));
161 if (err)
162 goto fail;
163
164 return 0;
165
166fail:
167 ar9170_unregister_leds(ar);
168 return err;
169}
170
171#endif /* CONFIG_AR9170_LEDS */
diff --git a/drivers/net/wireless/ar9170/mac.c b/drivers/net/wireless/ar9170/mac.c
new file mode 100644
index 000000000000..c8fa3073169f
--- /dev/null
+++ b/drivers/net/wireless/ar9170/mac.c
@@ -0,0 +1,452 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * MAC programming
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#include "ar9170.h"
39#include "cmd.h"
40
41int ar9170_set_qos(struct ar9170 *ar)
42{
43 ar9170_regwrite_begin(ar);
44
45 ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
46 (ar->edcf[0].cw_max << 16));
47 ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
48 (ar->edcf[1].cw_max << 16));
49 ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
50 (ar->edcf[2].cw_max << 16));
51 ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
52 (ar->edcf[3].cw_max << 16));
53 ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
54 (ar->edcf[4].cw_max << 16));
55
56 ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
57 ((ar->edcf[0].aifs * 9 + 10)) |
58 ((ar->edcf[1].aifs * 9 + 10) << 12) |
59 ((ar->edcf[2].aifs * 9 + 10) << 24));
60 ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
61 ((ar->edcf[2].aifs * 9 + 10) >> 8) |
62 ((ar->edcf[3].aifs * 9 + 10) << 4) |
63 ((ar->edcf[4].aifs * 9 + 10) << 16));
64
65 ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
66 ar->edcf[0].txop | ar->edcf[1].txop << 16);
67 ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
68 ar->edcf[1].txop | ar->edcf[3].txop << 16);
69
70 ar9170_regwrite_finish();
71
72 return ar9170_regwrite_result();
73}
74
75int ar9170_init_mac(struct ar9170 *ar)
76{
77 ar9170_regwrite_begin(ar);
78
79 ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
80
81 ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
82
83 /* enable MMIC */
84 ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
85 AR9170_MAC_REG_SNIFFER_DEFAULTS);
86
87 ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
88
89 ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
90 ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
91 ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
92
93 /* CF-END mode */
94 ar9170_regwrite(0x1c3b2c, 0x19000000);
95
96 /* NAV protects ACK only (in TXOP) */
97 ar9170_regwrite(0x1c3b38, 0x201);
98
99 /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
100 /* OTUS set AM to 0x1 */
101 ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
102
103 ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
104
105 /* AGG test code*/
106 /* Aggregation MAX number and timeout */
107 ar9170_regwrite(0x1c3b9c, 0x10000a);
108
109 ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
110 AR9170_MAC_REG_FTF_DEFAULTS);
111
112 /* Enable deaggregator, response in sniffer mode */
113 ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
114
115 /* rate sets */
116 ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
117 ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
118 ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
119
120 /* MIMO response control */
121 ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28 otus-AM */
122
123 /* switch MAC to OTUS interface */
124 ar9170_regwrite(0x1c3600, 0x3);
125
126 ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
127
128 /* set PHY register read timeout (??) */
129 ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
130
131 /* Disable Rx TimeOut, workaround for BB. */
132 ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
133
134 /* Set CPU clock frequency to 88/80MHz */
135 ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
136 AR9170_PWR_CLK_AHB_80_88MHZ |
137 AR9170_PWR_CLK_DAC_160_INV_DLY);
138
139 /* Set WLAN DMA interrupt mode: generate int per packet */
140 ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
141
142 ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
143 AR9170_MAC_FCS_FIFO_PROT);
144
145 /* Disables the CF_END frame, undocumented register */
146 ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
147 0x141E0F48);
148
149 ar9170_regwrite_finish();
150
151 return ar9170_regwrite_result();
152}
153
154static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
155{
156 static const u8 zero[ETH_ALEN] = { 0 };
157
158 if (!mac)
159 mac = zero;
160
161 ar9170_regwrite_begin(ar);
162
163 ar9170_regwrite(reg,
164 (mac[3] << 24) | (mac[2] << 16) |
165 (mac[1] << 8) | mac[0]);
166
167 ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]);
168
169 ar9170_regwrite_finish();
170
171 return ar9170_regwrite_result();
172}
173
174int ar9170_update_multicast(struct ar9170 *ar)
175{
176 int err;
177
178 ar9170_regwrite_begin(ar);
179 ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
180 ar->want_mc_hash >> 32);
181 ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
182 ar->want_mc_hash);
183
184 ar9170_regwrite_finish();
185 err = ar9170_regwrite_result();
186
187 if (err)
188 return err;
189
190 ar->cur_mc_hash = ar->want_mc_hash;
191
192 return 0;
193}
194
195int ar9170_update_frame_filter(struct ar9170 *ar)
196{
197 int err;
198
199 err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
200 ar->want_filter);
201
202 if (err)
203 return err;
204
205 ar->cur_filter = ar->want_filter;
206
207 return 0;
208}
209
210static int ar9170_set_promiscouous(struct ar9170 *ar)
211{
212 u32 encr_mode, sniffer;
213 int err;
214
215 err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
216 if (err)
217 return err;
218
219 err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
220 if (err)
221 return err;
222
223 if (ar->sniffer_enabled) {
224 sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
225
226 /*
227 * Rx decryption works in place.
228 *
229 * If we don't disable it, the hardware will render all
230 * encrypted frames which are encrypted with an unknown
231 * key useless.
232 */
233
234 encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
235 ar->sniffer_enabled = true;
236 } else {
237 sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
238
239 if (ar->rx_software_decryption)
240 encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
241 else
242 encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
243 }
244
245 ar9170_regwrite_begin(ar);
246 ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
247 ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
248 ar9170_regwrite_finish();
249
250 return ar9170_regwrite_result();
251}
252
253int ar9170_set_operating_mode(struct ar9170 *ar)
254{
255 u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
256 u8 *mac_addr, *bssid;
257 int err;
258
259 if (ar->vif) {
260 mac_addr = ar->mac_addr;
261 bssid = ar->bssid;
262
263 switch (ar->vif->type) {
264 case NL80211_IFTYPE_MESH_POINT:
265 case NL80211_IFTYPE_ADHOC:
266 pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
267 break;
268/* case NL80211_IFTYPE_AP:
269 pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
270 break;*/
271 case NL80211_IFTYPE_WDS:
272 pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
273 break;
274 case NL80211_IFTYPE_MONITOR:
275 ar->sniffer_enabled = true;
276 ar->rx_software_decryption = true;
277 break;
278 default:
279 pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
280 break;
281 }
282 } else {
283 mac_addr = NULL;
284 bssid = NULL;
285 }
286
287 err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
288 if (err)
289 return err;
290
291 err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
292 if (err)
293 return err;
294
295 err = ar9170_set_promiscouous(ar);
296 if (err)
297 return err;
298
299 ar9170_regwrite_begin(ar);
300
301 ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
302 ar9170_regwrite_finish();
303
304 return ar9170_regwrite_result();
305}
306
307int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
308{
309 u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
310
311 return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
312}
313
314int ar9170_set_beacon_timers(struct ar9170 *ar)
315{
316 u32 v = 0;
317 u32 pretbtt = 0;
318
319 v |= ar->hw->conf.beacon_int;
320
321 if (ar->vif) {
322 switch (ar->vif->type) {
323 case NL80211_IFTYPE_MESH_POINT:
324 case NL80211_IFTYPE_ADHOC:
325 v |= BIT(25);
326 break;
327 case NL80211_IFTYPE_AP:
328 v |= BIT(24);
329 pretbtt = (ar->hw->conf.beacon_int - 6) << 16;
330 break;
331 default:
332 break;
333 }
334
335 v |= ar->vif->bss_conf.dtim_period << 16;
336 }
337
338 ar9170_regwrite_begin(ar);
339
340 ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
341 ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
342 ar9170_regwrite_finish();
343 return ar9170_regwrite_result();
344}
345
346int ar9170_update_beacon(struct ar9170 *ar)
347{
348 struct sk_buff *skb;
349 __le32 *data, *old = NULL;
350 u32 word;
351 int i;
352
353 skb = ieee80211_beacon_get(ar->hw, ar->vif);
354 if (!skb)
355 return -ENOMEM;
356
357 data = (__le32 *)skb->data;
358 if (ar->beacon)
359 old = (__le32 *)ar->beacon->data;
360
361 ar9170_regwrite_begin(ar);
362 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
363 /*
364 * XXX: This accesses beyond skb data for up
365 * to the last 3 bytes!!
366 */
367
368 if (old && (data[i] == old[i]))
369 continue;
370
371 word = le32_to_cpu(data[i]);
372 ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
373 }
374
375 /* XXX: use skb->cb info */
376 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
377 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
378 ((skb->len + 4) << (3+16)) + 0x0400);
379 else
380 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
381 ((skb->len + 4) << (3+16)) + 0x0400);
382
383 ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
384 ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
385 ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
386
387 ar9170_regwrite_finish();
388
389 dev_kfree_skb(ar->beacon);
390 ar->beacon = skb;
391
392 return ar9170_regwrite_result();
393}
394
395void ar9170_new_beacon(struct work_struct *work)
396{
397 struct ar9170 *ar = container_of(work, struct ar9170,
398 beacon_work);
399 struct sk_buff *skb;
400
401 if (unlikely(!IS_STARTED(ar)))
402 return ;
403
404 mutex_lock(&ar->mutex);
405
406 if (!ar->vif)
407 goto out;
408
409 ar9170_update_beacon(ar);
410
411 rcu_read_lock();
412 while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
413 ar9170_op_tx(ar->hw, skb);
414
415 rcu_read_unlock();
416
417 out:
418 mutex_unlock(&ar->mutex);
419}
420
421int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
422 u8 keyidx, u8 *keydata, int keylen)
423{
424 __le32 vals[7];
425 static const u8 bcast[ETH_ALEN] =
426 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
427 u8 dummy;
428
429 mac = mac ? : bcast;
430
431 vals[0] = cpu_to_le32((keyidx << 16) + id);
432 vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
433 vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
434 mac[3] << 8 | mac[2]);
435 memset(&vals[3], 0, 16);
436 if (keydata)
437 memcpy(&vals[3], keydata, keylen);
438
439 return ar->exec_cmd(ar, AR9170_CMD_EKEY,
440 sizeof(vals), (u8 *)vals,
441 1, &dummy);
442}
443
444int ar9170_disable_key(struct ar9170 *ar, u8 id)
445{
446 __le32 val = cpu_to_le32(id);
447 u8 dummy;
448
449 return ar->exec_cmd(ar, AR9170_CMD_EKEY,
450 sizeof(val), (u8 *)&val,
451 1, &dummy);
452}
diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ar9170/main.c
new file mode 100644
index 000000000000..5996ff9f7f47
--- /dev/null
+++ b/drivers/net/wireless/ar9170/main.c
@@ -0,0 +1,1671 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * mac80211 interaction code
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2009, Christian Lamparter <chunkeey@web.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU 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; see the file COPYING. If not, see
21 * http://www.gnu.org/licenses/.
22 *
23 * This file incorporates work covered by the following copyright and
24 * permission notice:
25 * Copyright (c) 2007-2008 Atheros Communications, Inc.
26 *
27 * Permission to use, copy, modify, and/or distribute this software for any
28 * purpose with or without fee is hereby granted, provided that the above
29 * copyright notice and this permission notice appear in all copies.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */
39
40#include <linux/init.h>
41#include <linux/module.h>
42#include <linux/etherdevice.h>
43#include <net/mac80211.h>
44#include "ar9170.h"
45#include "hw.h"
46#include "cmd.h"
47
48static int modparam_nohwcrypt;
49module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
51
52#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
53 .bitrate = (_bitrate), \
54 .flags = (_flags), \
55 .hw_value = (_hw_rate) | (_txpidx) << 4, \
56}
57
58static struct ieee80211_rate __ar9170_ratetable[] = {
59 RATE(10, 0, 0, 0),
60 RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
61 RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
62 RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
63 RATE(60, 0xb, 0, 0),
64 RATE(90, 0xf, 0, 0),
65 RATE(120, 0xa, 0, 0),
66 RATE(180, 0xe, 0, 0),
67 RATE(240, 0x9, 0, 0),
68 RATE(360, 0xd, 1, 0),
69 RATE(480, 0x8, 2, 0),
70 RATE(540, 0xc, 3, 0),
71};
72#undef RATE
73
74#define ar9170_g_ratetable (__ar9170_ratetable + 0)
75#define ar9170_g_ratetable_size 12
76#define ar9170_a_ratetable (__ar9170_ratetable + 4)
77#define ar9170_a_ratetable_size 8
78
79/*
80 * NB: The hw_value is used as an index into the ar9170_phy_freq_params
81 * array in phy.c so that we don't have to do frequency lookups!
82 */
83#define CHAN(_freq, _idx) { \
84 .center_freq = (_freq), \
85 .hw_value = (_idx), \
86 .max_power = 18, /* XXX */ \
87}
88
89static struct ieee80211_channel ar9170_2ghz_chantable[] = {
90 CHAN(2412, 0),
91 CHAN(2417, 1),
92 CHAN(2422, 2),
93 CHAN(2427, 3),
94 CHAN(2432, 4),
95 CHAN(2437, 5),
96 CHAN(2442, 6),
97 CHAN(2447, 7),
98 CHAN(2452, 8),
99 CHAN(2457, 9),
100 CHAN(2462, 10),
101 CHAN(2467, 11),
102 CHAN(2472, 12),
103 CHAN(2484, 13),
104};
105
106static struct ieee80211_channel ar9170_5ghz_chantable[] = {
107 CHAN(4920, 14),
108 CHAN(4940, 15),
109 CHAN(4960, 16),
110 CHAN(4980, 17),
111 CHAN(5040, 18),
112 CHAN(5060, 19),
113 CHAN(5080, 20),
114 CHAN(5180, 21),
115 CHAN(5200, 22),
116 CHAN(5220, 23),
117 CHAN(5240, 24),
118 CHAN(5260, 25),
119 CHAN(5280, 26),
120 CHAN(5300, 27),
121 CHAN(5320, 28),
122 CHAN(5500, 29),
123 CHAN(5520, 30),
124 CHAN(5540, 31),
125 CHAN(5560, 32),
126 CHAN(5580, 33),
127 CHAN(5600, 34),
128 CHAN(5620, 35),
129 CHAN(5640, 36),
130 CHAN(5660, 37),
131 CHAN(5680, 38),
132 CHAN(5700, 39),
133 CHAN(5745, 40),
134 CHAN(5765, 41),
135 CHAN(5785, 42),
136 CHAN(5805, 43),
137 CHAN(5825, 44),
138 CHAN(5170, 45),
139 CHAN(5190, 46),
140 CHAN(5210, 47),
141 CHAN(5230, 48),
142};
143#undef CHAN
144
145static struct ieee80211_supported_band ar9170_band_2GHz = {
146 .channels = ar9170_2ghz_chantable,
147 .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
148 .bitrates = ar9170_g_ratetable,
149 .n_bitrates = ar9170_g_ratetable_size,
150};
151
152#ifdef AR9170_QUEUE_DEBUG
153/*
154 * In case some wants works with AR9170's crazy tx_status queueing techniques.
155 * He might need this rather useful probing function.
156 *
157 * NOTE: caller must hold the queue's spinlock!
158 */
159
160static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
161{
162 struct ar9170_tx_control *txc = (void *) skb->data;
163 struct ieee80211_hdr *hdr = (void *)txc->frame_data;
164
165 printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] "
166 "mac_control:%04x, phy_control:%08x]\n",
167 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
168 ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control),
169 le32_to_cpu(txc->phy_control));
170}
171
172static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
173 struct sk_buff_head *queue)
174{
175 struct sk_buff *skb;
176 int i = 0;
177
178 printk(KERN_DEBUG "---[ cut here ]---\n");
179 printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n",
180 wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
181
182 skb_queue_walk(queue, skb) {
183 struct ar9170_tx_control *txc = (void *) skb->data;
184 struct ieee80211_hdr *hdr = (void *)txc->frame_data;
185
186 printk(KERN_DEBUG "index:%d => \n", i);
187 ar9170_print_txheader(ar, skb);
188 }
189 printk(KERN_DEBUG "---[ end ]---\n");
190}
191#endif /* AR9170_QUEUE_DEBUG */
192
193static struct ieee80211_supported_band ar9170_band_5GHz = {
194 .channels = ar9170_5ghz_chantable,
195 .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
196 .bitrates = ar9170_a_ratetable,
197 .n_bitrates = ar9170_a_ratetable_size,
198};
199
200void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
201 bool valid_status, u16 tx_status)
202{
203 struct ieee80211_tx_info *txinfo;
204 unsigned int retries = 0, queue = skb_get_queue_mapping(skb);
205 unsigned long flags;
206
207 spin_lock_irqsave(&ar->tx_stats_lock, flags);
208 ar->tx_stats[queue].len--;
209 if (ieee80211_queue_stopped(ar->hw, queue))
210 ieee80211_wake_queue(ar->hw, queue);
211 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
212
213 txinfo = IEEE80211_SKB_CB(skb);
214 ieee80211_tx_info_clear_status(txinfo);
215
216 switch (tx_status) {
217 case AR9170_TX_STATUS_RETRY:
218 retries = 2;
219 case AR9170_TX_STATUS_COMPLETE:
220 txinfo->flags |= IEEE80211_TX_STAT_ACK;
221 break;
222
223 case AR9170_TX_STATUS_FAILED:
224 retries = ar->hw->conf.long_frame_max_tx_count;
225 break;
226
227 default:
228 printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
229 wiphy_name(ar->hw->wiphy), tx_status);
230 break;
231 }
232
233 if (valid_status)
234 txinfo->status.rates[0].count = retries + 1;
235
236 skb_pull(skb, sizeof(struct ar9170_tx_control));
237 ieee80211_tx_status_irqsafe(ar->hw, skb);
238}
239
240static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar,
241 const u8 *mac,
242 const u32 queue,
243 struct sk_buff_head *q)
244{
245 unsigned long flags;
246 struct sk_buff *skb;
247
248 spin_lock_irqsave(&q->lock, flags);
249 skb_queue_walk(q, skb) {
250 struct ar9170_tx_control *txc = (void *) skb->data;
251 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
252 u32 txc_queue = (le32_to_cpu(txc->phy_control) &
253 AR9170_TX_PHY_QOS_MASK) >>
254 AR9170_TX_PHY_QOS_SHIFT;
255
256 if ((queue != txc_queue) ||
257 (compare_ether_addr(ieee80211_get_DA(hdr), mac)))
258 continue;
259
260 __skb_unlink(skb, q);
261 spin_unlock_irqrestore(&q->lock, flags);
262 return skb;
263 }
264 spin_unlock_irqrestore(&q->lock, flags);
265 return NULL;
266}
267
268static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac,
269 const u32 queue)
270{
271 struct ieee80211_sta *sta;
272 struct sk_buff *skb;
273
274 /*
275 * Unfortunately, the firmware does not tell to which (queued) frame
276 * this transmission status report belongs to.
277 *
278 * So we have to make risky guesses - with the scarce information
279 * the firmware provided (-> destination MAC, and phy_control) -
280 * and hope that we picked the right one...
281 */
282 rcu_read_lock();
283 sta = ieee80211_find_sta(ar->hw, mac);
284
285 if (likely(sta)) {
286 struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv;
287 skb = skb_dequeue(&sta_priv->tx_status[queue]);
288 rcu_read_unlock();
289 if (likely(skb))
290 return skb;
291 } else
292 rcu_read_unlock();
293
294 /* scan the waste queue for candidates */
295 skb = ar9170_find_skb_in_queue(ar, mac, queue,
296 &ar->global_tx_status_waste);
297 if (!skb) {
298 /* so it still _must_ be in the global list. */
299 skb = ar9170_find_skb_in_queue(ar, mac, queue,
300 &ar->global_tx_status);
301 }
302
303#ifdef AR9170_QUEUE_DEBUG
304 if (unlikely((!skb) && net_ratelimit())) {
305 printk(KERN_ERR "%s: ESS:[%pM] does not have any "
306 "outstanding frames in this queue (%d).\n",
307 wiphy_name(ar->hw->wiphy), mac, queue);
308 }
309#endif /* AR9170_QUEUE_DEBUG */
310 return skb;
311}
312
313/*
314 * This worker tries to keep the global tx_status queue empty.
315 * So we can guarantee that incoming tx_status reports for
316 * unregistered stations are always synced with the actual
317 * frame - which we think - belongs to.
318 */
319
320static void ar9170_tx_status_janitor(struct work_struct *work)
321{
322 struct ar9170 *ar = container_of(work, struct ar9170,
323 tx_status_janitor.work);
324 struct sk_buff *skb;
325
326 if (unlikely(!IS_STARTED(ar)))
327 return ;
328
329 mutex_lock(&ar->mutex);
330 /* recycle the garbage back to mac80211... one by one. */
331 while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
332#ifdef AR9170_QUEUE_DEBUG
333 printk(KERN_DEBUG "%s: dispose queued frame =>\n",
334 wiphy_name(ar->hw->wiphy));
335 ar9170_print_txheader(ar, skb);
336#endif /* AR9170_QUEUE_DEBUG */
337 ar9170_handle_tx_status(ar, skb, false,
338 AR9170_TX_STATUS_FAILED);
339 }
340
341 while ((skb = skb_dequeue(&ar->global_tx_status))) {
342#ifdef AR9170_QUEUE_DEBUG
343 printk(KERN_DEBUG "%s: moving frame into waste queue =>\n",
344 wiphy_name(ar->hw->wiphy));
345
346 ar9170_print_txheader(ar, skb);
347#endif /* AR9170_QUEUE_DEBUG */
348 skb_queue_tail(&ar->global_tx_status_waste, skb);
349 }
350
351 /* recall the janitor in 100ms - if there's garbage in the can. */
352 if (skb_queue_len(&ar->global_tx_status_waste) > 0)
353 queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
354 msecs_to_jiffies(100));
355
356 mutex_unlock(&ar->mutex);
357}
358
359static void ar9170_handle_command_response(struct ar9170 *ar,
360 void *buf, u32 len)
361{
362 struct ar9170_cmd_response *cmd = (void *) buf;
363
364 if ((cmd->type & 0xc0) != 0xc0) {
365 ar->callback_cmd(ar, len, buf);
366 return;
367 }
368
369 /* hardware event handlers */
370 switch (cmd->type) {
371 case 0xc1: {
372 /*
373 * TX status notification:
374 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
375 *
376 * XX always 81
377 * YY always 00
378 * M1-M6 is the MAC address
379 * R1-R4 is the transmit rate
380 * S1-S2 is the transmit status
381 */
382
383 struct sk_buff *skb;
384 u32 queue = (le32_to_cpu(cmd->tx_status.rate) &
385 AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT;
386
387 skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue);
388 if (unlikely(!skb))
389 return ;
390
391 ar9170_handle_tx_status(ar, skb, true,
392 le16_to_cpu(cmd->tx_status.status));
393 break;
394 }
395
396 case 0xc0:
397 /*
398 * pre-TBTT event
399 */
400 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
401 queue_work(ar->hw->workqueue, &ar->beacon_work);
402 break;
403
404 case 0xc2:
405 /*
406 * (IBSS) beacon send notification
407 * bytes: 04 c2 XX YY B4 B3 B2 B1
408 *
409 * XX always 80
410 * YY always 00
411 * B1-B4 "should" be the number of send out beacons.
412 */
413 break;
414
415 case 0xc3:
416 /* End of Atim Window */
417 break;
418
419 case 0xc4:
420 case 0xc5:
421 /* BlockACK events */
422 break;
423
424 case 0xc6:
425 /* Watchdog Interrupt */
426 break;
427
428 case 0xc9:
429 /* retransmission issue / SIFS/EIFS collision ?! */
430 break;
431
432 default:
433 printk(KERN_INFO "received unhandled event %x\n", cmd->type);
434 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
435 break;
436 }
437}
438
439/*
440 * If the frame alignment is right (or the kernel has
441 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
442 * is only a single MPDU in the USB frame, then we can
443 * submit to mac80211 the SKB directly. However, since
444 * there may be multiple packets in one SKB in stream
445 * mode, and we need to observe the proper ordering,
446 * this is non-trivial.
447 */
448static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
449{
450 struct sk_buff *skb;
451 struct ar9170_rx_head *head = (void *)buf;
452 struct ar9170_rx_tail *tail;
453 struct ieee80211_rx_status status;
454 int mpdu_len, i;
455 u8 error, antennas = 0, decrypt;
456 __le16 fc;
457 int reserved;
458
459 if (unlikely(!IS_STARTED(ar)))
460 return ;
461
462 /* Received MPDU */
463 mpdu_len = len;
464 mpdu_len -= sizeof(struct ar9170_rx_head);
465 mpdu_len -= sizeof(struct ar9170_rx_tail);
466 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
467 BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24);
468
469 if (mpdu_len <= FCS_LEN)
470 return;
471
472 tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len);
473
474 for (i = 0; i < 3; i++)
475 if (tail->rssi[i] != 0x80)
476 antennas |= BIT(i);
477
478 /* post-process RSSI */
479 for (i = 0; i < 7; i++)
480 if (tail->rssi[i] & 0x80)
481 tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f;
482
483 memset(&status, 0, sizeof(status));
484
485 status.band = ar->channel->band;
486 status.freq = ar->channel->center_freq;
487 status.signal = ar->noise[0] + tail->rssi_combined;
488 status.noise = ar->noise[0];
489 status.antenna = antennas;
490
491 switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) {
492 case AR9170_RX_STATUS_MODULATION_CCK:
493 if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
494 status.flag |= RX_FLAG_SHORTPRE;
495 switch (head->plcp[0]) {
496 case 0x0a:
497 status.rate_idx = 0;
498 break;
499 case 0x14:
500 status.rate_idx = 1;
501 break;
502 case 0x37:
503 status.rate_idx = 2;
504 break;
505 case 0x6e:
506 status.rate_idx = 3;
507 break;
508 default:
509 if ((!ar->sniffer_enabled) && (net_ratelimit()))
510 printk(KERN_ERR "%s: invalid plcp cck rate "
511 "(%x).\n", wiphy_name(ar->hw->wiphy),
512 head->plcp[0]);
513 return;
514 }
515 break;
516 case AR9170_RX_STATUS_MODULATION_OFDM:
517 switch (head->plcp[0] & 0xF) {
518 case 0xB:
519 status.rate_idx = 0;
520 break;
521 case 0xF:
522 status.rate_idx = 1;
523 break;
524 case 0xA:
525 status.rate_idx = 2;
526 break;
527 case 0xE:
528 status.rate_idx = 3;
529 break;
530 case 0x9:
531 status.rate_idx = 4;
532 break;
533 case 0xD:
534 status.rate_idx = 5;
535 break;
536 case 0x8:
537 status.rate_idx = 6;
538 break;
539 case 0xC:
540 status.rate_idx = 7;
541 break;
542 default:
543 if ((!ar->sniffer_enabled) && (net_ratelimit()))
544 printk(KERN_ERR "%s: invalid plcp ofdm rate "
545 "(%x).\n", wiphy_name(ar->hw->wiphy),
546 head->plcp[0]);
547 return;
548 }
549 if (status.band == IEEE80211_BAND_2GHZ)
550 status.rate_idx += 4;
551 break;
552 case AR9170_RX_STATUS_MODULATION_HT:
553 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
554 /* XXX */
555
556 if (net_ratelimit())
557 printk(KERN_ERR "%s: invalid modulation\n",
558 wiphy_name(ar->hw->wiphy));
559 return;
560 }
561
562 error = tail->error;
563
564 if (error & AR9170_RX_ERROR_MMIC) {
565 status.flag |= RX_FLAG_MMIC_ERROR;
566 error &= ~AR9170_RX_ERROR_MMIC;
567 }
568
569 if (error & AR9170_RX_ERROR_PLCP) {
570 status.flag |= RX_FLAG_FAILED_PLCP_CRC;
571 error &= ~AR9170_RX_ERROR_PLCP;
572 }
573
574 if (error & AR9170_RX_ERROR_FCS) {
575 status.flag |= RX_FLAG_FAILED_FCS_CRC;
576 error &= ~AR9170_RX_ERROR_FCS;
577 }
578
579 decrypt = ar9170_get_decrypt_type(tail);
580 if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
581 decrypt != AR9170_ENC_ALG_NONE)
582 status.flag |= RX_FLAG_DECRYPTED;
583
584 /* ignore wrong RA errors */
585 error &= ~AR9170_RX_ERROR_WRONG_RA;
586
587 if (error & AR9170_RX_ERROR_DECRYPT) {
588 error &= ~AR9170_RX_ERROR_DECRYPT;
589
590 /*
591 * Rx decryption is done in place,
592 * the original data is lost anyway.
593 */
594 return ;
595 }
596
597 /* drop any other error frames */
598 if ((error) && (net_ratelimit())) {
599 printk(KERN_DEBUG "%s: errors: %#x\n",
600 wiphy_name(ar->hw->wiphy), error);
601 return;
602 }
603
604 buf += sizeof(struct ar9170_rx_head);
605 fc = *(__le16 *)buf;
606
607 if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc))
608 reserved = 32 + 2;
609 else
610 reserved = 32;
611
612 skb = dev_alloc_skb(mpdu_len + reserved);
613 if (!skb)
614 return;
615
616 skb_reserve(skb, reserved);
617 memcpy(skb_put(skb, mpdu_len), buf, mpdu_len);
618 ieee80211_rx_irqsafe(ar->hw, skb, &status);
619}
620
621void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
622{
623 unsigned int i, tlen, resplen;
624 u8 *tbuf, *respbuf;
625
626 tbuf = skb->data;
627 tlen = skb->len;
628
629 while (tlen >= 4) {
630 int clen = tbuf[1] << 8 | tbuf[0];
631 int wlen = (clen + 3) & ~3;
632
633 /*
634 * parse stream (if any)
635 */
636 if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
637 printk(KERN_ERR "%s: missing tag!\n",
638 wiphy_name(ar->hw->wiphy));
639 return ;
640 }
641 if (wlen > tlen - 4) {
642 printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n",
643 wiphy_name(ar->hw->wiphy), clen, wlen, tlen);
644 print_hex_dump(KERN_DEBUG, "data: ",
645 DUMP_PREFIX_OFFSET,
646 16, 1, tbuf, tlen, true);
647 return ;
648 }
649 resplen = clen;
650 respbuf = tbuf + 4;
651 tbuf += wlen + 4;
652 tlen -= wlen + 4;
653
654 i = 0;
655
656 /* weird thing, but this is the same in the original driver */
657 while (resplen > 2 && i < 12 &&
658 respbuf[0] == 0xff && respbuf[1] == 0xff) {
659 i += 2;
660 resplen -= 2;
661 respbuf += 2;
662 }
663
664 if (resplen < 4)
665 continue;
666
667 /* found the 6 * 0xffff marker? */
668 if (i == 12)
669 ar9170_handle_command_response(ar, respbuf, resplen);
670 else
671 ar9170_handle_mpdu(ar, respbuf, resplen);
672 }
673
674 if (tlen)
675 printk(KERN_ERR "%s: buffer remains!\n",
676 wiphy_name(ar->hw->wiphy));
677}
678
679#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
680do { \
681 queue.aifs = ai_fs; \
682 queue.cw_min = cwmin; \
683 queue.cw_max = cwmax; \
684 queue.txop = _txop; \
685} while (0)
686
687static int ar9170_op_start(struct ieee80211_hw *hw)
688{
689 struct ar9170 *ar = hw->priv;
690 int err, i;
691
692 mutex_lock(&ar->mutex);
693
694 /* reinitialize queues statistics */
695 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
696 for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
697 ar->tx_stats[i].limit = 8;
698
699 /* reset QoS defaults */
700 AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
701 AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
702 AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
703 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
704 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
705
706 err = ar->open(ar);
707 if (err)
708 goto out;
709
710 err = ar9170_init_mac(ar);
711 if (err)
712 goto out;
713
714 err = ar9170_set_qos(ar);
715 if (err)
716 goto out;
717
718 err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
719 if (err)
720 goto out;
721
722 err = ar9170_init_rf(ar);
723 if (err)
724 goto out;
725
726 /* start DMA */
727 err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
728 if (err)
729 goto out;
730
731 ar->state = AR9170_STARTED;
732
733out:
734 mutex_unlock(&ar->mutex);
735 return err;
736}
737
738static void ar9170_op_stop(struct ieee80211_hw *hw)
739{
740 struct ar9170 *ar = hw->priv;
741
742 if (IS_STARTED(ar))
743 ar->state = AR9170_IDLE;
744
745 mutex_lock(&ar->mutex);
746
747 cancel_delayed_work_sync(&ar->tx_status_janitor);
748 cancel_work_sync(&ar->filter_config_work);
749 cancel_work_sync(&ar->beacon_work);
750 skb_queue_purge(&ar->global_tx_status_waste);
751 skb_queue_purge(&ar->global_tx_status);
752
753 if (IS_ACCEPTING_CMD(ar)) {
754 ar9170_set_leds_state(ar, 0);
755
756 /* stop DMA */
757 ar9170_write_reg(ar, 0x1c3d30, 0);
758 ar->stop(ar);
759 }
760
761 mutex_unlock(&ar->mutex);
762}
763
764int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
765{
766 struct ar9170 *ar = hw->priv;
767 struct ieee80211_hdr *hdr;
768 struct ar9170_tx_control *txc;
769 struct ieee80211_tx_info *info;
770 struct ieee80211_rate *rate = NULL;
771 struct ieee80211_tx_rate *txrate;
772 unsigned int queue = skb_get_queue_mapping(skb);
773 unsigned long flags = 0;
774 struct ar9170_sta_info *sta_info = NULL;
775 u32 power, chains;
776 u16 keytype = 0;
777 u16 len, icv = 0;
778 int err;
779 bool tx_status;
780
781 if (unlikely(!IS_STARTED(ar)))
782 goto err_free;
783
784 hdr = (void *)skb->data;
785 info = IEEE80211_SKB_CB(skb);
786 len = skb->len;
787
788 spin_lock_irqsave(&ar->tx_stats_lock, flags);
789 if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) {
790 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
791 return NETDEV_TX_OK;
792 }
793
794 ar->tx_stats[queue].len++;
795 ar->tx_stats[queue].count++;
796 if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len)
797 ieee80211_stop_queue(hw, queue);
798
799 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
800
801 txc = (void *)skb_push(skb, sizeof(*txc));
802
803 tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) ||
804 ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0));
805
806 if (info->control.hw_key) {
807 icv = info->control.hw_key->icv_len;
808
809 switch (info->control.hw_key->alg) {
810 case ALG_WEP:
811 keytype = AR9170_TX_MAC_ENCR_RC4;
812 break;
813 case ALG_TKIP:
814 keytype = AR9170_TX_MAC_ENCR_RC4;
815 break;
816 case ALG_CCMP:
817 keytype = AR9170_TX_MAC_ENCR_AES;
818 break;
819 default:
820 WARN_ON(1);
821 goto err_dequeue;
822 }
823 }
824
825 /* Length */
826 txc->length = cpu_to_le16(len + icv + 4);
827
828 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
829 AR9170_TX_MAC_BACKOFF);
830 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
831 AR9170_TX_MAC_QOS_SHIFT);
832 txc->mac_control |= cpu_to_le16(keytype);
833 txc->phy_control = cpu_to_le32(0);
834
835 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
836 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
837
838 if (info->flags & IEEE80211_TX_CTL_AMPDU)
839 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
840
841 txrate = &info->control.rates[0];
842
843 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
844 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
845 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
846 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
847
848 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
849 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
850
851 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
852 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
853
854 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
855 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
856 /* this works because 40 MHz is 2 and dup is 3 */
857 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
858 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
859
860 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
861 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
862
863 if (txrate->flags & IEEE80211_TX_RC_MCS) {
864 u32 r = txrate->idx;
865 u8 *txpower;
866
867 r <<= AR9170_TX_PHY_MCS_SHIFT;
868 if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK))
869 goto err_dequeue;
870 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
871 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
872
873 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
874 if (info->band == IEEE80211_BAND_5GHZ)
875 txpower = ar->power_5G_ht40;
876 else
877 txpower = ar->power_2G_ht40;
878 } else {
879 if (info->band == IEEE80211_BAND_5GHZ)
880 txpower = ar->power_5G_ht20;
881 else
882 txpower = ar->power_2G_ht20;
883 }
884
885 power = txpower[(txrate->idx) & 7];
886 } else {
887 u8 *txpower;
888 u32 mod;
889 u32 phyrate;
890 u8 idx = txrate->idx;
891
892 if (info->band != IEEE80211_BAND_2GHZ) {
893 idx += 4;
894 txpower = ar->power_5G_leg;
895 mod = AR9170_TX_PHY_MOD_OFDM;
896 } else {
897 if (idx < 4) {
898 txpower = ar->power_2G_cck;
899 mod = AR9170_TX_PHY_MOD_CCK;
900 } else {
901 mod = AR9170_TX_PHY_MOD_OFDM;
902 txpower = ar->power_2G_ofdm;
903 }
904 }
905
906 rate = &__ar9170_ratetable[idx];
907
908 phyrate = rate->hw_value & 0xF;
909 power = txpower[(rate->hw_value & 0x30) >> 4];
910 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
911
912 txc->phy_control |= cpu_to_le32(mod);
913 txc->phy_control |= cpu_to_le32(phyrate);
914 }
915
916 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
917 power &= AR9170_TX_PHY_TX_PWR_MASK;
918 txc->phy_control |= cpu_to_le32(power);
919
920 /* set TX chains */
921 if (ar->eeprom.tx_mask == 1) {
922 chains = AR9170_TX_PHY_TXCHAIN_1;
923 } else {
924 chains = AR9170_TX_PHY_TXCHAIN_2;
925
926 /* >= 36M legacy OFDM - use only one chain */
927 if (rate && rate->bitrate >= 360)
928 chains = AR9170_TX_PHY_TXCHAIN_1;
929 }
930 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
931
932 if (tx_status) {
933 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
934 /*
935 * WARNING:
936 * Putting the QoS queue bits into an unexplored territory is
937 * certainly not elegant.
938 *
939 * In my defense: This idea provides a reasonable way to
940 * smuggle valuable information to the tx_status callback.
941 * Also, the idea behind this bit-abuse came straight from
942 * the original driver code.
943 */
944
945 txc->phy_control |=
946 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
947
948 if (info->control.sta) {
949 sta_info = (void *) info->control.sta->drv_priv;
950 skb_queue_tail(&sta_info->tx_status[queue], skb);
951 } else {
952 skb_queue_tail(&ar->global_tx_status, skb);
953
954 queue_delayed_work(ar->hw->workqueue,
955 &ar->tx_status_janitor,
956 msecs_to_jiffies(100));
957 }
958 }
959
960 err = ar->tx(ar, skb, tx_status, 0);
961 if (unlikely(tx_status && err)) {
962 if (info->control.sta)
963 skb_unlink(skb, &sta_info->tx_status[queue]);
964 else
965 skb_unlink(skb, &ar->global_tx_status);
966 }
967
968 return NETDEV_TX_OK;
969
970err_dequeue:
971 spin_lock_irqsave(&ar->tx_stats_lock, flags);
972 ar->tx_stats[queue].len--;
973 ar->tx_stats[queue].count--;
974 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
975
976err_free:
977 dev_kfree_skb(skb);
978 return NETDEV_TX_OK;
979}
980
981static int ar9170_op_add_interface(struct ieee80211_hw *hw,
982 struct ieee80211_if_init_conf *conf)
983{
984 struct ar9170 *ar = hw->priv;
985 int err = 0;
986
987 mutex_lock(&ar->mutex);
988
989 if (ar->vif) {
990 err = -EBUSY;
991 goto unlock;
992 }
993
994 ar->vif = conf->vif;
995 memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
996
997 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
998 ar->rx_software_decryption = true;
999 ar->disable_offload = true;
1000 }
1001
1002 ar->cur_filter = 0;
1003 ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
1004 err = ar9170_update_frame_filter(ar);
1005 if (err)
1006 goto unlock;
1007
1008 err = ar9170_set_operating_mode(ar);
1009
1010unlock:
1011 mutex_unlock(&ar->mutex);
1012 return err;
1013}
1014
1015static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
1016 struct ieee80211_if_init_conf *conf)
1017{
1018 struct ar9170 *ar = hw->priv;
1019
1020 mutex_lock(&ar->mutex);
1021 ar->vif = NULL;
1022 ar->want_filter = 0;
1023 ar9170_update_frame_filter(ar);
1024 ar9170_set_beacon_timers(ar);
1025 dev_kfree_skb(ar->beacon);
1026 ar->beacon = NULL;
1027 ar->sniffer_enabled = false;
1028 ar->rx_software_decryption = false;
1029 ar9170_set_operating_mode(ar);
1030 mutex_unlock(&ar->mutex);
1031}
1032
1033static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1034{
1035 struct ar9170 *ar = hw->priv;
1036 int err = 0;
1037
1038 mutex_lock(&ar->mutex);
1039
1040 if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
1041 /* TODO */
1042 err = 0;
1043 }
1044
1045 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
1046 /* TODO */
1047 err = 0;
1048 }
1049
1050 if (changed & IEEE80211_CONF_CHANGE_PS) {
1051 /* TODO */
1052 err = 0;
1053 }
1054
1055 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1056 /* TODO */
1057 err = 0;
1058 }
1059
1060 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
1061 /*
1062 * is it long_frame_max_tx_count or short_frame_max_tx_count?
1063 */
1064
1065 err = ar9170_set_hwretry_limit(ar,
1066 ar->hw->conf.long_frame_max_tx_count);
1067 if (err)
1068 goto out;
1069 }
1070
1071 if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) {
1072 err = ar9170_set_beacon_timers(ar);
1073 if (err)
1074 goto out;
1075 }
1076
1077 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1078 err = ar9170_set_channel(ar, hw->conf.channel,
1079 AR9170_RFI_NONE, AR9170_BW_20);
1080 if (err)
1081 goto out;
1082 /* adjust slot time for 5 GHz */
1083 if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
1084 err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
1085 9 << 10);
1086 }
1087
1088out:
1089 mutex_unlock(&ar->mutex);
1090 return err;
1091}
1092
1093static int ar9170_op_config_interface(struct ieee80211_hw *hw,
1094 struct ieee80211_vif *vif,
1095 struct ieee80211_if_conf *conf)
1096{
1097 struct ar9170 *ar = hw->priv;
1098 int err = 0;
1099
1100 mutex_lock(&ar->mutex);
1101
1102 if (conf->changed & IEEE80211_IFCC_BSSID) {
1103 memcpy(ar->bssid, conf->bssid, ETH_ALEN);
1104 err = ar9170_set_operating_mode(ar);
1105 }
1106
1107 if (conf->changed & IEEE80211_IFCC_BEACON) {
1108 err = ar9170_update_beacon(ar);
1109
1110 if (err)
1111 goto out;
1112 err = ar9170_set_beacon_timers(ar);
1113 }
1114
1115out:
1116 mutex_unlock(&ar->mutex);
1117 return err;
1118}
1119
1120static void ar9170_set_filters(struct work_struct *work)
1121{
1122 struct ar9170 *ar = container_of(work, struct ar9170,
1123 filter_config_work);
1124 int err;
1125
1126 mutex_lock(&ar->mutex);
1127 if (unlikely(!IS_STARTED(ar)))
1128 goto unlock;
1129
1130 if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
1131 err = ar9170_set_operating_mode(ar);
1132 if (err)
1133 goto unlock;
1134 }
1135
1136 if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) {
1137 err = ar9170_update_multicast(ar);
1138 if (err)
1139 goto unlock;
1140 }
1141
1142 if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER)
1143 err = ar9170_update_frame_filter(ar);
1144
1145unlock:
1146 mutex_unlock(&ar->mutex);
1147}
1148
1149static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1150 unsigned int changed_flags,
1151 unsigned int *new_flags,
1152 int mc_count, struct dev_mc_list *mclist)
1153{
1154 struct ar9170 *ar = hw->priv;
1155
1156 /* mask supported flags */
1157 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
1158 FIF_PROMISC_IN_BSS;
1159
1160 /*
1161 * We can support more by setting the sniffer bit and
1162 * then checking the error flags, later.
1163 */
1164
1165 if (changed_flags & FIF_ALLMULTI) {
1166 if (*new_flags & FIF_ALLMULTI) {
1167 ar->want_mc_hash = ~0ULL;
1168 } else {
1169 u64 mchash;
1170 int i;
1171
1172 /* always get broadcast frames */
1173 mchash = 1ULL << (0xff>>2);
1174
1175 for (i = 0; i < mc_count; i++) {
1176 if (WARN_ON(!mclist))
1177 break;
1178 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
1179 mclist = mclist->next;
1180 }
1181 ar->want_mc_hash = mchash;
1182 }
1183 ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST;
1184 }
1185
1186 if (changed_flags & FIF_CONTROL) {
1187 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
1188 AR9170_MAC_REG_FTF_RTS |
1189 AR9170_MAC_REG_FTF_CTS |
1190 AR9170_MAC_REG_FTF_ACK |
1191 AR9170_MAC_REG_FTF_CFE |
1192 AR9170_MAC_REG_FTF_CFE_ACK;
1193
1194 if (*new_flags & FIF_CONTROL)
1195 ar->want_filter = ar->cur_filter | filter;
1196 else
1197 ar->want_filter = ar->cur_filter & ~filter;
1198
1199 ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER;
1200 }
1201
1202 if (changed_flags & FIF_PROMISC_IN_BSS) {
1203 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
1204 ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC;
1205 }
1206
1207 if (likely(IS_STARTED(ar)))
1208 queue_work(ar->hw->workqueue, &ar->filter_config_work);
1209}
1210
1211static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1212 struct ieee80211_vif *vif,
1213 struct ieee80211_bss_conf *bss_conf,
1214 u32 changed)
1215{
1216 struct ar9170 *ar = hw->priv;
1217 int err = 0;
1218
1219 mutex_lock(&ar->mutex);
1220
1221 ar9170_regwrite_begin(ar);
1222
1223 if (changed & BSS_CHANGED_ASSOC) {
1224 ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
1225
1226#ifndef CONFIG_AR9170_LEDS
1227 /* enable assoc LED. */
1228 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
1229#endif /* CONFIG_AR9170_LEDS */
1230 }
1231
1232 if (changed & BSS_CHANGED_HT) {
1233 /* TODO */
1234 err = 0;
1235 }
1236
1237 if (changed & BSS_CHANGED_ERP_SLOT) {
1238 u32 slottime = 20;
1239
1240 if (bss_conf->use_short_slot)
1241 slottime = 9;
1242
1243 ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
1244 }
1245
1246 if (changed & BSS_CHANGED_BASIC_RATES) {
1247 u32 cck, ofdm;
1248
1249 if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) {
1250 ofdm = bss_conf->basic_rates;
1251 cck = 0;
1252 } else {
1253 /* four cck rates */
1254 cck = bss_conf->basic_rates & 0xf;
1255 ofdm = bss_conf->basic_rates >> 4;
1256 }
1257 ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
1258 ofdm << 8 | cck);
1259 }
1260
1261 ar9170_regwrite_finish();
1262 err = ar9170_regwrite_result();
1263 mutex_unlock(&ar->mutex);
1264}
1265
1266static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
1267{
1268 struct ar9170 *ar = hw->priv;
1269 int err;
1270 u32 tsf_low;
1271 u32 tsf_high;
1272 u64 tsf;
1273
1274 mutex_lock(&ar->mutex);
1275 err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
1276 if (!err)
1277 err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
1278 mutex_unlock(&ar->mutex);
1279
1280 if (WARN_ON(err))
1281 return 0;
1282
1283 tsf = tsf_high;
1284 tsf = (tsf << 32) | tsf_low;
1285 return tsf;
1286}
1287
1288static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1289 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
1290 struct ieee80211_key_conf *key)
1291{
1292 struct ar9170 *ar = hw->priv;
1293 int err = 0, i;
1294 u8 ktype;
1295
1296 if ((!ar->vif) || (ar->disable_offload))
1297 return -EOPNOTSUPP;
1298
1299 switch (key->alg) {
1300 case ALG_WEP:
1301 if (key->keylen == LEN_WEP40)
1302 ktype = AR9170_ENC_ALG_WEP64;
1303 else
1304 ktype = AR9170_ENC_ALG_WEP128;
1305 break;
1306 case ALG_TKIP:
1307 ktype = AR9170_ENC_ALG_TKIP;
1308 break;
1309 case ALG_CCMP:
1310 ktype = AR9170_ENC_ALG_AESCCMP;
1311 break;
1312 default:
1313 return -EOPNOTSUPP;
1314 }
1315
1316 mutex_lock(&ar->mutex);
1317 if (cmd == SET_KEY) {
1318 if (unlikely(!IS_STARTED(ar))) {
1319 err = -EOPNOTSUPP;
1320 goto out;
1321 }
1322
1323 /* group keys need all-zeroes address */
1324 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1325 sta = NULL;
1326
1327 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
1328 for (i = 0; i < 64; i++)
1329 if (!(ar->usedkeys & BIT(i)))
1330 break;
1331 if (i == 64) {
1332 ar->rx_software_decryption = true;
1333 ar9170_set_operating_mode(ar);
1334 err = -ENOSPC;
1335 goto out;
1336 }
1337 } else {
1338 i = 64 + key->keyidx;
1339 }
1340
1341 key->hw_key_idx = i;
1342
1343 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
1344 key->key, min_t(u8, 16, key->keylen));
1345 if (err)
1346 goto out;
1347
1348 if (key->alg == ALG_TKIP) {
1349 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
1350 ktype, 1, key->key + 16, 16);
1351 if (err)
1352 goto out;
1353
1354 /*
1355 * hardware is not capable generating the MMIC
1356 * for fragmented frames!
1357 */
1358 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1359 }
1360
1361 if (i < 64)
1362 ar->usedkeys |= BIT(i);
1363
1364 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1365 } else {
1366 if (unlikely(!IS_STARTED(ar))) {
1367 /* The device is gone... together with the key ;-) */
1368 err = 0;
1369 goto out;
1370 }
1371
1372 err = ar9170_disable_key(ar, key->hw_key_idx);
1373 if (err)
1374 goto out;
1375
1376 if (key->hw_key_idx < 64) {
1377 ar->usedkeys &= ~BIT(key->hw_key_idx);
1378 } else {
1379 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
1380 AR9170_ENC_ALG_NONE, 0,
1381 NULL, 0);
1382 if (err)
1383 goto out;
1384
1385 if (key->alg == ALG_TKIP) {
1386 err = ar9170_upload_key(ar, key->hw_key_idx,
1387 NULL,
1388 AR9170_ENC_ALG_NONE, 1,
1389 NULL, 0);
1390 if (err)
1391 goto out;
1392 }
1393
1394 }
1395 }
1396
1397 ar9170_regwrite_begin(ar);
1398 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
1399 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
1400 ar9170_regwrite_finish();
1401 err = ar9170_regwrite_result();
1402
1403out:
1404 mutex_unlock(&ar->mutex);
1405
1406 return err;
1407}
1408
1409static void ar9170_sta_notify(struct ieee80211_hw *hw,
1410 struct ieee80211_vif *vif,
1411 enum sta_notify_cmd cmd,
1412 struct ieee80211_sta *sta)
1413{
1414 struct ar9170 *ar = hw->priv;
1415 struct ar9170_sta_info *info = (void *) sta->drv_priv;
1416 struct sk_buff *skb;
1417 unsigned int i;
1418
1419 switch (cmd) {
1420 case STA_NOTIFY_ADD:
1421 for (i = 0; i < ar->hw->queues; i++)
1422 skb_queue_head_init(&info->tx_status[i]);
1423 break;
1424
1425 case STA_NOTIFY_REMOVE:
1426
1427 /*
1428 * transfer all outstanding frames that need a tx_status
1429 * reports to the global tx_status queue
1430 */
1431
1432 for (i = 0; i < ar->hw->queues; i++) {
1433 while ((skb = skb_dequeue(&info->tx_status[i]))) {
1434#ifdef AR9170_QUEUE_DEBUG
1435 printk(KERN_DEBUG "%s: queueing frame in "
1436 "global tx_status queue =>\n",
1437 wiphy_name(ar->hw->wiphy));
1438
1439 ar9170_print_txheader(ar, skb);
1440#endif /* AR9170_QUEUE_DEBUG */
1441 skb_queue_tail(&ar->global_tx_status, skb);
1442 }
1443 }
1444 queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
1445 msecs_to_jiffies(100));
1446 break;
1447
1448 default:
1449 break;
1450 }
1451}
1452
1453static int ar9170_get_stats(struct ieee80211_hw *hw,
1454 struct ieee80211_low_level_stats *stats)
1455{
1456 struct ar9170 *ar = hw->priv;
1457 u32 val;
1458 int err;
1459
1460 mutex_lock(&ar->mutex);
1461 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
1462 ar->stats.dot11ACKFailureCount += val;
1463
1464 memcpy(stats, &ar->stats, sizeof(*stats));
1465 mutex_unlock(&ar->mutex);
1466
1467 return 0;
1468}
1469
1470static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
1471 struct ieee80211_tx_queue_stats *tx_stats)
1472{
1473 struct ar9170 *ar = hw->priv;
1474
1475 spin_lock_bh(&ar->tx_stats_lock);
1476 memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
1477 spin_unlock_bh(&ar->tx_stats_lock);
1478
1479 return 0;
1480}
1481
1482static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
1483 const struct ieee80211_tx_queue_params *param)
1484{
1485 struct ar9170 *ar = hw->priv;
1486 int ret;
1487
1488 mutex_lock(&ar->mutex);
1489 if ((param) && !(queue > ar->hw->queues)) {
1490 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
1491 param, sizeof(*param));
1492
1493 ret = ar9170_set_qos(ar);
1494 } else
1495 ret = -EINVAL;
1496
1497 mutex_unlock(&ar->mutex);
1498 return ret;
1499}
1500
1501static const struct ieee80211_ops ar9170_ops = {
1502 .start = ar9170_op_start,
1503 .stop = ar9170_op_stop,
1504 .tx = ar9170_op_tx,
1505 .add_interface = ar9170_op_add_interface,
1506 .remove_interface = ar9170_op_remove_interface,
1507 .config = ar9170_op_config,
1508 .config_interface = ar9170_op_config_interface,
1509 .configure_filter = ar9170_op_configure_filter,
1510 .conf_tx = ar9170_conf_tx,
1511 .bss_info_changed = ar9170_op_bss_info_changed,
1512 .get_tsf = ar9170_op_get_tsf,
1513 .set_key = ar9170_set_key,
1514 .sta_notify = ar9170_sta_notify,
1515 .get_stats = ar9170_get_stats,
1516 .get_tx_stats = ar9170_get_tx_stats,
1517};
1518
1519void *ar9170_alloc(size_t priv_size)
1520{
1521 struct ieee80211_hw *hw;
1522 struct ar9170 *ar;
1523 int i;
1524
1525 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
1526 if (!hw)
1527 return ERR_PTR(-ENOMEM);
1528
1529 ar = hw->priv;
1530 ar->hw = hw;
1531
1532 mutex_init(&ar->mutex);
1533 spin_lock_init(&ar->cmdlock);
1534 spin_lock_init(&ar->tx_stats_lock);
1535 skb_queue_head_init(&ar->global_tx_status);
1536 skb_queue_head_init(&ar->global_tx_status_waste);
1537 INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
1538 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
1539 INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor);
1540
1541 /* all hw supports 2.4 GHz, so set channel to 1 by default */
1542 ar->channel = &ar9170_2ghz_chantable[0];
1543
1544 /* first part of wiphy init */
1545 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1546 BIT(NL80211_IFTYPE_WDS) |
1547 BIT(NL80211_IFTYPE_ADHOC);
1548 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
1549 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1550 IEEE80211_HW_SIGNAL_DBM |
1551 IEEE80211_HW_NOISE_DBM;
1552
1553 ar->hw->queues = __AR9170_NUM_TXQ;
1554 ar->hw->extra_tx_headroom = 8;
1555 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
1556
1557 ar->hw->max_rates = 1;
1558 ar->hw->max_rate_tries = 3;
1559
1560 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
1561 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
1562
1563 return ar;
1564}
1565
1566static int ar9170_read_eeprom(struct ar9170 *ar)
1567{
1568#define RW 8 /* number of words to read at once */
1569#define RB (sizeof(u32) * RW)
1570 DECLARE_MAC_BUF(mbuf);
1571 u8 *eeprom = (void *)&ar->eeprom;
1572 u8 *addr = ar->eeprom.mac_address;
1573 __le32 offsets[RW];
1574 int i, j, err, bands = 0;
1575
1576 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
1577
1578 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
1579#ifndef __CHECKER__
1580 /* don't want to handle trailing remains */
1581 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
1582#endif
1583
1584 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
1585 for (j = 0; j < RW; j++)
1586 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
1587 RB * i + 4 * j);
1588
1589 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
1590 RB, (u8 *) &offsets,
1591 RB, eeprom + RB * i);
1592 if (err)
1593 return err;
1594 }
1595
1596#undef RW
1597#undef RB
1598
1599 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
1600 return -ENODATA;
1601
1602 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
1603 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
1604 bands++;
1605 }
1606 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
1607 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
1608 bands++;
1609 }
1610 /*
1611 * I measured this, a bandswitch takes roughly
1612 * 135 ms and a frequency switch about 80.
1613 *
1614 * FIXME: measure these values again once EEPROM settings
1615 * are used, that will influence them!
1616 */
1617 if (bands == 2)
1618 ar->hw->channel_change_time = 135 * 1000;
1619 else
1620 ar->hw->channel_change_time = 80 * 1000;
1621
1622 /* second part of wiphy init */
1623 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
1624
1625 return bands ? 0 : -EINVAL;
1626}
1627
1628int ar9170_register(struct ar9170 *ar, struct device *pdev)
1629{
1630 int err;
1631
1632 /* try to read EEPROM, init MAC addr */
1633 err = ar9170_read_eeprom(ar);
1634 if (err)
1635 goto err_out;
1636
1637 err = ieee80211_register_hw(ar->hw);
1638 if (err)
1639 goto err_out;
1640
1641 err = ar9170_init_leds(ar);
1642 if (err)
1643 goto err_unreg;
1644
1645#ifdef CONFIG_AR9170_LEDS
1646 err = ar9170_register_leds(ar);
1647 if (err)
1648 goto err_unreg;
1649#endif /* CONFIG_AR9170_LEDS */
1650
1651 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
1652 wiphy_name(ar->hw->wiphy));
1653
1654 return err;
1655
1656err_unreg:
1657 ieee80211_unregister_hw(ar->hw);
1658
1659err_out:
1660 return err;
1661}
1662
1663void ar9170_unregister(struct ar9170 *ar)
1664{
1665#ifdef CONFIG_AR9170_LEDS
1666 ar9170_unregister_leds(ar);
1667#endif /* CONFIG_AR9170_LEDS */
1668
1669 ieee80211_unregister_hw(ar->hw);
1670 mutex_destroy(&ar->mutex);
1671}
diff --git a/drivers/net/wireless/ar9170/phy.c b/drivers/net/wireless/ar9170/phy.c
new file mode 100644
index 000000000000..6ce20754b8e7
--- /dev/null
+++ b/drivers/net/wireless/ar9170/phy.c
@@ -0,0 +1,1240 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * PHY and RF code
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38
39#include <linux/bitrev.h>
40#include "ar9170.h"
41#include "cmd.h"
42
43static int ar9170_init_power_cal(struct ar9170 *ar)
44{
45 ar9170_regwrite_begin(ar);
46
47 ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
48 ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
49 ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
50 ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
51 ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
52 ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
53 ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
54 ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
55 ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
56 ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
57
58 ar9170_regwrite_finish();
59 return ar9170_regwrite_result();
60}
61
62struct ar9170_phy_init {
63 u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
64};
65
66static struct ar9170_phy_init ar5416_phy_init[] = {
67 { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
68 { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
69 { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
70 { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
71 { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
72 { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
73 { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
74 { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
75 { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
76 { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
77 { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
78 { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
79 { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
80 { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
81 { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
82 { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
83 { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
84 { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
85 { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
86 { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
87 { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
88 { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
89 { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
90 { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
91 { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
92 { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
93 { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
94 { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
95 { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
96 { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
97 { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
98 { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
99 { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
100 { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
101 { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
102 { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
103 { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
104 { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
105 { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
106 { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
107 { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
108 { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
109 { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
110 { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
111 { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
112 { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
113 { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
114 { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
115 { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
116 { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
117 { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
118 { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
119 { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
120 { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
121 { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
122 { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
123 { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
124 { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
125 { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
126 { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
127 { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
128 { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
129 { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
130 { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
131 { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
132 { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
133 { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
134 { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
135 { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
136 { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
137 { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
138 { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
139 { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
140 { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
141 { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
142 { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
143 { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
144 { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
145 { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
146 { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
147 { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
148 { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
149 { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
150 { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
151 { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
152 { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
153 { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
154 { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
155 { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
156 { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
157 { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
158 { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
159 { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
160 { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
161 { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
162 { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
163 { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
164 { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
165 { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
166 { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
167 { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
168 { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
169 { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
170 { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
171 { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
172 { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
173 { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
174 { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
175 { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
176 { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
177 { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
178 { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
179 { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
180 { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
181 { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
182 { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
183 { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
184 { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
185 { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
186 { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
187 { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
188 { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
189 { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
190 { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
191 { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
192 { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
193 { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
194 { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
195 { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
196 { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
197 { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
198 { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
199 { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
200 { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
201 { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
202 { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
203 { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
204 { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
205 { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
206 { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
207 { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
208 { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
209 { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
210 { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
211 { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
212 { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
213 { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
214 { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
215 { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
216 { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
217 { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
218 { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
219 { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
220 { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
221 { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
222 { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
223 { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
224 { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
225 { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
226 { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
227 { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
228 { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
229 { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
230 { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
231 { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
232 { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
233 { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
234 { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
235 { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
236 { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
237 { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
238 { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
239 { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
240 { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
241 { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
242 { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
243 { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
244 { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
245 { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
246 { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
247 { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
248 { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
249 { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
250 { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
251 { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
252 { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
253 { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
254 { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
255 { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
256 { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
257 { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
258 { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
259 { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
260 { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
261 { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
262 { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
263 { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
264 { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
265 { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
266 { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
267 { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
268 { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
269 { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
270 { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
271 { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
272 { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
273 { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
274 { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
275 { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
276 { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
277 { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
278 { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
279 { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
280 { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
281 { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
282 { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
283 { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
284 { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
285 { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
286 { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
287 { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
288 { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
289 { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
290 { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
291 { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
292 { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
293 { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
294 { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
295 { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
296 { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
297 { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
298 { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
299 { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
300 { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
301 { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
302 { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
303 { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
304 { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
305 { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
306 { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
307 { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
308 { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
309 { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
310 { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
311 { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
312 { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
313 { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
314 { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
315 { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
316 { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
317 { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
318 { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
319 { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
320 { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
321 { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
322 { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
323 { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
324 { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
325 { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
326 { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
327 { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
328 { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
329 { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
330 { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
331 { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
332 { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
333 { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
334 { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
335 { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
336 { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
337 { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
338 { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
339 { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
340 { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
341 { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
342 { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
343 { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
344 { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
345 { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
346 { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
347 { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
348 { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
349 { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
350 { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
351 { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
352 { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
353 { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
354 { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
355 { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
356 { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
357 { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
358 { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
359 { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
360 { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
361 { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
362 { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
363 { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
364 { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
365 { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
366 { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
367 { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
368 { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
369 { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
370 { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
371 { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
372 { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
373 { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
374 { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
375 { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
376 { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
377 { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
378 { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
379 { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
380/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
381 { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
382 { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
383 { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
384 { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
385 { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
386 { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
387 { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
388 { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
389 { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
390 { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
391 { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
392 { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
393 { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
394 { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
395 { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
396 { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
397};
398
399int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
400{
401 int i, err;
402 u32 val;
403 bool is_2ghz = band == IEEE80211_BAND_2GHZ;
404 bool is_40mhz = false; /* XXX: for now */
405
406 ar9170_regwrite_begin(ar);
407
408 for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
409 if (is_40mhz) {
410 if (is_2ghz)
411 val = ar5416_phy_init[i]._2ghz_40;
412 else
413 val = ar5416_phy_init[i]._5ghz_40;
414 } else {
415 if (is_2ghz)
416 val = ar5416_phy_init[i]._2ghz_20;
417 else
418 val = ar5416_phy_init[i]._5ghz_20;
419 }
420
421 ar9170_regwrite(ar5416_phy_init[i].reg, val);
422 }
423
424 ar9170_regwrite_finish();
425 err = ar9170_regwrite_result();
426 if (err)
427 return err;
428
429 /* XXX: use EEPROM data here! */
430
431 err = ar9170_init_power_cal(ar);
432 if (err)
433 return err;
434
435 /* XXX: remove magic! */
436 if (is_2ghz)
437 err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
438 else
439 err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
440
441 return err;
442}
443
444struct ar9170_rf_init {
445 u32 reg, _5ghz, _2ghz;
446};
447
448static struct ar9170_rf_init ar9170_rf_init[] = {
449 /* bank 0 */
450 { 0x1c58b0, 0x1e5795e5, 0x1e5795e5},
451 { 0x1c58e0, 0x02008020, 0x02008020},
452 /* bank 1 */
453 { 0x1c58b0, 0x02108421, 0x02108421},
454 { 0x1c58ec, 0x00000008, 0x00000008},
455 /* bank 2 */
456 { 0x1c58b0, 0x0e73ff17, 0x0e73ff17},
457 { 0x1c58e0, 0x00000420, 0x00000420},
458 /* bank 3 */
459 { 0x1c58f0, 0x01400018, 0x01c00018},
460 /* bank 4 */
461 { 0x1c58b0, 0x000001a1, 0x000001a1},
462 { 0x1c58e8, 0x00000001, 0x00000001},
463 /* bank 5 */
464 { 0x1c58b0, 0x00000013, 0x00000013},
465 { 0x1c58e4, 0x00000002, 0x00000002},
466 /* bank 6 */
467 { 0x1c58b0, 0x00000000, 0x00000000},
468 { 0x1c58b0, 0x00000000, 0x00000000},
469 { 0x1c58b0, 0x00000000, 0x00000000},
470 { 0x1c58b0, 0x00000000, 0x00000000},
471 { 0x1c58b0, 0x00000000, 0x00000000},
472 { 0x1c58b0, 0x00004000, 0x00004000},
473 { 0x1c58b0, 0x00006c00, 0x00006c00},
474 { 0x1c58b0, 0x00002c00, 0x00002c00},
475 { 0x1c58b0, 0x00004800, 0x00004800},
476 { 0x1c58b0, 0x00004000, 0x00004000},
477 { 0x1c58b0, 0x00006000, 0x00006000},
478 { 0x1c58b0, 0x00001000, 0x00001000},
479 { 0x1c58b0, 0x00004000, 0x00004000},
480 { 0x1c58b0, 0x00007c00, 0x00007c00},
481 { 0x1c58b0, 0x00007c00, 0x00007c00},
482 { 0x1c58b0, 0x00007c00, 0x00007c00},
483 { 0x1c58b0, 0x00007c00, 0x00007c00},
484 { 0x1c58b0, 0x00007c00, 0x00007c00},
485 { 0x1c58b0, 0x00087c00, 0x00087c00},
486 { 0x1c58b0, 0x00007c00, 0x00007c00},
487 { 0x1c58b0, 0x00005400, 0x00005400},
488 { 0x1c58b0, 0x00000c00, 0x00000c00},
489 { 0x1c58b0, 0x00001800, 0x00001800},
490 { 0x1c58b0, 0x00007c00, 0x00007c00},
491 { 0x1c58b0, 0x00006c00, 0x00006c00},
492 { 0x1c58b0, 0x00006c00, 0x00006c00},
493 { 0x1c58b0, 0x00007c00, 0x00007c00},
494 { 0x1c58b0, 0x00002c00, 0x00002c00},
495 { 0x1c58b0, 0x00003c00, 0x00003c00},
496 { 0x1c58b0, 0x00003800, 0x00003800},
497 { 0x1c58b0, 0x00001c00, 0x00001c00},
498 { 0x1c58b0, 0x00000800, 0x00000800},
499 { 0x1c58b0, 0x00000408, 0x00000408},
500 { 0x1c58b0, 0x00004c15, 0x00004c15},
501 { 0x1c58b0, 0x00004188, 0x00004188},
502 { 0x1c58b0, 0x0000201e, 0x0000201e},
503 { 0x1c58b0, 0x00010408, 0x00010408},
504 { 0x1c58b0, 0x00000801, 0x00000801},
505 { 0x1c58b0, 0x00000c08, 0x00000c08},
506 { 0x1c58b0, 0x0000181e, 0x0000181e},
507 { 0x1c58b0, 0x00001016, 0x00001016},
508 { 0x1c58b0, 0x00002800, 0x00002800},
509 { 0x1c58b0, 0x00004010, 0x00004010},
510 { 0x1c58b0, 0x0000081c, 0x0000081c},
511 { 0x1c58b0, 0x00000115, 0x00000115},
512 { 0x1c58b0, 0x00000015, 0x00000015},
513 { 0x1c58b0, 0x00000066, 0x00000066},
514 { 0x1c58b0, 0x0000001c, 0x0000001c},
515 { 0x1c58b0, 0x00000000, 0x00000000},
516 { 0x1c58b0, 0x00000004, 0x00000004},
517 { 0x1c58b0, 0x00000015, 0x00000015},
518 { 0x1c58b0, 0x0000001f, 0x0000001f},
519 { 0x1c58e0, 0x00000000, 0x00000400},
520 /* bank 7 */
521 { 0x1c58b0, 0x000000a0, 0x000000a0},
522 { 0x1c58b0, 0x00000000, 0x00000000},
523 { 0x1c58b0, 0x00000040, 0x00000040},
524 { 0x1c58f0, 0x0000001c, 0x0000001c},
525};
526
527static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
528{
529 int err, i;
530
531 ar9170_regwrite_begin(ar);
532
533 for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
534 ar9170_regwrite(ar9170_rf_init[i].reg,
535 band5ghz ? ar9170_rf_init[i]._5ghz
536 : ar9170_rf_init[i]._2ghz);
537
538 ar9170_regwrite_finish();
539 err = ar9170_regwrite_result();
540 if (err)
541 printk(KERN_ERR "%s: rf init failed\n",
542 wiphy_name(ar->hw->wiphy));
543 return err;
544}
545
546static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
547 u32 freq, enum ar9170_bw bw)
548{
549 int err;
550 u32 d0, d1, td0, td1, fd0, fd1;
551 u8 chansel;
552 u8 refsel0 = 1, refsel1 = 0;
553 u8 lf_synth = 0;
554
555 switch (bw) {
556 case AR9170_BW_40_ABOVE:
557 freq += 10;
558 break;
559 case AR9170_BW_40_BELOW:
560 freq -= 10;
561 break;
562 case AR9170_BW_20:
563 break;
564 case __AR9170_NUM_BW:
565 BUG();
566 }
567
568 if (band5ghz) {
569 if (freq % 10) {
570 chansel = (freq - 4800) / 5;
571 } else {
572 chansel = ((freq - 4800) / 10) * 2;
573 refsel0 = 0;
574 refsel1 = 1;
575 }
576 chansel = byte_rev_table[chansel];
577 } else {
578 if (freq == 2484) {
579 chansel = 10 + (freq - 2274) / 5;
580 lf_synth = 1;
581 } else
582 chansel = 16 + (freq - 2272) / 5;
583 chansel *= 4;
584 chansel = byte_rev_table[chansel];
585 }
586
587 d1 = chansel;
588 d0 = 0x21 |
589 refsel0 << 3 |
590 refsel1 << 2 |
591 lf_synth << 1;
592 td0 = d0 & 0x1f;
593 td1 = d1 & 0x1f;
594 fd0 = td1 << 5 | td0;
595
596 td0 = (d0 >> 5) & 0x7;
597 td1 = (d1 >> 5) & 0x7;
598 fd1 = td1 << 5 | td0;
599
600 ar9170_regwrite_begin(ar);
601
602 ar9170_regwrite(0x1c58b0, fd0);
603 ar9170_regwrite(0x1c58e8, fd1);
604
605 ar9170_regwrite_finish();
606 err = ar9170_regwrite_result();
607 if (err)
608 return err;
609
610 msleep(10);
611
612 return 0;
613}
614
615struct ar9170_phy_freq_params {
616 u8 coeff_exp;
617 u16 coeff_man;
618 u8 coeff_exp_shgi;
619 u16 coeff_man_shgi;
620};
621
622struct ar9170_phy_freq_entry {
623 u16 freq;
624 struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
625};
626
627/* NB: must be in sync with channel tables in main! */
628static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
629/*
630 * freq,
631 * 20MHz,
632 * 40MHz (below),
633 * 40Mhz (above),
634 */
635 { 2412, {
636 { 3, 21737, 3, 19563, },
637 { 3, 21827, 3, 19644, },
638 { 3, 21647, 3, 19482, },
639 } },
640 { 2417, {
641 { 3, 21692, 3, 19523, },
642 { 3, 21782, 3, 19604, },
643 { 3, 21602, 3, 19442, },
644 } },
645 { 2422, {
646 { 3, 21647, 3, 19482, },
647 { 3, 21737, 3, 19563, },
648 { 3, 21558, 3, 19402, },
649 } },
650 { 2427, {
651 { 3, 21602, 3, 19442, },
652 { 3, 21692, 3, 19523, },
653 { 3, 21514, 3, 19362, },
654 } },
655 { 2432, {
656 { 3, 21558, 3, 19402, },
657 { 3, 21647, 3, 19482, },
658 { 3, 21470, 3, 19323, },
659 } },
660 { 2437, {
661 { 3, 21514, 3, 19362, },
662 { 3, 21602, 3, 19442, },
663 { 3, 21426, 3, 19283, },
664 } },
665 { 2442, {
666 { 3, 21470, 3, 19323, },
667 { 3, 21558, 3, 19402, },
668 { 3, 21382, 3, 19244, },
669 } },
670 { 2447, {
671 { 3, 21426, 3, 19283, },
672 { 3, 21514, 3, 19362, },
673 { 3, 21339, 3, 19205, },
674 } },
675 { 2452, {
676 { 3, 21382, 3, 19244, },
677 { 3, 21470, 3, 19323, },
678 { 3, 21295, 3, 19166, },
679 } },
680 { 2457, {
681 { 3, 21339, 3, 19205, },
682 { 3, 21426, 3, 19283, },
683 { 3, 21252, 3, 19127, },
684 } },
685 { 2462, {
686 { 3, 21295, 3, 19166, },
687 { 3, 21382, 3, 19244, },
688 { 3, 21209, 3, 19088, },
689 } },
690 { 2467, {
691 { 3, 21252, 3, 19127, },
692 { 3, 21339, 3, 19205, },
693 { 3, 21166, 3, 19050, },
694 } },
695 { 2472, {
696 { 3, 21209, 3, 19088, },
697 { 3, 21295, 3, 19166, },
698 { 3, 21124, 3, 19011, },
699 } },
700 { 2484, {
701 { 3, 21107, 3, 18996, },
702 { 3, 21192, 3, 19073, },
703 { 3, 21022, 3, 18920, },
704 } },
705 { 4920, {
706 { 4, 21313, 4, 19181, },
707 { 4, 21356, 4, 19220, },
708 { 4, 21269, 4, 19142, },
709 } },
710 { 4940, {
711 { 4, 21226, 4, 19104, },
712 { 4, 21269, 4, 19142, },
713 { 4, 21183, 4, 19065, },
714 } },
715 { 4960, {
716 { 4, 21141, 4, 19027, },
717 { 4, 21183, 4, 19065, },
718 { 4, 21098, 4, 18988, },
719 } },
720 { 4980, {
721 { 4, 21056, 4, 18950, },
722 { 4, 21098, 4, 18988, },
723 { 4, 21014, 4, 18912, },
724 } },
725 { 5040, {
726 { 4, 20805, 4, 18725, },
727 { 4, 20846, 4, 18762, },
728 { 4, 20764, 4, 18687, },
729 } },
730 { 5060, {
731 { 4, 20723, 4, 18651, },
732 { 4, 20764, 4, 18687, },
733 { 4, 20682, 4, 18614, },
734 } },
735 { 5080, {
736 { 4, 20641, 4, 18577, },
737 { 4, 20682, 4, 18614, },
738 { 4, 20601, 4, 18541, },
739 } },
740 { 5180, {
741 { 4, 20243, 4, 18219, },
742 { 4, 20282, 4, 18254, },
743 { 4, 20204, 4, 18183, },
744 } },
745 { 5200, {
746 { 4, 20165, 4, 18148, },
747 { 4, 20204, 4, 18183, },
748 { 4, 20126, 4, 18114, },
749 } },
750 { 5220, {
751 { 4, 20088, 4, 18079, },
752 { 4, 20126, 4, 18114, },
753 { 4, 20049, 4, 18044, },
754 } },
755 { 5240, {
756 { 4, 20011, 4, 18010, },
757 { 4, 20049, 4, 18044, },
758 { 4, 19973, 4, 17976, },
759 } },
760 { 5260, {
761 { 4, 19935, 4, 17941, },
762 { 4, 19973, 4, 17976, },
763 { 4, 19897, 4, 17907, },
764 } },
765 { 5280, {
766 { 4, 19859, 4, 17873, },
767 { 4, 19897, 4, 17907, },
768 { 4, 19822, 4, 17840, },
769 } },
770 { 5300, {
771 { 4, 19784, 4, 17806, },
772 { 4, 19822, 4, 17840, },
773 { 4, 19747, 4, 17772, },
774 } },
775 { 5320, {
776 { 4, 19710, 4, 17739, },
777 { 4, 19747, 4, 17772, },
778 { 4, 19673, 4, 17706, },
779 } },
780 { 5500, {
781 { 4, 19065, 4, 17159, },
782 { 4, 19100, 4, 17190, },
783 { 4, 19030, 4, 17127, },
784 } },
785 { 5520, {
786 { 4, 18996, 4, 17096, },
787 { 4, 19030, 4, 17127, },
788 { 4, 18962, 4, 17065, },
789 } },
790 { 5540, {
791 { 4, 18927, 4, 17035, },
792 { 4, 18962, 4, 17065, },
793 { 4, 18893, 4, 17004, },
794 } },
795 { 5560, {
796 { 4, 18859, 4, 16973, },
797 { 4, 18893, 4, 17004, },
798 { 4, 18825, 4, 16943, },
799 } },
800 { 5580, {
801 { 4, 18792, 4, 16913, },
802 { 4, 18825, 4, 16943, },
803 { 4, 18758, 4, 16882, },
804 } },
805 { 5600, {
806 { 4, 18725, 4, 16852, },
807 { 4, 18758, 4, 16882, },
808 { 4, 18691, 4, 16822, },
809 } },
810 { 5620, {
811 { 4, 18658, 4, 16792, },
812 { 4, 18691, 4, 16822, },
813 { 4, 18625, 4, 16762, },
814 } },
815 { 5640, {
816 { 4, 18592, 4, 16733, },
817 { 4, 18625, 4, 16762, },
818 { 4, 18559, 4, 16703, },
819 } },
820 { 5660, {
821 { 4, 18526, 4, 16673, },
822 { 4, 18559, 4, 16703, },
823 { 4, 18493, 4, 16644, },
824 } },
825 { 5680, {
826 { 4, 18461, 4, 16615, },
827 { 4, 18493, 4, 16644, },
828 { 4, 18428, 4, 16586, },
829 } },
830 { 5700, {
831 { 4, 18396, 4, 16556, },
832 { 4, 18428, 4, 16586, },
833 { 4, 18364, 4, 16527, },
834 } },
835 { 5745, {
836 { 4, 18252, 4, 16427, },
837 { 4, 18284, 4, 16455, },
838 { 4, 18220, 4, 16398, },
839 } },
840 { 5765, {
841 { 4, 18189, 5, 32740, },
842 { 4, 18220, 4, 16398, },
843 { 4, 18157, 5, 32683, },
844 } },
845 { 5785, {
846 { 4, 18126, 5, 32626, },
847 { 4, 18157, 5, 32683, },
848 { 4, 18094, 5, 32570, },
849 } },
850 { 5805, {
851 { 4, 18063, 5, 32514, },
852 { 4, 18094, 5, 32570, },
853 { 4, 18032, 5, 32458, },
854 } },
855 { 5825, {
856 { 4, 18001, 5, 32402, },
857 { 4, 18032, 5, 32458, },
858 { 4, 17970, 5, 32347, },
859 } },
860 { 5170, {
861 { 4, 20282, 4, 18254, },
862 { 4, 20321, 4, 18289, },
863 { 4, 20243, 4, 18219, },
864 } },
865 { 5190, {
866 { 4, 20204, 4, 18183, },
867 { 4, 20243, 4, 18219, },
868 { 4, 20165, 4, 18148, },
869 } },
870 { 5210, {
871 { 4, 20126, 4, 18114, },
872 { 4, 20165, 4, 18148, },
873 { 4, 20088, 4, 18079, },
874 } },
875 { 5230, {
876 { 4, 20049, 4, 18044, },
877 { 4, 20088, 4, 18079, },
878 { 4, 20011, 4, 18010, },
879 } },
880};
881
882static const struct ar9170_phy_freq_params *
883ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
884 enum ar9170_bw bw)
885{
886 unsigned int chanidx = 0;
887 u16 freq = 2412;
888
889 if (channel) {
890 chanidx = channel->hw_value;
891 freq = channel->center_freq;
892 }
893
894 BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
895
896 BUILD_BUG_ON(__AR9170_NUM_BW != 3);
897
898 WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
899
900 return &ar9170_phy_freq_params[chanidx].params[bw];
901}
902
903
904int ar9170_init_rf(struct ar9170 *ar)
905{
906 const struct ar9170_phy_freq_params *freqpar;
907 __le32 cmd[7];
908 int err;
909
910 err = ar9170_init_rf_banks_0_7(ar, false);
911 if (err)
912 return err;
913
914 err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
915 if (err)
916 return err;
917
918 freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
919
920 cmd[0] = cpu_to_le32(2412 * 1000);
921 cmd[1] = cpu_to_le32(0);
922 cmd[2] = cpu_to_le32(1);
923 cmd[3] = cpu_to_le32(freqpar->coeff_exp);
924 cmd[4] = cpu_to_le32(freqpar->coeff_man);
925 cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
926 cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
927
928 /* RF_INIT echoes the command back to us */
929 err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
930 sizeof(cmd), (u8 *)cmd,
931 sizeof(cmd), (u8 *)cmd);
932 if (err)
933 return err;
934
935 msleep(1000);
936
937 return ar9170_echo_test(ar, 0xaabbccdd);
938}
939
940static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
941{
942 int idx = nfreqs - 2;
943
944 while (idx >= 0) {
945 if (f >= freqs[idx])
946 return idx;
947 idx--;
948 }
949
950 return 0;
951}
952
953static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
954{
955 /* nothing to interpolate, it's horizontal */
956 if (y2 == y1)
957 return y1;
958
959 /* check if we hit one of the edges */
960 if (x == x1)
961 return y1;
962 if (x == x2)
963 return y2;
964
965 /* x1 == x2 is bad, hopefully == x */
966 if (x2 == x1)
967 return y1;
968
969 return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
970}
971
972static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
973{
974#define SHIFT 8
975 s32 y;
976
977 y = ar9170_interpolate_s32(x << SHIFT,
978 x1 << SHIFT, y1 << SHIFT,
979 x2 << SHIFT, y2 << SHIFT);
980
981 /*
982 * XXX: unwrap this expression
983 * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
984 * Can we rely on the compiler to optimise away the div?
985 */
986 return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
987#undef SHIFT
988}
989
990static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
991{
992 struct ar9170_calibration_target_power_legacy *ctpl;
993 struct ar9170_calibration_target_power_ht *ctph;
994 u8 *ctpres;
995 int ntargets;
996 int idx, i, n;
997 u8 ackpower, ackchains, f;
998 u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
999
1000 if (freq < 3000)
1001 f = freq - 2300;
1002 else
1003 f = (freq - 4800)/5;
1004
1005 /*
1006 * cycle through the various modes
1007 *
1008 * legacy modes first: 5G, 2G CCK, 2G OFDM
1009 */
1010 for (i = 0; i < 3; i++) {
1011 switch (i) {
1012 case 0: /* 5 GHz legacy */
1013 ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
1014 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1015 ctpres = ar->power_5G_leg;
1016 break;
1017 case 1: /* 2.4 GHz CCK */
1018 ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
1019 ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
1020 ctpres = ar->power_2G_cck;
1021 break;
1022 case 2: /* 2.4 GHz OFDM */
1023 ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
1024 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1025 ctpres = ar->power_2G_ofdm;
1026 break;
1027 default:
1028 BUG();
1029 }
1030
1031 for (n = 0; n < ntargets; n++) {
1032 if (ctpl[n].freq == 0xff)
1033 break;
1034 pwr_freqs[n] = ctpl[n].freq;
1035 }
1036 ntargets = n;
1037 idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
1038 for (n = 0; n < 4; n++)
1039 ctpres[n] = ar9170_interpolate_u8(
1040 f,
1041 ctpl[idx + 0].freq,
1042 ctpl[idx + 0].power[n],
1043 ctpl[idx + 1].freq,
1044 ctpl[idx + 1].power[n]);
1045 }
1046
1047 /*
1048 * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
1049 */
1050 for (i = 0; i < 4; i++) {
1051 switch (i) {
1052 case 0: /* 5 GHz HT 20 */
1053 ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
1054 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1055 ctpres = ar->power_5G_ht20;
1056 break;
1057 case 1: /* 5 GHz HT 40 */
1058 ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
1059 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1060 ctpres = ar->power_5G_ht40;
1061 break;
1062 case 2: /* 2.4 GHz HT 20 */
1063 ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
1064 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1065 ctpres = ar->power_2G_ht20;
1066 break;
1067 case 3: /* 2.4 GHz HT 40 */
1068 ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
1069 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1070 ctpres = ar->power_2G_ht40;
1071 break;
1072 default:
1073 BUG();
1074 }
1075
1076 for (n = 0; n < ntargets; n++) {
1077 if (ctph[n].freq == 0xff)
1078 break;
1079 pwr_freqs[n] = ctph[n].freq;
1080 }
1081 ntargets = n;
1082 idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
1083 for (n = 0; n < 8; n++)
1084 ctpres[n] = ar9170_interpolate_u8(
1085 f,
1086 ctph[idx + 0].freq,
1087 ctph[idx + 0].power[n],
1088 ctph[idx + 1].freq,
1089 ctph[idx + 1].power[n]);
1090 }
1091
1092 /* set ACK/CTS TX power */
1093 ar9170_regwrite_begin(ar);
1094
1095 if (ar->eeprom.tx_mask != 1)
1096 ackchains = AR9170_TX_PHY_TXCHAIN_2;
1097 else
1098 ackchains = AR9170_TX_PHY_TXCHAIN_1;
1099
1100 if (freq < 3000)
1101 ackpower = ar->power_2G_ofdm[0] & 0x3f;
1102 else
1103 ackpower = ar->power_5G_leg[0] & 0x3f;
1104
1105 ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
1106 ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
1107 ackpower << 21 | ackchains << 27);
1108
1109 ar9170_regwrite_finish();
1110 return ar9170_regwrite_result();
1111}
1112
1113static int ar9170_calc_noise_dbm(u32 raw_noise)
1114{
1115 if (raw_noise & 0x100)
1116 return ~((raw_noise & 0x0ff) >> 1);
1117 else
1118 return (raw_noise & 0xff) >> 1;
1119}
1120
1121int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1122 enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
1123{
1124 const struct ar9170_phy_freq_params *freqpar;
1125 u32 cmd, tmp, offs;
1126 __le32 vals[8];
1127 int i, err;
1128 bool bandswitch;
1129
1130 /* clear BB heavy clip enable */
1131 err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
1132 if (err)
1133 return err;
1134
1135 /* may be NULL at first setup */
1136 if (ar->channel)
1137 bandswitch = ar->channel->band != channel->band;
1138 else
1139 bandswitch = true;
1140
1141 /* HW workaround */
1142 if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
1143 channel->center_freq <= 2417)
1144 bandswitch = true;
1145
1146 err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
1147 if (err)
1148 return err;
1149
1150 if (rfi != AR9170_RFI_NONE || bandswitch) {
1151 u32 val = 0x400;
1152
1153 if (rfi == AR9170_RFI_COLD)
1154 val = 0x800;
1155
1156 /* warm/cold reset BB/ADDA */
1157 err = ar9170_write_reg(ar, 0x1d4004, val);
1158 if (err)
1159 return err;
1160
1161 err = ar9170_write_reg(ar, 0x1d4004, 0x0);
1162 if (err)
1163 return err;
1164
1165 err = ar9170_init_phy(ar, channel->band);
1166 if (err)
1167 return err;
1168
1169 err = ar9170_init_rf_banks_0_7(ar,
1170 channel->band == IEEE80211_BAND_5GHZ);
1171 if (err)
1172 return err;
1173
1174 cmd = AR9170_CMD_RF_INIT;
1175 } else {
1176 cmd = AR9170_CMD_FREQUENCY;
1177 }
1178
1179 err = ar9170_init_rf_bank4_pwr(ar,
1180 channel->band == IEEE80211_BAND_5GHZ,
1181 channel->center_freq, bw);
1182 if (err)
1183 return err;
1184
1185 switch (bw) {
1186 case AR9170_BW_20:
1187 tmp = 0x240;
1188 offs = 0;
1189 break;
1190 case AR9170_BW_40_BELOW:
1191 tmp = 0x2c4;
1192 offs = 3;
1193 break;
1194 case AR9170_BW_40_ABOVE:
1195 tmp = 0x2d4;
1196 offs = 1;
1197 break;
1198 default:
1199 BUG();
1200 return -ENOSYS;
1201 }
1202
1203 if (0 /* 2 streams capable */)
1204 tmp |= 0x100;
1205
1206 err = ar9170_write_reg(ar, 0x1c5804, tmp);
1207 if (err)
1208 return err;
1209
1210 err = ar9170_set_power_cal(ar, channel->center_freq, bw);
1211 if (err)
1212 return err;
1213
1214 freqpar = ar9170_get_hw_dyn_params(channel, bw);
1215
1216 vals[0] = cpu_to_le32(channel->center_freq * 1000);
1217 vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1);
1218 vals[2] = cpu_to_le32(offs << 2 | 1);
1219 vals[3] = cpu_to_le32(freqpar->coeff_exp);
1220 vals[4] = cpu_to_le32(freqpar->coeff_man);
1221 vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
1222 vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
1223 vals[7] = cpu_to_le32(1000);
1224
1225 err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
1226 sizeof(vals), (u8 *)vals);
1227 if (err)
1228 return err;
1229
1230 for (i = 0; i < 2; i++) {
1231 ar->noise[i] = ar9170_calc_noise_dbm(
1232 (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
1233
1234 ar->noise[i + 2] = ar9170_calc_noise_dbm(
1235 (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
1236 }
1237
1238 ar->channel = channel;
1239 return 0;
1240}
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c
new file mode 100644
index 000000000000..ad296840893e
--- /dev/null
+++ b/drivers/net/wireless/ar9170/usb.c
@@ -0,0 +1,748 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * USB - frontend
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2009, Christian Lamparter <chunkeey@web.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU 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; see the file COPYING. If not, see
21 * http://www.gnu.org/licenses/.
22 *
23 * This file incorporates work covered by the following copyright and
24 * permission notice:
25 * Copyright (c) 2007-2008 Atheros Communications, Inc.
26 *
27 * Permission to use, copy, modify, and/or distribute this software for any
28 * purpose with or without fee is hereby granted, provided that the above
29 * copyright notice and this permission notice appear in all copies.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */
39
40#include <linux/module.h>
41#include <linux/usb.h>
42#include <linux/firmware.h>
43#include <linux/etherdevice.h>
44#include <net/mac80211.h>
45#include "ar9170.h"
46#include "cmd.h"
47#include "hw.h"
48#include "usb.h"
49
50MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
51MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
52MODULE_LICENSE("GPL");
53MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
54MODULE_FIRMWARE("ar9170-1.fw");
55MODULE_FIRMWARE("ar9170-2.fw");
56
57static struct usb_device_id ar9170_usb_ids[] = {
58 /* Atheros 9170 */
59 { USB_DEVICE(0x0cf3, 0x9170) },
60 /* Atheros TG121N */
61 { USB_DEVICE(0x0cf3, 0x1001) },
62 /* D-Link DWA 160A */
63 { USB_DEVICE(0x07d1, 0x3c10) },
64 /* Netgear WNDA3100 */
65 { USB_DEVICE(0x0846, 0x9010) },
66 /* Netgear WN111 v2 */
67 { USB_DEVICE(0x0846, 0x9001) },
68 /* Zydas ZD1221 */
69 { USB_DEVICE(0x0ace, 0x1221) },
70 /* Z-Com UB81 BG */
71 { USB_DEVICE(0x0cde, 0x0023) },
72 /* Z-Com UB82 ABG */
73 { USB_DEVICE(0x0cde, 0x0026) },
74 /* Arcadyan WN7512 */
75 { USB_DEVICE(0x083a, 0xf522) },
76 /* Planex GWUS300 */
77 { USB_DEVICE(0x2019, 0x5304) },
78 /* IO-Data WNGDNUS2 */
79 { USB_DEVICE(0x04bb, 0x093f) },
80
81 /* terminate */
82 {}
83};
84MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
85
86static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
87{
88 struct sk_buff *skb = urb->context;
89 struct ar9170_usb *aru = (struct ar9170_usb *)
90 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
91
92 if (!aru) {
93 dev_kfree_skb_irq(skb);
94 return ;
95 }
96
97 ar9170_handle_tx_status(&aru->common, skb, false,
98 AR9170_TX_STATUS_COMPLETE);
99}
100
101static void ar9170_usb_tx_urb_complete(struct urb *urb)
102{
103}
104
105static void ar9170_usb_irq_completed(struct urb *urb)
106{
107 struct ar9170_usb *aru = urb->context;
108
109 switch (urb->status) {
110 /* everything is fine */
111 case 0:
112 break;
113
114 /* disconnect */
115 case -ENOENT:
116 case -ECONNRESET:
117 case -ENODEV:
118 case -ESHUTDOWN:
119 goto free;
120
121 default:
122 goto resubmit;
123 }
124
125 print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
126 urb->transfer_buffer, urb->actual_length);
127
128resubmit:
129 usb_anchor_urb(urb, &aru->rx_submitted);
130 if (usb_submit_urb(urb, GFP_ATOMIC)) {
131 usb_unanchor_urb(urb);
132 goto free;
133 }
134
135 return;
136
137free:
138 usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
139}
140
141static void ar9170_usb_rx_completed(struct urb *urb)
142{
143 struct sk_buff *skb = urb->context;
144 struct ar9170_usb *aru = (struct ar9170_usb *)
145 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
146 int err;
147
148 if (!aru)
149 goto free;
150
151 switch (urb->status) {
152 /* everything is fine */
153 case 0:
154 break;
155
156 /* disconnect */
157 case -ENOENT:
158 case -ECONNRESET:
159 case -ENODEV:
160 case -ESHUTDOWN:
161 goto free;
162
163 default:
164 goto resubmit;
165 }
166
167 skb_put(skb, urb->actual_length);
168 ar9170_rx(&aru->common, skb);
169
170resubmit:
171 skb_reset_tail_pointer(skb);
172 skb_trim(skb, 0);
173
174 usb_anchor_urb(urb, &aru->rx_submitted);
175 err = usb_submit_urb(urb, GFP_ATOMIC);
176 if (err) {
177 usb_unanchor_urb(urb);
178 dev_kfree_skb_irq(skb);
179 }
180
181 return ;
182
183free:
184 dev_kfree_skb_irq(skb);
185 return;
186}
187
188static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
189 struct urb *urb, gfp_t gfp)
190{
191 struct sk_buff *skb;
192
193 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
194 if (!skb)
195 return -ENOMEM;
196
197 /* reserve some space for mac80211's radiotap */
198 skb_reserve(skb, 32);
199
200 usb_fill_bulk_urb(urb, aru->udev,
201 usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
202 skb->data, min(skb_tailroom(skb),
203 AR9170_MAX_RX_BUFFER_SIZE),
204 ar9170_usb_rx_completed, skb);
205
206 return 0;
207}
208
209static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
210{
211 struct urb *urb = NULL;
212 void *ibuf;
213 int err = -ENOMEM;
214
215 /* initialize interrupt endpoint */
216 urb = usb_alloc_urb(0, GFP_KERNEL);
217 if (!urb)
218 goto out;
219
220 ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
221 if (!ibuf)
222 goto out;
223
224 usb_fill_int_urb(urb, aru->udev,
225 usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
226 64, ar9170_usb_irq_completed, aru, 1);
227 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
228
229 usb_anchor_urb(urb, &aru->rx_submitted);
230 err = usb_submit_urb(urb, GFP_KERNEL);
231 if (err) {
232 usb_unanchor_urb(urb);
233 usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
234 urb->transfer_dma);
235 }
236
237out:
238 usb_free_urb(urb);
239 return err;
240}
241
242static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
243{
244 struct urb *urb;
245 int i;
246 int err = -EINVAL;
247
248 for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
249 err = -ENOMEM;
250 urb = usb_alloc_urb(0, GFP_KERNEL);
251 if (!urb)
252 goto err_out;
253
254 err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
255 if (err) {
256 usb_free_urb(urb);
257 goto err_out;
258 }
259
260 usb_anchor_urb(urb, &aru->rx_submitted);
261 err = usb_submit_urb(urb, GFP_KERNEL);
262 if (err) {
263 usb_unanchor_urb(urb);
264 dev_kfree_skb_any((void *) urb->transfer_buffer);
265 usb_free_urb(urb);
266 goto err_out;
267 }
268 usb_free_urb(urb);
269 }
270
271 /* the device now waiting for a firmware. */
272 aru->common.state = AR9170_IDLE;
273 return 0;
274
275err_out:
276
277 usb_kill_anchored_urbs(&aru->rx_submitted);
278 return err;
279}
280
281static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
282{
283 int ret;
284
285 aru->common.state = AR9170_UNKNOWN_STATE;
286
287 usb_unlink_anchored_urbs(&aru->tx_submitted);
288
289 /* give the LED OFF command and the deauth frame a chance to air. */
290 ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
291 msecs_to_jiffies(100));
292 if (ret == 0)
293 dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
294 usb_poison_anchored_urbs(&aru->tx_submitted);
295
296 usb_poison_anchored_urbs(&aru->rx_submitted);
297}
298
299static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
300 unsigned int plen, void *payload,
301 unsigned int outlen, void *out)
302{
303 struct ar9170_usb *aru = (void *) ar;
304 struct urb *urb = NULL;
305 unsigned long flags;
306 int err = -ENOMEM;
307
308 if (unlikely(!IS_ACCEPTING_CMD(ar)))
309 return -EPERM;
310
311 if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
312 return -EINVAL;
313
314 urb = usb_alloc_urb(0, GFP_ATOMIC);
315 if (unlikely(!urb))
316 goto err_free;
317
318 ar->cmdbuf[0] = cpu_to_le32(plen);
319 ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
320 /* writing multiple regs fills this buffer already */
321 if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
322 memcpy(&ar->cmdbuf[1], payload, plen);
323
324 spin_lock_irqsave(&aru->common.cmdlock, flags);
325 aru->readbuf = (u8 *)out;
326 aru->readlen = outlen;
327 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
328
329 usb_fill_int_urb(urb, aru->udev,
330 usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
331 aru->common.cmdbuf, plen + 4,
332 ar9170_usb_tx_urb_complete, NULL, 1);
333
334 usb_anchor_urb(urb, &aru->tx_submitted);
335 err = usb_submit_urb(urb, GFP_ATOMIC);
336 if (err) {
337 usb_unanchor_urb(urb);
338 usb_free_urb(urb);
339 goto err_unbuf;
340 }
341 usb_free_urb(urb);
342
343 err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
344 if (err == 0) {
345 err = -ETIMEDOUT;
346 goto err_unbuf;
347 }
348
349 if (outlen >= 0 && aru->readlen != outlen) {
350 err = -EMSGSIZE;
351 goto err_unbuf;
352 }
353
354 return 0;
355
356err_unbuf:
357 /* Maybe the device was removed in the second we were waiting? */
358 if (IS_STARTED(ar)) {
359 dev_err(&aru->udev->dev, "no command feedback "
360 "received (%d).\n", err);
361
362 /* provide some maybe useful debug information */
363 print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
364 aru->common.cmdbuf, plen + 4);
365 dump_stack();
366 }
367
368 /* invalidate to avoid completing the next prematurely */
369 spin_lock_irqsave(&aru->common.cmdlock, flags);
370 aru->readbuf = NULL;
371 aru->readlen = 0;
372 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
373
374err_free:
375
376 return err;
377}
378
379static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
380 bool txstatus_needed, unsigned int extra_len)
381{
382 struct ar9170_usb *aru = (struct ar9170_usb *) ar;
383 struct urb *urb;
384 int err;
385
386 if (unlikely(!IS_STARTED(ar))) {
387 /* Seriously, what were you drink... err... thinking!? */
388 return -EPERM;
389 }
390
391 urb = usb_alloc_urb(0, GFP_ATOMIC);
392 if (unlikely(!urb))
393 return -ENOMEM;
394
395 usb_fill_bulk_urb(urb, aru->udev,
396 usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
397 skb->data, skb->len + extra_len, (txstatus_needed ?
398 ar9170_usb_tx_urb_complete :
399 ar9170_usb_tx_urb_complete_free), skb);
400 urb->transfer_flags |= URB_ZERO_PACKET;
401
402 usb_anchor_urb(urb, &aru->tx_submitted);
403 err = usb_submit_urb(urb, GFP_ATOMIC);
404 if (unlikely(err))
405 usb_unanchor_urb(urb);
406
407 usb_free_urb(urb);
408 return err;
409}
410
411static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
412{
413 struct ar9170_usb *aru = (void *) ar;
414 unsigned long flags;
415 u32 in, out;
416
417 if (!buffer)
418 return ;
419
420 in = le32_to_cpup((__le32 *)buffer);
421 out = le32_to_cpu(ar->cmdbuf[0]);
422
423 /* mask off length byte */
424 out &= ~0xFF;
425
426 if (aru->readlen >= 0) {
427 /* add expected length */
428 out |= aru->readlen;
429 } else {
430 /* add obtained length */
431 out |= in & 0xFF;
432 }
433
434 /*
435 * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
436 * length and we cannot predict the correct length in advance.
437 * So we only check if we provided enough space for the data.
438 */
439 if (unlikely(out < in)) {
440 dev_warn(&aru->udev->dev, "received invalid command response "
441 "got %d bytes, instead of %d bytes "
442 "and the resp length is %d bytes\n",
443 in, out, len);
444 print_hex_dump_bytes("ar9170 invalid resp: ",
445 DUMP_PREFIX_OFFSET, buffer, len);
446 /*
447 * Do not complete, then the command times out,
448 * and we get a stack trace from there.
449 */
450 return ;
451 }
452
453 spin_lock_irqsave(&aru->common.cmdlock, flags);
454 if (aru->readbuf && len > 0) {
455 memcpy(aru->readbuf, buffer + 4, len - 4);
456 aru->readbuf = NULL;
457 }
458 complete(&aru->cmd_wait);
459 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
460}
461
462static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
463 size_t len, u32 addr, bool complete)
464{
465 int transfer, err;
466 u8 *buf = kmalloc(4096, GFP_KERNEL);
467
468 if (!buf)
469 return -ENOMEM;
470
471 while (len) {
472 transfer = min_t(int, len, 4096);
473 memcpy(buf, data, transfer);
474
475 err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
476 0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
477 addr >> 8, 0, buf, transfer, 1000);
478
479 if (err < 0) {
480 kfree(buf);
481 return err;
482 }
483
484 len -= transfer;
485 data += transfer;
486 addr += transfer;
487 }
488 kfree(buf);
489
490 if (complete) {
491 err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
492 0x31 /* FW DL COMPLETE */,
493 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
494 }
495
496 return 0;
497}
498
499static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
500{
501 int err = 0;
502
503 err = request_firmware(&aru->init_values, "ar9170-1.fw",
504 &aru->udev->dev);
505 if (err) {
506 dev_err(&aru->udev->dev, "file with init values not found.\n");
507 return err;
508 }
509
510 err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
511 if (err) {
512 release_firmware(aru->init_values);
513 dev_err(&aru->udev->dev, "firmware file not found.\n");
514 return err;
515 }
516
517 return err;
518}
519
520static int ar9170_usb_reset(struct ar9170_usb *aru)
521{
522 int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
523
524 if (lock) {
525 ret = usb_lock_device_for_reset(aru->udev, aru->intf);
526 if (ret < 0) {
527 dev_err(&aru->udev->dev, "unable to lock device "
528 "for reset (%d).\n", ret);
529 return ret;
530 }
531 }
532
533 ret = usb_reset_device(aru->udev);
534 if (lock)
535 usb_unlock_device(aru->udev);
536
537 /* let it rest - for a second - */
538 msleep(1000);
539
540 return ret;
541}
542
543static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
544{
545 int err;
546
547 /* First, upload initial values to device RAM */
548 err = ar9170_usb_upload(aru, aru->init_values->data,
549 aru->init_values->size, 0x102800, false);
550 if (err) {
551 dev_err(&aru->udev->dev, "firmware part 1 "
552 "upload failed (%d).\n", err);
553 return err;
554 }
555
556 /* Then, upload the firmware itself and start it */
557 return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
558 0x200000, true);
559}
560
561static int ar9170_usb_init_transport(struct ar9170_usb *aru)
562{
563 struct ar9170 *ar = (void *) &aru->common;
564 int err;
565
566 ar9170_regwrite_begin(ar);
567
568 /* Set USB Rx stream mode MAX packet number to 2 */
569 ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
570
571 /* Set USB Rx stream mode timeout to 10us */
572 ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
573
574 ar9170_regwrite_finish();
575
576 err = ar9170_regwrite_result();
577 if (err)
578 dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
579
580 return err;
581}
582
583static void ar9170_usb_stop(struct ar9170 *ar)
584{
585 struct ar9170_usb *aru = (void *) ar;
586 int ret;
587
588 if (IS_ACCEPTING_CMD(ar))
589 aru->common.state = AR9170_STOPPED;
590
591 /* lets wait a while until the tx - queues are dried out */
592 ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
593 msecs_to_jiffies(1000));
594 if (ret == 0)
595 dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
596
597 usb_poison_anchored_urbs(&aru->tx_submitted);
598
599 /*
600 * Note:
601 * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
602 * Else we would end up with a unresponsive device...
603 */
604}
605
606static int ar9170_usb_open(struct ar9170 *ar)
607{
608 struct ar9170_usb *aru = (void *) ar;
609 int err;
610
611 usb_unpoison_anchored_urbs(&aru->tx_submitted);
612 err = ar9170_usb_init_transport(aru);
613 if (err) {
614 usb_poison_anchored_urbs(&aru->tx_submitted);
615 return err;
616 }
617
618 aru->common.state = AR9170_IDLE;
619 return 0;
620}
621
622static int ar9170_usb_probe(struct usb_interface *intf,
623 const struct usb_device_id *id)
624{
625 struct ar9170_usb *aru;
626 struct ar9170 *ar;
627 struct usb_device *udev;
628 int err;
629
630 aru = ar9170_alloc(sizeof(*aru));
631 if (IS_ERR(aru)) {
632 err = PTR_ERR(aru);
633 goto out;
634 }
635
636 udev = interface_to_usbdev(intf);
637 usb_get_dev(udev);
638 aru->udev = udev;
639 aru->intf = intf;
640 ar = &aru->common;
641
642 usb_set_intfdata(intf, aru);
643 SET_IEEE80211_DEV(ar->hw, &udev->dev);
644
645 init_usb_anchor(&aru->rx_submitted);
646 init_usb_anchor(&aru->tx_submitted);
647 init_completion(&aru->cmd_wait);
648
649 aru->common.stop = ar9170_usb_stop;
650 aru->common.open = ar9170_usb_open;
651 aru->common.tx = ar9170_usb_tx;
652 aru->common.exec_cmd = ar9170_usb_exec_cmd;
653 aru->common.callback_cmd = ar9170_usb_callback_cmd;
654
655 err = ar9170_usb_reset(aru);
656 if (err)
657 goto err_unlock;
658
659 err = ar9170_usb_request_firmware(aru);
660 if (err)
661 goto err_unlock;
662
663 err = ar9170_usb_alloc_rx_irq_urb(aru);
664 if (err)
665 goto err_freefw;
666
667 err = ar9170_usb_alloc_rx_bulk_urbs(aru);
668 if (err)
669 goto err_unrx;
670
671 err = ar9170_usb_upload_firmware(aru);
672 if (err) {
673 err = ar9170_echo_test(&aru->common, 0x60d43110);
674 if (err) {
675 /* force user invention, by disabling the device */
676 err = usb_driver_set_configuration(aru->udev, -1);
677 dev_err(&aru->udev->dev, "device is in a bad state. "
678 "please reconnect it!\n");
679 goto err_unrx;
680 }
681 }
682
683 err = ar9170_usb_open(ar);
684 if (err)
685 goto err_unrx;
686
687 err = ar9170_register(ar, &udev->dev);
688
689 ar9170_usb_stop(ar);
690 if (err)
691 goto err_unrx;
692
693 return 0;
694
695err_unrx:
696 ar9170_usb_cancel_urbs(aru);
697
698err_freefw:
699 release_firmware(aru->init_values);
700 release_firmware(aru->firmware);
701
702err_unlock:
703 usb_set_intfdata(intf, NULL);
704 usb_put_dev(udev);
705 ieee80211_free_hw(ar->hw);
706out:
707 return err;
708}
709
710static void ar9170_usb_disconnect(struct usb_interface *intf)
711{
712 struct ar9170_usb *aru = usb_get_intfdata(intf);
713
714 if (!aru)
715 return;
716
717 aru->common.state = AR9170_IDLE;
718 ar9170_unregister(&aru->common);
719 ar9170_usb_cancel_urbs(aru);
720
721 release_firmware(aru->init_values);
722 release_firmware(aru->firmware);
723
724 usb_put_dev(aru->udev);
725 usb_set_intfdata(intf, NULL);
726 ieee80211_free_hw(aru->common.hw);
727}
728
729static struct usb_driver ar9170_driver = {
730 .name = "ar9170usb",
731 .probe = ar9170_usb_probe,
732 .disconnect = ar9170_usb_disconnect,
733 .id_table = ar9170_usb_ids,
734 .soft_unbind = 1,
735};
736
737static int __init ar9170_init(void)
738{
739 return usb_register(&ar9170_driver);
740}
741
742static void __exit ar9170_exit(void)
743{
744 usb_deregister(&ar9170_driver);
745}
746
747module_init(ar9170_init);
748module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ar9170/usb.h b/drivers/net/wireless/ar9170/usb.h
new file mode 100644
index 000000000000..f5852924cd64
--- /dev/null
+++ b/drivers/net/wireless/ar9170/usb.h
@@ -0,0 +1,74 @@
1/*
2 * Atheros AR9170 USB driver
3 *
4 * Driver specific definitions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2009, Christian Lamparter <chunkeey@web.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU 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; see the file COPYING. If not, see
21 * http://www.gnu.org/licenses/.
22 *
23 * This file incorporates work covered by the following copyright and
24 * permission notice:
25 * Copyright (c) 2007-2008 Atheros Communications, Inc.
26 *
27 * Permission to use, copy, modify, and/or distribute this software for any
28 * purpose with or without fee is hereby granted, provided that the above
29 * copyright notice and this permission notice appear in all copies.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */
39#ifndef __USB_H
40#define __USB_H
41
42#include <linux/usb.h>
43#include <linux/completion.h>
44#include <linux/spinlock.h>
45#include <linux/leds.h>
46#include <net/wireless.h>
47#include <net/mac80211.h>
48#include <linux/firmware.h>
49#include "eeprom.h"
50#include "hw.h"
51#include "ar9170.h"
52
53#define AR9170_NUM_RX_URBS 16
54
55struct firmware;
56
57struct ar9170_usb {
58 struct ar9170 common;
59 struct usb_device *udev;
60 struct usb_interface *intf;
61
62 struct usb_anchor rx_submitted;
63 struct usb_anchor tx_submitted;
64
65 spinlock_t cmdlock;
66 struct completion cmd_wait;
67 int readlen;
68 u8 *readbuf;
69
70 const struct firmware *init_values;
71 const struct firmware *firmware;
72};
73
74#endif /* __USB_H */
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 0dc2c7321c8b..0b616e72fe05 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -204,9 +204,9 @@
204#define AR5K_TUNE_CWMAX_11B 1023 204#define AR5K_TUNE_CWMAX_11B 1023
205#define AR5K_TUNE_CWMAX_XR 7 205#define AR5K_TUNE_CWMAX_XR 7
206#define AR5K_TUNE_NOISE_FLOOR -72 206#define AR5K_TUNE_NOISE_FLOOR -72
207#define AR5K_TUNE_MAX_TXPOWER 60 207#define AR5K_TUNE_MAX_TXPOWER 63
208#define AR5K_TUNE_DEFAULT_TXPOWER 30 208#define AR5K_TUNE_DEFAULT_TXPOWER 25
209#define AR5K_TUNE_TPC_TXPOWER true 209#define AR5K_TUNE_TPC_TXPOWER false
210#define AR5K_TUNE_ANT_DIVERSITY true 210#define AR5K_TUNE_ANT_DIVERSITY true
211#define AR5K_TUNE_HWTXTRIES 4 211#define AR5K_TUNE_HWTXTRIES 4
212 212
@@ -551,11 +551,11 @@ enum ath5k_pkt_type {
551 */ 551 */
552#define AR5K_TXPOWER_OFDM(_r, _v) ( \ 552#define AR5K_TXPOWER_OFDM(_r, _v) ( \
553 ((0 & 1) << ((_v) + 6)) | \ 553 ((0 & 1) << ((_v) + 6)) | \
554 (((ah->ah_txpower.txp_rates[(_r)]) & 0x3f) << (_v)) \ 554 (((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \
555) 555)
556 556
557#define AR5K_TXPOWER_CCK(_r, _v) ( \ 557#define AR5K_TXPOWER_CCK(_r, _v) ( \
558 (ah->ah_txpower.txp_rates[(_r)] & 0x3f) << (_v) \ 558 (ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v) \
559) 559)
560 560
561/* 561/*
@@ -1085,13 +1085,25 @@ struct ath5k_hw {
1085 struct ath5k_gain ah_gain; 1085 struct ath5k_gain ah_gain;
1086 u8 ah_offset[AR5K_MAX_RF_BANKS]; 1086 u8 ah_offset[AR5K_MAX_RF_BANKS];
1087 1087
1088
1088 struct { 1089 struct {
1089 u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE]; 1090 /* Temporary tables used for interpolation */
1090 u16 txp_rates[AR5K_MAX_RATES]; 1091 u8 tmpL[AR5K_EEPROM_N_PD_GAINS]
1091 s16 txp_min; 1092 [AR5K_EEPROM_POWER_TABLE_SIZE];
1092 s16 txp_max; 1093 u8 tmpR[AR5K_EEPROM_N_PD_GAINS]
1094 [AR5K_EEPROM_POWER_TABLE_SIZE];
1095 u8 txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
1096 u16 txp_rates_power_table[AR5K_MAX_RATES];
1097 u8 txp_min_idx;
1093 bool txp_tpc; 1098 bool txp_tpc;
1099 /* Values in 0.25dB units */
1100 s16 txp_min_pwr;
1101 s16 txp_max_pwr;
1102 s16 txp_offset;
1094 s16 txp_ofdm; 1103 s16 txp_ofdm;
1104 /* Values in dB units */
1105 s16 txp_cck_ofdm_pwr_delta;
1106 s16 txp_cck_ofdm_gainf_delta;
1095 } ah_txpower; 1107 } ah_txpower;
1096 1108
1097 struct { 1109 struct {
@@ -1161,6 +1173,7 @@ extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_l
1161 1173
1162/* EEPROM access functions */ 1174/* EEPROM access functions */
1163extern int ath5k_eeprom_init(struct ath5k_hw *ah); 1175extern int ath5k_eeprom_init(struct ath5k_hw *ah);
1176extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
1164extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); 1177extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1165extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah); 1178extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1166 1179
@@ -1256,8 +1269,8 @@ extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
1256extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); 1269extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1257extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1270extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1258/* TX power setup */ 1271/* TX power setup */
1259extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower); 1272extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
1260extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power); 1273extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
1261 1274
1262/* 1275/*
1263 * Functions used internaly 1276 * Functions used internaly
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c
index 656cb9dc833b..70d376c63aac 100644
--- a/drivers/net/wireless/ath5k/attach.c
+++ b/drivers/net/wireless/ath5k/attach.c
@@ -341,6 +341,8 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
341 if (ah->ah_rf_banks != NULL) 341 if (ah->ah_rf_banks != NULL)
342 kfree(ah->ah_rf_banks); 342 kfree(ah->ah_rf_banks);
343 343
344 ath5k_eeprom_detach(ah);
345
344 /* assume interrupts are down */ 346 /* assume interrupts are down */
345 kfree(ah); 347 kfree(ah);
346} 348}
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index cad3ccf61b00..5d57d774e466 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -685,13 +685,6 @@ ath5k_pci_resume(struct pci_dev *pdev)
685 if (err) 685 if (err)
686 return err; 686 return err;
687 687
688 /*
689 * Suspend/Resume resets the PCI configuration space, so we have to
690 * re-disable the RETRY_TIMEOUT register (0x41) to keep
691 * PCI Tx retries from interfering with C3 CPU state
692 */
693 pci_write_config_byte(pdev, 0x41, 0);
694
695 err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); 688 err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
696 if (err) { 689 if (err) {
697 ATH5K_ERR(sc, "request_irq failed\n"); 690 ATH5K_ERR(sc, "request_irq failed\n");
@@ -1095,9 +1088,18 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1095static inline int 1088static inline int
1096ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) 1089ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
1097{ 1090{
1098 WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES, 1091 int rix;
1099 "hw_rix out of bounds: %x\n", hw_rix); 1092
1100 return sc->rate_idx[sc->curband->band][hw_rix]; 1093 /* return base rate on errors */
1094 if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
1095 "hw_rix out of bounds: %x\n", hw_rix))
1096 return 0;
1097
1098 rix = sc->rate_idx[sc->curband->band][hw_rix];
1099 if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
1100 rix = 0;
1101
1102 return rix;
1101} 1103}
1102 1104
1103/***************\ 1105/***************\
@@ -1216,6 +1218,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1216 1218
1217 pktlen = skb->len; 1219 pktlen = skb->len;
1218 1220
1221 /* FIXME: If we are in g mode and rate is a CCK rate
1222 * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
1223 * from tx power (value is in dB units already) */
1219 if (info->control.hw_key) { 1224 if (info->control.hw_key) {
1220 keyidx = info->control.hw_key->hw_key_idx; 1225 keyidx = info->control.hw_key->hw_key_idx;
1221 pktlen += info->control.hw_key->icv_len; 1226 pktlen += info->control.hw_key->icv_len;
@@ -2044,6 +2049,9 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2044 antenna = sc->bsent & 4 ? 2 : 1; 2049 antenna = sc->bsent & 4 ? 2 : 1;
2045 } 2050 }
2046 2051
2052 /* FIXME: If we are in g mode and rate is a CCK rate
2053 * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
2054 * from tx power (value is in dB units already) */
2047 ds->ds_data = bf->skbaddr; 2055 ds->ds_data = bf->skbaddr;
2048 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 2056 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
2049 ieee80211_get_hdrlen_from_skb(skb), 2057 ieee80211_get_hdrlen_from_skb(skb),
@@ -2305,7 +2313,7 @@ ath5k_init(struct ath5k_softc *sc)
2305 sc->curband = &sc->sbands[sc->curchan->band]; 2313 sc->curband = &sc->sbands[sc->curchan->band];
2306 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | 2314 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
2307 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | 2315 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2308 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; 2316 AR5K_INT_FATAL | AR5K_INT_GLOBAL;
2309 ret = ath5k_reset(sc, false, false); 2317 ret = ath5k_reset(sc, false, false);
2310 if (ret) 2318 if (ret)
2311 goto done; 2319 goto done;
@@ -2554,7 +2562,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2554 if (skb_headroom(skb) < padsize) { 2562 if (skb_headroom(skb) < padsize) {
2555 ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough" 2563 ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
2556 " headroom to pad %d\n", hdrlen, padsize); 2564 " headroom to pad %d\n", hdrlen, padsize);
2557 return NETDEV_TX_BUSY; 2565 goto drop_packet;
2558 } 2566 }
2559 skb_push(skb, padsize); 2567 skb_push(skb, padsize);
2560 memmove(skb->data, skb->data+padsize, hdrlen); 2568 memmove(skb->data, skb->data+padsize, hdrlen);
@@ -2565,7 +2573,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2565 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); 2573 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
2566 spin_unlock_irqrestore(&sc->txbuflock, flags); 2574 spin_unlock_irqrestore(&sc->txbuflock, flags);
2567 ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); 2575 ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
2568 return NETDEV_TX_BUSY; 2576 goto drop_packet;
2569 } 2577 }
2570 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); 2578 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
2571 list_del(&bf->list); 2579 list_del(&bf->list);
@@ -2582,10 +2590,12 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2582 list_add_tail(&bf->list, &sc->txbuf); 2590 list_add_tail(&bf->list, &sc->txbuf);
2583 sc->txbuf_len++; 2591 sc->txbuf_len++;
2584 spin_unlock_irqrestore(&sc->txbuflock, flags); 2592 spin_unlock_irqrestore(&sc->txbuflock, flags);
2585 dev_kfree_skb_any(skb); 2593 goto drop_packet;
2586 return NETDEV_TX_OK;
2587 } 2594 }
2595 return NETDEV_TX_OK;
2588 2596
2597drop_packet:
2598 dev_kfree_skb_any(skb);
2589 return NETDEV_TX_OK; 2599 return NETDEV_TX_OK;
2590} 2600}
2591 2601
@@ -2608,12 +2618,6 @@ ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
2608 goto err; 2618 goto err;
2609 } 2619 }
2610 2620
2611 /*
2612 * This is needed only to setup initial state
2613 * but it's best done after a reset.
2614 */
2615 ath5k_hw_set_txpower_limit(sc->ah, 0);
2616
2617 ret = ath5k_rx_start(sc); 2621 ret = ath5k_rx_start(sc);
2618 if (ret) { 2622 if (ret) {
2619 ATH5K_ERR(sc, "can't start recv logic\n"); 2623 ATH5K_ERR(sc, "can't start recv logic\n");
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
index 20e0d14b41ec..822956114cd7 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -112,7 +112,7 @@ struct ath5k_softc {
112 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 112 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
113 struct ieee80211_channel channels[ATH_CHAN_MAX]; 113 struct ieee80211_channel channels[ATH_CHAN_MAX];
114 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES]; 114 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
115 u8 rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES]; 115 s8 rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
116 enum nl80211_iftype opmode; 116 enum nl80211_iftype opmode;
117 struct ath5k_hw *ah; /* Atheros HW */ 117 struct ath5k_hw *ah; /* Atheros HW */
118 118
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c
index b40a9287a39a..dc30a2b70a6b 100644
--- a/drivers/net/wireless/ath5k/desc.c
+++ b/drivers/net/wireless/ath5k/desc.c
@@ -194,6 +194,10 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
194 return -EINVAL; 194 return -EINVAL;
195 } 195 }
196 196
197 tx_power += ah->ah_txpower.txp_offset;
198 if (tx_power > AR5K_TUNE_MAX_TXPOWER)
199 tx_power = AR5K_TUNE_MAX_TXPOWER;
200
197 /* Clear descriptor */ 201 /* Clear descriptor */
198 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); 202 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
199 203
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c
index ac45ca47ca87..c0fb3b09ba45 100644
--- a/drivers/net/wireless/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath5k/eeprom.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> 2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> 3 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org> 4 * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -98,11 +98,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
98 int ret; 98 int ret;
99 u16 val; 99 u16 val;
100 100
101 /* Initial TX thermal adjustment values */
102 ee->ee_tx_clip = 4;
103 ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
104 ee->ee_gain_select = 1;
105
106 /* 101 /*
107 * Read values from EEPROM and store them in the capability structure 102 * Read values from EEPROM and store them in the capability structure
108 */ 103 */
@@ -241,22 +236,22 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
241 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); 236 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
242 switch(mode) { 237 switch(mode) {
243 case AR5K_EEPROM_MODE_11A: 238 case AR5K_EEPROM_MODE_11A:
244 ee->ee_ob[mode][3] = (val >> 5) & 0x7; 239 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
245 ee->ee_db[mode][3] = (val >> 2) & 0x7; 240 ee->ee_db[mode][3] = (val >> 2) & 0x7;
246 ee->ee_ob[mode][2] = (val << 1) & 0x7; 241 ee->ee_ob[mode][2] = (val << 1) & 0x7;
247 242
248 AR5K_EEPROM_READ(o++, val); 243 AR5K_EEPROM_READ(o++, val);
249 ee->ee_ob[mode][2] |= (val >> 15) & 0x1; 244 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
250 ee->ee_db[mode][2] = (val >> 12) & 0x7; 245 ee->ee_db[mode][2] = (val >> 12) & 0x7;
251 ee->ee_ob[mode][1] = (val >> 9) & 0x7; 246 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
252 ee->ee_db[mode][1] = (val >> 6) & 0x7; 247 ee->ee_db[mode][1] = (val >> 6) & 0x7;
253 ee->ee_ob[mode][0] = (val >> 3) & 0x7; 248 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
254 ee->ee_db[mode][0] = val & 0x7; 249 ee->ee_db[mode][0] = val & 0x7;
255 break; 250 break;
256 case AR5K_EEPROM_MODE_11G: 251 case AR5K_EEPROM_MODE_11G:
257 case AR5K_EEPROM_MODE_11B: 252 case AR5K_EEPROM_MODE_11B:
258 ee->ee_ob[mode][1] = (val >> 4) & 0x7; 253 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
259 ee->ee_db[mode][1] = val & 0x7; 254 ee->ee_db[mode][1] = val & 0x7;
260 break; 255 break;
261 } 256 }
262 257
@@ -504,35 +499,6 @@ ath5k_eeprom_init_modes(struct ath5k_hw *ah)
504 return 0; 499 return 0;
505} 500}
506 501
507/* Used to match PCDAC steps with power values on RF5111 chips
508 * (eeprom versions < 4). For RF5111 we have 10 pre-defined PCDAC
509 * steps that match with the power values we read from eeprom. On
510 * older eeprom versions (< 3.2) these steps are equaly spaced at
511 * 10% of the pcdac curve -until the curve reaches it's maximum-
512 * (10 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
513 * these 10 steps are spaced in a different way. This function returns
514 * the pcdac steps based on eeprom version and curve min/max so that we
515 * can have pcdac/pwr points.
516 */
517static inline void
518ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
519{
520 static const u16 intercepts3[] =
521 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
522 static const u16 intercepts3_2[] =
523 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
524 const u16 *ip;
525 int i;
526
527 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
528 ip = intercepts3_2;
529 else
530 ip = intercepts3;
531
532 for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
533 *vp++ = (ip[i] * max + (100 - ip[i]) * min) / 100;
534}
535
536/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff 502/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
537 * frequency mask) */ 503 * frequency mask) */
538static inline int 504static inline int
@@ -546,26 +512,25 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
546 int ret; 512 int ret;
547 u16 val; 513 u16 val;
548 514
515 ee->ee_n_piers[mode] = 0;
549 while(i < max) { 516 while(i < max) {
550 AR5K_EEPROM_READ(o++, val); 517 AR5K_EEPROM_READ(o++, val);
551 518
552 freq1 = (val >> 8) & 0xff; 519 freq1 = val & 0xff;
553 freq2 = val & 0xff; 520 if (!freq1)
554 521 break;
555 if (freq1) {
556 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
557 freq1, mode);
558 ee->ee_n_piers[mode]++;
559 }
560 522
561 if (freq2) { 523 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
562 pc[i++].freq = ath5k_eeprom_bin2freq(ee, 524 freq1, mode);
563 freq2, mode); 525 ee->ee_n_piers[mode]++;
564 ee->ee_n_piers[mode]++;
565 }
566 526
567 if (!freq1 || !freq2) 527 freq2 = (val >> 8) & 0xff;
528 if (!freq2)
568 break; 529 break;
530
531 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
532 freq2, mode);
533 ee->ee_n_piers[mode]++;
569 } 534 }
570 535
571 /* return new offset */ 536 /* return new offset */
@@ -652,13 +617,122 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
652 return 0; 617 return 0;
653} 618}
654 619
655/* Read power calibration for RF5111 chips 620/*
621 * Read power calibration for RF5111 chips
622 *
656 * For RF5111 we have an XPD -eXternal Power Detector- curve 623 * For RF5111 we have an XPD -eXternal Power Detector- curve
657 * for each calibrated channel. Each curve has PCDAC steps on 624 * for each calibrated channel. Each curve has 0,5dB Power steps
658 * x axis and power on y axis and looks like a logarithmic 625 * on x axis and PCDAC steps (offsets) on y axis and looks like an
659 * function. To recreate the curve and pass the power values 626 * exponential function. To recreate the curve we read 11 points
660 * on the pcdac table, we read 10 points here and interpolate later. 627 * here and interpolate later.
661 */ 628 */
629
630/* Used to match PCDAC steps with power values on RF5111 chips
631 * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
632 * steps that match with the power values we read from eeprom. On
633 * older eeprom versions (< 3.2) these steps are equaly spaced at
634 * 10% of the pcdac curve -until the curve reaches it's maximum-
635 * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
636 * these 11 steps are spaced in a different way. This function returns
637 * the pcdac steps based on eeprom version and curve min/max so that we
638 * can have pcdac/pwr points.
639 */
640static inline void
641ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
642{
643 const static u16 intercepts3[] =
644 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
645 const static u16 intercepts3_2[] =
646 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
647 const u16 *ip;
648 int i;
649
650 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
651 ip = intercepts3_2;
652 else
653 ip = intercepts3;
654
655 for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
656 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
657}
658
659/* Convert RF5111 specific data to generic raw data
660 * used by interpolation code */
661static int
662ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
663 struct ath5k_chan_pcal_info *chinfo)
664{
665 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
666 struct ath5k_chan_pcal_info_rf5111 *pcinfo;
667 struct ath5k_pdgain_info *pd;
668 u8 pier, point, idx;
669 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
670
671 /* Fill raw data for each calibration pier */
672 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
673
674 pcinfo = &chinfo[pier].rf5111_info;
675
676 /* Allocate pd_curves for this cal pier */
677 chinfo[pier].pd_curves =
678 kcalloc(AR5K_EEPROM_N_PD_CURVES,
679 sizeof(struct ath5k_pdgain_info),
680 GFP_KERNEL);
681
682 if (!chinfo[pier].pd_curves)
683 return -ENOMEM;
684
685 /* Only one curve for RF5111
686 * find out which one and place
687 * in in pd_curves.
688 * Note: ee_x_gain is reversed here */
689 for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
690
691 if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
692 pdgain_idx[0] = idx;
693 break;
694 }
695 }
696
697 ee->ee_pd_gains[mode] = 1;
698
699 pd = &chinfo[pier].pd_curves[idx];
700
701 pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
702
703 /* Allocate pd points for this curve */
704 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
705 sizeof(u8), GFP_KERNEL);
706 if (!pd->pd_step)
707 return -ENOMEM;
708
709 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
710 sizeof(s16), GFP_KERNEL);
711 if (!pd->pd_pwr)
712 return -ENOMEM;
713
714 /* Fill raw dataset
715 * (convert power to 0.25dB units
716 * for RF5112 combatibility) */
717 for (point = 0; point < pd->pd_points; point++) {
718
719 /* Absolute values */
720 pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
721
722 /* Already sorted */
723 pd->pd_step[point] = pcinfo->pcdac[point];
724 }
725
726 /* Set min/max pwr */
727 chinfo[pier].min_pwr = pd->pd_pwr[0];
728 chinfo[pier].max_pwr = pd->pd_pwr[10];
729
730 }
731
732 return 0;
733}
734
735/* Parse EEPROM data */
662static int 736static int
663ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) 737ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
664{ 738{
@@ -747,30 +821,165 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
747 cdata->pcdac_max, cdata->pcdac); 821 cdata->pcdac_max, cdata->pcdac);
748 } 822 }
749 823
750 return 0; 824 return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
751} 825}
752 826
753/* Read power calibration for RF5112 chips 827
828/*
829 * Read power calibration for RF5112 chips
830 *
754 * For RF5112 we have 4 XPD -eXternal Power Detector- curves 831 * For RF5112 we have 4 XPD -eXternal Power Detector- curves
755 * for each calibrated channel on 0, -6, -12 and -18dbm but we only 832 * for each calibrated channel on 0, -6, -12 and -18dbm but we only
756 * use the higher (3) and the lower (0) curves. Each curve has PCDAC 833 * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
757 * steps on x axis and power on y axis and looks like a linear 834 * power steps on x axis and PCDAC steps on y axis and looks like a
758 * function. To recreate the curve and pass the power values 835 * linear function. To recreate the curve and pass the power values
759 * on the pcdac table, we read 4 points for xpd 0 and 3 points 836 * on hw, we read 4 points for xpd 0 (lower gain -> max power)
760 * for xpd 3 here and interpolate later. 837 * and 3 points for xpd 3 (higher gain -> lower power) here and
838 * interpolate later.
761 * 839 *
762 * Note: Many vendors just use xpd 0 so xpd 3 is zeroed. 840 * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
763 */ 841 */
842
843/* Convert RF5112 specific data to generic raw data
844 * used by interpolation code */
845static int
846ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
847 struct ath5k_chan_pcal_info *chinfo)
848{
849 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
850 struct ath5k_chan_pcal_info_rf5112 *pcinfo;
851 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
852 unsigned int pier, pdg, point;
853
854 /* Fill raw data for each calibration pier */
855 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
856
857 pcinfo = &chinfo[pier].rf5112_info;
858
859 /* Allocate pd_curves for this cal pier */
860 chinfo[pier].pd_curves =
861 kcalloc(AR5K_EEPROM_N_PD_CURVES,
862 sizeof(struct ath5k_pdgain_info),
863 GFP_KERNEL);
864
865 if (!chinfo[pier].pd_curves)
866 return -ENOMEM;
867
868 /* Fill pd_curves */
869 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
870
871 u8 idx = pdgain_idx[pdg];
872 struct ath5k_pdgain_info *pd =
873 &chinfo[pier].pd_curves[idx];
874
875 /* Lowest gain curve (max power) */
876 if (pdg == 0) {
877 /* One more point for better accuracy */
878 pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
879
880 /* Allocate pd points for this curve */
881 pd->pd_step = kcalloc(pd->pd_points,
882 sizeof(u8), GFP_KERNEL);
883
884 if (!pd->pd_step)
885 return -ENOMEM;
886
887 pd->pd_pwr = kcalloc(pd->pd_points,
888 sizeof(s16), GFP_KERNEL);
889
890 if (!pd->pd_pwr)
891 return -ENOMEM;
892
893
894 /* Fill raw dataset
895 * (all power levels are in 0.25dB units) */
896 pd->pd_step[0] = pcinfo->pcdac_x0[0];
897 pd->pd_pwr[0] = pcinfo->pwr_x0[0];
898
899 for (point = 1; point < pd->pd_points;
900 point++) {
901 /* Absolute values */
902 pd->pd_pwr[point] =
903 pcinfo->pwr_x0[point];
904
905 /* Deltas */
906 pd->pd_step[point] =
907 pd->pd_step[point - 1] +
908 pcinfo->pcdac_x0[point];
909 }
910
911 /* Set min power for this frequency */
912 chinfo[pier].min_pwr = pd->pd_pwr[0];
913
914 /* Highest gain curve (min power) */
915 } else if (pdg == 1) {
916
917 pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
918
919 /* Allocate pd points for this curve */
920 pd->pd_step = kcalloc(pd->pd_points,
921 sizeof(u8), GFP_KERNEL);
922
923 if (!pd->pd_step)
924 return -ENOMEM;
925
926 pd->pd_pwr = kcalloc(pd->pd_points,
927 sizeof(s16), GFP_KERNEL);
928
929 if (!pd->pd_pwr)
930 return -ENOMEM;
931
932 /* Fill raw dataset
933 * (all power levels are in 0.25dB units) */
934 for (point = 0; point < pd->pd_points;
935 point++) {
936 /* Absolute values */
937 pd->pd_pwr[point] =
938 pcinfo->pwr_x3[point];
939
940 /* Fixed points */
941 pd->pd_step[point] =
942 pcinfo->pcdac_x3[point];
943 }
944
945 /* Since we have a higher gain curve
946 * override min power */
947 chinfo[pier].min_pwr = pd->pd_pwr[0];
948 }
949 }
950 }
951
952 return 0;
953}
954
955/* Parse EEPROM data */
764static int 956static int
765ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) 957ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
766{ 958{
767 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 959 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
768 struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info; 960 struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
769 struct ath5k_chan_pcal_info *gen_chan_info; 961 struct ath5k_chan_pcal_info *gen_chan_info;
962 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
770 u32 offset; 963 u32 offset;
771 unsigned int i, c; 964 u8 i, c;
772 u16 val; 965 u16 val;
773 int ret; 966 int ret;
967 u8 pd_gains = 0;
968
969 /* Count how many curves we have and
970 * identify them (which one of the 4
971 * available curves we have on each count).
972 * Curves are stored from lower (x0) to
973 * higher (x3) gain */
974 for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
975 /* ee_x_gain[mode] is x gain mask */
976 if ((ee->ee_x_gain[mode] >> i) & 0x1)
977 pdgain_idx[pd_gains++] = i;
978 }
979 ee->ee_pd_gains[mode] = pd_gains;
980
981 if (pd_gains == 0 || pd_gains > 2)
982 return -EINVAL;
774 983
775 switch (mode) { 984 switch (mode) {
776 case AR5K_EEPROM_MODE_11A: 985 case AR5K_EEPROM_MODE_11A:
@@ -808,13 +1017,13 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
808 for (i = 0; i < ee->ee_n_piers[mode]; i++) { 1017 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
809 chan_pcal_info = &gen_chan_info[i].rf5112_info; 1018 chan_pcal_info = &gen_chan_info[i].rf5112_info;
810 1019
811 /* Power values in dBm * 4 1020 /* Power values in quarter dB
812 * for the lower xpd gain curve 1021 * for the lower xpd gain curve
813 * (0 dBm -> higher output power) */ 1022 * (0 dBm -> higher output power) */
814 for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) { 1023 for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
815 AR5K_EEPROM_READ(offset++, val); 1024 AR5K_EEPROM_READ(offset++, val);
816 chan_pcal_info->pwr_x0[c] = (val & 0xff); 1025 chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
817 chan_pcal_info->pwr_x0[++c] = ((val >> 8) & 0xff); 1026 chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
818 } 1027 }
819 1028
820 /* PCDAC steps 1029 /* PCDAC steps
@@ -825,12 +1034,12 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
825 chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f); 1034 chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
826 chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f); 1035 chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
827 1036
828 /* Power values in dBm * 4 1037 /* Power values in quarter dB
829 * for the higher xpd gain curve 1038 * for the higher xpd gain curve
830 * (18 dBm -> lower output power) */ 1039 * (18 dBm -> lower output power) */
831 AR5K_EEPROM_READ(offset++, val); 1040 AR5K_EEPROM_READ(offset++, val);
832 chan_pcal_info->pwr_x3[0] = (val & 0xff); 1041 chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
833 chan_pcal_info->pwr_x3[1] = ((val >> 8) & 0xff); 1042 chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
834 1043
835 AR5K_EEPROM_READ(offset++, val); 1044 AR5K_EEPROM_READ(offset++, val);
836 chan_pcal_info->pwr_x3[2] = (val & 0xff); 1045 chan_pcal_info->pwr_x3[2] = (val & 0xff);
@@ -843,24 +1052,36 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
843 chan_pcal_info->pcdac_x3[2] = 63; 1052 chan_pcal_info->pcdac_x3[2] = 63;
844 1053
845 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) { 1054 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
846 chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0xff); 1055 chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
847 1056
848 /* Last xpd0 power level is also channel maximum */ 1057 /* Last xpd0 power level is also channel maximum */
849 gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3]; 1058 gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
850 } else { 1059 } else {
851 chan_pcal_info->pcdac_x0[0] = 1; 1060 chan_pcal_info->pcdac_x0[0] = 1;
852 gen_chan_info[i].max_pwr = ((val >> 8) & 0xff); 1061 gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
853 } 1062 }
854 1063
855 /* Recreate pcdac_x0 table for this channel using pcdac steps */
856 chan_pcal_info->pcdac_x0[1] += chan_pcal_info->pcdac_x0[0];
857 chan_pcal_info->pcdac_x0[2] += chan_pcal_info->pcdac_x0[1];
858 chan_pcal_info->pcdac_x0[3] += chan_pcal_info->pcdac_x0[2];
859 } 1064 }
860 1065
861 return 0; 1066 return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
862} 1067}
863 1068
1069
1070/*
1071 * Read power calibration for RF2413 chips
1072 *
1073 * For RF2413 we have a Power to PDDAC table (Power Detector)
1074 * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
1075 * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
1076 * axis and looks like an exponential function like the RF5111 curve.
1077 *
1078 * To recreate the curves we read here the points and interpolate
1079 * later. Note that in most cases only 2 (higher and lower) curves are
1080 * used (like RF5112) but vendors have the oportunity to include all
1081 * 4 curves on eeprom. The final curve (higher power) has an extra
1082 * point for better accuracy like RF5112.
1083 */
1084
864/* For RF2413 power calibration data doesn't start on a fixed location and 1085/* For RF2413 power calibration data doesn't start on a fixed location and
865 * if a mode is not supported, it's section is missing -not zeroed-. 1086 * if a mode is not supported, it's section is missing -not zeroed-.
866 * So we need to calculate the starting offset for each section by using 1087 * So we need to calculate the starting offset for each section by using
@@ -890,13 +1111,15 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
890 switch(mode) { 1111 switch(mode) {
891 case AR5K_EEPROM_MODE_11G: 1112 case AR5K_EEPROM_MODE_11G:
892 if (AR5K_EEPROM_HDR_11B(ee->ee_header)) 1113 if (AR5K_EEPROM_HDR_11B(ee->ee_header))
893 offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) + 1114 offset += ath5k_pdgains_size_2413(ee,
894 AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1115 AR5K_EEPROM_MODE_11B) +
1116 AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
895 /* fall through */ 1117 /* fall through */
896 case AR5K_EEPROM_MODE_11B: 1118 case AR5K_EEPROM_MODE_11B:
897 if (AR5K_EEPROM_HDR_11A(ee->ee_header)) 1119 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
898 offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) + 1120 offset += ath5k_pdgains_size_2413(ee,
899 AR5K_EEPROM_N_5GHZ_CHAN / 2; 1121 AR5K_EEPROM_MODE_11A) +
1122 AR5K_EEPROM_N_5GHZ_CHAN / 2;
900 /* fall through */ 1123 /* fall through */
901 case AR5K_EEPROM_MODE_11A: 1124 case AR5K_EEPROM_MODE_11A:
902 break; 1125 break;
@@ -907,37 +1130,118 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
907 return offset; 1130 return offset;
908} 1131}
909 1132
910/* Read power calibration for RF2413 chips 1133/* Convert RF2413 specific data to generic raw data
911 * For RF2413 we have a PDDAC table (Power Detector) instead 1134 * used by interpolation code */
912 * of a PCDAC and 4 pd gain curves for each calibrated channel. 1135static int
913 * Each curve has PDDAC steps on x axis and power on y axis and 1136ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
914 * looks like an exponential function. To recreate the curves 1137 struct ath5k_chan_pcal_info *chinfo)
915 * we read here the points and interpolate later. Note that 1138{
916 * in most cases only higher and lower curves are used (like 1139 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
917 * RF5112) but vendors have the oportunity to include all 4 1140 struct ath5k_chan_pcal_info_rf2413 *pcinfo;
918 * curves on eeprom. The final curve (higher power) has an extra 1141 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
919 * point for better accuracy like RF5112. 1142 unsigned int pier, pdg, point;
920 */ 1143
1144 /* Fill raw data for each calibration pier */
1145 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1146
1147 pcinfo = &chinfo[pier].rf2413_info;
1148
1149 /* Allocate pd_curves for this cal pier */
1150 chinfo[pier].pd_curves =
1151 kcalloc(AR5K_EEPROM_N_PD_CURVES,
1152 sizeof(struct ath5k_pdgain_info),
1153 GFP_KERNEL);
1154
1155 if (!chinfo[pier].pd_curves)
1156 return -ENOMEM;
1157
1158 /* Fill pd_curves */
1159 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1160
1161 u8 idx = pdgain_idx[pdg];
1162 struct ath5k_pdgain_info *pd =
1163 &chinfo[pier].pd_curves[idx];
1164
1165 /* One more point for the highest power
1166 * curve (lowest gain) */
1167 if (pdg == ee->ee_pd_gains[mode] - 1)
1168 pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
1169 else
1170 pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
1171
1172 /* Allocate pd points for this curve */
1173 pd->pd_step = kcalloc(pd->pd_points,
1174 sizeof(u8), GFP_KERNEL);
1175
1176 if (!pd->pd_step)
1177 return -ENOMEM;
1178
1179 pd->pd_pwr = kcalloc(pd->pd_points,
1180 sizeof(s16), GFP_KERNEL);
1181
1182 if (!pd->pd_pwr)
1183 return -ENOMEM;
1184
1185 /* Fill raw dataset
1186 * convert all pwr levels to
1187 * quarter dB for RF5112 combatibility */
1188 pd->pd_step[0] = pcinfo->pddac_i[pdg];
1189 pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
1190
1191 for (point = 1; point < pd->pd_points; point++) {
1192
1193 pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
1194 2 * pcinfo->pwr[pdg][point - 1];
1195
1196 pd->pd_step[point] = pd->pd_step[point - 1] +
1197 pcinfo->pddac[pdg][point - 1];
1198
1199 }
1200
1201 /* Highest gain curve -> min power */
1202 if (pdg == 0)
1203 chinfo[pier].min_pwr = pd->pd_pwr[0];
1204
1205 /* Lowest gain curve -> max power */
1206 if (pdg == ee->ee_pd_gains[mode] - 1)
1207 chinfo[pier].max_pwr =
1208 pd->pd_pwr[pd->pd_points - 1];
1209 }
1210 }
1211
1212 return 0;
1213}
1214
1215/* Parse EEPROM data */
921static int 1216static int
922ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) 1217ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
923{ 1218{
924 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1219 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
925 struct ath5k_chan_pcal_info_rf2413 *chan_pcal_info; 1220 struct ath5k_chan_pcal_info_rf2413 *pcinfo;
926 struct ath5k_chan_pcal_info *gen_chan_info; 1221 struct ath5k_chan_pcal_info *chinfo;
927 unsigned int i, c; 1222 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
928 u32 offset; 1223 u32 offset;
929 int ret; 1224 int idx, i, ret;
930 u16 val; 1225 u16 val;
931 u8 pd_gains = 0; 1226 u8 pd_gains = 0;
932 1227
933 if (ee->ee_x_gain[mode] & 0x1) pd_gains++; 1228 /* Count how many curves we have and
934 if ((ee->ee_x_gain[mode] >> 1) & 0x1) pd_gains++; 1229 * identify them (which one of the 4
935 if ((ee->ee_x_gain[mode] >> 2) & 0x1) pd_gains++; 1230 * available curves we have on each count).
936 if ((ee->ee_x_gain[mode] >> 3) & 0x1) pd_gains++; 1231 * Curves are stored from higher to
1232 * lower gain so we go backwards */
1233 for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
1234 /* ee_x_gain[mode] is x gain mask */
1235 if ((ee->ee_x_gain[mode] >> idx) & 0x1)
1236 pdgain_idx[pd_gains++] = idx;
1237
1238 }
937 ee->ee_pd_gains[mode] = pd_gains; 1239 ee->ee_pd_gains[mode] = pd_gains;
938 1240
1241 if (pd_gains == 0)
1242 return -EINVAL;
1243
939 offset = ath5k_cal_data_offset_2413(ee, mode); 1244 offset = ath5k_cal_data_offset_2413(ee, mode);
940 ee->ee_n_piers[mode] = 0;
941 switch (mode) { 1245 switch (mode) {
942 case AR5K_EEPROM_MODE_11A: 1246 case AR5K_EEPROM_MODE_11A:
943 if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) 1247 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
@@ -945,7 +1249,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
945 1249
946 ath5k_eeprom_init_11a_pcal_freq(ah, offset); 1250 ath5k_eeprom_init_11a_pcal_freq(ah, offset);
947 offset += AR5K_EEPROM_N_5GHZ_CHAN / 2; 1251 offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
948 gen_chan_info = ee->ee_pwr_cal_a; 1252 chinfo = ee->ee_pwr_cal_a;
949 break; 1253 break;
950 case AR5K_EEPROM_MODE_11B: 1254 case AR5K_EEPROM_MODE_11B:
951 if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) 1255 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
@@ -953,7 +1257,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
953 1257
954 ath5k_eeprom_init_11bg_2413(ah, mode, offset); 1258 ath5k_eeprom_init_11bg_2413(ah, mode, offset);
955 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1259 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
956 gen_chan_info = ee->ee_pwr_cal_b; 1260 chinfo = ee->ee_pwr_cal_b;
957 break; 1261 break;
958 case AR5K_EEPROM_MODE_11G: 1262 case AR5K_EEPROM_MODE_11G:
959 if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) 1263 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
@@ -961,41 +1265,35 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
961 1265
962 ath5k_eeprom_init_11bg_2413(ah, mode, offset); 1266 ath5k_eeprom_init_11bg_2413(ah, mode, offset);
963 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1267 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
964 gen_chan_info = ee->ee_pwr_cal_g; 1268 chinfo = ee->ee_pwr_cal_g;
965 break; 1269 break;
966 default: 1270 default:
967 return -EINVAL; 1271 return -EINVAL;
968 } 1272 }
969 1273
970 if (pd_gains == 0)
971 return 0;
972
973 for (i = 0; i < ee->ee_n_piers[mode]; i++) { 1274 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
974 chan_pcal_info = &gen_chan_info[i].rf2413_info; 1275 pcinfo = &chinfo[i].rf2413_info;
975 1276
976 /* 1277 /*
977 * Read pwr_i, pddac_i and the first 1278 * Read pwr_i, pddac_i and the first
978 * 2 pd points (pwr, pddac) 1279 * 2 pd points (pwr, pddac)
979 */ 1280 */
980 AR5K_EEPROM_READ(offset++, val); 1281 AR5K_EEPROM_READ(offset++, val);
981 chan_pcal_info->pwr_i[0] = val & 0x1f; 1282 pcinfo->pwr_i[0] = val & 0x1f;
982 chan_pcal_info->pddac_i[0] = (val >> 5) & 0x7f; 1283 pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
983 chan_pcal_info->pwr[0][0] = 1284 pcinfo->pwr[0][0] = (val >> 12) & 0xf;
984 (val >> 12) & 0xf;
985 1285
986 AR5K_EEPROM_READ(offset++, val); 1286 AR5K_EEPROM_READ(offset++, val);
987 chan_pcal_info->pddac[0][0] = val & 0x3f; 1287 pcinfo->pddac[0][0] = val & 0x3f;
988 chan_pcal_info->pwr[0][1] = (val >> 6) & 0xf; 1288 pcinfo->pwr[0][1] = (val >> 6) & 0xf;
989 chan_pcal_info->pddac[0][1] = 1289 pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
990 (val >> 10) & 0x3f;
991 1290
992 AR5K_EEPROM_READ(offset++, val); 1291 AR5K_EEPROM_READ(offset++, val);
993 chan_pcal_info->pwr[0][2] = val & 0xf; 1292 pcinfo->pwr[0][2] = val & 0xf;
994 chan_pcal_info->pddac[0][2] = 1293 pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
995 (val >> 4) & 0x3f;
996 1294
997 chan_pcal_info->pwr[0][3] = 0; 1295 pcinfo->pwr[0][3] = 0;
998 chan_pcal_info->pddac[0][3] = 0; 1296 pcinfo->pddac[0][3] = 0;
999 1297
1000 if (pd_gains > 1) { 1298 if (pd_gains > 1) {
1001 /* 1299 /*
@@ -1003,44 +1301,36 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
1003 * so it only has 2 pd points. 1301 * so it only has 2 pd points.
1004 * Continue wih pd gain 1. 1302 * Continue wih pd gain 1.
1005 */ 1303 */
1006 chan_pcal_info->pwr_i[1] = (val >> 10) & 0x1f; 1304 pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
1007 1305
1008 chan_pcal_info->pddac_i[1] = (val >> 15) & 0x1; 1306 pcinfo->pddac_i[1] = (val >> 15) & 0x1;
1009 AR5K_EEPROM_READ(offset++, val); 1307 AR5K_EEPROM_READ(offset++, val);
1010 chan_pcal_info->pddac_i[1] |= (val & 0x3F) << 1; 1308 pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
1011 1309
1012 chan_pcal_info->pwr[1][0] = (val >> 6) & 0xf; 1310 pcinfo->pwr[1][0] = (val >> 6) & 0xf;
1013 chan_pcal_info->pddac[1][0] = 1311 pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
1014 (val >> 10) & 0x3f;
1015 1312
1016 AR5K_EEPROM_READ(offset++, val); 1313 AR5K_EEPROM_READ(offset++, val);
1017 chan_pcal_info->pwr[1][1] = val & 0xf; 1314 pcinfo->pwr[1][1] = val & 0xf;
1018 chan_pcal_info->pddac[1][1] = 1315 pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
1019 (val >> 4) & 0x3f; 1316 pcinfo->pwr[1][2] = (val >> 10) & 0xf;
1020 chan_pcal_info->pwr[1][2] = 1317
1021 (val >> 10) & 0xf; 1318 pcinfo->pddac[1][2] = (val >> 14) & 0x3;
1022
1023 chan_pcal_info->pddac[1][2] =
1024 (val >> 14) & 0x3;
1025 AR5K_EEPROM_READ(offset++, val); 1319 AR5K_EEPROM_READ(offset++, val);
1026 chan_pcal_info->pddac[1][2] |= 1320 pcinfo->pddac[1][2] |= (val & 0xF) << 2;
1027 (val & 0xF) << 2;
1028 1321
1029 chan_pcal_info->pwr[1][3] = 0; 1322 pcinfo->pwr[1][3] = 0;
1030 chan_pcal_info->pddac[1][3] = 0; 1323 pcinfo->pddac[1][3] = 0;
1031 } else if (pd_gains == 1) { 1324 } else if (pd_gains == 1) {
1032 /* 1325 /*
1033 * Pd gain 0 is the last one so 1326 * Pd gain 0 is the last one so
1034 * read the extra point. 1327 * read the extra point.
1035 */ 1328 */
1036 chan_pcal_info->pwr[0][3] = 1329 pcinfo->pwr[0][3] = (val >> 10) & 0xf;
1037 (val >> 10) & 0xf;
1038 1330
1039 chan_pcal_info->pddac[0][3] = 1331 pcinfo->pddac[0][3] = (val >> 14) & 0x3;
1040 (val >> 14) & 0x3;
1041 AR5K_EEPROM_READ(offset++, val); 1332 AR5K_EEPROM_READ(offset++, val);
1042 chan_pcal_info->pddac[0][3] |= 1333 pcinfo->pddac[0][3] |= (val & 0xF) << 2;
1043 (val & 0xF) << 2;
1044 } 1334 }
1045 1335
1046 /* 1336 /*
@@ -1048,105 +1338,65 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
1048 * as above. 1338 * as above.
1049 */ 1339 */
1050 if (pd_gains > 2) { 1340 if (pd_gains > 2) {
1051 chan_pcal_info->pwr_i[2] = (val >> 4) & 0x1f; 1341 pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
1052 chan_pcal_info->pddac_i[2] = (val >> 9) & 0x7f; 1342 pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
1053 1343
1054 AR5K_EEPROM_READ(offset++, val); 1344 AR5K_EEPROM_READ(offset++, val);
1055 chan_pcal_info->pwr[2][0] = 1345 pcinfo->pwr[2][0] = (val >> 0) & 0xf;
1056 (val >> 0) & 0xf; 1346 pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
1057 chan_pcal_info->pddac[2][0] = 1347 pcinfo->pwr[2][1] = (val >> 10) & 0xf;
1058 (val >> 4) & 0x3f; 1348
1059 chan_pcal_info->pwr[2][1] = 1349 pcinfo->pddac[2][1] = (val >> 14) & 0x3;
1060 (val >> 10) & 0xf;
1061
1062 chan_pcal_info->pddac[2][1] =
1063 (val >> 14) & 0x3;
1064 AR5K_EEPROM_READ(offset++, val); 1350 AR5K_EEPROM_READ(offset++, val);
1065 chan_pcal_info->pddac[2][1] |= 1351 pcinfo->pddac[2][1] |= (val & 0xF) << 2;
1066 (val & 0xF) << 2;
1067 1352
1068 chan_pcal_info->pwr[2][2] = 1353 pcinfo->pwr[2][2] = (val >> 4) & 0xf;
1069 (val >> 4) & 0xf; 1354 pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
1070 chan_pcal_info->pddac[2][2] =
1071 (val >> 8) & 0x3f;
1072 1355
1073 chan_pcal_info->pwr[2][3] = 0; 1356 pcinfo->pwr[2][3] = 0;
1074 chan_pcal_info->pddac[2][3] = 0; 1357 pcinfo->pddac[2][3] = 0;
1075 } else if (pd_gains == 2) { 1358 } else if (pd_gains == 2) {
1076 chan_pcal_info->pwr[1][3] = 1359 pcinfo->pwr[1][3] = (val >> 4) & 0xf;
1077 (val >> 4) & 0xf; 1360 pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
1078 chan_pcal_info->pddac[1][3] =
1079 (val >> 8) & 0x3f;
1080 } 1361 }
1081 1362
1082 if (pd_gains > 3) { 1363 if (pd_gains > 3) {
1083 chan_pcal_info->pwr_i[3] = (val >> 14) & 0x3; 1364 pcinfo->pwr_i[3] = (val >> 14) & 0x3;
1084 AR5K_EEPROM_READ(offset++, val); 1365 AR5K_EEPROM_READ(offset++, val);
1085 chan_pcal_info->pwr_i[3] |= ((val >> 0) & 0x7) << 2; 1366 pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
1086 1367
1087 chan_pcal_info->pddac_i[3] = (val >> 3) & 0x7f; 1368 pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
1088 chan_pcal_info->pwr[3][0] = 1369 pcinfo->pwr[3][0] = (val >> 10) & 0xf;
1089 (val >> 10) & 0xf; 1370 pcinfo->pddac[3][0] = (val >> 14) & 0x3;
1090 chan_pcal_info->pddac[3][0] =
1091 (val >> 14) & 0x3;
1092 1371
1093 AR5K_EEPROM_READ(offset++, val); 1372 AR5K_EEPROM_READ(offset++, val);
1094 chan_pcal_info->pddac[3][0] |= 1373 pcinfo->pddac[3][0] |= (val & 0xF) << 2;
1095 (val & 0xF) << 2; 1374 pcinfo->pwr[3][1] = (val >> 4) & 0xf;
1096 chan_pcal_info->pwr[3][1] = 1375 pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
1097 (val >> 4) & 0xf; 1376
1098 chan_pcal_info->pddac[3][1] = 1377 pcinfo->pwr[3][2] = (val >> 14) & 0x3;
1099 (val >> 8) & 0x3f;
1100
1101 chan_pcal_info->pwr[3][2] =
1102 (val >> 14) & 0x3;
1103 AR5K_EEPROM_READ(offset++, val); 1378 AR5K_EEPROM_READ(offset++, val);
1104 chan_pcal_info->pwr[3][2] |= 1379 pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
1105 ((val >> 0) & 0x3) << 2;
1106 1380
1107 chan_pcal_info->pddac[3][2] = 1381 pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
1108 (val >> 2) & 0x3f; 1382 pcinfo->pwr[3][3] = (val >> 8) & 0xf;
1109 chan_pcal_info->pwr[3][3] =
1110 (val >> 8) & 0xf;
1111 1383
1112 chan_pcal_info->pddac[3][3] = 1384 pcinfo->pddac[3][3] = (val >> 12) & 0xF;
1113 (val >> 12) & 0xF;
1114 AR5K_EEPROM_READ(offset++, val); 1385 AR5K_EEPROM_READ(offset++, val);
1115 chan_pcal_info->pddac[3][3] |= 1386 pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
1116 ((val >> 0) & 0x3) << 4;
1117 } else if (pd_gains == 3) { 1387 } else if (pd_gains == 3) {
1118 chan_pcal_info->pwr[2][3] = 1388 pcinfo->pwr[2][3] = (val >> 14) & 0x3;
1119 (val >> 14) & 0x3;
1120 AR5K_EEPROM_READ(offset++, val); 1389 AR5K_EEPROM_READ(offset++, val);
1121 chan_pcal_info->pwr[2][3] |= 1390 pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
1122 ((val >> 0) & 0x3) << 2;
1123
1124 chan_pcal_info->pddac[2][3] =
1125 (val >> 2) & 0x3f;
1126 }
1127 1391
1128 for (c = 0; c < pd_gains; c++) { 1392 pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
1129 /* Recreate pwr table for this channel using pwr steps */
1130 chan_pcal_info->pwr[c][0] += chan_pcal_info->pwr_i[c] * 2;
1131 chan_pcal_info->pwr[c][1] += chan_pcal_info->pwr[c][0];
1132 chan_pcal_info->pwr[c][2] += chan_pcal_info->pwr[c][1];
1133 chan_pcal_info->pwr[c][3] += chan_pcal_info->pwr[c][2];
1134 if (chan_pcal_info->pwr[c][3] == chan_pcal_info->pwr[c][2])
1135 chan_pcal_info->pwr[c][3] = 0;
1136
1137 /* Recreate pddac table for this channel using pddac steps */
1138 chan_pcal_info->pddac[c][0] += chan_pcal_info->pddac_i[c];
1139 chan_pcal_info->pddac[c][1] += chan_pcal_info->pddac[c][0];
1140 chan_pcal_info->pddac[c][2] += chan_pcal_info->pddac[c][1];
1141 chan_pcal_info->pddac[c][3] += chan_pcal_info->pddac[c][2];
1142 if (chan_pcal_info->pddac[c][3] == chan_pcal_info->pddac[c][2])
1143 chan_pcal_info->pddac[c][3] = 0;
1144 } 1393 }
1145 } 1394 }
1146 1395
1147 return 0; 1396 return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
1148} 1397}
1149 1398
1399
1150/* 1400/*
1151 * Read per rate target power (this is the maximum tx power 1401 * Read per rate target power (this is the maximum tx power
1152 * supported by the card). This info is used when setting 1402 * supported by the card). This info is used when setting
@@ -1154,11 +1404,12 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
1154 * 1404 *
1155 * This also works for v5 EEPROMs. 1405 * This also works for v5 EEPROMs.
1156 */ 1406 */
1157static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) 1407static int
1408ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
1158{ 1409{
1159 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1410 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1160 struct ath5k_rate_pcal_info *rate_pcal_info; 1411 struct ath5k_rate_pcal_info *rate_pcal_info;
1161 u16 *rate_target_pwr_num; 1412 u8 *rate_target_pwr_num;
1162 u32 offset; 1413 u32 offset;
1163 u16 val; 1414 u16 val;
1164 int ret, i; 1415 int ret, i;
@@ -1264,7 +1515,9 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
1264 else 1515 else
1265 read_pcal = ath5k_eeprom_read_pcal_info_5111; 1516 read_pcal = ath5k_eeprom_read_pcal_info_5111;
1266 1517
1267 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) { 1518
1519 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
1520 mode++) {
1268 err = read_pcal(ah, mode); 1521 err = read_pcal(ah, mode);
1269 if (err) 1522 if (err)
1270 return err; 1523 return err;
@@ -1277,6 +1530,62 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
1277 return 0; 1530 return 0;
1278} 1531}
1279 1532
1533static int
1534ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
1535{
1536 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1537 struct ath5k_chan_pcal_info *chinfo;
1538 u8 pier, pdg;
1539
1540 switch (mode) {
1541 case AR5K_EEPROM_MODE_11A:
1542 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
1543 return 0;
1544 chinfo = ee->ee_pwr_cal_a;
1545 break;
1546 case AR5K_EEPROM_MODE_11B:
1547 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
1548 return 0;
1549 chinfo = ee->ee_pwr_cal_b;
1550 break;
1551 case AR5K_EEPROM_MODE_11G:
1552 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
1553 return 0;
1554 chinfo = ee->ee_pwr_cal_g;
1555 break;
1556 default:
1557 return -EINVAL;
1558 }
1559
1560 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1561 if (!chinfo[pier].pd_curves)
1562 continue;
1563
1564 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1565 struct ath5k_pdgain_info *pd =
1566 &chinfo[pier].pd_curves[pdg];
1567
1568 if (pd != NULL) {
1569 kfree(pd->pd_step);
1570 kfree(pd->pd_pwr);
1571 }
1572 }
1573
1574 kfree(chinfo[pier].pd_curves);
1575 }
1576
1577 return 0;
1578}
1579
1580void
1581ath5k_eeprom_detach(struct ath5k_hw *ah)
1582{
1583 u8 mode;
1584
1585 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
1586 ath5k_eeprom_free_pcal_info(ah, mode);
1587}
1588
1280/* Read conformance test limits used for regulatory control */ 1589/* Read conformance test limits used for regulatory control */
1281static int 1590static int
1282ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) 1591ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
@@ -1457,3 +1766,4 @@ bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
1457 else 1766 else
1458 return false; 1767 return false;
1459} 1768}
1769
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h
index 1deebc0257d4..b0c0606dea0b 100644
--- a/drivers/net/wireless/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath5k/eeprom.h
@@ -173,6 +173,7 @@
173#define AR5K_EEPROM_N_5GHZ_CHAN 10 173#define AR5K_EEPROM_N_5GHZ_CHAN 10
174#define AR5K_EEPROM_N_2GHZ_CHAN 3 174#define AR5K_EEPROM_N_2GHZ_CHAN 3
175#define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 175#define AR5K_EEPROM_N_2GHZ_CHAN_2413 4
176#define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4
176#define AR5K_EEPROM_MAX_CHAN 10 177#define AR5K_EEPROM_MAX_CHAN 10
177#define AR5K_EEPROM_N_PWR_POINTS_5111 11 178#define AR5K_EEPROM_N_PWR_POINTS_5111 11
178#define AR5K_EEPROM_N_PCDAC 11 179#define AR5K_EEPROM_N_PCDAC 11
@@ -193,7 +194,7 @@
193#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10) 194#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
194#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32) 195#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32)
195#define AR5K_EEPROM_MAX_CTLS 32 196#define AR5K_EEPROM_MAX_CTLS 32
196#define AR5K_EEPROM_N_XPD_PER_CHANNEL 4 197#define AR5K_EEPROM_N_PD_CURVES 4
197#define AR5K_EEPROM_N_XPD0_POINTS 4 198#define AR5K_EEPROM_N_XPD0_POINTS 4
198#define AR5K_EEPROM_N_XPD3_POINTS 3 199#define AR5K_EEPROM_N_XPD3_POINTS 3
199#define AR5K_EEPROM_N_PD_GAINS 4 200#define AR5K_EEPROM_N_PD_GAINS 4
@@ -232,7 +233,7 @@ enum ath5k_ctl_mode {
232 AR5K_CTL_11B = 1, 233 AR5K_CTL_11B = 1,
233 AR5K_CTL_11G = 2, 234 AR5K_CTL_11G = 2,
234 AR5K_CTL_TURBO = 3, 235 AR5K_CTL_TURBO = 3,
235 AR5K_CTL_108G = 4, 236 AR5K_CTL_TURBOG = 4,
236 AR5K_CTL_2GHT20 = 5, 237 AR5K_CTL_2GHT20 = 5,
237 AR5K_CTL_5GHT20 = 6, 238 AR5K_CTL_5GHT20 = 6,
238 AR5K_CTL_2GHT40 = 7, 239 AR5K_CTL_2GHT40 = 7,
@@ -240,65 +241,114 @@ enum ath5k_ctl_mode {
240 AR5K_CTL_MODE_M = 15, 241 AR5K_CTL_MODE_M = 15,
241}; 242};
242 243
244/* Default CTL ids for the 3 main reg domains.
245 * Atheros only uses these by default but vendors
246 * can have up to 32 different CTLs for different
247 * scenarios. Note that theese values are ORed with
248 * the mode id (above) so we can have up to 24 CTL
249 * datasets out of these 3 main regdomains. That leaves
250 * 8 ids that can be used by vendors and since 0x20 is
251 * missing from HAL sources i guess this is the set of
252 * custom CTLs vendors can use. */
253#define AR5K_CTL_FCC 0x10
254#define AR5K_CTL_CUSTOM 0x20
255#define AR5K_CTL_ETSI 0x30
256#define AR5K_CTL_MKK 0x40
257
258/* Indicates a CTL with only mode set and
259 * no reg domain mapping, such CTLs are used
260 * for world roaming domains or simply when
261 * a reg domain is not set */
262#define AR5K_CTL_NO_REGDOMAIN 0xf0
263
264/* Indicates an empty (invalid) CTL */
265#define AR5K_CTL_NO_CTL 0xff
266
243/* Per channel calibration data, used for power table setup */ 267/* Per channel calibration data, used for power table setup */
244struct ath5k_chan_pcal_info_rf5111 { 268struct ath5k_chan_pcal_info_rf5111 {
245 /* Power levels in half dbm units 269 /* Power levels in half dbm units
246 * for one power curve. */ 270 * for one power curve. */
247 u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111]; 271 u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
248 /* PCDAC table steps 272 /* PCDAC table steps
249 * for the above values */ 273 * for the above values */
250 u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111]; 274 u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
251 /* Starting PCDAC step */ 275 /* Starting PCDAC step */
252 u8 pcdac_min; 276 u8 pcdac_min;
253 /* Final PCDAC step */ 277 /* Final PCDAC step */
254 u8 pcdac_max; 278 u8 pcdac_max;
255}; 279};
256 280
257struct ath5k_chan_pcal_info_rf5112 { 281struct ath5k_chan_pcal_info_rf5112 {
258 /* Power levels in quarter dBm units 282 /* Power levels in quarter dBm units
259 * for lower (0) and higher (3) 283 * for lower (0) and higher (3)
260 * level curves */ 284 * level curves in 0.25dB units */
261 s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS]; 285 s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
262 s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS]; 286 s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
263 /* PCDAC table steps 287 /* PCDAC table steps
264 * for the above values */ 288 * for the above values */
265 u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS]; 289 u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
266 u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS]; 290 u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
267}; 291};
268 292
269struct ath5k_chan_pcal_info_rf2413 { 293struct ath5k_chan_pcal_info_rf2413 {
270 /* Starting pwr/pddac values */ 294 /* Starting pwr/pddac values */
271 s8 pwr_i[AR5K_EEPROM_N_PD_GAINS]; 295 s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
272 u8 pddac_i[AR5K_EEPROM_N_PD_GAINS]; 296 u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
273 /* (pwr,pddac) points */ 297 /* (pwr,pddac) points
274 s8 pwr[AR5K_EEPROM_N_PD_GAINS] 298 * power levels in 0.5dB units */
275 [AR5K_EEPROM_N_PD_POINTS]; 299 s8 pwr[AR5K_EEPROM_N_PD_GAINS]
276 u8 pddac[AR5K_EEPROM_N_PD_GAINS] 300 [AR5K_EEPROM_N_PD_POINTS];
277 [AR5K_EEPROM_N_PD_POINTS]; 301 u8 pddac[AR5K_EEPROM_N_PD_GAINS]
302 [AR5K_EEPROM_N_PD_POINTS];
303};
304
305enum ath5k_powertable_type {
306 AR5K_PWRTABLE_PWR_TO_PCDAC = 0,
307 AR5K_PWRTABLE_LINEAR_PCDAC = 1,
308 AR5K_PWRTABLE_PWR_TO_PDADC = 2,
309};
310
311struct ath5k_pdgain_info {
312 u8 pd_points;
313 u8 *pd_step;
314 /* Power values are in
315 * 0.25dB units */
316 s16 *pd_pwr;
278}; 317};
279 318
280struct ath5k_chan_pcal_info { 319struct ath5k_chan_pcal_info {
281 /* Frequency */ 320 /* Frequency */
282 u16 freq; 321 u16 freq;
283 /* Max available power */ 322 /* Tx power boundaries */
284 s8 max_pwr; 323 s16 max_pwr;
324 s16 min_pwr;
285 union { 325 union {
286 struct ath5k_chan_pcal_info_rf5111 rf5111_info; 326 struct ath5k_chan_pcal_info_rf5111 rf5111_info;
287 struct ath5k_chan_pcal_info_rf5112 rf5112_info; 327 struct ath5k_chan_pcal_info_rf5112 rf5112_info;
288 struct ath5k_chan_pcal_info_rf2413 rf2413_info; 328 struct ath5k_chan_pcal_info_rf2413 rf2413_info;
289 }; 329 };
330 /* Raw values used by phy code
331 * Curves are stored in order from lower
332 * gain to higher gain (max txpower -> min txpower) */
333 struct ath5k_pdgain_info *pd_curves;
290}; 334};
291 335
292/* Per rate calibration data for each mode, used for power table setup */ 336/* Per rate calibration data for each mode,
337 * used for rate power table setup.
338 * Note: Values in 0.5dB units */
293struct ath5k_rate_pcal_info { 339struct ath5k_rate_pcal_info {
294 u16 freq; /* Frequency */ 340 u16 freq; /* Frequency */
295 /* Power level for 6-24Mbit/s rates */ 341 /* Power level for 6-24Mbit/s rates or
342 * 1Mb rate */
296 u16 target_power_6to24; 343 u16 target_power_6to24;
297 /* Power level for 36Mbit rate */ 344 /* Power level for 36Mbit rate or
345 * 2Mb rate */
298 u16 target_power_36; 346 u16 target_power_36;
299 /* Power level for 48Mbit rate */ 347 /* Power level for 48Mbit rate or
348 * 5.5Mbit rate */
300 u16 target_power_48; 349 u16 target_power_48;
301 /* Power level for 54Mbit rate */ 350 /* Power level for 54Mbit rate or
351 * 11Mbit rate */
302 u16 target_power_54; 352 u16 target_power_54;
303}; 353};
304 354
@@ -330,12 +380,6 @@ struct ath5k_eeprom_info {
330 u16 ee_cck_ofdm_power_delta; 380 u16 ee_cck_ofdm_power_delta;
331 u16 ee_scaled_cck_delta; 381 u16 ee_scaled_cck_delta;
332 382
333 /* Used for tx thermal adjustment (eeprom_init, rfregs) */
334 u16 ee_tx_clip;
335 u16 ee_pwd_84;
336 u16 ee_pwd_90;
337 u16 ee_gain_select;
338
339 /* RF Calibration settings (reset, rfregs) */ 383 /* RF Calibration settings (reset, rfregs) */
340 u16 ee_i_cal[AR5K_EEPROM_N_MODES]; 384 u16 ee_i_cal[AR5K_EEPROM_N_MODES];
341 u16 ee_q_cal[AR5K_EEPROM_N_MODES]; 385 u16 ee_q_cal[AR5K_EEPROM_N_MODES];
@@ -363,23 +407,25 @@ struct ath5k_eeprom_info {
363 /* Power calibration data */ 407 /* Power calibration data */
364 u16 ee_false_detect[AR5K_EEPROM_N_MODES]; 408 u16 ee_false_detect[AR5K_EEPROM_N_MODES];
365 409
366 /* Number of pd gain curves per mode (RF2413) */ 410 /* Number of pd gain curves per mode */
367 u8 ee_pd_gains[AR5K_EEPROM_N_MODES]; 411 u8 ee_pd_gains[AR5K_EEPROM_N_MODES];
412 /* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */
413 u8 ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS];
368 414
369 u8 ee_n_piers[AR5K_EEPROM_N_MODES]; 415 u8 ee_n_piers[AR5K_EEPROM_N_MODES];
370 struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN]; 416 struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
371 struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN]; 417 struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
372 struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN]; 418 struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
373 419
374 /* Per rate target power levels */ 420 /* Per rate target power levels */
375 u16 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES]; 421 u8 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
376 struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN]; 422 struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
377 struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN]; 423 struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
378 struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN]; 424 struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
379 425
380 /* Conformance test limits (Unused) */ 426 /* Conformance test limits (Unused) */
381 u16 ee_ctls; 427 u8 ee_ctls;
382 u16 ee_ctl[AR5K_EEPROM_MAX_CTLS]; 428 u8 ee_ctl[AR5K_EEPROM_MAX_CTLS];
383 struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS]; 429 struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS];
384 430
385 /* Noise Floor Calibration settings */ 431 /* Noise Floor Calibration settings */
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
index 44886434187b..61fb621ed20d 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -1510,8 +1510,8 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1510 rf2425_ini_mode_end, mode); 1510 rf2425_ini_mode_end, mode);
1511 1511
1512 ath5k_hw_ini_registers(ah, 1512 ath5k_hw_ini_registers(ah,
1513 ARRAY_SIZE(rf2413_ini_common_end), 1513 ARRAY_SIZE(rf2425_ini_common_end),
1514 rf2413_ini_common_end, change_channel); 1514 rf2425_ini_common_end, change_channel);
1515 1515
1516 ath5k_hw_ini_registers(ah, 1516 ath5k_hw_ini_registers(ah,
1517 ARRAY_SIZE(rf5112_ini_bbgain), 1517 ARRAY_SIZE(rf5112_ini_bbgain),
diff --git a/drivers/net/wireless/ath5k/led.c b/drivers/net/wireless/ath5k/led.c
index 0686e12738b3..19555fb79c9b 100644
--- a/drivers/net/wireless/ath5k/led.c
+++ b/drivers/net/wireless/ath5k/led.c
@@ -65,6 +65,8 @@ static const struct pci_device_id ath5k_led_devices[] = {
65 { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) }, 65 { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
66 /* E-machines E510 (tuliom@gmail.com) */ 66 /* E-machines E510 (tuliom@gmail.com) */
67 { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) }, 67 { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
68 /* Acer Extensa 5620z (nekoreeve@gmail.com) */
69 { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
68 { } 70 { }
69}; 71};
70 72
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 81f5bebc48b1..9e2faae5ae94 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -4,6 +4,7 @@
4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> 4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com> 5 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> 6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
7 * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
7 * 8 *
8 * Permission to use, copy, modify, and distribute this software for any 9 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above 10 * purpose with or without fee is hereby granted, provided that the above
@@ -183,7 +184,9 @@ static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
183 if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE) 184 if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
184 return; 185 return;
185 186
186 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max, 187 /* Send the packet with 2dB below max power as
188 * patent doc suggest */
189 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
187 AR5K_PHY_PAPD_PROBE_TXPOWER) | 190 AR5K_PHY_PAPD_PROBE_TXPOWER) |
188 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); 191 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
189 192
@@ -1433,93 +1436,1120 @@ unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
1433 return false; /*XXX: What do we return for 5210 ?*/ 1436 return false; /*XXX: What do we return for 5210 ?*/
1434} 1437}
1435 1438
1439
1440/****************\
1441* TX power setup *
1442\****************/
1443
1444/*
1445 * Helper functions
1446 */
1447
1448/*
1449 * Do linear interpolation between two given (x, y) points
1450 */
1451static s16
1452ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
1453 s16 y_left, s16 y_right)
1454{
1455 s16 ratio, result;
1456
1457 /* Avoid divide by zero and skip interpolation
1458 * if we have the same point */
1459 if ((x_left == x_right) || (y_left == y_right))
1460 return y_left;
1461
1462 /*
1463 * Since we use ints and not fps, we need to scale up in
1464 * order to get a sane ratio value (or else we 'll eg. get
1465 * always 1 instead of 1.25, 1.75 etc). We scale up by 100
1466 * to have some accuracy both for 0.5 and 0.25 steps.
1467 */
1468 ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
1469
1470 /* Now scale down to be in range */
1471 result = y_left + (ratio * (target - x_left) / 100);
1472
1473 return result;
1474}
1475
1476/*
1477 * Find vertical boundary (min pwr) for the linear PCDAC curve.
1478 *
1479 * Since we have the top of the curve and we draw the line below
1480 * until we reach 1 (1 pcdac step) we need to know which point
1481 * (x value) that is so that we don't go below y axis and have negative
1482 * pcdac values when creating the curve, or fill the table with zeroes.
1483 */
1484static s16
1485ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
1486 const s16 *pwrL, const s16 *pwrR)
1487{
1488 s8 tmp;
1489 s16 min_pwrL, min_pwrR;
1490 s16 pwr_i = pwrL[0];
1491
1492 do {
1493 pwr_i--;
1494 tmp = (s8) ath5k_get_interpolated_value(pwr_i,
1495 pwrL[0], pwrL[1],
1496 stepL[0], stepL[1]);
1497
1498 } while (tmp > 1);
1499
1500 min_pwrL = pwr_i;
1501
1502 pwr_i = pwrR[0];
1503 do {
1504 pwr_i--;
1505 tmp = (s8) ath5k_get_interpolated_value(pwr_i,
1506 pwrR[0], pwrR[1],
1507 stepR[0], stepR[1]);
1508
1509 } while (tmp > 1);
1510
1511 min_pwrR = pwr_i;
1512
1513 /* Keep the right boundary so that it works for both curves */
1514 return max(min_pwrL, min_pwrR);
1515}
1516
1517/*
1518 * Interpolate (pwr,vpd) points to create a Power to PDADC or a
1519 * Power to PCDAC curve.
1520 *
1521 * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
1522 * steps (offsets) on y axis. Power can go up to 31.5dB and max
1523 * PCDAC/PDADC step for each curve is 64 but we can write more than
1524 * one curves on hw so we can go up to 128 (which is the max step we
1525 * can write on the final table).
1526 *
1527 * We write y values (PCDAC/PDADC steps) on hw.
1528 */
1529static void
1530ath5k_create_power_curve(s16 pmin, s16 pmax,
1531 const s16 *pwr, const u8 *vpd,
1532 u8 num_points,
1533 u8 *vpd_table, u8 type)
1534{
1535 u8 idx[2] = { 0, 1 };
1536 s16 pwr_i = 2*pmin;
1537 int i;
1538
1539 if (num_points < 2)
1540 return;
1541
1542 /* We want the whole line, so adjust boundaries
1543 * to cover the entire power range. Note that
1544 * power values are already 0.25dB so no need
1545 * to multiply pwr_i by 2 */
1546 if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
1547 pwr_i = pmin;
1548 pmin = 0;
1549 pmax = 63;
1550 }
1551
1552 /* Find surrounding turning points (TPs)
1553 * and interpolate between them */
1554 for (i = 0; (i <= (u16) (pmax - pmin)) &&
1555 (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
1556
1557 /* We passed the right TP, move to the next set of TPs
1558 * if we pass the last TP, extrapolate above using the last
1559 * two TPs for ratio */
1560 if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
1561 idx[0]++;
1562 idx[1]++;
1563 }
1564
1565 vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
1566 pwr[idx[0]], pwr[idx[1]],
1567 vpd[idx[0]], vpd[idx[1]]);
1568
1569 /* Increase by 0.5dB
1570 * (0.25 dB units) */
1571 pwr_i += 2;
1572 }
1573}
1574
1575/*
1576 * Get the surrounding per-channel power calibration piers
1577 * for a given frequency so that we can interpolate between
1578 * them and come up with an apropriate dataset for our current
1579 * channel.
1580 */
1581static void
1582ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
1583 struct ieee80211_channel *channel,
1584 struct ath5k_chan_pcal_info **pcinfo_l,
1585 struct ath5k_chan_pcal_info **pcinfo_r)
1586{
1587 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1588 struct ath5k_chan_pcal_info *pcinfo;
1589 u8 idx_l, idx_r;
1590 u8 mode, max, i;
1591 u32 target = channel->center_freq;
1592
1593 idx_l = 0;
1594 idx_r = 0;
1595
1596 if (!(channel->hw_value & CHANNEL_OFDM)) {
1597 pcinfo = ee->ee_pwr_cal_b;
1598 mode = AR5K_EEPROM_MODE_11B;
1599 } else if (channel->hw_value & CHANNEL_2GHZ) {
1600 pcinfo = ee->ee_pwr_cal_g;
1601 mode = AR5K_EEPROM_MODE_11G;
1602 } else {
1603 pcinfo = ee->ee_pwr_cal_a;
1604 mode = AR5K_EEPROM_MODE_11A;
1605 }
1606 max = ee->ee_n_piers[mode] - 1;
1607
1608 /* Frequency is below our calibrated
1609 * range. Use the lowest power curve
1610 * we have */
1611 if (target < pcinfo[0].freq) {
1612 idx_l = idx_r = 0;
1613 goto done;
1614 }
1615
1616 /* Frequency is above our calibrated
1617 * range. Use the highest power curve
1618 * we have */
1619 if (target > pcinfo[max].freq) {
1620 idx_l = idx_r = max;
1621 goto done;
1622 }
1623
1624 /* Frequency is inside our calibrated
1625 * channel range. Pick the surrounding
1626 * calibration piers so that we can
1627 * interpolate */
1628 for (i = 0; i <= max; i++) {
1629
1630 /* Frequency matches one of our calibration
1631 * piers, no need to interpolate, just use
1632 * that calibration pier */
1633 if (pcinfo[i].freq == target) {
1634 idx_l = idx_r = i;
1635 goto done;
1636 }
1637
1638 /* We found a calibration pier that's above
1639 * frequency, use this pier and the previous
1640 * one to interpolate */
1641 if (target < pcinfo[i].freq) {
1642 idx_r = i;
1643 idx_l = idx_r - 1;
1644 goto done;
1645 }
1646 }
1647
1648done:
1649 *pcinfo_l = &pcinfo[idx_l];
1650 *pcinfo_r = &pcinfo[idx_r];
1651
1652 return;
1653}
1654
1655/*
1656 * Get the surrounding per-rate power calibration data
1657 * for a given frequency and interpolate between power
1658 * values to set max target power supported by hw for
1659 * each rate.
1660 */
1661static void
1662ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
1663 struct ieee80211_channel *channel,
1664 struct ath5k_rate_pcal_info *rates)
1665{
1666 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1667 struct ath5k_rate_pcal_info *rpinfo;
1668 u8 idx_l, idx_r;
1669 u8 mode, max, i;
1670 u32 target = channel->center_freq;
1671
1672 idx_l = 0;
1673 idx_r = 0;
1674
1675 if (!(channel->hw_value & CHANNEL_OFDM)) {
1676 rpinfo = ee->ee_rate_tpwr_b;
1677 mode = AR5K_EEPROM_MODE_11B;
1678 } else if (channel->hw_value & CHANNEL_2GHZ) {
1679 rpinfo = ee->ee_rate_tpwr_g;
1680 mode = AR5K_EEPROM_MODE_11G;
1681 } else {
1682 rpinfo = ee->ee_rate_tpwr_a;
1683 mode = AR5K_EEPROM_MODE_11A;
1684 }
1685 max = ee->ee_rate_target_pwr_num[mode] - 1;
1686
1687 /* Get the surrounding calibration
1688 * piers - same as above */
1689 if (target < rpinfo[0].freq) {
1690 idx_l = idx_r = 0;
1691 goto done;
1692 }
1693
1694 if (target > rpinfo[max].freq) {
1695 idx_l = idx_r = max;
1696 goto done;
1697 }
1698
1699 for (i = 0; i <= max; i++) {
1700
1701 if (rpinfo[i].freq == target) {
1702 idx_l = idx_r = i;
1703 goto done;
1704 }
1705
1706 if (target < rpinfo[i].freq) {
1707 idx_r = i;
1708 idx_l = idx_r - 1;
1709 goto done;
1710 }
1711 }
1712
1713done:
1714 /* Now interpolate power value, based on the frequency */
1715 rates->freq = target;
1716
1717 rates->target_power_6to24 =
1718 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
1719 rpinfo[idx_r].freq,
1720 rpinfo[idx_l].target_power_6to24,
1721 rpinfo[idx_r].target_power_6to24);
1722
1723 rates->target_power_36 =
1724 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
1725 rpinfo[idx_r].freq,
1726 rpinfo[idx_l].target_power_36,
1727 rpinfo[idx_r].target_power_36);
1728
1729 rates->target_power_48 =
1730 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
1731 rpinfo[idx_r].freq,
1732 rpinfo[idx_l].target_power_48,
1733 rpinfo[idx_r].target_power_48);
1734
1735 rates->target_power_54 =
1736 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
1737 rpinfo[idx_r].freq,
1738 rpinfo[idx_l].target_power_54,
1739 rpinfo[idx_r].target_power_54);
1740}
1741
1742/*
1743 * Get the max edge power for this channel if
1744 * we have such data from EEPROM's Conformance Test
1745 * Limits (CTL), and limit max power if needed.
1746 *
1747 * FIXME: Only works for world regulatory domains
1748 */
1749static void
1750ath5k_get_max_ctl_power(struct ath5k_hw *ah,
1751 struct ieee80211_channel *channel)
1752{
1753 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1754 struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
1755 u8 *ctl_val = ee->ee_ctl;
1756 s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
1757 s16 edge_pwr = 0;
1758 u8 rep_idx;
1759 u8 i, ctl_mode;
1760 u8 ctl_idx = 0xFF;
1761 u32 target = channel->center_freq;
1762
1763 /* Find out a CTL for our mode that's not mapped
1764 * on a specific reg domain.
1765 *
1766 * TODO: Map our current reg domain to one of the 3 available
1767 * reg domain ids so that we can support more CTLs. */
1768 switch (channel->hw_value & CHANNEL_MODES) {
1769 case CHANNEL_A:
1770 ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
1771 break;
1772 case CHANNEL_G:
1773 ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
1774 break;
1775 case CHANNEL_B:
1776 ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
1777 break;
1778 case CHANNEL_T:
1779 ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN;
1780 break;
1781 case CHANNEL_TG:
1782 ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN;
1783 break;
1784 case CHANNEL_XR:
1785 /* Fall through */
1786 default:
1787 return;
1788 }
1789
1790 for (i = 0; i < ee->ee_ctls; i++) {
1791 if (ctl_val[i] == ctl_mode) {
1792 ctl_idx = i;
1793 break;
1794 }
1795 }
1796
1797 /* If we have a CTL dataset available grab it and find the
1798 * edge power for our frequency */
1799 if (ctl_idx == 0xFF)
1800 return;
1801
1802 /* Edge powers are sorted by frequency from lower
1803 * to higher. Each CTL corresponds to 8 edge power
1804 * measurements. */
1805 rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
1806
1807 /* Don't do boundaries check because we
1808 * might have more that one bands defined
1809 * for this mode */
1810
1811 /* Get the edge power that's closer to our
1812 * frequency */
1813 for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
1814 rep_idx += i;
1815 if (target <= rep[rep_idx].freq)
1816 edge_pwr = (s16) rep[rep_idx].edge;
1817 }
1818
1819 if (edge_pwr)
1820 ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
1821}
1822
1823
1824/*
1825 * Power to PCDAC table functions
1826 */
1827
1436/* 1828/*
1437 * TX power setup 1829 * Fill Power to PCDAC table on RF5111
1830 *
1831 * No further processing is needed for RF5111, the only thing we have to
1832 * do is fill the values below and above calibration range since eeprom data
1833 * may not cover the entire PCDAC table.
1438 */ 1834 */
1835static void
1836ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
1837 s16 *table_max)
1838{
1839 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
1840 u8 *pcdac_tmp = ah->ah_txpower.tmpL[0];
1841 u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
1842 s16 min_pwr, max_pwr;
1843
1844 /* Get table boundaries */
1845 min_pwr = table_min[0];
1846 pcdac_0 = pcdac_tmp[0];
1847
1848 max_pwr = table_max[0];
1849 pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
1850
1851 /* Extrapolate below minimum using pcdac_0 */
1852 pcdac_i = 0;
1853 for (i = 0; i < min_pwr; i++)
1854 pcdac_out[pcdac_i++] = pcdac_0;
1855
1856 /* Copy values from pcdac_tmp */
1857 pwr_idx = min_pwr;
1858 for (i = 0 ; pwr_idx <= max_pwr &&
1859 pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
1860 pcdac_out[pcdac_i++] = pcdac_tmp[i];
1861 pwr_idx++;
1862 }
1863
1864 /* Extrapolate above maximum */
1865 while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
1866 pcdac_out[pcdac_i++] = pcdac_n;
1867
1868}
1439 1869
1440/* 1870/*
1441 * Initialize the tx power table (not fully implemented) 1871 * Combine available XPD Curves and fill Linear Power to PCDAC table
1872 * on RF5112
1873 *
1874 * RFX112 can have up to 2 curves (one for low txpower range and one for
1875 * higher txpower range). We need to put them both on pcdac_out and place
1876 * them in the correct location. In case we only have one curve available
1877 * just fit it on pcdac_out (it's supposed to cover the entire range of
1878 * available pwr levels since it's always the higher power curve). Extrapolate
1879 * below and above final table if needed.
1442 */ 1880 */
1443static void ath5k_txpower_table(struct ath5k_hw *ah, 1881static void
1444 struct ieee80211_channel *channel, s16 max_power) 1882ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
1883 s16 *table_max, u8 pdcurves)
1445{ 1884{
1446 unsigned int i, min, max, n; 1885 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
1447 u16 txpower, *rates; 1886 u8 *pcdac_low_pwr;
1448 1887 u8 *pcdac_high_pwr;
1449 rates = ah->ah_txpower.txp_rates; 1888 u8 *pcdac_tmp;
1450 1889 u8 pwr;
1451 txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2; 1890 s16 max_pwr_idx;
1452 if (max_power > txpower) 1891 s16 min_pwr_idx;
1453 txpower = max_power > AR5K_TUNE_MAX_TXPOWER ? 1892 s16 mid_pwr_idx = 0;
1454 AR5K_TUNE_MAX_TXPOWER : max_power; 1893 /* Edge flag turs on the 7nth bit on the PCDAC
1455 1894 * to delcare the higher power curve (force values
1456 for (i = 0; i < AR5K_MAX_RATES; i++) 1895 * to be greater than 64). If we only have one curve
1457 rates[i] = txpower; 1896 * we don't need to set this, if we have 2 curves and
1458 1897 * fill the table backwards this can also be used to
1459 /* XXX setup target powers by rate */ 1898 * switch from higher power curve to lower power curve */
1460 1899 u8 edge_flag;
1461 ah->ah_txpower.txp_min = rates[7]; 1900 int i;
1462 ah->ah_txpower.txp_max = rates[0]; 1901
1463 ah->ah_txpower.txp_ofdm = rates[0]; 1902 /* When we have only one curve available
1464 1903 * that's the higher power curve. If we have
1465 /* Calculate the power table */ 1904 * two curves the first is the high power curve
1466 n = ARRAY_SIZE(ah->ah_txpower.txp_pcdac); 1905 * and the next is the low power curve. */
1467 min = AR5K_EEPROM_PCDAC_START; 1906 if (pdcurves > 1) {
1468 max = AR5K_EEPROM_PCDAC_STOP; 1907 pcdac_low_pwr = ah->ah_txpower.tmpL[1];
1469 for (i = 0; i < n; i += AR5K_EEPROM_PCDAC_STEP) 1908 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
1470 ah->ah_txpower.txp_pcdac[i] = 1909 mid_pwr_idx = table_max[1] - table_min[1] - 1;
1471#ifdef notyet 1910 max_pwr_idx = (table_max[0] - table_min[0]) / 2;
1472 min + ((i * (max - min)) / n); 1911
1473#else 1912 /* If table size goes beyond 31.5dB, keep the
1474 min; 1913 * upper 31.5dB range when setting tx power.
1914 * Note: 126 = 31.5 dB in quarter dB steps */
1915 if (table_max[0] - table_min[1] > 126)
1916 min_pwr_idx = table_max[0] - 126;
1917 else
1918 min_pwr_idx = table_min[1];
1919
1920 /* Since we fill table backwards
1921 * start from high power curve */
1922 pcdac_tmp = pcdac_high_pwr;
1923
1924 edge_flag = 0x40;
1925#if 0
1926 /* If both min and max power limits are in lower
1927 * power curve's range, only use the low power curve.
1928 * TODO: min/max levels are related to target
1929 * power values requested from driver/user
1930 * XXX: Is this really needed ? */
1931 if (min_pwr < table_max[1] &&
1932 max_pwr < table_max[1]) {
1933 edge_flag = 0;
1934 pcdac_tmp = pcdac_low_pwr;
1935 max_pwr_idx = (table_max[1] - table_min[1])/2;
1936 }
1475#endif 1937#endif
1938 } else {
1939 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
1940 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
1941 min_pwr_idx = table_min[0];
1942 max_pwr_idx = (table_max[0] - table_min[0]) / 2;
1943 pcdac_tmp = pcdac_high_pwr;
1944 edge_flag = 0;
1945 }
1946
1947 /* This is used when setting tx power*/
1948 ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
1949
1950 /* Fill Power to PCDAC table backwards */
1951 pwr = max_pwr_idx;
1952 for (i = 63; i >= 0; i--) {
1953 /* Entering lower power range, reset
1954 * edge flag and set pcdac_tmp to lower
1955 * power curve.*/
1956 if (edge_flag == 0x40 &&
1957 (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
1958 edge_flag = 0x00;
1959 pcdac_tmp = pcdac_low_pwr;
1960 pwr = mid_pwr_idx/2;
1961 }
1962
1963 /* Don't go below 1, extrapolate below if we have
1964 * already swithced to the lower power curve -or
1965 * we only have one curve and edge_flag is zero
1966 * anyway */
1967 if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
1968 while (i >= 0) {
1969 pcdac_out[i] = pcdac_out[i + 1];
1970 i--;
1971 }
1972 break;
1973 }
1974
1975 pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
1976
1977 /* Extrapolate above if pcdac is greater than
1978 * 126 -this can happen because we OR pcdac_out
1979 * value with edge_flag on high power curve */
1980 if (pcdac_out[i] > 126)
1981 pcdac_out[i] = 126;
1982
1983 /* Decrease by a 0.5dB step */
1984 pwr--;
1985 }
1476} 1986}
1477 1987
1988/* Write PCDAC values on hw */
1989static void
1990ath5k_setup_pcdac_table(struct ath5k_hw *ah)
1991{
1992 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
1993 int i;
1994
1995 /*
1996 * Write TX power values
1997 */
1998 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
1999 ath5k_hw_reg_write(ah,
2000 (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
2001 (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
2002 AR5K_PHY_PCDAC_TXPOWER(i));
2003 }
2004}
2005
2006
1478/* 2007/*
1479 * Set transmition power 2008 * Power to PDADC table functions
1480 */ 2009 */
1481int /*O.K. - txpower_table is unimplemented so this doesn't work*/ 2010
1482ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, 2011/*
1483 unsigned int txpower) 2012 * Set the gain boundaries and create final Power to PDADC table
2013 *
2014 * We can have up to 4 pd curves, we need to do a simmilar process
2015 * as we do for RF5112. This time we don't have an edge_flag but we
2016 * set the gain boundaries on a separate register.
2017 */
2018static void
2019ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
2020 s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
1484{ 2021{
1485 bool tpc = ah->ah_txpower.txp_tpc; 2022 u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
1486 unsigned int i; 2023 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
2024 u8 *pdadc_tmp;
2025 s16 pdadc_0;
2026 u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
2027 u8 pd_gain_overlap;
2028
2029 /* Note: Register value is initialized on initvals
2030 * there is no feedback from hw.
2031 * XXX: What about pd_gain_overlap from EEPROM ? */
2032 pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
2033 AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
2034
2035 /* Create final PDADC table */
2036 for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
2037 pdadc_tmp = ah->ah_txpower.tmpL[pdg];
2038
2039 if (pdg == pdcurves - 1)
2040 /* 2 dB boundary stretch for last
2041 * (higher power) curve */
2042 gain_boundaries[pdg] = pwr_max[pdg] + 4;
2043 else
2044 /* Set gain boundary in the middle
2045 * between this curve and the next one */
2046 gain_boundaries[pdg] =
2047 (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
2048
2049 /* Sanity check in case our 2 db stretch got out of
2050 * range. */
2051 if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
2052 gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
2053
2054 /* For the first curve (lower power)
2055 * start from 0 dB */
2056 if (pdg == 0)
2057 pdadc_0 = 0;
2058 else
2059 /* For the other curves use the gain overlap */
2060 pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
2061 pd_gain_overlap;
1487 2062
1488 ATH5K_TRACE(ah->ah_sc); 2063 /* Force each power step to be at least 0.5 dB */
1489 if (txpower > AR5K_TUNE_MAX_TXPOWER) { 2064 if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
1490 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); 2065 pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
1491 return -EINVAL; 2066 else
2067 pwr_step = 1;
2068
2069 /* If pdadc_0 is negative, we need to extrapolate
2070 * below this pdgain by a number of pwr_steps */
2071 while ((pdadc_0 < 0) && (pdadc_i < 128)) {
2072 s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
2073 pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
2074 pdadc_0++;
2075 }
2076
2077 /* Set last pwr level, using gain boundaries */
2078 pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
2079 /* Limit it to be inside pwr range */
2080 table_size = pwr_max[pdg] - pwr_min[pdg];
2081 max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
2082
2083 /* Fill pdadc_out table */
2084 while (pdadc_0 < max_idx)
2085 pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
2086
2087 /* Need to extrapolate above this pdgain? */
2088 if (pdadc_n <= max_idx)
2089 continue;
2090
2091 /* Force each power step to be at least 0.5 dB */
2092 if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
2093 pwr_step = pdadc_tmp[table_size - 1] -
2094 pdadc_tmp[table_size - 2];
2095 else
2096 pwr_step = 1;
2097
2098 /* Extrapolate above */
2099 while ((pdadc_0 < (s16) pdadc_n) &&
2100 (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
2101 s16 tmp = pdadc_tmp[table_size - 1] +
2102 (pdadc_0 - max_idx) * pwr_step;
2103 pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
2104 pdadc_0++;
2105 }
1492 } 2106 }
1493 2107
2108 while (pdg < AR5K_EEPROM_N_PD_GAINS) {
2109 gain_boundaries[pdg] = gain_boundaries[pdg - 1];
2110 pdg++;
2111 }
2112
2113 while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
2114 pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
2115 pdadc_i++;
2116 }
2117
2118 /* Set gain boundaries */
2119 ath5k_hw_reg_write(ah,
2120 AR5K_REG_SM(pd_gain_overlap,
2121 AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
2122 AR5K_REG_SM(gain_boundaries[0],
2123 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
2124 AR5K_REG_SM(gain_boundaries[1],
2125 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
2126 AR5K_REG_SM(gain_boundaries[2],
2127 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
2128 AR5K_REG_SM(gain_boundaries[3],
2129 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
2130 AR5K_PHY_TPC_RG5);
2131
2132 /* Used for setting rate power table */
2133 ah->ah_txpower.txp_min_idx = pwr_min[0];
2134
2135}
2136
2137/* Write PDADC values on hw */
2138static void
2139ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
2140 u8 pdcurves, u8 *pdg_to_idx)
2141{
2142 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
2143 u32 reg;
2144 u8 i;
2145
2146 /* Select the right pdgain curves */
2147
2148 /* Clear current settings */
2149 reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
2150 reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
2151 AR5K_PHY_TPC_RG1_PDGAIN_2 |
2152 AR5K_PHY_TPC_RG1_PDGAIN_3 |
2153 AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
2154
1494 /* 2155 /*
1495 * RF2413 for some reason can't 2156 * Use pd_gains curve from eeprom
1496 * transmit anything if we call
1497 * this funtion, so we skip it
1498 * until we fix txpower.
1499 * 2157 *
1500 * XXX: Assume same for RF2425 2158 * This overrides the default setting from initvals
1501 * to be safe. 2159 * in case some vendors (e.g. Zcomax) don't use the default
2160 * curves. If we don't honor their settings we 'll get a
2161 * 5dB (1 * gain overlap ?) drop.
1502 */ 2162 */
1503 if ((ah->ah_radio == AR5K_RF2413) || (ah->ah_radio == AR5K_RF2425)) 2163 reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
1504 return 0;
1505 2164
1506 /* Reset TX power values */ 2165 switch (pdcurves) {
1507 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); 2166 case 3:
1508 ah->ah_txpower.txp_tpc = tpc; 2167 reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
1509 2168 /* Fall through */
1510 /* Initialize TX power table */ 2169 case 2:
1511 ath5k_txpower_table(ah, channel, txpower); 2170 reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
2171 /* Fall through */
2172 case 1:
2173 reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
2174 break;
2175 }
2176 ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
1512 2177
1513 /* 2178 /*
1514 * Write TX power values 2179 * Write TX power values
1515 */ 2180 */
1516 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) { 2181 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
1517 ath5k_hw_reg_write(ah, 2182 ath5k_hw_reg_write(ah,
1518 ((((ah->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) & 0xffff) << 16) | 2183 ((pdadc_out[4*i + 0] & 0xff) << 0) |
1519 (((ah->ah_txpower.txp_pcdac[(i << 1) ] << 8) | 0xff) & 0xffff), 2184 ((pdadc_out[4*i + 1] & 0xff) << 8) |
1520 AR5K_PHY_PCDAC_TXPOWER(i)); 2185 ((pdadc_out[4*i + 2] & 0xff) << 16) |
2186 ((pdadc_out[4*i + 3] & 0xff) << 24),
2187 AR5K_PHY_PDADC_TXPOWER(i));
2188 }
2189}
2190
2191
2192/*
2193 * Common code for PCDAC/PDADC tables
2194 */
2195
2196/*
2197 * This is the main function that uses all of the above
2198 * to set PCDAC/PDADC table on hw for the current channel.
2199 * This table is used for tx power calibration on the basband,
2200 * without it we get weird tx power levels and in some cases
2201 * distorted spectral mask
2202 */
2203static int
2204ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2205 struct ieee80211_channel *channel,
2206 u8 ee_mode, u8 type)
2207{
2208 struct ath5k_pdgain_info *pdg_L, *pdg_R;
2209 struct ath5k_chan_pcal_info *pcinfo_L;
2210 struct ath5k_chan_pcal_info *pcinfo_R;
2211 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2212 u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
2213 s16 table_min[AR5K_EEPROM_N_PD_GAINS];
2214 s16 table_max[AR5K_EEPROM_N_PD_GAINS];
2215 u8 *tmpL;
2216 u8 *tmpR;
2217 u32 target = channel->center_freq;
2218 int pdg, i;
2219
2220 /* Get surounding freq piers for this channel */
2221 ath5k_get_chan_pcal_surrounding_piers(ah, channel,
2222 &pcinfo_L,
2223 &pcinfo_R);
2224
2225 /* Loop over pd gain curves on
2226 * surounding freq piers by index */
2227 for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
2228
2229 /* Fill curves in reverse order
2230 * from lower power (max gain)
2231 * to higher power. Use curve -> idx
2232 * backmaping we did on eeprom init */
2233 u8 idx = pdg_curve_to_idx[pdg];
2234
2235 /* Grab the needed curves by index */
2236 pdg_L = &pcinfo_L->pd_curves[idx];
2237 pdg_R = &pcinfo_R->pd_curves[idx];
2238
2239 /* Initialize the temp tables */
2240 tmpL = ah->ah_txpower.tmpL[pdg];
2241 tmpR = ah->ah_txpower.tmpR[pdg];
2242
2243 /* Set curve's x boundaries and create
2244 * curves so that they cover the same
2245 * range (if we don't do that one table
2246 * will have values on some range and the
2247 * other one won't have any so interpolation
2248 * will fail) */
2249 table_min[pdg] = min(pdg_L->pd_pwr[0],
2250 pdg_R->pd_pwr[0]) / 2;
2251
2252 table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
2253 pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
2254
2255 /* Now create the curves on surrounding channels
2256 * and interpolate if needed to get the final
2257 * curve for this gain on this channel */
2258 switch (type) {
2259 case AR5K_PWRTABLE_LINEAR_PCDAC:
2260 /* Override min/max so that we don't loose
2261 * accuracy (don't divide by 2) */
2262 table_min[pdg] = min(pdg_L->pd_pwr[0],
2263 pdg_R->pd_pwr[0]);
2264
2265 table_max[pdg] =
2266 max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
2267 pdg_R->pd_pwr[pdg_R->pd_points - 1]);
2268
2269 /* Override minimum so that we don't get
2270 * out of bounds while extrapolating
2271 * below. Don't do this when we have 2
2272 * curves and we are on the high power curve
2273 * because table_min is ok in this case */
2274 if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
2275
2276 table_min[pdg] =
2277 ath5k_get_linear_pcdac_min(pdg_L->pd_step,
2278 pdg_R->pd_step,
2279 pdg_L->pd_pwr,
2280 pdg_R->pd_pwr);
2281
2282 /* Don't go too low because we will
2283 * miss the upper part of the curve.
2284 * Note: 126 = 31.5dB (max power supported)
2285 * in 0.25dB units */
2286 if (table_max[pdg] - table_min[pdg] > 126)
2287 table_min[pdg] = table_max[pdg] - 126;
2288 }
2289
2290 /* Fall through */
2291 case AR5K_PWRTABLE_PWR_TO_PCDAC:
2292 case AR5K_PWRTABLE_PWR_TO_PDADC:
2293
2294 ath5k_create_power_curve(table_min[pdg],
2295 table_max[pdg],
2296 pdg_L->pd_pwr,
2297 pdg_L->pd_step,
2298 pdg_L->pd_points, tmpL, type);
2299
2300 /* We are in a calibration
2301 * pier, no need to interpolate
2302 * between freq piers */
2303 if (pcinfo_L == pcinfo_R)
2304 continue;
2305
2306 ath5k_create_power_curve(table_min[pdg],
2307 table_max[pdg],
2308 pdg_R->pd_pwr,
2309 pdg_R->pd_step,
2310 pdg_R->pd_points, tmpR, type);
2311 break;
2312 default:
2313 return -EINVAL;
2314 }
2315
2316 /* Interpolate between curves
2317 * of surounding freq piers to
2318 * get the final curve for this
2319 * pd gain. Re-use tmpL for interpolation
2320 * output */
2321 for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
2322 (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
2323 tmpL[i] = (u8) ath5k_get_interpolated_value(target,
2324 (s16) pcinfo_L->freq,
2325 (s16) pcinfo_R->freq,
2326 (s16) tmpL[i],
2327 (s16) tmpR[i]);
2328 }
1521 } 2329 }
1522 2330
2331 /* Now we have a set of curves for this
2332 * channel on tmpL (x range is table_max - table_min
2333 * and y values are tmpL[pdg][]) sorted in the same
2334 * order as EEPROM (because we've used the backmaping).
2335 * So for RF5112 it's from higher power to lower power
2336 * and for RF2413 it's from lower power to higher power.
2337 * For RF5111 we only have one curve. */
2338
2339 /* Fill min and max power levels for this
2340 * channel by interpolating the values on
2341 * surounding channels to complete the dataset */
2342 ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
2343 (s16) pcinfo_L->freq,
2344 (s16) pcinfo_R->freq,
2345 pcinfo_L->min_pwr, pcinfo_R->min_pwr);
2346
2347 ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
2348 (s16) pcinfo_L->freq,
2349 (s16) pcinfo_R->freq,
2350 pcinfo_L->max_pwr, pcinfo_R->max_pwr);
2351
2352 /* We are ready to go, fill PCDAC/PDADC
2353 * table and write settings on hardware */
2354 switch (type) {
2355 case AR5K_PWRTABLE_LINEAR_PCDAC:
2356 /* For RF5112 we can have one or two curves
2357 * and each curve covers a certain power lvl
2358 * range so we need to do some more processing */
2359 ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
2360 ee->ee_pd_gains[ee_mode]);
2361
2362 /* Set txp.offset so that we can
2363 * match max power value with max
2364 * table index */
2365 ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
2366
2367 /* Write settings on hw */
2368 ath5k_setup_pcdac_table(ah);
2369 break;
2370 case AR5K_PWRTABLE_PWR_TO_PCDAC:
2371 /* We are done for RF5111 since it has only
2372 * one curve, just fit the curve on the table */
2373 ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
2374
2375 /* No rate powertable adjustment for RF5111 */
2376 ah->ah_txpower.txp_min_idx = 0;
2377 ah->ah_txpower.txp_offset = 0;
2378
2379 /* Write settings on hw */
2380 ath5k_setup_pcdac_table(ah);
2381 break;
2382 case AR5K_PWRTABLE_PWR_TO_PDADC:
2383 /* Set PDADC boundaries and fill
2384 * final PDADC table */
2385 ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
2386 ee->ee_pd_gains[ee_mode]);
2387
2388 /* Write settings on hw */
2389 ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
2390
2391 /* Set txp.offset, note that table_min
2392 * can be negative */
2393 ah->ah_txpower.txp_offset = table_min[0];
2394 break;
2395 default:
2396 return -EINVAL;
2397 }
2398
2399 return 0;
2400}
2401
2402
2403/*
2404 * Per-rate tx power setting
2405 *
2406 * This is the code that sets the desired tx power (below
2407 * maximum) on hw for each rate (we also have TPC that sets
2408 * power per packet). We do that by providing an index on the
2409 * PCDAC/PDADC table we set up.
2410 */
2411
2412/*
2413 * Set rate power table
2414 *
2415 * For now we only limit txpower based on maximum tx power
2416 * supported by hw (what's inside rate_info). We need to limit
2417 * this even more, based on regulatory domain etc.
2418 *
2419 * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps)
2420 * and is indexed as follows:
2421 * rates[0] - rates[7] -> OFDM rates
2422 * rates[8] - rates[14] -> CCK rates
2423 * rates[15] -> XR rates (they all have the same power)
2424 */
2425static void
2426ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
2427 struct ath5k_rate_pcal_info *rate_info,
2428 u8 ee_mode)
2429{
2430 unsigned int i;
2431 u16 *rates;
2432
2433 /* max_pwr is power level we got from driver/user in 0.5dB
2434 * units, switch to 0.25dB units so we can compare */
2435 max_pwr *= 2;
2436 max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
2437
2438 /* apply rate limits */
2439 rates = ah->ah_txpower.txp_rates_power_table;
2440
2441 /* OFDM rates 6 to 24Mb/s */
2442 for (i = 0; i < 5; i++)
2443 rates[i] = min(max_pwr, rate_info->target_power_6to24);
2444
2445 /* Rest OFDM rates */
2446 rates[5] = min(rates[0], rate_info->target_power_36);
2447 rates[6] = min(rates[0], rate_info->target_power_48);
2448 rates[7] = min(rates[0], rate_info->target_power_54);
2449
2450 /* CCK rates */
2451 /* 1L */
2452 rates[8] = min(rates[0], rate_info->target_power_6to24);
2453 /* 2L */
2454 rates[9] = min(rates[0], rate_info->target_power_36);
2455 /* 2S */
2456 rates[10] = min(rates[0], rate_info->target_power_36);
2457 /* 5L */
2458 rates[11] = min(rates[0], rate_info->target_power_48);
2459 /* 5S */
2460 rates[12] = min(rates[0], rate_info->target_power_48);
2461 /* 11L */
2462 rates[13] = min(rates[0], rate_info->target_power_54);
2463 /* 11S */
2464 rates[14] = min(rates[0], rate_info->target_power_54);
2465
2466 /* XR rates */
2467 rates[15] = min(rates[0], rate_info->target_power_6to24);
2468
2469 /* CCK rates have different peak to average ratio
2470 * so we have to tweak their power so that gainf
2471 * correction works ok. For this we use OFDM to
2472 * CCK delta from eeprom */
2473 if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
2474 (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
2475 for (i = 8; i <= 15; i++)
2476 rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
2477
2478 ah->ah_txpower.txp_min_pwr = rates[7];
2479 ah->ah_txpower.txp_max_pwr = rates[0];
2480 ah->ah_txpower.txp_ofdm = rates[7];
2481}
2482
2483
2484/*
2485 * Set transmition power
2486 */
2487int
2488ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
2489 u8 ee_mode, u8 txpower)
2490{
2491 struct ath5k_rate_pcal_info rate_info;
2492 u8 type;
2493 int ret;
2494
2495 ATH5K_TRACE(ah->ah_sc);
2496 if (txpower > AR5K_TUNE_MAX_TXPOWER) {
2497 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
2498 return -EINVAL;
2499 }
2500 if (txpower == 0)
2501 txpower = AR5K_TUNE_DEFAULT_TXPOWER;
2502
2503 /* Reset TX power values */
2504 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
2505 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
2506 ah->ah_txpower.txp_min_pwr = 0;
2507 ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
2508
2509 /* Initialize TX power table */
2510 switch (ah->ah_radio) {
2511 case AR5K_RF5111:
2512 type = AR5K_PWRTABLE_PWR_TO_PCDAC;
2513 break;
2514 case AR5K_RF5112:
2515 type = AR5K_PWRTABLE_LINEAR_PCDAC;
2516 break;
2517 case AR5K_RF2413:
2518 case AR5K_RF5413:
2519 case AR5K_RF2316:
2520 case AR5K_RF2317:
2521 case AR5K_RF2425:
2522 type = AR5K_PWRTABLE_PWR_TO_PDADC;
2523 break;
2524 default:
2525 return -EINVAL;
2526 }
2527
2528 /* FIXME: Only on channel/mode change */
2529 ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
2530 if (ret)
2531 return ret;
2532
2533 /* Limit max power if we have a CTL available */
2534 ath5k_get_max_ctl_power(ah, channel);
2535
2536 /* FIXME: Tx power limit for this regdomain
2537 * XXX: Mac80211/CRDA will do that anyway ? */
2538
2539 /* FIXME: Antenna reduction stuff */
2540
2541 /* FIXME: Limit power on turbo modes */
2542
2543 /* FIXME: TPC scale reduction */
2544
2545 /* Get surounding channels for per-rate power table
2546 * calibration */
2547 ath5k_get_rate_pcal_data(ah, channel, &rate_info);
2548
2549 /* Setup rate power table */
2550 ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
2551
2552 /* Write rate power table on hw */
1523 ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) | 2553 ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
1524 AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) | 2554 AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
1525 AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1); 2555 AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
@@ -1536,26 +2566,34 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1536 AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) | 2566 AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
1537 AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4); 2567 AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
1538 2568
1539 if (ah->ah_txpower.txp_tpc) 2569 /* FIXME: TPC support */
2570 if (ah->ah_txpower.txp_tpc) {
1540 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE | 2571 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
1541 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); 2572 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
1542 else 2573
2574 ath5k_hw_reg_write(ah,
2575 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
2576 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
2577 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
2578 AR5K_TPC);
2579 } else {
1543 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX | 2580 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
1544 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); 2581 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
2582 }
1545 2583
1546 return 0; 2584 return 0;
1547} 2585}
1548 2586
1549int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power) 2587int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower)
1550{ 2588{
1551 /*Just a try M.F.*/ 2589 /*Just a try M.F.*/
1552 struct ieee80211_channel *channel = &ah->ah_current_channel; 2590 struct ieee80211_channel *channel = &ah->ah_current_channel;
1553 2591
1554 ATH5K_TRACE(ah->ah_sc); 2592 ATH5K_TRACE(ah->ah_sc);
1555 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, 2593 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
1556 "changing txpower to %d\n", power); 2594 "changing txpower to %d\n", txpower);
1557 2595
1558 return ath5k_hw_txpower(ah, channel, power); 2596 return ath5k_hw_txpower(ah, channel, mode, txpower);
1559} 2597}
1560 2598
1561#undef _ATH5K_PHY 2599#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 2dc008e10226..7070d1543cdc 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -1554,6 +1554,19 @@
1554/*===5212 Specific PCU registers===*/ 1554/*===5212 Specific PCU registers===*/
1555 1555
1556/* 1556/*
1557 * Transmit power control register
1558 */
1559#define AR5K_TPC 0x80e8
1560#define AR5K_TPC_ACK 0x0000003f /* ack frames */
1561#define AR5K_TPC_ACK_S 0
1562#define AR5K_TPC_CTS 0x00003f00 /* cts frames */
1563#define AR5K_TPC_CTS_S 8
1564#define AR5K_TPC_CHIRP 0x003f0000 /* chirp frames */
1565#define AR5K_TPC_CHIRP_S 16
1566#define AR5K_TPC_DOPPLER 0x0f000000 /* doppler chirp span */
1567#define AR5K_TPC_DOPPLER_S 24
1568
1569/*
1557 * XR (eXtended Range) mode register 1570 * XR (eXtended Range) mode register
1558 */ 1571 */
1559#define AR5K_XRMODE 0x80c0 /* Register Address */ 1572#define AR5K_XRMODE 0x80c0 /* Register Address */
@@ -2550,6 +2563,12 @@
2550#define AR5K_PHY_TPC_RG1 0xa258 2563#define AR5K_PHY_TPC_RG1 0xa258
2551#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000 2564#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000
2552#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14 2565#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14
2566#define AR5K_PHY_TPC_RG1_PDGAIN_1 0x00030000
2567#define AR5K_PHY_TPC_RG1_PDGAIN_1_S 16
2568#define AR5K_PHY_TPC_RG1_PDGAIN_2 0x000c0000
2569#define AR5K_PHY_TPC_RG1_PDGAIN_2_S 18
2570#define AR5K_PHY_TPC_RG1_PDGAIN_3 0x00300000
2571#define AR5K_PHY_TPC_RG1_PDGAIN_3_S 20
2553 2572
2554#define AR5K_PHY_TPC_RG5 0xa26C 2573#define AR5K_PHY_TPC_RG5 0xa26C
2555#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F 2574#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
index 685dc213edae..7a17d31b2fd9 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -664,29 +664,35 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
664 struct ieee80211_channel *channel, u8 *ant, u8 ee_mode) 664 struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
665{ 665{
666 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 666 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
667 s16 cck_ofdm_pwr_delta;
667 668
668 /* Set CCK to OFDM power delta */ 669 /* Adjust power delta for channel 14 */
669 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { 670 if (channel->center_freq == 2484)
670 int16_t cck_ofdm_pwr_delta; 671 cck_ofdm_pwr_delta =
671 672 ((ee->ee_cck_ofdm_power_delta -
672 /* Adjust power delta for channel 14 */ 673 ee->ee_scaled_cck_delta) * 2) / 10;
673 if (channel->center_freq == 2484) 674 else
674 cck_ofdm_pwr_delta = 675 cck_ofdm_pwr_delta =
675 ((ee->ee_cck_ofdm_power_delta - 676 (ee->ee_cck_ofdm_power_delta * 2) / 10;
676 ee->ee_scaled_cck_delta) * 2) / 10;
677 else
678 cck_ofdm_pwr_delta =
679 (ee->ee_cck_ofdm_power_delta * 2) / 10;
680 677
678 /* Set CCK to OFDM power delta on tx power
679 * adjustment register */
680 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
681 if (channel->hw_value == CHANNEL_G) 681 if (channel->hw_value == CHANNEL_G)
682 ath5k_hw_reg_write(ah, 682 ath5k_hw_reg_write(ah,
683 AR5K_REG_SM((ee->ee_cck_ofdm_power_delta * -1), 683 AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
684 AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) | 684 AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
685 AR5K_REG_SM((cck_ofdm_pwr_delta * -1), 685 AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
686 AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX), 686 AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
687 AR5K_PHY_TX_PWR_ADJ); 687 AR5K_PHY_TX_PWR_ADJ);
688 else 688 else
689 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ); 689 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
690 } else {
691 /* For older revs we scale power on sw during tx power
692 * setup */
693 ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
694 ah->ah_txpower.txp_cck_ofdm_gainf_delta =
695 ee->ee_cck_ofdm_gain_delta;
690 } 696 }
691 697
692 /* Set antenna idle switch table */ 698 /* Set antenna idle switch table */
@@ -994,7 +1000,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
994 /* 1000 /*
995 * Set TX power (FIXME) 1001 * Set TX power (FIXME)
996 */ 1002 */
997 ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER); 1003 ret = ath5k_hw_txpower(ah, channel, ee_mode,
1004 AR5K_TUNE_DEFAULT_TXPOWER);
998 if (ret) 1005 if (ret)
999 return ret; 1006 return ret;
1000 1007
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c
index 00cc7bb01f2e..0e65c51ba176 100644
--- a/drivers/net/wireless/ath9k/ahb.c
+++ b/drivers/net/wireless/ath9k/ahb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> 3 * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
4 * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> 4 * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
5 * 5 *
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c
index a39eb760cbb7..6c5e887d50d7 100644
--- a/drivers/net/wireless/ath9k/ani.c
+++ b/drivers/net/wireless/ath9k/ani.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath9k/ani.h
index 7315761f6d74..08b4e7ed5ff0 100644
--- a/drivers/net/wireless/ath9k/ani.h
+++ b/drivers/net/wireless/ath9k/ani.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index b64be8e9a690..2689a08a2844 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -295,13 +295,9 @@ struct ath_tx_control {
295 enum ath9k_internal_frame_type frame_type; 295 enum ath9k_internal_frame_type frame_type;
296}; 296};
297 297
298struct ath_xmit_status {
299 int retries;
300 int flags;
301#define ATH_TX_ERROR 0x01 298#define ATH_TX_ERROR 0x01
302#define ATH_TX_XRETRY 0x02 299#define ATH_TX_XRETRY 0x02
303#define ATH_TX_BAR 0x04 300#define ATH_TX_BAR 0x04
304};
305 301
306/* All RSSI values are noise floor adjusted */ 302/* All RSSI values are noise floor adjusted */
307struct ath_tx_stat { 303struct ath_tx_stat {
@@ -390,6 +386,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
390 386
391struct ath_vif { 387struct ath_vif {
392 int av_bslot; 388 int av_bslot;
389 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
393 enum nl80211_iftype av_opmode; 390 enum nl80211_iftype av_opmode;
394 struct ath_buf *av_bcbuf; 391 struct ath_buf *av_bcbuf;
395 struct ath_tx_control av_btxctl; 392 struct ath_tx_control av_btxctl;
@@ -406,7 +403,7 @@ struct ath_vif {
406 * number of beacon intervals, the game's up. 403 * number of beacon intervals, the game's up.
407 */ 404 */
408#define BSTUCK_THRESH (9 * ATH_BCBUF) 405#define BSTUCK_THRESH (9 * ATH_BCBUF)
409#define ATH_BCBUF 1 406#define ATH_BCBUF 4
410#define ATH_DEFAULT_BINTVAL 100 /* TU */ 407#define ATH_DEFAULT_BINTVAL 100 /* TU */
411#define ATH_DEFAULT_BMISS_LIMIT 10 408#define ATH_DEFAULT_BMISS_LIMIT 10
412#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) 409#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 039c78136c50..ec995730632d 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -70,7 +70,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
70 ds = bf->bf_desc; 70 ds = bf->bf_desc;
71 flags = ATH9K_TXDESC_NOACK; 71 flags = ATH9K_TXDESC_NOACK;
72 72
73 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC && 73 if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
74 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
74 (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { 75 (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
75 ds->ds_link = bf->bf_daddr; /* self-linked */ 76 ds->ds_link = bf->bf_daddr; /* self-linked */
76 flags |= ATH9K_TXDESC_VEOL; 77 flags |= ATH9K_TXDESC_VEOL;
@@ -153,6 +154,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
153 bf->bf_mpdu = skb; 154 bf->bf_mpdu = skb;
154 if (skb == NULL) 155 if (skb == NULL)
155 return NULL; 156 return NULL;
157 ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
158 avp->tsf_adjust;
156 159
157 info = IEEE80211_SKB_CB(skb); 160 info = IEEE80211_SKB_CB(skb);
158 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 161 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -253,7 +256,6 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
253{ 256{
254 struct ath_softc *sc = aphy->sc; 257 struct ath_softc *sc = aphy->sc;
255 struct ath_vif *avp; 258 struct ath_vif *avp;
256 struct ieee80211_hdr *hdr;
257 struct ath_buf *bf; 259 struct ath_buf *bf;
258 struct sk_buff *skb; 260 struct sk_buff *skb;
259 __le64 tstamp; 261 __le64 tstamp;
@@ -316,42 +318,33 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
316 318
317 tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; 319 tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
318 sc->beacon.bc_tstamp = le64_to_cpu(tstamp); 320 sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
319 321 /* Calculate a TSF adjustment factor required for staggered beacons. */
320 /*
321 * Calculate a TSF adjustment factor required for
322 * staggered beacons. Note that we assume the format
323 * of the beacon frame leaves the tstamp field immediately
324 * following the header.
325 */
326 if (avp->av_bslot > 0) { 322 if (avp->av_bslot > 0) {
327 u64 tsfadjust; 323 u64 tsfadjust;
328 __le64 val;
329 int intval; 324 int intval;
330 325
331 intval = sc->hw->conf.beacon_int ? 326 intval = sc->hw->conf.beacon_int ?
332 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; 327 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
333 328
334 /* 329 /*
335 * The beacon interval is in TU's; the TSF in usecs. 330 * Calculate the TSF offset for this beacon slot, i.e., the
336 * We figure out how many TU's to add to align the 331 * number of usecs that need to be added to the timestamp field
337 * timestamp then convert to TSF units and handle 332 * in Beacon and Probe Response frames. Beacon slot 0 is
338 * byte swapping before writing it in the frame. 333 * processed at the correct offset, so it does not require TSF
339 * The hardware will then add this each time a beacon 334 * adjustment. Other slots are adjusted to get the timestamp
340 * frame is sent. Note that we align vif's 1..N 335 * close to the TBTT for the BSS.
341 * and leave vif 0 untouched. This means vap 0
342 * has a timestamp in one beacon interval while the
343 * others get a timestamp aligned to the next interval.
344 */ 336 */
345 tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF; 337 tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
346 val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */ 338 avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
347 339
348 DPRINTF(sc, ATH_DBG_BEACON, 340 DPRINTF(sc, ATH_DBG_BEACON,
349 "stagger beacons, bslot %d intval %u tsfadjust %llu\n", 341 "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
350 avp->av_bslot, intval, (unsigned long long)tsfadjust); 342 avp->av_bslot, intval, (unsigned long long)tsfadjust);
351 343
352 hdr = (struct ieee80211_hdr *)skb->data; 344 ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
353 memcpy(&hdr[1], &val, sizeof(val)); 345 avp->tsf_adjust;
354 } 346 } else
347 avp->tsf_adjust = cpu_to_le64(0);
355 348
356 bf->bf_mpdu = skb; 349 bf->bf_mpdu = skb;
357 bf->bf_buf_addr = bf->bf_dmacontext = 350 bf->bf_buf_addr = bf->bf_dmacontext =
@@ -447,8 +440,16 @@ void ath_beacon_tasklet(unsigned long data)
447 tsf = ath9k_hw_gettsf64(ah); 440 tsf = ath9k_hw_gettsf64(ah);
448 tsftu = TSF_TO_TU(tsf>>32, tsf); 441 tsftu = TSF_TO_TU(tsf>>32, tsf);
449 slot = ((tsftu % intval) * ATH_BCBUF) / intval; 442 slot = ((tsftu % intval) * ATH_BCBUF) / intval;
450 vif = sc->beacon.bslot[(slot + 1) % ATH_BCBUF]; 443 /*
451 aphy = sc->beacon.bslot_aphy[(slot + 1) % ATH_BCBUF]; 444 * Reverse the slot order to get slot 0 on the TBTT offset that does
445 * not require TSF adjustment and other slots adding
446 * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
447 * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
448 * and slot 0 is at correct offset to TBTT.
449 */
450 slot = ATH_BCBUF - slot - 1;
451 vif = sc->beacon.bslot[slot];
452 aphy = sc->beacon.bslot_aphy[slot];
452 453
453 DPRINTF(sc, ATH_DBG_BEACON, 454 DPRINTF(sc, ATH_DBG_BEACON,
454 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", 455 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
@@ -728,6 +729,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
728 ath_beacon_config_ap(sc, &conf, avp); 729 ath_beacon_config_ap(sc, &conf, avp);
729 break; 730 break;
730 case NL80211_IFTYPE_ADHOC: 731 case NL80211_IFTYPE_ADHOC:
732 case NL80211_IFTYPE_MESH_POINT:
731 ath_beacon_config_adhoc(sc, &conf, avp, vif); 733 ath_beacon_config_adhoc(sc, &conf, avp, vif);
732 break; 734 break;
733 case NL80211_IFTYPE_STATION: 735 case NL80211_IFTYPE_STATION:
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
index c9446fb6b153..e2d62e97131c 100644
--- a/drivers/net/wireless/ath9k/calib.c
+++ b/drivers/net/wireless/ath9k/calib.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath9k/calib.h
index 32589e0c5018..1c74bd50700d 100644
--- a/drivers/net/wireless/ath9k/calib.h
+++ b/drivers/net/wireless/ath9k/calib.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c
index 82573cadb1ab..fdf9528fa49b 100644
--- a/drivers/net/wireless/ath9k/debug.c
+++ b/drivers/net/wireless/ath9k/debug.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath9k/debug.h
index 065268b8568f..7b0e5419d2bc 100644
--- a/drivers/net/wireless/ath9k/debug.h
+++ b/drivers/net/wireless/ath9k/debug.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
index 183c949bcca1..ffc36b0361c7 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath9k/eeprom.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -342,8 +342,7 @@ static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
342static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) 342static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
343{ 343{
344#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 344#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
345 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 345 u16 *eep_data = (u16 *)&ah->eeprom.map4k;
346 u16 *eep_data;
347 int addr, eep_start_loc = 0; 346 int addr, eep_start_loc = 0;
348 347
349 eep_start_loc = 64; 348 eep_start_loc = 64;
@@ -353,8 +352,6 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
353 "Reading from EEPROM, not flash\n"); 352 "Reading from EEPROM, not flash\n");
354 } 353 }
355 354
356 eep_data = (u16 *)eep;
357
358 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { 355 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
359 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) { 356 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
360 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 357 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
@@ -363,6 +360,7 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
363 } 360 }
364 eep_data++; 361 eep_data++;
365 } 362 }
363
366 return true; 364 return true;
367#undef SIZE_EEPROM_4K 365#undef SIZE_EEPROM_4K
368} 366}
@@ -379,16 +377,15 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
379 377
380 378
381 if (!ath9k_hw_use_flash(ah)) { 379 if (!ath9k_hw_use_flash(ah)) {
382
383 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, 380 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
384 &magic)) { 381 &magic)) {
385 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 382 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
386 "Reading Magic # failed\n"); 383 "Reading Magic # failed\n");
387 return false; 384 return false;
388 } 385 }
389 386
390 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 387 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
391 "Read Magic = 0x%04X\n", magic); 388 "Read Magic = 0x%04X\n", magic);
392 389
393 if (magic != AR5416_EEPROM_MAGIC) { 390 if (magic != AR5416_EEPROM_MAGIC) {
394 magic2 = swab16(magic); 391 magic2 = swab16(magic);
@@ -401,16 +398,9 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
401 temp = swab16(*eepdata); 398 temp = swab16(*eepdata);
402 *eepdata = temp; 399 *eepdata = temp;
403 eepdata++; 400 eepdata++;
404
405 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
406 "0x%04X ", *eepdata);
407
408 if (((addr + 1) % 6) == 0)
409 DPRINTF(ah->ah_sc,
410 ATH_DBG_EEPROM, "\n");
411 } 401 }
412 } else { 402 } else {
413 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 403 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
414 "Invalid EEPROM Magic. " 404 "Invalid EEPROM Magic. "
415 "endianness mismatch.\n"); 405 "endianness mismatch.\n");
416 return -EINVAL; 406 return -EINVAL;
@@ -426,7 +416,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
426 else 416 else
427 el = ah->eeprom.map4k.baseEepHeader.length; 417 el = ah->eeprom.map4k.baseEepHeader.length;
428 418
429 if (el > sizeof(struct ar5416_eeprom_def)) 419 if (el > sizeof(struct ar5416_eeprom_4k))
430 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16); 420 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
431 else 421 else
432 el = el / sizeof(u16); 422 el = el / sizeof(u16);
@@ -441,7 +431,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
441 u16 word; 431 u16 word;
442 432
443 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 433 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
444 "EEPROM Endianness is not native.. Changing \n"); 434 "EEPROM Endianness is not native.. Changing\n");
445 435
446 word = swab16(eep->baseEepHeader.length); 436 word = swab16(eep->baseEepHeader.length);
447 eep->baseEepHeader.length = word; 437 eep->baseEepHeader.length = word;
@@ -483,7 +473,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
483 473
484 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || 474 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
485 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 475 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
486 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 476 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
487 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 477 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
488 sum, ah->eep_ops->get_eeprom_ver(ah)); 478 sum, ah->eep_ops->get_eeprom_ver(ah));
489 return -EINVAL; 479 return -EINVAL;
@@ -1203,57 +1193,63 @@ static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
1203 } 1193 }
1204} 1194}
1205 1195
1206static bool ath9k_hw_4k_set_board_values(struct ath_hw *ah, 1196static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
1207 struct ath9k_channel *chan) 1197 struct modal_eep_4k_header *pModal,
1198 struct ar5416_eeprom_4k *eep,
1199 u8 txRxAttenLocal, int regChainOffset)
1208{ 1200{
1209 struct modal_eep_4k_header *pModal;
1210 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1211 int regChainOffset;
1212 u8 txRxAttenLocal;
1213 u8 ob[5], db1[5], db2[5];
1214 u8 ant_div_control1, ant_div_control2;
1215 u32 regVal;
1216
1217
1218 pModal = &eep->modalHeader;
1219
1220 txRxAttenLocal = 23;
1221
1222 REG_WRITE(ah, AR_PHY_SWITCH_COM,
1223 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
1224
1225 regChainOffset = 0;
1226 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, 1201 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
1227 pModal->antCtrlChain[0]); 1202 pModal->antCtrlChain[0]);
1228 1203
1229 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1204 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
1230 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & 1205 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
1231 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1206 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
1232 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1207 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1233 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1208 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
1234 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1209 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1235 1210
1236 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1211 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1237 AR5416_EEP_MINOR_VER_3) { 1212 AR5416_EEP_MINOR_VER_3) {
1238 txRxAttenLocal = pModal->txRxAttenCh[0]; 1213 txRxAttenLocal = pModal->txRxAttenCh[0];
1214
1239 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1215 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1240 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]); 1216 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
1241 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1217 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1242 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 1218 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
1243 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1219 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1244 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 1220 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1245 pModal->xatten2Margin[0]); 1221 pModal->xatten2Margin[0]);
1246 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1222 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1247 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); 1223 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
1248 } 1224 }
1249 1225
1250 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1226 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1251 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1227 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1252 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1228 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1253 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 1229 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
1254 1230
1255 if (AR_SREV_9285_11(ah)) 1231 if (AR_SREV_9285_11(ah))
1256 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); 1232 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
1233}
1234
1235static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1236 struct ath9k_channel *chan)
1237{
1238 struct modal_eep_4k_header *pModal;
1239 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1240 u8 txRxAttenLocal;
1241 u8 ob[5], db1[5], db2[5];
1242 u8 ant_div_control1, ant_div_control2;
1243 u32 regVal;
1244
1245 pModal = &eep->modalHeader;
1246 txRxAttenLocal = 23;
1247
1248 REG_WRITE(ah, AR_PHY_SWITCH_COM,
1249 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
1250
1251 /* Single chain for 4K EEPROM*/
1252 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
1257 1253
1258 /* Initialize Ant Diversity settings from EEPROM */ 1254 /* Initialize Ant Diversity settings from EEPROM */
1259 if (pModal->version == 3) { 1255 if (pModal->version == 3) {
@@ -1295,9 +1291,6 @@ static bool ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1295 db2[4] = ((pModal->db2_234 >> 8) & 0xf); 1291 db2[4] = ((pModal->db2_234 >> 8) & 0xf);
1296 1292
1297 } else if (pModal->version == 1) { 1293 } else if (pModal->version == 1) {
1298
1299 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1300 "EEPROM Model version is set to 1 \n");
1301 ob[0] = (pModal->ob_01 & 0xf); 1294 ob[0] = (pModal->ob_01 & 0xf);
1302 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf; 1295 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
1303 db1[0] = (pModal->db1_01 & 0xf); 1296 db1[0] = (pModal->db1_01 & 0xf);
@@ -1385,8 +1378,6 @@ static bool ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1385 AR_PHY_SETTLING_SWITCH, 1378 AR_PHY_SETTLING_SWITCH,
1386 pModal->swSettleHt40); 1379 pModal->swSettleHt40);
1387 } 1380 }
1388
1389 return true;
1390} 1381}
1391 1382
1392static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, 1383static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
@@ -1464,16 +1455,13 @@ static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
1464static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) 1455static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
1465{ 1456{
1466#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) 1457#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
1467 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1458 u16 *eep_data = (u16 *)&ah->eeprom.def;
1468 u16 *eep_data;
1469 int addr, ar5416_eep_start_loc = 0x100; 1459 int addr, ar5416_eep_start_loc = 0x100;
1470 1460
1471 eep_data = (u16 *)eep;
1472
1473 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { 1461 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
1474 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, 1462 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
1475 eep_data)) { 1463 eep_data)) {
1476 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1464 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
1477 "Unable to read eeprom region\n"); 1465 "Unable to read eeprom region\n");
1478 return false; 1466 return false;
1479 } 1467 }
@@ -1492,17 +1480,14 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
1492 bool need_swap = false; 1480 bool need_swap = false;
1493 int i, addr, size; 1481 int i, addr, size;
1494 1482
1495 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, 1483 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
1496 &magic)) { 1484 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
1497 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1498 "Reading Magic # failed\n");
1499 return false; 1485 return false;
1500 } 1486 }
1501 1487
1502 if (!ath9k_hw_use_flash(ah)) { 1488 if (!ath9k_hw_use_flash(ah)) {
1503
1504 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1489 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1505 "Read Magic = 0x%04X\n", magic); 1490 "Read Magic = 0x%04X\n", magic);
1506 1491
1507 if (magic != AR5416_EEPROM_MAGIC) { 1492 if (magic != AR5416_EEPROM_MAGIC) {
1508 magic2 = swab16(magic); 1493 magic2 = swab16(magic);
@@ -1516,18 +1501,11 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
1516 temp = swab16(*eepdata); 1501 temp = swab16(*eepdata);
1517 *eepdata = temp; 1502 *eepdata = temp;
1518 eepdata++; 1503 eepdata++;
1519
1520 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1521 "0x%04X ", *eepdata);
1522
1523 if (((addr + 1) % 6) == 0)
1524 DPRINTF(ah->ah_sc,
1525 ATH_DBG_EEPROM, "\n");
1526 } 1504 }
1527 } else { 1505 } else {
1528 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1506 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
1529 "Invalid EEPROM Magic. " 1507 "Invalid EEPROM Magic. "
1530 "endianness mismatch.\n"); 1508 "Endianness mismatch.\n");
1531 return -EINVAL; 1509 return -EINVAL;
1532 } 1510 }
1533 } 1511 }
@@ -1556,7 +1534,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
1556 u16 word; 1534 u16 word;
1557 1535
1558 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1536 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1559 "EEPROM Endianness is not native.. Changing \n"); 1537 "EEPROM Endianness is not native.. Changing.\n");
1560 1538
1561 word = swab16(eep->baseEepHeader.length); 1539 word = swab16(eep->baseEepHeader.length);
1562 eep->baseEepHeader.length = word; 1540 eep->baseEepHeader.length = word;
@@ -1602,7 +1580,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
1602 1580
1603 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || 1581 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
1604 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 1582 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
1605 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1583 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
1606 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 1584 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
1607 sum, ah->eep_ops->get_eeprom_ver(ah)); 1585 sum, ah->eep_ops->get_eeprom_ver(ah));
1608 return -EINVAL; 1586 return -EINVAL;
@@ -1614,7 +1592,6 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
1614static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, 1592static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
1615 enum eeprom_param param) 1593 enum eeprom_param param)
1616{ 1594{
1617#define AR5416_VER_MASK (pBase->version & AR5416_EEP_VER_MINOR_MASK)
1618 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1595 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1619 struct modal_eep_header *pModal = eep->modalHeader; 1596 struct modal_eep_header *pModal = eep->modalHeader;
1620 struct base_eep_header *pBase = &eep->baseEepHeader; 1597 struct base_eep_header *pBase = &eep->baseEepHeader;
@@ -1681,21 +1658,73 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
1681 default: 1658 default:
1682 return 0; 1659 return 0;
1683 } 1660 }
1684#undef AR5416_VER_MASK
1685} 1661}
1686 1662
1687/* XXX: Clean me up, make me more legible */ 1663static void ath9k_hw_def_set_gain(struct ath_hw *ah,
1688static bool ath9k_hw_def_set_board_values(struct ath_hw *ah, 1664 struct modal_eep_header *pModal,
1665 struct ar5416_eeprom_def *eep,
1666 u8 txRxAttenLocal, int regChainOffset, int i)
1667{
1668 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
1669 txRxAttenLocal = pModal->txRxAttenCh[i];
1670
1671 if (AR_SREV_9280_10_OR_LATER(ah)) {
1672 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1673 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
1674 pModal->bswMargin[i]);
1675 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1676 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
1677 pModal->bswAtten[i]);
1678 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1679 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1680 pModal->xatten2Margin[i]);
1681 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1682 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
1683 pModal->xatten2Db[i]);
1684 } else {
1685 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1686 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
1687 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
1688 | SM(pModal-> bswMargin[i],
1689 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
1690 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1691 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
1692 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
1693 | SM(pModal->bswAtten[i],
1694 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
1695 }
1696 }
1697
1698 if (AR_SREV_9280_10_OR_LATER(ah)) {
1699 REG_RMW_FIELD(ah,
1700 AR_PHY_RXGAIN + regChainOffset,
1701 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1702 REG_RMW_FIELD(ah,
1703 AR_PHY_RXGAIN + regChainOffset,
1704 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
1705 } else {
1706 REG_WRITE(ah,
1707 AR_PHY_RXGAIN + regChainOffset,
1708 (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
1709 ~AR_PHY_RXGAIN_TXRX_ATTEN)
1710 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
1711 REG_WRITE(ah,
1712 AR_PHY_GAIN_2GHZ + regChainOffset,
1713 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
1714 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
1715 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
1716 }
1717}
1718
1719static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
1689 struct ath9k_channel *chan) 1720 struct ath9k_channel *chan)
1690{ 1721{
1691#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
1692 struct modal_eep_header *pModal; 1722 struct modal_eep_header *pModal;
1693 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1723 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1694 int i, regChainOffset; 1724 int i, regChainOffset;
1695 u8 txRxAttenLocal; 1725 u8 txRxAttenLocal;
1696 1726
1697 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1727 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
1698
1699 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; 1728 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
1700 1729
1701 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1730 REG_WRITE(ah, AR_PHY_SWITCH_COM,
@@ -1708,8 +1737,7 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
1708 } 1737 }
1709 1738
1710 if (AR_SREV_5416_20_OR_LATER(ah) && 1739 if (AR_SREV_5416_20_OR_LATER(ah) &&
1711 (ah->rxchainmask == 5 || ah->txchainmask == 5) 1740 (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
1712 && (i != 0))
1713 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1741 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
1714 else 1742 else
1715 regChainOffset = i * 0x1000; 1743 regChainOffset = i * 0x1000;
@@ -1718,9 +1746,7 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
1718 pModal->antCtrlChain[i]); 1746 pModal->antCtrlChain[i]);
1719 1747
1720 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1748 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
1721 (REG_READ(ah, 1749 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
1722 AR_PHY_TIMING_CTRL4(0) +
1723 regChainOffset) &
1724 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1750 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
1725 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1751 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1726 SM(pModal->iqCalICh[i], 1752 SM(pModal->iqCalICh[i],
@@ -1728,87 +1754,9 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
1728 SM(pModal->iqCalQCh[i], 1754 SM(pModal->iqCalQCh[i],
1729 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1755 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1730 1756
1731 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { 1757 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
1732 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { 1758 ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
1733 txRxAttenLocal = pModal->txRxAttenCh[i]; 1759 regChainOffset, i);
1734 if (AR_SREV_9280_10_OR_LATER(ah)) {
1735 REG_RMW_FIELD(ah,
1736 AR_PHY_GAIN_2GHZ +
1737 regChainOffset,
1738 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
1739 pModal->
1740 bswMargin[i]);
1741 REG_RMW_FIELD(ah,
1742 AR_PHY_GAIN_2GHZ +
1743 regChainOffset,
1744 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
1745 pModal->
1746 bswAtten[i]);
1747 REG_RMW_FIELD(ah,
1748 AR_PHY_GAIN_2GHZ +
1749 regChainOffset,
1750 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1751 pModal->
1752 xatten2Margin[i]);
1753 REG_RMW_FIELD(ah,
1754 AR_PHY_GAIN_2GHZ +
1755 regChainOffset,
1756 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
1757 pModal->
1758 xatten2Db[i]);
1759 } else {
1760 REG_WRITE(ah,
1761 AR_PHY_GAIN_2GHZ +
1762 regChainOffset,
1763 (REG_READ(ah,
1764 AR_PHY_GAIN_2GHZ +
1765 regChainOffset) &
1766 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
1767 | SM(pModal->
1768 bswMargin[i],
1769 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
1770 REG_WRITE(ah,
1771 AR_PHY_GAIN_2GHZ +
1772 regChainOffset,
1773 (REG_READ(ah,
1774 AR_PHY_GAIN_2GHZ +
1775 regChainOffset) &
1776 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
1777 | SM(pModal->bswAtten[i],
1778 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
1779 }
1780 }
1781 if (AR_SREV_9280_10_OR_LATER(ah)) {
1782 REG_RMW_FIELD(ah,
1783 AR_PHY_RXGAIN +
1784 regChainOffset,
1785 AR9280_PHY_RXGAIN_TXRX_ATTEN,
1786 txRxAttenLocal);
1787 REG_RMW_FIELD(ah,
1788 AR_PHY_RXGAIN +
1789 regChainOffset,
1790 AR9280_PHY_RXGAIN_TXRX_MARGIN,
1791 pModal->rxTxMarginCh[i]);
1792 } else {
1793 REG_WRITE(ah,
1794 AR_PHY_RXGAIN + regChainOffset,
1795 (REG_READ(ah,
1796 AR_PHY_RXGAIN +
1797 regChainOffset) &
1798 ~AR_PHY_RXGAIN_TXRX_ATTEN) |
1799 SM(txRxAttenLocal,
1800 AR_PHY_RXGAIN_TXRX_ATTEN));
1801 REG_WRITE(ah,
1802 AR_PHY_GAIN_2GHZ +
1803 regChainOffset,
1804 (REG_READ(ah,
1805 AR_PHY_GAIN_2GHZ +
1806 regChainOffset) &
1807 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
1808 SM(pModal->rxTxMarginCh[i],
1809 AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
1810 }
1811 }
1812 } 1760 }
1813 1761
1814 if (AR_SREV_9280_10_OR_LATER(ah)) { 1762 if (AR_SREV_9280_10_OR_LATER(ah)) {
@@ -1855,8 +1803,6 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
1855 AR_AN_TOP2_LOCALBIAS, 1803 AR_AN_TOP2_LOCALBIAS,
1856 AR_AN_TOP2_LOCALBIAS_S, 1804 AR_AN_TOP2_LOCALBIAS_S,
1857 pModal->local_bias); 1805 pModal->local_bias);
1858 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "ForceXPAon: %d\n",
1859 pModal->force_xpaon);
1860 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, 1806 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
1861 pModal->force_xpaon); 1807 pModal->force_xpaon);
1862 } 1808 }
@@ -1882,6 +1828,7 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
1882 1828
1883 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 1829 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1884 pModal->txEndToRxOn); 1830 pModal->txEndToRxOn);
1831
1885 if (AR_SREV_9280_10_OR_LATER(ah)) { 1832 if (AR_SREV_9280_10_OR_LATER(ah)) {
1886 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1833 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1887 pModal->thresh62); 1834 pModal->thresh62);
@@ -1912,10 +1859,10 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
1912 } 1859 }
1913 1860
1914 if (AR_SREV_9280_20_OR_LATER(ah) && 1861 if (AR_SREV_9280_20_OR_LATER(ah) &&
1915 AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 1862 AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
1916 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, 1863 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
1917 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, 1864 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
1918 pModal->miscBits); 1865 pModal->miscBits);
1919 1866
1920 1867
1921 if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { 1868 if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
@@ -1926,18 +1873,15 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
1926 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); 1873 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
1927 else 1874 else
1928 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 1875 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
1929 eep->baseEepHeader.dacLpMode); 1876 eep->baseEepHeader.dacLpMode);
1930 1877
1931 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, 1878 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
1932 pModal->miscBits >> 2); 1879 pModal->miscBits >> 2);
1933 1880
1934 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, 1881 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
1935 AR_PHY_TX_DESIRED_SCALE_CCK, 1882 AR_PHY_TX_DESIRED_SCALE_CCK,
1936 eep->baseEepHeader.desiredScaleCCK); 1883 eep->baseEepHeader.desiredScaleCCK);
1937 } 1884 }
1938
1939 return true;
1940#undef AR5416_VER_MASK
1941} 1885}
1942 1886
1943static void ath9k_hw_def_set_addac(struct ath_hw *ah, 1887static void ath9k_hw_def_set_addac(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath9k/eeprom.h
index d6f6108f63c7..25b68c881ff1 100644
--- a/drivers/net/wireless/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath9k/eeprom.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -95,6 +95,7 @@
95#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) 95#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
96#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM)) 96#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM))
97 97
98#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
98#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ 99#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
99 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) 100 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
100 101
@@ -489,7 +490,7 @@ struct eeprom_ops {
489 u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band); 490 u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
490 u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw, 491 u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
491 struct ath9k_channel *chan); 492 struct ath9k_channel *chan);
492 bool (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); 493 void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
493 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); 494 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
494 int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, 495 int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
495 u16 cfgCtl, u8 twiceAntennaReduction, 496 u16 cfgCtl, u8 twiceAntennaReduction,
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index d494e98ba971..b15eaf8417ff 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -588,6 +588,10 @@ static int ath9k_hw_post_attach(struct ath_hw *ah)
588 ecode = ath9k_hw_eeprom_attach(ah); 588 ecode = ath9k_hw_eeprom_attach(ah);
589 if (ecode != 0) 589 if (ecode != 0)
590 return ecode; 590 return ecode;
591
592 DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n",
593 ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah));
594
591 ecode = ath9k_hw_rfattach(ah); 595 ecode = ath9k_hw_rfattach(ah);
592 if (ecode != 0) 596 if (ecode != 0)
593 return ecode; 597 return ecode;
@@ -1444,6 +1448,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
1444 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 1448 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1445 break; 1449 break;
1446 case NL80211_IFTYPE_ADHOC: 1450 case NL80211_IFTYPE_ADHOC:
1451 case NL80211_IFTYPE_MESH_POINT:
1447 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC 1452 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
1448 | AR_STA_ID1_KSRCH_MODE); 1453 | AR_STA_ID1_KSRCH_MODE);
1449 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 1454 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
@@ -2273,11 +2278,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2273 else 2278 else
2274 ath9k_hw_spur_mitigate(ah, chan); 2279 ath9k_hw_spur_mitigate(ah, chan);
2275 2280
2276 if (!ah->eep_ops->set_board_values(ah, chan)) { 2281 ah->eep_ops->set_board_values(ah, chan);
2277 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2278 "error setting board options\n");
2279 return -EIO;
2280 }
2281 2282
2282 ath9k_hw_decrease_chain_power(ah, chan); 2283 ath9k_hw_decrease_chain_power(ah, chan);
2283 2284
@@ -3149,6 +3150,7 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
3149 flags |= AR_TBTT_TIMER_EN; 3150 flags |= AR_TBTT_TIMER_EN;
3150 break; 3151 break;
3151 case NL80211_IFTYPE_ADHOC: 3152 case NL80211_IFTYPE_ADHOC:
3153 case NL80211_IFTYPE_MESH_POINT:
3152 REG_SET_BIT(ah, AR_TXCFG, 3154 REG_SET_BIT(ah, AR_TXCFG,
3153 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 3155 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
3154 REG_WRITE(ah, AR_NEXT_NDP_TIMER, 3156 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
index dc681f011fdf..0b594e0ee260 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h
index 1d60c3706f1c..e2f0a34b79a1 100644
--- a/drivers/net/wireless/ath9k/initvals.h
+++ b/drivers/net/wireless/ath9k/initvals.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c
index f757bc7eec68..e0a6dee45839 100644
--- a/drivers/net/wireless/ath9k/mac.c
+++ b/drivers/net/wireless/ath9k/mac.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath9k/mac.h
index a75f65dae1d7..1176bce8b76c 100644
--- a/drivers/net/wireless/ath9k/mac.h
+++ b/drivers/net/wireless/ath9k/mac.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 8db75f6de53e..13d4e6756c99 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -940,18 +940,25 @@ static void ath_led_blink_work(struct work_struct *work)
940 940
941 if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) 941 if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
942 return; 942 return;
943 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 943
944 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); 944 if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
945 (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
946 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
947 else
948 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
949 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
945 950
946 queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work, 951 queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
947 (sc->sc_flags & SC_OP_LED_ON) ? 952 (sc->sc_flags & SC_OP_LED_ON) ?
948 msecs_to_jiffies(sc->led_off_duration) : 953 msecs_to_jiffies(sc->led_off_duration) :
949 msecs_to_jiffies(sc->led_on_duration)); 954 msecs_to_jiffies(sc->led_on_duration));
950 955
951 sc->led_on_duration = 956 sc->led_on_duration = sc->led_on_cnt ?
952 max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25); 957 max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
953 sc->led_off_duration = 958 ATH_LED_ON_DURATION_IDLE;
954 max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10); 959 sc->led_off_duration = sc->led_off_cnt ?
960 max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
961 ATH_LED_OFF_DURATION_IDLE;
955 sc->led_on_cnt = sc->led_off_cnt = 0; 962 sc->led_on_cnt = sc->led_off_cnt = 0;
956 if (sc->sc_flags & SC_OP_LED_ON) 963 if (sc->sc_flags & SC_OP_LED_ON)
957 sc->sc_flags &= ~SC_OP_LED_ON; 964 sc->sc_flags &= ~SC_OP_LED_ON;
@@ -1592,7 +1599,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
1592 hw->wiphy->interface_modes = 1599 hw->wiphy->interface_modes =
1593 BIT(NL80211_IFTYPE_AP) | 1600 BIT(NL80211_IFTYPE_AP) |
1594 BIT(NL80211_IFTYPE_STATION) | 1601 BIT(NL80211_IFTYPE_STATION) |
1595 BIT(NL80211_IFTYPE_ADHOC); 1602 BIT(NL80211_IFTYPE_ADHOC) |
1603 BIT(NL80211_IFTYPE_MESH_POINT);
1596 1604
1597 hw->wiphy->reg_notifier = ath9k_reg_notifier; 1605 hw->wiphy->reg_notifier = ath9k_reg_notifier;
1598 hw->wiphy->strict_regulatory = true; 1606 hw->wiphy->strict_regulatory = true;
@@ -2200,18 +2208,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2200 ic_opmode = NL80211_IFTYPE_STATION; 2208 ic_opmode = NL80211_IFTYPE_STATION;
2201 break; 2209 break;
2202 case NL80211_IFTYPE_ADHOC: 2210 case NL80211_IFTYPE_ADHOC:
2203 if (sc->nbcnvifs >= ATH_BCBUF) {
2204 ret = -ENOBUFS;
2205 goto out;
2206 }
2207 ic_opmode = NL80211_IFTYPE_ADHOC;
2208 break;
2209 case NL80211_IFTYPE_AP: 2211 case NL80211_IFTYPE_AP:
2212 case NL80211_IFTYPE_MESH_POINT:
2210 if (sc->nbcnvifs >= ATH_BCBUF) { 2213 if (sc->nbcnvifs >= ATH_BCBUF) {
2211 ret = -ENOBUFS; 2214 ret = -ENOBUFS;
2212 goto out; 2215 goto out;
2213 } 2216 }
2214 ic_opmode = NL80211_IFTYPE_AP; 2217 ic_opmode = conf->type;
2215 break; 2218 break;
2216 default: 2219 default:
2217 DPRINTF(sc, ATH_DBG_FATAL, 2220 DPRINTF(sc, ATH_DBG_FATAL,
@@ -2247,7 +2250,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2247 * Note we only do this (at the moment) for station mode. 2250 * Note we only do this (at the moment) for station mode.
2248 */ 2251 */
2249 if ((conf->type == NL80211_IFTYPE_STATION) || 2252 if ((conf->type == NL80211_IFTYPE_STATION) ||
2250 (conf->type == NL80211_IFTYPE_ADHOC)) { 2253 (conf->type == NL80211_IFTYPE_ADHOC) ||
2254 (conf->type == NL80211_IFTYPE_MESH_POINT)) {
2251 if (ath9k_hw_phycounters(sc->sc_ah)) 2255 if (ath9k_hw_phycounters(sc->sc_ah))
2252 sc->imask |= ATH9K_INT_MIB; 2256 sc->imask |= ATH9K_INT_MIB;
2253 sc->imask |= ATH9K_INT_TSFOOR; 2257 sc->imask |= ATH9K_INT_TSFOOR;
@@ -2294,8 +2298,9 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
2294 del_timer_sync(&sc->ani.timer); 2298 del_timer_sync(&sc->ani.timer);
2295 2299
2296 /* Reclaim beacon resources */ 2300 /* Reclaim beacon resources */
2297 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || 2301 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
2298 sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) { 2302 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
2303 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
2299 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); 2304 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
2300 ath_beacon_return(sc, avp); 2305 ath_beacon_return(sc, avp);
2301 } 2306 }
@@ -2428,6 +2433,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
2428 switch (vif->type) { 2433 switch (vif->type) {
2429 case NL80211_IFTYPE_STATION: 2434 case NL80211_IFTYPE_STATION:
2430 case NL80211_IFTYPE_ADHOC: 2435 case NL80211_IFTYPE_ADHOC:
2436 case NL80211_IFTYPE_MESH_POINT:
2431 /* Set BSSID */ 2437 /* Set BSSID */
2432 memcpy(sc->curbssid, conf->bssid, ETH_ALEN); 2438 memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
2433 memcpy(avp->bssid, conf->bssid, ETH_ALEN); 2439 memcpy(avp->bssid, conf->bssid, ETH_ALEN);
@@ -2451,7 +2457,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
2451 } 2457 }
2452 2458
2453 if ((vif->type == NL80211_IFTYPE_ADHOC) || 2459 if ((vif->type == NL80211_IFTYPE_ADHOC) ||
2454 (vif->type == NL80211_IFTYPE_AP)) { 2460 (vif->type == NL80211_IFTYPE_AP) ||
2461 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
2455 if ((conf->changed & IEEE80211_IFCC_BEACON) || 2462 if ((conf->changed & IEEE80211_IFCC_BEACON) ||
2456 (conf->changed & IEEE80211_IFCC_BEACON_ENABLED && 2463 (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
2457 conf->enable_beacon)) { 2464 conf->enable_beacon)) {
@@ -2723,7 +2730,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
2723 2730
2724 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); 2731 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2725 break; 2732 break;
2726 case IEEE80211_AMPDU_TX_RESUME: 2733 case IEEE80211_AMPDU_TX_OPERATIONAL:
2727 ath_tx_aggr_resume(sc, sta, tid); 2734 ath_tx_aggr_resume(sc, sta, tid);
2728 break; 2735 break;
2729 default: 2736 default:
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
index 9a58baabb9ca..6dbc58580abb 100644
--- a/drivers/net/wireless/ath9k/pci.c
+++ b/drivers/net/wireless/ath9k/pci.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -87,7 +87,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
87 struct ath_softc *sc; 87 struct ath_softc *sc;
88 struct ieee80211_hw *hw; 88 struct ieee80211_hw *hw;
89 u8 csz; 89 u8 csz;
90 u32 val;
91 int ret = 0; 90 int ret = 0;
92 struct ath_hw *ah; 91 struct ath_hw *ah;
93 92
@@ -134,14 +133,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
134 133
135 pci_set_master(pdev); 134 pci_set_master(pdev);
136 135
137 /*
138 * Disable the RETRY_TIMEOUT register (0x41) to keep
139 * PCI Tx retries from interfering with C3 CPU state.
140 */
141 pci_read_config_dword(pdev, 0x40, &val);
142 if ((val & 0x0000ff00) != 0)
143 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
144
145 ret = pci_request_region(pdev, 0, "ath9k"); 136 ret = pci_request_region(pdev, 0, "ath9k");
146 if (ret) { 137 if (ret) {
147 dev_err(&pdev->dev, "PCI memory region reserve error\n"); 138 dev_err(&pdev->dev, "PCI memory region reserve error\n");
@@ -253,21 +244,12 @@ static int ath_pci_resume(struct pci_dev *pdev)
253 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 244 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
254 struct ath_wiphy *aphy = hw->priv; 245 struct ath_wiphy *aphy = hw->priv;
255 struct ath_softc *sc = aphy->sc; 246 struct ath_softc *sc = aphy->sc;
256 u32 val;
257 int err; 247 int err;
258 248
259 err = pci_enable_device(pdev); 249 err = pci_enable_device(pdev);
260 if (err) 250 if (err)
261 return err; 251 return err;
262 pci_restore_state(pdev); 252 pci_restore_state(pdev);
263 /*
264 * Suspend/Resume resets the PCI configuration space, so we have to
265 * re-disable the RETRY_TIMEOUT register (0x41) to keep
266 * PCI Tx retries from interfering with C3 CPU state
267 */
268 pci_read_config_dword(pdev, 0x40, &val);
269 if ((val & 0x0000ff00) != 0)
270 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
271 253
272 /* Enable LED */ 254 /* Enable LED */
273 ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN, 255 ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
index e1494bae0f9f..8bcba906929a 100644
--- a/drivers/net/wireless/ath9k/phy.c
+++ b/drivers/net/wireless/ath9k/phy.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
index 1eac8c707342..0f7f8e0c9c95 100644
--- a/drivers/net/wireless/ath9k/phy.h
+++ b/drivers/net/wireless/ath9k/phy.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 832735677a46..824ccbb8b7b8 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Video54 Technologies, Inc. 2 * Copyright (c) 2004 Video54 Technologies, Inc.
3 * Copyright (c) 2004-2008 Atheros Communications, Inc. 3 * Copyright (c) 2004-2009 Atheros Communications, Inc.
4 * 4 *
5 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -864,6 +864,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
864 rate_table, nrix, 1, 0); 864 rate_table, nrix, 1, 0);
865 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 865 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
866 try_per_rate, nrix, 0); 866 try_per_rate, nrix, 0);
867
868 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
867 } else { 869 } else {
868 try_per_rate = (ATH_11N_TXMAXTRY/4); 870 try_per_rate = (ATH_11N_TXMAXTRY/4);
869 /* Set the choosen rate. No RTS for first series entry. */ 871 /* Set the choosen rate. No RTS for first series entry. */
@@ -1468,16 +1470,18 @@ static void ath_rc_init(struct ath_softc *sc,
1468 ath_rc_priv->ht_cap); 1470 ath_rc_priv->ht_cap);
1469} 1471}
1470 1472
1471static u8 ath_rc_build_ht_caps(struct ath_softc *sc, bool is_ht, bool is_cw40, 1473static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
1472 bool is_sgi40) 1474 bool is_cw40, bool is_sgi40)
1473{ 1475{
1474 u8 caps = 0; 1476 u8 caps = 0;
1475 1477
1476 if (is_ht) { 1478 if (sta->ht_cap.ht_supported) {
1477 caps = WLAN_RC_HT_FLAG; 1479 caps = WLAN_RC_HT_FLAG;
1478 if (sc->sc_ah->caps.tx_chainmask != 1 && 1480 if (sc->sc_ah->caps.tx_chainmask != 1 &&
1479 ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) 1481 ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
1480 caps |= WLAN_RC_DS_FLAG; 1482 if (sta->ht_cap.mcs.rx_mask[1])
1483 caps |= WLAN_RC_DS_FLAG;
1484 }
1481 if (is_cw40) 1485 if (is_cw40)
1482 caps |= WLAN_RC_40_FLAG; 1486 caps |= WLAN_RC_40_FLAG;
1483 if (is_sgi40) 1487 if (is_sgi40)
@@ -1615,6 +1619,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1615 /* Choose rate table first */ 1619 /* Choose rate table first */
1616 1620
1617 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || 1621 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
1622 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
1618 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { 1623 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
1619 rate_table = ath_choose_rate_table(sc, sband->band, 1624 rate_table = ath_choose_rate_table(sc, sband->band,
1620 sta->ht_cap.ht_supported, 1625 sta->ht_cap.ht_supported,
@@ -1624,8 +1629,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1624 rate_table = sc->cur_rate_table; 1629 rate_table = sc->cur_rate_table;
1625 } 1630 }
1626 1631
1627 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta->ht_cap.ht_supported, 1632 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
1628 is_cw40, is_sgi40);
1629 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1633 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
1630} 1634}
1631 1635
@@ -1659,8 +1663,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1659 rate_table = ath_choose_rate_table(sc, sband->band, 1663 rate_table = ath_choose_rate_table(sc, sband->band,
1660 sta->ht_cap.ht_supported, 1664 sta->ht_cap.ht_supported,
1661 oper_cw40); 1665 oper_cw40);
1662 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, 1666 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
1663 sta->ht_cap.ht_supported,
1664 oper_cw40, oper_sgi40); 1667 oper_cw40, oper_sgi40);
1665 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1668 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
1666 1669
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
index db9b0b9a3431..199a3ce57d64 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Sam Leffler, Errno Consulting 2 * Copyright (c) 2004 Sam Leffler, Errno Consulting
3 * Copyright (c) 2004 Video54 Technologies, Inc. 3 * Copyright (c) 2004 Video54 Technologies, Inc.
4 * Copyright (c) 2008 Atheros Communications Inc. 4 * Copyright (c) 2008-2009 Atheros Communications Inc.
5 * 5 *
6 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 0bba17662a1f..71cb18d6757d 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -344,8 +344,13 @@ void ath_rx_cleanup(struct ath_softc *sc)
344 344
345 list_for_each_entry(bf, &sc->rx.rxbuf, list) { 345 list_for_each_entry(bf, &sc->rx.rxbuf, list) {
346 skb = bf->bf_mpdu; 346 skb = bf->bf_mpdu;
347 if (skb) 347 if (skb) {
348 dma_unmap_single(sc->dev,
349 bf->bf_buf_addr,
350 sc->rx.bufsize,
351 DMA_FROM_DEVICE);
348 dev_kfree_skb(skb); 352 dev_kfree_skb(skb);
353 }
349 } 354 }
350 355
351 if (sc->rx.rxdma.dd_desc_len != 0) 356 if (sc->rx.rxdma.dd_desc_len != 0)
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
index d86e90e38173..52605246679f 100644
--- a/drivers/net/wireless/ath9k/reg.h
+++ b/drivers/net/wireless/ath9k/reg.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index b8f9b6d6bec4..4ca625102291 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
index 8f885f3bc8df..9f5fbd4eea7a 100644
--- a/drivers/net/wireless/ath9k/regd.h
+++ b/drivers/net/wireless/ath9k/regd.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h
index b41d0002f3fe..4d0e298cd1c7 100644
--- a/drivers/net/wireless/ath9k/regd_common.h
+++ b/drivers/net/wireless/ath9k/regd_common.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index e3f376611f85..689bdbf78808 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -64,6 +64,10 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
64static 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,
65 struct list_head *head); 65 struct list_head *head);
66static 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);
67static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
68 int txok);
69static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
70 int nbad, int txok, bool update_rc);
67 71
68/*********************/ 72/*********************/
69/* Aggregation logic */ 73/* Aggregation logic */
@@ -274,9 +278,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
274 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; 278 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
275 struct ath_desc *ds = bf_last->bf_desc; 279 struct ath_desc *ds = bf_last->bf_desc;
276 struct list_head bf_head, bf_pending; 280 struct list_head bf_head, bf_pending;
277 u16 seq_st = 0; 281 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
278 u32 ba[WME_BA_BMP_SIZE >> 5]; 282 u32 ba[WME_BA_BMP_SIZE >> 5];
279 int isaggr, txfail, txpending, sendbar = 0, needreset = 0; 283 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
284 bool rc_update = true;
280 285
281 skb = (struct sk_buff *)bf->bf_mpdu; 286 skb = (struct sk_buff *)bf->bf_mpdu;
282 hdr = (struct ieee80211_hdr *)skb->data; 287 hdr = (struct ieee80211_hdr *)skb->data;
@@ -316,6 +321,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
316 INIT_LIST_HEAD(&bf_pending); 321 INIT_LIST_HEAD(&bf_pending);
317 INIT_LIST_HEAD(&bf_head); 322 INIT_LIST_HEAD(&bf_head);
318 323
324 nbad = ath_tx_num_badfrms(sc, bf, txok);
319 while (bf) { 325 while (bf) {
320 txfail = txpending = 0; 326 txfail = txpending = 0;
321 bf_next = bf->bf_next; 327 bf_next = bf->bf_next;
@@ -323,8 +329,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
323 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { 329 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
324 /* transmit completion, subframe is 330 /* transmit completion, subframe is
325 * acked by block ack */ 331 * acked by block ack */
332 acked_cnt++;
326 } else if (!isaggr && txok) { 333 } else if (!isaggr && txok) {
327 /* transmit completion */ 334 /* transmit completion */
335 acked_cnt++;
328 } else { 336 } else {
329 if (!(tid->state & AGGR_CLEANUP) && 337 if (!(tid->state & AGGR_CLEANUP) &&
330 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { 338 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
@@ -335,6 +343,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
335 bf->bf_state.bf_type |= BUF_XRETRY; 343 bf->bf_state.bf_type |= BUF_XRETRY;
336 txfail = 1; 344 txfail = 1;
337 sendbar = 1; 345 sendbar = 1;
346 txfail_cnt++;
338 } 347 }
339 } else { 348 } else {
340 /* 349 /*
@@ -361,6 +370,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
361 ath_tx_update_baw(sc, tid, bf->bf_seqno); 370 ath_tx_update_baw(sc, tid, bf->bf_seqno);
362 spin_unlock_bh(&txq->axq_lock); 371 spin_unlock_bh(&txq->axq_lock);
363 372
373 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
374 ath_tx_rc_status(bf, ds, nbad, txok, true);
375 rc_update = false;
376 } else {
377 ath_tx_rc_status(bf, ds, nbad, txok, false);
378 }
379
364 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); 380 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
365 } else { 381 } else {
366 /* retry the un-acked ones */ 382 /* retry the un-acked ones */
@@ -1734,7 +1750,7 @@ exit:
1734/*****************/ 1750/*****************/
1735 1751
1736static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 1752static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1737 struct ath_xmit_status *tx_status) 1753 int tx_flags)
1738{ 1754{
1739 struct ieee80211_hw *hw = sc->hw; 1755 struct ieee80211_hw *hw = sc->hw;
1740 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1756 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1755,18 +1771,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1755 tx_info->rate_driver_data[0] = NULL; 1771 tx_info->rate_driver_data[0] = NULL;
1756 } 1772 }
1757 1773
1758 if (tx_status->flags & ATH_TX_BAR) { 1774 if (tx_flags & ATH_TX_BAR)
1759 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 1775 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1760 tx_status->flags &= ~ATH_TX_BAR;
1761 }
1762 1776
1763 if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) { 1777 if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
1764 /* Frame was ACKed */ 1778 /* Frame was ACKed */
1765 tx_info->flags |= IEEE80211_TX_STAT_ACK; 1779 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1766 } 1780 }
1767 1781
1768 tx_info->status.rates[0].count = tx_status->retries + 1;
1769
1770 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1782 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1771 padsize = hdrlen & 3; 1783 padsize = hdrlen & 3;
1772 if (padsize && hdrlen >= 24) { 1784 if (padsize && hdrlen >= 24) {
@@ -1789,29 +1801,22 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1789 int txok, int sendbar) 1801 int txok, int sendbar)
1790{ 1802{
1791 struct sk_buff *skb = bf->bf_mpdu; 1803 struct sk_buff *skb = bf->bf_mpdu;
1792 struct ath_xmit_status tx_status;
1793 unsigned long flags; 1804 unsigned long flags;
1805 int tx_flags = 0;
1794 1806
1795 /*
1796 * Set retry information.
1797 * NB: Don't use the information in the descriptor, because the frame
1798 * could be software retried.
1799 */
1800 tx_status.retries = bf->bf_retries;
1801 tx_status.flags = 0;
1802 1807
1803 if (sendbar) 1808 if (sendbar)
1804 tx_status.flags = ATH_TX_BAR; 1809 tx_flags = ATH_TX_BAR;
1805 1810
1806 if (!txok) { 1811 if (!txok) {
1807 tx_status.flags |= ATH_TX_ERROR; 1812 tx_flags |= ATH_TX_ERROR;
1808 1813
1809 if (bf_isxretried(bf)) 1814 if (bf_isxretried(bf))
1810 tx_status.flags |= ATH_TX_XRETRY; 1815 tx_flags |= ATH_TX_XRETRY;
1811 } 1816 }
1812 1817
1813 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1818 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1814 ath_tx_complete(sc, skb, &tx_status); 1819 ath_tx_complete(sc, skb, tx_flags);
1815 1820
1816 /* 1821 /*
1817 * Return the list of ath_buf of this mpdu to free queue 1822 * Return the list of ath_buf of this mpdu to free queue
@@ -1852,27 +1857,40 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1852 return nbad; 1857 return nbad;
1853} 1858}
1854 1859
1855static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad) 1860static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
1861 int nbad, int txok, bool update_rc)
1856{ 1862{
1857 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; 1863 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
1858 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1864 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1859 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1865 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1860 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); 1866 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1867 struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
1868 u8 i, tx_rateindex;
1869
1870 if (txok)
1871 tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
1861 1872
1862 tx_info_priv->update_rc = false; 1873 tx_rateindex = ds->ds_txstat.ts_rateindex;
1874 WARN_ON(tx_rateindex >= hw->max_rates);
1875
1876 tx_info_priv->update_rc = update_rc;
1863 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) 1877 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
1864 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 1878 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1865 1879
1866 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && 1880 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
1867 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { 1881 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
1868 if (ieee80211_is_data(hdr->frame_control)) { 1882 if (ieee80211_is_data(hdr->frame_control)) {
1869 memcpy(&tx_info_priv->tx, &ds->ds_txstat, 1883 memcpy(&tx_info_priv->tx, &ds->ds_txstat,
1870 sizeof(tx_info_priv->tx)); 1884 sizeof(tx_info_priv->tx));
1871 tx_info_priv->n_frames = bf->bf_nframes; 1885 tx_info_priv->n_frames = bf->bf_nframes;
1872 tx_info_priv->n_bad_frames = nbad; 1886 tx_info_priv->n_bad_frames = nbad;
1873 tx_info_priv->update_rc = true;
1874 } 1887 }
1875 } 1888 }
1889
1890 for (i = tx_rateindex + 1; i < hw->max_rates; i++)
1891 tx_info->status.rates[i].count = 0;
1892
1893 tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
1876} 1894}
1877 1895
1878static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) 1896static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
@@ -1897,7 +1915,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1897 struct ath_buf *bf, *lastbf, *bf_held = NULL; 1915 struct ath_buf *bf, *lastbf, *bf_held = NULL;
1898 struct list_head bf_head; 1916 struct list_head bf_head;
1899 struct ath_desc *ds; 1917 struct ath_desc *ds;
1900 int txok, nbad = 0; 1918 int txok;
1901 int status; 1919 int status;
1902 1920
1903 DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", 1921 DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
@@ -1991,13 +2009,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1991 bf->bf_retries = ds->ds_txstat.ts_longretry; 2009 bf->bf_retries = ds->ds_txstat.ts_longretry;
1992 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) 2010 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
1993 bf->bf_state.bf_type |= BUF_XRETRY; 2011 bf->bf_state.bf_type |= BUF_XRETRY;
1994 nbad = 0; 2012 ath_tx_rc_status(bf, ds, 0, txok, true);
1995 } else {
1996 nbad = ath_tx_num_badfrms(sc, bf, txok);
1997 } 2013 }
1998 2014
1999 ath_tx_rc_status(bf, ds, nbad);
2000
2001 if (bf_isampdu(bf)) 2015 if (bf_isampdu(bf))
2002 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); 2016 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
2003 else 2017 else
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index b72ef3fd315a..4896e0831114 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3993,6 +3993,8 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
3993 dev->irq_reason = 0; 3993 dev->irq_reason = 0;
3994 memset(dev->dma_reason, 0, sizeof(dev->dma_reason)); 3994 memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
3995 dev->irq_savedstate = B43_IRQ_MASKTEMPLATE; 3995 dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
3996 if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
3997 dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
3996 3998
3997 dev->mac_suspended = 1; 3999 dev->mac_suspended = 1;
3998 4000
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 0f53c7e5e01e..a63d88841df8 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -50,7 +50,7 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
50} 50}
51 51
52/* Extract the bitrate index out of an OFDM PLCP header. */ 52/* Extract the bitrate index out of an OFDM PLCP header. */
53static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy) 53static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
54{ 54{
55 int base = aphy ? 0 : 4; 55 int base = aphy ? 0 : 4;
56 56
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 205603d082aa..73f93a0ff2df 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -233,7 +233,7 @@ struct iwl3945_eeprom {
233#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ 233#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */
234 234
235#define TFD_QUEUE_MIN 0 235#define TFD_QUEUE_MIN 0
236#define TFD_QUEUE_MAX 6 236#define TFD_QUEUE_MAX 5 /* 4 DATA + 1 CMD */
237 237
238#define IWL_NUM_SCAN_RATES (2) 238#define IWL_NUM_SCAN_RATES (2)
239 239
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index f65c308a6714..af6b9d444778 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -124,7 +124,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
124#define IWL39_RATE_HIGH_TH 11520 124#define IWL39_RATE_HIGH_TH 11520
125#define IWL_SUCCESS_UP_TH 8960 125#define IWL_SUCCESS_UP_TH 8960
126#define IWL_SUCCESS_DOWN_TH 10880 126#define IWL_SUCCESS_DOWN_TH 10880
127#define IWL_RATE_MIN_FAILURE_TH 8 127#define IWL_RATE_MIN_FAILURE_TH 6
128#define IWL_RATE_MIN_SUCCESS_TH 8 128#define IWL_RATE_MIN_SUCCESS_TH 8
129#define IWL_RATE_DECREASE_TH 1920 129#define IWL_RATE_DECREASE_TH 1920
130#define IWL_RATE_RETRY_TH 15 130#define IWL_RATE_RETRY_TH 15
@@ -488,7 +488,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
488 488
489 IWL_DEBUG_RATE(priv, "enter\n"); 489 IWL_DEBUG_RATE(priv, "enter\n");
490 490
491 retries = info->status.rates[0].count - 1; 491 retries = info->status.rates[0].count;
492 /* Sanity Check for retries */ 492 /* Sanity Check for retries */
493 if (retries > IWL_RATE_RETRY_TH) 493 if (retries > IWL_RATE_RETRY_TH)
494 retries = IWL_RATE_RETRY_TH; 494 retries = IWL_RATE_RETRY_TH;
@@ -791,16 +791,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
791 if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { 791 if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
792 IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n"); 792 IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
793 scale_action = -1; 793 scale_action = -1;
794
795 /* No throughput measured yet for adjacent rates, 794 /* No throughput measured yet for adjacent rates,
796 * try increase */ 795 * try increase */
797 } else if ((low_tpt == IWL_INVALID_VALUE) && 796 } else if ((low_tpt == IWL_INVALID_VALUE) &&
798 (high_tpt == IWL_INVALID_VALUE)) { 797 (high_tpt == IWL_INVALID_VALUE)) {
799 798
800 if (high != IWL_RATE_INVALID && window->success_counter >= IWL_RATE_INCREASE_TH) 799 if (high != IWL_RATE_INVALID && window->success_ratio >= IWL_RATE_INCREASE_TH)
801 scale_action = 1; 800 scale_action = 1;
802 else if (low != IWL_RATE_INVALID) 801 else if (low != IWL_RATE_INVALID)
803 scale_action = -1; 802 scale_action = 0;
804 803
805 /* Both adjacent throughputs are measured, but neither one has 804 /* Both adjacent throughputs are measured, but neither one has
806 * better throughput; we're using the best rate, don't change 805 * better throughput; we're using the best rate, don't change
@@ -826,14 +825,14 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
826 else { 825 else {
827 IWL_DEBUG_RATE(priv, 826 IWL_DEBUG_RATE(priv,
828 "decrease rate because of high tpt\n"); 827 "decrease rate because of high tpt\n");
829 scale_action = -1; 828 scale_action = 0;
830 } 829 }
831 } else if (low_tpt != IWL_INVALID_VALUE) { 830 } else if (low_tpt != IWL_INVALID_VALUE) {
832 if (low_tpt > current_tpt) { 831 if (low_tpt > current_tpt) {
833 IWL_DEBUG_RATE(priv, 832 IWL_DEBUG_RATE(priv,
834 "decrease rate because of low tpt\n"); 833 "decrease rate because of low tpt\n");
835 scale_action = -1; 834 scale_action = -1;
836 } else if (window->success_counter >= IWL_RATE_INCREASE_TH) { 835 } else if (window->success_ratio >= IWL_RATE_INCREASE_TH) {
837 /* Lower rate has better 836 /* Lower rate has better
838 * throughput,decrease rate */ 837 * throughput,decrease rate */
839 scale_action = 1; 838 scale_action = 1;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index ba7e720e73c1..2399328e8de7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -293,7 +293,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
293 if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && 293 if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
294 (txq_id != IWL_CMD_QUEUE_NUM) && 294 (txq_id != IWL_CMD_QUEUE_NUM) &&
295 priv->mac80211_registered) 295 priv->mac80211_registered)
296 ieee80211_wake_queue(priv->hw, txq_id); 296 iwl_wake_queue(priv, txq_id);
297} 297}
298 298
299/** 299/**
@@ -747,11 +747,6 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
747 int i; 747 int i;
748 int counter; 748 int counter;
749 749
750 /* classify bd */
751 if (txq->q.id == IWL_CMD_QUEUE_NUM)
752 /* nothing to cleanup after for host commands */
753 return;
754
755 /* sanity check */ 750 /* sanity check */
756 counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); 751 counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
757 if (counter > NUM_TFD_CHUNKS) { 752 if (counter > NUM_TFD_CHUNKS) {
@@ -1046,7 +1041,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
1046 goto error; 1041 goto error;
1047 1042
1048 /* Tx queue(s) */ 1043 /* Tx queue(s) */
1049 for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) { 1044 for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) {
1050 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? 1045 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
1051 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; 1046 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
1052 rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, 1047 rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
@@ -1184,7 +1179,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
1184 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); 1179 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
1185 1180
1186 rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); 1181 rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
1187 if(rc) 1182 if (rc)
1188 return rc; 1183 return rc;
1189 1184
1190 priv->cfg->ops->lib->apm_ops.config(priv); 1185 priv->cfg->ops->lib->apm_ops.config(priv);
@@ -1239,8 +1234,12 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
1239 int txq_id; 1234 int txq_id;
1240 1235
1241 /* Tx queues */ 1236 /* Tx queues */
1242 for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) 1237 for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++)
1243 iwl_tx_queue_free(priv, txq_id); 1238 if (txq_id == IWL_CMD_QUEUE_NUM)
1239 iwl_cmd_queue_free(priv);
1240 else
1241 iwl_tx_queue_free(priv, txq_id);
1242
1244} 1243}
1245 1244
1246void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) 1245void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
@@ -1259,7 +1258,7 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
1259 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); 1258 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
1260 1259
1261 /* reset TFD queues */ 1260 /* reset TFD queues */
1262 for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) { 1261 for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) {
1263 iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0); 1262 iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
1264 iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS, 1263 iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
1265 FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), 1264 FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
@@ -2488,6 +2487,9 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2488 return -ENOMEM; 2487 return -ENOMEM;
2489 } 2488 }
2490 2489
2490 /* Assign number of Usable TX queues */
2491 priv->hw_params.max_txq_num = TFD_QUEUE_MAX;
2492
2491 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); 2493 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
2492 priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K; 2494 priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
2493 priv->hw_params.max_pkt_size = 2342; 2495 priv->hw_params.max_pkt_size = 2342;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index bd0140be774e..847a6220c5e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2178,10 +2178,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2178 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 2178 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
2179 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { 2179 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
2180 if (agg->state == IWL_AGG_OFF) 2180 if (agg->state == IWL_AGG_OFF)
2181 ieee80211_wake_queue(priv->hw, txq_id); 2181 iwl_wake_queue(priv, txq_id);
2182 else 2182 else
2183 ieee80211_wake_queue(priv->hw, 2183 iwl_wake_queue(priv, txq->swq_id);
2184 txq->swq_id);
2185 } 2184 }
2186 } 2185 }
2187 } else { 2186 } else {
@@ -2205,7 +2204,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2205 2204
2206 if (priv->mac80211_registered && 2205 if (priv->mac80211_registered &&
2207 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 2206 (iwl_queue_space(&txq->q) > txq->q.low_mark))
2208 ieee80211_wake_queue(priv->hw, txq_id); 2207 iwl_wake_queue(priv, txq_id);
2209 } 2208 }
2210 2209
2211 if (qc && likely(sta_id != IWL_INVALID_STATION)) 2210 if (qc && likely(sta_id != IWL_INVALID_STATION))
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 08c19bea71e3..e5ca2511a81a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1077,7 +1077,7 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1077 1077
1078 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || 1078 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
1079 (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { 1079 (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
1080 IWL_WARN(priv, 1080 IWL_ERR(priv,
1081 "queue number out of range: %d, must be %d to %d\n", 1081 "queue number out of range: %d, must be %d to %d\n",
1082 txq_id, IWL50_FIRST_AMPDU_QUEUE, 1082 txq_id, IWL50_FIRST_AMPDU_QUEUE,
1083 IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); 1083 IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
@@ -1295,10 +1295,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1295 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 1295 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1296 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { 1296 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
1297 if (agg->state == IWL_AGG_OFF) 1297 if (agg->state == IWL_AGG_OFF)
1298 ieee80211_wake_queue(priv->hw, txq_id); 1298 iwl_wake_queue(priv, txq_id);
1299 else 1299 else
1300 ieee80211_wake_queue(priv->hw, 1300 iwl_wake_queue(priv, txq->swq_id);
1301 txq->swq_id);
1302 } 1301 }
1303 } 1302 }
1304 } else { 1303 } else {
@@ -1324,7 +1323,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1324 1323
1325 if (priv->mac80211_registered && 1324 if (priv->mac80211_registered &&
1326 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 1325 (iwl_queue_space(&txq->q) > txq->q.low_mark))
1327 ieee80211_wake_queue(priv->hw, txq_id); 1326 iwl_wake_queue(priv, txq_id);
1328 } 1327 }
1329 1328
1330 if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) 1329 if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 0db3bc011ac2..663dc83be501 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1567,9 +1567,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
1567 if (iwl_is_associated(priv)) { 1567 if (iwl_is_associated(priv)) {
1568 struct iwl_rxon_cmd *active_rxon = 1568 struct iwl_rxon_cmd *active_rxon =
1569 (struct iwl_rxon_cmd *)&priv->active_rxon; 1569 (struct iwl_rxon_cmd *)&priv->active_rxon;
1570 1570 /* apply any changes in staging */
1571 memcpy(&priv->staging_rxon, &priv->active_rxon, 1571 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
1572 sizeof(priv->staging_rxon));
1573 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1572 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1574 } else { 1573 } else {
1575 /* Initialize our rx_config data */ 1574 /* Initialize our rx_config data */
@@ -2184,110 +2183,112 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2184 struct iwl_priv *priv = hw->priv; 2183 struct iwl_priv *priv = hw->priv;
2185 const struct iwl_channel_info *ch_info; 2184 const struct iwl_channel_info *ch_info;
2186 struct ieee80211_conf *conf = &hw->conf; 2185 struct ieee80211_conf *conf = &hw->conf;
2187 unsigned long flags; 2186 unsigned long flags = 0;
2188 int ret = 0; 2187 int ret = 0;
2189 u16 channel; 2188 u16 ch;
2189 int scan_active = 0;
2190 2190
2191 mutex_lock(&priv->mutex); 2191 mutex_lock(&priv->mutex);
2192 IWL_DEBUG_MAC80211(priv, "enter to channel %d\n", conf->channel->hw_value); 2192 IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
2193 conf->channel->hw_value, changed);
2193 2194
2194 priv->current_ht_config.is_ht = conf_is_ht(conf); 2195 if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
2195 2196 test_bit(STATUS_SCANNING, &priv->status))) {
2196 if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { 2197 scan_active = 1;
2197 IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - waiting for uCode\n"); 2198 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
2198 goto out;
2199 } 2199 }
2200 2200
2201 if (!conf->radio_enabled)
2202 iwl_radio_kill_sw_disable_radio(priv);
2203 2201
2204 if (!iwl_is_ready(priv)) { 2202 /* during scanning mac80211 will delay channel setting until
2205 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 2203 * scan finish with changed = 0
2206 ret = -EIO; 2204 */
2207 goto out; 2205 if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
2208 } 2206 if (scan_active)
2207 goto set_ch_out;
2208
2209 ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
2210 ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
2211 if (!is_channel_valid(ch_info)) {
2212 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
2213 ret = -EINVAL;
2214 goto set_ch_out;
2215 }
2209 2216
2210 if (unlikely(!priv->cfg->mod_params->disable_hw_scan && 2217 if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
2211 test_bit(STATUS_SCANNING, &priv->status))) { 2218 !is_channel_ibss(ch_info)) {
2212 IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); 2219 IWL_ERR(priv, "channel %d in band %d not "
2213 mutex_unlock(&priv->mutex); 2220 "IBSS channel\n",
2214 return 0; 2221 conf->channel->hw_value, conf->channel->band);
2215 } 2222 ret = -EINVAL;
2223 goto set_ch_out;
2224 }
2216 2225
2217 channel = ieee80211_frequency_to_channel(conf->channel->center_freq); 2226 priv->current_ht_config.is_ht = conf_is_ht(conf);
2218 ch_info = iwl_get_channel_info(priv, conf->channel->band, channel);
2219 if (!is_channel_valid(ch_info)) {
2220 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
2221 ret = -EINVAL;
2222 goto out;
2223 }
2224 2227
2225 if (priv->iw_mode == NL80211_IFTYPE_ADHOC && 2228 spin_lock_irqsave(&priv->lock, flags);
2226 !is_channel_ibss(ch_info)) {
2227 IWL_ERR(priv, "channel %d in band %d not IBSS channel\n",
2228 conf->channel->hw_value, conf->channel->band);
2229 ret = -EINVAL;
2230 goto out;
2231 }
2232 2229
2233 spin_lock_irqsave(&priv->lock, flags);
2234 2230
2231 /* if we are switching from ht to 2.4 clear flags
2232 * from any ht related info since 2.4 does not
2233 * support ht */
2234 if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
2235 priv->staging_rxon.flags = 0;
2235 2236
2236 /* if we are switching from ht to 2.4 clear flags 2237 iwl_set_rxon_channel(priv, conf->channel);
2237 * from any ht related info since 2.4 does not
2238 * support ht */
2239 if ((le16_to_cpu(priv->staging_rxon.channel) != channel)
2240#ifdef IEEE80211_CONF_CHANNEL_SWITCH
2241 && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH)
2242#endif
2243 )
2244 priv->staging_rxon.flags = 0;
2245 2238
2246 iwl_set_rxon_channel(priv, conf->channel); 2239 iwl_set_flags_for_band(priv, conf->channel->band);
2240 spin_unlock_irqrestore(&priv->lock, flags);
2241 set_ch_out:
2242 /* The list of supported rates and rate mask can be different
2243 * for each band; since the band may have changed, reset
2244 * the rate mask to what mac80211 lists */
2245 iwl_set_rate(priv);
2246 }
2247 2247
2248 iwl_set_flags_for_band(priv, conf->channel->band); 2248 if (changed & IEEE80211_CONF_CHANGE_PS) {
2249 if (conf->flags & IEEE80211_CONF_PS)
2250 ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
2251 else
2252 ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
2253 if (ret)
2254 IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
2249 2255
2250 /* The list of supported rates and rate mask can be different 2256 }
2251 * for each band; since the band may have changed, reset
2252 * the rate mask to what mac80211 lists */
2253 iwl_set_rate(priv);
2254 2257
2255 spin_unlock_irqrestore(&priv->lock, flags); 2258 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2259 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
2260 priv->tx_power_user_lmt, conf->power_level);
2256 2261
2257#ifdef IEEE80211_CONF_CHANNEL_SWITCH 2262 iwl_set_tx_power(priv, conf->power_level, false);
2258 if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) { 2263 }
2259 iwl_hw_channel_switch(priv, conf->channel); 2264
2260 goto out; 2265 /* call to ensure that 4965 rx_chain is set properly in monitor mode */
2266 iwl_set_rxon_chain(priv);
2267
2268 if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
2269 if (conf->radio_enabled &&
2270 iwl_radio_kill_sw_enable_radio(priv)) {
2271 IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
2272 "waiting for uCode\n");
2273 goto out;
2274 }
2275
2276 if (!conf->radio_enabled)
2277 iwl_radio_kill_sw_disable_radio(priv);
2261 } 2278 }
2262#endif
2263 2279
2264 if (!conf->radio_enabled) { 2280 if (!conf->radio_enabled) {
2265 IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); 2281 IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
2266 goto out; 2282 goto out;
2267 } 2283 }
2268 2284
2269 if (iwl_is_rfkill(priv)) { 2285 if (!iwl_is_ready(priv)) {
2270 IWL_DEBUG_MAC80211(priv, "leave - RF kill\n"); 2286 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2271 ret = -EIO;
2272 goto out; 2287 goto out;
2273 } 2288 }
2274 2289
2275 if (conf->flags & IEEE80211_CONF_PS) 2290 if (scan_active)
2276 ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); 2291 goto out;
2277 else
2278 ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
2279 if (ret)
2280 IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
2281
2282 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
2283 priv->tx_power_user_lmt, conf->power_level);
2284
2285 iwl_set_tx_power(priv, conf->power_level, false);
2286
2287 iwl_set_rate(priv);
2288
2289 /* call to ensure that 4965 rx_chain is set properly in monitor mode */
2290 iwl_set_rxon_chain(priv);
2291 2292
2292 if (memcmp(&priv->active_rxon, 2293 if (memcmp(&priv->active_rxon,
2293 &priv->staging_rxon, sizeof(priv->staging_rxon))) 2294 &priv->staging_rxon, sizeof(priv->staging_rxon)))
@@ -2295,9 +2296,9 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2295 else 2296 else
2296 IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n"); 2297 IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
2297 2298
2298 IWL_DEBUG_MAC80211(priv, "leave\n");
2299 2299
2300out: 2300out:
2301 IWL_DEBUG_MAC80211(priv, "leave\n");
2301 mutex_unlock(&priv->mutex); 2302 mutex_unlock(&priv->mutex);
2302 return ret; 2303 return ret;
2303} 2304}
@@ -2682,6 +2683,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2682 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 2683 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2683{ 2684{
2684 struct iwl_priv *priv = hw->priv; 2685 struct iwl_priv *priv = hw->priv;
2686 int ret;
2685 2687
2686 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", 2688 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
2687 sta->addr, tid); 2689 sta->addr, tid);
@@ -2695,13 +2697,21 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2695 return iwl_sta_rx_agg_start(priv, sta->addr, tid, *ssn); 2697 return iwl_sta_rx_agg_start(priv, sta->addr, tid, *ssn);
2696 case IEEE80211_AMPDU_RX_STOP: 2698 case IEEE80211_AMPDU_RX_STOP:
2697 IWL_DEBUG_HT(priv, "stop Rx\n"); 2699 IWL_DEBUG_HT(priv, "stop Rx\n");
2698 return iwl_sta_rx_agg_stop(priv, sta->addr, tid); 2700 ret = iwl_sta_rx_agg_stop(priv, sta->addr, tid);
2701 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2702 return 0;
2703 else
2704 return ret;
2699 case IEEE80211_AMPDU_TX_START: 2705 case IEEE80211_AMPDU_TX_START:
2700 IWL_DEBUG_HT(priv, "start Tx\n"); 2706 IWL_DEBUG_HT(priv, "start Tx\n");
2701 return iwl_tx_agg_start(priv, sta->addr, tid, ssn); 2707 return iwl_tx_agg_start(priv, sta->addr, tid, ssn);
2702 case IEEE80211_AMPDU_TX_STOP: 2708 case IEEE80211_AMPDU_TX_STOP:
2703 IWL_DEBUG_HT(priv, "stop Tx\n"); 2709 IWL_DEBUG_HT(priv, "stop Tx\n");
2704 return iwl_tx_agg_stop(priv, sta->addr, tid); 2710 ret = iwl_tx_agg_stop(priv, sta->addr, tid);
2711 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2712 return 0;
2713 else
2714 return ret;
2705 default: 2715 default:
2706 IWL_DEBUG_HT(priv, "unknown\n"); 2716 IWL_DEBUG_HT(priv, "unknown\n");
2707 return -EINVAL; 2717 return -EINVAL;
@@ -3083,11 +3093,6 @@ static ssize_t store_power_level(struct device *d,
3083 3093
3084 mutex_lock(&priv->mutex); 3094 mutex_lock(&priv->mutex);
3085 3095
3086 if (!iwl_is_ready(priv)) {
3087 ret = -EAGAIN;
3088 goto out;
3089 }
3090
3091 ret = strict_strtoul(buf, 10, &mode); 3096 ret = strict_strtoul(buf, 10, &mode);
3092 if (ret) 3097 if (ret)
3093 goto out; 3098 goto out;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 085e9cf1cac9..c54fb93e9d72 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1298,6 +1298,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
1298 hw->flags = IEEE80211_HW_SIGNAL_DBM | 1298 hw->flags = IEEE80211_HW_SIGNAL_DBM |
1299 IEEE80211_HW_NOISE_DBM | 1299 IEEE80211_HW_NOISE_DBM |
1300 IEEE80211_HW_AMPDU_AGGREGATION | 1300 IEEE80211_HW_AMPDU_AGGREGATION |
1301 IEEE80211_HW_SPECTRUM_MGMT |
1301 IEEE80211_HW_SUPPORTS_PS; 1302 IEEE80211_HW_SUPPORTS_PS;
1302 hw->wiphy->interface_modes = 1303 hw->wiphy->interface_modes =
1303 BIT(NL80211_IFTYPE_STATION) | 1304 BIT(NL80211_IFTYPE_STATION) |
@@ -1308,9 +1309,6 @@ int iwl_setup_mac(struct iwl_priv *priv)
1308 1309
1309 /* Default value; 4 EDCA QOS priorities */ 1310 /* Default value; 4 EDCA QOS priorities */
1310 hw->queues = 4; 1311 hw->queues = 4;
1311 /* queues to support 11n aggregation */
1312 if (priv->cfg->sku & IWL_SKU_N)
1313 hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
1314 1312
1315 hw->conf.beacon_int = 100; 1313 hw->conf.beacon_int = 100;
1316 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; 1314 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
@@ -1437,6 +1435,10 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
1437 1435
1438 priv->tx_power_user_lmt = tx_power; 1436 priv->tx_power_user_lmt = tx_power;
1439 1437
1438 /* if nic is not up don't send command */
1439 if (!iwl_is_ready_rf(priv))
1440 return ret;
1441
1440 if (force && priv->cfg->ops->lib->send_tx_power) 1442 if (force && priv->cfg->ops->lib->send_tx_power)
1441 ret = priv->cfg->ops->lib->send_tx_power(priv); 1443 ret = priv->cfg->ops->lib->send_tx_power(priv);
1442 1444
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 27310fec2e43..a8eac8c3c1fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -264,6 +264,7 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
264* RX 264* RX
265******************************************************/ 265******************************************************/
266void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 266void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
267void iwl_cmd_queue_free(struct iwl_priv *priv);
267int iwl_rx_queue_alloc(struct iwl_priv *priv); 268int iwl_rx_queue_alloc(struct iwl_priv *priv);
268void iwl_rx_handle(struct iwl_priv *priv); 269void iwl_rx_handle(struct iwl_priv *priv);
269int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, 270int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 36cfeccfafbc..64eb585f1578 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -425,6 +425,56 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
425 return ret; 425 return ret;
426} 426}
427 427
428static ssize_t iwl_dbgfs_status_read(struct file *file,
429 char __user *user_buf,
430 size_t count, loff_t *ppos) {
431
432 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
433 char buf[512];
434 int pos = 0;
435 const size_t bufsz = sizeof(buf);
436
437 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
438 test_bit(STATUS_HCMD_ACTIVE, &priv->status));
439 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
440 test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status));
441 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
442 test_bit(STATUS_INT_ENABLED, &priv->status));
443 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
444 test_bit(STATUS_RF_KILL_HW, &priv->status));
445 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n",
446 test_bit(STATUS_RF_KILL_SW, &priv->status));
447 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
448 test_bit(STATUS_INIT, &priv->status));
449 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
450 test_bit(STATUS_ALIVE, &priv->status));
451 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
452 test_bit(STATUS_READY, &priv->status));
453 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
454 test_bit(STATUS_TEMPERATURE, &priv->status));
455 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
456 test_bit(STATUS_GEO_CONFIGURED, &priv->status));
457 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
458 test_bit(STATUS_EXIT_PENDING, &priv->status));
459 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_IN_SUSPEND:\t %d\n",
460 test_bit(STATUS_IN_SUSPEND, &priv->status));
461 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
462 test_bit(STATUS_STATISTICS, &priv->status));
463 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
464 test_bit(STATUS_SCANNING, &priv->status));
465 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
466 test_bit(STATUS_SCAN_ABORTING, &priv->status));
467 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
468 test_bit(STATUS_SCAN_HW, &priv->status));
469 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
470 test_bit(STATUS_POWER_PMI, &priv->status));
471 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
472 test_bit(STATUS_FW_ERROR, &priv->status));
473 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n",
474 test_bit(STATUS_MODE_PENDING, &priv->status));
475 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
476}
477
428DEBUGFS_READ_WRITE_FILE_OPS(sram); 478DEBUGFS_READ_WRITE_FILE_OPS(sram);
429DEBUGFS_WRITE_FILE_OPS(log_event); 479DEBUGFS_WRITE_FILE_OPS(log_event);
430DEBUGFS_READ_FILE_OPS(eeprom); 480DEBUGFS_READ_FILE_OPS(eeprom);
@@ -432,6 +482,7 @@ DEBUGFS_READ_FILE_OPS(stations);
432DEBUGFS_READ_FILE_OPS(rx_statistics); 482DEBUGFS_READ_FILE_OPS(rx_statistics);
433DEBUGFS_READ_FILE_OPS(tx_statistics); 483DEBUGFS_READ_FILE_OPS(tx_statistics);
434DEBUGFS_READ_FILE_OPS(channels); 484DEBUGFS_READ_FILE_OPS(channels);
485DEBUGFS_READ_FILE_OPS(status);
435 486
436/* 487/*
437 * Create the debugfs files and directories 488 * Create the debugfs files and directories
@@ -466,7 +517,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
466 DEBUGFS_ADD_FILE(rx_statistics, data); 517 DEBUGFS_ADD_FILE(rx_statistics, data);
467 DEBUGFS_ADD_FILE(tx_statistics, data); 518 DEBUGFS_ADD_FILE(tx_statistics, data);
468 DEBUGFS_ADD_FILE(channels, data); 519 DEBUGFS_ADD_FILE(channels, data);
469 DEBUGFS_ADD_X32(status, data, (u32 *)&priv->status); 520 DEBUGFS_ADD_FILE(status, data);
470 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 521 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
471 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 522 DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
472 &priv->disable_chain_noise_cal); 523 &priv->disable_chain_noise_cal);
@@ -496,6 +547,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
496 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); 547 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
497 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); 548 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
498 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); 549 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
550 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
499 DEBUGFS_REMOVE(priv->dbgfs->dir_data); 551 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
500 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 552 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
501 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); 553 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0baae8022824..ec9a13846edd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -996,6 +996,12 @@ struct iwl_priv {
996 u8 key_mapping_key; 996 u8 key_mapping_key;
997 unsigned long ucode_key_table; 997 unsigned long ucode_key_table;
998 998
999 /* queue refcounts */
1000#define IWL_MAX_HW_QUEUES 32
1001 unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
1002 /* for each AC */
1003 atomic_t queue_stop_count[4];
1004
999 /* Indication if ieee80211_ops->open has been called */ 1005 /* Indication if ieee80211_ops->open has been called */
1000 u8 is_open; 1006 u8 is_open;
1001 1007
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index fb64d297dd4e..a1328c3c81ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -93,4 +93,56 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
93 return (desc->v_addr != NULL) ? 0 : -ENOMEM; 93 return (desc->v_addr != NULL) ? 0 : -ENOMEM;
94} 94}
95 95
96/*
97 * we have 8 bits used like this:
98 *
99 * 7 6 5 4 3 2 1 0
100 * | | | | | | | |
101 * | | | | | | +-+-------- AC queue (0-3)
102 * | | | | | |
103 * | +-+-+-+-+------------ HW A-MPDU queue
104 * |
105 * +---------------------- indicates agg queue
106 */
107static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq)
108{
109 BUG_ON(ac > 3); /* only have 2 bits */
110 BUG_ON(hwq > 31); /* only have 5 bits */
111
112 return 0x80 | (hwq << 2) | ac;
113}
114
115static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue)
116{
117 u8 ac = queue;
118 u8 hwq = queue;
119
120 if (queue & 0x80) {
121 ac = queue & 3;
122 hwq = (queue >> 2) & 0x1f;
123 }
124
125 if (test_and_clear_bit(hwq, priv->queue_stopped))
126 if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
127 ieee80211_wake_queue(priv->hw, ac);
128}
129
130static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
131{
132 u8 ac = queue;
133 u8 hwq = queue;
134
135 if (queue & 0x80) {
136 ac = queue & 3;
137 hwq = (queue >> 2) & 0x1f;
138 }
139
140 if (!test_and_set_bit(hwq, priv->queue_stopped))
141 if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
142 ieee80211_stop_queue(priv->hw, ac);
143}
144
145#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
146#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
147
96#endif /* __iwl_helpers_h__ */ 148#endif /* __iwl_helpers_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 18b7e4195ea1..47c894530eb5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -273,7 +273,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
273 if (priv->iw_mode != NL80211_IFTYPE_STATION) 273 if (priv->iw_mode != NL80211_IFTYPE_STATION)
274 final_mode = IWL_POWER_MODE_CAM; 274 final_mode = IWL_POWER_MODE_CAM;
275 275
276 if (!iwl_is_rfkill(priv) && !setting->power_disabled && 276 if (iwl_is_ready_rf(priv) && !setting->power_disabled &&
277 ((setting->power_mode != final_mode) || force)) { 277 ((setting->power_mode != final_mode) || force)) {
278 struct iwl_powertable_cmd cmd; 278 struct iwl_powertable_cmd cmd;
279 279
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 1684490d93c0..5798fe49c771 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1138,8 +1138,10 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid)
1138 int sta_id; 1138 int sta_id;
1139 1139
1140 sta_id = iwl_find_station(priv, addr); 1140 sta_id = iwl_find_station(priv, addr);
1141 if (sta_id == IWL_INVALID_STATION) 1141 if (sta_id == IWL_INVALID_STATION) {
1142 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1142 return -ENXIO; 1143 return -ENXIO;
1144 }
1143 1145
1144 spin_lock_irqsave(&priv->sta_lock, flags); 1146 spin_lock_irqsave(&priv->sta_lock, flags);
1145 priv->stations[sta_id].sta.station_flags_msk = 0; 1147 priv->stations[sta_id].sta.station_flags_msk = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index dff60fb70214..1f117a49c569 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -174,7 +174,7 @@ EXPORT_SYMBOL(iwl_tx_queue_free);
174 * Free all buffers. 174 * Free all buffers.
175 * 0-fill, but do not free "txq" descriptor structure. 175 * 0-fill, but do not free "txq" descriptor structure.
176 */ 176 */
177static void iwl_cmd_queue_free(struct iwl_priv *priv) 177void iwl_cmd_queue_free(struct iwl_priv *priv)
178{ 178{
179 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; 179 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
180 struct iwl_queue *q = &txq->q; 180 struct iwl_queue *q = &txq->q;
@@ -193,12 +193,14 @@ static void iwl_cmd_queue_free(struct iwl_priv *priv)
193 193
194 /* De-alloc circular buffer of TFDs */ 194 /* De-alloc circular buffer of TFDs */
195 if (txq->q.n_bd) 195 if (txq->q.n_bd)
196 pci_free_consistent(dev, sizeof(struct iwl_tfd) * 196 pci_free_consistent(dev, priv->hw_params.tfd_size *
197 txq->q.n_bd, txq->tfds, txq->q.dma_addr); 197 txq->q.n_bd, txq->tfds, txq->q.dma_addr);
198 198
199 /* 0-fill queue descriptor structure */ 199 /* 0-fill queue descriptor structure */
200 memset(txq, 0, sizeof(*txq)); 200 memset(txq, 0, sizeof(*txq));
201} 201}
202EXPORT_SYMBOL(iwl_cmd_queue_free);
203
202/*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** 204/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
203 * DMA services 205 * DMA services
204 * 206 *
@@ -761,8 +763,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
761 hdr->seq_ctrl |= cpu_to_le16(seq_number); 763 hdr->seq_ctrl |= cpu_to_le16(seq_number);
762 seq_number += 0x10; 764 seq_number += 0x10;
763 /* aggregation is on for this <sta,tid> */ 765 /* aggregation is on for this <sta,tid> */
764 if (info->flags & IEEE80211_TX_CTL_AMPDU) 766 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
765 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; 767 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
768 swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id);
769 }
766 priv->stations[sta_id].tid[tid].tfds_in_queue++; 770 priv->stations[sta_id].tid[tid].tfds_in_queue++;
767 } 771 }
768 772
@@ -893,7 +897,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
893 iwl_txq_update_write_ptr(priv, txq); 897 iwl_txq_update_write_ptr(priv, txq);
894 spin_unlock_irqrestore(&priv->lock, flags); 898 spin_unlock_irqrestore(&priv->lock, flags);
895 } else { 899 } else {
896 ieee80211_stop_queue(priv->hw, txq->swq_id); 900 iwl_stop_queue(priv, txq->swq_id);
897 } 901 }
898 } 902 }
899 903
@@ -1221,8 +1225,10 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
1221 1225
1222 sta_id = iwl_find_station(priv, ra); 1226 sta_id = iwl_find_station(priv, ra);
1223 1227
1224 if (sta_id == IWL_INVALID_STATION) 1228 if (sta_id == IWL_INVALID_STATION) {
1229 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1225 return -ENXIO; 1230 return -ENXIO;
1231 }
1226 1232
1227 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) 1233 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
1228 IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n"); 1234 IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n");
@@ -1429,7 +1435,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1429 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && 1435 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1430 priv->mac80211_registered && 1436 priv->mac80211_registered &&
1431 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) 1437 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1432 ieee80211_wake_queue(priv->hw, txq->swq_id); 1438 iwl_wake_queue(priv, txq->swq_id);
1433 1439
1434 iwl_txq_check_empty(priv, sta_id, tid, scd_flow); 1440 iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
1435 } 1441 }
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4465320f2735..a71b08ca7c71 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -485,14 +485,14 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
485 memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key, 485 memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
486 keyconf->keylen); 486 keyconf->keylen);
487 487
488 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) 488 if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
489 == STA_KEY_FLG_NO_ENC) 489 == STA_KEY_FLG_NO_ENC)
490 priv->stations[sta_id].sta.key.key_offset = 490 priv->stations_39[sta_id].sta.key.key_offset =
491 iwl_get_free_ucode_key_index(priv); 491 iwl_get_free_ucode_key_index(priv);
492 /* else, we are overriding an existing key => no need to allocated room 492 /* else, we are overriding an existing key => no need to allocated room
493 * in uCode. */ 493 * in uCode. */
494 494
495 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, 495 WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
496 "no space for a new key"); 496 "no space for a new key");
497 497
498 priv->stations_39[sta_id].sta.key.key_flags = key_flags; 498 priv->stations_39[sta_id].sta.key.key_flags = key_flags;
@@ -560,7 +560,7 @@ static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
560 ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id); 560 ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id);
561 break; 561 break;
562 default: 562 default:
563 IWL_ERR(priv,"Unknown alg: %s alg = %d\n", __func__, keyconf->alg); 563 IWL_ERR(priv, "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
564 ret = -EINVAL; 564 ret = -EINVAL;
565 } 565 }
566 566
@@ -1168,7 +1168,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
1168 spin_unlock_irqrestore(&priv->lock, flags); 1168 spin_unlock_irqrestore(&priv->lock, flags);
1169 } 1169 }
1170 1170
1171 ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb)); 1171 iwl_stop_queue(priv, skb_get_queue_mapping(skb));
1172 } 1172 }
1173 1173
1174 return 0; 1174 return 0;
@@ -3773,15 +3773,19 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
3773 } 3773 }
3774#endif 3774#endif
3775 3775
3776 if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { 3776 if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
3777 IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - waiting for uCode\n"); 3777 if (conf->radio_enabled &&
3778 goto out; 3778 iwl_radio_kill_sw_enable_radio(priv)) {
3779 } 3779 IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
3780 "waiting for uCode\n");
3781 goto out;
3782 }
3780 3783
3781 if (!conf->radio_enabled) { 3784 if (!conf->radio_enabled) {
3782 iwl_radio_kill_sw_disable_radio(priv); 3785 iwl_radio_kill_sw_disable_radio(priv);
3783 IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); 3786 IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
3784 goto out; 3787 goto out;
3788 }
3785 } 3789 }
3786 3790
3787 if (iwl_is_rfkill(priv)) { 3791 if (iwl_is_rfkill(priv)) {
@@ -4546,11 +4550,6 @@ static ssize_t store_power_level(struct device *d,
4546 4550
4547 mutex_lock(&priv->mutex); 4551 mutex_lock(&priv->mutex);
4548 4552
4549 if (!iwl_is_ready(priv)) {
4550 ret = -EAGAIN;
4551 goto out;
4552 }
4553
4554 ret = strict_strtoul(buf, 10, &mode); 4553 ret = strict_strtoul(buf, 10, &mode);
4555 if (ret) 4554 if (ret)
4556 goto out; 4555 goto out;
@@ -4905,7 +4904,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
4905 4904
4906 /* Tell mac80211 our characteristics */ 4905 /* Tell mac80211 our characteristics */
4907 hw->flags = IEEE80211_HW_SIGNAL_DBM | 4906 hw->flags = IEEE80211_HW_SIGNAL_DBM |
4908 IEEE80211_HW_NOISE_DBM; 4907 IEEE80211_HW_NOISE_DBM |
4908 IEEE80211_HW_SPECTRUM_MGMT;
4909 4909
4910 hw->wiphy->interface_modes = 4910 hw->wiphy->interface_modes =
4911 BIT(NL80211_IFTYPE_STATION) | 4911 BIT(NL80211_IFTYPE_STATION) |
diff --git a/drivers/net/wireless/libertas/radiotap.h b/drivers/net/wireless/libertas/radiotap.h
index f8eb9097ff0a..d16b26416e82 100644
--- a/drivers/net/wireless/libertas/radiotap.h
+++ b/drivers/net/wireless/libertas/radiotap.h
@@ -33,22 +33,12 @@ struct rx_radiotap_hdr {
33 struct ieee80211_radiotap_header hdr; 33 struct ieee80211_radiotap_header hdr;
34 u8 flags; 34 u8 flags;
35 u8 rate; 35 u8 rate;
36 u16 chan_freq;
37 u16 chan_flags;
38 u8 antenna;
39 u8 antsignal; 36 u8 antsignal;
40 u16 rx_flags;
41#if 0
42 u8 pad[IEEE80211_RADIOTAP_HDRLEN - 18];
43#endif
44} __attribute__ ((packed)); 37} __attribute__ ((packed));
45 38
46#define RX_RADIOTAP_PRESENT ( \ 39#define RX_RADIOTAP_PRESENT ( \
47 (1 << IEEE80211_RADIOTAP_FLAGS) | \ 40 (1 << IEEE80211_RADIOTAP_FLAGS) | \
48 (1 << IEEE80211_RADIOTAP_RATE) | \ 41 (1 << IEEE80211_RADIOTAP_RATE) | \
49 (1 << IEEE80211_RADIOTAP_CHANNEL) | \
50 (1 << IEEE80211_RADIOTAP_ANTENNA) | \
51 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |\ 42 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |\
52 (1 << IEEE80211_RADIOTAP_RX_FLAGS) | \
53 0) 43 0)
54 44
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 4f60948dde9c..63d7e19ce9bd 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -351,19 +351,11 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
351 radiotap_hdr.hdr.it_pad = 0; 351 radiotap_hdr.hdr.it_pad = 0;
352 radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr)); 352 radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
353 radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT); 353 radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
354 /* unknown values */ 354 if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
355 radiotap_hdr.flags = 0; 355 radiotap_hdr.flags |= IEEE80211_RADIOTAP_F_BADFCS;
356 radiotap_hdr.chan_freq = 0;
357 radiotap_hdr.chan_flags = 0;
358 radiotap_hdr.antenna = 0;
359 /* known values */
360 radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate); 356 radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
361 /* XXX must check no carryout */ 357 /* XXX must check no carryout */
362 radiotap_hdr.antsignal = prxpd->snr + prxpd->nf; 358 radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
363 radiotap_hdr.rx_flags = 0;
364 if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
365 radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
366 //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
367 359
368 /* chop the rxpd */ 360 /* chop the rxpd */
369 skb_pull(skb, sizeof(struct rxpd)); 361 skb_pull(skb, sizeof(struct rxpd));
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 2368b7f825a2..d4fdc8b7d7d8 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -933,7 +933,6 @@ static int __init init_mac80211_hwsim(void)
933 BIT(NL80211_IFTYPE_STATION) | 933 BIT(NL80211_IFTYPE_STATION) |
934 BIT(NL80211_IFTYPE_AP) | 934 BIT(NL80211_IFTYPE_AP) |
935 BIT(NL80211_IFTYPE_MESH_POINT); 935 BIT(NL80211_IFTYPE_MESH_POINT);
936 hw->ampdu_queues = 1;
937 936
938 hw->flags = IEEE80211_HW_MFP_CAPABLE; 937 hw->flags = IEEE80211_HW_MFP_CAPABLE;
939 938
@@ -1041,6 +1040,9 @@ static int __init init_mac80211_hwsim(void)
1041 break; 1040 break;
1042 } 1041 }
1043 1042
1043 /* give the regulatory workqueue a chance to run */
1044 if (regtest)
1045 schedule_timeout_interruptible(1);
1044 err = ieee80211_register_hw(hw); 1046 err = ieee80211_register_hw(hw);
1045 if (err < 0) { 1047 if (err < 0) {
1046 printk(KERN_DEBUG "mac80211_hwsim: " 1048 printk(KERN_DEBUG "mac80211_hwsim: "
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig
index cfc5f41aa136..b45d6a4ed1e8 100644
--- a/drivers/net/wireless/p54/Kconfig
+++ b/drivers/net/wireless/p54/Kconfig
@@ -1,9 +1,10 @@
1config P54_COMMON 1config P54_COMMON
2 tristate "Softmac Prism54 support" 2 tristate "Softmac Prism54 support"
3 depends on MAC80211 && WLAN_80211 && FW_LOADER && EXPERIMENTAL 3 depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
4 select FW_LOADER
4 ---help--- 5 ---help---
5 This is common code for isl38xx based cards. 6 This is common code for isl38xx/stlc45xx based modules.
6 This module does nothing by itself - the USB/PCI frontends 7 This module does nothing by itself - the USB/PCI/SPI front-ends
7 also need to be enabled in order to support any devices. 8 also need to be enabled in order to support any devices.
8 9
9 These devices require softmac firmware which can be found at 10 These devices require softmac firmware which can be found at
@@ -17,31 +18,6 @@ config P54_USB
17 select CRC32 18 select CRC32
18 ---help--- 19 ---help---
19 This driver is for USB isl38xx based wireless cards. 20 This driver is for USB isl38xx based wireless cards.
20 These are USB based adapters found in devices such as:
21
22 3COM 3CRWE254G72
23 SMC 2862W-G
24 Accton 802.11g WN4501 USB
25 Siemens Gigaset USB
26 Netgear WG121
27 Netgear WG111
28 Medion 40900, Roper Europe
29 Shuttle PN15, Airvast WM168g, IOGear GWU513
30 Linksys WUSB54G
31 Linksys WUSB54G Portable
32 DLink DWL-G120 Spinnaker
33 DLink DWL-G122
34 Belkin F5D7050 ver 1000
35 Cohiba Proto board
36 SMC 2862W-G version 2
37 U.S. Robotics U5 802.11g Adapter
38 FUJITSU E-5400 USB D1700
39 Sagem XG703A
40 DLink DWL-G120 Cohiba
41 Spinnaker Proto board
42 Linksys WUSB54AG
43 Inventel UR054G
44 Spinnaker DUT
45 21
46 These devices require softmac firmware which can be found at 22 These devices require softmac firmware which can be found at
47 http://prism54.org/ 23 http://prism54.org/
@@ -64,10 +40,15 @@ config P54_PCI
64 40
65config P54_SPI 41config P54_SPI
66 tristate "Prism54 SPI (stlc45xx) support" 42 tristate "Prism54 SPI (stlc45xx) support"
67 depends on P54_COMMON && SPI_MASTER 43 depends on P54_COMMON && SPI_MASTER && GENERIC_HARDIRQS
68 ---help--- 44 ---help---
69 This driver is for stlc4550 or stlc4560 based wireless chips. 45 This driver is for stlc4550 or stlc4560 based wireless chips.
70 This driver is experimental, untested and will probably only work on 46 This driver is experimental, untested and will probably only work on
71 Nokia's N800/N810 Portable Internet Tablet. 47 Nokia's N800/N810 Portable Internet Tablet.
72 48
73 If you choose to build a module, it'll be called p54spi. 49 If you choose to build a module, it'll be called p54spi.
50
51config P54_LEDS
52 bool
53 depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON)
54 default y
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 0a989834b70d..0c1b0577d4ee 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -21,9 +21,9 @@
21#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
22 22
23#include <net/mac80211.h> 23#include <net/mac80211.h>
24#ifdef CONFIG_MAC80211_LEDS 24#ifdef CONFIG_P54_LEDS
25#include <linux/leds.h> 25#include <linux/leds.h>
26#endif /* CONFIG_MAC80211_LEDS */ 26#endif /* CONFIG_P54_LEDS */
27 27
28#include "p54.h" 28#include "p54.h"
29#include "p54common.h" 29#include "p54common.h"
@@ -2420,7 +2420,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
2420 return 0; 2420 return 0;
2421} 2421}
2422 2422
2423#ifdef CONFIG_MAC80211_LEDS 2423#ifdef CONFIG_P54_LEDS
2424static void p54_led_brightness_set(struct led_classdev *led_dev, 2424static void p54_led_brightness_set(struct led_classdev *led_dev,
2425 enum led_brightness brightness) 2425 enum led_brightness brightness)
2426{ 2426{
@@ -2508,7 +2508,7 @@ static void p54_unregister_leds(struct ieee80211_hw *dev)
2508 if (priv->assoc_led.registered) 2508 if (priv->assoc_led.registered)
2509 led_classdev_unregister(&priv->assoc_led.led_dev); 2509 led_classdev_unregister(&priv->assoc_led.led_dev);
2510} 2510}
2511#endif /* CONFIG_MAC80211_LEDS */ 2511#endif /* CONFIG_P54_LEDS */
2512 2512
2513static const struct ieee80211_ops p54_ops = { 2513static const struct ieee80211_ops p54_ops = {
2514 .tx = p54_tx, 2514 .tx = p54_tx,
@@ -2592,11 +2592,11 @@ int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
2592 return err; 2592 return err;
2593 } 2593 }
2594 2594
2595 #ifdef CONFIG_MAC80211_LEDS 2595#ifdef CONFIG_P54_LEDS
2596 err = p54_init_leds(dev); 2596 err = p54_init_leds(dev);
2597 if (err) 2597 if (err)
2598 return err; 2598 return err;
2599 #endif /* CONFIG_MAC80211_LEDS */ 2599#endif /* CONFIG_P54_LEDS */
2600 2600
2601 dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy)); 2601 dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
2602 return 0; 2602 return 0;
@@ -2610,9 +2610,9 @@ void p54_free_common(struct ieee80211_hw *dev)
2610 kfree(priv->output_limit); 2610 kfree(priv->output_limit);
2611 kfree(priv->curve_data); 2611 kfree(priv->curve_data);
2612 2612
2613 #ifdef CONFIG_MAC80211_LEDS 2613#ifdef CONFIG_P54_LEDS
2614 p54_unregister_leds(dev); 2614 p54_unregister_leds(dev);
2615 #endif /* CONFIG_MAC80211_LEDS */ 2615#endif /* CONFIG_P54_LEDS */
2616} 2616}
2617EXPORT_SYMBOL_GPL(p54_free_common); 2617EXPORT_SYMBOL_GPL(p54_free_common);
2618 2618
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 24fdfdfee3df..420fff42c0dd 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2425,6 +2425,8 @@ static struct usb_device_id rt73usb_device_table[] = {
2425 { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) }, 2425 { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
2426 /* Surecom */ 2426 /* Surecom */
2427 { USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) }, 2427 { USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) },
2428 /* Tilgin */
2429 { USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) },
2428 /* Philips */ 2430 /* Philips */
2429 { USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) }, 2431 { USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) },
2430 /* Planex */ 2432 /* Planex */
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index b1b947edcf01..540a2948596c 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -53,11 +53,11 @@ config SSB_B43_PCI_BRIDGE
53 53
54config SSB_PCMCIAHOST_POSSIBLE 54config SSB_PCMCIAHOST_POSSIBLE
55 bool 55 bool
56 depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL 56 depends on SSB && (PCMCIA = y || PCMCIA = SSB)
57 default y 57 default y
58 58
59config SSB_PCMCIAHOST 59config SSB_PCMCIAHOST
60 bool "Support for SSB on PCMCIA-bus host (EXPERIMENTAL)" 60 bool "Support for SSB on PCMCIA-bus host"
61 depends on SSB_PCMCIAHOST_POSSIBLE 61 depends on SSB_PCMCIAHOST_POSSIBLE
62 select SSB_SPROM 62 select SSB_SPROM
63 help 63 help
@@ -107,14 +107,14 @@ config SSB_DRIVER_PCICORE
107 If unsure, say Y 107 If unsure, say Y
108 108
109config SSB_PCICORE_HOSTMODE 109config SSB_PCICORE_HOSTMODE
110 bool "Hostmode support for SSB PCI core (EXPERIMENTAL)" 110 bool "Hostmode support for SSB PCI core"
111 depends on SSB_DRIVER_PCICORE && SSB_DRIVER_MIPS && EXPERIMENTAL 111 depends on SSB_DRIVER_PCICORE && SSB_DRIVER_MIPS
112 help 112 help
113 PCIcore hostmode operation (external PCI bus). 113 PCIcore hostmode operation (external PCI bus).
114 114
115config SSB_DRIVER_MIPS 115config SSB_DRIVER_MIPS
116 bool "SSB Broadcom MIPS core driver (EXPERIMENTAL)" 116 bool "SSB Broadcom MIPS core driver"
117 depends on SSB && MIPS && EXPERIMENTAL 117 depends on SSB && MIPS
118 select SSB_SERIAL 118 select SSB_SERIAL
119 help 119 help
120 Driver for the Sonics Silicon Backplane attached 120 Driver for the Sonics Silicon Backplane attached
@@ -129,8 +129,8 @@ config SSB_EMBEDDED
129 default y 129 default y
130 130
131config SSB_DRIVER_EXTIF 131config SSB_DRIVER_EXTIF
132 bool "SSB Broadcom EXTIF core driver (EXPERIMENTAL)" 132 bool "SSB Broadcom EXTIF core driver"
133 depends on SSB_DRIVER_MIPS && EXPERIMENTAL 133 depends on SSB_DRIVER_MIPS
134 help 134 help
135 Driver for the Sonics Silicon Backplane attached 135 Driver for the Sonics Silicon Backplane attached
136 Broadcom EXTIF core. 136 Broadcom EXTIF core.
diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c
index 27a677584a4c..ef9c6a04ad8f 100644
--- a/drivers/ssb/b43_pci_bridge.c
+++ b/drivers/ssb/b43_pci_bridge.c
@@ -18,6 +18,7 @@
18 18
19static const struct pci_device_id b43_pci_bridge_tbl[] = { 19static const struct pci_device_id b43_pci_bridge_tbl[] = {
20 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4301) }, 20 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4301) },
21 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4306) },
21 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4307) }, 22 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4307) },
22 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4311) }, 23 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4311) },
23 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) }, 24 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index b1bb817d1427..4b501b48ce86 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -18,6 +18,22 @@
18#include <linux/types.h> 18#include <linux/types.h>
19#include <asm/byteorder.h> 19#include <asm/byteorder.h>
20 20
21/*
22 * DS bit usage
23 *
24 * TA = transmitter address
25 * RA = receiver address
26 * DA = destination address
27 * SA = source address
28 *
29 * ToDS FromDS A1(RA) A2(TA) A3 A4 Use
30 * -----------------------------------------------------------------
31 * 0 0 DA SA BSSID - IBSS/DLS
32 * 0 1 DA BSSID SA - AP -> STA
33 * 1 0 BSSID SA DA - AP <- STA
34 * 1 1 RA TA DA SA unspecified (WDS)
35 */
36
21#define FCS_LEN 4 37#define FCS_LEN 4
22 38
23#define IEEE80211_FCTL_VERS 0x0003 39#define IEEE80211_FCTL_VERS 0x0003
@@ -851,6 +867,7 @@ struct ieee80211_ht_info {
851/* Authentication algorithms */ 867/* Authentication algorithms */
852#define WLAN_AUTH_OPEN 0 868#define WLAN_AUTH_OPEN 0
853#define WLAN_AUTH_SHARED_KEY 1 869#define WLAN_AUTH_SHARED_KEY 1
870#define WLAN_AUTH_FT 2
854#define WLAN_AUTH_LEAP 128 871#define WLAN_AUTH_LEAP 128
855 872
856#define WLAN_AUTH_CHALLENGE_LEN 128 873#define WLAN_AUTH_CHALLENGE_LEN 128
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index f33aa08dd9b3..cbe8ce3bf486 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -142,6 +142,12 @@
142 * %NL80211_ATTR_IE. If the command succeeds, the requested data will be 142 * %NL80211_ATTR_IE. If the command succeeds, the requested data will be
143 * added to all specified management frames generated by 143 * added to all specified management frames generated by
144 * kernel/firmware/driver. 144 * kernel/firmware/driver.
145 * Note: This command has been removed and it is only reserved at this
146 * point to avoid re-using existing command number. The functionality this
147 * command was planned for has been provided with cleaner design with the
148 * option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN,
149 * NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE,
150 * NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE.
145 * 151 *
146 * @NL80211_CMD_GET_SCAN: get scan results 152 * @NL80211_CMD_GET_SCAN: get scan results
147 * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters 153 * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
@@ -161,6 +167,38 @@
161 * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on 167 * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
162 * to (%NL80211_ATTR_REG_ALPHA2). 168 * to (%NL80211_ATTR_REG_ALPHA2).
163 * 169 *
170 * @NL80211_CMD_AUTHENTICATE: authentication request and notification.
171 * This command is used both as a command (request to authenticate) and
172 * as an event on the "mlme" multicast group indicating completion of the
173 * authentication process.
174 * When used as a command, %NL80211_ATTR_IFINDEX is used to identify the
175 * interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and
176 * BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
177 * the SSID (mainly for association, but is included in authentication
178 * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used
179 * to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE
180 * is used to specify the authentication type. %NL80211_ATTR_IE is used to
181 * define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs)
182 * to be added to the frame.
183 * When used as an event, this reports reception of an Authentication
184 * frame in station and IBSS modes when the local MLME processed the
185 * frame, i.e., it was for the local STA and was received in correct
186 * state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
187 * MLME SAP interface (kernel providing MLME, userspace SME). The
188 * included NL80211_ATTR_FRAME attribute contains the management frame
189 * (including both the header and frame body, but not FCS).
190 * @NL80211_CMD_ASSOCIATE: association request and notification; like
191 * NL80211_CMD_AUTHENTICATE but for Association and Reassociation
192 * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
193 * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives).
194 * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like
195 * NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to
196 * MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication
197 * primitives).
198 * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like
199 * NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to
200 * MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives).
201 *
164 * @NL80211_CMD_MAX: highest used command number 202 * @NL80211_CMD_MAX: highest used command number
165 * @__NL80211_CMD_AFTER_LAST: internal use 203 * @__NL80211_CMD_AFTER_LAST: internal use
166 */ 204 */
@@ -206,7 +244,7 @@ enum nl80211_commands {
206 NL80211_CMD_GET_MESH_PARAMS, 244 NL80211_CMD_GET_MESH_PARAMS,
207 NL80211_CMD_SET_MESH_PARAMS, 245 NL80211_CMD_SET_MESH_PARAMS,
208 246
209 NL80211_CMD_SET_MGMT_EXTRA_IE, 247 NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
210 248
211 NL80211_CMD_GET_REG, 249 NL80211_CMD_GET_REG,
212 250
@@ -217,6 +255,11 @@ enum nl80211_commands {
217 255
218 NL80211_CMD_REG_CHANGE, 256 NL80211_CMD_REG_CHANGE,
219 257
258 NL80211_CMD_AUTHENTICATE,
259 NL80211_CMD_ASSOCIATE,
260 NL80211_CMD_DEAUTHENTICATE,
261 NL80211_CMD_DISASSOCIATE,
262
220 /* add new commands above here */ 263 /* add new commands above here */
221 264
222 /* used to define NL80211_CMD_MAX below */ 265 /* used to define NL80211_CMD_MAX below */
@@ -230,8 +273,11 @@ enum nl80211_commands {
230 */ 273 */
231#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS 274#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
232#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE 275#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE
233
234#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE 276#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE
277#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE
278#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
279#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
280#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
235 281
236/** 282/**
237 * enum nl80211_attrs - nl80211 netlink attributes 283 * enum nl80211_attrs - nl80211 netlink attributes
@@ -349,6 +395,19 @@ enum nl80211_commands {
349 * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently 395 * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently
350 * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*) 396 * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
351 * 397 *
398 * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies
399 * an array of command numbers (i.e. a mapping index to command number)
400 * that the driver for the given wiphy supports.
401 *
402 * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header
403 * and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and
404 * NL80211_CMD_ASSOCIATE events
405 * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets)
406 * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type,
407 * represented as a u32
408 * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and
409 * %NL80211_CMD_DISASSOCIATE, u16
410 *
352 * @NL80211_ATTR_MAX: highest attribute number currently defined 411 * @NL80211_ATTR_MAX: highest attribute number currently defined
353 * @__NL80211_ATTR_AFTER_LAST: internal use 412 * @__NL80211_ATTR_AFTER_LAST: internal use
354 */ 413 */
@@ -426,6 +485,13 @@ enum nl80211_attrs {
426 NL80211_ATTR_REG_INITIATOR, 485 NL80211_ATTR_REG_INITIATOR,
427 NL80211_ATTR_REG_TYPE, 486 NL80211_ATTR_REG_TYPE,
428 487
488 NL80211_ATTR_SUPPORTED_COMMANDS,
489
490 NL80211_ATTR_FRAME,
491 NL80211_ATTR_SSID,
492 NL80211_ATTR_AUTH_TYPE,
493 NL80211_ATTR_REASON_CODE,
494
429 /* add attributes here, update the policy in nl80211.c */ 495 /* add attributes here, update the policy in nl80211.c */
430 496
431 __NL80211_ATTR_AFTER_LAST, 497 __NL80211_ATTR_AFTER_LAST,
@@ -445,6 +511,10 @@ enum nl80211_attrs {
445#define NL80211_ATTR_IE NL80211_ATTR_IE 511#define NL80211_ATTR_IE NL80211_ATTR_IE
446#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR 512#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
447#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE 513#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE
514#define NL80211_ATTR_FRAME NL80211_ATTR_FRAME
515#define NL80211_ATTR_SSID NL80211_ATTR_SSID
516#define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE
517#define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE
448 518
449#define NL80211_MAX_SUPP_RATES 32 519#define NL80211_MAX_SUPP_RATES 32
450#define NL80211_MAX_SUPP_REG_RULES 32 520#define NL80211_MAX_SUPP_REG_RULES 32
@@ -978,4 +1048,18 @@ enum nl80211_bss {
978 NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1 1048 NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
979}; 1049};
980 1050
1051/**
1052 * enum nl80211_auth_type - AuthenticationType
1053 *
1054 * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication
1055 * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only)
1056 * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r)
1057 * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP)
1058 */
1059enum nl80211_auth_type {
1060 NL80211_AUTHTYPE_OPEN_SYSTEM,
1061 NL80211_AUTHTYPE_SHARED_KEY,
1062 NL80211_AUTHTYPE_FT,
1063 NL80211_AUTHTYPE_NETWORK_EAP,
1064};
981#endif /* __LINUX_NL80211_H */ 1065#endif /* __LINUX_NL80211_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 097f410edefa..05dfa7c4fb64 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2271,6 +2271,8 @@
2271#define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 2271#define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600
2272#define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff 2272#define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff
2273 2273
2274#define PCI_VENDOR_ID_QMI 0x1a32
2275
2274#define PCI_VENDOR_ID_TEKRAM 0x1de1 2276#define PCI_VENDOR_ID_TEKRAM 0x1de1
2275#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 2277#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
2276 2278
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 50f3fd9ff524..5389afdc1297 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -471,26 +471,6 @@ struct ieee80211_txq_params {
471 u8 aifs; 471 u8 aifs;
472}; 472};
473 473
474/**
475 * struct mgmt_extra_ie_params - Extra management frame IE parameters
476 *
477 * Used to add extra IE(s) into management frames. If the driver cannot add the
478 * requested data into all management frames of the specified subtype that are
479 * generated in kernel or firmware/hardware, it must reject the configuration
480 * call. The IE data buffer is added to the end of the specified management
481 * frame body after all other IEs. This addition is not applied to frames that
482 * are injected through a monitor interface.
483 *
484 * @subtype: Management frame subtype
485 * @ies: IE data buffer or %NULL to remove previous data
486 * @ies_len: Length of @ies in octets
487 */
488struct mgmt_extra_ie_params {
489 u8 subtype;
490 u8 *ies;
491 int ies_len;
492};
493
494/* from net/wireless.h */ 474/* from net/wireless.h */
495struct wiphy; 475struct wiphy;
496 476
@@ -559,6 +539,7 @@ enum cfg80211_signal_type {
559 * is no guarantee that these are well-formed!) 539 * is no guarantee that these are well-formed!)
560 * @len_information_elements: total length of the information elements 540 * @len_information_elements: total length of the information elements
561 * @signal: signal strength value (type depends on the wiphy's signal_type) 541 * @signal: signal strength value (type depends on the wiphy's signal_type)
542 * @hold: BSS should not expire
562 * @free_priv: function pointer to free private data 543 * @free_priv: function pointer to free private data
563 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes 544 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
564 */ 545 */
@@ -579,6 +560,105 @@ struct cfg80211_bss {
579}; 560};
580 561
581/** 562/**
563 * struct cfg80211_auth_request - Authentication request data
564 *
565 * This structure provides information needed to complete IEEE 802.11
566 * authentication.
567 * NOTE: This structure will likely change when more code from mac80211 is
568 * moved into cfg80211 so that non-mac80211 drivers can benefit from it, too.
569 * Before using this in a driver that does not use mac80211, it would be better
570 * to check the status of that work and better yet, volunteer to work on it.
571 *
572 * @chan: The channel to use or %NULL if not specified (auto-select based on
573 * scan results)
574 * @peer_addr: The address of the peer STA (AP BSSID in infrastructure case);
575 * this field is required to be present; if the driver wants to help with
576 * BSS selection, it should use (yet to be added) MLME event to allow user
577 * space SME to be notified of roaming candidate, so that the SME can then
578 * use the authentication request with the recommended BSSID and whatever
579 * other data may be needed for authentication/association
580 * @ssid: SSID or %NULL if not yet available
581 * @ssid_len: Length of ssid in octets
582 * @auth_type: Authentication type (algorithm)
583 * @ie: Extra IEs to add to Authentication frame or %NULL
584 * @ie_len: Length of ie buffer in octets
585 */
586struct cfg80211_auth_request {
587 struct ieee80211_channel *chan;
588 u8 *peer_addr;
589 const u8 *ssid;
590 size_t ssid_len;
591 enum nl80211_auth_type auth_type;
592 const u8 *ie;
593 size_t ie_len;
594};
595
596/**
597 * struct cfg80211_assoc_request - (Re)Association request data
598 *
599 * This structure provides information needed to complete IEEE 802.11
600 * (re)association.
601 * NOTE: This structure will likely change when more code from mac80211 is
602 * moved into cfg80211 so that non-mac80211 drivers can benefit from it, too.
603 * Before using this in a driver that does not use mac80211, it would be better
604 * to check the status of that work and better yet, volunteer to work on it.
605 *
606 * @chan: The channel to use or %NULL if not specified (auto-select based on
607 * scan results)
608 * @peer_addr: The address of the peer STA (AP BSSID); this field is required
609 * to be present and the STA must be in State 2 (authenticated) with the
610 * peer STA
611 * @ssid: SSID
612 * @ssid_len: Length of ssid in octets
613 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
614 * @ie_len: Length of ie buffer in octets
615 */
616struct cfg80211_assoc_request {
617 struct ieee80211_channel *chan;
618 u8 *peer_addr;
619 const u8 *ssid;
620 size_t ssid_len;
621 const u8 *ie;
622 size_t ie_len;
623};
624
625/**
626 * struct cfg80211_deauth_request - Deauthentication request data
627 *
628 * This structure provides information needed to complete IEEE 802.11
629 * deauthentication.
630 *
631 * @peer_addr: The address of the peer STA (AP BSSID); this field is required
632 * to be present and the STA must be authenticated with the peer STA
633 * @ie: Extra IEs to add to Deauthentication frame or %NULL
634 * @ie_len: Length of ie buffer in octets
635 */
636struct cfg80211_deauth_request {
637 u8 *peer_addr;
638 u16 reason_code;
639 const u8 *ie;
640 size_t ie_len;
641};
642
643/**
644 * struct cfg80211_disassoc_request - Disassociation request data
645 *
646 * This structure provides information needed to complete IEEE 802.11
647 * disassocation.
648 *
649 * @peer_addr: The address of the peer STA (AP BSSID); this field is required
650 * to be present and the STA must be associated with the peer STA
651 * @ie: Extra IEs to add to Disassociation frame or %NULL
652 * @ie_len: Length of ie buffer in octets
653 */
654struct cfg80211_disassoc_request {
655 u8 *peer_addr;
656 u16 reason_code;
657 const u8 *ie;
658 size_t ie_len;
659};
660
661/**
582 * struct cfg80211_ops - backend description for wireless configuration 662 * struct cfg80211_ops - backend description for wireless configuration
583 * 663 *
584 * This struct is registered by fullmac card drivers and/or wireless stacks 664 * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -644,12 +724,15 @@ struct cfg80211_bss {
644 * 724 *
645 * @set_channel: Set channel 725 * @set_channel: Set channel
646 * 726 *
647 * @set_mgmt_extra_ie: Set extra IE data for management frames
648 *
649 * @scan: Request to do a scan. If returning zero, the scan request is given 727 * @scan: Request to do a scan. If returning zero, the scan request is given
650 * the driver, and will be valid until passed to cfg80211_scan_done(). 728 * the driver, and will be valid until passed to cfg80211_scan_done().
651 * For scan results, call cfg80211_inform_bss(); you can call this outside 729 * For scan results, call cfg80211_inform_bss(); you can call this outside
652 * the scan/scan_done bracket too. 730 * the scan/scan_done bracket too.
731 *
732 * @auth: Request to authenticate with the specified peer
733 * @assoc: Request to (re)associate with the specified peer
734 * @deauth: Request to deauthenticate from the specified peer
735 * @disassoc: Request to disassociate from the specified peer
653 */ 736 */
654struct cfg80211_ops { 737struct cfg80211_ops {
655 int (*suspend)(struct wiphy *wiphy); 738 int (*suspend)(struct wiphy *wiphy);
@@ -724,12 +807,17 @@ struct cfg80211_ops {
724 struct ieee80211_channel *chan, 807 struct ieee80211_channel *chan,
725 enum nl80211_channel_type channel_type); 808 enum nl80211_channel_type channel_type);
726 809
727 int (*set_mgmt_extra_ie)(struct wiphy *wiphy,
728 struct net_device *dev,
729 struct mgmt_extra_ie_params *params);
730
731 int (*scan)(struct wiphy *wiphy, struct net_device *dev, 810 int (*scan)(struct wiphy *wiphy, struct net_device *dev,
732 struct cfg80211_scan_request *request); 811 struct cfg80211_scan_request *request);
812
813 int (*auth)(struct wiphy *wiphy, struct net_device *dev,
814 struct cfg80211_auth_request *req);
815 int (*assoc)(struct wiphy *wiphy, struct net_device *dev,
816 struct cfg80211_assoc_request *req);
817 int (*deauth)(struct wiphy *wiphy, struct net_device *dev,
818 struct cfg80211_deauth_request *req);
819 int (*disassoc)(struct wiphy *wiphy, struct net_device *dev,
820 struct cfg80211_disassoc_request *req);
733}; 821};
734 822
735/* temporary wext handlers */ 823/* temporary wext handlers */
@@ -807,4 +895,67 @@ void cfg80211_put_bss(struct cfg80211_bss *bss);
807 */ 895 */
808void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); 896void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
809 897
898/**
899 * cfg80211_send_rx_auth - notification of processed authentication
900 * @dev: network device
901 * @buf: authentication frame (header + body)
902 * @len: length of the frame data
903 *
904 * This function is called whenever an authentication has been processed in
905 * station mode.
906 */
907void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
908
909/**
910 * cfg80211_send_rx_assoc - notification of processed association
911 * @dev: network device
912 * @buf: (re)association response frame (header + body)
913 * @len: length of the frame data
914 *
915 * This function is called whenever a (re)association response has been
916 * processed in station mode.
917 */
918void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
919
920/**
921 * cfg80211_send_rx_deauth - notification of processed deauthentication
922 * @dev: network device
923 * @buf: deauthentication frame (header + body)
924 * @len: length of the frame data
925 *
926 * This function is called whenever deauthentication has been processed in
927 * station mode.
928 */
929void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf,
930 size_t len);
931
932/**
933 * cfg80211_send_rx_disassoc - notification of processed disassociation
934 * @dev: network device
935 * @buf: disassociation response frame (header + body)
936 * @len: length of the frame data
937 *
938 * This function is called whenever disassociation has been processed in
939 * station mode.
940 */
941void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
942 size_t len);
943
944/**
945 * cfg80211_hold_bss - exclude bss from expiration
946 * @bss: bss which should not expire
947 *
948 * In a case when the BSS is not updated but it shouldn't expire this
949 * function can be used to mark the BSS to be excluded from expiration.
950 */
951void cfg80211_hold_bss(struct cfg80211_bss *bss);
952
953/**
954 * cfg80211_unhold_bss - remove expiration exception from the BSS
955 * @bss: bss which can expire again
956 *
957 * This function marks the BSS to be expirable again.
958 */
959void cfg80211_unhold_bss(struct cfg80211_bss *bss);
960
810#endif /* __NET_CFG80211_H */ 961#endif /* __NET_CFG80211_H */
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 384698cb773a..23c3f3d97779 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -230,8 +230,10 @@ enum ieee80211_radiotap_type {
230 * 802.11 header and payload 230 * 802.11 header and payload
231 * (to 32-bit boundary) 231 * (to 32-bit boundary)
232 */ 232 */
233#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */
234
233/* For IEEE80211_RADIOTAP_RX_FLAGS */ 235/* For IEEE80211_RADIOTAP_RX_FLAGS */
234#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ 236#define IEEE80211_RADIOTAP_F_RX_BADPLCP 0x0002 /* frame has bad PLCP */
235 237
236/* For IEEE80211_RADIOTAP_TX_FLAGS */ 238/* For IEEE80211_RADIOTAP_TX_FLAGS */
237#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive 239#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 12a52efcd0d1..3b83a80e3fe0 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -93,12 +93,9 @@ struct ieee80211_ht_bss_info {
93 * enum ieee80211_max_queues - maximum number of queues 93 * enum ieee80211_max_queues - maximum number of queues
94 * 94 *
95 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. 95 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
96 * @IEEE80211_MAX_AMPDU_QUEUES: Maximum number of queues usable
97 * for A-MPDU operation.
98 */ 96 */
99enum ieee80211_max_queues { 97enum ieee80211_max_queues {
100 IEEE80211_MAX_QUEUES = 16, 98 IEEE80211_MAX_QUEUES = 4,
101 IEEE80211_MAX_AMPDU_QUEUES = 16,
102}; 99};
103 100
104/** 101/**
@@ -245,6 +242,12 @@ struct ieee80211_bss_conf {
245 * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be 242 * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be
246 * set by rate control algorithms to indicate probe rate, will 243 * set by rate control algorithms to indicate probe rate, will
247 * be cleared for fragmented frames (except on the last fragment) 244 * be cleared for fragmented frames (except on the last fragment)
245 * @IEEE80211_TX_INTFL_RCALGO: mac80211 internal flag, do not test or
246 * set this flag in the driver; indicates that the rate control
247 * algorithm was used and should be notified of TX status
248 * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211,
249 * used to indicate that a pending frame requires TX processing before
250 * it can be sent out.
248 */ 251 */
249enum mac80211_tx_control_flags { 252enum mac80211_tx_control_flags {
250 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), 253 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -260,6 +263,8 @@ enum mac80211_tx_control_flags {
260 IEEE80211_TX_STAT_AMPDU = BIT(10), 263 IEEE80211_TX_STAT_AMPDU = BIT(10),
261 IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11), 264 IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11),
262 IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), 265 IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12),
266 IEEE80211_TX_INTFL_RCALGO = BIT(13),
267 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14),
263}; 268};
264 269
265/** 270/**
@@ -520,12 +525,6 @@ enum ieee80211_conf_flags {
520 IEEE80211_CONF_PS = (1<<1), 525 IEEE80211_CONF_PS = (1<<1),
521}; 526};
522 527
523/* XXX: remove all this once drivers stop trying to use it */
524static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void)
525{
526 return 0;
527}
528#define IEEE80211_CONF_SHORT_SLOT_TIME (__IEEE80211_CONF_SHORT_SLOT_TIME())
529 528
530/** 529/**
531 * enum ieee80211_conf_changed - denotes which configuration changed 530 * enum ieee80211_conf_changed - denotes which configuration changed
@@ -888,6 +887,10 @@ enum ieee80211_tkip_key_type {
888 * 887 *
889 * @IEEE80211_HW_MFP_CAPABLE: 888 * @IEEE80211_HW_MFP_CAPABLE:
890 * Hardware supports management frame protection (MFP, IEEE 802.11w). 889 * Hardware supports management frame protection (MFP, IEEE 802.11w).
890 *
891 * @IEEE80211_HW_BEACON_FILTER:
892 * Hardware supports dropping of irrelevant beacon frames to
893 * avoid waking up cpu.
891 */ 894 */
892enum ieee80211_hw_flags { 895enum ieee80211_hw_flags {
893 IEEE80211_HW_RX_INCLUDES_FCS = 1<<1, 896 IEEE80211_HW_RX_INCLUDES_FCS = 1<<1,
@@ -903,6 +906,7 @@ enum ieee80211_hw_flags {
903 IEEE80211_HW_PS_NULLFUNC_STACK = 1<<11, 906 IEEE80211_HW_PS_NULLFUNC_STACK = 1<<11,
904 IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, 907 IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12,
905 IEEE80211_HW_MFP_CAPABLE = 1<<13, 908 IEEE80211_HW_MFP_CAPABLE = 1<<13,
909 IEEE80211_HW_BEACON_FILTER = 1<<14,
906}; 910};
907 911
908/** 912/**
@@ -945,12 +949,6 @@ enum ieee80211_hw_flags {
945 * data packets. WMM/QoS requires at least four, these 949 * data packets. WMM/QoS requires at least four, these
946 * queues need to have configurable access parameters. 950 * queues need to have configurable access parameters.
947 * 951 *
948 * @ampdu_queues: number of available hardware transmit queues
949 * for A-MPDU packets, these have no access parameters
950 * because they're used only for A-MPDU frames. Note that
951 * mac80211 will not currently use any of the regular queues
952 * for aggregation.
953 *
954 * @rate_control_algorithm: rate control algorithm for this hardware. 952 * @rate_control_algorithm: rate control algorithm for this hardware.
955 * If unset (NULL), the default algorithm will be used. Must be 953 * If unset (NULL), the default algorithm will be used. Must be
956 * set before calling ieee80211_register_hw(). 954 * set before calling ieee80211_register_hw().
@@ -975,7 +973,6 @@ struct ieee80211_hw {
975 int vif_data_size; 973 int vif_data_size;
976 int sta_data_size; 974 int sta_data_size;
977 u16 queues; 975 u16 queues;
978 u16 ampdu_queues;
979 u16 max_listen_interval; 976 u16 max_listen_interval;
980 s8 max_signal; 977 s8 max_signal;
981 u8 max_rates; 978 u8 max_rates;
@@ -1017,11 +1014,6 @@ static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr)
1017 memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN); 1014 memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN);
1018} 1015}
1019 1016
1020static inline int ieee80211_num_regular_queues(struct ieee80211_hw *hw)
1021{
1022 return hw->queues;
1023}
1024
1025static inline struct ieee80211_rate * 1017static inline struct ieee80211_rate *
1026ieee80211_get_tx_rate(const struct ieee80211_hw *hw, 1018ieee80211_get_tx_rate(const struct ieee80211_hw *hw,
1027 const struct ieee80211_tx_info *c) 1019 const struct ieee80211_tx_info *c)
@@ -1132,6 +1124,24 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
1132 */ 1124 */
1133 1125
1134/** 1126/**
1127 * DOC: Beacon filter support
1128 *
1129 * Some hardware have beacon filter support to reduce host cpu wakeups
1130 * which will reduce system power consumption. It usuallly works so that
1131 * the firmware creates a checksum of the beacon but omits all constantly
1132 * changing elements (TSF, TIM etc). Whenever the checksum changes the
1133 * beacon is forwarded to the host, otherwise it will be just dropped. That
1134 * way the host will only receive beacons where some relevant information
1135 * (for example ERP protection or WMM settings) have changed.
1136 *
1137 * Beacon filter support is informed with %IEEE80211_HW_BEACON_FILTER flag.
1138 * The driver needs to enable beacon filter support whenever power save is
1139 * enabled, that is %IEEE80211_CONF_PS is set. When power save is enabled,
1140 * the stack will not check for beacon miss at all and the driver needs to
1141 * notify about complete loss of beacons with ieee80211_beacon_loss().
1142 */
1143
1144/**
1135 * DOC: Frame filtering 1145 * DOC: Frame filtering
1136 * 1146 *
1137 * mac80211 requires to see many management frames for proper 1147 * mac80211 requires to see many management frames for proper
@@ -1220,14 +1230,14 @@ enum ieee80211_filter_flags {
1220 * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation 1230 * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation
1221 * @IEEE80211_AMPDU_TX_START: start Tx aggregation 1231 * @IEEE80211_AMPDU_TX_START: start Tx aggregation
1222 * @IEEE80211_AMPDU_TX_STOP: stop Tx aggregation 1232 * @IEEE80211_AMPDU_TX_STOP: stop Tx aggregation
1223 * @IEEE80211_AMPDU_TX_RESUME: resume TX aggregation 1233 * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational
1224 */ 1234 */
1225enum ieee80211_ampdu_mlme_action { 1235enum ieee80211_ampdu_mlme_action {
1226 IEEE80211_AMPDU_RX_START, 1236 IEEE80211_AMPDU_RX_START,
1227 IEEE80211_AMPDU_RX_STOP, 1237 IEEE80211_AMPDU_RX_STOP,
1228 IEEE80211_AMPDU_TX_START, 1238 IEEE80211_AMPDU_TX_START,
1229 IEEE80211_AMPDU_TX_STOP, 1239 IEEE80211_AMPDU_TX_STOP,
1230 IEEE80211_AMPDU_TX_RESUME, 1240 IEEE80211_AMPDU_TX_OPERATIONAL,
1231}; 1241};
1232 1242
1233/** 1243/**
@@ -1318,11 +1328,13 @@ enum ieee80211_ampdu_mlme_action {
1318 * 1328 *
1319 * @hw_scan: Ask the hardware to service the scan request, no need to start 1329 * @hw_scan: Ask the hardware to service the scan request, no need to start
1320 * the scan state machine in stack. The scan must honour the channel 1330 * the scan state machine in stack. The scan must honour the channel
1321 * configuration done by the regulatory agent in the wiphy's registered 1331 * configuration done by the regulatory agent in the wiphy's
1322 * bands. When the scan finishes, ieee80211_scan_completed() must be 1332 * registered bands. The hardware (or the driver) needs to make sure
1323 * called; note that it also must be called when the scan cannot finish 1333 * that power save is disabled. When the scan finishes,
1324 * because the hardware is turned off! Anything else is a bug! 1334 * ieee80211_scan_completed() must be called; note that it also must
1325 * Returns a negative error code which will be seen in userspace. 1335 * be called when the scan cannot finish because the hardware is
1336 * turned off! Anything else is a bug! Returns a negative error code
1337 * which will be seen in userspace.
1326 * 1338 *
1327 * @sw_scan_start: Notifier function that is called just before a software scan 1339 * @sw_scan_start: Notifier function that is called just before a software scan
1328 * is started. Can be NULL, if the driver doesn't need this notification. 1340 * is started. Can be NULL, if the driver doesn't need this notification.
@@ -1350,8 +1362,8 @@ enum ieee80211_ampdu_mlme_action {
1350 * @get_tx_stats: Get statistics of the current TX queue status. This is used 1362 * @get_tx_stats: Get statistics of the current TX queue status. This is used
1351 * to get number of currently queued packets (queue length), maximum queue 1363 * to get number of currently queued packets (queue length), maximum queue
1352 * size (limit), and total number of packets sent using each TX queue 1364 * size (limit), and total number of packets sent using each TX queue
1353 * (count). The 'stats' pointer points to an array that has hw->queues + 1365 * (count). The 'stats' pointer points to an array that has hw->queues
1354 * hw->ampdu_queues items. 1366 * items.
1355 * 1367 *
1356 * @get_tsf: Get the current TSF timer value from firmware/hardware. Currently, 1368 * @get_tsf: Get the current TSF timer value from firmware/hardware. Currently,
1357 * this is only used for IBSS mode BSSID merging and debugging. Is not a 1369 * this is only used for IBSS mode BSSID merging and debugging. Is not a
@@ -1979,6 +1991,16 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra,
1979struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, 1991struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
1980 const u8 *addr); 1992 const u8 *addr);
1981 1993
1994/**
1995 * ieee80211_beacon_loss - inform hardware does not receive beacons
1996 *
1997 * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
1998 *
1999 * When beacon filtering is enabled with IEEE80211_HW_BEACON_FILTERING and
2000 * IEEE80211_CONF_PS is set, the driver needs to inform whenever the
2001 * hardware is not receiving beacons with this function.
2002 */
2003void ieee80211_beacon_loss(struct ieee80211_vif *vif);
1982 2004
1983/* Rate control API */ 2005/* Rate control API */
1984 2006
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index a95affc94629..07656d830bc4 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -197,6 +197,14 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
197 197
198 status = WLAN_STATUS_REQUEST_DECLINED; 198 status = WLAN_STATUS_REQUEST_DECLINED;
199 199
200 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
201#ifdef CONFIG_MAC80211_HT_DEBUG
202 printk(KERN_DEBUG "Suspend in progress. "
203 "Denying ADDBA request\n");
204#endif
205 goto end_no_lock;
206 }
207
200 /* sanity check for incoming parameters: 208 /* sanity check for incoming parameters:
201 * check if configuration can support the BA policy 209 * check if configuration can support the BA policy
202 * and if buffer size does not exceeds max value */ 210 * and if buffer size does not exceeds max value */
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 1df116d4d6e7..947aaaad35d2 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -131,24 +131,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
131 131
132 state = &sta->ampdu_mlme.tid_state_tx[tid]; 132 state = &sta->ampdu_mlme.tid_state_tx[tid];
133 133
134 if (local->hw.ampdu_queues) {
135 if (initiator) {
136 /*
137 * Stop the AC queue to avoid issues where we send
138 * unaggregated frames already before the delba.
139 */
140 ieee80211_stop_queue_by_reason(&local->hw,
141 local->hw.queues + sta->tid_to_tx_q[tid],
142 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
143 }
144
145 /*
146 * Pretend the driver woke the queue, just in case
147 * it disabled it before the session was stopped.
148 */
149 ieee80211_wake_queue(
150 &local->hw, local->hw.queues + sta->tid_to_tx_q[tid]);
151 }
152 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 134 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
153 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 135 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
154 136
@@ -158,6 +140,10 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
158 /* HW shall not deny going back to legacy */ 140 /* HW shall not deny going back to legacy */
159 if (WARN_ON(ret)) { 141 if (WARN_ON(ret)) {
160 *state = HT_AGG_STATE_OPERATIONAL; 142 *state = HT_AGG_STATE_OPERATIONAL;
143 /*
144 * We may have pending packets get stuck in this case...
145 * Not bothering with a workaround for now.
146 */
161 } 147 }
162 148
163 return ret; 149 return ret;
@@ -212,7 +198,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
212 struct sta_info *sta; 198 struct sta_info *sta;
213 struct ieee80211_sub_if_data *sdata; 199 struct ieee80211_sub_if_data *sdata;
214 u8 *state; 200 u8 *state;
215 int i, qn = -1, ret = 0; 201 int ret = 0;
216 u16 start_seq_num; 202 u16 start_seq_num;
217 203
218 if (WARN_ON(!local->ops->ampdu_action)) 204 if (WARN_ON(!local->ops->ampdu_action))
@@ -226,13 +212,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
226 ra, tid); 212 ra, tid);
227#endif /* CONFIG_MAC80211_HT_DEBUG */ 213#endif /* CONFIG_MAC80211_HT_DEBUG */
228 214
229 if (hw->ampdu_queues && ieee80211_ac_from_tid(tid) == 0) {
230#ifdef CONFIG_MAC80211_HT_DEBUG
231 printk(KERN_DEBUG "rejecting on voice AC\n");
232#endif
233 return -EINVAL;
234 }
235
236 rcu_read_lock(); 215 rcu_read_lock();
237 216
238 sta = sta_info_get(local, ra); 217 sta = sta_info_get(local, ra);
@@ -257,7 +236,17 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
257 goto unlock; 236 goto unlock;
258 } 237 }
259 238
239 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
240#ifdef CONFIG_MAC80211_HT_DEBUG
241 printk(KERN_DEBUG "Suspend in progress. "
242 "Denying BA session request\n");
243#endif
244 ret = -EINVAL;
245 goto unlock;
246 }
247
260 spin_lock_bh(&sta->lock); 248 spin_lock_bh(&sta->lock);
249 spin_lock(&local->ampdu_lock);
261 250
262 sdata = sta->sdata; 251 sdata = sta->sdata;
263 252
@@ -278,41 +267,16 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
278 goto err_unlock_sta; 267 goto err_unlock_sta;
279 } 268 }
280 269
281 if (hw->ampdu_queues) { 270 /*
282 spin_lock(&local->queue_stop_reason_lock); 271 * While we're asking the driver about the aggregation,
283 /* reserve a new queue for this session */ 272 * stop the AC queue so that we don't have to worry
284 for (i = 0; i < local->hw.ampdu_queues; i++) { 273 * about frames that came in while we were doing that,
285 if (local->ampdu_ac_queue[i] < 0) { 274 * which would require us to put them to the AC pending
286 qn = i; 275 * afterwards which just makes the code more complex.
287 local->ampdu_ac_queue[qn] = 276 */
288 ieee80211_ac_from_tid(tid); 277 ieee80211_stop_queue_by_reason(
289 break; 278 &local->hw, ieee80211_ac_from_tid(tid),
290 } 279 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
291 }
292 spin_unlock(&local->queue_stop_reason_lock);
293
294 if (qn < 0) {
295#ifdef CONFIG_MAC80211_HT_DEBUG
296 printk(KERN_DEBUG "BA request denied - "
297 "queue unavailable for tid %d\n", tid);
298#endif /* CONFIG_MAC80211_HT_DEBUG */
299 ret = -ENOSPC;
300 goto err_unlock_sta;
301 }
302
303 /*
304 * If we successfully allocate the session, we can't have
305 * anything going on on the queue this TID maps into, so
306 * stop it for now. This is a "virtual" stop using the same
307 * mechanism that drivers will use.
308 *
309 * XXX: queue up frames for this session in the sta_info
310 * struct instead to avoid hitting all other STAs.
311 */
312 ieee80211_stop_queue_by_reason(
313 &local->hw, hw->queues + qn,
314 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
315 }
316 280
317 /* prepare A-MPDU MLME for Tx aggregation */ 281 /* prepare A-MPDU MLME for Tx aggregation */
318 sta->ampdu_mlme.tid_tx[tid] = 282 sta->ampdu_mlme.tid_tx[tid] =
@@ -324,9 +288,11 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
324 tid); 288 tid);
325#endif 289#endif
326 ret = -ENOMEM; 290 ret = -ENOMEM;
327 goto err_return_queue; 291 goto err_wake_queue;
328 } 292 }
329 293
294 skb_queue_head_init(&sta->ampdu_mlme.tid_tx[tid]->pending);
295
330 /* Tx timer */ 296 /* Tx timer */
331 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = 297 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
332 sta_addba_resp_timer_expired; 298 sta_addba_resp_timer_expired;
@@ -351,8 +317,13 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
351 *state = HT_AGG_STATE_IDLE; 317 *state = HT_AGG_STATE_IDLE;
352 goto err_free; 318 goto err_free;
353 } 319 }
354 sta->tid_to_tx_q[tid] = qn;
355 320
321 /* Driver vetoed or OKed, but we can take packets again now */
322 ieee80211_wake_queue_by_reason(
323 &local->hw, ieee80211_ac_from_tid(tid),
324 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
325
326 spin_unlock(&local->ampdu_lock);
356 spin_unlock_bh(&sta->lock); 327 spin_unlock_bh(&sta->lock);
357 328
358 /* send an addBA request */ 329 /* send an addBA request */
@@ -377,17 +348,12 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
377 err_free: 348 err_free:
378 kfree(sta->ampdu_mlme.tid_tx[tid]); 349 kfree(sta->ampdu_mlme.tid_tx[tid]);
379 sta->ampdu_mlme.tid_tx[tid] = NULL; 350 sta->ampdu_mlme.tid_tx[tid] = NULL;
380 err_return_queue: 351 err_wake_queue:
381 if (qn >= 0) { 352 ieee80211_wake_queue_by_reason(
382 /* We failed, so start queue again right away. */ 353 &local->hw, ieee80211_ac_from_tid(tid),
383 ieee80211_wake_queue_by_reason(hw, hw->queues + qn, 354 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
384 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
385 /* give queue back to pool */
386 spin_lock(&local->queue_stop_reason_lock);
387 local->ampdu_ac_queue[qn] = -1;
388 spin_unlock(&local->queue_stop_reason_lock);
389 }
390 err_unlock_sta: 355 err_unlock_sta:
356 spin_unlock(&local->ampdu_lock);
391 spin_unlock_bh(&sta->lock); 357 spin_unlock_bh(&sta->lock);
392 unlock: 358 unlock:
393 rcu_read_unlock(); 359 rcu_read_unlock();
@@ -395,6 +361,67 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
395} 361}
396EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 362EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
397 363
364/*
365 * splice packets from the STA's pending to the local pending,
366 * requires a call to ieee80211_agg_splice_finish and holding
367 * local->ampdu_lock across both calls.
368 */
369static void ieee80211_agg_splice_packets(struct ieee80211_local *local,
370 struct sta_info *sta, u16 tid)
371{
372 unsigned long flags;
373 u16 queue = ieee80211_ac_from_tid(tid);
374
375 ieee80211_stop_queue_by_reason(
376 &local->hw, queue,
377 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
378
379 if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) {
380 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
381 /* mark queue as pending, it is stopped already */
382 __set_bit(IEEE80211_QUEUE_STOP_REASON_PENDING,
383 &local->queue_stop_reasons[queue]);
384 /* copy over remaining packets */
385 skb_queue_splice_tail_init(
386 &sta->ampdu_mlme.tid_tx[tid]->pending,
387 &local->pending[queue]);
388 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
389 }
390}
391
392static void ieee80211_agg_splice_finish(struct ieee80211_local *local,
393 struct sta_info *sta, u16 tid)
394{
395 u16 queue = ieee80211_ac_from_tid(tid);
396
397 ieee80211_wake_queue_by_reason(
398 &local->hw, queue,
399 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
400}
401
402/* caller must hold sta->lock */
403static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
404 struct sta_info *sta, u16 tid)
405{
406#ifdef CONFIG_MAC80211_HT_DEBUG
407 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
408#endif
409
410 spin_lock(&local->ampdu_lock);
411 ieee80211_agg_splice_packets(local, sta, tid);
412 /*
413 * NB: we rely on sta->lock being taken in the TX
414 * processing here when adding to the pending queue,
415 * otherwise we could only change the state of the
416 * session to OPERATIONAL _here_.
417 */
418 ieee80211_agg_splice_finish(local, sta, tid);
419 spin_unlock(&local->ampdu_lock);
420
421 local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_OPERATIONAL,
422 &sta->sta, tid, NULL);
423}
424
398void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) 425void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
399{ 426{
400 struct ieee80211_local *local = hw_to_local(hw); 427 struct ieee80211_local *local = hw_to_local(hw);
@@ -437,20 +464,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
437 464
438 *state |= HT_ADDBA_DRV_READY_MSK; 465 *state |= HT_ADDBA_DRV_READY_MSK;
439 466
440 if (*state == HT_AGG_STATE_OPERATIONAL) { 467 if (*state == HT_AGG_STATE_OPERATIONAL)
441#ifdef CONFIG_MAC80211_HT_DEBUG 468 ieee80211_agg_tx_operational(local, sta, tid);
442 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
443#endif
444 if (hw->ampdu_queues) {
445 /*
446 * Wake up this queue, we stopped it earlier,
447 * this will in turn wake the entire AC.
448 */
449 ieee80211_wake_queue_by_reason(hw,
450 hw->queues + sta->tid_to_tx_q[tid],
451 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
452 }
453 }
454 469
455 out: 470 out:
456 spin_unlock_bh(&sta->lock); 471 spin_unlock_bh(&sta->lock);
@@ -584,22 +599,19 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
584 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 599 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
585 600
586 spin_lock_bh(&sta->lock); 601 spin_lock_bh(&sta->lock);
602 spin_lock(&local->ampdu_lock);
587 603
588 if (*state & HT_AGG_STATE_INITIATOR_MSK && 604 ieee80211_agg_splice_packets(local, sta, tid);
589 hw->ampdu_queues) {
590 /*
591 * Wake up this queue, we stopped it earlier,
592 * this will in turn wake the entire AC.
593 */
594 ieee80211_wake_queue_by_reason(hw,
595 hw->queues + sta->tid_to_tx_q[tid],
596 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
597 }
598 605
599 *state = HT_AGG_STATE_IDLE; 606 *state = HT_AGG_STATE_IDLE;
607 /* from now on packets are no longer put onto sta->pending */
600 sta->ampdu_mlme.addba_req_num[tid] = 0; 608 sta->ampdu_mlme.addba_req_num[tid] = 0;
601 kfree(sta->ampdu_mlme.tid_tx[tid]); 609 kfree(sta->ampdu_mlme.tid_tx[tid]);
602 sta->ampdu_mlme.tid_tx[tid] = NULL; 610 sta->ampdu_mlme.tid_tx[tid] = NULL;
611
612 ieee80211_agg_splice_finish(local, sta, tid);
613
614 spin_unlock(&local->ampdu_lock);
603 spin_unlock_bh(&sta->lock); 615 spin_unlock_bh(&sta->lock);
604 616
605 rcu_read_unlock(); 617 rcu_read_unlock();
@@ -637,9 +649,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
637 struct ieee80211_mgmt *mgmt, 649 struct ieee80211_mgmt *mgmt,
638 size_t len) 650 size_t len)
639{ 651{
640 struct ieee80211_hw *hw = &local->hw; 652 u16 capab, tid;
641 u16 capab;
642 u16 tid, start_seq_num;
643 u8 *state; 653 u8 *state;
644 654
645 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 655 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
@@ -673,26 +683,10 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
673 683
674 *state |= HT_ADDBA_RECEIVED_MSK; 684 *state |= HT_ADDBA_RECEIVED_MSK;
675 685
676 if (hw->ampdu_queues && *state != curstate && 686 if (*state != curstate && *state == HT_AGG_STATE_OPERATIONAL)
677 *state == HT_AGG_STATE_OPERATIONAL) { 687 ieee80211_agg_tx_operational(local, sta, tid);
678 /*
679 * Wake up this queue, we stopped it earlier,
680 * this will in turn wake the entire AC.
681 */
682 ieee80211_wake_queue_by_reason(hw,
683 hw->queues + sta->tid_to_tx_q[tid],
684 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
685 }
686 sta->ampdu_mlme.addba_req_num[tid] = 0;
687 688
688 if (local->ops->ampdu_action) { 689 sta->ampdu_mlme.addba_req_num[tid] = 0;
689 (void)local->ops->ampdu_action(hw,
690 IEEE80211_AMPDU_TX_RESUME,
691 &sta->sta, tid, &start_seq_num);
692 }
693#ifdef CONFIG_MAC80211_HT_DEBUG
694 printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
695#endif /* CONFIG_MAC80211_HT_DEBUG */
696 } else { 690 } else {
697 sta->ampdu_mlme.addba_req_num[tid]++; 691 sta->ampdu_mlme.addba_req_num[tid]++;
698 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 692 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 58693e52d458..e677b751d468 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -540,9 +540,6 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
540 540
541 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 541 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
542 542
543 if (sdata->vif.type != NL80211_IFTYPE_AP)
544 return -EINVAL;
545
546 old = sdata->u.ap.beacon; 543 old = sdata->u.ap.beacon;
547 544
548 if (old) 545 if (old)
@@ -559,9 +556,6 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
559 556
560 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 557 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
561 558
562 if (sdata->vif.type != NL80211_IFTYPE_AP)
563 return -EINVAL;
564
565 old = sdata->u.ap.beacon; 559 old = sdata->u.ap.beacon;
566 560
567 if (!old) 561 if (!old)
@@ -577,9 +571,6 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
577 571
578 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 572 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
579 573
580 if (sdata->vif.type != NL80211_IFTYPE_AP)
581 return -EINVAL;
582
583 old = sdata->u.ap.beacon; 574 old = sdata->u.ap.beacon;
584 575
585 if (!old) 576 if (!old)
@@ -728,10 +719,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
728 int err; 719 int err;
729 int layer2_update; 720 int layer2_update;
730 721
731 /* Prevent a race with changing the rate control algorithm */
732 if (!netif_running(dev))
733 return -ENETDOWN;
734
735 if (params->vlan) { 722 if (params->vlan) {
736 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 723 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
737 724
@@ -860,14 +847,8 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
860 struct sta_info *sta; 847 struct sta_info *sta;
861 int err; 848 int err;
862 849
863 if (!netif_running(dev))
864 return -ENETDOWN;
865
866 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 850 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
867 851
868 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
869 return -ENOTSUPP;
870
871 rcu_read_lock(); 852 rcu_read_lock();
872 sta = sta_info_get(local, next_hop); 853 sta = sta_info_get(local, next_hop);
873 if (!sta) { 854 if (!sta) {
@@ -913,14 +894,8 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
913 struct mesh_path *mpath; 894 struct mesh_path *mpath;
914 struct sta_info *sta; 895 struct sta_info *sta;
915 896
916 if (!netif_running(dev))
917 return -ENETDOWN;
918
919 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 897 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
920 898
921 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
922 return -ENOTSUPP;
923
924 rcu_read_lock(); 899 rcu_read_lock();
925 900
926 sta = sta_info_get(local, next_hop); 901 sta = sta_info_get(local, next_hop);
@@ -989,9 +964,6 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
989 964
990 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 965 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
991 966
992 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
993 return -ENOTSUPP;
994
995 rcu_read_lock(); 967 rcu_read_lock();
996 mpath = mesh_path_lookup(dst, sdata); 968 mpath = mesh_path_lookup(dst, sdata);
997 if (!mpath) { 969 if (!mpath) {
@@ -1013,9 +985,6 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1013 985
1014 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 986 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1015 987
1016 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
1017 return -ENOTSUPP;
1018
1019 rcu_read_lock(); 988 rcu_read_lock();
1020 mpath = mesh_path_lookup_by_idx(idx, sdata); 989 mpath = mesh_path_lookup_by_idx(idx, sdata);
1021 if (!mpath) { 990 if (!mpath) {
@@ -1035,8 +1004,6 @@ static int ieee80211_get_mesh_params(struct wiphy *wiphy,
1035 struct ieee80211_sub_if_data *sdata; 1004 struct ieee80211_sub_if_data *sdata;
1036 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1005 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1037 1006
1038 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
1039 return -ENOTSUPP;
1040 memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config)); 1007 memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config));
1041 return 0; 1008 return 0;
1042} 1009}
@@ -1054,9 +1021,6 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1054 struct ieee80211_sub_if_data *sdata; 1021 struct ieee80211_sub_if_data *sdata;
1055 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1022 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1056 1023
1057 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
1058 return -ENOTSUPP;
1059
1060 /* Set the config options which we are interested in setting */ 1024 /* Set the config options which we are interested in setting */
1061 conf = &(sdata->u.mesh.mshcfg); 1025 conf = &(sdata->u.mesh.mshcfg);
1062 if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask)) 1026 if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask))
@@ -1104,9 +1068,6 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1104 1068
1105 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1069 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1106 1070
1107 if (sdata->vif.type != NL80211_IFTYPE_AP)
1108 return -EINVAL;
1109
1110 if (params->use_cts_prot >= 0) { 1071 if (params->use_cts_prot >= 0) {
1111 sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; 1072 sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
1112 changed |= BSS_CHANGED_ERP_CTS_PROT; 1073 changed |= BSS_CHANGED_ERP_CTS_PROT;
@@ -1181,91 +1142,6 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1181 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1142 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1182} 1143}
1183 1144
1184static int set_mgmt_extra_ie_sta(struct ieee80211_sub_if_data *sdata,
1185 u8 subtype, u8 *ies, size_t ies_len)
1186{
1187 struct ieee80211_local *local = sdata->local;
1188 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1189
1190 switch (subtype) {
1191 case IEEE80211_STYPE_PROBE_REQ >> 4:
1192 if (local->ops->hw_scan)
1193 break;
1194 kfree(ifmgd->ie_probereq);
1195 ifmgd->ie_probereq = ies;
1196 ifmgd->ie_probereq_len = ies_len;
1197 return 0;
1198 case IEEE80211_STYPE_PROBE_RESP >> 4:
1199 kfree(ifmgd->ie_proberesp);
1200 ifmgd->ie_proberesp = ies;
1201 ifmgd->ie_proberesp_len = ies_len;
1202 return 0;
1203 case IEEE80211_STYPE_AUTH >> 4:
1204 kfree(ifmgd->ie_auth);
1205 ifmgd->ie_auth = ies;
1206 ifmgd->ie_auth_len = ies_len;
1207 return 0;
1208 case IEEE80211_STYPE_ASSOC_REQ >> 4:
1209 kfree(ifmgd->ie_assocreq);
1210 ifmgd->ie_assocreq = ies;
1211 ifmgd->ie_assocreq_len = ies_len;
1212 return 0;
1213 case IEEE80211_STYPE_REASSOC_REQ >> 4:
1214 kfree(ifmgd->ie_reassocreq);
1215 ifmgd->ie_reassocreq = ies;
1216 ifmgd->ie_reassocreq_len = ies_len;
1217 return 0;
1218 case IEEE80211_STYPE_DEAUTH >> 4:
1219 kfree(ifmgd->ie_deauth);
1220 ifmgd->ie_deauth = ies;
1221 ifmgd->ie_deauth_len = ies_len;
1222 return 0;
1223 case IEEE80211_STYPE_DISASSOC >> 4:
1224 kfree(ifmgd->ie_disassoc);
1225 ifmgd->ie_disassoc = ies;
1226 ifmgd->ie_disassoc_len = ies_len;
1227 return 0;
1228 }
1229
1230 return -EOPNOTSUPP;
1231}
1232
1233static int ieee80211_set_mgmt_extra_ie(struct wiphy *wiphy,
1234 struct net_device *dev,
1235 struct mgmt_extra_ie_params *params)
1236{
1237 struct ieee80211_sub_if_data *sdata;
1238 u8 *ies;
1239 size_t ies_len;
1240 int ret = -EOPNOTSUPP;
1241
1242 if (params->ies) {
1243 ies = kmemdup(params->ies, params->ies_len, GFP_KERNEL);
1244 if (ies == NULL)
1245 return -ENOMEM;
1246 ies_len = params->ies_len;
1247 } else {
1248 ies = NULL;
1249 ies_len = 0;
1250 }
1251
1252 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1253
1254 switch (sdata->vif.type) {
1255 case NL80211_IFTYPE_STATION:
1256 ret = set_mgmt_extra_ie_sta(sdata, params->subtype,
1257 ies, ies_len);
1258 break;
1259 default:
1260 ret = -EOPNOTSUPP;
1261 break;
1262 }
1263
1264 if (ret)
1265 kfree(ies);
1266 return ret;
1267}
1268
1269#ifdef CONFIG_PM 1145#ifdef CONFIG_PM
1270static int ieee80211_suspend(struct wiphy *wiphy) 1146static int ieee80211_suspend(struct wiphy *wiphy)
1271{ 1147{
@@ -1287,9 +1163,6 @@ static int ieee80211_scan(struct wiphy *wiphy,
1287{ 1163{
1288 struct ieee80211_sub_if_data *sdata; 1164 struct ieee80211_sub_if_data *sdata;
1289 1165
1290 if (!netif_running(dev))
1291 return -ENETDOWN;
1292
1293 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1166 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1294 1167
1295 if (sdata->vif.type != NL80211_IFTYPE_STATION && 1168 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
@@ -1300,6 +1173,119 @@ static int ieee80211_scan(struct wiphy *wiphy,
1300 return ieee80211_request_scan(sdata, req); 1173 return ieee80211_request_scan(sdata, req);
1301} 1174}
1302 1175
1176static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1177 struct cfg80211_auth_request *req)
1178{
1179 struct ieee80211_sub_if_data *sdata;
1180
1181 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1182
1183 switch (req->auth_type) {
1184 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1185 sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_OPEN;
1186 break;
1187 case NL80211_AUTHTYPE_SHARED_KEY:
1188 sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_SHARED_KEY;
1189 break;
1190 case NL80211_AUTHTYPE_FT:
1191 sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_FT;
1192 break;
1193 case NL80211_AUTHTYPE_NETWORK_EAP:
1194 sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_LEAP;
1195 break;
1196 default:
1197 return -EOPNOTSUPP;
1198 }
1199
1200 memcpy(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN);
1201 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
1202 sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
1203
1204 /* TODO: req->chan */
1205 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL;
1206
1207 if (req->ssid) {
1208 sdata->u.mgd.flags |= IEEE80211_STA_SSID_SET;
1209 memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
1210 sdata->u.mgd.ssid_len = req->ssid_len;
1211 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
1212 }
1213
1214 kfree(sdata->u.mgd.sme_auth_ie);
1215 sdata->u.mgd.sme_auth_ie = NULL;
1216 sdata->u.mgd.sme_auth_ie_len = 0;
1217 if (req->ie) {
1218 sdata->u.mgd.sme_auth_ie = kmalloc(req->ie_len, GFP_KERNEL);
1219 if (sdata->u.mgd.sme_auth_ie == NULL)
1220 return -ENOMEM;
1221 memcpy(sdata->u.mgd.sme_auth_ie, req->ie, req->ie_len);
1222 sdata->u.mgd.sme_auth_ie_len = req->ie_len;
1223 }
1224
1225 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
1226 sdata->u.mgd.state = IEEE80211_STA_MLME_DIRECT_PROBE;
1227 ieee80211_sta_req_auth(sdata);
1228 return 0;
1229}
1230
1231static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1232 struct cfg80211_assoc_request *req)
1233{
1234 struct ieee80211_sub_if_data *sdata;
1235 int ret;
1236
1237 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1238
1239 if (memcmp(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN) != 0 ||
1240 !(sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED))
1241 return -ENOLINK; /* not authenticated */
1242
1243 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
1244 sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
1245
1246 /* TODO: req->chan */
1247 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL;
1248
1249 if (req->ssid) {
1250 sdata->u.mgd.flags |= IEEE80211_STA_SSID_SET;
1251 memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
1252 sdata->u.mgd.ssid_len = req->ssid_len;
1253 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
1254 } else
1255 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
1256
1257 ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
1258 if (ret)
1259 return ret;
1260
1261 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
1262 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
1263 ieee80211_sta_req_auth(sdata);
1264 return 0;
1265}
1266
1267static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
1268 struct cfg80211_deauth_request *req)
1269{
1270 struct ieee80211_sub_if_data *sdata;
1271
1272 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1273
1274 /* TODO: req->ie */
1275 return ieee80211_sta_deauthenticate(sdata, req->reason_code);
1276}
1277
1278static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1279 struct cfg80211_disassoc_request *req)
1280{
1281 struct ieee80211_sub_if_data *sdata;
1282
1283 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1284
1285 /* TODO: req->ie */
1286 return ieee80211_sta_disassociate(sdata, req->reason_code);
1287}
1288
1303struct cfg80211_ops mac80211_config_ops = { 1289struct cfg80211_ops mac80211_config_ops = {
1304 .add_virtual_intf = ieee80211_add_iface, 1290 .add_virtual_intf = ieee80211_add_iface,
1305 .del_virtual_intf = ieee80211_del_iface, 1291 .del_virtual_intf = ieee80211_del_iface,
@@ -1329,8 +1315,11 @@ struct cfg80211_ops mac80211_config_ops = {
1329 .change_bss = ieee80211_change_bss, 1315 .change_bss = ieee80211_change_bss,
1330 .set_txq_params = ieee80211_set_txq_params, 1316 .set_txq_params = ieee80211_set_txq_params,
1331 .set_channel = ieee80211_set_channel, 1317 .set_channel = ieee80211_set_channel,
1332 .set_mgmt_extra_ie = ieee80211_set_mgmt_extra_ie,
1333 .suspend = ieee80211_suspend, 1318 .suspend = ieee80211_suspend,
1334 .resume = ieee80211_resume, 1319 .resume = ieee80211_resume,
1335 .scan = ieee80211_scan, 1320 .scan = ieee80211_scan,
1321 .auth = ieee80211_auth,
1322 .assoc = ieee80211_assoc,
1323 .deauth = ieee80211_deauth,
1324 .disassoc = ieee80211_disassoc,
1336}; 1325};
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index e37f557de3f3..210b9b6fecd2 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -40,6 +40,10 @@ static const struct file_operations name## _ops = { \
40 local->debugfs.name = debugfs_create_file(#name, 0400, phyd, \ 40 local->debugfs.name = debugfs_create_file(#name, 0400, phyd, \
41 local, &name## _ops); 41 local, &name## _ops);
42 42
43#define DEBUGFS_ADD_MODE(name, mode) \
44 local->debugfs.name = debugfs_create_file(#name, mode, phyd, \
45 local, &name## _ops);
46
43#define DEBUGFS_DEL(name) \ 47#define DEBUGFS_DEL(name) \
44 debugfs_remove(local->debugfs.name); \ 48 debugfs_remove(local->debugfs.name); \
45 local->debugfs.name = NULL; 49 local->debugfs.name = NULL;
@@ -113,6 +117,24 @@ static const struct file_operations tsf_ops = {
113 .open = mac80211_open_file_generic 117 .open = mac80211_open_file_generic
114}; 118};
115 119
120static ssize_t reset_write(struct file *file, const char __user *user_buf,
121 size_t count, loff_t *ppos)
122{
123 struct ieee80211_local *local = file->private_data;
124
125 rtnl_lock();
126 __ieee80211_suspend(&local->hw);
127 __ieee80211_resume(&local->hw);
128 rtnl_unlock();
129
130 return count;
131}
132
133static const struct file_operations reset_ops = {
134 .write = reset_write,
135 .open = mac80211_open_file_generic,
136};
137
116/* statistics stuff */ 138/* statistics stuff */
117 139
118#define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ 140#define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \
@@ -254,6 +276,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
254 DEBUGFS_ADD(total_ps_buffered); 276 DEBUGFS_ADD(total_ps_buffered);
255 DEBUGFS_ADD(wep_iv); 277 DEBUGFS_ADD(wep_iv);
256 DEBUGFS_ADD(tsf); 278 DEBUGFS_ADD(tsf);
279 DEBUGFS_ADD_MODE(reset, 0200);
257 280
258 statsd = debugfs_create_dir("statistics", phyd); 281 statsd = debugfs_create_dir("statistics", phyd);
259 local->debugfs.statistics = statsd; 282 local->debugfs.statistics = statsd;
@@ -308,6 +331,7 @@ void debugfs_hw_del(struct ieee80211_local *local)
308 DEBUGFS_DEL(total_ps_buffered); 331 DEBUGFS_DEL(total_ps_buffered);
309 DEBUGFS_DEL(wep_iv); 332 DEBUGFS_DEL(wep_iv);
310 DEBUGFS_DEL(tsf); 333 DEBUGFS_DEL(tsf);
334 DEBUGFS_DEL(reset);
311 335
312 DEBUGFS_STATS_DEL(transmitted_fragment_count); 336 DEBUGFS_STATS_DEL(transmitted_fragment_count);
313 DEBUGFS_STATS_DEL(multicast_transmitted_frame_count); 337 DEBUGFS_STATS_DEL(multicast_transmitted_frame_count);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f4becc12904e..3201e1f96365 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -812,8 +812,9 @@ int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata)
812 812
813 ifibss->ibss_join_req = jiffies; 813 ifibss->ibss_join_req = jiffies;
814 ifibss->state = IEEE80211_IBSS_MLME_SEARCH; 814 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
815 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
815 816
816 return ieee80211_sta_find_ibss(sdata); 817 return 0;
817} 818}
818 819
819int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len) 820int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index fbb91f1aebb2..e6ed78cb16b3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -149,11 +149,6 @@ struct ieee80211_tx_data {
149 149
150 struct ieee80211_channel *channel; 150 struct ieee80211_channel *channel;
151 151
152 /* Extra fragments (in addition to the first fragment
153 * in skb) */
154 struct sk_buff **extra_frag;
155 int num_extra_frag;
156
157 u16 ethertype; 152 u16 ethertype;
158 unsigned int flags; 153 unsigned int flags;
159}; 154};
@@ -189,12 +184,6 @@ struct ieee80211_rx_data {
189 u16 tkip_iv16; 184 u16 tkip_iv16;
190}; 185};
191 186
192struct ieee80211_tx_stored_packet {
193 struct sk_buff *skb;
194 struct sk_buff **extra_frag;
195 int num_extra_frag;
196};
197
198struct beacon_data { 187struct beacon_data {
199 u8 *head, *tail; 188 u8 *head, *tail;
200 int head_len, tail_len; 189 int head_len, tail_len;
@@ -247,8 +236,9 @@ struct mesh_preq_queue {
247#define IEEE80211_STA_ASSOCIATED BIT(4) 236#define IEEE80211_STA_ASSOCIATED BIT(4)
248#define IEEE80211_STA_PROBEREQ_POLL BIT(5) 237#define IEEE80211_STA_PROBEREQ_POLL BIT(5)
249#define IEEE80211_STA_CREATE_IBSS BIT(6) 238#define IEEE80211_STA_CREATE_IBSS BIT(6)
250#define IEEE80211_STA_MIXED_CELL BIT(7) 239/* hole at 7, please re-use */
251#define IEEE80211_STA_WMM_ENABLED BIT(8) 240#define IEEE80211_STA_WMM_ENABLED BIT(8)
241/* hole at 9, please re-use */
252#define IEEE80211_STA_AUTO_SSID_SEL BIT(10) 242#define IEEE80211_STA_AUTO_SSID_SEL BIT(10)
253#define IEEE80211_STA_AUTO_BSSID_SEL BIT(11) 243#define IEEE80211_STA_AUTO_BSSID_SEL BIT(11)
254#define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12) 244#define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12)
@@ -256,6 +246,7 @@ struct mesh_preq_queue {
256#define IEEE80211_STA_TKIP_WEP_USED BIT(14) 246#define IEEE80211_STA_TKIP_WEP_USED BIT(14)
257#define IEEE80211_STA_CSA_RECEIVED BIT(15) 247#define IEEE80211_STA_CSA_RECEIVED BIT(15)
258#define IEEE80211_STA_MFP_ENABLED BIT(16) 248#define IEEE80211_STA_MFP_ENABLED BIT(16)
249#define IEEE80211_STA_EXT_SME BIT(17)
259/* flags for MLME request */ 250/* flags for MLME request */
260#define IEEE80211_STA_REQ_SCAN 0 251#define IEEE80211_STA_REQ_SCAN 0
261#define IEEE80211_STA_REQ_DIRECT_PROBE 1 252#define IEEE80211_STA_REQ_DIRECT_PROBE 1
@@ -266,12 +257,14 @@ struct mesh_preq_queue {
266#define IEEE80211_AUTH_ALG_OPEN BIT(0) 257#define IEEE80211_AUTH_ALG_OPEN BIT(0)
267#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1) 258#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1)
268#define IEEE80211_AUTH_ALG_LEAP BIT(2) 259#define IEEE80211_AUTH_ALG_LEAP BIT(2)
260#define IEEE80211_AUTH_ALG_FT BIT(3)
269 261
270struct ieee80211_if_managed { 262struct ieee80211_if_managed {
271 struct timer_list timer; 263 struct timer_list timer;
272 struct timer_list chswitch_timer; 264 struct timer_list chswitch_timer;
273 struct work_struct work; 265 struct work_struct work;
274 struct work_struct chswitch_work; 266 struct work_struct chswitch_work;
267 struct work_struct beacon_loss_work;
275 268
276 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; 269 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
277 270
@@ -305,6 +298,7 @@ struct ieee80211_if_managed {
305 unsigned long request; 298 unsigned long request;
306 299
307 unsigned long last_probe; 300 unsigned long last_probe;
301 unsigned long last_beacon;
308 302
309 unsigned int flags; 303 unsigned int flags;
310 304
@@ -321,20 +315,8 @@ struct ieee80211_if_managed {
321 int wmm_last_param_set; 315 int wmm_last_param_set;
322 316
323 /* Extra IE data for management frames */ 317 /* Extra IE data for management frames */
324 u8 *ie_probereq; 318 u8 *sme_auth_ie;
325 size_t ie_probereq_len; 319 size_t sme_auth_ie_len;
326 u8 *ie_proberesp;
327 size_t ie_proberesp_len;
328 u8 *ie_auth;
329 size_t ie_auth_len;
330 u8 *ie_assocreq;
331 size_t ie_assocreq_len;
332 u8 *ie_reassocreq;
333 size_t ie_reassocreq_len;
334 u8 *ie_deauth;
335 size_t ie_deauth_len;
336 u8 *ie_disassoc;
337 size_t ie_disassoc_len;
338}; 320};
339 321
340enum ieee80211_ibss_flags { 322enum ieee80211_ibss_flags {
@@ -421,7 +403,6 @@ struct ieee80211_if_mesh {
421 * 403 *
422 * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets 404 * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets
423 * @IEEE80211_SDATA_PROMISC: interface is promisc 405 * @IEEE80211_SDATA_PROMISC: interface is promisc
424 * @IEEE80211_SDATA_USERSPACE_MLME: userspace MLME is active
425 * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode 406 * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode
426 * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between 407 * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between
427 * associated stations and deliver multicast frames both 408 * associated stations and deliver multicast frames both
@@ -430,9 +411,8 @@ struct ieee80211_if_mesh {
430enum ieee80211_sub_if_data_flags { 411enum ieee80211_sub_if_data_flags {
431 IEEE80211_SDATA_ALLMULTI = BIT(0), 412 IEEE80211_SDATA_ALLMULTI = BIT(0),
432 IEEE80211_SDATA_PROMISC = BIT(1), 413 IEEE80211_SDATA_PROMISC = BIT(1),
433 IEEE80211_SDATA_USERSPACE_MLME = BIT(2), 414 IEEE80211_SDATA_OPERATING_GMODE = BIT(2),
434 IEEE80211_SDATA_OPERATING_GMODE = BIT(3), 415 IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3),
435 IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(4),
436}; 416};
437 417
438struct ieee80211_sub_if_data { 418struct ieee80211_sub_if_data {
@@ -598,6 +578,8 @@ enum queue_stop_reason {
598 IEEE80211_QUEUE_STOP_REASON_PS, 578 IEEE80211_QUEUE_STOP_REASON_PS,
599 IEEE80211_QUEUE_STOP_REASON_CSA, 579 IEEE80211_QUEUE_STOP_REASON_CSA,
600 IEEE80211_QUEUE_STOP_REASON_AGGREGATION, 580 IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
581 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
582 IEEE80211_QUEUE_STOP_REASON_PENDING,
601}; 583};
602 584
603struct ieee80211_master_priv { 585struct ieee80211_master_priv {
@@ -612,12 +594,7 @@ struct ieee80211_local {
612 594
613 const struct ieee80211_ops *ops; 595 const struct ieee80211_ops *ops;
614 596
615 /* AC queue corresponding to each AMPDU queue */ 597 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
616 s8 ampdu_ac_queue[IEEE80211_MAX_AMPDU_QUEUES];
617 unsigned int amdpu_ac_stop_refcnt[IEEE80211_MAX_AMPDU_QUEUES];
618
619 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES +
620 IEEE80211_MAX_AMPDU_QUEUES];
621 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ 598 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
622 spinlock_t queue_stop_reason_lock; 599 spinlock_t queue_stop_reason_lock;
623 600
@@ -654,11 +631,17 @@ struct ieee80211_local {
654 struct sta_info *sta_hash[STA_HASH_SIZE]; 631 struct sta_info *sta_hash[STA_HASH_SIZE];
655 struct timer_list sta_cleanup; 632 struct timer_list sta_cleanup;
656 633
657 unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)]; 634 struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
658 unsigned long queues_pending_run[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
659 struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES];
660 struct tasklet_struct tx_pending_tasklet; 635 struct tasklet_struct tx_pending_tasklet;
661 636
637 /*
638 * This lock is used to prevent concurrent A-MPDU
639 * session start/stop processing, this thus also
640 * synchronises the ->ampdu_action() callback to
641 * drivers and limits it to one at a time.
642 */
643 spinlock_t ampdu_lock;
644
662 /* number of interfaces with corresponding IFF_ flags */ 645 /* number of interfaces with corresponding IFF_ flags */
663 atomic_t iff_allmultis, iff_promiscs; 646 atomic_t iff_allmultis, iff_promiscs;
664 647
@@ -774,6 +757,7 @@ struct ieee80211_local {
774 struct dentry *total_ps_buffered; 757 struct dentry *total_ps_buffered;
775 struct dentry *wep_iv; 758 struct dentry *wep_iv;
776 struct dentry *tsf; 759 struct dentry *tsf;
760 struct dentry *reset;
777 struct dentry *statistics; 761 struct dentry *statistics;
778 struct local_debugfsdentries_statsdentries { 762 struct local_debugfsdentries_statsdentries {
779 struct dentry *transmitted_fragment_count; 763 struct dentry *transmitted_fragment_count;
@@ -969,7 +953,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata,
969 struct sk_buff *skb, 953 struct sk_buff *skb,
970 struct ieee80211_rx_status *rx_status); 954 struct ieee80211_rx_status *rx_status);
971int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, 955int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
972 char *ie, size_t len); 956 const char *ie, size_t len);
973 957
974void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); 958void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
975void ieee80211_scan_failed(struct ieee80211_local *local); 959void ieee80211_scan_failed(struct ieee80211_local *local);
@@ -1053,8 +1037,19 @@ void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
1053 u8 pwr_constr_elem_len); 1037 u8 pwr_constr_elem_len);
1054 1038
1055/* Suspend/resume */ 1039/* Suspend/resume */
1040#ifdef CONFIG_PM
1056int __ieee80211_suspend(struct ieee80211_hw *hw); 1041int __ieee80211_suspend(struct ieee80211_hw *hw);
1057int __ieee80211_resume(struct ieee80211_hw *hw); 1042int __ieee80211_resume(struct ieee80211_hw *hw);
1043#else
1044static inline int __ieee80211_suspend(struct ieee80211_hw *hw)
1045{
1046 return 0;
1047}
1048static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1049{
1050 return 0;
1051}
1052#endif
1058 1053
1059/* utility functions/constants */ 1054/* utility functions/constants */
1060extern void *mac80211_wiphy_privid; /* for wiphy privid */ 1055extern void *mac80211_wiphy_privid; /* for wiphy privid */
@@ -1081,6 +1076,9 @@ void ieee80211_dynamic_ps_timer(unsigned long data);
1081void ieee80211_send_nullfunc(struct ieee80211_local *local, 1076void ieee80211_send_nullfunc(struct ieee80211_local *local,
1082 struct ieee80211_sub_if_data *sdata, 1077 struct ieee80211_sub_if_data *sdata,
1083 int powersave); 1078 int powersave);
1079void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1080 struct ieee80211_hdr *hdr);
1081void ieee80211_beacon_loss_work(struct work_struct *work);
1084 1082
1085void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1083void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1086 enum queue_stop_reason reason); 1084 enum queue_stop_reason reason);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index f9f27b9cadbe..91e8e1bacaaa 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -261,8 +261,7 @@ static int ieee80211_open(struct net_device *dev)
261 ieee80211_bss_info_change_notify(sdata, changed); 261 ieee80211_bss_info_change_notify(sdata, changed);
262 ieee80211_enable_keys(sdata); 262 ieee80211_enable_keys(sdata);
263 263
264 if (sdata->vif.type == NL80211_IFTYPE_STATION && 264 if (sdata->vif.type == NL80211_IFTYPE_STATION)
265 !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
266 netif_carrier_off(dev); 265 netif_carrier_off(dev);
267 else 266 else
268 netif_carrier_on(dev); 267 netif_carrier_on(dev);
@@ -478,6 +477,9 @@ static int ieee80211_stop(struct net_device *dev)
478 */ 477 */
479 cancel_work_sync(&sdata->u.mgd.work); 478 cancel_work_sync(&sdata->u.mgd.work);
480 cancel_work_sync(&sdata->u.mgd.chswitch_work); 479 cancel_work_sync(&sdata->u.mgd.chswitch_work);
480
481 cancel_work_sync(&sdata->u.mgd.beacon_loss_work);
482
481 /* 483 /*
482 * When we get here, the interface is marked down. 484 * When we get here, the interface is marked down.
483 * Call synchronize_rcu() to wait for the RX path 485 * Call synchronize_rcu() to wait for the RX path
@@ -653,13 +655,7 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
653 kfree(sdata->u.mgd.extra_ie); 655 kfree(sdata->u.mgd.extra_ie);
654 kfree(sdata->u.mgd.assocreq_ies); 656 kfree(sdata->u.mgd.assocreq_ies);
655 kfree(sdata->u.mgd.assocresp_ies); 657 kfree(sdata->u.mgd.assocresp_ies);
656 kfree(sdata->u.mgd.ie_probereq); 658 kfree(sdata->u.mgd.sme_auth_ie);
657 kfree(sdata->u.mgd.ie_proberesp);
658 kfree(sdata->u.mgd.ie_auth);
659 kfree(sdata->u.mgd.ie_assocreq);
660 kfree(sdata->u.mgd.ie_reassocreq);
661 kfree(sdata->u.mgd.ie_deauth);
662 kfree(sdata->u.mgd.ie_disassoc);
663 break; 659 break;
664 case NL80211_IFTYPE_WDS: 660 case NL80211_IFTYPE_WDS:
665 case NL80211_IFTYPE_AP_VLAN: 661 case NL80211_IFTYPE_AP_VLAN:
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index f38db4d37e5d..a6f1d8a869bc 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -161,12 +161,6 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
161 if (WARN_ON(!netif_running(sdata->dev))) 161 if (WARN_ON(!netif_running(sdata->dev)))
162 return 0; 162 return 0;
163 163
164 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
165 return -EINVAL;
166
167 if (!local->ops->config_interface)
168 return 0;
169
170 memset(&conf, 0, sizeof(conf)); 164 memset(&conf, 0, sizeof(conf));
171 165
172 if (sdata->vif.type == NL80211_IFTYPE_STATION) 166 if (sdata->vif.type == NL80211_IFTYPE_STATION)
@@ -183,6 +177,9 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
183 return -EINVAL; 177 return -EINVAL;
184 } 178 }
185 179
180 if (!local->ops->config_interface)
181 return 0;
182
186 switch (sdata->vif.type) { 183 switch (sdata->vif.type) {
187 case NL80211_IFTYPE_AP: 184 case NL80211_IFTYPE_AP:
188 case NL80211_IFTYPE_ADHOC: 185 case NL80211_IFTYPE_ADHOC:
@@ -224,9 +221,6 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
224 } 221 }
225 } 222 }
226 223
227 if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID)))
228 return -EINVAL;
229
230 conf.changed = changed; 224 conf.changed = changed;
231 225
232 return local->ops->config_interface(local_to_hw(local), 226 return local->ops->config_interface(local_to_hw(local),
@@ -780,13 +774,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
780 setup_timer(&local->dynamic_ps_timer, 774 setup_timer(&local->dynamic_ps_timer,
781 ieee80211_dynamic_ps_timer, (unsigned long) local); 775 ieee80211_dynamic_ps_timer, (unsigned long) local);
782 776
783 for (i = 0; i < IEEE80211_MAX_AMPDU_QUEUES; i++)
784 local->ampdu_ac_queue[i] = -1;
785 /* using an s8 won't work with more than that */
786 BUILD_BUG_ON(IEEE80211_MAX_AMPDU_QUEUES > 127);
787
788 sta_info_init(local); 777 sta_info_init(local);
789 778
779 for (i = 0; i < IEEE80211_MAX_QUEUES; i++)
780 skb_queue_head_init(&local->pending[i]);
790 tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, 781 tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
791 (unsigned long)local); 782 (unsigned long)local);
792 tasklet_disable(&local->tx_pending_tasklet); 783 tasklet_disable(&local->tx_pending_tasklet);
@@ -799,6 +790,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
799 skb_queue_head_init(&local->skb_queue); 790 skb_queue_head_init(&local->skb_queue);
800 skb_queue_head_init(&local->skb_queue_unreliable); 791 skb_queue_head_init(&local->skb_queue_unreliable);
801 792
793 spin_lock_init(&local->ampdu_lock);
794
802 return local_to_hw(local); 795 return local_to_hw(local);
803} 796}
804EXPORT_SYMBOL(ieee80211_alloc_hw); 797EXPORT_SYMBOL(ieee80211_alloc_hw);
@@ -876,10 +869,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
876 */ 869 */
877 if (hw->queues > IEEE80211_MAX_QUEUES) 870 if (hw->queues > IEEE80211_MAX_QUEUES)
878 hw->queues = IEEE80211_MAX_QUEUES; 871 hw->queues = IEEE80211_MAX_QUEUES;
879 if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
880 hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
881 if (hw->queues < 4)
882 hw->ampdu_queues = 0;
883 872
884 mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv), 873 mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv),
885 "wmaster%d", ieee80211_master_setup, 874 "wmaster%d", ieee80211_master_setup,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 841b8450b3de..7ecda9d59d8a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -30,7 +30,7 @@
30#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 30#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
31#define IEEE80211_ASSOC_MAX_TRIES 3 31#define IEEE80211_ASSOC_MAX_TRIES 3
32#define IEEE80211_MONITORING_INTERVAL (2 * HZ) 32#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
33#define IEEE80211_PROBE_INTERVAL (60 * HZ) 33#define IEEE80211_PROBE_IDLE_TIME (60 * HZ)
34#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ) 34#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
35 35
36/* utils */ 36/* utils */
@@ -82,38 +82,23 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
82 82
83/* frame sending functions */ 83/* frame sending functions */
84 84
85static void add_extra_ies(struct sk_buff *skb, u8 *ies, size_t ies_len)
86{
87 if (ies)
88 memcpy(skb_put(skb, ies_len), ies, ies_len);
89}
90
91static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 85static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
92{ 86{
93 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 87 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
94 struct ieee80211_local *local = sdata->local; 88 struct ieee80211_local *local = sdata->local;
95 struct sk_buff *skb; 89 struct sk_buff *skb;
96 struct ieee80211_mgmt *mgmt; 90 struct ieee80211_mgmt *mgmt;
97 u8 *pos, *ies, *ht_ie, *e_ies; 91 u8 *pos, *ies, *ht_ie;
98 int i, len, count, rates_len, supp_rates_len; 92 int i, len, count, rates_len, supp_rates_len;
99 u16 capab; 93 u16 capab;
100 struct ieee80211_bss *bss; 94 struct ieee80211_bss *bss;
101 int wmm = 0; 95 int wmm = 0;
102 struct ieee80211_supported_band *sband; 96 struct ieee80211_supported_band *sband;
103 u32 rates = 0; 97 u32 rates = 0;
104 size_t e_ies_len;
105
106 if (ifmgd->flags & IEEE80211_IBSS_PREV_BSSID_SET) {
107 e_ies = sdata->u.mgd.ie_reassocreq;
108 e_ies_len = sdata->u.mgd.ie_reassocreq_len;
109 } else {
110 e_ies = sdata->u.mgd.ie_assocreq;
111 e_ies_len = sdata->u.mgd.ie_assocreq_len;
112 }
113 98
114 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 99 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
115 sizeof(*mgmt) + 200 + ifmgd->extra_ie_len + 100 sizeof(*mgmt) + 200 + ifmgd->extra_ie_len +
116 ifmgd->ssid_len + e_ies_len); 101 ifmgd->ssid_len);
117 if (!skb) { 102 if (!skb) {
118 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " 103 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
119 "frame\n", sdata->dev->name); 104 "frame\n", sdata->dev->name);
@@ -304,8 +289,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
304 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 289 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
305 } 290 }
306 291
307 add_extra_ies(skb, e_ies, e_ies_len);
308
309 kfree(ifmgd->assocreq_ies); 292 kfree(ifmgd->assocreq_ies);
310 ifmgd->assocreq_ies_len = (skb->data + skb->len) - ies; 293 ifmgd->assocreq_ies_len = (skb->data + skb->len) - ies;
311 ifmgd->assocreq_ies = kmalloc(ifmgd->assocreq_ies_len, GFP_KERNEL); 294 ifmgd->assocreq_ies = kmalloc(ifmgd->assocreq_ies_len, GFP_KERNEL);
@@ -323,19 +306,8 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
323 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 306 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
324 struct sk_buff *skb; 307 struct sk_buff *skb;
325 struct ieee80211_mgmt *mgmt; 308 struct ieee80211_mgmt *mgmt;
326 u8 *ies;
327 size_t ies_len;
328
329 if (stype == IEEE80211_STYPE_DEAUTH) {
330 ies = sdata->u.mgd.ie_deauth;
331 ies_len = sdata->u.mgd.ie_deauth_len;
332 } else {
333 ies = sdata->u.mgd.ie_disassoc;
334 ies_len = sdata->u.mgd.ie_disassoc_len;
335 }
336 309
337 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 310 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
338 ies_len);
339 if (!skb) { 311 if (!skb) {
340 printk(KERN_DEBUG "%s: failed to allocate buffer for " 312 printk(KERN_DEBUG "%s: failed to allocate buffer for "
341 "deauth/disassoc frame\n", sdata->dev->name); 313 "deauth/disassoc frame\n", sdata->dev->name);
@@ -353,8 +325,6 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
353 /* u.deauth.reason_code == u.disassoc.reason_code */ 325 /* u.deauth.reason_code == u.disassoc.reason_code */
354 mgmt->u.deauth.reason_code = cpu_to_le16(reason); 326 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
355 327
356 add_extra_ies(skb, ies, ies_len);
357
358 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); 328 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
359} 329}
360 330
@@ -640,6 +610,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
640 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 610 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
641 bss->cbss.capability, bss->has_erp_value, bss->erp_value); 611 bss->cbss.capability, bss->has_erp_value, bss->erp_value);
642 612
613 cfg80211_hold_bss(&bss->cbss);
614
643 ieee80211_rx_bss_put(local, bss); 615 ieee80211_rx_bss_put(local, bss);
644 } 616 }
645 617
@@ -682,6 +654,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
682static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata) 654static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
683{ 655{
684 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 656 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
657 struct ieee80211_local *local = sdata->local;
685 658
686 ifmgd->direct_probe_tries++; 659 ifmgd->direct_probe_tries++;
687 if (ifmgd->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) { 660 if (ifmgd->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -697,6 +670,13 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
697 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 670 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
698 sdata->local->hw.conf.channel->center_freq, 671 sdata->local->hw.conf.channel->center_freq,
699 ifmgd->ssid, ifmgd->ssid_len); 672 ifmgd->ssid, ifmgd->ssid_len);
673
674 /*
675 * We might have a pending scan which had no chance to run yet
676 * due to state == IEEE80211_STA_MLME_DIRECT_PROBE.
677 * Hence, queue the STAs work again
678 */
679 queue_work(local->hw.workqueue, &ifmgd->work);
700 return; 680 return;
701 } 681 }
702 682
@@ -721,6 +701,9 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
721static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata) 701static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
722{ 702{
723 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 703 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
704 struct ieee80211_local *local = sdata->local;
705 u8 *ies;
706 size_t ies_len;
724 707
725 ifmgd->auth_tries++; 708 ifmgd->auth_tries++;
726 if (ifmgd->auth_tries > IEEE80211_AUTH_MAX_TRIES) { 709 if (ifmgd->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -732,6 +715,13 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
732 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 715 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
733 sdata->local->hw.conf.channel->center_freq, 716 sdata->local->hw.conf.channel->center_freq,
734 ifmgd->ssid, ifmgd->ssid_len); 717 ifmgd->ssid, ifmgd->ssid_len);
718
719 /*
720 * We might have a pending scan which had no chance to run yet
721 * due to state == IEEE80211_STA_MLME_AUTHENTICATE.
722 * Hence, queue the STAs work again
723 */
724 queue_work(local->hw.workqueue, &ifmgd->work);
735 return; 725 return;
736 } 726 }
737 727
@@ -739,7 +729,14 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
739 printk(KERN_DEBUG "%s: authenticate with AP %pM\n", 729 printk(KERN_DEBUG "%s: authenticate with AP %pM\n",
740 sdata->dev->name, ifmgd->bssid); 730 sdata->dev->name, ifmgd->bssid);
741 731
742 ieee80211_send_auth(sdata, 1, ifmgd->auth_alg, NULL, 0, 732 if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
733 ies = ifmgd->sme_auth_ie;
734 ies_len = ifmgd->sme_auth_ie_len;
735 } else {
736 ies = NULL;
737 ies_len = 0;
738 }
739 ieee80211_send_auth(sdata, 1, ifmgd->auth_alg, ies, ies_len,
743 ifmgd->bssid, 0); 740 ifmgd->bssid, 0);
744 ifmgd->auth_transaction = 2; 741 ifmgd->auth_transaction = 2;
745 742
@@ -756,6 +753,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
756{ 753{
757 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 754 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
758 struct ieee80211_local *local = sdata->local; 755 struct ieee80211_local *local = sdata->local;
756 struct ieee80211_conf *conf = &local_to_hw(local)->conf;
757 struct ieee80211_bss *bss;
759 struct sta_info *sta; 758 struct sta_info *sta;
760 u32 changed = 0, config_changed = 0; 759 u32 changed = 0, config_changed = 0;
761 760
@@ -779,6 +778,15 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
779 778
780 ieee80211_sta_tear_down_BA_sessions(sta); 779 ieee80211_sta_tear_down_BA_sessions(sta);
781 780
781 bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
782 conf->channel->center_freq,
783 ifmgd->ssid, ifmgd->ssid_len);
784
785 if (bss) {
786 cfg80211_unhold_bss(&bss->cbss);
787 ieee80211_rx_bss_put(local, bss);
788 }
789
782 if (self_disconnected) { 790 if (self_disconnected) {
783 if (deauth) 791 if (deauth)
784 ieee80211_send_deauth_disassoc(sdata, 792 ieee80211_send_deauth_disassoc(sdata,
@@ -854,7 +862,7 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata)
854 int wep_privacy; 862 int wep_privacy;
855 int privacy_invoked; 863 int privacy_invoked;
856 864
857 if (!ifmgd || (ifmgd->flags & IEEE80211_STA_MIXED_CELL)) 865 if (!ifmgd || (ifmgd->flags & IEEE80211_STA_EXT_SME))
858 return 0; 866 return 0;
859 867
860 bss = ieee80211_rx_bss_get(local, ifmgd->bssid, 868 bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
@@ -878,6 +886,7 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata)
878static void ieee80211_associate(struct ieee80211_sub_if_data *sdata) 886static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
879{ 887{
880 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 888 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
889 struct ieee80211_local *local = sdata->local;
881 890
882 ifmgd->assoc_tries++; 891 ifmgd->assoc_tries++;
883 if (ifmgd->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { 892 if (ifmgd->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
@@ -889,6 +898,12 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
889 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 898 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
890 sdata->local->hw.conf.channel->center_freq, 899 sdata->local->hw.conf.channel->center_freq,
891 ifmgd->ssid, ifmgd->ssid_len); 900 ifmgd->ssid, ifmgd->ssid_len);
901 /*
902 * We might have a pending scan which had no chance to run yet
903 * due to state == IEEE80211_STA_MLME_ASSOCIATE.
904 * Hence, queue the STAs work again
905 */
906 queue_work(local->hw.workqueue, &ifmgd->work);
892 return; 907 return;
893 } 908 }
894 909
@@ -907,13 +922,55 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
907 mod_timer(&ifmgd->timer, jiffies + IEEE80211_ASSOC_TIMEOUT); 922 mod_timer(&ifmgd->timer, jiffies + IEEE80211_ASSOC_TIMEOUT);
908} 923}
909 924
925void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
926 struct ieee80211_hdr *hdr)
927{
928 /*
929 * We can postpone the mgd.timer whenever receiving unicast frames
930 * from AP because we know that the connection is working both ways
931 * at that time. But multicast frames (and hence also beacons) must
932 * be ignored here, because we need to trigger the timer during
933 * data idle periods for sending the periodical probe request to
934 * the AP.
935 */
936 if (!is_multicast_ether_addr(hdr->addr1))
937 mod_timer(&sdata->u.mgd.timer,
938 jiffies + IEEE80211_MONITORING_INTERVAL);
939}
940
941void ieee80211_beacon_loss_work(struct work_struct *work)
942{
943 struct ieee80211_sub_if_data *sdata =
944 container_of(work, struct ieee80211_sub_if_data,
945 u.mgd.beacon_loss_work);
946 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
947
948 printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM "
949 "- sending probe request\n", sdata->dev->name,
950 sdata->u.mgd.bssid);
951
952 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
953 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
954 ifmgd->ssid_len, NULL, 0);
955
956 mod_timer(&ifmgd->timer, jiffies + IEEE80211_MONITORING_INTERVAL);
957}
958
959void ieee80211_beacon_loss(struct ieee80211_vif *vif)
960{
961 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
962
963 queue_work(sdata->local->hw.workqueue,
964 &sdata->u.mgd.beacon_loss_work);
965}
966EXPORT_SYMBOL(ieee80211_beacon_loss);
910 967
911static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) 968static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
912{ 969{
913 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 970 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
914 struct ieee80211_local *local = sdata->local; 971 struct ieee80211_local *local = sdata->local;
915 struct sta_info *sta; 972 struct sta_info *sta;
916 int disassoc; 973 bool disassoc = false;
917 974
918 /* TODO: start monitoring current AP signal quality and number of 975 /* TODO: start monitoring current AP signal quality and number of
919 * missed beacons. Scan other channels every now and then and search 976 * missed beacons. Scan other channels every now and then and search
@@ -928,36 +985,45 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
928 if (!sta) { 985 if (!sta) {
929 printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", 986 printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n",
930 sdata->dev->name, ifmgd->bssid); 987 sdata->dev->name, ifmgd->bssid);
931 disassoc = 1; 988 disassoc = true;
932 } else { 989 goto unlock;
933 disassoc = 0;
934 if (time_after(jiffies,
935 sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
936 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
937 printk(KERN_DEBUG "%s: No ProbeResp from "
938 "current AP %pM - assume out of "
939 "range\n",
940 sdata->dev->name, ifmgd->bssid);
941 disassoc = 1;
942 } else
943 ieee80211_send_probe_req(sdata, ifmgd->bssid,
944 ifmgd->ssid,
945 ifmgd->ssid_len,
946 NULL, 0);
947 ifmgd->flags ^= IEEE80211_STA_PROBEREQ_POLL;
948 } else {
949 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
950 if (time_after(jiffies, ifmgd->last_probe +
951 IEEE80211_PROBE_INTERVAL)) {
952 ifmgd->last_probe = jiffies;
953 ieee80211_send_probe_req(sdata, ifmgd->bssid,
954 ifmgd->ssid,
955 ifmgd->ssid_len,
956 NULL, 0);
957 }
958 }
959 } 990 }
960 991
992 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
993 time_after(jiffies, sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
994 printk(KERN_DEBUG "%s: no probe response from AP %pM "
995 "- disassociating\n",
996 sdata->dev->name, ifmgd->bssid);
997 disassoc = true;
998 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
999 goto unlock;
1000 }
1001
1002 /*
1003 * Beacon filtering is only enabled with power save and then the
1004 * stack should not check for beacon loss.
1005 */
1006 if (!((local->hw.flags & IEEE80211_HW_BEACON_FILTER) &&
1007 (local->hw.conf.flags & IEEE80211_CONF_PS)) &&
1008 time_after(jiffies,
1009 ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) {
1010 printk(KERN_DEBUG "%s: beacon loss from AP %pM "
1011 "- sending probe request\n",
1012 sdata->dev->name, ifmgd->bssid);
1013 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
1014 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1015 ifmgd->ssid_len, NULL, 0);
1016 goto unlock;
1017
1018 }
1019
1020 if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) {
1021 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
1022 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1023 ifmgd->ssid_len, NULL, 0);
1024 }
1025
1026 unlock:
961 rcu_read_unlock(); 1027 rcu_read_unlock();
962 1028
963 if (disassoc) 1029 if (disassoc)
@@ -975,7 +1041,11 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata)
975 1041
976 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name); 1042 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
977 ifmgd->flags |= IEEE80211_STA_AUTHENTICATED; 1043 ifmgd->flags |= IEEE80211_STA_AUTHENTICATED;
978 ieee80211_associate(sdata); 1044 if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
1045 /* Wait for SME to request association */
1046 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1047 } else
1048 ieee80211_associate(sdata);
979} 1049}
980 1050
981 1051
@@ -1061,12 +1131,15 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1061 switch (ifmgd->auth_alg) { 1131 switch (ifmgd->auth_alg) {
1062 case WLAN_AUTH_OPEN: 1132 case WLAN_AUTH_OPEN:
1063 case WLAN_AUTH_LEAP: 1133 case WLAN_AUTH_LEAP:
1134 case WLAN_AUTH_FT:
1064 ieee80211_auth_completed(sdata); 1135 ieee80211_auth_completed(sdata);
1136 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len);
1065 break; 1137 break;
1066 case WLAN_AUTH_SHARED_KEY: 1138 case WLAN_AUTH_SHARED_KEY:
1067 if (ifmgd->auth_transaction == 4) 1139 if (ifmgd->auth_transaction == 4) {
1068 ieee80211_auth_completed(sdata); 1140 ieee80211_auth_completed(sdata);
1069 else 1141 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len);
1142 } else
1070 ieee80211_auth_challenge(sdata, mgmt, len); 1143 ieee80211_auth_challenge(sdata, mgmt, len);
1071 break; 1144 break;
1072 } 1145 }
@@ -1092,9 +1165,10 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1092 printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n", 1165 printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n",
1093 sdata->dev->name, reason_code); 1166 sdata->dev->name, reason_code);
1094 1167
1095 if (ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE || 1168 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
1096 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE || 1169 (ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE ||
1097 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) { 1170 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE ||
1171 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)) {
1098 ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE; 1172 ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1099 mod_timer(&ifmgd->timer, jiffies + 1173 mod_timer(&ifmgd->timer, jiffies +
1100 IEEE80211_RETRY_AUTH_INTERVAL); 1174 IEEE80211_RETRY_AUTH_INTERVAL);
@@ -1102,6 +1176,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1102 1176
1103 ieee80211_set_disassoc(sdata, true, false, 0); 1177 ieee80211_set_disassoc(sdata, true, false, 0);
1104 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED; 1178 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
1179 cfg80211_send_rx_deauth(sdata->dev, (u8 *) mgmt, len);
1105} 1180}
1106 1181
1107 1182
@@ -1124,13 +1199,15 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1124 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", 1199 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
1125 sdata->dev->name, reason_code); 1200 sdata->dev->name, reason_code);
1126 1201
1127 if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) { 1202 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
1203 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) {
1128 ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE; 1204 ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE;
1129 mod_timer(&ifmgd->timer, jiffies + 1205 mod_timer(&ifmgd->timer, jiffies +
1130 IEEE80211_RETRY_AUTH_INTERVAL); 1206 IEEE80211_RETRY_AUTH_INTERVAL);
1131 } 1207 }
1132 1208
1133 ieee80211_set_disassoc(sdata, false, false, reason_code); 1209 ieee80211_set_disassoc(sdata, false, false, reason_code);
1210 cfg80211_send_rx_disassoc(sdata->dev, (u8 *) mgmt, len);
1134} 1211}
1135 1212
1136 1213
@@ -1346,7 +1423,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1346 bss_conf->assoc_capability = capab_info; 1423 bss_conf->assoc_capability = capab_info;
1347 ieee80211_set_associated(sdata, changed); 1424 ieee80211_set_associated(sdata, changed);
1348 1425
1426 /*
1427 * initialise the time of last beacon to be the association time,
1428 * otherwise beacon loss check will trigger immediately
1429 */
1430 ifmgd->last_beacon = jiffies;
1431
1349 ieee80211_associated(sdata); 1432 ieee80211_associated(sdata);
1433 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
1350} 1434}
1351 1435
1352 1436
@@ -1393,9 +1477,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1393 size_t len, 1477 size_t len,
1394 struct ieee80211_rx_status *rx_status) 1478 struct ieee80211_rx_status *rx_status)
1395{ 1479{
1480 struct ieee80211_if_managed *ifmgd;
1396 size_t baselen; 1481 size_t baselen;
1397 struct ieee802_11_elems elems; 1482 struct ieee802_11_elems elems;
1398 1483
1484 ifmgd = &sdata->u.mgd;
1485
1399 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) 1486 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
1400 return; /* ignore ProbeResp to foreign address */ 1487 return; /* ignore ProbeResp to foreign address */
1401 1488
@@ -1410,11 +1497,14 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1410 1497
1411 /* direct probe may be part of the association flow */ 1498 /* direct probe may be part of the association flow */
1412 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE, 1499 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
1413 &sdata->u.mgd.request)) { 1500 &ifmgd->request)) {
1414 printk(KERN_DEBUG "%s direct probe responded\n", 1501 printk(KERN_DEBUG "%s direct probe responded\n",
1415 sdata->dev->name); 1502 sdata->dev->name);
1416 ieee80211_authenticate(sdata); 1503 ieee80211_authenticate(sdata);
1417 } 1504 }
1505
1506 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
1507 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1418} 1508}
1419 1509
1420static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, 1510static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
@@ -1636,6 +1726,8 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata)
1636 ifmgd->auth_alg = WLAN_AUTH_SHARED_KEY; 1726 ifmgd->auth_alg = WLAN_AUTH_SHARED_KEY;
1637 else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_LEAP) 1727 else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_LEAP)
1638 ifmgd->auth_alg = WLAN_AUTH_LEAP; 1728 ifmgd->auth_alg = WLAN_AUTH_LEAP;
1729 else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_FT)
1730 ifmgd->auth_alg = WLAN_AUTH_FT;
1639 else 1731 else
1640 ifmgd->auth_alg = WLAN_AUTH_OPEN; 1732 ifmgd->auth_alg = WLAN_AUTH_OPEN;
1641 ifmgd->auth_transaction = -1; 1733 ifmgd->auth_transaction = -1;
@@ -1659,7 +1751,8 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
1659 u16 capa_val = WLAN_CAPABILITY_ESS; 1751 u16 capa_val = WLAN_CAPABILITY_ESS;
1660 struct ieee80211_channel *chan = local->oper_channel; 1752 struct ieee80211_channel *chan = local->oper_channel;
1661 1753
1662 if (ifmgd->flags & (IEEE80211_STA_AUTO_SSID_SEL | 1754 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
1755 ifmgd->flags & (IEEE80211_STA_AUTO_SSID_SEL |
1663 IEEE80211_STA_AUTO_BSSID_SEL | 1756 IEEE80211_STA_AUTO_BSSID_SEL |
1664 IEEE80211_STA_AUTO_CHANNEL_SEL)) { 1757 IEEE80211_STA_AUTO_CHANNEL_SEL)) {
1665 capa_mask |= WLAN_CAPABILITY_PRIVACY; 1758 capa_mask |= WLAN_CAPABILITY_PRIVACY;
@@ -1822,6 +1915,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1822 ifmgd = &sdata->u.mgd; 1915 ifmgd = &sdata->u.mgd;
1823 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 1916 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
1824 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 1917 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
1918 INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work);
1825 setup_timer(&ifmgd->timer, ieee80211_sta_timer, 1919 setup_timer(&ifmgd->timer, ieee80211_sta_timer,
1826 (unsigned long) sdata); 1920 (unsigned long) sdata);
1827 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, 1921 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
@@ -1834,7 +1928,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1834 ifmgd->flags |= IEEE80211_STA_CREATE_IBSS | 1928 ifmgd->flags |= IEEE80211_STA_CREATE_IBSS |
1835 IEEE80211_STA_AUTO_BSSID_SEL | 1929 IEEE80211_STA_AUTO_BSSID_SEL |
1836 IEEE80211_STA_AUTO_CHANNEL_SEL; 1930 IEEE80211_STA_AUTO_CHANNEL_SEL;
1837 if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4) 1931 if (sdata->local->hw.queues >= 4)
1838 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; 1932 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
1839} 1933}
1840 1934
@@ -1856,7 +1950,11 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata)
1856 ieee80211_set_disassoc(sdata, true, true, 1950 ieee80211_set_disassoc(sdata, true, true,
1857 WLAN_REASON_DEAUTH_LEAVING); 1951 WLAN_REASON_DEAUTH_LEAVING);
1858 1952
1859 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); 1953 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) ||
1954 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE)
1955 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
1956 else if (ifmgd->flags & IEEE80211_STA_EXT_SME)
1957 set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
1860 queue_work(local->hw.workqueue, &ifmgd->work); 1958 queue_work(local->hw.workqueue, &ifmgd->work);
1861 } 1959 }
1862} 1960}
@@ -1865,8 +1963,6 @@ int ieee80211_sta_commit(struct ieee80211_sub_if_data *sdata)
1865{ 1963{
1866 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1964 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1867 1965
1868 ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
1869
1870 if (ifmgd->ssid_len) 1966 if (ifmgd->ssid_len)
1871 ifmgd->flags |= IEEE80211_STA_SSID_SET; 1967 ifmgd->flags |= IEEE80211_STA_SSID_SET;
1872 else 1968 else
@@ -1885,6 +1981,10 @@ int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size
1885 ifmgd = &sdata->u.mgd; 1981 ifmgd = &sdata->u.mgd;
1886 1982
1887 if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) { 1983 if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) {
1984 /*
1985 * Do not use reassociation if SSID is changed (different ESS).
1986 */
1987 ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
1888 memset(ifmgd->ssid, 0, sizeof(ifmgd->ssid)); 1988 memset(ifmgd->ssid, 0, sizeof(ifmgd->ssid));
1889 memcpy(ifmgd->ssid, ssid, len); 1989 memcpy(ifmgd->ssid, ssid, len);
1890 ifmgd->ssid_len = len; 1990 ifmgd->ssid_len = len;
@@ -1923,7 +2023,8 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
1923 return ieee80211_sta_commit(sdata); 2023 return ieee80211_sta_commit(sdata);
1924} 2024}
1925 2025
1926int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len) 2026int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
2027 const char *ie, size_t len)
1927{ 2028{
1928 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2029 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1929 2030
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 44525f517077..027302326498 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -10,6 +10,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
10 struct ieee80211_sub_if_data *sdata; 10 struct ieee80211_sub_if_data *sdata;
11 struct ieee80211_if_init_conf conf; 11 struct ieee80211_if_init_conf conf;
12 struct sta_info *sta; 12 struct sta_info *sta;
13 unsigned long flags;
14
15 ieee80211_stop_queues_by_reason(hw,
16 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
13 17
14 flush_workqueue(local->hw.workqueue); 18 flush_workqueue(local->hw.workqueue);
15 19
@@ -17,10 +21,23 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
17 list_for_each_entry(sdata, &local->interfaces, list) 21 list_for_each_entry(sdata, &local->interfaces, list)
18 ieee80211_disable_keys(sdata); 22 ieee80211_disable_keys(sdata);
19 23
20 /* remove STAs */ 24 /* Tear down aggregation sessions */
21 list_for_each_entry(sta, &local->sta_list, list) { 25
26 rcu_read_lock();
27
28 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
29 list_for_each_entry_rcu(sta, &local->sta_list, list) {
30 set_sta_flags(sta, WLAN_STA_SUSPEND);
31 ieee80211_sta_tear_down_BA_sessions(sta);
32 }
33 }
22 34
23 if (local->ops->sta_notify) { 35 rcu_read_unlock();
36
37 /* remove STAs */
38 if (local->ops->sta_notify) {
39 spin_lock_irqsave(&local->sta_lock, flags);
40 list_for_each_entry(sta, &local->sta_list, list) {
24 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 41 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
25 sdata = container_of(sdata->bss, 42 sdata = container_of(sdata->bss,
26 struct ieee80211_sub_if_data, 43 struct ieee80211_sub_if_data,
@@ -29,11 +46,11 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
29 local->ops->sta_notify(hw, &sdata->vif, 46 local->ops->sta_notify(hw, &sdata->vif,
30 STA_NOTIFY_REMOVE, &sta->sta); 47 STA_NOTIFY_REMOVE, &sta->sta);
31 } 48 }
49 spin_unlock_irqrestore(&local->sta_lock, flags);
32 } 50 }
33 51
34 /* remove all interfaces */ 52 /* remove all interfaces */
35 list_for_each_entry(sdata, &local->interfaces, list) { 53 list_for_each_entry(sdata, &local->interfaces, list) {
36
37 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 54 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
38 sdata->vif.type != NL80211_IFTYPE_MONITOR && 55 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
39 netif_running(sdata->dev)) { 56 netif_running(sdata->dev)) {
@@ -61,6 +78,7 @@ int __ieee80211_resume(struct ieee80211_hw *hw)
61 struct ieee80211_sub_if_data *sdata; 78 struct ieee80211_sub_if_data *sdata;
62 struct ieee80211_if_init_conf conf; 79 struct ieee80211_if_init_conf conf;
63 struct sta_info *sta; 80 struct sta_info *sta;
81 unsigned long flags;
64 int res; 82 int res;
65 83
66 /* restart hardware */ 84 /* restart hardware */
@@ -72,7 +90,6 @@ int __ieee80211_resume(struct ieee80211_hw *hw)
72 90
73 /* add interfaces */ 91 /* add interfaces */
74 list_for_each_entry(sdata, &local->interfaces, list) { 92 list_for_each_entry(sdata, &local->interfaces, list) {
75
76 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 93 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
77 sdata->vif.type != NL80211_IFTYPE_MONITOR && 94 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
78 netif_running(sdata->dev)) { 95 netif_running(sdata->dev)) {
@@ -84,9 +101,9 @@ int __ieee80211_resume(struct ieee80211_hw *hw)
84 } 101 }
85 102
86 /* add STAs back */ 103 /* add STAs back */
87 list_for_each_entry(sta, &local->sta_list, list) { 104 if (local->ops->sta_notify) {
88 105 spin_lock_irqsave(&local->sta_lock, flags);
89 if (local->ops->sta_notify) { 106 list_for_each_entry(sta, &local->sta_list, list) {
90 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 107 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
91 sdata = container_of(sdata->bss, 108 sdata = container_of(sdata->bss,
92 struct ieee80211_sub_if_data, 109 struct ieee80211_sub_if_data,
@@ -95,8 +112,21 @@ int __ieee80211_resume(struct ieee80211_hw *hw)
95 local->ops->sta_notify(hw, &sdata->vif, 112 local->ops->sta_notify(hw, &sdata->vif,
96 STA_NOTIFY_ADD, &sta->sta); 113 STA_NOTIFY_ADD, &sta->sta);
97 } 114 }
115 spin_unlock_irqrestore(&local->sta_lock, flags);
98 } 116 }
99 117
118 /* Clear Suspend state so that ADDBA requests can be processed */
119
120 rcu_read_lock();
121
122 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
123 list_for_each_entry_rcu(sta, &local->sta_list, list) {
124 clear_sta_flags(sta, WLAN_STA_SUSPEND);
125 }
126 }
127
128 rcu_read_unlock();
129
100 /* add back keys */ 130 /* add back keys */
101 list_for_each_entry(sdata, &local->interfaces, list) 131 list_for_each_entry(sdata, &local->interfaces, list)
102 if (netif_running(sdata->dev)) 132 if (netif_running(sdata->dev))
@@ -113,5 +143,37 @@ int __ieee80211_resume(struct ieee80211_hw *hw)
113 ieee80211_configure_filter(local); 143 ieee80211_configure_filter(local);
114 netif_addr_unlock_bh(local->mdev); 144 netif_addr_unlock_bh(local->mdev);
115 145
146 /* Finally also reconfigure all the BSS information */
147 list_for_each_entry(sdata, &local->interfaces, list) {
148 u32 changed = ~0;
149 if (!netif_running(sdata->dev))
150 continue;
151 switch (sdata->vif.type) {
152 case NL80211_IFTYPE_STATION:
153 /* disable beacon change bits */
154 changed &= ~IEEE80211_IFCC_BEACON;
155 /* fall through */
156 case NL80211_IFTYPE_ADHOC:
157 case NL80211_IFTYPE_AP:
158 case NL80211_IFTYPE_MESH_POINT:
159 WARN_ON(ieee80211_if_config(sdata, changed));
160 ieee80211_bss_info_change_notify(sdata, ~0);
161 break;
162 case NL80211_IFTYPE_WDS:
163 break;
164 case NL80211_IFTYPE_AP_VLAN:
165 case NL80211_IFTYPE_MONITOR:
166 /* ignore virtual */
167 break;
168 case NL80211_IFTYPE_UNSPECIFIED:
169 case __NL80211_IFTYPE_AFTER_LAST:
170 WARN_ON(1);
171 break;
172 }
173 }
174
175 ieee80211_wake_queues_by_reason(hw,
176 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
177
116 return 0; 178 return 0;
117} 179}
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 3fa7ab285066..4641f00a1e5c 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -219,10 +219,12 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
219 info->control.rates[i].count = 1; 219 info->control.rates[i].count = 1;
220 } 220 }
221 221
222 if (sta && sdata->force_unicast_rateidx > -1) 222 if (sta && sdata->force_unicast_rateidx > -1) {
223 info->control.rates[0].idx = sdata->force_unicast_rateidx; 223 info->control.rates[0].idx = sdata->force_unicast_rateidx;
224 else 224 } else {
225 ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); 225 ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
226 info->flags |= IEEE80211_TX_INTFL_RCALGO;
227 }
226 228
227 /* 229 /*
228 * try to enforce the maximum rate the user wanted 230 * try to enforce the maximum rate the user wanted
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index b9164c9a9563..2ab5ad9e71ce 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -44,8 +44,10 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
44 struct rate_control_ref *ref = local->rate_ctrl; 44 struct rate_control_ref *ref = local->rate_ctrl;
45 struct ieee80211_sta *ista = &sta->sta; 45 struct ieee80211_sta *ista = &sta->sta;
46 void *priv_sta = sta->rate_ctrl_priv; 46 void *priv_sta = sta->rate_ctrl_priv;
47 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
47 48
48 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb); 49 if (likely(info->flags & IEEE80211_TX_INTFL_RCALGO))
50 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
49} 51}
50 52
51 53
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 66f7ecf51b92..64ebe664effc 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -142,6 +142,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
142 /* IEEE80211_RADIOTAP_FLAGS */ 142 /* IEEE80211_RADIOTAP_FLAGS */
143 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 143 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
144 *pos |= IEEE80211_RADIOTAP_F_FCS; 144 *pos |= IEEE80211_RADIOTAP_F_FCS;
145 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
146 *pos |= IEEE80211_RADIOTAP_F_BADFCS;
145 if (status->flag & RX_FLAG_SHORTPRE) 147 if (status->flag & RX_FLAG_SHORTPRE)
146 *pos |= IEEE80211_RADIOTAP_F_SHORTPRE; 148 *pos |= IEEE80211_RADIOTAP_F_SHORTPRE;
147 pos++; 149 pos++;
@@ -204,9 +206,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
204 /* ensure 2 byte alignment for the 2 byte field as required */ 206 /* ensure 2 byte alignment for the 2 byte field as required */
205 if ((pos - (unsigned char *)rthdr) & 1) 207 if ((pos - (unsigned char *)rthdr) & 1)
206 pos++; 208 pos++;
207 /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ 209 if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
208 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) 210 *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADPLCP);
209 *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS);
210 pos += 2; 211 pos += 2;
211} 212}
212 213
@@ -849,12 +850,19 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
849 * Mesh beacons will update last_rx when if they are found to 850 * Mesh beacons will update last_rx when if they are found to
850 * match the current local configuration when processed. 851 * match the current local configuration when processed.
851 */ 852 */
852 sta->last_rx = jiffies; 853 if (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
854 ieee80211_is_beacon(hdr->frame_control)) {
855 rx->sdata->u.mgd.last_beacon = jiffies;
856 } else
857 sta->last_rx = jiffies;
853 } 858 }
854 859
855 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 860 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
856 return RX_CONTINUE; 861 return RX_CONTINUE;
857 862
863 if (rx->sdata->vif.type == NL80211_IFTYPE_STATION)
864 ieee80211_sta_rx_notify(rx->sdata, hdr);
865
858 sta->rx_fragments++; 866 sta->rx_fragments++;
859 sta->rx_bytes += rx->skb->len; 867 sta->rx_bytes += rx->skb->len;
860 sta->last_signal = rx->status->signal; 868 sta->last_signal = rx->status->signal;
@@ -1876,18 +1884,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1876 if (ieee80211_vif_is_mesh(&sdata->vif)) 1884 if (ieee80211_vif_is_mesh(&sdata->vif))
1877 return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status); 1885 return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status);
1878 1886
1879 if (sdata->vif.type != NL80211_IFTYPE_STATION && 1887 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
1880 sdata->vif.type != NL80211_IFTYPE_ADHOC) 1888 return ieee80211_ibss_rx_mgmt(sdata, rx->skb, rx->status);
1881 return RX_DROP_MONITOR;
1882
1883 1889
1884 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 1890 if (sdata->vif.type == NL80211_IFTYPE_STATION)
1885 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
1886 return RX_DROP_MONITOR;
1887 return ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status); 1891 return ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status);
1888 }
1889 1892
1890 return ieee80211_ibss_rx_mgmt(sdata, rx->skb, rx->status); 1893 return RX_DROP_MONITOR;
1891} 1894}
1892 1895
1893static void ieee80211_rx_michael_mic_report(struct net_device *dev, 1896static void ieee80211_rx_michael_mic_report(struct net_device *dev,
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 5030a3c87509..3bf9839f5916 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -214,6 +214,66 @@ void ieee80211_scan_failed(struct ieee80211_local *local)
214 local->scan_req = NULL; 214 local->scan_req = NULL;
215} 215}
216 216
217/*
218 * inform AP that we will go to sleep so that it will buffer the frames
219 * while we scan
220 */
221static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
222{
223 struct ieee80211_local *local = sdata->local;
224 bool ps = false;
225
226 /* FIXME: what to do when local->pspolling is true? */
227
228 del_timer_sync(&local->dynamic_ps_timer);
229 cancel_work_sync(&local->dynamic_ps_enable_work);
230
231 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
232 ps = true;
233 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
234 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
235 }
236
237 if (!ps || !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
238 /*
239 * If power save was enabled, no need to send a nullfunc
240 * frame because AP knows that we are sleeping. But if the
241 * hardware is creating the nullfunc frame for power save
242 * status (ie. IEEE80211_HW_PS_NULLFUNC_STACK is not
243 * enabled) and power save was enabled, the firmware just
244 * sent a null frame with power save disabled. So we need
245 * to send a new nullfunc frame to inform the AP that we
246 * are again sleeping.
247 */
248 ieee80211_send_nullfunc(local, sdata, 1);
249}
250
251/* inform AP that we are awake again, unless power save is enabled */
252static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
253{
254 struct ieee80211_local *local = sdata->local;
255
256 if (!local->powersave)
257 ieee80211_send_nullfunc(local, sdata, 0);
258 else {
259 /*
260 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
261 * will send a nullfunc frame with the powersave bit set
262 * even though the AP already knows that we are sleeping.
263 * This could be avoided by sending a null frame with power
264 * save bit disabled before enabling the power save, but
265 * this doesn't gain anything.
266 *
267 * When IEEE80211_HW_PS_NULLFUNC_STACK is enabled, no need
268 * to send a nullfunc frame because AP already knows that
269 * we are sleeping, let's just enable power save mode in
270 * hardware.
271 */
272 local->hw.conf.flags |= IEEE80211_CONF_PS;
273 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
274 }
275}
276
217void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 277void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
218{ 278{
219 struct ieee80211_local *local = hw_to_local(hw); 279 struct ieee80211_local *local = hw_to_local(hw);
@@ -268,7 +328,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
268 /* Tell AP we're back */ 328 /* Tell AP we're back */
269 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 329 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
270 if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) { 330 if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
271 ieee80211_send_nullfunc(local, sdata, 0); 331 ieee80211_scan_ps_disable(sdata);
272 netif_tx_wake_all_queues(sdata->dev); 332 netif_tx_wake_all_queues(sdata->dev);
273 } 333 }
274 } else 334 } else
@@ -409,6 +469,19 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
409 return 0; 469 return 0;
410 } 470 }
411 471
472 /*
473 * Hardware/driver doesn't support hw_scan, so use software
474 * scanning instead. First send a nullfunc frame with power save
475 * bit on so that AP will buffer the frames for us while we are not
476 * listening, then send probe requests to each channel and wait for
477 * the responses. After all channels are scanned, tune back to the
478 * original channel and send a nullfunc frame with power save bit
479 * off to trigger the AP to send us all the buffered frames.
480 *
481 * Note that while local->sw_scanning is true everything else but
482 * nullfunc frames and probe requests will be dropped in
483 * ieee80211_tx_h_check_assoc().
484 */
412 local->sw_scanning = true; 485 local->sw_scanning = true;
413 if (local->ops->sw_scan_start) 486 if (local->ops->sw_scan_start)
414 local->ops->sw_scan_start(local_to_hw(local)); 487 local->ops->sw_scan_start(local_to_hw(local));
@@ -428,7 +501,7 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
428 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 501 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
429 if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) { 502 if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
430 netif_tx_stop_all_queues(sdata->dev); 503 netif_tx_stop_all_queues(sdata->dev);
431 ieee80211_send_nullfunc(local, sdata, 1); 504 ieee80211_scan_ps_enable(sdata);
432 } 505 }
433 } else 506 } else
434 netif_tx_stop_all_queues(sdata->dev); 507 netif_tx_stop_all_queues(sdata->dev);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 4ba3c540fcf3..c5f14e6bbde2 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -203,17 +203,6 @@ void sta_info_destroy(struct sta_info *sta)
203 if (tid_rx) 203 if (tid_rx)
204 tid_rx->shutdown = true; 204 tid_rx->shutdown = true;
205 205
206 /*
207 * The stop callback cannot find this station any more, but
208 * it didn't complete its work -- start the queue if necessary
209 */
210 if (sta->ampdu_mlme.tid_state_tx[i] & HT_AGG_STATE_INITIATOR_MSK &&
211 sta->ampdu_mlme.tid_state_tx[i] & HT_AGG_STATE_REQ_STOP_BA_MSK &&
212 local->hw.ampdu_queues)
213 ieee80211_wake_queue_by_reason(&local->hw,
214 local->hw.queues + sta->tid_to_tx_q[i],
215 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
216
217 spin_unlock_bh(&sta->lock); 206 spin_unlock_bh(&sta->lock);
218 207
219 /* 208 /*
@@ -239,6 +228,11 @@ void sta_info_destroy(struct sta_info *sta)
239 tid_tx = sta->ampdu_mlme.tid_tx[i]; 228 tid_tx = sta->ampdu_mlme.tid_tx[i];
240 if (tid_tx) { 229 if (tid_tx) {
241 del_timer_sync(&tid_tx->addba_resp_timer); 230 del_timer_sync(&tid_tx->addba_resp_timer);
231 /*
232 * STA removed while aggregation session being
233 * started? Bit odd, but purge frames anyway.
234 */
235 skb_queue_purge(&tid_tx->pending);
242 kfree(tid_tx); 236 kfree(tid_tx);
243 } 237 }
244 } 238 }
@@ -287,7 +281,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
287 * enable session_timer's data differentiation. refer to 281 * enable session_timer's data differentiation. refer to
288 * sta_rx_agg_session_timer_expired for useage */ 282 * sta_rx_agg_session_timer_expired for useage */
289 sta->timer_to_tid[i] = i; 283 sta->timer_to_tid[i] = i;
290 sta->tid_to_tx_q[i] = -1;
291 /* rx */ 284 /* rx */
292 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; 285 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
293 sta->ampdu_mlme.tid_rx[i] = NULL; 286 sta->ampdu_mlme.tid_rx[i] = NULL;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 1f45573c580c..5534d489f506 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -35,6 +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.
39 * Used to deny ADDBA requests (both TX and RX).
38 */ 40 */
39enum ieee80211_sta_info_flags { 41enum ieee80211_sta_info_flags {
40 WLAN_STA_AUTH = 1<<0, 42 WLAN_STA_AUTH = 1<<0,
@@ -48,6 +50,7 @@ enum ieee80211_sta_info_flags {
48 WLAN_STA_PSPOLL = 1<<8, 50 WLAN_STA_PSPOLL = 1<<8,
49 WLAN_STA_CLEAR_PS_FILT = 1<<9, 51 WLAN_STA_CLEAR_PS_FILT = 1<<9,
50 WLAN_STA_MFP = 1<<10, 52 WLAN_STA_MFP = 1<<10,
53 WLAN_STA_SUSPEND = 1<<11
51}; 54};
52 55
53#define STA_TID_NUM 16 56#define STA_TID_NUM 16
@@ -70,11 +73,13 @@ enum ieee80211_sta_info_flags {
70 * struct tid_ampdu_tx - TID aggregation information (Tx). 73 * struct tid_ampdu_tx - TID aggregation information (Tx).
71 * 74 *
72 * @addba_resp_timer: timer for peer's response to addba request 75 * @addba_resp_timer: timer for peer's response to addba request
76 * @pending: pending frames queue -- use sta's spinlock to protect
73 * @ssn: Starting Sequence Number expected to be aggregated. 77 * @ssn: Starting Sequence Number expected to be aggregated.
74 * @dialog_token: dialog token for aggregation session 78 * @dialog_token: dialog token for aggregation session
75 */ 79 */
76struct tid_ampdu_tx { 80struct tid_ampdu_tx {
77 struct timer_list addba_resp_timer; 81 struct timer_list addba_resp_timer;
82 struct sk_buff_head pending;
78 u16 ssn; 83 u16 ssn;
79 u8 dialog_token; 84 u8 dialog_token;
80}; 85};
@@ -201,7 +206,6 @@ struct sta_ampdu_mlme {
201 * @tid_seq: per-TID sequence numbers for sending to this STA 206 * @tid_seq: per-TID sequence numbers for sending to this STA
202 * @ampdu_mlme: A-MPDU state machine state 207 * @ampdu_mlme: A-MPDU state machine state
203 * @timer_to_tid: identity mapping to ID timers 208 * @timer_to_tid: identity mapping to ID timers
204 * @tid_to_tx_q: map tid to tx queue (invalid == negative values)
205 * @llid: Local link ID 209 * @llid: Local link ID
206 * @plid: Peer link ID 210 * @plid: Peer link ID
207 * @reason: Cancel reason on PLINK_HOLDING state 211 * @reason: Cancel reason on PLINK_HOLDING state
@@ -276,7 +280,6 @@ struct sta_info {
276 */ 280 */
277 struct sta_ampdu_mlme ampdu_mlme; 281 struct sta_ampdu_mlme ampdu_mlme;
278 u8 timer_to_tid[STA_TID_NUM]; 282 u8 timer_to_tid[STA_TID_NUM];
279 s8 tid_to_tx_q[STA_TID_NUM];
280 283
281#ifdef CONFIG_MAC80211_MESH 284#ifdef CONFIG_MAC80211_MESH
282 /* 285 /*
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 457238a2f3fc..3fb04a86444d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -34,8 +34,7 @@
34 34
35#define IEEE80211_TX_OK 0 35#define IEEE80211_TX_OK 0
36#define IEEE80211_TX_AGAIN 1 36#define IEEE80211_TX_AGAIN 1
37#define IEEE80211_TX_FRAG_AGAIN 2 37#define IEEE80211_TX_PENDING 2
38#define IEEE80211_TX_PENDING 3
39 38
40/* misc utils */ 39/* misc utils */
41 40
@@ -193,7 +192,19 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
193 return TX_CONTINUE; 192 return TX_CONTINUE;
194 193
195 if (unlikely(tx->local->sw_scanning) && 194 if (unlikely(tx->local->sw_scanning) &&
196 !ieee80211_is_probe_req(hdr->frame_control)) 195 !ieee80211_is_probe_req(hdr->frame_control) &&
196 !ieee80211_is_nullfunc(hdr->frame_control))
197 /*
198 * When software scanning only nullfunc frames (to notify
199 * the sleep state to the AP) and probe requests (for the
200 * active scan) are allowed, all other frames should not be
201 * sent and we should not get here, but if we do
202 * nonetheless, drop them to avoid sending them
203 * off-channel. See the link below and
204 * ieee80211_start_scan() for more.
205 *
206 * http://article.gmane.org/gmane.linux.kernel.wireless.general/30089
207 */
197 return TX_DROP; 208 return TX_DROP;
198 209
199 if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) 210 if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
@@ -690,17 +701,62 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
690 return TX_CONTINUE; 701 return TX_CONTINUE;
691} 702}
692 703
704static int ieee80211_fragment(struct ieee80211_local *local,
705 struct sk_buff *skb, int hdrlen,
706 int frag_threshold)
707{
708 struct sk_buff *tail = skb, *tmp;
709 int per_fragm = frag_threshold - hdrlen - FCS_LEN;
710 int pos = hdrlen + per_fragm;
711 int rem = skb->len - hdrlen - per_fragm;
712
713 if (WARN_ON(rem < 0))
714 return -EINVAL;
715
716 while (rem) {
717 int fraglen = per_fragm;
718
719 if (fraglen > rem)
720 fraglen = rem;
721 rem -= fraglen;
722 tmp = dev_alloc_skb(local->tx_headroom +
723 frag_threshold +
724 IEEE80211_ENCRYPT_HEADROOM +
725 IEEE80211_ENCRYPT_TAILROOM);
726 if (!tmp)
727 return -ENOMEM;
728 tail->next = tmp;
729 tail = tmp;
730 skb_reserve(tmp, local->tx_headroom +
731 IEEE80211_ENCRYPT_HEADROOM);
732 /* copy control information */
733 memcpy(tmp->cb, skb->cb, sizeof(tmp->cb));
734 skb_copy_queue_mapping(tmp, skb);
735 tmp->priority = skb->priority;
736 tmp->do_not_encrypt = skb->do_not_encrypt;
737 tmp->dev = skb->dev;
738 tmp->iif = skb->iif;
739
740 /* copy header and data */
741 memcpy(skb_put(tmp, hdrlen), skb->data, hdrlen);
742 memcpy(skb_put(tmp, fraglen), skb->data + pos, fraglen);
743
744 pos += fraglen;
745 }
746
747 skb->len = hdrlen + per_fragm;
748 return 0;
749}
750
693static ieee80211_tx_result debug_noinline 751static ieee80211_tx_result debug_noinline
694ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) 752ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
695{ 753{
696 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 754 struct sk_buff *skb = tx->skb;
697 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 755 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
698 size_t hdrlen, per_fragm, num_fragm, payload_len, left; 756 struct ieee80211_hdr *hdr = (void *)skb->data;
699 struct sk_buff **frags, *first, *frag;
700 int i;
701 u16 seq;
702 u8 *pos;
703 int frag_threshold = tx->local->fragmentation_threshold; 757 int frag_threshold = tx->local->fragmentation_threshold;
758 int hdrlen;
759 int fragnum;
704 760
705 if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) 761 if (!(tx->flags & IEEE80211_TX_FRAGMENTED))
706 return TX_CONTINUE; 762 return TX_CONTINUE;
@@ -713,58 +769,35 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
713 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) 769 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
714 return TX_DROP; 770 return TX_DROP;
715 771
716 first = tx->skb;
717
718 hdrlen = ieee80211_hdrlen(hdr->frame_control); 772 hdrlen = ieee80211_hdrlen(hdr->frame_control);
719 payload_len = first->len - hdrlen;
720 per_fragm = frag_threshold - hdrlen - FCS_LEN;
721 num_fragm = DIV_ROUND_UP(payload_len, per_fragm);
722
723 frags = kzalloc(num_fragm * sizeof(struct sk_buff *), GFP_ATOMIC);
724 if (!frags)
725 goto fail;
726
727 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
728 seq = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ;
729 pos = first->data + hdrlen + per_fragm;
730 left = payload_len - per_fragm;
731 for (i = 0; i < num_fragm - 1; i++) {
732 struct ieee80211_hdr *fhdr;
733 size_t copylen;
734
735 if (left <= 0)
736 goto fail;
737 773
738 /* reserve enough extra head and tail room for possible 774 /* internal error, why is TX_FRAGMENTED set? */
739 * encryption */ 775 if (WARN_ON(skb->len <= frag_threshold))
740 frag = frags[i] = 776 return TX_DROP;
741 dev_alloc_skb(tx->local->tx_headroom +
742 frag_threshold +
743 IEEE80211_ENCRYPT_HEADROOM +
744 IEEE80211_ENCRYPT_TAILROOM);
745 if (!frag)
746 goto fail;
747
748 /* Make sure that all fragments use the same priority so
749 * that they end up using the same TX queue */
750 frag->priority = first->priority;
751 777
752 skb_reserve(frag, tx->local->tx_headroom + 778 /*
753 IEEE80211_ENCRYPT_HEADROOM); 779 * Now fragment the frame. This will allocate all the fragments and
780 * chain them (using skb as the first fragment) to skb->next.
781 * During transmission, we will remove the successfully transmitted
782 * fragments from this list. When the low-level driver rejects one
783 * of the fragments then we will simply pretend to accept the skb
784 * but store it away as pending.
785 */
786 if (ieee80211_fragment(tx->local, skb, hdrlen, frag_threshold))
787 return TX_DROP;
754 788
755 /* copy TX information */ 789 /* update duration/seq/flags of fragments */
756 info = IEEE80211_SKB_CB(frag); 790 fragnum = 0;
757 memcpy(info, first->cb, sizeof(frag->cb)); 791 do {
792 int next_len;
793 const __le16 morefrags = cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
758 794
759 /* copy/fill in 802.11 header */ 795 hdr = (void *)skb->data;
760 fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); 796 info = IEEE80211_SKB_CB(skb);
761 memcpy(fhdr, first->data, hdrlen);
762 fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG));
763 797
764 if (i == num_fragm - 2) { 798 if (skb->next) {
765 /* clear MOREFRAGS bit for the last fragment */ 799 hdr->frame_control |= morefrags;
766 fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS); 800 next_len = skb->next->len;
767 } else {
768 /* 801 /*
769 * No multi-rate retries for fragmented frames, that 802 * No multi-rate retries for fragmented frames, that
770 * would completely throw off the NAV at other STAs. 803 * would completely throw off the NAV at other STAs.
@@ -775,37 +808,16 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
775 info->control.rates[4].idx = -1; 808 info->control.rates[4].idx = -1;
776 BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); 809 BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5);
777 info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; 810 info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
811 } else {
812 hdr->frame_control &= ~morefrags;
813 next_len = 0;
778 } 814 }
779 815 hdr->duration_id = ieee80211_duration(tx, 0, next_len);
780 /* copy data */ 816 hdr->seq_ctrl |= cpu_to_le16(fragnum & IEEE80211_SCTL_FRAG);
781 copylen = left > per_fragm ? per_fragm : left; 817 fragnum++;
782 memcpy(skb_put(frag, copylen), pos, copylen); 818 } while ((skb = skb->next));
783
784 skb_copy_queue_mapping(frag, first);
785
786 frag->do_not_encrypt = first->do_not_encrypt;
787 frag->dev = first->dev;
788 frag->iif = first->iif;
789
790 pos += copylen;
791 left -= copylen;
792 }
793 skb_trim(first, hdrlen + per_fragm);
794
795 tx->num_extra_frag = num_fragm - 1;
796 tx->extra_frag = frags;
797 819
798 return TX_CONTINUE; 820 return TX_CONTINUE;
799
800 fail:
801 if (frags) {
802 for (i = 0; i < num_fragm - 1; i++)
803 if (frags[i])
804 dev_kfree_skb(frags[i]);
805 kfree(frags);
806 }
807 I802_DEBUG_INC(tx->local->tx_handlers_drop_fragment);
808 return TX_DROP;
809} 821}
810 822
811static ieee80211_tx_result debug_noinline 823static ieee80211_tx_result debug_noinline
@@ -833,27 +845,19 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx)
833static ieee80211_tx_result debug_noinline 845static ieee80211_tx_result debug_noinline
834ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) 846ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
835{ 847{
836 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 848 struct sk_buff *skb = tx->skb;
837 int next_len, i; 849 struct ieee80211_hdr *hdr;
838 int group_addr = is_multicast_ether_addr(hdr->addr1); 850 int next_len;
839 851 bool group_addr;
840 if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) {
841 hdr->duration_id = ieee80211_duration(tx, group_addr, 0);
842 return TX_CONTINUE;
843 }
844 852
845 hdr->duration_id = ieee80211_duration(tx, group_addr, 853 do {
846 tx->extra_frag[0]->len); 854 hdr = (void *) skb->data;
855 next_len = skb->next ? skb->next->len : 0;
856 group_addr = is_multicast_ether_addr(hdr->addr1);
847 857
848 for (i = 0; i < tx->num_extra_frag; i++) { 858 hdr->duration_id =
849 if (i + 1 < tx->num_extra_frag) 859 ieee80211_duration(tx, group_addr, next_len);
850 next_len = tx->extra_frag[i + 1]->len; 860 } while ((skb = skb->next));
851 else
852 next_len = 0;
853
854 hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data;
855 hdr->duration_id = ieee80211_duration(tx, 0, next_len);
856 }
857 861
858 return TX_CONTINUE; 862 return TX_CONTINUE;
859} 863}
@@ -861,19 +865,16 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
861static ieee80211_tx_result debug_noinline 865static ieee80211_tx_result debug_noinline
862ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) 866ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
863{ 867{
864 int i; 868 struct sk_buff *skb = tx->skb;
865 869
866 if (!tx->sta) 870 if (!tx->sta)
867 return TX_CONTINUE; 871 return TX_CONTINUE;
868 872
869 tx->sta->tx_packets++; 873 tx->sta->tx_packets++;
870 tx->sta->tx_fragments++; 874 do {
871 tx->sta->tx_bytes += tx->skb->len; 875 tx->sta->tx_fragments++;
872 if (tx->extra_frag) { 876 tx->sta->tx_bytes += skb->len;
873 tx->sta->tx_fragments += tx->num_extra_frag; 877 } while ((skb = skb->next));
874 for (i = 0; i < tx->num_extra_frag; i++)
875 tx->sta->tx_bytes += tx->extra_frag[i]->len;
876 }
877 878
878 return TX_CONTINUE; 879 return TX_CONTINUE;
879} 880}
@@ -983,9 +984,9 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
983 struct ieee80211_hdr *hdr; 984 struct ieee80211_hdr *hdr;
984 struct ieee80211_sub_if_data *sdata; 985 struct ieee80211_sub_if_data *sdata;
985 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 986 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
986
987 int hdrlen, tid; 987 int hdrlen, tid;
988 u8 *qc, *state; 988 u8 *qc, *state;
989 bool queued = false;
989 990
990 memset(tx, 0, sizeof(*tx)); 991 memset(tx, 0, sizeof(*tx));
991 tx->skb = skb; 992 tx->skb = skb;
@@ -1012,25 +1013,53 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1012 */ 1013 */
1013 } 1014 }
1014 1015
1016 /*
1017 * If this flag is set to true anywhere, and we get here,
1018 * we are doing the needed processing, so remove the flag
1019 * now.
1020 */
1021 info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1022
1015 hdr = (struct ieee80211_hdr *) skb->data; 1023 hdr = (struct ieee80211_hdr *) skb->data;
1016 1024
1017 tx->sta = sta_info_get(local, hdr->addr1); 1025 tx->sta = sta_info_get(local, hdr->addr1);
1018 1026
1019 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control)) { 1027 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
1028 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
1020 unsigned long flags; 1029 unsigned long flags;
1030 struct tid_ampdu_tx *tid_tx;
1031
1021 qc = ieee80211_get_qos_ctl(hdr); 1032 qc = ieee80211_get_qos_ctl(hdr);
1022 tid = *qc & IEEE80211_QOS_CTL_TID_MASK; 1033 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
1023 1034
1024 spin_lock_irqsave(&tx->sta->lock, flags); 1035 spin_lock_irqsave(&tx->sta->lock, flags);
1036 /*
1037 * XXX: This spinlock could be fairly expensive, but see the
1038 * comment in agg-tx.c:ieee80211_agg_tx_operational().
1039 * One way to solve this would be to do something RCU-like
1040 * for managing the tid_tx struct and using atomic bitops
1041 * for the actual state -- by introducing an actual
1042 * 'operational' bit that would be possible. It would
1043 * require changing ieee80211_agg_tx_operational() to
1044 * set that bit, and changing the way tid_tx is managed
1045 * everywhere, including races between that bit and
1046 * tid_tx going away (tid_tx being added can be easily
1047 * committed to memory before the 'operational' bit).
1048 */
1049 tid_tx = tx->sta->ampdu_mlme.tid_tx[tid];
1025 state = &tx->sta->ampdu_mlme.tid_state_tx[tid]; 1050 state = &tx->sta->ampdu_mlme.tid_state_tx[tid];
1026 if (*state == HT_AGG_STATE_OPERATIONAL) { 1051 if (*state == HT_AGG_STATE_OPERATIONAL) {
1027 info->flags |= IEEE80211_TX_CTL_AMPDU; 1052 info->flags |= IEEE80211_TX_CTL_AMPDU;
1028 if (local->hw.ampdu_queues) 1053 } else if (*state != HT_AGG_STATE_IDLE) {
1029 skb_set_queue_mapping( 1054 /* in progress */
1030 skb, tx->local->hw.queues + 1055 queued = true;
1031 tx->sta->tid_to_tx_q[tid]); 1056 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1057 __skb_queue_tail(&tid_tx->pending, skb);
1032 } 1058 }
1033 spin_unlock_irqrestore(&tx->sta->lock, flags); 1059 spin_unlock_irqrestore(&tx->sta->lock, flags);
1060
1061 if (unlikely(queued))
1062 return TX_QUEUED;
1034 } 1063 }
1035 1064
1036 if (is_multicast_ether_addr(hdr->addr1)) { 1065 if (is_multicast_ether_addr(hdr->addr1)) {
@@ -1081,51 +1110,55 @@ static int ieee80211_tx_prepare(struct ieee80211_local *local,
1081 } 1110 }
1082 if (unlikely(!dev)) 1111 if (unlikely(!dev))
1083 return -ENODEV; 1112 return -ENODEV;
1084 /* initialises tx with control */ 1113 /*
1114 * initialises tx with control
1115 *
1116 * return value is safe to ignore here because this function
1117 * can only be invoked for multicast frames
1118 *
1119 * XXX: clean up
1120 */
1085 __ieee80211_tx_prepare(tx, skb, dev); 1121 __ieee80211_tx_prepare(tx, skb, dev);
1086 dev_put(dev); 1122 dev_put(dev);
1087 return 0; 1123 return 0;
1088} 1124}
1089 1125
1090static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, 1126static int __ieee80211_tx(struct ieee80211_local *local,
1091 struct ieee80211_tx_data *tx) 1127 struct sk_buff **skbp,
1128 struct sta_info *sta)
1092{ 1129{
1130 struct sk_buff *skb = *skbp, *next;
1093 struct ieee80211_tx_info *info; 1131 struct ieee80211_tx_info *info;
1094 int ret, i; 1132 int ret, len;
1133 bool fragm = false;
1095 1134
1096 if (skb) { 1135 local->mdev->trans_start = jiffies;
1136
1137 while (skb) {
1097 if (ieee80211_queue_stopped(&local->hw, 1138 if (ieee80211_queue_stopped(&local->hw,
1098 skb_get_queue_mapping(skb))) 1139 skb_get_queue_mapping(skb)))
1099 return IEEE80211_TX_PENDING; 1140 return IEEE80211_TX_PENDING;
1100 1141
1101 ret = local->ops->tx(local_to_hw(local), skb); 1142 info = IEEE80211_SKB_CB(skb);
1102 if (ret) 1143
1103 return IEEE80211_TX_AGAIN; 1144 if (fragm)
1104 local->mdev->trans_start = jiffies;
1105 ieee80211_led_tx(local, 1);
1106 }
1107 if (tx->extra_frag) {
1108 for (i = 0; i < tx->num_extra_frag; i++) {
1109 if (!tx->extra_frag[i])
1110 continue;
1111 info = IEEE80211_SKB_CB(tx->extra_frag[i]);
1112 info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | 1145 info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
1113 IEEE80211_TX_CTL_FIRST_FRAGMENT); 1146 IEEE80211_TX_CTL_FIRST_FRAGMENT);
1114 if (ieee80211_queue_stopped(&local->hw, 1147
1115 skb_get_queue_mapping(tx->extra_frag[i]))) 1148 next = skb->next;
1116 return IEEE80211_TX_FRAG_AGAIN; 1149 len = skb->len;
1117 1150 ret = local->ops->tx(local_to_hw(local), skb);
1118 ret = local->ops->tx(local_to_hw(local), 1151 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
1119 tx->extra_frag[i]); 1152 dev_kfree_skb(skb);
1120 if (ret) 1153 ret = NETDEV_TX_OK;
1121 return IEEE80211_TX_FRAG_AGAIN;
1122 local->mdev->trans_start = jiffies;
1123 ieee80211_led_tx(local, 1);
1124 tx->extra_frag[i] = NULL;
1125 } 1154 }
1126 kfree(tx->extra_frag); 1155 if (ret != NETDEV_TX_OK)
1127 tx->extra_frag = NULL; 1156 return IEEE80211_TX_AGAIN;
1157 *skbp = skb = next;
1158 ieee80211_led_tx(local, 1);
1159 fragm = true;
1128 } 1160 }
1161
1129 return IEEE80211_TX_OK; 1162 return IEEE80211_TX_OK;
1130} 1163}
1131 1164
@@ -1137,7 +1170,6 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1137{ 1170{
1138 struct sk_buff *skb = tx->skb; 1171 struct sk_buff *skb = tx->skb;
1139 ieee80211_tx_result res = TX_DROP; 1172 ieee80211_tx_result res = TX_DROP;
1140 int i;
1141 1173
1142#define CALL_TXH(txh) \ 1174#define CALL_TXH(txh) \
1143 res = txh(tx); \ 1175 res = txh(tx); \
@@ -1161,11 +1193,13 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1161 txh_done: 1193 txh_done:
1162 if (unlikely(res == TX_DROP)) { 1194 if (unlikely(res == TX_DROP)) {
1163 I802_DEBUG_INC(tx->local->tx_handlers_drop); 1195 I802_DEBUG_INC(tx->local->tx_handlers_drop);
1164 dev_kfree_skb(skb); 1196 while (skb) {
1165 for (i = 0; i < tx->num_extra_frag; i++) 1197 struct sk_buff *next;
1166 if (tx->extra_frag[i]) 1198
1167 dev_kfree_skb(tx->extra_frag[i]); 1199 next = skb->next;
1168 kfree(tx->extra_frag); 1200 dev_kfree_skb(skb);
1201 skb = next;
1202 }
1169 return -1; 1203 return -1;
1170 } else if (unlikely(res == TX_QUEUED)) { 1204 } else if (unlikely(res == TX_QUEUED)) {
1171 I802_DEBUG_INC(tx->local->tx_handlers_queued); 1205 I802_DEBUG_INC(tx->local->tx_handlers_queued);
@@ -1175,23 +1209,26 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1175 return 0; 1209 return 0;
1176} 1210}
1177 1211
1178static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb) 1212static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1213 bool txpending)
1179{ 1214{
1180 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1215 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1181 struct sta_info *sta; 1216 struct sta_info *sta;
1182 struct ieee80211_tx_data tx; 1217 struct ieee80211_tx_data tx;
1183 ieee80211_tx_result res_prepare; 1218 ieee80211_tx_result res_prepare;
1184 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1219 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1185 int ret, i; 1220 struct sk_buff *next;
1221 unsigned long flags;
1222 int ret, retries;
1186 u16 queue; 1223 u16 queue;
1187 1224
1188 queue = skb_get_queue_mapping(skb); 1225 queue = skb_get_queue_mapping(skb);
1189 1226
1190 WARN_ON(test_bit(queue, local->queues_pending)); 1227 WARN_ON(!txpending && !skb_queue_empty(&local->pending[queue]));
1191 1228
1192 if (unlikely(skb->len < 10)) { 1229 if (unlikely(skb->len < 10)) {
1193 dev_kfree_skb(skb); 1230 dev_kfree_skb(skb);
1194 return 0; 1231 return;
1195 } 1232 }
1196 1233
1197 rcu_read_lock(); 1234 rcu_read_lock();
@@ -1199,10 +1236,13 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)
1199 /* initialises tx */ 1236 /* initialises tx */
1200 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev); 1237 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev);
1201 1238
1202 if (res_prepare == TX_DROP) { 1239 if (unlikely(res_prepare == TX_DROP)) {
1203 dev_kfree_skb(skb); 1240 dev_kfree_skb(skb);
1204 rcu_read_unlock(); 1241 rcu_read_unlock();
1205 return 0; 1242 return;
1243 } else if (unlikely(res_prepare == TX_QUEUED)) {
1244 rcu_read_unlock();
1245 return;
1206 } 1246 }
1207 1247
1208 sta = tx.sta; 1248 sta = tx.sta;
@@ -1212,59 +1252,71 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)
1212 if (invoke_tx_handlers(&tx)) 1252 if (invoke_tx_handlers(&tx))
1213 goto out; 1253 goto out;
1214 1254
1215retry: 1255 retries = 0;
1216 ret = __ieee80211_tx(local, skb, &tx); 1256 retry:
1217 if (ret) { 1257 ret = __ieee80211_tx(local, &tx.skb, tx.sta);
1218 struct ieee80211_tx_stored_packet *store; 1258 switch (ret) {
1219 1259 case IEEE80211_TX_OK:
1260 break;
1261 case IEEE80211_TX_AGAIN:
1220 /* 1262 /*
1221 * Since there are no fragmented frames on A-MPDU 1263 * Since there are no fragmented frames on A-MPDU
1222 * queues, there's no reason for a driver to reject 1264 * queues, there's no reason for a driver to reject
1223 * a frame there, warn and drop it. 1265 * a frame there, warn and drop it.
1224 */ 1266 */
1225 if (ret != IEEE80211_TX_PENDING) 1267 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
1226 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) 1268 goto drop;
1227 goto drop; 1269 /* fall through */
1270 case IEEE80211_TX_PENDING:
1271 skb = tx.skb;
1272
1273 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1274
1275 if (__netif_subqueue_stopped(local->mdev, queue)) {
1276 do {
1277 next = skb->next;
1278 skb->next = NULL;
1279 if (unlikely(txpending))
1280 skb_queue_head(&local->pending[queue],
1281 skb);
1282 else
1283 skb_queue_tail(&local->pending[queue],
1284 skb);
1285 } while ((skb = next));
1228 1286
1229 store = &local->pending_packet[queue]; 1287 /*
1288 * Make sure nobody will enable the queue on us
1289 * (without going through the tasklet) nor disable the
1290 * netdev queue underneath the pending handling code.
1291 */
1292 __set_bit(IEEE80211_QUEUE_STOP_REASON_PENDING,
1293 &local->queue_stop_reasons[queue]);
1230 1294
1231 if (ret == IEEE80211_TX_FRAG_AGAIN) 1295 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1232 skb = NULL; 1296 flags);
1297 } else {
1298 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1299 flags);
1233 1300
1234 set_bit(queue, local->queues_pending); 1301 retries++;
1235 smp_mb(); 1302 if (WARN(retries > 10, "tx refused but queue active"))
1236 /* 1303 goto drop;
1237 * When the driver gets out of buffers during sending of
1238 * fragments and calls ieee80211_stop_queue, the netif
1239 * subqueue is stopped. There is, however, a small window
1240 * in which the PENDING bit is not yet set. If a buffer
1241 * gets available in that window (i.e. driver calls
1242 * ieee80211_wake_queue), we would end up with ieee80211_tx
1243 * called with the PENDING bit still set. Prevent this by
1244 * continuing transmitting here when that situation is
1245 * possible to have happened.
1246 */
1247 if (!__netif_subqueue_stopped(local->mdev, queue)) {
1248 clear_bit(queue, local->queues_pending);
1249 goto retry; 1304 goto retry;
1250 } 1305 }
1251 store->skb = skb;
1252 store->extra_frag = tx.extra_frag;
1253 store->num_extra_frag = tx.num_extra_frag;
1254 } 1306 }
1255 out: 1307 out:
1256 rcu_read_unlock(); 1308 rcu_read_unlock();
1257 return 0; 1309 return;
1258 1310
1259 drop: 1311 drop:
1260 if (skb)
1261 dev_kfree_skb(skb);
1262 for (i = 0; i < tx.num_extra_frag; i++)
1263 if (tx.extra_frag[i])
1264 dev_kfree_skb(tx.extra_frag[i]);
1265 kfree(tx.extra_frag);
1266 rcu_read_unlock(); 1312 rcu_read_unlock();
1267 return 0; 1313
1314 skb = tx.skb;
1315 while (skb) {
1316 next = skb->next;
1317 dev_kfree_skb(skb);
1318 skb = next;
1319 }
1268} 1320}
1269 1321
1270/* device xmit handlers */ 1322/* device xmit handlers */
@@ -1323,7 +1375,6 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1323 FOUND_SDATA, 1375 FOUND_SDATA,
1324 UNKNOWN_ADDRESS, 1376 UNKNOWN_ADDRESS,
1325 } monitor_iface = NOT_MONITOR; 1377 } monitor_iface = NOT_MONITOR;
1326 int ret;
1327 1378
1328 if (skb->iif) 1379 if (skb->iif)
1329 odev = dev_get_by_index(&init_net, skb->iif); 1380 odev = dev_get_by_index(&init_net, skb->iif);
@@ -1337,7 +1388,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1337 "originating device\n", dev->name); 1388 "originating device\n", dev->name);
1338#endif 1389#endif
1339 dev_kfree_skb(skb); 1390 dev_kfree_skb(skb);
1340 return 0; 1391 return NETDEV_TX_OK;
1341 } 1392 }
1342 1393
1343 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 1394 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
@@ -1366,7 +1417,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1366 else 1417 else
1367 if (mesh_nexthop_lookup(skb, osdata)) { 1418 if (mesh_nexthop_lookup(skb, osdata)) {
1368 dev_put(odev); 1419 dev_put(odev);
1369 return 0; 1420 return NETDEV_TX_OK;
1370 } 1421 }
1371 if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0) 1422 if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
1372 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh, 1423 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
@@ -1428,7 +1479,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1428 if (ieee80211_skb_resize(osdata->local, skb, headroom, may_encrypt)) { 1479 if (ieee80211_skb_resize(osdata->local, skb, headroom, may_encrypt)) {
1429 dev_kfree_skb(skb); 1480 dev_kfree_skb(skb);
1430 dev_put(odev); 1481 dev_put(odev);
1431 return 0; 1482 return NETDEV_TX_OK;
1432 } 1483 }
1433 1484
1434 if (osdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1485 if (osdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -1437,10 +1488,11 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1437 u.ap); 1488 u.ap);
1438 if (likely(monitor_iface != UNKNOWN_ADDRESS)) 1489 if (likely(monitor_iface != UNKNOWN_ADDRESS))
1439 info->control.vif = &osdata->vif; 1490 info->control.vif = &osdata->vif;
1440 ret = ieee80211_tx(odev, skb); 1491
1492 ieee80211_tx(odev, skb, false);
1441 dev_put(odev); 1493 dev_put(odev);
1442 1494
1443 return ret; 1495 return NETDEV_TX_OK;
1444} 1496}
1445 1497
1446int ieee80211_monitor_start_xmit(struct sk_buff *skb, 1498int ieee80211_monitor_start_xmit(struct sk_buff *skb,
@@ -1666,8 +1718,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1666 } 1718 }
1667 1719
1668 /* receiver and we are QoS enabled, use a QoS type frame */ 1720 /* receiver and we are QoS enabled, use a QoS type frame */
1669 if (sta_flags & WLAN_STA_WME && 1721 if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) {
1670 ieee80211_num_regular_queues(&local->hw) >= 4) {
1671 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); 1722 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
1672 hdrlen += 2; 1723 hdrlen += 2;
1673 } 1724 }
@@ -1799,19 +1850,58 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1799 */ 1850 */
1800void ieee80211_clear_tx_pending(struct ieee80211_local *local) 1851void ieee80211_clear_tx_pending(struct ieee80211_local *local)
1801{ 1852{
1802 int i, j; 1853 int i;
1803 struct ieee80211_tx_stored_packet *store;
1804 1854
1805 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) { 1855 for (i = 0; i < local->hw.queues; i++)
1806 if (!test_bit(i, local->queues_pending)) 1856 skb_queue_purge(&local->pending[i]);
1807 continue; 1857}
1808 store = &local->pending_packet[i]; 1858
1809 kfree_skb(store->skb); 1859static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1810 for (j = 0; j < store->num_extra_frag; j++) 1860 struct sk_buff *skb)
1811 kfree_skb(store->extra_frag[j]); 1861{
1812 kfree(store->extra_frag); 1862 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1813 clear_bit(i, local->queues_pending); 1863 struct ieee80211_sub_if_data *sdata;
1864 struct sta_info *sta;
1865 struct ieee80211_hdr *hdr;
1866 struct net_device *dev;
1867 int ret;
1868 bool result = true;
1869
1870 /* does interface still exist? */
1871 dev = dev_get_by_index(&init_net, skb->iif);
1872 if (!dev) {
1873 dev_kfree_skb(skb);
1874 return true;
1814 } 1875 }
1876
1877 /* validate info->control.vif against skb->iif */
1878 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1879 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1880 sdata = container_of(sdata->bss,
1881 struct ieee80211_sub_if_data,
1882 u.ap);
1883
1884 if (unlikely(info->control.vif && info->control.vif != &sdata->vif)) {
1885 dev_kfree_skb(skb);
1886 result = true;
1887 goto out;
1888 }
1889
1890 if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) {
1891 ieee80211_tx(dev, skb, true);
1892 } else {
1893 hdr = (struct ieee80211_hdr *)skb->data;
1894 sta = sta_info_get(local, hdr->addr1);
1895
1896 ret = __ieee80211_tx(local, &skb, sta);
1897 if (ret != IEEE80211_TX_OK)
1898 result = false;
1899 }
1900
1901 out:
1902 dev_put(dev);
1903
1904 return result;
1815} 1905}
1816 1906
1817/* 1907/*
@@ -1822,40 +1912,53 @@ void ieee80211_tx_pending(unsigned long data)
1822{ 1912{
1823 struct ieee80211_local *local = (struct ieee80211_local *)data; 1913 struct ieee80211_local *local = (struct ieee80211_local *)data;
1824 struct net_device *dev = local->mdev; 1914 struct net_device *dev = local->mdev;
1825 struct ieee80211_tx_stored_packet *store; 1915 unsigned long flags;
1826 struct ieee80211_tx_data tx; 1916 int i;
1827 int i, ret; 1917 bool next;
1828 1918
1919 rcu_read_lock();
1829 netif_tx_lock_bh(dev); 1920 netif_tx_lock_bh(dev);
1830 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
1831 /* Check that this queue is ok */
1832 if (__netif_subqueue_stopped(local->mdev, i) &&
1833 !test_bit(i, local->queues_pending_run))
1834 continue;
1835 1921
1836 if (!test_bit(i, local->queues_pending)) { 1922 for (i = 0; i < local->hw.queues; i++) {
1837 clear_bit(i, local->queues_pending_run); 1923 /*
1838 ieee80211_wake_queue(&local->hw, i); 1924 * If queue is stopped by something other than due to pending
1925 * frames, or we have no pending frames, proceed to next queue.
1926 */
1927 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1928 next = false;
1929 if (local->queue_stop_reasons[i] !=
1930 BIT(IEEE80211_QUEUE_STOP_REASON_PENDING) ||
1931 skb_queue_empty(&local->pending[i]))
1932 next = true;
1933 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
1934
1935 if (next)
1839 continue; 1936 continue;
1840 }
1841 1937
1842 clear_bit(i, local->queues_pending_run); 1938 /*
1939 * start the queue now to allow processing our packets,
1940 * we're under the tx lock here anyway so nothing will
1941 * happen as a result of this
1942 */
1843 netif_start_subqueue(local->mdev, i); 1943 netif_start_subqueue(local->mdev, i);
1844 1944
1845 store = &local->pending_packet[i]; 1945 while (!skb_queue_empty(&local->pending[i])) {
1846 tx.extra_frag = store->extra_frag; 1946 struct sk_buff *skb = skb_dequeue(&local->pending[i]);
1847 tx.num_extra_frag = store->num_extra_frag; 1947
1848 tx.flags = 0; 1948 if (!ieee80211_tx_pending_skb(local, skb)) {
1849 ret = __ieee80211_tx(local, store->skb, &tx); 1949 skb_queue_head(&local->pending[i], skb);
1850 if (ret) { 1950 break;
1851 if (ret == IEEE80211_TX_FRAG_AGAIN) 1951 }
1852 store->skb = NULL;
1853 } else {
1854 clear_bit(i, local->queues_pending);
1855 ieee80211_wake_queue(&local->hw, i);
1856 } 1952 }
1953
1954 /* Start regular packet processing again. */
1955 if (skb_queue_empty(&local->pending[i]))
1956 ieee80211_wake_queue_by_reason(&local->hw, i,
1957 IEEE80211_QUEUE_STOP_REASON_PENDING);
1857 } 1958 }
1959
1858 netif_tx_unlock_bh(dev); 1960 netif_tx_unlock_bh(dev);
1961 rcu_read_unlock();
1859} 1962}
1860 1963
1861/* functions for drivers to get certain frames */ 1964/* functions for drivers to get certain frames */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index e0431a1d218b..fdf432f14554 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -166,18 +166,13 @@ int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
166 166
167void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx) 167void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
168{ 168{
169 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 169 struct sk_buff *skb = tx->skb;
170 170 struct ieee80211_hdr *hdr;
171 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 171
172 if (tx->extra_frag) { 172 do {
173 struct ieee80211_hdr *fhdr; 173 hdr = (struct ieee80211_hdr *) skb->data;
174 int i; 174 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
175 for (i = 0; i < tx->num_extra_frag; i++) { 175 } while ((skb = skb->next));
176 fhdr = (struct ieee80211_hdr *)
177 tx->extra_frag[i]->data;
178 fhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
179 }
180 }
181} 176}
182 177
183int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 178int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
@@ -344,42 +339,21 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
344{ 339{
345 struct ieee80211_local *local = hw_to_local(hw); 340 struct ieee80211_local *local = hw_to_local(hw);
346 341
347 if (queue >= hw->queues) { 342 if (WARN_ON(queue >= hw->queues))
348 if (local->ampdu_ac_queue[queue - hw->queues] < 0) 343 return;
349 return;
350
351 /*
352 * for virtual aggregation queues, we need to refcount the
353 * internal mac80211 disable (multiple times!), keep track of
354 * driver disable _and_ make sure the regular queue is
355 * actually enabled.
356 */
357 if (reason == IEEE80211_QUEUE_STOP_REASON_AGGREGATION)
358 local->amdpu_ac_stop_refcnt[queue - hw->queues]--;
359 else
360 __clear_bit(reason, &local->queue_stop_reasons[queue]);
361
362 if (local->queue_stop_reasons[queue] ||
363 local->amdpu_ac_stop_refcnt[queue - hw->queues])
364 return;
365
366 /* now go on to treat the corresponding regular queue */
367 queue = local->ampdu_ac_queue[queue - hw->queues];
368 reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION;
369 }
370 344
371 __clear_bit(reason, &local->queue_stop_reasons[queue]); 345 __clear_bit(reason, &local->queue_stop_reasons[queue]);
372 346
347 if (!skb_queue_empty(&local->pending[queue]) &&
348 local->queue_stop_reasons[queue] ==
349 BIT(IEEE80211_QUEUE_STOP_REASON_PENDING))
350 tasklet_schedule(&local->tx_pending_tasklet);
351
373 if (local->queue_stop_reasons[queue] != 0) 352 if (local->queue_stop_reasons[queue] != 0)
374 /* someone still has this queue stopped */ 353 /* someone still has this queue stopped */
375 return; 354 return;
376 355
377 if (test_bit(queue, local->queues_pending)) { 356 netif_wake_subqueue(local->mdev, queue);
378 set_bit(queue, local->queues_pending_run);
379 tasklet_schedule(&local->tx_pending_tasklet);
380 } else {
381 netif_wake_subqueue(local->mdev, queue);
382 }
383} 357}
384 358
385void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 359void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -405,29 +379,18 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
405{ 379{
406 struct ieee80211_local *local = hw_to_local(hw); 380 struct ieee80211_local *local = hw_to_local(hw);
407 381
408 if (queue >= hw->queues) { 382 if (WARN_ON(queue >= hw->queues))
409 if (local->ampdu_ac_queue[queue - hw->queues] < 0) 383 return;
410 return;
411
412 /*
413 * for virtual aggregation queues, we need to refcount the
414 * internal mac80211 disable (multiple times!), keep track of
415 * driver disable _and_ make sure the regular queue is
416 * actually enabled.
417 */
418 if (reason == IEEE80211_QUEUE_STOP_REASON_AGGREGATION)
419 local->amdpu_ac_stop_refcnt[queue - hw->queues]++;
420 else
421 __set_bit(reason, &local->queue_stop_reasons[queue]);
422 384
423 /* now go on to treat the corresponding regular queue */ 385 /*
424 queue = local->ampdu_ac_queue[queue - hw->queues]; 386 * Only stop if it was previously running, this is necessary
425 reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION; 387 * for correct pending packets handling because there we may
426 } 388 * start (but not wake) the queue and rely on that.
389 */
390 if (!local->queue_stop_reasons[queue])
391 netif_stop_subqueue(local->mdev, queue);
427 392
428 __set_bit(reason, &local->queue_stop_reasons[queue]); 393 __set_bit(reason, &local->queue_stop_reasons[queue]);
429
430 netif_stop_subqueue(local->mdev, queue);
431} 394}
432 395
433void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 396void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -473,15 +436,9 @@ EXPORT_SYMBOL(ieee80211_stop_queues);
473int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) 436int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
474{ 437{
475 struct ieee80211_local *local = hw_to_local(hw); 438 struct ieee80211_local *local = hw_to_local(hw);
476 unsigned long flags;
477 439
478 if (queue >= hw->queues) { 440 if (WARN_ON(queue >= hw->queues))
479 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 441 return true;
480 queue = local->ampdu_ac_queue[queue - hw->queues];
481 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
482 if (queue < 0)
483 return true;
484 }
485 442
486 return __netif_subqueue_stopped(local->mdev, queue); 443 return __netif_subqueue_stopped(local->mdev, queue);
487} 444}
@@ -496,7 +453,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
496 453
497 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 454 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
498 455
499 for (i = 0; i < hw->queues + hw->ampdu_queues; i++) 456 for (i = 0; i < hw->queues; i++)
500 __ieee80211_wake_queue(hw, i, reason); 457 __ieee80211_wake_queue(hw, i, reason);
501 458
502 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 459 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
@@ -846,16 +803,9 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
846 struct ieee80211_local *local = sdata->local; 803 struct ieee80211_local *local = sdata->local;
847 struct sk_buff *skb; 804 struct sk_buff *skb;
848 struct ieee80211_mgmt *mgmt; 805 struct ieee80211_mgmt *mgmt;
849 const u8 *ie_auth = NULL;
850 int ie_auth_len = 0;
851
852 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
853 ie_auth_len = sdata->u.mgd.ie_auth_len;
854 ie_auth = sdata->u.mgd.ie_auth;
855 }
856 806
857 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 807 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
858 sizeof(*mgmt) + 6 + extra_len + ie_auth_len); 808 sizeof(*mgmt) + 6 + extra_len);
859 if (!skb) { 809 if (!skb) {
860 printk(KERN_DEBUG "%s: failed to allocate buffer for auth " 810 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
861 "frame\n", sdata->dev->name); 811 "frame\n", sdata->dev->name);
@@ -877,8 +827,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
877 mgmt->u.auth.status_code = cpu_to_le16(0); 827 mgmt->u.auth.status_code = cpu_to_le16(0);
878 if (extra) 828 if (extra)
879 memcpy(skb_put(skb, extra_len), extra, extra_len); 829 memcpy(skb_put(skb, extra_len), extra, extra_len);
880 if (ie_auth)
881 memcpy(skb_put(skb, ie_auth_len), ie_auth, ie_auth_len);
882 830
883 ieee80211_tx_skb(sdata, skb, encrypt); 831 ieee80211_tx_skb(sdata, skb, encrypt);
884} 832}
@@ -891,20 +839,11 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
891 struct ieee80211_supported_band *sband; 839 struct ieee80211_supported_band *sband;
892 struct sk_buff *skb; 840 struct sk_buff *skb;
893 struct ieee80211_mgmt *mgmt; 841 struct ieee80211_mgmt *mgmt;
894 u8 *pos, *supp_rates, *esupp_rates = NULL, *extra_preq_ie = NULL; 842 u8 *pos, *supp_rates, *esupp_rates = NULL;
895 int i, extra_preq_ie_len = 0; 843 int i;
896
897 switch (sdata->vif.type) {
898 case NL80211_IFTYPE_STATION:
899 extra_preq_ie_len = sdata->u.mgd.ie_probereq_len;
900 extra_preq_ie = sdata->u.mgd.ie_probereq;
901 break;
902 default:
903 break;
904 }
905 844
906 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + 845 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
907 ie_len + extra_preq_ie_len); 846 ie_len);
908 if (!skb) { 847 if (!skb) {
909 printk(KERN_DEBUG "%s: failed to allocate buffer for probe " 848 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
910 "request\n", sdata->dev->name); 849 "request\n", sdata->dev->name);
@@ -953,9 +892,6 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
953 892
954 if (ie) 893 if (ie)
955 memcpy(skb_put(skb, ie_len), ie, ie_len); 894 memcpy(skb_put(skb, ie_len), ie, ie_len);
956 if (extra_preq_ie)
957 memcpy(skb_put(skb, extra_preq_ie_len), extra_preq_ie,
958 extra_preq_ie_len);
959 895
960 ieee80211_tx_skb(sdata, skb, 0); 896 ieee80211_tx_skb(sdata, skb, 0);
961} 897}
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 7043ddc75498..ef73105b3061 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -329,24 +329,17 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
329ieee80211_tx_result 329ieee80211_tx_result
330ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) 330ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
331{ 331{
332 int i; 332 struct sk_buff *skb;
333 333
334 ieee80211_tx_set_protected(tx); 334 ieee80211_tx_set_protected(tx);
335 335
336 if (wep_encrypt_skb(tx, tx->skb) < 0) { 336 skb = tx->skb;
337 I802_DEBUG_INC(tx->local->tx_handlers_drop_wep); 337 do {
338 return TX_DROP; 338 if (wep_encrypt_skb(tx, skb) < 0) {
339 } 339 I802_DEBUG_INC(tx->local->tx_handlers_drop_wep);
340 340 return TX_DROP;
341 if (tx->extra_frag) {
342 for (i = 0; i < tx->num_extra_frag; i++) {
343 if (wep_encrypt_skb(tx, tx->extra_frag[i])) {
344 I802_DEBUG_INC(tx->local->
345 tx_handlers_drop_wep);
346 return TX_DROP;
347 }
348 } 341 }
349 } 342 } while ((skb = skb->next));
350 343
351 return TX_CONTINUE; 344 return TX_CONTINUE;
352} 345}
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 935c63ed3dfa..deb4ecec122a 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -129,14 +129,12 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
129 129
130 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 130 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
131 131
132 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
133 return -EOPNOTSUPP;
134
135 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 132 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
136 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length); 133 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
137 if (ret) 134 if (ret)
138 return ret; 135 return ret;
139 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 136 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
137 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
140 ieee80211_sta_req_auth(sdata); 138 ieee80211_sta_req_auth(sdata);
141 return 0; 139 return 0;
142 } 140 }
@@ -207,14 +205,6 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
207 205
208 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 206 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
209 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 207 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
210 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
211 if (len > IEEE80211_MAX_SSID_LEN)
212 return -EINVAL;
213 memcpy(sdata->u.mgd.ssid, ssid, len);
214 sdata->u.mgd.ssid_len = len;
215 return 0;
216 }
217
218 if (data->flags) 208 if (data->flags)
219 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; 209 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
220 else 210 else
@@ -224,6 +214,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
224 if (ret) 214 if (ret)
225 return ret; 215 return ret;
226 216
217 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
227 ieee80211_sta_req_auth(sdata); 218 ieee80211_sta_req_auth(sdata);
228 return 0; 219 return 0;
229 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 220 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
@@ -272,11 +263,7 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
272 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 263 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
273 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 264 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
274 int ret; 265 int ret;
275 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 266
276 memcpy(sdata->u.mgd.bssid, (u8 *) &ap_addr->sa_data,
277 ETH_ALEN);
278 return 0;
279 }
280 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data)) 267 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
281 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL | 268 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
282 IEEE80211_STA_AUTO_CHANNEL_SEL; 269 IEEE80211_STA_AUTO_CHANNEL_SEL;
@@ -287,6 +274,7 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
287 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data); 274 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
288 if (ret) 275 if (ret)
289 return ret; 276 return ret;
277 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
290 ieee80211_sta_req_auth(sdata); 278 ieee80211_sta_req_auth(sdata);
291 return 0; 279 return 0;
292 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 280 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
@@ -630,7 +618,7 @@ static int ieee80211_ioctl_siwencode(struct net_device *dev,
630 struct ieee80211_sub_if_data *sdata; 618 struct ieee80211_sub_if_data *sdata;
631 int idx, i, alg = ALG_WEP; 619 int idx, i, alg = ALG_WEP;
632 u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 620 u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
633 int remove = 0; 621 int remove = 0, ret;
634 622
635 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 623 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
636 624
@@ -656,11 +644,20 @@ static int ieee80211_ioctl_siwencode(struct net_device *dev,
656 return 0; 644 return 0;
657 } 645 }
658 646
659 return ieee80211_set_encryption( 647 ret = ieee80211_set_encryption(
660 sdata, bcaddr, 648 sdata, bcaddr,
661 idx, alg, remove, 649 idx, alg, remove,
662 !sdata->default_key, 650 !sdata->default_key,
663 keybuf, erq->length); 651 keybuf, erq->length);
652
653 if (!ret) {
654 if (remove)
655 sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
656 else
657 sdata->u.mgd.flags |= IEEE80211_STA_TKIP_WEP_USED;
658 }
659
660 return ret;
664} 661}
665 662
666 663
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 9101b48ec2ae..4f8bfea278f2 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -196,19 +196,13 @@ ieee80211_tx_result
196ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) 196ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
197{ 197{
198 struct sk_buff *skb = tx->skb; 198 struct sk_buff *skb = tx->skb;
199 int i;
200 199
201 ieee80211_tx_set_protected(tx); 200 ieee80211_tx_set_protected(tx);
202 201
203 if (tkip_encrypt_skb(tx, skb) < 0) 202 do {
204 return TX_DROP; 203 if (tkip_encrypt_skb(tx, skb) < 0)
205 204 return TX_DROP;
206 if (tx->extra_frag) { 205 } while ((skb = skb->next));
207 for (i = 0; i < tx->num_extra_frag; i++) {
208 if (tkip_encrypt_skb(tx, tx->extra_frag[i]))
209 return TX_DROP;
210 }
211 }
212 206
213 return TX_CONTINUE; 207 return TX_CONTINUE;
214} 208}
@@ -428,19 +422,13 @@ ieee80211_tx_result
428ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) 422ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
429{ 423{
430 struct sk_buff *skb = tx->skb; 424 struct sk_buff *skb = tx->skb;
431 int i;
432 425
433 ieee80211_tx_set_protected(tx); 426 ieee80211_tx_set_protected(tx);
434 427
435 if (ccmp_encrypt_skb(tx, skb) < 0) 428 do {
436 return TX_DROP; 429 if (ccmp_encrypt_skb(tx, skb) < 0)
437 430 return TX_DROP;
438 if (tx->extra_frag) { 431 } while ((skb = skb->next));
439 for (i = 0; i < tx->num_extra_frag; i++) {
440 if (ccmp_encrypt_skb(tx, tx->extra_frag[i]))
441 return TX_DROP;
442 }
443 }
444 432
445 return TX_CONTINUE; 433 return TX_CONTINUE;
446} 434}
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 092ae6faccca..3c3bc9e579ed 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -10,51 +10,19 @@ config CFG80211_REG_DEBUG
10 10
11 If unsure, say N. 11 If unsure, say N.
12 12
13config NL80211
14 bool "nl80211 new netlink interface support"
15 depends on CFG80211
16 default y
17 ---help---
18 This option turns on the new netlink interface
19 (nl80211) support in cfg80211.
20
21 If =n, drivers using mac80211 will be configured via
22 wireless extension support provided by that subsystem.
23
24 If unsure, say Y.
25
26config WIRELESS_OLD_REGULATORY 13config WIRELESS_OLD_REGULATORY
27 bool "Old wireless static regulatory definitions" 14 bool "Old wireless static regulatory definitions"
28 default y 15 default n
29 ---help--- 16 ---help---
30 This option enables the old static regulatory information 17 This option enables the old static regulatory information
31 and uses it within the new framework. This is available 18 and uses it within the new framework. This option is available
32 temporarily as an option to help prevent immediate issues 19 for historical reasons and it is advised to leave it off.
33 due to the switch to the new regulatory framework which 20
34 does require a new userspace application which has the 21 For details see:
35 database of regulatory information (CRDA) and another for 22
36 setting regulatory domains (iw). 23 http://wireless.kernel.org/en/developers/Regulatory
37 24
38 For more information see: 25 Say N and if you say Y, please tell us why. The default is N.
39
40 http://wireless.kernel.org/en/developers/Regulatory/CRDA
41 http://wireless.kernel.org/en/users/Documentation/iw
42
43 It is important to note though that if you *do* have CRDA present
44 and if this option is enabled CRDA *will* be called to update the
45 regulatory domain (for US and JP only). Support for letting the user
46 set the regulatory domain through iw is also supported. This option
47 mainly exists to leave around for a kernel release some old static
48 regulatory domains that were defined and to keep around the old
49 ieee80211_regdom module parameter. This is being phased out and you
50 should stop using them ASAP.
51
52 Note: You will need CRDA if you want 802.11d support
53
54 Say Y unless you have installed a new userspace application.
55 Also say Y if have one currently depending on the ieee80211_regdom
56 module parameter and cannot port it to use the new userspace
57 interfaces.
58 26
59config WIRELESS_EXT 27config WIRELESS_EXT
60 bool "Wireless extensions" 28 bool "Wireless extensions"
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index dad43c24f695..6d1e7b27b752 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,8 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o 5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o 6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
7 7
8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o
9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o 9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
10cfg80211-$(CONFIG_NL80211) += nl80211.o
11 10
12ccflags-y += -D__CHECK_ENDIAN__ 11ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 17fe39049740..d1f556535f6d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -87,7 +87,7 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
87} 87}
88 88
89/* requires cfg80211_mutex to be held! */ 89/* requires cfg80211_mutex to be held! */
90static struct cfg80211_registered_device * 90struct cfg80211_registered_device *
91__cfg80211_drv_from_info(struct genl_info *info) 91__cfg80211_drv_from_info(struct genl_info *info)
92{ 92{
93 int ifindex; 93 int ifindex;
@@ -176,13 +176,14 @@ void cfg80211_put_dev(struct cfg80211_registered_device *drv)
176 mutex_unlock(&drv->mtx); 176 mutex_unlock(&drv->mtx);
177} 177}
178 178
179/* requires cfg80211_mutex to be held */
179int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 180int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
180 char *newname) 181 char *newname)
181{ 182{
182 struct cfg80211_registered_device *drv; 183 struct cfg80211_registered_device *drv;
183 int wiphy_idx, taken = -1, result, digits; 184 int wiphy_idx, taken = -1, result, digits;
184 185
185 mutex_lock(&cfg80211_mutex); 186 assert_cfg80211_lock();
186 187
187 /* prohibit calling the thing phy%d when %d is not its number */ 188 /* prohibit calling the thing phy%d when %d is not its number */
188 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); 189 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
@@ -195,30 +196,23 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
195 * deny the name if it is phy<idx> where <idx> is printed 196 * deny the name if it is phy<idx> where <idx> is printed
196 * without leading zeroes. taken == strlen(newname) here 197 * without leading zeroes. taken == strlen(newname) here
197 */ 198 */
198 result = -EINVAL;
199 if (taken == strlen(PHY_NAME) + digits) 199 if (taken == strlen(PHY_NAME) + digits)
200 goto out_unlock; 200 return -EINVAL;
201 } 201 }
202 202
203 203
204 /* Ignore nop renames */ 204 /* Ignore nop renames */
205 result = 0;
206 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) 205 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
207 goto out_unlock; 206 return 0;
208 207
209 /* Ensure another device does not already have this name. */ 208 /* Ensure another device does not already have this name. */
210 list_for_each_entry(drv, &cfg80211_drv_list, list) { 209 list_for_each_entry(drv, &cfg80211_drv_list, list)
211 result = -EINVAL;
212 if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0) 210 if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0)
213 goto out_unlock; 211 return -EINVAL;
214 }
215 212
216 /* this will only check for collisions in sysfs
217 * which is not even always compiled in.
218 */
219 result = device_rename(&rdev->wiphy.dev, newname); 213 result = device_rename(&rdev->wiphy.dev, newname);
220 if (result) 214 if (result)
221 goto out_unlock; 215 return result;
222 216
223 if (rdev->wiphy.debugfsdir && 217 if (rdev->wiphy.debugfsdir &&
224 !debugfs_rename(rdev->wiphy.debugfsdir->d_parent, 218 !debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
@@ -228,13 +222,9 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
228 printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", 222 printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n",
229 newname); 223 newname);
230 224
231 result = 0; 225 nl80211_notify_dev_rename(rdev);
232out_unlock:
233 mutex_unlock(&cfg80211_mutex);
234 if (result == 0)
235 nl80211_notify_dev_rename(rdev);
236 226
237 return result; 227 return 0;
238} 228}
239 229
240/* exported functions */ 230/* exported functions */
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 6acd483a61f8..d43daa236ef9 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -90,6 +90,8 @@ struct cfg80211_internal_bss {
90 struct rb_node rbn; 90 struct rb_node rbn;
91 unsigned long ts; 91 unsigned long ts;
92 struct kref ref; 92 struct kref ref;
93 bool hold;
94
93 /* must be last because of priv member */ 95 /* must be last because of priv member */
94 struct cfg80211_bss pub; 96 struct cfg80211_bss pub;
95}; 97};
@@ -97,6 +99,9 @@ struct cfg80211_internal_bss {
97struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx); 99struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx);
98int get_wiphy_idx(struct wiphy *wiphy); 100int get_wiphy_idx(struct wiphy *wiphy);
99 101
102struct cfg80211_registered_device *
103__cfg80211_drv_from_info(struct genl_info *info);
104
100/* 105/*
101 * This function returns a pointer to the driver 106 * This function returns a pointer to the driver
102 * that the genl_info item that is passed refers to. 107 * that the genl_info item that is passed refers to.
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
new file mode 100644
index 000000000000..bec5721b6f99
--- /dev/null
+++ b/net/wireless/mlme.c
@@ -0,0 +1,46 @@
1/*
2 * cfg80211 MLME SAP interface
3 *
4 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
5 */
6
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/netdevice.h>
10#include <linux/nl80211.h>
11#include <net/cfg80211.h>
12#include "core.h"
13#include "nl80211.h"
14
15void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
16{
17 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
18 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
19 nl80211_send_rx_auth(rdev, dev, buf, len);
20}
21EXPORT_SYMBOL(cfg80211_send_rx_auth);
22
23void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
24{
25 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
26 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
27 nl80211_send_rx_assoc(rdev, dev, buf, len);
28}
29EXPORT_SYMBOL(cfg80211_send_rx_assoc);
30
31void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, size_t len)
32{
33 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
34 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
35 nl80211_send_rx_deauth(rdev, dev, buf, len);
36}
37EXPORT_SYMBOL(cfg80211_send_rx_deauth);
38
39void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
40 size_t len)
41{
42 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
43 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
44 nl80211_send_rx_disassoc(rdev, dev, buf, len);
45}
46EXPORT_SYMBOL(cfg80211_send_rx_disassoc);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ab9d8f14e151..353e1a4ece83 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -111,6 +111,11 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
111 .len = IEEE80211_MAX_DATA_LEN }, 111 .len = IEEE80211_MAX_DATA_LEN },
112 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED }, 112 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
113 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED }, 113 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
114
115 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
116 .len = IEEE80211_MAX_SSID_LEN },
117 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
118 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
114}; 119};
115 120
116/* message building helper */ 121/* message building helper */
@@ -131,6 +136,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
131 struct nlattr *nl_freqs, *nl_freq; 136 struct nlattr *nl_freqs, *nl_freq;
132 struct nlattr *nl_rates, *nl_rate; 137 struct nlattr *nl_rates, *nl_rate;
133 struct nlattr *nl_modes; 138 struct nlattr *nl_modes;
139 struct nlattr *nl_cmds;
134 enum ieee80211_band band; 140 enum ieee80211_band band;
135 struct ieee80211_channel *chan; 141 struct ieee80211_channel *chan;
136 struct ieee80211_rate *rate; 142 struct ieee80211_rate *rate;
@@ -242,6 +248,35 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
242 } 248 }
243 nla_nest_end(msg, nl_bands); 249 nla_nest_end(msg, nl_bands);
244 250
251 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
252 if (!nl_cmds)
253 goto nla_put_failure;
254
255 i = 0;
256#define CMD(op, n) \
257 do { \
258 if (dev->ops->op) { \
259 i++; \
260 NLA_PUT_U32(msg, i, NL80211_CMD_ ## n); \
261 } \
262 } while (0)
263
264 CMD(add_virtual_intf, NEW_INTERFACE);
265 CMD(change_virtual_intf, SET_INTERFACE);
266 CMD(add_key, NEW_KEY);
267 CMD(add_beacon, NEW_BEACON);
268 CMD(add_station, NEW_STATION);
269 CMD(add_mpath, NEW_MPATH);
270 CMD(set_mesh_params, SET_MESH_PARAMS);
271 CMD(change_bss, SET_BSS);
272 CMD(auth, AUTHENTICATE);
273 CMD(assoc, ASSOCIATE);
274 CMD(deauth, DEAUTHENTICATE);
275 CMD(disassoc, DISASSOCIATE);
276
277#undef CMD
278 nla_nest_end(msg, nl_cmds);
279
245 return genlmsg_end(msg, hdr); 280 return genlmsg_end(msg, hdr);
246 281
247 nla_put_failure: 282 nla_put_failure:
@@ -331,16 +366,26 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
331 int result = 0, rem_txq_params = 0; 366 int result = 0, rem_txq_params = 0;
332 struct nlattr *nl_txq_params; 367 struct nlattr *nl_txq_params;
333 368
334 rdev = cfg80211_get_dev_from_info(info); 369 rtnl_lock();
335 if (IS_ERR(rdev)) 370
336 return PTR_ERR(rdev); 371 mutex_lock(&cfg80211_mutex);
337 372
338 if (info->attrs[NL80211_ATTR_WIPHY_NAME]) { 373 rdev = __cfg80211_drv_from_info(info);
374 if (IS_ERR(rdev)) {
375 result = PTR_ERR(rdev);
376 goto unlock;
377 }
378
379 mutex_lock(&rdev->mtx);
380
381 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
339 result = cfg80211_dev_rename( 382 result = cfg80211_dev_rename(
340 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); 383 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
341 if (result) 384
342 goto bad_res; 385 mutex_unlock(&cfg80211_mutex);
343 } 386
387 if (result)
388 goto bad_res;
344 389
345 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { 390 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
346 struct ieee80211_txq_params txq_params; 391 struct ieee80211_txq_params txq_params;
@@ -436,7 +481,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
436 481
437 482
438 bad_res: 483 bad_res:
439 cfg80211_put_dev(rdev); 484 mutex_unlock(&rdev->mtx);
485 unlock:
486 rtnl_unlock();
440 return result; 487 return result;
441} 488}
442 489
@@ -572,21 +619,31 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
572 enum nl80211_iftype type; 619 enum nl80211_iftype type;
573 struct net_device *dev; 620 struct net_device *dev;
574 u32 _flags, *flags = NULL; 621 u32 _flags, *flags = NULL;
622 bool change = false;
575 623
576 memset(&params, 0, sizeof(params)); 624 memset(&params, 0, sizeof(params));
577 625
626 rtnl_lock();
627
578 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 628 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
579 if (err) 629 if (err)
580 return err; 630 goto unlock_rtnl;
631
581 ifindex = dev->ifindex; 632 ifindex = dev->ifindex;
582 type = dev->ieee80211_ptr->iftype; 633 type = dev->ieee80211_ptr->iftype;
583 dev_put(dev); 634 dev_put(dev);
584 635
585 err = -EINVAL;
586 if (info->attrs[NL80211_ATTR_IFTYPE]) { 636 if (info->attrs[NL80211_ATTR_IFTYPE]) {
587 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 637 enum nl80211_iftype ntype;
588 if (type > NL80211_IFTYPE_MAX) 638
639 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
640 if (type != ntype)
641 change = true;
642 type = ntype;
643 if (type > NL80211_IFTYPE_MAX) {
644 err = -EINVAL;
589 goto unlock; 645 goto unlock;
646 }
590 } 647 }
591 648
592 if (!drv->ops->change_virtual_intf || 649 if (!drv->ops->change_virtual_intf ||
@@ -602,6 +659,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
602 } 659 }
603 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); 660 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
604 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); 661 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
662 change = true;
605 } 663 }
606 664
607 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { 665 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
@@ -611,20 +669,26 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
611 } 669 }
612 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS], 670 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
613 &_flags); 671 &_flags);
614 if (!err) 672 if (err)
615 flags = &_flags; 673 goto unlock;
674
675 flags = &_flags;
676 change = true;
616 } 677 }
617 rtnl_lock(); 678
618 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, 679 if (change)
619 type, flags, &params); 680 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
681 type, flags, &params);
682 else
683 err = 0;
620 684
621 dev = __dev_get_by_index(&init_net, ifindex); 685 dev = __dev_get_by_index(&init_net, ifindex);
622 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type)); 686 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
623 687
624 rtnl_unlock();
625
626 unlock: 688 unlock:
627 cfg80211_put_dev(drv); 689 cfg80211_put_dev(drv);
690 unlock_rtnl:
691 rtnl_unlock();
628 return err; 692 return err;
629} 693}
630 694
@@ -647,9 +711,13 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
647 return -EINVAL; 711 return -EINVAL;
648 } 712 }
649 713
714 rtnl_lock();
715
650 drv = cfg80211_get_dev_from_info(info); 716 drv = cfg80211_get_dev_from_info(info);
651 if (IS_ERR(drv)) 717 if (IS_ERR(drv)) {
652 return PTR_ERR(drv); 718 err = PTR_ERR(drv);
719 goto unlock_rtnl;
720 }
653 721
654 if (!drv->ops->add_virtual_intf || 722 if (!drv->ops->add_virtual_intf ||
655 !(drv->wiphy.interface_modes & (1 << type))) { 723 !(drv->wiphy.interface_modes & (1 << type))) {
@@ -663,18 +731,17 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
663 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); 731 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
664 } 732 }
665 733
666 rtnl_lock();
667 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 734 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
668 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, 735 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
669 &flags); 736 &flags);
670 err = drv->ops->add_virtual_intf(&drv->wiphy, 737 err = drv->ops->add_virtual_intf(&drv->wiphy,
671 nla_data(info->attrs[NL80211_ATTR_IFNAME]), 738 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
672 type, err ? NULL : &flags, &params); 739 type, err ? NULL : &flags, &params);
673 rtnl_unlock();
674
675 740
676 unlock: 741 unlock:
677 cfg80211_put_dev(drv); 742 cfg80211_put_dev(drv);
743 unlock_rtnl:
744 rtnl_unlock();
678 return err; 745 return err;
679} 746}
680 747
@@ -684,9 +751,11 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
684 int ifindex, err; 751 int ifindex, err;
685 struct net_device *dev; 752 struct net_device *dev;
686 753
754 rtnl_lock();
755
687 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 756 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
688 if (err) 757 if (err)
689 return err; 758 goto unlock_rtnl;
690 ifindex = dev->ifindex; 759 ifindex = dev->ifindex;
691 dev_put(dev); 760 dev_put(dev);
692 761
@@ -695,12 +764,12 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
695 goto out; 764 goto out;
696 } 765 }
697 766
698 rtnl_lock();
699 err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex); 767 err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
700 rtnl_unlock();
701 768
702 out: 769 out:
703 cfg80211_put_dev(drv); 770 cfg80211_put_dev(drv);
771 unlock_rtnl:
772 rtnl_unlock();
704 return err; 773 return err;
705} 774}
706 775
@@ -752,9 +821,11 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
752 if (info->attrs[NL80211_ATTR_MAC]) 821 if (info->attrs[NL80211_ATTR_MAC])
753 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 822 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
754 823
824 rtnl_lock();
825
755 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 826 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
756 if (err) 827 if (err)
757 return err; 828 goto unlock_rtnl;
758 829
759 if (!drv->ops->get_key) { 830 if (!drv->ops->get_key) {
760 err = -EOPNOTSUPP; 831 err = -EOPNOTSUPP;
@@ -782,10 +853,8 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
782 if (mac_addr) 853 if (mac_addr)
783 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); 854 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
784 855
785 rtnl_lock();
786 err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr, 856 err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
787 &cookie, get_key_callback); 857 &cookie, get_key_callback);
788 rtnl_unlock();
789 858
790 if (err) 859 if (err)
791 goto out; 860 goto out;
@@ -803,6 +872,9 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
803 out: 872 out:
804 cfg80211_put_dev(drv); 873 cfg80211_put_dev(drv);
805 dev_put(dev); 874 dev_put(dev);
875 unlock_rtnl:
876 rtnl_unlock();
877
806 return err; 878 return err;
807} 879}
808 880
@@ -831,9 +903,11 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
831 !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]) 903 !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT])
832 return -EINVAL; 904 return -EINVAL;
833 905
906 rtnl_lock();
907
834 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 908 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
835 if (err) 909 if (err)
836 return err; 910 goto unlock_rtnl;
837 911
838 if (info->attrs[NL80211_ATTR_KEY_DEFAULT]) 912 if (info->attrs[NL80211_ATTR_KEY_DEFAULT])
839 func = drv->ops->set_default_key; 913 func = drv->ops->set_default_key;
@@ -845,13 +919,15 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
845 goto out; 919 goto out;
846 } 920 }
847 921
848 rtnl_lock();
849 err = func(&drv->wiphy, dev, key_idx); 922 err = func(&drv->wiphy, dev, key_idx);
850 rtnl_unlock();
851 923
852 out: 924 out:
853 cfg80211_put_dev(drv); 925 cfg80211_put_dev(drv);
854 dev_put(dev); 926 dev_put(dev);
927
928 unlock_rtnl:
929 rtnl_unlock();
930
855 return err; 931 return err;
856} 932}
857 933
@@ -921,22 +997,25 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
921 return -EINVAL; 997 return -EINVAL;
922 } 998 }
923 999
1000 rtnl_lock();
1001
924 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1002 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
925 if (err) 1003 if (err)
926 return err; 1004 goto unlock_rtnl;
927 1005
928 if (!drv->ops->add_key) { 1006 if (!drv->ops->add_key) {
929 err = -EOPNOTSUPP; 1007 err = -EOPNOTSUPP;
930 goto out; 1008 goto out;
931 } 1009 }
932 1010
933 rtnl_lock();
934 err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params); 1011 err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
935 rtnl_unlock();
936 1012
937 out: 1013 out:
938 cfg80211_put_dev(drv); 1014 cfg80211_put_dev(drv);
939 dev_put(dev); 1015 dev_put(dev);
1016 unlock_rtnl:
1017 rtnl_unlock();
1018
940 return err; 1019 return err;
941} 1020}
942 1021
@@ -957,22 +1036,26 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
957 if (info->attrs[NL80211_ATTR_MAC]) 1036 if (info->attrs[NL80211_ATTR_MAC])
958 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1037 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
959 1038
1039 rtnl_lock();
1040
960 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1041 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
961 if (err) 1042 if (err)
962 return err; 1043 goto unlock_rtnl;
963 1044
964 if (!drv->ops->del_key) { 1045 if (!drv->ops->del_key) {
965 err = -EOPNOTSUPP; 1046 err = -EOPNOTSUPP;
966 goto out; 1047 goto out;
967 } 1048 }
968 1049
969 rtnl_lock();
970 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr); 1050 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
971 rtnl_unlock();
972 1051
973 out: 1052 out:
974 cfg80211_put_dev(drv); 1053 cfg80211_put_dev(drv);
975 dev_put(dev); 1054 dev_put(dev);
1055
1056 unlock_rtnl:
1057 rtnl_unlock();
1058
976 return err; 1059 return err;
977} 1060}
978 1061
@@ -986,9 +1069,16 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
986 struct beacon_parameters params; 1069 struct beacon_parameters params;
987 int haveinfo = 0; 1070 int haveinfo = 0;
988 1071
1072 rtnl_lock();
1073
989 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1074 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
990 if (err) 1075 if (err)
991 return err; 1076 goto unlock_rtnl;
1077
1078 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
1079 err = -EOPNOTSUPP;
1080 goto out;
1081 }
992 1082
993 switch (info->genlhdr->cmd) { 1083 switch (info->genlhdr->cmd) {
994 case NL80211_CMD_NEW_BEACON: 1084 case NL80211_CMD_NEW_BEACON:
@@ -1049,13 +1139,14 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1049 goto out; 1139 goto out;
1050 } 1140 }
1051 1141
1052 rtnl_lock();
1053 err = call(&drv->wiphy, dev, &params); 1142 err = call(&drv->wiphy, dev, &params);
1054 rtnl_unlock();
1055 1143
1056 out: 1144 out:
1057 cfg80211_put_dev(drv); 1145 cfg80211_put_dev(drv);
1058 dev_put(dev); 1146 dev_put(dev);
1147 unlock_rtnl:
1148 rtnl_unlock();
1149
1059 return err; 1150 return err;
1060} 1151}
1061 1152
@@ -1065,22 +1156,29 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1065 int err; 1156 int err;
1066 struct net_device *dev; 1157 struct net_device *dev;
1067 1158
1159 rtnl_lock();
1160
1068 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1161 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1069 if (err) 1162 if (err)
1070 return err; 1163 goto unlock_rtnl;
1071 1164
1072 if (!drv->ops->del_beacon) { 1165 if (!drv->ops->del_beacon) {
1073 err = -EOPNOTSUPP; 1166 err = -EOPNOTSUPP;
1074 goto out; 1167 goto out;
1075 } 1168 }
1076 1169
1077 rtnl_lock(); 1170 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
1171 err = -EOPNOTSUPP;
1172 goto out;
1173 }
1078 err = drv->ops->del_beacon(&drv->wiphy, dev); 1174 err = drv->ops->del_beacon(&drv->wiphy, dev);
1079 rtnl_unlock();
1080 1175
1081 out: 1176 out:
1082 cfg80211_put_dev(drv); 1177 cfg80211_put_dev(drv);
1083 dev_put(dev); 1178 dev_put(dev);
1179 unlock_rtnl:
1180 rtnl_unlock();
1181
1084 return err; 1182 return err;
1085} 1183}
1086 1184
@@ -1246,30 +1344,32 @@ static int nl80211_dump_station(struct sk_buff *skb,
1246 return -EINVAL; 1344 return -EINVAL;
1247 } 1345 }
1248 1346
1249 netdev = dev_get_by_index(&init_net, ifidx); 1347 rtnl_lock();
1250 if (!netdev) 1348
1251 return -ENODEV; 1349 netdev = __dev_get_by_index(&init_net, ifidx);
1350 if (!netdev) {
1351 err = -ENODEV;
1352 goto out_rtnl;
1353 }
1252 1354
1253 dev = cfg80211_get_dev_from_ifindex(ifidx); 1355 dev = cfg80211_get_dev_from_ifindex(ifidx);
1254 if (IS_ERR(dev)) { 1356 if (IS_ERR(dev)) {
1255 err = PTR_ERR(dev); 1357 err = PTR_ERR(dev);
1256 goto out_put_netdev; 1358 goto out_rtnl;
1257 } 1359 }
1258 1360
1259 if (!dev->ops->dump_station) { 1361 if (!dev->ops->dump_station) {
1260 err = -ENOSYS; 1362 err = -EOPNOTSUPP;
1261 goto out_err; 1363 goto out_err;
1262 } 1364 }
1263 1365
1264 rtnl_lock();
1265
1266 while (1) { 1366 while (1) {
1267 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, 1367 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
1268 mac_addr, &sinfo); 1368 mac_addr, &sinfo);
1269 if (err == -ENOENT) 1369 if (err == -ENOENT)
1270 break; 1370 break;
1271 if (err) 1371 if (err)
1272 goto out_err_rtnl; 1372 goto out_err;
1273 1373
1274 if (nl80211_send_station(skb, 1374 if (nl80211_send_station(skb,
1275 NETLINK_CB(cb->skb).pid, 1375 NETLINK_CB(cb->skb).pid,
@@ -1285,12 +1385,10 @@ static int nl80211_dump_station(struct sk_buff *skb,
1285 out: 1385 out:
1286 cb->args[1] = sta_idx; 1386 cb->args[1] = sta_idx;
1287 err = skb->len; 1387 err = skb->len;
1288 out_err_rtnl:
1289 rtnl_unlock();
1290 out_err: 1388 out_err:
1291 cfg80211_put_dev(dev); 1389 cfg80211_put_dev(dev);
1292 out_put_netdev: 1390 out_rtnl:
1293 dev_put(netdev); 1391 rtnl_unlock();
1294 1392
1295 return err; 1393 return err;
1296} 1394}
@@ -1311,19 +1409,18 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1311 1409
1312 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1410 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1313 1411
1412 rtnl_lock();
1413
1314 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1414 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1315 if (err) 1415 if (err)
1316 return err; 1416 goto out_rtnl;
1317 1417
1318 if (!drv->ops->get_station) { 1418 if (!drv->ops->get_station) {
1319 err = -EOPNOTSUPP; 1419 err = -EOPNOTSUPP;
1320 goto out; 1420 goto out;
1321 } 1421 }
1322 1422
1323 rtnl_lock();
1324 err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo); 1423 err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
1325 rtnl_unlock();
1326
1327 if (err) 1424 if (err)
1328 goto out; 1425 goto out;
1329 1426
@@ -1340,10 +1437,12 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1340 1437
1341 out_free: 1438 out_free:
1342 nlmsg_free(msg); 1439 nlmsg_free(msg);
1343
1344 out: 1440 out:
1345 cfg80211_put_dev(drv); 1441 cfg80211_put_dev(drv);
1346 dev_put(dev); 1442 dev_put(dev);
1443 out_rtnl:
1444 rtnl_unlock();
1445
1347 return err; 1446 return err;
1348} 1447}
1349 1448
@@ -1411,9 +1510,11 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1411 params.plink_action = 1510 params.plink_action =
1412 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 1511 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1413 1512
1513 rtnl_lock();
1514
1414 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1515 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1415 if (err) 1516 if (err)
1416 return err; 1517 goto out_rtnl;
1417 1518
1418 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan); 1519 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1419 if (err) 1520 if (err)
@@ -1424,15 +1525,16 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1424 goto out; 1525 goto out;
1425 } 1526 }
1426 1527
1427 rtnl_lock();
1428 err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params); 1528 err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
1429 rtnl_unlock();
1430 1529
1431 out: 1530 out:
1432 if (params.vlan) 1531 if (params.vlan)
1433 dev_put(params.vlan); 1532 dev_put(params.vlan);
1434 cfg80211_put_dev(drv); 1533 cfg80211_put_dev(drv);
1435 dev_put(dev); 1534 dev_put(dev);
1535 out_rtnl:
1536 rtnl_unlock();
1537
1436 return err; 1538 return err;
1437} 1539}
1438 1540
@@ -1474,9 +1576,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1474 &params.station_flags)) 1576 &params.station_flags))
1475 return -EINVAL; 1577 return -EINVAL;
1476 1578
1579 rtnl_lock();
1580
1477 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1581 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1478 if (err) 1582 if (err)
1479 return err; 1583 goto out_rtnl;
1480 1584
1481 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan); 1585 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1482 if (err) 1586 if (err)
@@ -1487,15 +1591,21 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1487 goto out; 1591 goto out;
1488 } 1592 }
1489 1593
1490 rtnl_lock(); 1594 if (!netif_running(dev)) {
1595 err = -ENETDOWN;
1596 goto out;
1597 }
1598
1491 err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params); 1599 err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
1492 rtnl_unlock();
1493 1600
1494 out: 1601 out:
1495 if (params.vlan) 1602 if (params.vlan)
1496 dev_put(params.vlan); 1603 dev_put(params.vlan);
1497 cfg80211_put_dev(drv); 1604 cfg80211_put_dev(drv);
1498 dev_put(dev); 1605 dev_put(dev);
1606 out_rtnl:
1607 rtnl_unlock();
1608
1499 return err; 1609 return err;
1500} 1610}
1501 1611
@@ -1509,22 +1619,25 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1509 if (info->attrs[NL80211_ATTR_MAC]) 1619 if (info->attrs[NL80211_ATTR_MAC])
1510 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1620 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1511 1621
1622 rtnl_lock();
1623
1512 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1624 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1513 if (err) 1625 if (err)
1514 return err; 1626 goto out_rtnl;
1515 1627
1516 if (!drv->ops->del_station) { 1628 if (!drv->ops->del_station) {
1517 err = -EOPNOTSUPP; 1629 err = -EOPNOTSUPP;
1518 goto out; 1630 goto out;
1519 } 1631 }
1520 1632
1521 rtnl_lock();
1522 err = drv->ops->del_station(&drv->wiphy, dev, mac_addr); 1633 err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1523 rtnl_unlock();
1524 1634
1525 out: 1635 out:
1526 cfg80211_put_dev(drv); 1636 cfg80211_put_dev(drv);
1527 dev_put(dev); 1637 dev_put(dev);
1638 out_rtnl:
1639 rtnl_unlock();
1640
1528 return err; 1641 return err;
1529} 1642}
1530 1643
@@ -1605,22 +1718,29 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
1605 return -EINVAL; 1718 return -EINVAL;
1606 } 1719 }
1607 1720
1608 netdev = dev_get_by_index(&init_net, ifidx); 1721 rtnl_lock();
1609 if (!netdev) 1722
1610 return -ENODEV; 1723 netdev = __dev_get_by_index(&init_net, ifidx);
1724 if (!netdev) {
1725 err = -ENODEV;
1726 goto out_rtnl;
1727 }
1611 1728
1612 dev = cfg80211_get_dev_from_ifindex(ifidx); 1729 dev = cfg80211_get_dev_from_ifindex(ifidx);
1613 if (IS_ERR(dev)) { 1730 if (IS_ERR(dev)) {
1614 err = PTR_ERR(dev); 1731 err = PTR_ERR(dev);
1615 goto out_put_netdev; 1732 goto out_rtnl;
1616 } 1733 }
1617 1734
1618 if (!dev->ops->dump_mpath) { 1735 if (!dev->ops->dump_mpath) {
1619 err = -ENOSYS; 1736 err = -EOPNOTSUPP;
1620 goto out_err; 1737 goto out_err;
1621 } 1738 }
1622 1739
1623 rtnl_lock(); 1740 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1741 err = -EOPNOTSUPP;
1742 goto out;
1743 }
1624 1744
1625 while (1) { 1745 while (1) {
1626 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx, 1746 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
@@ -1628,7 +1748,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
1628 if (err == -ENOENT) 1748 if (err == -ENOENT)
1629 break; 1749 break;
1630 if (err) 1750 if (err)
1631 goto out_err_rtnl; 1751 goto out_err;
1632 1752
1633 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid, 1753 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
1634 cb->nlh->nlmsg_seq, NLM_F_MULTI, 1754 cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@ -1643,12 +1763,10 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
1643 out: 1763 out:
1644 cb->args[1] = path_idx; 1764 cb->args[1] = path_idx;
1645 err = skb->len; 1765 err = skb->len;
1646 out_err_rtnl:
1647 rtnl_unlock();
1648 out_err: 1766 out_err:
1649 cfg80211_put_dev(dev); 1767 cfg80211_put_dev(dev);
1650 out_put_netdev: 1768 out_rtnl:
1651 dev_put(netdev); 1769 rtnl_unlock();
1652 1770
1653 return err; 1771 return err;
1654} 1772}
@@ -1670,19 +1788,23 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1670 1788
1671 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 1789 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1672 1790
1791 rtnl_lock();
1792
1673 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1793 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1674 if (err) 1794 if (err)
1675 return err; 1795 goto out_rtnl;
1676 1796
1677 if (!drv->ops->get_mpath) { 1797 if (!drv->ops->get_mpath) {
1678 err = -EOPNOTSUPP; 1798 err = -EOPNOTSUPP;
1679 goto out; 1799 goto out;
1680 } 1800 }
1681 1801
1682 rtnl_lock(); 1802 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1683 err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo); 1803 err = -EOPNOTSUPP;
1684 rtnl_unlock(); 1804 goto out;
1805 }
1685 1806
1807 err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
1686 if (err) 1808 if (err)
1687 goto out; 1809 goto out;
1688 1810
@@ -1699,10 +1821,12 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1699 1821
1700 out_free: 1822 out_free:
1701 nlmsg_free(msg); 1823 nlmsg_free(msg);
1702
1703 out: 1824 out:
1704 cfg80211_put_dev(drv); 1825 cfg80211_put_dev(drv);
1705 dev_put(dev); 1826 dev_put(dev);
1827 out_rtnl:
1828 rtnl_unlock();
1829
1706 return err; 1830 return err;
1707} 1831}
1708 1832
@@ -1723,22 +1847,35 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
1723 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 1847 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1724 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); 1848 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1725 1849
1850 rtnl_lock();
1851
1726 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1852 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1727 if (err) 1853 if (err)
1728 return err; 1854 goto out_rtnl;
1729 1855
1730 if (!drv->ops->change_mpath) { 1856 if (!drv->ops->change_mpath) {
1731 err = -EOPNOTSUPP; 1857 err = -EOPNOTSUPP;
1732 goto out; 1858 goto out;
1733 } 1859 }
1734 1860
1735 rtnl_lock(); 1861 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1862 err = -EOPNOTSUPP;
1863 goto out;
1864 }
1865
1866 if (!netif_running(dev)) {
1867 err = -ENETDOWN;
1868 goto out;
1869 }
1870
1736 err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop); 1871 err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
1737 rtnl_unlock();
1738 1872
1739 out: 1873 out:
1740 cfg80211_put_dev(drv); 1874 cfg80211_put_dev(drv);
1741 dev_put(dev); 1875 dev_put(dev);
1876 out_rtnl:
1877 rtnl_unlock();
1878
1742 return err; 1879 return err;
1743} 1880}
1744static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) 1881static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
@@ -1758,22 +1895,35 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
1758 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 1895 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1759 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); 1896 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1760 1897
1898 rtnl_lock();
1899
1761 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1900 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1762 if (err) 1901 if (err)
1763 return err; 1902 goto out_rtnl;
1764 1903
1765 if (!drv->ops->add_mpath) { 1904 if (!drv->ops->add_mpath) {
1766 err = -EOPNOTSUPP; 1905 err = -EOPNOTSUPP;
1767 goto out; 1906 goto out;
1768 } 1907 }
1769 1908
1770 rtnl_lock(); 1909 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1910 err = -EOPNOTSUPP;
1911 goto out;
1912 }
1913
1914 if (!netif_running(dev)) {
1915 err = -ENETDOWN;
1916 goto out;
1917 }
1918
1771 err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop); 1919 err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
1772 rtnl_unlock();
1773 1920
1774 out: 1921 out:
1775 cfg80211_put_dev(drv); 1922 cfg80211_put_dev(drv);
1776 dev_put(dev); 1923 dev_put(dev);
1924 out_rtnl:
1925 rtnl_unlock();
1926
1777 return err; 1927 return err;
1778} 1928}
1779 1929
@@ -1787,22 +1937,25 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1787 if (info->attrs[NL80211_ATTR_MAC]) 1937 if (info->attrs[NL80211_ATTR_MAC])
1788 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 1938 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1789 1939
1940 rtnl_lock();
1941
1790 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1942 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1791 if (err) 1943 if (err)
1792 return err; 1944 goto out_rtnl;
1793 1945
1794 if (!drv->ops->del_mpath) { 1946 if (!drv->ops->del_mpath) {
1795 err = -EOPNOTSUPP; 1947 err = -EOPNOTSUPP;
1796 goto out; 1948 goto out;
1797 } 1949 }
1798 1950
1799 rtnl_lock();
1800 err = drv->ops->del_mpath(&drv->wiphy, dev, dst); 1951 err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
1801 rtnl_unlock();
1802 1952
1803 out: 1953 out:
1804 cfg80211_put_dev(drv); 1954 cfg80211_put_dev(drv);
1805 dev_put(dev); 1955 dev_put(dev);
1956 out_rtnl:
1957 rtnl_unlock();
1958
1806 return err; 1959 return err;
1807} 1960}
1808 1961
@@ -1835,22 +1988,30 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1835 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 1988 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
1836 } 1989 }
1837 1990
1991 rtnl_lock();
1992
1838 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1993 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1839 if (err) 1994 if (err)
1840 return err; 1995 goto out_rtnl;
1841 1996
1842 if (!drv->ops->change_bss) { 1997 if (!drv->ops->change_bss) {
1843 err = -EOPNOTSUPP; 1998 err = -EOPNOTSUPP;
1844 goto out; 1999 goto out;
1845 } 2000 }
1846 2001
1847 rtnl_lock(); 2002 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
2003 err = -EOPNOTSUPP;
2004 goto out;
2005 }
2006
1848 err = drv->ops->change_bss(&drv->wiphy, dev, &params); 2007 err = drv->ops->change_bss(&drv->wiphy, dev, &params);
1849 rtnl_unlock();
1850 2008
1851 out: 2009 out:
1852 cfg80211_put_dev(drv); 2010 cfg80211_put_dev(drv);
1853 dev_put(dev); 2011 dev_put(dev);
2012 out_rtnl:
2013 rtnl_unlock();
2014
1854 return err; 2015 return err;
1855} 2016}
1856 2017
@@ -1945,10 +2106,12 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
1945 struct nlattr *pinfoattr; 2106 struct nlattr *pinfoattr;
1946 struct sk_buff *msg; 2107 struct sk_buff *msg;
1947 2108
2109 rtnl_lock();
2110
1948 /* Look up our device */ 2111 /* Look up our device */
1949 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2112 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1950 if (err) 2113 if (err)
1951 return err; 2114 goto out_rtnl;
1952 2115
1953 if (!drv->ops->get_mesh_params) { 2116 if (!drv->ops->get_mesh_params) {
1954 err = -EOPNOTSUPP; 2117 err = -EOPNOTSUPP;
@@ -1956,9 +2119,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
1956 } 2119 }
1957 2120
1958 /* Get the mesh params */ 2121 /* Get the mesh params */
1959 rtnl_lock();
1960 err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params); 2122 err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params);
1961 rtnl_unlock();
1962 if (err) 2123 if (err)
1963 goto out; 2124 goto out;
1964 2125
@@ -2007,13 +2168,16 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2007 err = genlmsg_unicast(msg, info->snd_pid); 2168 err = genlmsg_unicast(msg, info->snd_pid);
2008 goto out; 2169 goto out;
2009 2170
2010nla_put_failure: 2171 nla_put_failure:
2011 genlmsg_cancel(msg, hdr); 2172 genlmsg_cancel(msg, hdr);
2012 err = -EMSGSIZE; 2173 err = -EMSGSIZE;
2013out: 2174 out:
2014 /* Cleanup */ 2175 /* Cleanup */
2015 cfg80211_put_dev(drv); 2176 cfg80211_put_dev(drv);
2016 dev_put(dev); 2177 dev_put(dev);
2178 out_rtnl:
2179 rtnl_unlock();
2180
2017 return err; 2181 return err;
2018} 2182}
2019 2183
@@ -2060,9 +2224,11 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2060 parent_attr, nl80211_meshconf_params_policy)) 2224 parent_attr, nl80211_meshconf_params_policy))
2061 return -EINVAL; 2225 return -EINVAL;
2062 2226
2227 rtnl_lock();
2228
2063 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2229 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2064 if (err) 2230 if (err)
2065 return err; 2231 goto out_rtnl;
2066 2232
2067 if (!drv->ops->set_mesh_params) { 2233 if (!drv->ops->set_mesh_params) {
2068 err = -EOPNOTSUPP; 2234 err = -EOPNOTSUPP;
@@ -2109,14 +2275,15 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2109 nla_get_u16); 2275 nla_get_u16);
2110 2276
2111 /* Apply changes */ 2277 /* Apply changes */
2112 rtnl_lock();
2113 err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask); 2278 err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask);
2114 rtnl_unlock();
2115 2279
2116 out: 2280 out:
2117 /* cleanup */ 2281 /* cleanup */
2118 cfg80211_put_dev(drv); 2282 cfg80211_put_dev(drv);
2119 dev_put(dev); 2283 dev_put(dev);
2284 out_rtnl:
2285 rtnl_unlock();
2286
2120 return err; 2287 return err;
2121} 2288}
2122 2289
@@ -2262,43 +2429,6 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2262 return -EINVAL; 2429 return -EINVAL;
2263} 2430}
2264 2431
2265static int nl80211_set_mgmt_extra_ie(struct sk_buff *skb,
2266 struct genl_info *info)
2267{
2268 struct cfg80211_registered_device *drv;
2269 int err;
2270 struct net_device *dev;
2271 struct mgmt_extra_ie_params params;
2272
2273 memset(&params, 0, sizeof(params));
2274
2275 if (!info->attrs[NL80211_ATTR_MGMT_SUBTYPE])
2276 return -EINVAL;
2277 params.subtype = nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
2278 if (params.subtype > 15)
2279 return -EINVAL; /* FC Subtype field is 4 bits (0..15) */
2280
2281 if (info->attrs[NL80211_ATTR_IE]) {
2282 params.ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2283 params.ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2284 }
2285
2286 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2287 if (err)
2288 return err;
2289
2290 if (drv->ops->set_mgmt_extra_ie) {
2291 rtnl_lock();
2292 err = drv->ops->set_mgmt_extra_ie(&drv->wiphy, dev, &params);
2293 rtnl_unlock();
2294 } else
2295 err = -EOPNOTSUPP;
2296
2297 cfg80211_put_dev(drv);
2298 dev_put(dev);
2299 return err;
2300}
2301
2302static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) 2432static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2303{ 2433{
2304 struct cfg80211_registered_device *drv; 2434 struct cfg80211_registered_device *drv;
@@ -2312,9 +2442,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2312 enum ieee80211_band band; 2442 enum ieee80211_band band;
2313 size_t ie_len; 2443 size_t ie_len;
2314 2444
2445 rtnl_lock();
2446
2315 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2447 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2316 if (err) 2448 if (err)
2317 return err; 2449 goto out_rtnl;
2318 2450
2319 wiphy = &drv->wiphy; 2451 wiphy = &drv->wiphy;
2320 2452
@@ -2323,11 +2455,14 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2323 goto out; 2455 goto out;
2324 } 2456 }
2325 2457
2326 rtnl_lock(); 2458 if (!netif_running(dev)) {
2459 err = -ENETDOWN;
2460 goto out;
2461 }
2327 2462
2328 if (drv->scan_req) { 2463 if (drv->scan_req) {
2329 err = -EBUSY; 2464 err = -EBUSY;
2330 goto out_unlock; 2465 goto out;
2331 } 2466 }
2332 2467
2333 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { 2468 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
@@ -2335,7 +2470,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2335 n_channels++; 2470 n_channels++;
2336 if (!n_channels) { 2471 if (!n_channels) {
2337 err = -EINVAL; 2472 err = -EINVAL;
2338 goto out_unlock; 2473 goto out;
2339 } 2474 }
2340 } else { 2475 } else {
2341 for (band = 0; band < IEEE80211_NUM_BANDS; band++) 2476 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
@@ -2349,7 +2484,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2349 2484
2350 if (n_ssids > wiphy->max_scan_ssids) { 2485 if (n_ssids > wiphy->max_scan_ssids) {
2351 err = -EINVAL; 2486 err = -EINVAL;
2352 goto out_unlock; 2487 goto out;
2353 } 2488 }
2354 2489
2355 if (info->attrs[NL80211_ATTR_IE]) 2490 if (info->attrs[NL80211_ATTR_IE])
@@ -2363,7 +2498,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2363 + ie_len, GFP_KERNEL); 2498 + ie_len, GFP_KERNEL);
2364 if (!request) { 2499 if (!request) {
2365 err = -ENOMEM; 2500 err = -ENOMEM;
2366 goto out_unlock; 2501 goto out;
2367 } 2502 }
2368 2503
2369 request->channels = (void *)((char *)request + sizeof(*request)); 2504 request->channels = (void *)((char *)request + sizeof(*request));
@@ -2434,11 +2569,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2434 drv->scan_req = NULL; 2569 drv->scan_req = NULL;
2435 kfree(request); 2570 kfree(request);
2436 } 2571 }
2437 out_unlock:
2438 rtnl_unlock();
2439 out: 2572 out:
2440 cfg80211_put_dev(drv); 2573 cfg80211_put_dev(drv);
2441 dev_put(dev); 2574 dev_put(dev);
2575 out_rtnl:
2576 rtnl_unlock();
2577
2442 return err; 2578 return err;
2443} 2579}
2444 2580
@@ -2558,6 +2694,288 @@ static int nl80211_dump_scan(struct sk_buff *skb,
2558 return err; 2694 return err;
2559} 2695}
2560 2696
2697static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type)
2698{
2699 return auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM ||
2700 auth_type == NL80211_AUTHTYPE_SHARED_KEY ||
2701 auth_type == NL80211_AUTHTYPE_FT ||
2702 auth_type == NL80211_AUTHTYPE_NETWORK_EAP;
2703}
2704
2705static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2706{
2707 struct cfg80211_registered_device *drv;
2708 struct net_device *dev;
2709 struct cfg80211_auth_request req;
2710 struct wiphy *wiphy;
2711 int err;
2712
2713 rtnl_lock();
2714
2715 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2716 if (err)
2717 goto unlock_rtnl;
2718
2719 if (!drv->ops->auth) {
2720 err = -EOPNOTSUPP;
2721 goto out;
2722 }
2723
2724 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
2725 err = -EOPNOTSUPP;
2726 goto out;
2727 }
2728
2729 if (!netif_running(dev)) {
2730 err = -ENETDOWN;
2731 goto out;
2732 }
2733
2734 if (!info->attrs[NL80211_ATTR_MAC]) {
2735 err = -EINVAL;
2736 goto out;
2737 }
2738
2739 wiphy = &drv->wiphy;
2740 memset(&req, 0, sizeof(req));
2741
2742 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2743
2744 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2745 req.chan = ieee80211_get_channel(
2746 wiphy,
2747 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
2748 if (!req.chan) {
2749 err = -EINVAL;
2750 goto out;
2751 }
2752 }
2753
2754 if (info->attrs[NL80211_ATTR_SSID]) {
2755 req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
2756 req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
2757 }
2758
2759 if (info->attrs[NL80211_ATTR_IE]) {
2760 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
2761 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2762 }
2763
2764 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
2765 req.auth_type =
2766 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
2767 if (!nl80211_valid_auth_type(req.auth_type)) {
2768 err = -EINVAL;
2769 goto out;
2770 }
2771 }
2772
2773 err = drv->ops->auth(&drv->wiphy, dev, &req);
2774
2775out:
2776 cfg80211_put_dev(drv);
2777 dev_put(dev);
2778unlock_rtnl:
2779 rtnl_unlock();
2780 return err;
2781}
2782
2783static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2784{
2785 struct cfg80211_registered_device *drv;
2786 struct net_device *dev;
2787 struct cfg80211_assoc_request req;
2788 struct wiphy *wiphy;
2789 int err;
2790
2791 rtnl_lock();
2792
2793 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2794 if (err)
2795 goto unlock_rtnl;
2796
2797 if (!drv->ops->assoc) {
2798 err = -EOPNOTSUPP;
2799 goto out;
2800 }
2801
2802 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
2803 err = -EOPNOTSUPP;
2804 goto out;
2805 }
2806
2807 if (!netif_running(dev)) {
2808 err = -ENETDOWN;
2809 goto out;
2810 }
2811
2812 if (!info->attrs[NL80211_ATTR_MAC] ||
2813 !info->attrs[NL80211_ATTR_SSID]) {
2814 err = -EINVAL;
2815 goto out;
2816 }
2817
2818 wiphy = &drv->wiphy;
2819 memset(&req, 0, sizeof(req));
2820
2821 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2822
2823 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2824 req.chan = ieee80211_get_channel(
2825 wiphy,
2826 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
2827 if (!req.chan) {
2828 err = -EINVAL;
2829 goto out;
2830 }
2831 }
2832
2833 req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
2834 req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
2835
2836 if (info->attrs[NL80211_ATTR_IE]) {
2837 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
2838 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2839 }
2840
2841 err = drv->ops->assoc(&drv->wiphy, dev, &req);
2842
2843out:
2844 cfg80211_put_dev(drv);
2845 dev_put(dev);
2846unlock_rtnl:
2847 rtnl_unlock();
2848 return err;
2849}
2850
2851static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2852{
2853 struct cfg80211_registered_device *drv;
2854 struct net_device *dev;
2855 struct cfg80211_deauth_request req;
2856 struct wiphy *wiphy;
2857 int err;
2858
2859 rtnl_lock();
2860
2861 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2862 if (err)
2863 goto unlock_rtnl;
2864
2865 if (!drv->ops->deauth) {
2866 err = -EOPNOTSUPP;
2867 goto out;
2868 }
2869
2870 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
2871 err = -EOPNOTSUPP;
2872 goto out;
2873 }
2874
2875 if (!netif_running(dev)) {
2876 err = -ENETDOWN;
2877 goto out;
2878 }
2879
2880 if (!info->attrs[NL80211_ATTR_MAC]) {
2881 err = -EINVAL;
2882 goto out;
2883 }
2884
2885 wiphy = &drv->wiphy;
2886 memset(&req, 0, sizeof(req));
2887
2888 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2889
2890 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
2891 req.reason_code =
2892 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2893 if (req.reason_code == 0) {
2894 /* Reason Code 0 is reserved */
2895 err = -EINVAL;
2896 goto out;
2897 }
2898 }
2899
2900 if (info->attrs[NL80211_ATTR_IE]) {
2901 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
2902 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2903 }
2904
2905 err = drv->ops->deauth(&drv->wiphy, dev, &req);
2906
2907out:
2908 cfg80211_put_dev(drv);
2909 dev_put(dev);
2910unlock_rtnl:
2911 rtnl_unlock();
2912 return err;
2913}
2914
2915static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2916{
2917 struct cfg80211_registered_device *drv;
2918 struct net_device *dev;
2919 struct cfg80211_disassoc_request req;
2920 struct wiphy *wiphy;
2921 int err;
2922
2923 rtnl_lock();
2924
2925 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2926 if (err)
2927 goto unlock_rtnl;
2928
2929 if (!drv->ops->disassoc) {
2930 err = -EOPNOTSUPP;
2931 goto out;
2932 }
2933
2934 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
2935 err = -EOPNOTSUPP;
2936 goto out;
2937 }
2938
2939 if (!netif_running(dev)) {
2940 err = -ENETDOWN;
2941 goto out;
2942 }
2943
2944 if (!info->attrs[NL80211_ATTR_MAC]) {
2945 err = -EINVAL;
2946 goto out;
2947 }
2948
2949 wiphy = &drv->wiphy;
2950 memset(&req, 0, sizeof(req));
2951
2952 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2953
2954 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
2955 req.reason_code =
2956 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2957 if (req.reason_code == 0) {
2958 /* Reason Code 0 is reserved */
2959 err = -EINVAL;
2960 goto out;
2961 }
2962 }
2963
2964 if (info->attrs[NL80211_ATTR_IE]) {
2965 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
2966 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2967 }
2968
2969 err = drv->ops->disassoc(&drv->wiphy, dev, &req);
2970
2971out:
2972 cfg80211_put_dev(drv);
2973 dev_put(dev);
2974unlock_rtnl:
2975 rtnl_unlock();
2976 return err;
2977}
2978
2561static struct genl_ops nl80211_ops[] = { 2979static struct genl_ops nl80211_ops[] = {
2562 { 2980 {
2563 .cmd = NL80211_CMD_GET_WIPHY, 2981 .cmd = NL80211_CMD_GET_WIPHY,
@@ -2725,12 +3143,6 @@ static struct genl_ops nl80211_ops[] = {
2725 .flags = GENL_ADMIN_PERM, 3143 .flags = GENL_ADMIN_PERM,
2726 }, 3144 },
2727 { 3145 {
2728 .cmd = NL80211_CMD_SET_MGMT_EXTRA_IE,
2729 .doit = nl80211_set_mgmt_extra_ie,
2730 .policy = nl80211_policy,
2731 .flags = GENL_ADMIN_PERM,
2732 },
2733 {
2734 .cmd = NL80211_CMD_TRIGGER_SCAN, 3146 .cmd = NL80211_CMD_TRIGGER_SCAN,
2735 .doit = nl80211_trigger_scan, 3147 .doit = nl80211_trigger_scan,
2736 .policy = nl80211_policy, 3148 .policy = nl80211_policy,
@@ -2741,6 +3153,33 @@ static struct genl_ops nl80211_ops[] = {
2741 .policy = nl80211_policy, 3153 .policy = nl80211_policy,
2742 .dumpit = nl80211_dump_scan, 3154 .dumpit = nl80211_dump_scan,
2743 }, 3155 },
3156 {
3157 .cmd = NL80211_CMD_AUTHENTICATE,
3158 .doit = nl80211_authenticate,
3159 .policy = nl80211_policy,
3160 .flags = GENL_ADMIN_PERM,
3161 },
3162 {
3163 .cmd = NL80211_CMD_ASSOCIATE,
3164 .doit = nl80211_associate,
3165 .policy = nl80211_policy,
3166 .flags = GENL_ADMIN_PERM,
3167 },
3168 {
3169 .cmd = NL80211_CMD_DEAUTHENTICATE,
3170 .doit = nl80211_deauthenticate,
3171 .policy = nl80211_policy,
3172 .flags = GENL_ADMIN_PERM,
3173 },
3174 {
3175 .cmd = NL80211_CMD_DISASSOCIATE,
3176 .doit = nl80211_disassociate,
3177 .policy = nl80211_policy,
3178 .flags = GENL_ADMIN_PERM,
3179 },
3180};
3181static struct genl_multicast_group nl80211_mlme_mcgrp = {
3182 .name = "mlme",
2744}; 3183};
2745 3184
2746/* multicast groups */ 3185/* multicast groups */
@@ -2887,6 +3326,71 @@ nla_put_failure:
2887 nlmsg_free(msg); 3326 nlmsg_free(msg);
2888} 3327}
2889 3328
3329static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
3330 struct net_device *netdev,
3331 const u8 *buf, size_t len,
3332 enum nl80211_commands cmd)
3333{
3334 struct sk_buff *msg;
3335 void *hdr;
3336
3337 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3338 if (!msg)
3339 return;
3340
3341 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
3342 if (!hdr) {
3343 nlmsg_free(msg);
3344 return;
3345 }
3346
3347 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3348 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3349 NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
3350
3351 if (genlmsg_end(msg, hdr) < 0) {
3352 nlmsg_free(msg);
3353 return;
3354 }
3355
3356 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
3357 return;
3358
3359 nla_put_failure:
3360 genlmsg_cancel(msg, hdr);
3361 nlmsg_free(msg);
3362}
3363
3364void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
3365 struct net_device *netdev, const u8 *buf, size_t len)
3366{
3367 nl80211_send_mlme_event(rdev, netdev, buf, len,
3368 NL80211_CMD_AUTHENTICATE);
3369}
3370
3371void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
3372 struct net_device *netdev, const u8 *buf,
3373 size_t len)
3374{
3375 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
3376}
3377
3378void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
3379 struct net_device *netdev, const u8 *buf,
3380 size_t len)
3381{
3382 nl80211_send_mlme_event(rdev, netdev, buf, len,
3383 NL80211_CMD_DEAUTHENTICATE);
3384}
3385
3386void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
3387 struct net_device *netdev, const u8 *buf,
3388 size_t len)
3389{
3390 nl80211_send_mlme_event(rdev, netdev, buf, len,
3391 NL80211_CMD_DISASSOCIATE);
3392}
3393
2890/* initialisation/exit functions */ 3394/* initialisation/exit functions */
2891 3395
2892int nl80211_init(void) 3396int nl80211_init(void)
@@ -2915,6 +3419,10 @@ int nl80211_init(void)
2915 if (err) 3419 if (err)
2916 goto err_out; 3420 goto err_out;
2917 3421
3422 err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp);
3423 if (err)
3424 goto err_out;
3425
2918 return 0; 3426 return 0;
2919 err_out: 3427 err_out:
2920 genl_unregister_family(&nl80211_fam); 3428 genl_unregister_family(&nl80211_fam);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index e65a3c38c52f..b77af4ab80be 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -3,7 +3,6 @@
3 3
4#include "core.h" 4#include "core.h"
5 5
6#ifdef CONFIG_NL80211
7extern int nl80211_init(void); 6extern int nl80211_init(void);
8extern void nl80211_exit(void); 7extern void nl80211_exit(void);
9extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); 8extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
@@ -12,30 +11,17 @@ extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
12extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 11extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
13 struct net_device *netdev); 12 struct net_device *netdev);
14extern void nl80211_send_reg_change_event(struct regulatory_request *request); 13extern void nl80211_send_reg_change_event(struct regulatory_request *request);
15#else 14extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
16static inline int nl80211_init(void) 15 struct net_device *netdev,
17{ 16 const u8 *buf, size_t len);
18 return 0; 17extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
19} 18 struct net_device *netdev,
20static inline void nl80211_exit(void) 19 const u8 *buf, size_t len);
21{ 20extern void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
22} 21 struct net_device *netdev,
23static inline void nl80211_notify_dev_rename( 22 const u8 *buf, size_t len);
24 struct cfg80211_registered_device *rdev) 23extern void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
25{ 24 struct net_device *netdev,
26} 25 const u8 *buf, size_t len);
27static inline void
28nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev)
30{}
31static inline void nl80211_send_scan_aborted(
32 struct cfg80211_registered_device *rdev,
33 struct net_device *netdev)
34{}
35static inline void
36nl80211_send_reg_change_event(struct regulatory_request *request)
37{
38}
39#endif /* CONFIG_NL80211 */
40 26
41#endif /* __NET_WIRELESS_NL80211_H */ 27#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index eb8b8ed16155..6327e1617acb 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -122,9 +122,14 @@ static const struct ieee80211_regdomain *cfg80211_world_regdom =
122 122
123#ifdef CONFIG_WIRELESS_OLD_REGULATORY 123#ifdef CONFIG_WIRELESS_OLD_REGULATORY
124static char *ieee80211_regdom = "US"; 124static char *ieee80211_regdom = "US";
125#else
126static char *ieee80211_regdom = "00";
127#endif
128
125module_param(ieee80211_regdom, charp, 0444); 129module_param(ieee80211_regdom, charp, 0444);
126MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 130MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
127 131
132#ifdef CONFIG_WIRELESS_OLD_REGULATORY
128/* 133/*
129 * We assume 40 MHz bandwidth for the old regulatory work. 134 * We assume 40 MHz bandwidth for the old regulatory work.
130 * We make emphasis we are using the exact same frequencies 135 * We make emphasis we are using the exact same frequencies
@@ -1415,16 +1420,6 @@ new_request:
1415 return r; 1420 return r;
1416 } 1421 }
1417 1422
1418 /*
1419 * Note: When CONFIG_WIRELESS_OLD_REGULATORY is enabled
1420 * AND if CRDA is NOT present nothing will happen, if someone
1421 * wants to bother with 11d with OLD_REG you can add a timer.
1422 * If after x amount of time nothing happens you can call:
1423 *
1424 * return set_regdom(country_ie_regdomain);
1425 *
1426 * to intersect with the static rd
1427 */
1428 return call_crda(last_request->alpha2); 1423 return call_crda(last_request->alpha2);
1429} 1424}
1430 1425
@@ -1601,6 +1596,10 @@ static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1601 1596
1602 assert_cfg80211_lock(); 1597 assert_cfg80211_lock();
1603 1598
1599 if (unlikely(last_request->initiator !=
1600 NL80211_REGDOM_SET_BY_COUNTRY_IE))
1601 return false;
1602
1604 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 1603 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1605 1604
1606 if (!request_wiphy) 1605 if (!request_wiphy)
@@ -1663,7 +1662,9 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1663 * we optimize an early check to exit out early if we don't have to 1662 * we optimize an early check to exit out early if we don't have to
1664 * do anything 1663 * do anything
1665 */ 1664 */
1666 if (likely(wiphy_idx_valid(last_request->wiphy_idx))) { 1665 if (likely(last_request->initiator ==
1666 NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1667 wiphy_idx_valid(last_request->wiphy_idx))) {
1667 struct cfg80211_registered_device *drv_last_ie; 1668 struct cfg80211_registered_device *drv_last_ie;
1668 1669
1669 drv_last_ie = 1670 drv_last_ie =
@@ -2022,28 +2023,21 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2022 */ 2023 */
2023 2024
2024 BUG_ON(!country_ie_regdomain); 2025 BUG_ON(!country_ie_regdomain);
2026 BUG_ON(rd == country_ie_regdomain);
2025 2027
2026 if (rd != country_ie_regdomain) { 2028 /*
2027 /* 2029 * Intersect what CRDA returned and our what we
2028 * Intersect what CRDA returned and our what we 2030 * had built from the Country IE received
2029 * had built from the Country IE received 2031 */
2030 */
2031 2032
2032 intersected_rd = regdom_intersect(rd, country_ie_regdomain); 2033 intersected_rd = regdom_intersect(rd, country_ie_regdomain);
2033 2034
2034 reg_country_ie_process_debug(rd, country_ie_regdomain, 2035 reg_country_ie_process_debug(rd,
2035 intersected_rd); 2036 country_ie_regdomain,
2037 intersected_rd);
2036 2038
2037 kfree(country_ie_regdomain); 2039 kfree(country_ie_regdomain);
2038 country_ie_regdomain = NULL; 2040 country_ie_regdomain = NULL;
2039 } else {
2040 /*
2041 * This would happen when CRDA was not present and
2042 * OLD_REGULATORY was enabled. We intersect our Country
2043 * IE rd and what was set on cfg80211 originally
2044 */
2045 intersected_rd = regdom_intersect(rd, cfg80211_regdomain);
2046 }
2047 2041
2048 if (!intersected_rd) 2042 if (!intersected_rd)
2049 return -EINVAL; 2043 return -EINVAL;
@@ -2135,15 +2129,18 @@ int regulatory_init(void)
2135 /* 2129 /*
2136 * The old code still requests for a new regdomain and if 2130 * The old code still requests for a new regdomain and if
2137 * you have CRDA you get it updated, otherwise you get 2131 * you have CRDA you get it updated, otherwise you get
2138 * stuck with the static values. We ignore "EU" code as 2132 * stuck with the static values. Since "EU" is not a valid
2139 * that is not a valid ISO / IEC 3166 alpha2 2133 * ISO / IEC 3166 alpha2 code we can't expect userpace to
2134 * give us a regulatory domain for it. We need last_request
2135 * iniitalized though so lets just send a request which we
2136 * know will be ignored... this crap will be removed once
2137 * OLD_REG dies.
2140 */ 2138 */
2141 if (ieee80211_regdom[0] != 'E' || ieee80211_regdom[1] != 'U') 2139 err = regulatory_hint_core(ieee80211_regdom);
2142 err = regulatory_hint_core(ieee80211_regdom);
2143#else 2140#else
2144 cfg80211_regdomain = cfg80211_world_regdom; 2141 cfg80211_regdomain = cfg80211_world_regdom;
2145 2142
2146 err = regulatory_hint_core("00"); 2143 err = regulatory_hint_core(ieee80211_regdom);
2147#endif 2144#endif
2148 if (err) { 2145 if (err) {
2149 if (err == -ENOMEM) 2146 if (err == -ENOMEM)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 280dbcd02c15..2a00e362f5fe 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -80,7 +80,8 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
80 bool expired = false; 80 bool expired = false;
81 81
82 list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) { 82 list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
83 if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE)) 83 if (bss->hold ||
84 !time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
84 continue; 85 continue;
85 list_del(&bss->list); 86 list_del(&bss->list);
86 rb_erase(&bss->rbn, &dev->bss_tree); 87 rb_erase(&bss->rbn, &dev->bss_tree);
@@ -471,6 +472,30 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
471} 472}
472EXPORT_SYMBOL(cfg80211_unlink_bss); 473EXPORT_SYMBOL(cfg80211_unlink_bss);
473 474
475void cfg80211_hold_bss(struct cfg80211_bss *pub)
476{
477 struct cfg80211_internal_bss *bss;
478
479 if (!pub)
480 return;
481
482 bss = container_of(pub, struct cfg80211_internal_bss, pub);
483 bss->hold = true;
484}
485EXPORT_SYMBOL(cfg80211_hold_bss);
486
487void cfg80211_unhold_bss(struct cfg80211_bss *pub)
488{
489 struct cfg80211_internal_bss *bss;
490
491 if (!pub)
492 return;
493
494 bss = container_of(pub, struct cfg80211_internal_bss, pub);
495 bss->hold = false;
496}
497EXPORT_SYMBOL(cfg80211_unhold_bss);
498
474#ifdef CONFIG_WIRELESS_EXT 499#ifdef CONFIG_WIRELESS_EXT
475int cfg80211_wext_siwscan(struct net_device *dev, 500int cfg80211_wext_siwscan(struct net_device *dev,
476 struct iw_request_info *info, 501 struct iw_request_info *info,
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index b84a9b4fe96a..0fd1db6e95bb 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -66,6 +66,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
66 struct cfg80211_registered_device *rdev; 66 struct cfg80211_registered_device *rdev;
67 struct vif_params vifparams; 67 struct vif_params vifparams;
68 enum nl80211_iftype type; 68 enum nl80211_iftype type;
69 int ret;
69 70
70 if (!wdev) 71 if (!wdev)
71 return -EOPNOTSUPP; 72 return -EOPNOTSUPP;
@@ -96,10 +97,16 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
96 return -EINVAL; 97 return -EINVAL;
97 } 98 }
98 99
100 if (type == wdev->iftype)
101 return 0;
102
99 memset(&vifparams, 0, sizeof(vifparams)); 103 memset(&vifparams, 0, sizeof(vifparams));
100 104
101 return rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type, 105 ret = rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
102 NULL, &vifparams); 106 NULL, &vifparams);
107 WARN_ON(!ret && wdev->iftype != type);
108
109 return ret;
103} 110}
104EXPORT_SYMBOL(cfg80211_wext_siwmode); 111EXPORT_SYMBOL(cfg80211_wext_siwmode);
105 112