aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-10-01 07:39:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-10-01 07:39:36 -0400
commite4d680c706284ca0413a84bd2a28fda76b360904 (patch)
tree6613396dafb5c7d1f2d946ea8e7f4f57a482bad6 /drivers/net/wireless
parenta248afdc1b5916c2bfd007233112333d85aa28f6 (diff)
parent5160b46f3e53c41c4c6b9e7cdbe0401d3afbfb63 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c65
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c55
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c4
-rw-r--r--drivers/net/wireless/b43legacy/main.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h33
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c46
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c48
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c2416
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h81
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c49
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h5
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c386
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c2
-rw-r--r--drivers/net/wireless/mwifiex/decl.h6
-rw-r--r--drivers/net/wireless/mwifiex/fw.h43
-rw-r--r--drivers/net/wireless/mwifiex/ie.c86
-rw-r--r--drivers/net/wireless/mwifiex/init.c14
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h2
-rw-r--r--drivers/net/wireless/mwifiex/main.c41
-rw-r--r--drivers/net/wireless/mwifiex/main.h36
-rw-r--r--drivers/net/wireless/mwifiex/scan.c5
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c92
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c39
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c12
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c59
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c6
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c12
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c22
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c15
-rw-r--r--drivers/net/wireless/mwifiex/util.c40
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c9
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c79
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h7
-rw-r--r--drivers/net/wireless/ti/wl18xx/debugfs.c2
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c128
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h7
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c21
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h5
-rw-r--r--drivers/net/wireless/ti/wlcore/conf.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/debug.h16
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c32
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c12
-rw-r--r--drivers/net/wireless/ti/wlcore/io.h4
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c366
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c10
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c20
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c10
-rw-r--r--drivers/net/wireless/ti/wlcore/testmode.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c51
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h23
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h13
63 files changed, 3259 insertions, 1366 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index d5b2e0ecc21c..301bf72c53bf 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -182,6 +182,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
182 struct ath9k_hw_capabilities *pCap = &ah->caps; 182 struct ath9k_hw_capabilities *pCap = &ah->caps;
183 struct ath_common *common = ath9k_hw_common(ah); 183 struct ath_common *common = ath9k_hw_common(ah);
184 u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; 184 u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ;
185 bool fatal_int;
185 186
186 if (ath9k_hw_mci_is_enabled(ah)) 187 if (ath9k_hw_mci_is_enabled(ah))
187 async_mask |= AR_INTR_ASYNC_MASK_MCI; 188 async_mask |= AR_INTR_ASYNC_MASK_MCI;
@@ -310,6 +311,22 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
310 311
311 if (sync_cause) { 312 if (sync_cause) {
312 ath9k_debug_sync_cause(common, sync_cause); 313 ath9k_debug_sync_cause(common, sync_cause);
314 fatal_int =
315 (sync_cause &
316 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
317 ? true : false;
318
319 if (fatal_int) {
320 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
321 ath_dbg(common, ANY,
322 "received PCI FATAL interrupt\n");
323 }
324 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
325 ath_dbg(common, ANY,
326 "received PCI PERR interrupt\n");
327 }
328 *masked |= ATH9K_INT_FATAL;
329 }
313 330
314 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { 331 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
315 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); 332 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index 8dbb60b53f1a..44c202ce6c66 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -813,8 +813,8 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable)
813 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); 813 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
814} 814}
815 815
816void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, 816int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
817 bool is_full_sleep) 817 bool is_full_sleep)
818{ 818{
819 struct ath_common *common = ath9k_hw_common(ah); 819 struct ath_common *common = ath9k_hw_common(ah);
820 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 820 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
@@ -824,14 +824,13 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
824 is_full_sleep, is_2g); 824 is_full_sleep, is_2g);
825 825
826 if (!mci->gpm_addr && !mci->sched_addr) { 826 if (!mci->gpm_addr && !mci->sched_addr) {
827 ath_dbg(common, MCI, 827 ath_err(common, "MCI GPM and schedule buffers are not allocated\n");
828 "MCI GPM and schedule buffers are not allocated\n"); 828 return -ENOMEM;
829 return;
830 } 829 }
831 830
832 if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { 831 if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
833 ath_dbg(common, MCI, "BTCOEX control register is dead\n"); 832 ath_err(common, "BTCOEX control register is dead\n");
834 return; 833 return -EINVAL;
835 } 834 }
836 835
837 /* Program MCI DMA related registers */ 836 /* Program MCI DMA related registers */
@@ -913,6 +912,8 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
913 912
914 if (en_int) 913 if (en_int)
915 ar9003_mci_enable_interrupt(ah); 914 ar9003_mci_enable_interrupt(ah);
915
916 return 0;
916} 917}
917 918
918void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) 919void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
@@ -1144,8 +1145,8 @@ void ar9003_mci_init_cal_done(struct ath_hw *ah)
1144 ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); 1145 ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
1145} 1146}
1146 1147
1147void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, 1148int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
1148 u16 len, u32 sched_addr) 1149 u16 len, u32 sched_addr)
1149{ 1150{
1150 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 1151 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1151 1152
@@ -1154,7 +1155,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
1154 mci->gpm_len = len; 1155 mci->gpm_len = len;
1155 mci->sched_addr = sched_addr; 1156 mci->sched_addr = sched_addr;
1156 1157
1157 ar9003_mci_reset(ah, true, true, true); 1158 return ar9003_mci_reset(ah, true, true, true);
1158} 1159}
1159EXPORT_SYMBOL(ar9003_mci_setup); 1160EXPORT_SYMBOL(ar9003_mci_setup);
1160 1161
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
index 30acf2869aa4..2a2d01889613 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
@@ -249,8 +249,8 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
249 u32 *payload, u8 len, bool wait_done, 249 u32 *payload, u8 len, bool wait_done,
250 bool check_bt); 250 bool check_bt);
251u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type); 251u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type);
252void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, 252int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
253 u16 len, u32 sched_addr); 253 u16 len, u32 sched_addr);
254void ar9003_mci_cleanup(struct ath_hw *ah); 254void ar9003_mci_cleanup(struct ath_hw *ah);
255void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, 255void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
256 u32 *rx_msg_intr); 256 u32 *rx_msg_intr);
@@ -272,8 +272,8 @@ void ar9003_mci_check_bt(struct ath_hw *ah);
272bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); 272bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan);
273int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, 273int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
274 struct ath9k_hw_cal_data *caldata); 274 struct ath9k_hw_cal_data *caldata);
275void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, 275int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
276 bool is_full_sleep); 276 bool is_full_sleep);
277void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); 277void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked);
278void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); 278void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah);
279void ar9003_mci_set_power_awake(struct ath_hw *ah); 279void ar9003_mci_set_power_awake(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index fc67844a1430..759f5f5a7154 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1360,7 +1360,7 @@ static void ar9003_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah,
1360 if (enable) { 1360 if (enable) {
1361 REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, 1361 REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL,
1362 (1 << AR_PHY_ANT_SW_RX_PROT_S)); 1362 (1 << AR_PHY_ANT_SW_RX_PROT_S));
1363 if (IS_CHAN_2GHZ(ah->curchan)) 1363 if (ah->curchan && IS_CHAN_2GHZ(ah->curchan))
1364 REG_SET_BIT(ah, AR_PHY_RESTART, 1364 REG_SET_BIT(ah, AR_PHY_RESTART,
1365 AR_PHY_RESTART_ENABLE_DIV_M2FLAG); 1365 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
1366 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, 1366 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 8e27f4fb21fe..dfe6a4707fd2 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -173,6 +173,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
173 173
174#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) 174#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
175 175
176#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
177
176#define ATH_TX_COMPLETE_POLL_INT 1000 178#define ATH_TX_COMPLETE_POLL_INT 1000
177 179
178enum ATH_AGGR_STATUS { 180enum ATH_AGGR_STATUS {
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index acd437384fe4..419e9a3f2fed 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -43,8 +43,8 @@ static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX]
43 { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* STOMP_NONE */ 43 { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* STOMP_NONE */
44}; 44};
45 45
46static const u32 ar9462_wlan_weights[ATH_BTCOEX_STOMP_MAX] 46static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX]
47 [AR9300_NUM_WLAN_WEIGHTS] = { 47 [AR9300_NUM_WLAN_WEIGHTS] = {
48 { 0x01017d01, 0x41414101, 0x41414101, 0x41414141 }, /* STOMP_ALL */ 48 { 0x01017d01, 0x41414101, 0x41414101, 0x41414141 }, /* STOMP_ALL */
49 { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ 49 { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */
50 { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ 50 { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */
@@ -208,14 +208,37 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
208 AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); 208 AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
209} 209}
210 210
211/*
212 * For AR9002, bt_weight/wlan_weight are used.
213 * For AR9003 and above, stomp_type is used.
214 */
211void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, 215void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
212 u32 bt_weight, 216 u32 bt_weight,
213 u32 wlan_weight) 217 u32 wlan_weight,
218 enum ath_stomp_type stomp_type)
214{ 219{
215 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 220 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
216 221
217 btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) | 222 if (AR_SREV_9300_20_OR_LATER(ah)) {
218 SM(wlan_weight, AR_BTCOEX_WL_WGHT); 223 const u32 *weight = ar9003_wlan_weights[stomp_type];
224 int i;
225
226 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
227 if ((stomp_type == ATH_BTCOEX_STOMP_LOW) &&
228 btcoex_hw->mci.stomp_ftp)
229 stomp_type = ATH_BTCOEX_STOMP_LOW_FTP;
230 weight = mci_wlan_weights[stomp_type];
231 }
232
233 for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) {
234 btcoex_hw->bt_weight[i] = AR9300_BT_WGHT;
235 btcoex_hw->wlan_weight[i] = weight[i];
236 }
237 } else {
238 btcoex_hw->bt_coex_weights =
239 SM(bt_weight, AR_BTCOEX_BT_WGHT) |
240 SM(wlan_weight, AR_BTCOEX_WL_WGHT);
241 }
219} 242}
220EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); 243EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
221 244
@@ -282,7 +305,7 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
282 ath9k_hw_btcoex_enable_2wire(ah); 305 ath9k_hw_btcoex_enable_2wire(ah);
283 break; 306 break;
284 case ATH_BTCOEX_CFG_3WIRE: 307 case ATH_BTCOEX_CFG_3WIRE:
285 if (AR_SREV_9462(ah)) { 308 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
286 ath9k_hw_btcoex_enable_mci(ah); 309 ath9k_hw_btcoex_enable_mci(ah);
287 return; 310 return;
288 } 311 }
@@ -304,7 +327,7 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
304 int i; 327 int i;
305 328
306 btcoex_hw->enabled = false; 329 btcoex_hw->enabled = false;
307 if (AR_SREV_9462(ah)) { 330 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
308 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); 331 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
309 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) 332 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++)
310 REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), 333 REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i),
@@ -332,26 +355,6 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
332} 355}
333EXPORT_SYMBOL(ath9k_hw_btcoex_disable); 356EXPORT_SYMBOL(ath9k_hw_btcoex_disable);
334 357
335static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
336 enum ath_stomp_type stomp_type)
337{
338 struct ath_btcoex_hw *btcoex = &ah->btcoex_hw;
339 const u32 *weight = ar9003_wlan_weights[stomp_type];
340 int i;
341
342 if (AR_SREV_9462(ah)) {
343 if ((stomp_type == ATH_BTCOEX_STOMP_LOW) &&
344 btcoex->mci.stomp_ftp)
345 stomp_type = ATH_BTCOEX_STOMP_LOW_FTP;
346 weight = ar9462_wlan_weights[stomp_type];
347 }
348
349 for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) {
350 btcoex->bt_weight[i] = AR9300_BT_WGHT;
351 btcoex->wlan_weight[i] = weight[i];
352 }
353}
354
355/* 358/*
356 * Configures appropriate weight based on stomp type. 359 * Configures appropriate weight based on stomp type.
357 */ 360 */
@@ -359,22 +362,22 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
359 enum ath_stomp_type stomp_type) 362 enum ath_stomp_type stomp_type)
360{ 363{
361 if (AR_SREV_9300_20_OR_LATER(ah)) { 364 if (AR_SREV_9300_20_OR_LATER(ah)) {
362 ar9003_btcoex_bt_stomp(ah, stomp_type); 365 ath9k_hw_btcoex_set_weight(ah, 0, 0, stomp_type);
363 return; 366 return;
364 } 367 }
365 368
366 switch (stomp_type) { 369 switch (stomp_type) {
367 case ATH_BTCOEX_STOMP_ALL: 370 case ATH_BTCOEX_STOMP_ALL:
368 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 371 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
369 AR_STOMP_ALL_WLAN_WGHT); 372 AR_STOMP_ALL_WLAN_WGHT, 0);
370 break; 373 break;
371 case ATH_BTCOEX_STOMP_LOW: 374 case ATH_BTCOEX_STOMP_LOW:
372 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 375 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
373 AR_STOMP_LOW_WLAN_WGHT); 376 AR_STOMP_LOW_WLAN_WGHT, 0);
374 break; 377 break;
375 case ATH_BTCOEX_STOMP_NONE: 378 case ATH_BTCOEX_STOMP_NONE:
376 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 379 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
377 AR_STOMP_NONE_WLAN_WGHT); 380 AR_STOMP_NONE_WLAN_WGHT, 0);
378 break; 381 break;
379 default: 382 default:
380 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Invalid Stomptype\n"); 383 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Invalid Stomptype\n");
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 20092f98658f..385197ad79b0 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -107,7 +107,8 @@ void ath9k_hw_btcoex_init_mci(struct ath_hw *ah);
107void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum); 107void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
108void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, 108void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
109 u32 bt_weight, 109 u32 bt_weight,
110 u32 wlan_weight); 110 u32 wlan_weight,
111 enum ath_stomp_type stomp_type);
111void ath9k_hw_btcoex_disable(struct ath_hw *ah); 112void ath9k_hw_btcoex_disable(struct ath_hw *ah);
112void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, 113void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
113 enum ath_stomp_type stomp_type); 114 enum ath_stomp_type stomp_type);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index e1041a6b457b..6727b566d294 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -222,6 +222,57 @@ static const struct file_operations fops_disable_ani = {
222 .llseek = default_llseek, 222 .llseek = default_llseek,
223}; 223};
224 224
225static ssize_t read_file_ant_diversity(struct file *file, char __user *user_buf,
226 size_t count, loff_t *ppos)
227{
228 struct ath_softc *sc = file->private_data;
229 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
230 char buf[32];
231 unsigned int len;
232
233 len = sprintf(buf, "%d\n", common->antenna_diversity);
234 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
235}
236
237static ssize_t write_file_ant_diversity(struct file *file,
238 const char __user *user_buf,
239 size_t count, loff_t *ppos)
240{
241 struct ath_softc *sc = file->private_data;
242 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
243 unsigned long antenna_diversity;
244 char buf[32];
245 ssize_t len;
246
247 len = min(count, sizeof(buf) - 1);
248 if (copy_from_user(buf, user_buf, len))
249 return -EFAULT;
250
251 if (!AR_SREV_9565(sc->sc_ah))
252 goto exit;
253
254 buf[len] = '\0';
255 if (strict_strtoul(buf, 0, &antenna_diversity))
256 return -EINVAL;
257
258 common->antenna_diversity = !!antenna_diversity;
259 ath9k_ps_wakeup(sc);
260 ath_ant_comb_update(sc);
261 ath_dbg(common, CONFIG, "Antenna diversity: %d\n",
262 common->antenna_diversity);
263 ath9k_ps_restore(sc);
264exit:
265 return count;
266}
267
268static const struct file_operations fops_ant_diversity = {
269 .read = read_file_ant_diversity,
270 .write = write_file_ant_diversity,
271 .open = simple_open,
272 .owner = THIS_MODULE,
273 .llseek = default_llseek,
274};
275
225static ssize_t read_file_dma(struct file *file, char __user *user_buf, 276static ssize_t read_file_dma(struct file *file, char __user *user_buf,
226 size_t count, loff_t *ppos) 277 size_t count, loff_t *ppos)
227{ 278{
@@ -1601,12 +1652,12 @@ int ath9k_init_debug(struct ath_hw *ah)
1601 debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, 1652 debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
1602 &fops_samps); 1653 &fops_samps);
1603#endif 1654#endif
1604
1605 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, 1655 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
1606 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); 1656 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
1607
1608 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, 1657 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
1609 sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); 1658 sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
1659 debugfs_create_file("diversity", S_IRUSR | S_IWUSR,
1660 sc->debug.debugfs_phy, sc, &fops_ant_diversity);
1610 1661
1611 return 0; 1662 return 0;
1612} 1663}
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index bf7d29ec1a87..d9ed141a053e 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -395,7 +395,10 @@ void ath9k_start_btcoex(struct ath_softc *sc)
395 !ah->btcoex_hw.enabled) { 395 !ah->btcoex_hw.enabled) {
396 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) 396 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
397 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 397 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
398 AR_STOMP_LOW_WLAN_WGHT); 398 AR_STOMP_LOW_WLAN_WGHT, 0);
399 else
400 ath9k_hw_btcoex_set_weight(ah, 0, 0,
401 ATH_BTCOEX_STOMP_NONE);
399 ath9k_hw_btcoex_enable(ah); 402 ath9k_hw_btcoex_enable(ah);
400 403
401 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) 404 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
@@ -412,7 +415,7 @@ void ath9k_stop_btcoex(struct ath_softc *sc)
412 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) 415 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
413 ath9k_btcoex_timer_pause(sc); 416 ath9k_btcoex_timer_pause(sc);
414 ath9k_hw_btcoex_disable(ah); 417 ath9k_hw_btcoex_disable(ah);
415 if (AR_SREV_9462(ah)) 418 if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
416 ath_mci_flush_profile(&sc->btcoex.mci); 419 ath_mci_flush_profile(&sc->btcoex.mci);
417 } 420 }
418} 421}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 8fd64a6f0eb9..0eacfc13c915 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -161,7 +161,7 @@ void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv)
161 161
162 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) { 162 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) {
163 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 163 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
164 AR_STOMP_LOW_WLAN_WGHT); 164 AR_STOMP_LOW_WLAN_WGHT, 0);
165 ath9k_hw_btcoex_enable(ah); 165 ath9k_hw_btcoex_enable(ah);
166 ath_htc_resume_btcoex_work(priv); 166 ath_htc_resume_btcoex_work(priv);
167 } 167 }
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 8f51e9e358fd..ec2d7c807567 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -392,6 +392,7 @@ int ath_mci_setup(struct ath_softc *sc)
392 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 392 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
393 struct ath_mci_coex *mci = &sc->mci_coex; 393 struct ath_mci_coex *mci = &sc->mci_coex;
394 struct ath_mci_buf *buf = &mci->sched_buf; 394 struct ath_mci_buf *buf = &mci->sched_buf;
395 int ret;
395 396
396 buf->bf_addr = dma_alloc_coherent(sc->dev, 397 buf->bf_addr = dma_alloc_coherent(sc->dev,
397 ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, 398 ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
@@ -411,9 +412,13 @@ int ath_mci_setup(struct ath_softc *sc)
411 mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len; 412 mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len;
412 mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len; 413 mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len;
413 414
414 ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr, 415 ret = ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr,
415 mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), 416 mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4),
416 mci->sched_buf.bf_paddr); 417 mci->sched_buf.bf_paddr);
418 if (ret) {
419 ath_err(common, "Failed to initialize MCI\n");
420 return ret;
421 }
417 422
418 INIT_WORK(&sc->mci_work, ath9k_mci_work); 423 INIT_WORK(&sc->mci_work, ath9k_mci_work);
419 ath_dbg(common, MCI, "MCI Initialized\n"); 424 ath_dbg(common, MCI, "MCI Initialized\n");
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 4480c0cc655f..83d16e7ed272 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -424,8 +424,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
424 rfilt |= ATH9K_RX_FILTER_COMP_BAR; 424 rfilt |= ATH9K_RX_FILTER_COMP_BAR;
425 425
426 if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { 426 if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
427 /* The following may also be needed for other older chips */ 427 /* This is needed for older chips */
428 if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) 428 if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160)
429 rfilt |= ATH9K_RX_FILTER_PROM; 429 rfilt |= ATH9K_RX_FILTER_PROM;
430 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; 430 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
431 } 431 }
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 44a08eb53c62..a483d518758c 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -497,7 +497,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
497 497
498 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); 498 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
499 499
500 if (AR_SREV_9462(ah)) { 500 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
501 /* 501 /*
502 * this is needed to prevent the chip waking up 502 * this is needed to prevent the chip waking up
503 * the host within 3-4 seconds with certain 503 * the host within 3-4 seconds with certain
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index b088fa0eb022..36618e3a5e60 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1820,10 +1820,14 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
1820{ 1820{
1821 struct ath_hw *ah = sc->sc_ah; 1821 struct ath_hw *ah = sc->sc_ah;
1822 struct ath9k_channel *curchan = ah->curchan; 1822 struct ath9k_channel *curchan = ah->curchan;
1823
1823 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && 1824 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) &&
1824 (curchan->channelFlags & CHANNEL_5GHZ) && 1825 (curchan->channelFlags & CHANNEL_5GHZ) &&
1825 (chainmask == 0x7) && (rate < 0x90)) 1826 (chainmask == 0x7) && (rate < 0x90))
1826 return 0x3; 1827 return 0x3;
1828 else if (AR_SREV_9462(ah) && ath9k_hw_btcoex_is_enabled(ah) &&
1829 IS_CCK_RATE(rate))
1830 return 0x2;
1827 else 1831 else
1828 return chainmask; 1832 return chainmask;
1829} 1833}
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 291cdf654088..18e208e3eca1 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3895,6 +3895,8 @@ static void b43legacy_remove(struct ssb_device *dev)
3895 cancel_work_sync(&wl->firmware_load); 3895 cancel_work_sync(&wl->firmware_load);
3896 3896
3897 B43legacy_WARN_ON(!wl); 3897 B43legacy_WARN_ON(!wl);
3898 if (!wldev->fw.ucode)
3899 return; /* NULL if fw never loaded */
3898 if (wl->current_dev == wldev) 3900 if (wl->current_dev == wldev)
3899 ieee80211_unregister_hw(wl->hw); 3901 ieee80211_unregister_hw(wl->hw);
3900 3902
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 55e489d2147d..17e7ae73e008 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -27,6 +27,7 @@
27 * IO codes that are interpreted by dongle firmware 27 * IO codes that are interpreted by dongle firmware
28 ******************************************************************************/ 28 ******************************************************************************/
29#define BRCMF_C_UP 2 29#define BRCMF_C_UP 2
30#define BRCMF_C_DOWN 3
30#define BRCMF_C_SET_PROMISC 10 31#define BRCMF_C_SET_PROMISC 10
31#define BRCMF_C_GET_RATE 12 32#define BRCMF_C_GET_RATE 12
32#define BRCMF_C_GET_INFRA 19 33#define BRCMF_C_GET_INFRA 19
@@ -50,7 +51,10 @@
50#define BRCMF_C_REASSOC 53 51#define BRCMF_C_REASSOC 53
51#define BRCMF_C_SET_ROAM_TRIGGER 55 52#define BRCMF_C_SET_ROAM_TRIGGER 55
52#define BRCMF_C_SET_ROAM_DELTA 57 53#define BRCMF_C_SET_ROAM_DELTA 57
54#define BRCMF_C_GET_BCNPRD 75
55#define BRCMF_C_SET_BCNPRD 76
53#define BRCMF_C_GET_DTIMPRD 77 56#define BRCMF_C_GET_DTIMPRD 77
57#define BRCMF_C_SET_DTIMPRD 78
54#define BRCMF_C_SET_COUNTRY 84 58#define BRCMF_C_SET_COUNTRY 84
55#define BRCMF_C_GET_PM 85 59#define BRCMF_C_GET_PM 85
56#define BRCMF_C_SET_PM 86 60#define BRCMF_C_SET_PM 86
@@ -134,6 +138,9 @@
134 138
135#define WLC_BSS_RSSI_ON_CHANNEL 0x0002 139#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
136 140
141#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
142#define BRCMF_STA_ASSOC 0x10 /* Associated */
143
137struct brcmf_event_msg { 144struct brcmf_event_msg {
138 __be16 version; 145 __be16 version;
139 __be16 flags; 146 __be16 flags;
@@ -566,6 +573,28 @@ struct brcmf_channel_info_le {
566 __le32 scan_channel; 573 __le32 scan_channel;
567}; 574};
568 575
576struct brcmf_sta_info_le {
577 __le16 ver; /* version of this struct */
578 __le16 len; /* length in bytes of this structure */
579 __le16 cap; /* sta's advertised capabilities */
580 __le32 flags; /* flags defined below */
581 __le32 idle; /* time since data pkt rx'd from sta */
582 u8 ea[ETH_ALEN]; /* Station address */
583 __le32 count; /* # rates in this set */
584 u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
585 /* w/hi bit set if basic */
586 __le32 in; /* seconds elapsed since associated */
587 __le32 listen_interval_inms; /* Min Listen interval in ms for STA */
588 __le32 tx_pkts; /* # of packets transmitted */
589 __le32 tx_failures; /* # of packets failed */
590 __le32 rx_ucast_pkts; /* # of unicast packets received */
591 __le32 rx_mcast_pkts; /* # of multicast packets received */
592 __le32 tx_rate; /* Rate of last successful tx frame */
593 __le32 rx_rate; /* Rate of last successful rx frame */
594 __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
595 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
596};
597
569/* Bus independent dongle command */ 598/* Bus independent dongle command */
570struct brcmf_dcmd { 599struct brcmf_dcmd {
571 uint cmd; /* common dongle cmd definition */ 600 uint cmd; /* common dongle cmd definition */
@@ -585,7 +614,7 @@ struct brcmf_pub {
585 /* Linkage ponters */ 614 /* Linkage ponters */
586 struct brcmf_bus *bus_if; 615 struct brcmf_bus *bus_if;
587 struct brcmf_proto *prot; 616 struct brcmf_proto *prot;
588 struct brcmf_cfg80211_dev *config; 617 struct brcmf_cfg80211_info *config;
589 struct device *dev; /* fullmac dongle device pointer */ 618 struct device *dev; /* fullmac dongle device pointer */
590 619
591 /* Internal brcmf items */ 620 /* Internal brcmf items */
@@ -658,6 +687,8 @@ extern const struct bcmevent_name bcmevent_names[];
658 687
659extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, 688extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
660 char *buf, uint len); 689 char *buf, uint len);
690extern uint brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen,
691 char *buf, uint buflen, s32 bssidx);
661 692
662extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); 693extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
663 694
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index aa4f719a51a9..15c5db5752d1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -88,6 +88,52 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
88 return len; 88 return len;
89} 89}
90 90
91uint
92brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen,
93 char *buf, uint buflen, s32 bssidx)
94{
95 const s8 *prefix = "bsscfg:";
96 s8 *p;
97 u32 prefixlen;
98 u32 namelen;
99 u32 iolen;
100 __le32 bssidx_le;
101
102 if (bssidx == 0)
103 return brcmf_c_mkiovar(name, data, datalen, buf, buflen);
104
105 prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */
106 namelen = (u32) strlen(name) + 1; /* lengh of iovar name + null */
107 iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen;
108
109 if (buflen < 0 || iolen > (u32)buflen) {
110 brcmf_dbg(ERROR, "buffer is too short\n");
111 return 0;
112 }
113
114 p = buf;
115
116 /* copy prefix, no null */
117 memcpy(p, prefix, prefixlen);
118 p += prefixlen;
119
120 /* copy iovar name including null */
121 memcpy(p, name, namelen);
122 p += namelen;
123
124 /* bss config index as first data */
125 bssidx_le = cpu_to_le32(bssidx);
126 memcpy(p, &bssidx_le, sizeof(bssidx_le));
127 p += sizeof(bssidx_le);
128
129 /* parameter buffer follows */
130 if (datalen)
131 memcpy(p, data, datalen);
132
133 return iolen;
134
135}
136
91bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, 137bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
92 struct sk_buff *pkt, int prec) 138 struct sk_buff *pkt, int prec)
93{ 139{
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 5fe6ec7f838e..a2b4b1e71017 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -160,40 +160,17 @@ static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
160 return brcmf_usb_get_buspub(dev)->devinfo; 160 return brcmf_usb_get_buspub(dev)->devinfo;
161} 161}
162 162
163static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo, 163static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo)
164 uint *condition, bool *pending)
165{ 164{
166 DECLARE_WAITQUEUE(wait, current); 165 return wait_event_timeout(devinfo->ioctl_resp_wait,
167 int timeout = IOCTL_RESP_TIMEOUT; 166 devinfo->ctl_completed,
168 167 msecs_to_jiffies(IOCTL_RESP_TIMEOUT));
169 /* Convert timeout in millsecond to jiffies */
170 timeout = msecs_to_jiffies(timeout);
171 /* Wait until control frame is available */
172 add_wait_queue(&devinfo->ioctl_resp_wait, &wait);
173 set_current_state(TASK_INTERRUPTIBLE);
174
175 smp_mb();
176 while (!(*condition) && (!signal_pending(current) && timeout)) {
177 timeout = schedule_timeout(timeout);
178 /* Wait until control frame is available */
179 smp_mb();
180 }
181
182 if (signal_pending(current))
183 *pending = true;
184
185 set_current_state(TASK_RUNNING);
186 remove_wait_queue(&devinfo->ioctl_resp_wait, &wait);
187
188 return timeout;
189} 168}
190 169
191static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) 170static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
192{ 171{
193 if (waitqueue_active(&devinfo->ioctl_resp_wait)) 172 if (waitqueue_active(&devinfo->ioctl_resp_wait))
194 wake_up_interruptible(&devinfo->ioctl_resp_wait); 173 wake_up(&devinfo->ioctl_resp_wait);
195
196 return 0;
197} 174}
198 175
199static void 176static void
@@ -322,7 +299,6 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
322{ 299{
323 int err = 0; 300 int err = 0;
324 int timeout = 0; 301 int timeout = 0;
325 bool pending;
326 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 302 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
327 303
328 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { 304 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
@@ -340,9 +316,7 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
340 clear_bit(0, &devinfo->ctl_op); 316 clear_bit(0, &devinfo->ctl_op);
341 return err; 317 return err;
342 } 318 }
343 319 timeout = brcmf_usb_ioctl_resp_wait(devinfo);
344 timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
345 &pending);
346 clear_bit(0, &devinfo->ctl_op); 320 clear_bit(0, &devinfo->ctl_op);
347 if (!timeout) { 321 if (!timeout) {
348 brcmf_dbg(ERROR, "Txctl wait timed out\n"); 322 brcmf_dbg(ERROR, "Txctl wait timed out\n");
@@ -355,7 +329,6 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
355{ 329{
356 int err = 0; 330 int err = 0;
357 int timeout = 0; 331 int timeout = 0;
358 bool pending;
359 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 332 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
360 333
361 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { 334 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
@@ -365,15 +338,14 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
365 if (test_and_set_bit(0, &devinfo->ctl_op)) 338 if (test_and_set_bit(0, &devinfo->ctl_op))
366 return -EIO; 339 return -EIO;
367 340
341 devinfo->ctl_completed = false;
368 err = brcmf_usb_recv_ctl(devinfo, buf, len); 342 err = brcmf_usb_recv_ctl(devinfo, buf, len);
369 if (err) { 343 if (err) {
370 brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len); 344 brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
371 clear_bit(0, &devinfo->ctl_op); 345 clear_bit(0, &devinfo->ctl_op);
372 return err; 346 return err;
373 } 347 }
374 devinfo->ctl_completed = false; 348 timeout = brcmf_usb_ioctl_resp_wait(devinfo);
375 timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
376 &pending);
377 err = devinfo->ctl_urb_status; 349 err = devinfo->ctl_urb_status;
378 clear_bit(0, &devinfo->ctl_op); 350 clear_bit(0, &devinfo->ctl_op);
379 if (!timeout) { 351 if (!timeout) {
@@ -493,6 +465,8 @@ static void brcmf_usb_tx_complete(struct urb *urb)
493 else 465 else
494 devinfo->bus_pub.bus->dstats.tx_errors++; 466 devinfo->bus_pub.bus->dstats.tx_errors++;
495 467
468 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
469
496 brcmu_pkt_buf_free_skb(req->skb); 470 brcmu_pkt_buf_free_skb(req->skb);
497 req->skb = NULL; 471 req->skb = NULL;
498 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount); 472 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index af396e4ab977..c1abaa6db59e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -48,6 +48,46 @@
48#define BRCMF_PNO_SCAN_COMPLETE 1 48#define BRCMF_PNO_SCAN_COMPLETE 1
49#define BRCMF_PNO_SCAN_INCOMPLETE 0 49#define BRCMF_PNO_SCAN_INCOMPLETE 0
50 50
51#define TLV_LEN_OFF 1 /* length offset */
52#define TLV_HDR_LEN 2 /* header length */
53#define TLV_BODY_OFF 2 /* body offset */
54#define TLV_OUI_LEN 3 /* oui id length */
55#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56#define WPA_OUI_TYPE 1
57#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58#define WME_OUI_TYPE 2
59
60#define VS_IE_FIXED_HDR_LEN 6
61#define WPA_IE_VERSION_LEN 2
62#define WPA_IE_MIN_OUI_LEN 4
63#define WPA_IE_SUITE_COUNT_LEN 2
64
65#define WPA_CIPHER_NONE 0 /* None */
66#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
67#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
68#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
69#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
70
71#define RSN_AKM_NONE 0 /* None (IBSS) */
72#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
73#define RSN_AKM_PSK 2 /* Pre-shared Key */
74#define RSN_CAP_LEN 2 /* Length of RSN capabilities */
75#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
76
77#define VNDR_IE_CMD_LEN 4 /* length of the set command
78 * string :"add", "del" (+ NUL)
79 */
80#define VNDR_IE_COUNT_OFFSET 4
81#define VNDR_IE_PKTFLAG_OFFSET 8
82#define VNDR_IE_VSIE_OFFSET 12
83#define VNDR_IE_HDR_SIZE 12
84#define VNDR_IE_BEACON_FLAG 0x1
85#define VNDR_IE_PRBRSP_FLAG 0x2
86#define MAX_VNDR_IE_NUMBER 5
87
88#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
89#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
90
51#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ 91#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
52 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) 92 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
53 93
@@ -55,33 +95,12 @@ static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
55 95
56static u32 brcmf_dbg_level = WL_DBG_ERR; 96static u32 brcmf_dbg_level = WL_DBG_ERR;
57 97
58static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
59{
60 dev->driver_data = data;
61}
62
63static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
64{
65 void *data = NULL;
66
67 if (dev)
68 data = dev->driver_data;
69 return data;
70}
71
72static
73struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
74{
75 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
76 return ci->cfg_priv;
77}
78
79static bool check_sys_up(struct wiphy *wiphy) 98static bool check_sys_up(struct wiphy *wiphy)
80{ 99{
81 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 100 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
82 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) { 101 if (!test_bit(WL_STATUS_READY, &cfg->status)) {
83 WL_INFO("device is not ready : status (%d)\n", 102 WL_INFO("device is not ready : status (%d)\n",
84 (int)cfg_priv->status); 103 (int)cfg->status);
85 return false; 104 return false;
86 } 105 }
87 return true; 106 return true;
@@ -269,6 +288,25 @@ struct brcmf_tlv {
269 u8 data[1]; 288 u8 data[1];
270}; 289};
271 290
291/* Vendor specific ie. id = 221, oui and type defines exact ie */
292struct brcmf_vs_tlv {
293 u8 id;
294 u8 len;
295 u8 oui[3];
296 u8 oui_type;
297};
298
299struct parsed_vndr_ie_info {
300 u8 *ie_ptr;
301 u32 ie_len; /* total length including id & length field */
302 struct brcmf_vs_tlv vndrie;
303};
304
305struct parsed_vndr_ies {
306 u32 count;
307 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
308};
309
272/* Quarter dBm units to mW 310/* Quarter dBm units to mW
273 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 311 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
274 * Table is offset so the last entry is largest mW value that fits in 312 * Table is offset so the last entry is largest mW value that fits in
@@ -366,6 +404,44 @@ brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
366 return err; 404 return err;
367} 405}
368 406
407static s32
408brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name,
409 void *param, s32 paramlen,
410 void *buf, s32 buflen, s32 bssidx)
411{
412 s32 err = -ENOMEM;
413 u32 len;
414
415 len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
416 buf, buflen, bssidx);
417 BUG_ON(!len);
418 if (len > 0)
419 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
420 if (err)
421 WL_ERR("error (%d)\n", err);
422
423 return err;
424}
425
426static s32
427brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name,
428 void *param, s32 paramlen,
429 void *buf, s32 buflen, s32 bssidx)
430{
431 s32 err = -ENOMEM;
432 u32 len;
433
434 len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
435 buf, buflen, bssidx);
436 BUG_ON(!len);
437 if (len > 0)
438 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len);
439 if (err)
440 WL_ERR("error (%d)\n", err);
441
442 return err;
443}
444
369static void convert_key_from_CPU(struct brcmf_wsec_key *key, 445static void convert_key_from_CPU(struct brcmf_wsec_key *key,
370 struct brcmf_wsec_key_le *key_le) 446 struct brcmf_wsec_key_le *key_le)
371{ 447{
@@ -380,16 +456,22 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key,
380 memcpy(key_le->ea, key->ea, sizeof(key->ea)); 456 memcpy(key_le->ea, key->ea, sizeof(key->ea));
381} 457}
382 458
383static int send_key_to_dongle(struct net_device *ndev, 459static int
384 struct brcmf_wsec_key *key) 460send_key_to_dongle(struct brcmf_cfg80211_info *cfg, s32 bssidx,
461 struct net_device *ndev, struct brcmf_wsec_key *key)
385{ 462{
386 int err; 463 int err;
387 struct brcmf_wsec_key_le key_le; 464 struct brcmf_wsec_key_le key_le;
388 465
389 convert_key_from_CPU(key, &key_le); 466 convert_key_from_CPU(key, &key_le);
390 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le)); 467
468 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
469 sizeof(key_le),
470 cfg->extra_buf,
471 WL_EXTRA_BUF_MAX, bssidx);
472
391 if (err) 473 if (err)
392 WL_ERR("WLC_SET_KEY error (%d)\n", err); 474 WL_ERR("wsec_key error (%d)\n", err);
393 return err; 475 return err;
394} 476}
395 477
@@ -398,14 +480,12 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
398 enum nl80211_iftype type, u32 *flags, 480 enum nl80211_iftype type, u32 *flags,
399 struct vif_params *params) 481 struct vif_params *params)
400{ 482{
401 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 483 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
402 struct wireless_dev *wdev;
403 s32 infra = 0; 484 s32 infra = 0;
485 s32 ap = 0;
404 s32 err = 0; 486 s32 err = 0;
405 487
406 WL_TRACE("Enter\n"); 488 WL_TRACE("Enter, ndev=%p, type=%d\n", ndev, type);
407 if (!check_sys_up(wiphy))
408 return -EIO;
409 489
410 switch (type) { 490 switch (type) {
411 case NL80211_IFTYPE_MONITOR: 491 case NL80211_IFTYPE_MONITOR:
@@ -414,29 +494,44 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
414 type); 494 type);
415 return -EOPNOTSUPP; 495 return -EOPNOTSUPP;
416 case NL80211_IFTYPE_ADHOC: 496 case NL80211_IFTYPE_ADHOC:
417 cfg_priv->conf->mode = WL_MODE_IBSS; 497 cfg->conf->mode = WL_MODE_IBSS;
418 infra = 0; 498 infra = 0;
419 break; 499 break;
420 case NL80211_IFTYPE_STATION: 500 case NL80211_IFTYPE_STATION:
421 cfg_priv->conf->mode = WL_MODE_BSS; 501 cfg->conf->mode = WL_MODE_BSS;
422 infra = 1; 502 infra = 1;
423 break; 503 break;
504 case NL80211_IFTYPE_AP:
505 cfg->conf->mode = WL_MODE_AP;
506 ap = 1;
507 break;
424 default: 508 default:
425 err = -EINVAL; 509 err = -EINVAL;
426 goto done; 510 goto done;
427 } 511 }
428 512
429 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); 513 if (ap) {
430 if (err) { 514 set_bit(WL_STATUS_AP_CREATING, &cfg->status);
431 WL_ERR("WLC_SET_INFRA error (%d)\n", err); 515 if (!cfg->ap_info)
432 err = -EAGAIN; 516 cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
517 GFP_KERNEL);
518 if (!cfg->ap_info) {
519 err = -ENOMEM;
520 goto done;
521 }
522 WL_INFO("IF Type = AP\n");
433 } else { 523 } else {
434 wdev = ndev->ieee80211_ptr; 524 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
435 wdev->iftype = type; 525 if (err) {
526 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
527 err = -EAGAIN;
528 goto done;
529 }
530 WL_INFO("IF Type = %s\n",
531 (cfg->conf->mode == WL_MODE_IBSS) ?
532 "Adhoc" : "Infra");
436 } 533 }
437 534 ndev->ieee80211_ptr->iftype = type;
438 WL_INFO("IF Type = %s\n",
439 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
440 535
441done: 536done:
442 WL_TRACE("Exit\n"); 537 WL_TRACE("Exit\n");
@@ -487,12 +582,55 @@ brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
487 return err; 582 return err;
488} 583}
489 584
585static s32
586brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val,
587 s32 bssidx)
588{
589 s8 buf[BRCMF_DCMD_SMLEN];
590 __le32 val_le;
591
592 val_le = cpu_to_le32(val);
593
594 return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le,
595 sizeof(val_le), buf, sizeof(buf),
596 bssidx);
597}
598
599static s32
600brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val,
601 s32 bssidx)
602{
603 s8 buf[BRCMF_DCMD_SMLEN];
604 s32 err;
605 __le32 val_le;
606
607 memset(buf, 0, sizeof(buf));
608 err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf,
609 sizeof(buf), bssidx);
610 if (err == 0) {
611 memcpy(&val_le, buf, sizeof(val_le));
612 *val = le32_to_cpu(val_le);
613 }
614 return err;
615}
616
617
618/*
619 * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this
620 * should return the ndev matching bssidx.
621 */
622static s32
623brcmf_find_bssidx(struct brcmf_cfg80211_info *cfg, struct net_device *ndev)
624{
625 return 0;
626}
627
490static void brcmf_set_mpc(struct net_device *ndev, int mpc) 628static void brcmf_set_mpc(struct net_device *ndev, int mpc)
491{ 629{
492 s32 err = 0; 630 s32 err = 0;
493 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 631 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
494 632
495 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) { 633 if (test_bit(WL_STATUS_READY, &cfg->status)) {
496 err = brcmf_dev_intvar_set(ndev, "mpc", mpc); 634 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
497 if (err) { 635 if (err) {
498 WL_ERR("fail to set mpc\n"); 636 WL_ERR("fail to set mpc\n");
@@ -578,10 +716,10 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
578 return err; 716 return err;
579} 717}
580 718
581static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv) 719static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
582{ 720{
583 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 721 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
584 struct net_device *ndev = cfg_to_ndev(cfg_priv); 722 struct net_device *ndev = cfg_to_ndev(cfg);
585 struct brcmf_ssid ssid; 723 struct brcmf_ssid ssid;
586 __le32 passive_scan; 724 __le32 passive_scan;
587 s32 err = 0; 725 s32 err = 0;
@@ -591,19 +729,19 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
591 729
592 iscan->state = WL_ISCAN_STATE_SCANING; 730 iscan->state = WL_ISCAN_STATE_SCANING;
593 731
594 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1); 732 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
595 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN, 733 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_SET_PASSIVE_SCAN,
596 &passive_scan, sizeof(passive_scan)); 734 &passive_scan, sizeof(passive_scan));
597 if (err) { 735 if (err) {
598 WL_ERR("error (%d)\n", err); 736 WL_ERR("error (%d)\n", err);
599 return err; 737 return err;
600 } 738 }
601 brcmf_set_mpc(ndev, 0); 739 brcmf_set_mpc(ndev, 0);
602 cfg_priv->iscan_kickstart = true; 740 cfg->iscan_kickstart = true;
603 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); 741 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
604 if (err) { 742 if (err) {
605 brcmf_set_mpc(ndev, 1); 743 brcmf_set_mpc(ndev, 1);
606 cfg_priv->iscan_kickstart = false; 744 cfg->iscan_kickstart = false;
607 return err; 745 return err;
608 } 746 }
609 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); 747 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
@@ -616,27 +754,27 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
616 struct cfg80211_scan_request *request, 754 struct cfg80211_scan_request *request,
617 struct cfg80211_ssid *this_ssid) 755 struct cfg80211_ssid *this_ssid)
618{ 756{
619 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 757 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
620 struct cfg80211_ssid *ssids; 758 struct cfg80211_ssid *ssids;
621 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int; 759 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
622 __le32 passive_scan; 760 __le32 passive_scan;
623 bool iscan_req; 761 bool iscan_req;
624 bool spec_scan; 762 bool spec_scan;
625 s32 err = 0; 763 s32 err = 0;
626 u32 SSID_len; 764 u32 SSID_len;
627 765
628 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 766 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
629 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status); 767 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
630 return -EAGAIN; 768 return -EAGAIN;
631 } 769 }
632 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) { 770 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
633 WL_ERR("Scanning being aborted : status (%lu)\n", 771 WL_ERR("Scanning being aborted : status (%lu)\n",
634 cfg_priv->status); 772 cfg->status);
635 return -EAGAIN; 773 return -EAGAIN;
636 } 774 }
637 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { 775 if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
638 WL_ERR("Connecting : status (%lu)\n", 776 WL_ERR("Connecting : status (%lu)\n",
639 cfg_priv->status); 777 cfg->status);
640 return -EAGAIN; 778 return -EAGAIN;
641 } 779 }
642 780
@@ -645,7 +783,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
645 if (request) { 783 if (request) {
646 /* scan bss */ 784 /* scan bss */
647 ssids = request->ssids; 785 ssids = request->ssids;
648 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len)) 786 if (cfg->iscan_on && (!ssids || !ssids->ssid_len))
649 iscan_req = true; 787 iscan_req = true;
650 } else { 788 } else {
651 /* scan in ibss */ 789 /* scan in ibss */
@@ -653,10 +791,10 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
653 ssids = this_ssid; 791 ssids = this_ssid;
654 } 792 }
655 793
656 cfg_priv->scan_request = request; 794 cfg->scan_request = request;
657 set_bit(WL_STATUS_SCANNING, &cfg_priv->status); 795 set_bit(WL_STATUS_SCANNING, &cfg->status);
658 if (iscan_req) { 796 if (iscan_req) {
659 err = brcmf_do_iscan(cfg_priv); 797 err = brcmf_do_iscan(cfg);
660 if (!err) 798 if (!err)
661 return err; 799 return err;
662 else 800 else
@@ -675,7 +813,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
675 WL_SCAN("Broadcast scan\n"); 813 WL_SCAN("Broadcast scan\n");
676 } 814 }
677 815
678 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1); 816 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
679 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, 817 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
680 &passive_scan, sizeof(passive_scan)); 818 &passive_scan, sizeof(passive_scan));
681 if (err) { 819 if (err) {
@@ -700,8 +838,8 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
700 return 0; 838 return 0;
701 839
702scan_out: 840scan_out:
703 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); 841 clear_bit(WL_STATUS_SCANNING, &cfg->status);
704 cfg_priv->scan_request = NULL; 842 cfg->scan_request = NULL;
705 return err; 843 return err;
706} 844}
707 845
@@ -806,7 +944,7 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
806} 944}
807 945
808static s32 946static s32
809brcmf_notify_escan_complete(struct brcmf_cfg80211_priv *cfg_priv, 947brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
810 struct net_device *ndev, 948 struct net_device *ndev,
811 bool aborted, bool fw_abort) 949 bool aborted, bool fw_abort)
812{ 950{
@@ -818,11 +956,11 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_priv *cfg_priv,
818 956
819 /* clear scan request, because the FW abort can cause a second call */ 957 /* clear scan request, because the FW abort can cause a second call */
820 /* to this functon and might cause a double cfg80211_scan_done */ 958 /* to this functon and might cause a double cfg80211_scan_done */
821 scan_request = cfg_priv->scan_request; 959 scan_request = cfg->scan_request;
822 cfg_priv->scan_request = NULL; 960 cfg->scan_request = NULL;
823 961
824 if (timer_pending(&cfg_priv->escan_timeout)) 962 if (timer_pending(&cfg->escan_timeout))
825 del_timer_sync(&cfg_priv->escan_timeout); 963 del_timer_sync(&cfg->escan_timeout);
826 964
827 if (fw_abort) { 965 if (fw_abort) {
828 /* Do a scan abort to stop the driver's scan engine */ 966 /* Do a scan abort to stop the driver's scan engine */
@@ -848,11 +986,11 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_priv *cfg_priv,
848 * e-scan can be initiated by scheduled scan 986 * e-scan can be initiated by scheduled scan
849 * which takes precedence. 987 * which takes precedence.
850 */ 988 */
851 if (cfg_priv->sched_escan) { 989 if (cfg->sched_escan) {
852 WL_SCAN("scheduled scan completed\n"); 990 WL_SCAN("scheduled scan completed\n");
853 cfg_priv->sched_escan = false; 991 cfg->sched_escan = false;
854 if (!aborted) 992 if (!aborted)
855 cfg80211_sched_scan_results(cfg_to_wiphy(cfg_priv)); 993 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
856 brcmf_set_mpc(ndev, 1); 994 brcmf_set_mpc(ndev, 1);
857 } else if (scan_request) { 995 } else if (scan_request) {
858 WL_SCAN("ESCAN Completed scan: %s\n", 996 WL_SCAN("ESCAN Completed scan: %s\n",
@@ -860,7 +998,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_priv *cfg_priv,
860 cfg80211_scan_done(scan_request, aborted); 998 cfg80211_scan_done(scan_request, aborted);
861 brcmf_set_mpc(ndev, 1); 999 brcmf_set_mpc(ndev, 1);
862 } 1000 }
863 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 1001 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
864 WL_ERR("Scan complete while device not scanning\n"); 1002 WL_ERR("Scan complete while device not scanning\n");
865 return -EPERM; 1003 return -EPERM;
866 } 1004 }
@@ -869,7 +1007,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_priv *cfg_priv,
869} 1007}
870 1008
871static s32 1009static s32
872brcmf_run_escan(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev, 1010brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
873 struct cfg80211_scan_request *request, u16 action) 1011 struct cfg80211_scan_request *request, u16 action)
874{ 1012{
875 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + 1013 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
@@ -899,7 +1037,7 @@ brcmf_run_escan(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev,
899 params->sync_id = cpu_to_le16(0x1234); 1037 params->sync_id = cpu_to_le16(0x1234);
900 1038
901 err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size, 1039 err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
902 cfg_priv->escan_ioctl_buf, BRCMF_DCMD_MEDLEN); 1040 cfg->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
903 if (err) { 1041 if (err) {
904 if (err == -EBUSY) 1042 if (err == -EBUSY)
905 WL_INFO("system busy : escan canceled\n"); 1043 WL_INFO("system busy : escan canceled\n");
@@ -913,7 +1051,7 @@ exit:
913} 1051}
914 1052
915static s32 1053static s32
916brcmf_do_escan(struct brcmf_cfg80211_priv *cfg_priv, struct wiphy *wiphy, 1054brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
917 struct net_device *ndev, struct cfg80211_scan_request *request) 1055 struct net_device *ndev, struct cfg80211_scan_request *request)
918{ 1056{
919 s32 err; 1057 s32 err;
@@ -921,10 +1059,10 @@ brcmf_do_escan(struct brcmf_cfg80211_priv *cfg_priv, struct wiphy *wiphy,
921 struct brcmf_scan_results *results; 1059 struct brcmf_scan_results *results;
922 1060
923 WL_SCAN("Enter\n"); 1061 WL_SCAN("Enter\n");
924 cfg_priv->escan_info.ndev = ndev; 1062 cfg->escan_info.ndev = ndev;
925 cfg_priv->escan_info.wiphy = wiphy; 1063 cfg->escan_info.wiphy = wiphy;
926 cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_SCANNING; 1064 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
927 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1); 1065 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
928 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, 1066 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
929 &passive_scan, sizeof(passive_scan)); 1067 &passive_scan, sizeof(passive_scan));
930 if (err) { 1068 if (err) {
@@ -932,12 +1070,12 @@ brcmf_do_escan(struct brcmf_cfg80211_priv *cfg_priv, struct wiphy *wiphy,
932 return err; 1070 return err;
933 } 1071 }
934 brcmf_set_mpc(ndev, 0); 1072 brcmf_set_mpc(ndev, 0);
935 results = (struct brcmf_scan_results *)cfg_priv->escan_info.escan_buf; 1073 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
936 results->version = 0; 1074 results->version = 0;
937 results->count = 0; 1075 results->count = 0;
938 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE; 1076 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
939 1077
940 err = brcmf_run_escan(cfg_priv, ndev, request, WL_ESCAN_ACTION_START); 1078 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
941 if (err) 1079 if (err)
942 brcmf_set_mpc(ndev, 1); 1080 brcmf_set_mpc(ndev, 1);
943 return err; 1081 return err;
@@ -948,9 +1086,9 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
948 struct cfg80211_scan_request *request, 1086 struct cfg80211_scan_request *request,
949 struct cfg80211_ssid *this_ssid) 1087 struct cfg80211_ssid *this_ssid)
950{ 1088{
951 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1089 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
952 struct cfg80211_ssid *ssids; 1090 struct cfg80211_ssid *ssids;
953 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int; 1091 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
954 __le32 passive_scan; 1092 __le32 passive_scan;
955 bool escan_req; 1093 bool escan_req;
956 bool spec_scan; 1094 bool spec_scan;
@@ -959,23 +1097,23 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
959 1097
960 WL_SCAN("START ESCAN\n"); 1098 WL_SCAN("START ESCAN\n");
961 1099
962 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 1100 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
963 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status); 1101 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
964 return -EAGAIN; 1102 return -EAGAIN;
965 } 1103 }
966 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) { 1104 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
967 WL_ERR("Scanning being aborted : status (%lu)\n", 1105 WL_ERR("Scanning being aborted : status (%lu)\n",
968 cfg_priv->status); 1106 cfg->status);
969 return -EAGAIN; 1107 return -EAGAIN;
970 } 1108 }
971 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { 1109 if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
972 WL_ERR("Connecting : status (%lu)\n", 1110 WL_ERR("Connecting : status (%lu)\n",
973 cfg_priv->status); 1111 cfg->status);
974 return -EAGAIN; 1112 return -EAGAIN;
975 } 1113 }
976 1114
977 /* Arm scan timeout timer */ 1115 /* Arm scan timeout timer */
978 mod_timer(&cfg_priv->escan_timeout, jiffies + 1116 mod_timer(&cfg->escan_timeout, jiffies +
979 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); 1117 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
980 1118
981 escan_req = false; 1119 escan_req = false;
@@ -989,10 +1127,10 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
989 ssids = this_ssid; 1127 ssids = this_ssid;
990 } 1128 }
991 1129
992 cfg_priv->scan_request = request; 1130 cfg->scan_request = request;
993 set_bit(WL_STATUS_SCANNING, &cfg_priv->status); 1131 set_bit(WL_STATUS_SCANNING, &cfg->status);
994 if (escan_req) { 1132 if (escan_req) {
995 err = brcmf_do_escan(cfg_priv, wiphy, ndev, request); 1133 err = brcmf_do_escan(cfg, wiphy, ndev, request);
996 if (!err) 1134 if (!err)
997 return err; 1135 return err;
998 else 1136 else
@@ -1011,7 +1149,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
1011 } else 1149 } else
1012 WL_SCAN("Broadcast scan\n"); 1150 WL_SCAN("Broadcast scan\n");
1013 1151
1014 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1); 1152 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1015 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, 1153 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
1016 &passive_scan, sizeof(passive_scan)); 1154 &passive_scan, sizeof(passive_scan));
1017 if (err) { 1155 if (err) {
@@ -1036,10 +1174,10 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
1036 return 0; 1174 return 0;
1037 1175
1038scan_out: 1176scan_out:
1039 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); 1177 clear_bit(WL_STATUS_SCANNING, &cfg->status);
1040 if (timer_pending(&cfg_priv->escan_timeout)) 1178 if (timer_pending(&cfg->escan_timeout))
1041 del_timer_sync(&cfg_priv->escan_timeout); 1179 del_timer_sync(&cfg->escan_timeout);
1042 cfg_priv->scan_request = NULL; 1180 cfg->scan_request = NULL;
1043 return err; 1181 return err;
1044} 1182}
1045 1183
@@ -1048,7 +1186,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
1048 struct cfg80211_scan_request *request) 1186 struct cfg80211_scan_request *request)
1049{ 1187{
1050 struct net_device *ndev = request->wdev->netdev; 1188 struct net_device *ndev = request->wdev->netdev;
1051 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1189 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1052 s32 err = 0; 1190 s32 err = 0;
1053 1191
1054 WL_TRACE("Enter\n"); 1192 WL_TRACE("Enter\n");
@@ -1056,9 +1194,9 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
1056 if (!check_sys_up(wiphy)) 1194 if (!check_sys_up(wiphy))
1057 return -EIO; 1195 return -EIO;
1058 1196
1059 if (cfg_priv->iscan_on) 1197 if (cfg->iscan_on)
1060 err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL); 1198 err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
1061 else if (cfg_priv->escan_on) 1199 else if (cfg->escan_on)
1062 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); 1200 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1063 1201
1064 if (err) 1202 if (err)
@@ -1105,8 +1243,8 @@ static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1105 1243
1106static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1244static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1107{ 1245{
1108 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1246 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1109 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1247 struct net_device *ndev = cfg_to_ndev(cfg);
1110 s32 err = 0; 1248 s32 err = 0;
1111 1249
1112 WL_TRACE("Enter\n"); 1250 WL_TRACE("Enter\n");
@@ -1114,30 +1252,30 @@ static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1114 return -EIO; 1252 return -EIO;
1115 1253
1116 if (changed & WIPHY_PARAM_RTS_THRESHOLD && 1254 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1117 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) { 1255 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1118 cfg_priv->conf->rts_threshold = wiphy->rts_threshold; 1256 cfg->conf->rts_threshold = wiphy->rts_threshold;
1119 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold); 1257 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1120 if (!err) 1258 if (!err)
1121 goto done; 1259 goto done;
1122 } 1260 }
1123 if (changed & WIPHY_PARAM_FRAG_THRESHOLD && 1261 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1124 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) { 1262 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1125 cfg_priv->conf->frag_threshold = wiphy->frag_threshold; 1263 cfg->conf->frag_threshold = wiphy->frag_threshold;
1126 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold); 1264 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1127 if (!err) 1265 if (!err)
1128 goto done; 1266 goto done;
1129 } 1267 }
1130 if (changed & WIPHY_PARAM_RETRY_LONG 1268 if (changed & WIPHY_PARAM_RETRY_LONG
1131 && (cfg_priv->conf->retry_long != wiphy->retry_long)) { 1269 && (cfg->conf->retry_long != wiphy->retry_long)) {
1132 cfg_priv->conf->retry_long = wiphy->retry_long; 1270 cfg->conf->retry_long = wiphy->retry_long;
1133 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true); 1271 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1134 if (!err) 1272 if (!err)
1135 goto done; 1273 goto done;
1136 } 1274 }
1137 if (changed & WIPHY_PARAM_RETRY_SHORT 1275 if (changed & WIPHY_PARAM_RETRY_SHORT
1138 && (cfg_priv->conf->retry_short != wiphy->retry_short)) { 1276 && (cfg->conf->retry_short != wiphy->retry_short)) {
1139 cfg_priv->conf->retry_short = wiphy->retry_short; 1277 cfg->conf->retry_short = wiphy->retry_short;
1140 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false); 1278 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1141 if (!err) 1279 if (!err)
1142 goto done; 1280 goto done;
1143 } 1281 }
@@ -1147,61 +1285,6 @@ done:
1147 return err; 1285 return err;
1148} 1286}
1149 1287
1150static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
1151{
1152 switch (item) {
1153 case WL_PROF_SEC:
1154 return &cfg_priv->profile->sec;
1155 case WL_PROF_BSSID:
1156 return &cfg_priv->profile->bssid;
1157 case WL_PROF_SSID:
1158 return &cfg_priv->profile->ssid;
1159 }
1160 WL_ERR("invalid item (%d)\n", item);
1161 return NULL;
1162}
1163
1164static s32
1165brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
1166 const struct brcmf_event_msg *e, void *data, s32 item)
1167{
1168 s32 err = 0;
1169 struct brcmf_ssid *ssid;
1170
1171 switch (item) {
1172 case WL_PROF_SSID:
1173 ssid = (struct brcmf_ssid *) data;
1174 memset(cfg_priv->profile->ssid.SSID, 0,
1175 sizeof(cfg_priv->profile->ssid.SSID));
1176 memcpy(cfg_priv->profile->ssid.SSID,
1177 ssid->SSID, ssid->SSID_len);
1178 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
1179 break;
1180 case WL_PROF_BSSID:
1181 if (data)
1182 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
1183 else
1184 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
1185 break;
1186 case WL_PROF_SEC:
1187 memcpy(&cfg_priv->profile->sec, data,
1188 sizeof(cfg_priv->profile->sec));
1189 break;
1190 case WL_PROF_BEACONINT:
1191 cfg_priv->profile->beacon_interval = *(u16 *)data;
1192 break;
1193 case WL_PROF_DTIMPERIOD:
1194 cfg_priv->profile->dtim_period = *(u8 *)data;
1195 break;
1196 default:
1197 WL_ERR("unsupported item (%d)\n", item);
1198 err = -EOPNOTSUPP;
1199 break;
1200 }
1201
1202 return err;
1203}
1204
1205static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof) 1288static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1206{ 1289{
1207 memset(prof, 0, sizeof(*prof)); 1290 memset(prof, 0, sizeof(*prof));
@@ -1234,20 +1317,20 @@ static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
1234 } 1317 }
1235} 1318}
1236 1319
1237static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv) 1320static void brcmf_link_down(struct brcmf_cfg80211_info *cfg)
1238{ 1321{
1239 struct net_device *ndev = NULL; 1322 struct net_device *ndev = NULL;
1240 s32 err = 0; 1323 s32 err = 0;
1241 1324
1242 WL_TRACE("Enter\n"); 1325 WL_TRACE("Enter\n");
1243 1326
1244 if (cfg_priv->link_up) { 1327 if (cfg->link_up) {
1245 ndev = cfg_to_ndev(cfg_priv); 1328 ndev = cfg_to_ndev(cfg);
1246 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); 1329 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
1247 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0); 1330 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
1248 if (err) 1331 if (err)
1249 WL_ERR("WLC_DISASSOC failed (%d)\n", err); 1332 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
1250 cfg_priv->link_up = false; 1333 cfg->link_up = false;
1251 } 1334 }
1252 WL_TRACE("Exit\n"); 1335 WL_TRACE("Exit\n");
1253} 1336}
@@ -1256,13 +1339,13 @@ static s32
1256brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, 1339brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1257 struct cfg80211_ibss_params *params) 1340 struct cfg80211_ibss_params *params)
1258{ 1341{
1259 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1342 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1343 struct brcmf_cfg80211_profile *profile = cfg->profile;
1260 struct brcmf_join_params join_params; 1344 struct brcmf_join_params join_params;
1261 size_t join_params_size = 0; 1345 size_t join_params_size = 0;
1262 s32 err = 0; 1346 s32 err = 0;
1263 s32 wsec = 0; 1347 s32 wsec = 0;
1264 s32 bcnprd; 1348 s32 bcnprd;
1265 struct brcmf_ssid ssid;
1266 1349
1267 WL_TRACE("Enter\n"); 1350 WL_TRACE("Enter\n");
1268 if (!check_sys_up(wiphy)) 1351 if (!check_sys_up(wiphy))
@@ -1275,7 +1358,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1275 return -EOPNOTSUPP; 1358 return -EOPNOTSUPP;
1276 } 1359 }
1277 1360
1278 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1361 set_bit(WL_STATUS_CONNECTING, &cfg->status);
1279 1362
1280 if (params->bssid) 1363 if (params->bssid)
1281 WL_CONN("BSSID: %pM\n", params->bssid); 1364 WL_CONN("BSSID: %pM\n", params->bssid);
@@ -1338,40 +1421,38 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1338 memset(&join_params, 0, sizeof(struct brcmf_join_params)); 1421 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1339 1422
1340 /* SSID */ 1423 /* SSID */
1341 ssid.SSID_len = min_t(u32, params->ssid_len, 32); 1424 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1342 memcpy(ssid.SSID, params->ssid, ssid.SSID_len); 1425 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1343 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len); 1426 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1344 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len); 1427 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1345 join_params_size = sizeof(join_params.ssid_le); 1428 join_params_size = sizeof(join_params.ssid_le);
1346 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1347 1429
1348 /* BSSID */ 1430 /* BSSID */
1349 if (params->bssid) { 1431 if (params->bssid) {
1350 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN); 1432 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1351 join_params_size = sizeof(join_params.ssid_le) + 1433 join_params_size = sizeof(join_params.ssid_le) +
1352 BRCMF_ASSOC_PARAMS_FIXED_SIZE; 1434 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1435 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1353 } else { 1436 } else {
1354 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); 1437 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1438 memset(profile->bssid, 0, ETH_ALEN);
1355 } 1439 }
1356 1440
1357 brcmf_update_prof(cfg_priv, NULL,
1358 &join_params.params_le.bssid, WL_PROF_BSSID);
1359
1360 /* Channel */ 1441 /* Channel */
1361 if (params->channel) { 1442 if (params->channel) {
1362 u32 target_channel; 1443 u32 target_channel;
1363 1444
1364 cfg_priv->channel = 1445 cfg->channel =
1365 ieee80211_frequency_to_channel( 1446 ieee80211_frequency_to_channel(
1366 params->channel->center_freq); 1447 params->channel->center_freq);
1367 if (params->channel_fixed) { 1448 if (params->channel_fixed) {
1368 /* adding chanspec */ 1449 /* adding chanspec */
1369 brcmf_ch_to_chanspec(cfg_priv->channel, 1450 brcmf_ch_to_chanspec(cfg->channel,
1370 &join_params, &join_params_size); 1451 &join_params, &join_params_size);
1371 } 1452 }
1372 1453
1373 /* set channel for starter */ 1454 /* set channel for starter */
1374 target_channel = cfg_priv->channel; 1455 target_channel = cfg->channel;
1375 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL, 1456 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1376 &target_channel); 1457 &target_channel);
1377 if (err) { 1458 if (err) {
@@ -1379,9 +1460,9 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1379 goto done; 1460 goto done;
1380 } 1461 }
1381 } else 1462 } else
1382 cfg_priv->channel = 0; 1463 cfg->channel = 0;
1383 1464
1384 cfg_priv->ibss_starter = false; 1465 cfg->ibss_starter = false;
1385 1466
1386 1467
1387 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, 1468 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
@@ -1393,7 +1474,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1393 1474
1394done: 1475done:
1395 if (err) 1476 if (err)
1396 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1477 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
1397 WL_TRACE("Exit\n"); 1478 WL_TRACE("Exit\n");
1398 return err; 1479 return err;
1399} 1480}
@@ -1401,14 +1482,14 @@ done:
1401static s32 1482static s32
1402brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) 1483brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1403{ 1484{
1404 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1485 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1405 s32 err = 0; 1486 s32 err = 0;
1406 1487
1407 WL_TRACE("Enter\n"); 1488 WL_TRACE("Enter\n");
1408 if (!check_sys_up(wiphy)) 1489 if (!check_sys_up(wiphy))
1409 return -EIO; 1490 return -EIO;
1410 1491
1411 brcmf_link_down(cfg_priv); 1492 brcmf_link_down(cfg);
1412 1493
1413 WL_TRACE("Exit\n"); 1494 WL_TRACE("Exit\n");
1414 1495
@@ -1418,7 +1499,8 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1418static s32 brcmf_set_wpa_version(struct net_device *ndev, 1499static s32 brcmf_set_wpa_version(struct net_device *ndev,
1419 struct cfg80211_connect_params *sme) 1500 struct cfg80211_connect_params *sme)
1420{ 1501{
1421 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1502 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1503 struct brcmf_cfg80211_profile *profile = cfg->profile;
1422 struct brcmf_cfg80211_security *sec; 1504 struct brcmf_cfg80211_security *sec;
1423 s32 val = 0; 1505 s32 val = 0;
1424 s32 err = 0; 1506 s32 err = 0;
@@ -1435,7 +1517,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
1435 WL_ERR("set wpa_auth failed (%d)\n", err); 1517 WL_ERR("set wpa_auth failed (%d)\n", err);
1436 return err; 1518 return err;
1437 } 1519 }
1438 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1520 sec = &profile->sec;
1439 sec->wpa_versions = sme->crypto.wpa_versions; 1521 sec->wpa_versions = sme->crypto.wpa_versions;
1440 return err; 1522 return err;
1441} 1523}
@@ -1443,7 +1525,8 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
1443static s32 brcmf_set_auth_type(struct net_device *ndev, 1525static s32 brcmf_set_auth_type(struct net_device *ndev,
1444 struct cfg80211_connect_params *sme) 1526 struct cfg80211_connect_params *sme)
1445{ 1527{
1446 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1528 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1529 struct brcmf_cfg80211_profile *profile = cfg->profile;
1447 struct brcmf_cfg80211_security *sec; 1530 struct brcmf_cfg80211_security *sec;
1448 s32 val = 0; 1531 s32 val = 0;
1449 s32 err = 0; 1532 s32 err = 0;
@@ -1474,7 +1557,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
1474 WL_ERR("set auth failed (%d)\n", err); 1557 WL_ERR("set auth failed (%d)\n", err);
1475 return err; 1558 return err;
1476 } 1559 }
1477 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1560 sec = &profile->sec;
1478 sec->auth_type = sme->auth_type; 1561 sec->auth_type = sme->auth_type;
1479 return err; 1562 return err;
1480} 1563}
@@ -1483,7 +1566,8 @@ static s32
1483brcmf_set_set_cipher(struct net_device *ndev, 1566brcmf_set_set_cipher(struct net_device *ndev,
1484 struct cfg80211_connect_params *sme) 1567 struct cfg80211_connect_params *sme)
1485{ 1568{
1486 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1569 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1570 struct brcmf_cfg80211_profile *profile = cfg->profile;
1487 struct brcmf_cfg80211_security *sec; 1571 struct brcmf_cfg80211_security *sec;
1488 s32 pval = 0; 1572 s32 pval = 0;
1489 s32 gval = 0; 1573 s32 gval = 0;
@@ -1539,7 +1623,7 @@ brcmf_set_set_cipher(struct net_device *ndev,
1539 return err; 1623 return err;
1540 } 1624 }
1541 1625
1542 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1626 sec = &profile->sec;
1543 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0]; 1627 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1544 sec->cipher_group = sme->crypto.cipher_group; 1628 sec->cipher_group = sme->crypto.cipher_group;
1545 1629
@@ -1549,7 +1633,8 @@ brcmf_set_set_cipher(struct net_device *ndev,
1549static s32 1633static s32
1550brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) 1634brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1551{ 1635{
1552 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1636 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1637 struct brcmf_cfg80211_profile *profile = cfg->profile;
1553 struct brcmf_cfg80211_security *sec; 1638 struct brcmf_cfg80211_security *sec;
1554 s32 val = 0; 1639 s32 val = 0;
1555 s32 err = 0; 1640 s32 err = 0;
@@ -1595,74 +1680,76 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1595 return err; 1680 return err;
1596 } 1681 }
1597 } 1682 }
1598 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1683 sec = &profile->sec;
1599 sec->wpa_auth = sme->crypto.akm_suites[0]; 1684 sec->wpa_auth = sme->crypto.akm_suites[0];
1600 1685
1601 return err; 1686 return err;
1602} 1687}
1603 1688
1604static s32 1689static s32
1605brcmf_set_wep_sharedkey(struct net_device *ndev, 1690brcmf_set_sharedkey(struct net_device *ndev,
1606 struct cfg80211_connect_params *sme) 1691 struct cfg80211_connect_params *sme)
1607{ 1692{
1608 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1693 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1694 struct brcmf_cfg80211_profile *profile = cfg->profile;
1609 struct brcmf_cfg80211_security *sec; 1695 struct brcmf_cfg80211_security *sec;
1610 struct brcmf_wsec_key key; 1696 struct brcmf_wsec_key key;
1611 s32 val; 1697 s32 val;
1612 s32 err = 0; 1698 s32 err = 0;
1699 s32 bssidx;
1613 1700
1614 WL_CONN("key len (%d)\n", sme->key_len); 1701 WL_CONN("key len (%d)\n", sme->key_len);
1615 1702
1616 if (sme->key_len == 0) 1703 if (sme->key_len == 0)
1617 return 0; 1704 return 0;
1618 1705
1619 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1706 sec = &profile->sec;
1620 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n", 1707 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1621 sec->wpa_versions, sec->cipher_pairwise); 1708 sec->wpa_versions, sec->cipher_pairwise);
1622 1709
1623 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) 1710 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1624 return 0; 1711 return 0;
1625 1712
1626 if (sec->cipher_pairwise & 1713 if (!(sec->cipher_pairwise &
1627 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) { 1714 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1628 memset(&key, 0, sizeof(key)); 1715 return 0;
1629 key.len = (u32) sme->key_len;
1630 key.index = (u32) sme->key_idx;
1631 if (key.len > sizeof(key.data)) {
1632 WL_ERR("Too long key length (%u)\n", key.len);
1633 return -EINVAL;
1634 }
1635 memcpy(key.data, sme->key, key.len);
1636 key.flags = BRCMF_PRIMARY_KEY;
1637 switch (sec->cipher_pairwise) {
1638 case WLAN_CIPHER_SUITE_WEP40:
1639 key.algo = CRYPTO_ALGO_WEP1;
1640 break;
1641 case WLAN_CIPHER_SUITE_WEP104:
1642 key.algo = CRYPTO_ALGO_WEP128;
1643 break;
1644 default:
1645 WL_ERR("Invalid algorithm (%d)\n",
1646 sme->crypto.ciphers_pairwise[0]);
1647 return -EINVAL;
1648 }
1649 /* Set the new key/index */
1650 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1651 key.len, key.index, key.algo);
1652 WL_CONN("key \"%s\"\n", key.data);
1653 err = send_key_to_dongle(ndev, &key);
1654 if (err)
1655 return err;
1656 1716
1657 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { 1717 memset(&key, 0, sizeof(key));
1658 WL_CONN("set auth_type to shared key\n"); 1718 key.len = (u32) sme->key_len;
1659 val = 1; /* shared key */ 1719 key.index = (u32) sme->key_idx;
1660 err = brcmf_dev_intvar_set(ndev, "auth", val); 1720 if (key.len > sizeof(key.data)) {
1661 if (err) { 1721 WL_ERR("Too long key length (%u)\n", key.len);
1662 WL_ERR("set auth failed (%d)\n", err); 1722 return -EINVAL;
1663 return err; 1723 }
1664 } 1724 memcpy(key.data, sme->key, key.len);
1665 } 1725 key.flags = BRCMF_PRIMARY_KEY;
1726 switch (sec->cipher_pairwise) {
1727 case WLAN_CIPHER_SUITE_WEP40:
1728 key.algo = CRYPTO_ALGO_WEP1;
1729 break;
1730 case WLAN_CIPHER_SUITE_WEP104:
1731 key.algo = CRYPTO_ALGO_WEP128;
1732 break;
1733 default:
1734 WL_ERR("Invalid algorithm (%d)\n",
1735 sme->crypto.ciphers_pairwise[0]);
1736 return -EINVAL;
1737 }
1738 /* Set the new key/index */
1739 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1740 key.len, key.index, key.algo);
1741 WL_CONN("key \"%s\"\n", key.data);
1742 bssidx = brcmf_find_bssidx(cfg, ndev);
1743 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1744 if (err)
1745 return err;
1746
1747 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1748 WL_CONN("set auth_type to shared key\n");
1749 val = WL_AUTH_SHARED_KEY; /* shared key */
1750 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx);
1751 if (err)
1752 WL_ERR("set auth failed (%d)\n", err);
1666 } 1753 }
1667 return err; 1754 return err;
1668} 1755}
@@ -1671,7 +1758,8 @@ static s32
1671brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, 1758brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1672 struct cfg80211_connect_params *sme) 1759 struct cfg80211_connect_params *sme)
1673{ 1760{
1674 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1761 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1762 struct brcmf_cfg80211_profile *profile = cfg->profile;
1675 struct ieee80211_channel *chan = sme->channel; 1763 struct ieee80211_channel *chan = sme->channel;
1676 struct brcmf_join_params join_params; 1764 struct brcmf_join_params join_params;
1677 size_t join_params_size; 1765 size_t join_params_size;
@@ -1688,15 +1776,15 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1688 return -EOPNOTSUPP; 1776 return -EOPNOTSUPP;
1689 } 1777 }
1690 1778
1691 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1779 set_bit(WL_STATUS_CONNECTING, &cfg->status);
1692 1780
1693 if (chan) { 1781 if (chan) {
1694 cfg_priv->channel = 1782 cfg->channel =
1695 ieee80211_frequency_to_channel(chan->center_freq); 1783 ieee80211_frequency_to_channel(chan->center_freq);
1696 WL_CONN("channel (%d), center_req (%d)\n", 1784 WL_CONN("channel (%d), center_req (%d)\n",
1697 cfg_priv->channel, chan->center_freq); 1785 cfg->channel, chan->center_freq);
1698 } else 1786 } else
1699 cfg_priv->channel = 0; 1787 cfg->channel = 0;
1700 1788
1701 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); 1789 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1702 1790
@@ -1724,20 +1812,20 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1724 goto done; 1812 goto done;
1725 } 1813 }
1726 1814
1727 err = brcmf_set_wep_sharedkey(ndev, sme); 1815 err = brcmf_set_sharedkey(ndev, sme);
1728 if (err) { 1816 if (err) {
1729 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err); 1817 WL_ERR("brcmf_set_sharedkey failed (%d)\n", err);
1730 goto done; 1818 goto done;
1731 } 1819 }
1732 1820
1733 memset(&join_params, 0, sizeof(join_params)); 1821 memset(&join_params, 0, sizeof(join_params));
1734 join_params_size = sizeof(join_params.ssid_le); 1822 join_params_size = sizeof(join_params.ssid_le);
1735 1823
1736 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len); 1824 profile->ssid.SSID_len = min_t(u32,
1737 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len); 1825 sizeof(ssid.SSID), (u32)sme->ssid_len);
1738 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len); 1826 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1739 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len); 1827 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1740 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID); 1828 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1741 1829
1742 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); 1830 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1743 1831
@@ -1745,7 +1833,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1745 WL_CONN("ssid \"%s\", len (%d)\n", 1833 WL_CONN("ssid \"%s\", len (%d)\n",
1746 ssid.SSID, ssid.SSID_len); 1834 ssid.SSID, ssid.SSID_len);
1747 1835
1748 brcmf_ch_to_chanspec(cfg_priv->channel, 1836 brcmf_ch_to_chanspec(cfg->channel,
1749 &join_params, &join_params_size); 1837 &join_params, &join_params_size);
1750 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, 1838 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1751 &join_params, join_params_size); 1839 &join_params, join_params_size);
@@ -1754,7 +1842,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1754 1842
1755done: 1843done:
1756 if (err) 1844 if (err)
1757 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1845 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
1758 WL_TRACE("Exit\n"); 1846 WL_TRACE("Exit\n");
1759 return err; 1847 return err;
1760} 1848}
@@ -1763,7 +1851,8 @@ static s32
1763brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, 1851brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1764 u16 reason_code) 1852 u16 reason_code)
1765{ 1853{
1766 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1854 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1855 struct brcmf_cfg80211_profile *profile = cfg->profile;
1767 struct brcmf_scb_val_le scbval; 1856 struct brcmf_scb_val_le scbval;
1768 s32 err = 0; 1857 s32 err = 0;
1769 1858
@@ -1771,16 +1860,16 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1771 if (!check_sys_up(wiphy)) 1860 if (!check_sys_up(wiphy))
1772 return -EIO; 1861 return -EIO;
1773 1862
1774 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 1863 clear_bit(WL_STATUS_CONNECTED, &cfg->status);
1775 1864
1776 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN); 1865 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1777 scbval.val = cpu_to_le32(reason_code); 1866 scbval.val = cpu_to_le32(reason_code);
1778 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval, 1867 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1779 sizeof(struct brcmf_scb_val_le)); 1868 sizeof(struct brcmf_scb_val_le));
1780 if (err) 1869 if (err)
1781 WL_ERR("error (%d)\n", err); 1870 WL_ERR("error (%d)\n", err);
1782 1871
1783 cfg_priv->link_up = false; 1872 cfg->link_up = false;
1784 1873
1785 WL_TRACE("Exit\n"); 1874 WL_TRACE("Exit\n");
1786 return err; 1875 return err;
@@ -1791,8 +1880,8 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1791 enum nl80211_tx_power_setting type, s32 mbm) 1880 enum nl80211_tx_power_setting type, s32 mbm)
1792{ 1881{
1793 1882
1794 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1883 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1795 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1884 struct net_device *ndev = cfg_to_ndev(cfg);
1796 u16 txpwrmw; 1885 u16 txpwrmw;
1797 s32 err = 0; 1886 s32 err = 0;
1798 s32 disable = 0; 1887 s32 disable = 0;
@@ -1828,7 +1917,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1828 (s32) (brcmf_mw_to_qdbm(txpwrmw))); 1917 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1829 if (err) 1918 if (err)
1830 WL_ERR("qtxpower error (%d)\n", err); 1919 WL_ERR("qtxpower error (%d)\n", err);
1831 cfg_priv->conf->tx_power = dbm; 1920 cfg->conf->tx_power = dbm;
1832 1921
1833done: 1922done:
1834 WL_TRACE("Exit\n"); 1923 WL_TRACE("Exit\n");
@@ -1837,8 +1926,8 @@ done:
1837 1926
1838static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) 1927static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1839{ 1928{
1840 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1929 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1841 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1930 struct net_device *ndev = cfg_to_ndev(cfg);
1842 s32 txpwrdbm; 1931 s32 txpwrdbm;
1843 u8 result; 1932 u8 result;
1844 s32 err = 0; 1933 s32 err = 0;
@@ -1865,16 +1954,19 @@ static s32
1865brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, 1954brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1866 u8 key_idx, bool unicast, bool multicast) 1955 u8 key_idx, bool unicast, bool multicast)
1867{ 1956{
1957 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1868 u32 index; 1958 u32 index;
1869 u32 wsec; 1959 u32 wsec;
1870 s32 err = 0; 1960 s32 err = 0;
1961 s32 bssidx;
1871 1962
1872 WL_TRACE("Enter\n"); 1963 WL_TRACE("Enter\n");
1873 WL_CONN("key index (%d)\n", key_idx); 1964 WL_CONN("key index (%d)\n", key_idx);
1874 if (!check_sys_up(wiphy)) 1965 if (!check_sys_up(wiphy))
1875 return -EIO; 1966 return -EIO;
1876 1967
1877 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec); 1968 bssidx = brcmf_find_bssidx(cfg, ndev);
1969 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1878 if (err) { 1970 if (err) {
1879 WL_ERR("WLC_GET_WSEC error (%d)\n", err); 1971 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1880 goto done; 1972 goto done;
@@ -1897,9 +1989,11 @@ static s32
1897brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, 1989brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1898 u8 key_idx, const u8 *mac_addr, struct key_params *params) 1990 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1899{ 1991{
1992 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1900 struct brcmf_wsec_key key; 1993 struct brcmf_wsec_key key;
1901 struct brcmf_wsec_key_le key_le; 1994 struct brcmf_wsec_key_le key_le;
1902 s32 err = 0; 1995 s32 err = 0;
1996 s32 bssidx;
1903 1997
1904 memset(&key, 0, sizeof(key)); 1998 memset(&key, 0, sizeof(key));
1905 key.index = (u32) key_idx; 1999 key.index = (u32) key_idx;
@@ -1908,12 +2002,13 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1908 if (!is_multicast_ether_addr(mac_addr)) 2002 if (!is_multicast_ether_addr(mac_addr))
1909 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); 2003 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1910 key.len = (u32) params->key_len; 2004 key.len = (u32) params->key_len;
2005 bssidx = brcmf_find_bssidx(cfg, ndev);
1911 /* check for key index change */ 2006 /* check for key index change */
1912 if (key.len == 0) { 2007 if (key.len == 0) {
1913 /* key delete */ 2008 /* key delete */
1914 err = send_key_to_dongle(ndev, &key); 2009 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1915 if (err) 2010 if (err)
1916 return err; 2011 WL_ERR("key delete error (%d)\n", err);
1917 } else { 2012 } else {
1918 if (key.len > sizeof(key.data)) { 2013 if (key.len > sizeof(key.data)) {
1919 WL_ERR("Invalid key length (%d)\n", key.len); 2014 WL_ERR("Invalid key length (%d)\n", key.len);
@@ -1969,12 +2064,12 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1969 convert_key_from_CPU(&key, &key_le); 2064 convert_key_from_CPU(&key, &key_le);
1970 2065
1971 brcmf_netdev_wait_pend8021x(ndev); 2066 brcmf_netdev_wait_pend8021x(ndev);
1972 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, 2067 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
1973 sizeof(key_le)); 2068 sizeof(key_le),
1974 if (err) { 2069 cfg->extra_buf,
1975 WL_ERR("WLC_SET_KEY error (%d)\n", err); 2070 WL_EXTRA_BUF_MAX, bssidx);
1976 return err; 2071 if (err)
1977 } 2072 WL_ERR("wsec_key error (%d)\n", err);
1978 } 2073 }
1979 return err; 2074 return err;
1980} 2075}
@@ -1984,11 +2079,13 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1984 u8 key_idx, bool pairwise, const u8 *mac_addr, 2079 u8 key_idx, bool pairwise, const u8 *mac_addr,
1985 struct key_params *params) 2080 struct key_params *params)
1986{ 2081{
2082 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1987 struct brcmf_wsec_key key; 2083 struct brcmf_wsec_key key;
1988 s32 val; 2084 s32 val;
1989 s32 wsec; 2085 s32 wsec;
1990 s32 err = 0; 2086 s32 err = 0;
1991 u8 keybuf[8]; 2087 u8 keybuf[8];
2088 s32 bssidx;
1992 2089
1993 WL_TRACE("Enter\n"); 2090 WL_TRACE("Enter\n");
1994 WL_CONN("key index (%d)\n", key_idx); 2091 WL_CONN("key index (%d)\n", key_idx);
@@ -2015,25 +2112,33 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2015 switch (params->cipher) { 2112 switch (params->cipher) {
2016 case WLAN_CIPHER_SUITE_WEP40: 2113 case WLAN_CIPHER_SUITE_WEP40:
2017 key.algo = CRYPTO_ALGO_WEP1; 2114 key.algo = CRYPTO_ALGO_WEP1;
2115 val = WEP_ENABLED;
2018 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); 2116 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2019 break; 2117 break;
2020 case WLAN_CIPHER_SUITE_WEP104: 2118 case WLAN_CIPHER_SUITE_WEP104:
2021 key.algo = CRYPTO_ALGO_WEP128; 2119 key.algo = CRYPTO_ALGO_WEP128;
2120 val = WEP_ENABLED;
2022 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); 2121 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2023 break; 2122 break;
2024 case WLAN_CIPHER_SUITE_TKIP: 2123 case WLAN_CIPHER_SUITE_TKIP:
2025 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 2124 if (cfg->conf->mode != WL_MODE_AP) {
2026 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 2125 WL_CONN("Swapping key\n");
2027 memcpy(&key.data[16], keybuf, sizeof(keybuf)); 2126 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2127 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2128 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2129 }
2028 key.algo = CRYPTO_ALGO_TKIP; 2130 key.algo = CRYPTO_ALGO_TKIP;
2131 val = TKIP_ENABLED;
2029 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n"); 2132 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2030 break; 2133 break;
2031 case WLAN_CIPHER_SUITE_AES_CMAC: 2134 case WLAN_CIPHER_SUITE_AES_CMAC:
2032 key.algo = CRYPTO_ALGO_AES_CCM; 2135 key.algo = CRYPTO_ALGO_AES_CCM;
2136 val = AES_ENABLED;
2033 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n"); 2137 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2034 break; 2138 break;
2035 case WLAN_CIPHER_SUITE_CCMP: 2139 case WLAN_CIPHER_SUITE_CCMP:
2036 key.algo = CRYPTO_ALGO_AES_CCM; 2140 key.algo = CRYPTO_ALGO_AES_CCM;
2141 val = AES_ENABLED;
2037 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n"); 2142 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
2038 break; 2143 break;
2039 default: 2144 default:
@@ -2042,28 +2147,23 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2042 goto done; 2147 goto done;
2043 } 2148 }
2044 2149
2045 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */ 2150 bssidx = brcmf_find_bssidx(cfg, ndev);
2151 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
2046 if (err) 2152 if (err)
2047 goto done; 2153 goto done;
2048 2154
2049 val = WEP_ENABLED; 2155 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
2050 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
2051 if (err) { 2156 if (err) {
2052 WL_ERR("get wsec error (%d)\n", err); 2157 WL_ERR("get wsec error (%d)\n", err);
2053 goto done; 2158 goto done;
2054 } 2159 }
2055 wsec &= ~(WEP_ENABLED);
2056 wsec |= val; 2160 wsec |= val;
2057 err = brcmf_dev_intvar_set(ndev, "wsec", wsec); 2161 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
2058 if (err) { 2162 if (err) {
2059 WL_ERR("set wsec error (%d)\n", err); 2163 WL_ERR("set wsec error (%d)\n", err);
2060 goto done; 2164 goto done;
2061 } 2165 }
2062 2166
2063 val = 1; /* assume shared key. otherwise 0 */
2064 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
2065 if (err)
2066 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
2067done: 2167done:
2068 WL_TRACE("Exit\n"); 2168 WL_TRACE("Exit\n");
2069 return err; 2169 return err;
@@ -2073,10 +2173,10 @@ static s32
2073brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, 2173brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2074 u8 key_idx, bool pairwise, const u8 *mac_addr) 2174 u8 key_idx, bool pairwise, const u8 *mac_addr)
2075{ 2175{
2176 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2076 struct brcmf_wsec_key key; 2177 struct brcmf_wsec_key key;
2077 s32 err = 0; 2178 s32 err = 0;
2078 s32 val; 2179 s32 bssidx;
2079 s32 wsec;
2080 2180
2081 WL_TRACE("Enter\n"); 2181 WL_TRACE("Enter\n");
2082 if (!check_sys_up(wiphy)) 2182 if (!check_sys_up(wiphy))
@@ -2091,7 +2191,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2091 WL_CONN("key index (%d)\n", key_idx); 2191 WL_CONN("key index (%d)\n", key_idx);
2092 2192
2093 /* Set the new key/index */ 2193 /* Set the new key/index */
2094 err = send_key_to_dongle(ndev, &key); 2194 bssidx = brcmf_find_bssidx(cfg, ndev);
2195 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
2095 if (err) { 2196 if (err) {
2096 if (err == -EINVAL) { 2197 if (err == -EINVAL) {
2097 if (key.index >= DOT11_MAX_DEFAULT_KEYS) 2198 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
@@ -2100,35 +2201,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2100 } 2201 }
2101 /* Ignore this error, may happen during DISASSOC */ 2202 /* Ignore this error, may happen during DISASSOC */
2102 err = -EAGAIN; 2203 err = -EAGAIN;
2103 goto done;
2104 }
2105
2106 val = 0;
2107 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
2108 if (err) {
2109 WL_ERR("get wsec error (%d)\n", err);
2110 /* Ignore this error, may happen during DISASSOC */
2111 err = -EAGAIN;
2112 goto done;
2113 }
2114 wsec &= ~(WEP_ENABLED);
2115 wsec |= val;
2116 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
2117 if (err) {
2118 WL_ERR("set wsec error (%d)\n", err);
2119 /* Ignore this error, may happen during DISASSOC */
2120 err = -EAGAIN;
2121 goto done;
2122 } 2204 }
2123 2205
2124 val = 0; /* assume open key. otherwise 1 */
2125 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
2126 if (err) {
2127 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
2128 /* Ignore this error, may happen during DISASSOC */
2129 err = -EAGAIN;
2130 }
2131done:
2132 WL_TRACE("Exit\n"); 2206 WL_TRACE("Exit\n");
2133 return err; 2207 return err;
2134} 2208}
@@ -2139,10 +2213,12 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2139 void (*callback) (void *cookie, struct key_params * params)) 2213 void (*callback) (void *cookie, struct key_params * params))
2140{ 2214{
2141 struct key_params params; 2215 struct key_params params;
2142 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2216 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2217 struct brcmf_cfg80211_profile *profile = cfg->profile;
2143 struct brcmf_cfg80211_security *sec; 2218 struct brcmf_cfg80211_security *sec;
2144 s32 wsec; 2219 s32 wsec;
2145 s32 err = 0; 2220 s32 err = 0;
2221 s32 bssidx;
2146 2222
2147 WL_TRACE("Enter\n"); 2223 WL_TRACE("Enter\n");
2148 WL_CONN("key index (%d)\n", key_idx); 2224 WL_CONN("key index (%d)\n", key_idx);
@@ -2151,16 +2227,17 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2151 2227
2152 memset(&params, 0, sizeof(params)); 2228 memset(&params, 0, sizeof(params));
2153 2229
2154 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec); 2230 bssidx = brcmf_find_bssidx(cfg, ndev);
2231 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
2155 if (err) { 2232 if (err) {
2156 WL_ERR("WLC_GET_WSEC error (%d)\n", err); 2233 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
2157 /* Ignore this error, may happen during DISASSOC */ 2234 /* Ignore this error, may happen during DISASSOC */
2158 err = -EAGAIN; 2235 err = -EAGAIN;
2159 goto done; 2236 goto done;
2160 } 2237 }
2161 switch (wsec) { 2238 switch (wsec & ~SES_OW_ENABLED) {
2162 case WEP_ENABLED: 2239 case WEP_ENABLED:
2163 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 2240 sec = &profile->sec;
2164 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { 2241 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2165 params.cipher = WLAN_CIPHER_SUITE_WEP40; 2242 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2166 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); 2243 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
@@ -2200,53 +2277,73 @@ brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2200 2277
2201static s32 2278static s32
2202brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, 2279brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2203 u8 *mac, struct station_info *sinfo) 2280 u8 *mac, struct station_info *sinfo)
2204{ 2281{
2205 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2282 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2283 struct brcmf_cfg80211_profile *profile = cfg->profile;
2206 struct brcmf_scb_val_le scb_val; 2284 struct brcmf_scb_val_le scb_val;
2207 int rssi; 2285 int rssi;
2208 s32 rate; 2286 s32 rate;
2209 s32 err = 0; 2287 s32 err = 0;
2210 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID); 2288 u8 *bssid = profile->bssid;
2289 struct brcmf_sta_info_le *sta_info_le;
2211 2290
2212 WL_TRACE("Enter\n"); 2291 WL_TRACE("Enter, MAC %pM\n", mac);
2213 if (!check_sys_up(wiphy)) 2292 if (!check_sys_up(wiphy))
2214 return -EIO; 2293 return -EIO;
2215 2294
2216 if (memcmp(mac, bssid, ETH_ALEN)) { 2295 if (cfg->conf->mode == WL_MODE_AP) {
2217 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X" 2296 err = brcmf_dev_iovar_getbuf(ndev, "sta_info", mac, ETH_ALEN,
2218 "wl_bssid-%X:%X:%X:%X:%X:%X\n", 2297 cfg->dcmd_buf,
2219 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], 2298 WL_DCMD_LEN_MAX);
2220 bssid[0], bssid[1], bssid[2], bssid[3], 2299 if (err < 0) {
2221 bssid[4], bssid[5]); 2300 WL_ERR("GET STA INFO failed, %d\n", err);
2222 err = -ENOENT; 2301 goto done;
2223 goto done; 2302 }
2224 } 2303 sta_info_le = (struct brcmf_sta_info_le *)cfg->dcmd_buf;
2225
2226 /* Report the current tx rate */
2227 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
2228 if (err) {
2229 WL_ERR("Could not get rate (%d)\n", err);
2230 } else {
2231 sinfo->filled |= STATION_INFO_TX_BITRATE;
2232 sinfo->txrate.legacy = rate * 5;
2233 WL_CONN("Rate %d Mbps\n", rate / 2);
2234 }
2235 2304
2236 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { 2305 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2237 memset(&scb_val, 0, sizeof(scb_val)); 2306 sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000;
2238 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, 2307 if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) {
2239 sizeof(struct brcmf_scb_val_le)); 2308 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2309 sinfo->connected_time = le32_to_cpu(sta_info_le->in);
2310 }
2311 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
2312 sinfo->inactive_time, sinfo->connected_time);
2313 } else if (cfg->conf->mode == WL_MODE_BSS) {
2314 if (memcmp(mac, bssid, ETH_ALEN)) {
2315 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2316 mac, bssid);
2317 err = -ENOENT;
2318 goto done;
2319 }
2320 /* Report the current tx rate */
2321 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
2240 if (err) { 2322 if (err) {
2241 WL_ERR("Could not get rssi (%d)\n", err); 2323 WL_ERR("Could not get rate (%d)\n", err);
2324 goto done;
2242 } else { 2325 } else {
2243 rssi = le32_to_cpu(scb_val.val); 2326 sinfo->filled |= STATION_INFO_TX_BITRATE;
2244 sinfo->filled |= STATION_INFO_SIGNAL; 2327 sinfo->txrate.legacy = rate * 5;
2245 sinfo->signal = rssi; 2328 WL_CONN("Rate %d Mbps\n", rate / 2);
2246 WL_CONN("RSSI %d dBm\n", rssi);
2247 } 2329 }
2248 }
2249 2330
2331 if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) {
2332 memset(&scb_val, 0, sizeof(scb_val));
2333 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
2334 sizeof(scb_val));
2335 if (err) {
2336 WL_ERR("Could not get rssi (%d)\n", err);
2337 goto done;
2338 } else {
2339 rssi = le32_to_cpu(scb_val.val);
2340 sinfo->filled |= STATION_INFO_SIGNAL;
2341 sinfo->signal = rssi;
2342 WL_CONN("RSSI %d dBm\n", rssi);
2343 }
2344 }
2345 } else
2346 err = -EPERM;
2250done: 2347done:
2251 WL_TRACE("Exit\n"); 2348 WL_TRACE("Exit\n");
2252 return err; 2349 return err;
@@ -2258,7 +2355,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2258{ 2355{
2259 s32 pm; 2356 s32 pm;
2260 s32 err = 0; 2357 s32 err = 0;
2261 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2358 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2262 2359
2263 WL_TRACE("Enter\n"); 2360 WL_TRACE("Enter\n");
2264 2361
@@ -2266,14 +2363,13 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2266 * Powersave enable/disable request is coming from the 2363 * Powersave enable/disable request is coming from the
2267 * cfg80211 even before the interface is up. In that 2364 * cfg80211 even before the interface is up. In that
2268 * scenario, driver will be storing the power save 2365 * scenario, driver will be storing the power save
2269 * preference in cfg_priv struct to apply this to 2366 * preference in cfg struct to apply this to
2270 * FW later while initializing the dongle 2367 * FW later while initializing the dongle
2271 */ 2368 */
2272 cfg_priv->pwr_save = enabled; 2369 cfg->pwr_save = enabled;
2273 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) { 2370 if (!test_bit(WL_STATUS_READY, &cfg->status)) {
2274 2371
2275 WL_INFO("Device is not ready," 2372 WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
2276 "storing the value in cfg_priv struct\n");
2277 goto done; 2373 goto done;
2278 } 2374 }
2279 2375
@@ -2351,10 +2447,10 @@ done:
2351 return err; 2447 return err;
2352} 2448}
2353 2449
2354static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, 2450static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2355 struct brcmf_bss_info_le *bi) 2451 struct brcmf_bss_info_le *bi)
2356{ 2452{
2357 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 2453 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2358 struct ieee80211_channel *notify_channel; 2454 struct ieee80211_channel *notify_channel;
2359 struct cfg80211_bss *bss; 2455 struct cfg80211_bss *bss;
2360 struct ieee80211_supported_band *band; 2456 struct ieee80211_supported_band *band;
@@ -2418,14 +2514,14 @@ next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2418 le32_to_cpu(bss->length)); 2514 le32_to_cpu(bss->length));
2419} 2515}
2420 2516
2421static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) 2517static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2422{ 2518{
2423 struct brcmf_scan_results *bss_list; 2519 struct brcmf_scan_results *bss_list;
2424 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */ 2520 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2425 s32 err = 0; 2521 s32 err = 0;
2426 int i; 2522 int i;
2427 2523
2428 bss_list = cfg_priv->bss_list; 2524 bss_list = cfg->bss_list;
2429 if (bss_list->version != BRCMF_BSS_INFO_VERSION) { 2525 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2430 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", 2526 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2431 bss_list->version); 2527 bss_list->version);
@@ -2434,17 +2530,17 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2434 WL_SCAN("scanned AP count (%d)\n", bss_list->count); 2530 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2435 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { 2531 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2436 bi = next_bss_le(bss_list, bi); 2532 bi = next_bss_le(bss_list, bi);
2437 err = brcmf_inform_single_bss(cfg_priv, bi); 2533 err = brcmf_inform_single_bss(cfg, bi);
2438 if (err) 2534 if (err)
2439 break; 2535 break;
2440 } 2536 }
2441 return err; 2537 return err;
2442} 2538}
2443 2539
2444static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, 2540static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2445 struct net_device *ndev, const u8 *bssid) 2541 struct net_device *ndev, const u8 *bssid)
2446{ 2542{
2447 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 2543 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2448 struct ieee80211_channel *notify_channel; 2544 struct ieee80211_channel *notify_channel;
2449 struct brcmf_bss_info_le *bi = NULL; 2545 struct brcmf_bss_info_le *bi = NULL;
2450 struct ieee80211_supported_band *band; 2546 struct ieee80211_supported_band *band;
@@ -2519,9 +2615,9 @@ CleanUp:
2519 return err; 2615 return err;
2520} 2616}
2521 2617
2522static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv) 2618static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg)
2523{ 2619{
2524 return cfg_priv->conf->mode == WL_MODE_IBSS; 2620 return cfg->conf->mode == WL_MODE_IBSS;
2525} 2621}
2526 2622
2527/* 2623/*
@@ -2538,22 +2634,62 @@ static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2538 totlen = buflen; 2634 totlen = buflen;
2539 2635
2540 /* find tagged parameter */ 2636 /* find tagged parameter */
2541 while (totlen >= 2) { 2637 while (totlen >= TLV_HDR_LEN) {
2542 int len = elt->len; 2638 int len = elt->len;
2543 2639
2544 /* validate remaining totlen */ 2640 /* validate remaining totlen */
2545 if ((elt->id == key) && (totlen >= (len + 2))) 2641 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2546 return elt; 2642 return elt;
2547 2643
2548 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2)); 2644 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2549 totlen -= (len + 2); 2645 totlen -= (len + TLV_HDR_LEN);
2646 }
2647
2648 return NULL;
2649}
2650
2651/* Is any of the tlvs the expected entry? If
2652 * not update the tlvs buffer pointer/length.
2653 */
2654static bool
2655brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2656 u8 *oui, u32 oui_len, u8 type)
2657{
2658 /* If the contents match the OUI and the type */
2659 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2660 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2661 type == ie[TLV_BODY_OFF + oui_len]) {
2662 return true;
2550 } 2663 }
2551 2664
2665 if (tlvs == NULL)
2666 return false;
2667 /* point to the next ie */
2668 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2669 /* calculate the length of the rest of the buffer */
2670 *tlvs_len -= (int)(ie - *tlvs);
2671 /* update the pointer to the start of the buffer */
2672 *tlvs = ie;
2673
2674 return false;
2675}
2676
2677struct brcmf_vs_tlv *
2678brcmf_find_wpaie(u8 *parse, u32 len)
2679{
2680 struct brcmf_tlv *ie;
2681
2682 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_WPA))) {
2683 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2684 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2685 return (struct brcmf_vs_tlv *)ie;
2686 }
2552 return NULL; 2687 return NULL;
2553} 2688}
2554 2689
2555static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) 2690static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2556{ 2691{
2692 struct brcmf_cfg80211_profile *profile = cfg->profile;
2557 struct brcmf_bss_info_le *bi; 2693 struct brcmf_bss_info_le *bi;
2558 struct brcmf_ssid *ssid; 2694 struct brcmf_ssid *ssid;
2559 struct brcmf_tlv *tim; 2695 struct brcmf_tlv *tim;
@@ -2564,21 +2700,21 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2564 s32 err = 0; 2700 s32 err = 0;
2565 2701
2566 WL_TRACE("Enter\n"); 2702 WL_TRACE("Enter\n");
2567 if (brcmf_is_ibssmode(cfg_priv)) 2703 if (brcmf_is_ibssmode(cfg))
2568 return err; 2704 return err;
2569 2705
2570 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID); 2706 ssid = &profile->ssid;
2571 2707
2572 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); 2708 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2573 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO, 2709 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_GET_BSS_INFO,
2574 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX); 2710 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2575 if (err) { 2711 if (err) {
2576 WL_ERR("Could not get bss info %d\n", err); 2712 WL_ERR("Could not get bss info %d\n", err);
2577 goto update_bss_info_out; 2713 goto update_bss_info_out;
2578 } 2714 }
2579 2715
2580 bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4); 2716 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2581 err = brcmf_inform_single_bss(cfg_priv, bi); 2717 err = brcmf_inform_single_bss(cfg, bi);
2582 if (err) 2718 if (err)
2583 goto update_bss_info_out; 2719 goto update_bss_info_out;
2584 2720
@@ -2596,7 +2732,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2596 * so we speficially query dtim information to dongle. 2732 * so we speficially query dtim information to dongle.
2597 */ 2733 */
2598 u32 var; 2734 u32 var;
2599 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv), 2735 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg),
2600 "dtim_assoc", &var); 2736 "dtim_assoc", &var);
2601 if (err) { 2737 if (err) {
2602 WL_ERR("wl dtim_assoc failed (%d)\n", err); 2738 WL_ERR("wl dtim_assoc failed (%d)\n", err);
@@ -2605,22 +2741,22 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2605 dtim_period = (u8)var; 2741 dtim_period = (u8)var;
2606 } 2742 }
2607 2743
2608 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT); 2744 profile->beacon_interval = beacon_interval;
2609 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD); 2745 profile->dtim_period = dtim_period;
2610 2746
2611update_bss_info_out: 2747update_bss_info_out:
2612 WL_TRACE("Exit"); 2748 WL_TRACE("Exit");
2613 return err; 2749 return err;
2614} 2750}
2615 2751
2616static void brcmf_abort_scanning(struct brcmf_cfg80211_priv *cfg_priv) 2752static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2617{ 2753{
2618 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2754 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2619 struct escan_info *escan = &cfg_priv->escan_info; 2755 struct escan_info *escan = &cfg->escan_info;
2620 struct brcmf_ssid ssid; 2756 struct brcmf_ssid ssid;
2621 2757
2622 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); 2758 set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
2623 if (cfg_priv->iscan_on) { 2759 if (cfg->iscan_on) {
2624 iscan->state = WL_ISCAN_STATE_IDLE; 2760 iscan->state = WL_ISCAN_STATE_IDLE;
2625 2761
2626 if (iscan->timer_on) { 2762 if (iscan->timer_on) {
@@ -2634,39 +2770,39 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_priv *cfg_priv)
2634 memset(&ssid, 0, sizeof(ssid)); 2770 memset(&ssid, 0, sizeof(ssid));
2635 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT); 2771 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2636 2772
2637 if (cfg_priv->scan_request) { 2773 if (cfg->scan_request) {
2638 /* Indidate scan abort to cfg80211 layer */ 2774 /* Indidate scan abort to cfg80211 layer */
2639 WL_INFO("Terminating scan in progress\n"); 2775 WL_INFO("Terminating scan in progress\n");
2640 cfg80211_scan_done(cfg_priv->scan_request, true); 2776 cfg80211_scan_done(cfg->scan_request, true);
2641 cfg_priv->scan_request = NULL; 2777 cfg->scan_request = NULL;
2642 } 2778 }
2643 } 2779 }
2644 if (cfg_priv->escan_on && cfg_priv->scan_request) { 2780 if (cfg->escan_on && cfg->scan_request) {
2645 escan->escan_state = WL_ESCAN_STATE_IDLE; 2781 escan->escan_state = WL_ESCAN_STATE_IDLE;
2646 brcmf_notify_escan_complete(cfg_priv, escan->ndev, true, true); 2782 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2647 } 2783 }
2648 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); 2784 clear_bit(WL_STATUS_SCANNING, &cfg->status);
2649 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); 2785 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
2650} 2786}
2651 2787
2652static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, 2788static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2653 bool aborted) 2789 bool aborted)
2654{ 2790{
2655 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); 2791 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2656 struct net_device *ndev = cfg_to_ndev(cfg_priv); 2792 struct net_device *ndev = cfg_to_ndev(cfg);
2657 2793
2658 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 2794 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
2659 WL_ERR("Scan complete while device not scanning\n"); 2795 WL_ERR("Scan complete while device not scanning\n");
2660 return; 2796 return;
2661 } 2797 }
2662 if (cfg_priv->scan_request) { 2798 if (cfg->scan_request) {
2663 WL_SCAN("ISCAN Completed scan: %s\n", 2799 WL_SCAN("ISCAN Completed scan: %s\n",
2664 aborted ? "Aborted" : "Done"); 2800 aborted ? "Aborted" : "Done");
2665 cfg80211_scan_done(cfg_priv->scan_request, aborted); 2801 cfg80211_scan_done(cfg->scan_request, aborted);
2666 brcmf_set_mpc(ndev, 1); 2802 brcmf_set_mpc(ndev, 1);
2667 cfg_priv->scan_request = NULL; 2803 cfg->scan_request = NULL;
2668 } 2804 }
2669 cfg_priv->iscan_kickstart = false; 2805 cfg->iscan_kickstart = false;
2670} 2806}
2671 2807
2672static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) 2808static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
@@ -2719,21 +2855,21 @@ brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2719 return err; 2855 return err;
2720} 2856}
2721 2857
2722static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv) 2858static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg)
2723{ 2859{
2724 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2860 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2725 s32 err = 0; 2861 s32 err = 0;
2726 2862
2727 iscan->state = WL_ISCAN_STATE_IDLE; 2863 iscan->state = WL_ISCAN_STATE_IDLE;
2728 brcmf_inform_bss(cfg_priv); 2864 brcmf_inform_bss(cfg);
2729 brcmf_notify_iscan_complete(iscan, false); 2865 brcmf_notify_iscan_complete(iscan, false);
2730 2866
2731 return err; 2867 return err;
2732} 2868}
2733 2869
2734static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv) 2870static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg)
2735{ 2871{
2736 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2872 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2737 s32 err = 0; 2873 s32 err = 0;
2738 2874
2739 /* Reschedule the timer */ 2875 /* Reschedule the timer */
@@ -2743,12 +2879,12 @@ static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2743 return err; 2879 return err;
2744} 2880}
2745 2881
2746static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv) 2882static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg)
2747{ 2883{
2748 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2884 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2749 s32 err = 0; 2885 s32 err = 0;
2750 2886
2751 brcmf_inform_bss(cfg_priv); 2887 brcmf_inform_bss(cfg);
2752 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE); 2888 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2753 /* Reschedule the timer */ 2889 /* Reschedule the timer */
2754 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); 2890 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
@@ -2757,9 +2893,9 @@ static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2757 return err; 2893 return err;
2758} 2894}
2759 2895
2760static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv) 2896static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg)
2761{ 2897{
2762 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2898 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2763 s32 err = 0; 2899 s32 err = 0;
2764 2900
2765 iscan->state = WL_ISCAN_STATE_IDLE; 2901 iscan->state = WL_ISCAN_STATE_IDLE;
@@ -2773,7 +2909,7 @@ static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2773 struct brcmf_cfg80211_iscan_ctrl *iscan = 2909 struct brcmf_cfg80211_iscan_ctrl *iscan =
2774 container_of(work, struct brcmf_cfg80211_iscan_ctrl, 2910 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2775 work); 2911 work);
2776 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); 2912 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2777 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; 2913 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2778 u32 status = BRCMF_SCAN_RESULTS_PARTIAL; 2914 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2779 2915
@@ -2782,12 +2918,12 @@ static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2782 iscan->timer_on = 0; 2918 iscan->timer_on = 0;
2783 } 2919 }
2784 2920
2785 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) { 2921 if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) {
2786 status = BRCMF_SCAN_RESULTS_ABORTED; 2922 status = BRCMF_SCAN_RESULTS_ABORTED;
2787 WL_ERR("Abort iscan\n"); 2923 WL_ERR("Abort iscan\n");
2788 } 2924 }
2789 2925
2790 el->handler[status](cfg_priv); 2926 el->handler[status](cfg);
2791} 2927}
2792 2928
2793static void brcmf_iscan_timer(unsigned long data) 2929static void brcmf_iscan_timer(unsigned long data)
@@ -2802,11 +2938,11 @@ static void brcmf_iscan_timer(unsigned long data)
2802 } 2938 }
2803} 2939}
2804 2940
2805static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv) 2941static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg)
2806{ 2942{
2807 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2943 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2808 2944
2809 if (cfg_priv->iscan_on) { 2945 if (cfg->iscan_on) {
2810 iscan->state = WL_ISCAN_STATE_IDLE; 2946 iscan->state = WL_ISCAN_STATE_IDLE;
2811 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler); 2947 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2812 } 2948 }
@@ -2824,21 +2960,21 @@ static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2824 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted; 2960 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2825} 2961}
2826 2962
2827static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv) 2963static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg)
2828{ 2964{
2829 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2965 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2830 int err = 0; 2966 int err = 0;
2831 2967
2832 if (cfg_priv->iscan_on) { 2968 if (cfg->iscan_on) {
2833 iscan->ndev = cfg_to_ndev(cfg_priv); 2969 iscan->ndev = cfg_to_ndev(cfg);
2834 brcmf_init_iscan_eloop(&iscan->el); 2970 brcmf_init_iscan_eloop(&iscan->el);
2835 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; 2971 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2836 init_timer(&iscan->timer); 2972 init_timer(&iscan->timer);
2837 iscan->timer.data = (unsigned long) iscan; 2973 iscan->timer.data = (unsigned long) iscan;
2838 iscan->timer.function = brcmf_iscan_timer; 2974 iscan->timer.function = brcmf_iscan_timer;
2839 err = brcmf_invoke_iscan(cfg_priv); 2975 err = brcmf_invoke_iscan(cfg);
2840 if (!err) 2976 if (!err)
2841 iscan->data = cfg_priv; 2977 iscan->data = cfg;
2842 } 2978 }
2843 2979
2844 return err; 2980 return err;
@@ -2846,23 +2982,23 @@ static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2846 2982
2847static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) 2983static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2848{ 2984{
2849 struct brcmf_cfg80211_priv *cfg_priv = 2985 struct brcmf_cfg80211_info *cfg =
2850 container_of(work, struct brcmf_cfg80211_priv, 2986 container_of(work, struct brcmf_cfg80211_info,
2851 escan_timeout_work); 2987 escan_timeout_work);
2852 2988
2853 brcmf_notify_escan_complete(cfg_priv, 2989 brcmf_notify_escan_complete(cfg,
2854 cfg_priv->escan_info.ndev, true, true); 2990 cfg->escan_info.ndev, true, true);
2855} 2991}
2856 2992
2857static void brcmf_escan_timeout(unsigned long data) 2993static void brcmf_escan_timeout(unsigned long data)
2858{ 2994{
2859 struct brcmf_cfg80211_priv *cfg_priv = 2995 struct brcmf_cfg80211_info *cfg =
2860 (struct brcmf_cfg80211_priv *)data; 2996 (struct brcmf_cfg80211_info *)data;
2861 2997
2862 if (cfg_priv->scan_request) { 2998 if (cfg->scan_request) {
2863 WL_ERR("timer expired\n"); 2999 WL_ERR("timer expired\n");
2864 if (cfg_priv->escan_on) 3000 if (cfg->escan_on)
2865 schedule_work(&cfg_priv->escan_timeout_work); 3001 schedule_work(&cfg->escan_timeout_work);
2866 } 3002 }
2867} 3003}
2868 3004
@@ -2899,7 +3035,7 @@ brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2899} 3035}
2900 3036
2901static s32 3037static s32
2902brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv, 3038brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
2903 struct net_device *ndev, 3039 struct net_device *ndev,
2904 const struct brcmf_event_msg *e, void *data) 3040 const struct brcmf_event_msg *e, void *data)
2905{ 3041{
@@ -2915,11 +3051,11 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv,
2915 3051
2916 status = be32_to_cpu(e->status); 3052 status = be32_to_cpu(e->status);
2917 3053
2918 if (!ndev || !cfg_priv->escan_on || 3054 if (!ndev || !cfg->escan_on ||
2919 !test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 3055 !test_bit(WL_STATUS_SCANNING, &cfg->status)) {
2920 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", 3056 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
2921 ndev, cfg_priv->escan_on, 3057 ndev, cfg->escan_on,
2922 !test_bit(WL_STATUS_SCANNING, &cfg_priv->status)); 3058 !test_bit(WL_STATUS_SCANNING, &cfg->status));
2923 return -EPERM; 3059 return -EPERM;
2924 } 3060 }
2925 3061
@@ -2930,7 +3066,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv,
2930 WL_ERR("Invalid escan result (NULL pointer)\n"); 3066 WL_ERR("Invalid escan result (NULL pointer)\n");
2931 goto exit; 3067 goto exit;
2932 } 3068 }
2933 if (!cfg_priv->scan_request) { 3069 if (!cfg->scan_request) {
2934 WL_SCAN("result without cfg80211 request\n"); 3070 WL_SCAN("result without cfg80211 request\n");
2935 goto exit; 3071 goto exit;
2936 } 3072 }
@@ -2950,7 +3086,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv,
2950 goto exit; 3086 goto exit;
2951 } 3087 }
2952 3088
2953 if (!(cfg_to_wiphy(cfg_priv)->interface_modes & 3089 if (!(cfg_to_wiphy(cfg)->interface_modes &
2954 BIT(NL80211_IFTYPE_ADHOC))) { 3090 BIT(NL80211_IFTYPE_ADHOC))) {
2955 if (le16_to_cpu(bss_info_le->capability) & 3091 if (le16_to_cpu(bss_info_le->capability) &
2956 WLAN_CAPABILITY_IBSS) { 3092 WLAN_CAPABILITY_IBSS) {
@@ -2960,7 +3096,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv,
2960 } 3096 }
2961 3097
2962 list = (struct brcmf_scan_results *) 3098 list = (struct brcmf_scan_results *)
2963 cfg_priv->escan_info.escan_buf; 3099 cfg->escan_info.escan_buf;
2964 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) { 3100 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2965 WL_ERR("Buffer is too small: ignoring\n"); 3101 WL_ERR("Buffer is too small: ignoring\n");
2966 goto exit; 3102 goto exit;
@@ -2973,19 +3109,19 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv,
2973 if (brcmf_compare_update_same_bss(bss, bss_info_le)) 3109 if (brcmf_compare_update_same_bss(bss, bss_info_le))
2974 goto exit; 3110 goto exit;
2975 } 3111 }
2976 memcpy(&(cfg_priv->escan_info.escan_buf[list->buflen]), 3112 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2977 bss_info_le, bi_length); 3113 bss_info_le, bi_length);
2978 list->version = le32_to_cpu(bss_info_le->version); 3114 list->version = le32_to_cpu(bss_info_le->version);
2979 list->buflen += bi_length; 3115 list->buflen += bi_length;
2980 list->count++; 3116 list->count++;
2981 } else { 3117 } else {
2982 cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_IDLE; 3118 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2983 if (cfg_priv->scan_request) { 3119 if (cfg->scan_request) {
2984 cfg_priv->bss_list = (struct brcmf_scan_results *) 3120 cfg->bss_list = (struct brcmf_scan_results *)
2985 cfg_priv->escan_info.escan_buf; 3121 cfg->escan_info.escan_buf;
2986 brcmf_inform_bss(cfg_priv); 3122 brcmf_inform_bss(cfg);
2987 aborted = status != BRCMF_E_STATUS_SUCCESS; 3123 aborted = status != BRCMF_E_STATUS_SUCCESS;
2988 brcmf_notify_escan_complete(cfg_priv, ndev, aborted, 3124 brcmf_notify_escan_complete(cfg, ndev, aborted,
2989 false); 3125 false);
2990 } else 3126 } else
2991 WL_ERR("Unexpected scan result 0x%x\n", status); 3127 WL_ERR("Unexpected scan result 0x%x\n", status);
@@ -2994,18 +3130,18 @@ exit:
2994 return err; 3130 return err;
2995} 3131}
2996 3132
2997static void brcmf_init_escan(struct brcmf_cfg80211_priv *cfg_priv) 3133static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2998{ 3134{
2999 3135
3000 if (cfg_priv->escan_on) { 3136 if (cfg->escan_on) {
3001 cfg_priv->el.handler[BRCMF_E_ESCAN_RESULT] = 3137 cfg->el.handler[BRCMF_E_ESCAN_RESULT] =
3002 brcmf_cfg80211_escan_handler; 3138 brcmf_cfg80211_escan_handler;
3003 cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_IDLE; 3139 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3004 /* Init scan_timeout timer */ 3140 /* Init scan_timeout timer */
3005 init_timer(&cfg_priv->escan_timeout); 3141 init_timer(&cfg->escan_timeout);
3006 cfg_priv->escan_timeout.data = (unsigned long) cfg_priv; 3142 cfg->escan_timeout.data = (unsigned long) cfg;
3007 cfg_priv->escan_timeout.function = brcmf_escan_timeout; 3143 cfg->escan_timeout.function = brcmf_escan_timeout;
3008 INIT_WORK(&cfg_priv->escan_timeout_work, 3144 INIT_WORK(&cfg->escan_timeout_work,
3009 brcmf_cfg80211_escan_timeout_worker); 3145 brcmf_cfg80211_escan_timeout_worker);
3010 } 3146 }
3011} 3147}
@@ -3022,7 +3158,7 @@ static __always_inline void brcmf_delay(u32 ms)
3022 3158
3023static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) 3159static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3024{ 3160{
3025 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3161 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3026 3162
3027 /* 3163 /*
3028 * Check for WL_STATUS_READY before any function call which 3164 * Check for WL_STATUS_READY before any function call which
@@ -3031,7 +3167,7 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3031 */ 3167 */
3032 WL_TRACE("Enter\n"); 3168 WL_TRACE("Enter\n");
3033 3169
3034 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) 3170 if (test_bit(WL_STATUS_READY, &cfg->status))
3035 brcmf_invoke_iscan(wiphy_to_cfg(wiphy)); 3171 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
3036 3172
3037 WL_TRACE("Exit\n"); 3173 WL_TRACE("Exit\n");
@@ -3041,8 +3177,8 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3041static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, 3177static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3042 struct cfg80211_wowlan *wow) 3178 struct cfg80211_wowlan *wow)
3043{ 3179{
3044 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3180 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3045 struct net_device *ndev = cfg_to_ndev(cfg_priv); 3181 struct net_device *ndev = cfg_to_ndev(cfg);
3046 3182
3047 WL_TRACE("Enter\n"); 3183 WL_TRACE("Enter\n");
3048 3184
@@ -3056,12 +3192,12 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3056 * While going to suspend if associated with AP disassociate 3192 * While going to suspend if associated with AP disassociate
3057 * from AP to save power while system is in suspended state 3193 * from AP to save power while system is in suspended state
3058 */ 3194 */
3059 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) || 3195 if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
3060 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) && 3196 test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
3061 test_bit(WL_STATUS_READY, &cfg_priv->status)) { 3197 test_bit(WL_STATUS_READY, &cfg->status)) {
3062 WL_INFO("Disassociating from AP" 3198 WL_INFO("Disassociating from AP"
3063 " while entering suspend state\n"); 3199 " while entering suspend state\n");
3064 brcmf_link_down(cfg_priv); 3200 brcmf_link_down(cfg);
3065 3201
3066 /* 3202 /*
3067 * Make sure WPA_Supplicant receives all the event 3203 * Make sure WPA_Supplicant receives all the event
@@ -3071,13 +3207,13 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3071 brcmf_delay(500); 3207 brcmf_delay(500);
3072 } 3208 }
3073 3209
3074 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) 3210 if (test_bit(WL_STATUS_READY, &cfg->status))
3075 brcmf_abort_scanning(cfg_priv); 3211 brcmf_abort_scanning(cfg);
3076 else 3212 else
3077 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); 3213 clear_bit(WL_STATUS_SCANNING, &cfg->status);
3078 3214
3079 /* Turn off watchdog timer */ 3215 /* Turn off watchdog timer */
3080 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) 3216 if (test_bit(WL_STATUS_READY, &cfg->status))
3081 brcmf_set_mpc(ndev, 1); 3217 brcmf_set_mpc(ndev, 1);
3082 3218
3083 WL_TRACE("Exit\n"); 3219 WL_TRACE("Exit\n");
@@ -3088,14 +3224,14 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3088static __used s32 3224static __used s32
3089brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len) 3225brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
3090{ 3226{
3091 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 3227 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
3092 u32 buflen; 3228 u32 buflen;
3093 3229
3094 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf, 3230 buflen = brcmf_c_mkiovar(name, buf, len, cfg->dcmd_buf,
3095 WL_DCMD_LEN_MAX); 3231 WL_DCMD_LEN_MAX);
3096 BUG_ON(!buflen); 3232 BUG_ON(!buflen);
3097 3233
3098 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf, 3234 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg->dcmd_buf,
3099 buflen); 3235 buflen);
3100} 3236}
3101 3237
@@ -3103,20 +3239,20 @@ static s32
3103brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf, 3239brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
3104 s32 buf_len) 3240 s32 buf_len)
3105{ 3241{
3106 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 3242 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
3107 u32 len; 3243 u32 len;
3108 s32 err = 0; 3244 s32 err = 0;
3109 3245
3110 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf, 3246 len = brcmf_c_mkiovar(name, NULL, 0, cfg->dcmd_buf,
3111 WL_DCMD_LEN_MAX); 3247 WL_DCMD_LEN_MAX);
3112 BUG_ON(!len); 3248 BUG_ON(!len);
3113 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf, 3249 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg->dcmd_buf,
3114 WL_DCMD_LEN_MAX); 3250 WL_DCMD_LEN_MAX);
3115 if (err) { 3251 if (err) {
3116 WL_ERR("error (%d)\n", err); 3252 WL_ERR("error (%d)\n", err);
3117 return err; 3253 return err;
3118 } 3254 }
3119 memcpy(buf, cfg_priv->dcmd_buf, buf_len); 3255 memcpy(buf, cfg->dcmd_buf, buf_len);
3120 3256
3121 return err; 3257 return err;
3122} 3258}
@@ -3149,8 +3285,8 @@ static s32
3149brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, 3285brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3150 struct cfg80211_pmksa *pmksa) 3286 struct cfg80211_pmksa *pmksa)
3151{ 3287{
3152 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3288 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3153 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids; 3289 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
3154 s32 err = 0; 3290 s32 err = 0;
3155 int i; 3291 int i;
3156 int pmkid_len; 3292 int pmkid_len;
@@ -3178,7 +3314,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3178 for (i = 0; i < WLAN_PMKID_LEN; i++) 3314 for (i = 0; i < WLAN_PMKID_LEN; i++)
3179 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]); 3315 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3180 3316
3181 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3317 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3182 3318
3183 WL_TRACE("Exit\n"); 3319 WL_TRACE("Exit\n");
3184 return err; 3320 return err;
@@ -3188,7 +3324,7 @@ static s32
3188brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, 3324brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3189 struct cfg80211_pmksa *pmksa) 3325 struct cfg80211_pmksa *pmksa)
3190{ 3326{
3191 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3327 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3192 struct pmkid_list pmkid; 3328 struct pmkid_list pmkid;
3193 s32 err = 0; 3329 s32 err = 0;
3194 int i, pmkid_len; 3330 int i, pmkid_len;
@@ -3205,30 +3341,30 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3205 for (i = 0; i < WLAN_PMKID_LEN; i++) 3341 for (i = 0; i < WLAN_PMKID_LEN; i++)
3206 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]); 3342 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
3207 3343
3208 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid); 3344 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
3209 for (i = 0; i < pmkid_len; i++) 3345 for (i = 0; i < pmkid_len; i++)
3210 if (!memcmp 3346 if (!memcmp
3211 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, 3347 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
3212 ETH_ALEN)) 3348 ETH_ALEN))
3213 break; 3349 break;
3214 3350
3215 if ((pmkid_len > 0) 3351 if ((pmkid_len > 0)
3216 && (i < pmkid_len)) { 3352 && (i < pmkid_len)) {
3217 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0, 3353 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
3218 sizeof(struct pmkid)); 3354 sizeof(struct pmkid));
3219 for (; i < (pmkid_len - 1); i++) { 3355 for (; i < (pmkid_len - 1); i++) {
3220 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, 3356 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
3221 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID, 3357 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
3222 ETH_ALEN); 3358 ETH_ALEN);
3223 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID, 3359 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
3224 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID, 3360 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
3225 WLAN_PMKID_LEN); 3361 WLAN_PMKID_LEN);
3226 } 3362 }
3227 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1); 3363 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3228 } else 3364 } else
3229 err = -EINVAL; 3365 err = -EINVAL;
3230 3366
3231 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3367 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3232 3368
3233 WL_TRACE("Exit\n"); 3369 WL_TRACE("Exit\n");
3234 return err; 3370 return err;
@@ -3238,15 +3374,15 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3238static s32 3374static s32
3239brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) 3375brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3240{ 3376{
3241 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3377 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3242 s32 err = 0; 3378 s32 err = 0;
3243 3379
3244 WL_TRACE("Enter\n"); 3380 WL_TRACE("Enter\n");
3245 if (!check_sys_up(wiphy)) 3381 if (!check_sys_up(wiphy))
3246 return -EIO; 3382 return -EIO;
3247 3383
3248 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list)); 3384 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
3249 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3385 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3250 3386
3251 WL_TRACE("Exit\n"); 3387 WL_TRACE("Exit\n");
3252 return err; 3388 return err;
@@ -3262,7 +3398,7 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3262 * cfg80211_scan_request one out of the received PNO event. 3398 * cfg80211_scan_request one out of the received PNO event.
3263 */ 3399 */
3264static s32 3400static s32
3265brcmf_notify_sched_scan_results(struct brcmf_cfg80211_priv *cfg_priv, 3401brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
3266 struct net_device *ndev, 3402 struct net_device *ndev,
3267 const struct brcmf_event_msg *e, void *data) 3403 const struct brcmf_event_msg *e, void *data)
3268{ 3404{
@@ -3270,7 +3406,7 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_priv *cfg_priv,
3270 struct cfg80211_scan_request *request = NULL; 3406 struct cfg80211_scan_request *request = NULL;
3271 struct cfg80211_ssid *ssid = NULL; 3407 struct cfg80211_ssid *ssid = NULL;
3272 struct ieee80211_channel *channel = NULL; 3408 struct ieee80211_channel *channel = NULL;
3273 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 3409 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3274 int err = 0; 3410 int err = 0;
3275 int channel_req = 0; 3411 int channel_req = 0;
3276 int band = 0; 3412 int band = 0;
@@ -3299,8 +3435,8 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_priv *cfg_priv,
3299 int i; 3435 int i;
3300 3436
3301 request = kzalloc(sizeof(*request), GFP_KERNEL); 3437 request = kzalloc(sizeof(*request), GFP_KERNEL);
3302 ssid = kzalloc(sizeof(*ssid) * result_count, GFP_KERNEL); 3438 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3303 channel = kzalloc(sizeof(*channel) * result_count, GFP_KERNEL); 3439 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3304 if (!request || !ssid || !channel) { 3440 if (!request || !ssid || !channel) {
3305 err = -ENOMEM; 3441 err = -ENOMEM;
3306 goto out_err; 3442 goto out_err;
@@ -3342,19 +3478,19 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_priv *cfg_priv,
3342 if (request->n_ssids) 3478 if (request->n_ssids)
3343 request->ssids = &ssid[0]; 3479 request->ssids = &ssid[0];
3344 3480
3345 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 3481 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3346 /* Abort any on-going scan */ 3482 /* Abort any on-going scan */
3347 brcmf_abort_scanning(cfg_priv); 3483 brcmf_abort_scanning(cfg);
3348 } 3484 }
3349 3485
3350 set_bit(WL_STATUS_SCANNING, &cfg_priv->status); 3486 set_bit(WL_STATUS_SCANNING, &cfg->status);
3351 err = brcmf_do_escan(cfg_priv, wiphy, ndev, request); 3487 err = brcmf_do_escan(cfg, wiphy, ndev, request);
3352 if (err) { 3488 if (err) {
3353 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); 3489 clear_bit(WL_STATUS_SCANNING, &cfg->status);
3354 goto out_err; 3490 goto out_err;
3355 } 3491 }
3356 cfg_priv->sched_escan = true; 3492 cfg->sched_escan = true;
3357 cfg_priv->scan_request = request; 3493 cfg->scan_request = request;
3358 } else { 3494 } else {
3359 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n"); 3495 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
3360 goto out_err; 3496 goto out_err;
@@ -3419,15 +3555,15 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3419 struct cfg80211_sched_scan_request *request) 3555 struct cfg80211_sched_scan_request *request)
3420{ 3556{
3421 char iovbuf[128]; 3557 char iovbuf[128];
3422 struct brcmf_cfg80211_priv *cfg_priv = wiphy_priv(wiphy); 3558 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3423 struct brcmf_pno_net_param_le pfn; 3559 struct brcmf_pno_net_param_le pfn;
3424 int i; 3560 int i;
3425 int ret = 0; 3561 int ret = 0;
3426 3562
3427 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n", 3563 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
3428 request->n_match_sets, request->n_ssids); 3564 request->n_match_sets, request->n_ssids);
3429 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 3565 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3430 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status); 3566 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
3431 return -EAGAIN; 3567 return -EAGAIN;
3432 } 3568 }
3433 3569
@@ -3506,12 +3642,12 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3506static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, 3642static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3507 struct net_device *ndev) 3643 struct net_device *ndev)
3508{ 3644{
3509 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3645 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3510 3646
3511 WL_SCAN("enter\n"); 3647 WL_SCAN("enter\n");
3512 brcmf_dev_pno_clean(ndev); 3648 brcmf_dev_pno_clean(ndev);
3513 if (cfg_priv->sched_escan) 3649 if (cfg->sched_escan)
3514 brcmf_notify_escan_complete(cfg_priv, ndev, true, true); 3650 brcmf_notify_escan_complete(cfg, ndev, true, true);
3515 return 0; 3651 return 0;
3516} 3652}
3517#endif /* CONFIG_BRCMISCAN */ 3653#endif /* CONFIG_BRCMISCAN */
@@ -3519,8 +3655,8 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3519#ifdef CONFIG_NL80211_TESTMODE 3655#ifdef CONFIG_NL80211_TESTMODE
3520static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) 3656static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3521{ 3657{
3522 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3658 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3523 struct net_device *ndev = cfg_priv->wdev->netdev; 3659 struct net_device *ndev = cfg->wdev->netdev;
3524 struct brcmf_dcmd *dcmd = data; 3660 struct brcmf_dcmd *dcmd = data;
3525 struct sk_buff *reply; 3661 struct sk_buff *reply;
3526 int ret; 3662 int ret;
@@ -3535,6 +3671,682 @@ static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3535} 3671}
3536#endif 3672#endif
3537 3673
3674static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3675{
3676 s32 err;
3677
3678 /* set auth */
3679 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", 0, bssidx);
3680 if (err < 0) {
3681 WL_ERR("auth error %d\n", err);
3682 return err;
3683 }
3684 /* set wsec */
3685 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", 0, bssidx);
3686 if (err < 0) {
3687 WL_ERR("wsec error %d\n", err);
3688 return err;
3689 }
3690 /* set upper-layer auth */
3691 err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth",
3692 WPA_AUTH_NONE, bssidx);
3693 if (err < 0) {
3694 WL_ERR("wpa_auth error %d\n", err);
3695 return err;
3696 }
3697
3698 return 0;
3699}
3700
3701static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3702{
3703 if (is_rsn_ie)
3704 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3705
3706 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3707}
3708
3709static s32
3710brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3711 bool is_rsn_ie, s32 bssidx)
3712{
3713 u32 auth = 0; /* d11 open authentication */
3714 u16 count;
3715 s32 err = 0;
3716 s32 len = 0;
3717 u32 i;
3718 u32 wsec;
3719 u32 pval = 0;
3720 u32 gval = 0;
3721 u32 wpa_auth = 0;
3722 u32 offset;
3723 u8 *data;
3724 u16 rsn_cap;
3725 u32 wme_bss_disable;
3726
3727 WL_TRACE("Enter\n");
3728 if (wpa_ie == NULL)
3729 goto exit;
3730
3731 len = wpa_ie->len + TLV_HDR_LEN;
3732 data = (u8 *)wpa_ie;
3733 offset = 0;
3734 if (!is_rsn_ie)
3735 offset += VS_IE_FIXED_HDR_LEN;
3736 offset += WPA_IE_VERSION_LEN;
3737
3738 /* check for multicast cipher suite */
3739 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3740 err = -EINVAL;
3741 WL_ERR("no multicast cipher suite\n");
3742 goto exit;
3743 }
3744
3745 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3746 err = -EINVAL;
3747 WL_ERR("ivalid OUI\n");
3748 goto exit;
3749 }
3750 offset += TLV_OUI_LEN;
3751
3752 /* pick up multicast cipher */
3753 switch (data[offset]) {
3754 case WPA_CIPHER_NONE:
3755 gval = 0;
3756 break;
3757 case WPA_CIPHER_WEP_40:
3758 case WPA_CIPHER_WEP_104:
3759 gval = WEP_ENABLED;
3760 break;
3761 case WPA_CIPHER_TKIP:
3762 gval = TKIP_ENABLED;
3763 break;
3764 case WPA_CIPHER_AES_CCM:
3765 gval = AES_ENABLED;
3766 break;
3767 default:
3768 err = -EINVAL;
3769 WL_ERR("Invalid multi cast cipher info\n");
3770 goto exit;
3771 }
3772
3773 offset++;
3774 /* walk thru unicast cipher list and pick up what we recognize */
3775 count = data[offset] + (data[offset + 1] << 8);
3776 offset += WPA_IE_SUITE_COUNT_LEN;
3777 /* Check for unicast suite(s) */
3778 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3779 err = -EINVAL;
3780 WL_ERR("no unicast cipher suite\n");
3781 goto exit;
3782 }
3783 for (i = 0; i < count; i++) {
3784 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3785 err = -EINVAL;
3786 WL_ERR("ivalid OUI\n");
3787 goto exit;
3788 }
3789 offset += TLV_OUI_LEN;
3790 switch (data[offset]) {
3791 case WPA_CIPHER_NONE:
3792 break;
3793 case WPA_CIPHER_WEP_40:
3794 case WPA_CIPHER_WEP_104:
3795 pval |= WEP_ENABLED;
3796 break;
3797 case WPA_CIPHER_TKIP:
3798 pval |= TKIP_ENABLED;
3799 break;
3800 case WPA_CIPHER_AES_CCM:
3801 pval |= AES_ENABLED;
3802 break;
3803 default:
3804 WL_ERR("Ivalid unicast security info\n");
3805 }
3806 offset++;
3807 }
3808 /* walk thru auth management suite list and pick up what we recognize */
3809 count = data[offset] + (data[offset + 1] << 8);
3810 offset += WPA_IE_SUITE_COUNT_LEN;
3811 /* Check for auth key management suite(s) */
3812 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3813 err = -EINVAL;
3814 WL_ERR("no auth key mgmt suite\n");
3815 goto exit;
3816 }
3817 for (i = 0; i < count; i++) {
3818 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3819 err = -EINVAL;
3820 WL_ERR("ivalid OUI\n");
3821 goto exit;
3822 }
3823 offset += TLV_OUI_LEN;
3824 switch (data[offset]) {
3825 case RSN_AKM_NONE:
3826 WL_TRACE("RSN_AKM_NONE\n");
3827 wpa_auth |= WPA_AUTH_NONE;
3828 break;
3829 case RSN_AKM_UNSPECIFIED:
3830 WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3831 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3832 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3833 break;
3834 case RSN_AKM_PSK:
3835 WL_TRACE("RSN_AKM_PSK\n");
3836 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3837 (wpa_auth |= WPA_AUTH_PSK);
3838 break;
3839 default:
3840 WL_ERR("Ivalid key mgmt info\n");
3841 }
3842 offset++;
3843 }
3844
3845 if (is_rsn_ie) {
3846 wme_bss_disable = 1;
3847 if ((offset + RSN_CAP_LEN) <= len) {
3848 rsn_cap = data[offset] + (data[offset + 1] << 8);
3849 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3850 wme_bss_disable = 0;
3851 }
3852 /* set wme_bss_disable to sync RSN Capabilities */
3853 err = brcmf_dev_intvar_set_bsscfg(ndev, "wme_bss_disable",
3854 wme_bss_disable, bssidx);
3855 if (err < 0) {
3856 WL_ERR("wme_bss_disable error %d\n", err);
3857 goto exit;
3858 }
3859 }
3860 /* FOR WPS , set SES_OW_ENABLED */
3861 wsec = (pval | gval | SES_OW_ENABLED);
3862
3863 /* set auth */
3864 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", auth, bssidx);
3865 if (err < 0) {
3866 WL_ERR("auth error %d\n", err);
3867 goto exit;
3868 }
3869 /* set wsec */
3870 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
3871 if (err < 0) {
3872 WL_ERR("wsec error %d\n", err);
3873 goto exit;
3874 }
3875 /* set upper-layer auth */
3876 err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", wpa_auth, bssidx);
3877 if (err < 0) {
3878 WL_ERR("wpa_auth error %d\n", err);
3879 goto exit;
3880 }
3881
3882exit:
3883 return err;
3884}
3885
3886static s32
3887brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len,
3888 struct parsed_vndr_ies *vndr_ies)
3889{
3890 s32 err = 0;
3891 struct brcmf_vs_tlv *vndrie;
3892 struct brcmf_tlv *ie;
3893 struct parsed_vndr_ie_info *parsed_info;
3894 s32 remaining_len;
3895
3896 remaining_len = (s32)vndr_ie_len;
3897 memset(vndr_ies, 0, sizeof(*vndr_ies));
3898
3899 ie = (struct brcmf_tlv *)vndr_ie_buf;
3900 while (ie) {
3901 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3902 goto next;
3903 vndrie = (struct brcmf_vs_tlv *)ie;
3904 /* len should be bigger than OUI length + one */
3905 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3906 WL_ERR("invalid vndr ie. length is too small %d\n",
3907 vndrie->len);
3908 goto next;
3909 }
3910 /* if wpa or wme ie, do not add ie */
3911 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3912 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3913 (vndrie->oui_type == WME_OUI_TYPE))) {
3914 WL_TRACE("Found WPA/WME oui. Do not add it\n");
3915 goto next;
3916 }
3917
3918 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3919
3920 /* save vndr ie information */
3921 parsed_info->ie_ptr = (char *)vndrie;
3922 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3923 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3924
3925 vndr_ies->count++;
3926
3927 WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3928 parsed_info->vndrie.oui[0],
3929 parsed_info->vndrie.oui[1],
3930 parsed_info->vndrie.oui[2],
3931 parsed_info->vndrie.oui_type);
3932
3933 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3934 break;
3935next:
3936 remaining_len -= ie->len;
3937 if (remaining_len <= 2)
3938 ie = NULL;
3939 else
3940 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len);
3941 }
3942 return err;
3943}
3944
3945static u32
3946brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3947{
3948
3949 __le32 iecount_le;
3950 __le32 pktflag_le;
3951
3952 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3953 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3954
3955 iecount_le = cpu_to_le32(1);
3956 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3957
3958 pktflag_le = cpu_to_le32(pktflag);
3959 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3960
3961 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3962
3963 return ie_len + VNDR_IE_HDR_SIZE;
3964}
3965
3966s32
3967brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
3968 struct net_device *ndev, s32 bssidx, s32 pktflag,
3969 u8 *vndr_ie_buf, u32 vndr_ie_len)
3970{
3971 s32 err = 0;
3972 u8 *iovar_ie_buf;
3973 u8 *curr_ie_buf;
3974 u8 *mgmt_ie_buf = NULL;
3975 u32 mgmt_ie_buf_len = 0;
3976 u32 *mgmt_ie_len = 0;
3977 u32 del_add_ie_buf_len = 0;
3978 u32 total_ie_buf_len = 0;
3979 u32 parsed_ie_buf_len = 0;
3980 struct parsed_vndr_ies old_vndr_ies;
3981 struct parsed_vndr_ies new_vndr_ies;
3982 struct parsed_vndr_ie_info *vndrie_info;
3983 s32 i;
3984 u8 *ptr;
3985 u32 remained_buf_len;
3986
3987 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag);
3988 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3989 if (!iovar_ie_buf)
3990 return -ENOMEM;
3991 curr_ie_buf = iovar_ie_buf;
3992 if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) ||
3993 test_bit(WL_STATUS_AP_CREATED, &cfg->status)) {
3994 switch (pktflag) {
3995 case VNDR_IE_PRBRSP_FLAG:
3996 mgmt_ie_buf = cfg->ap_info->probe_res_ie;
3997 mgmt_ie_len = &cfg->ap_info->probe_res_ie_len;
3998 mgmt_ie_buf_len =
3999 sizeof(cfg->ap_info->probe_res_ie);
4000 break;
4001 case VNDR_IE_BEACON_FLAG:
4002 mgmt_ie_buf = cfg->ap_info->beacon_ie;
4003 mgmt_ie_len = &cfg->ap_info->beacon_ie_len;
4004 mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie);
4005 break;
4006 default:
4007 err = -EPERM;
4008 WL_ERR("not suitable type\n");
4009 goto exit;
4010 }
4011 bssidx = 0;
4012 } else {
4013 err = -EPERM;
4014 WL_ERR("not suitable type\n");
4015 goto exit;
4016 }
4017
4018 if (vndr_ie_len > mgmt_ie_buf_len) {
4019 err = -ENOMEM;
4020 WL_ERR("extra IE size too big\n");
4021 goto exit;
4022 }
4023
4024 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4025 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4026 ptr = curr_ie_buf;
4027 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4028 for (i = 0; i < new_vndr_ies.count; i++) {
4029 vndrie_info = &new_vndr_ies.ie_info[i];
4030 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4031 vndrie_info->ie_len);
4032 parsed_ie_buf_len += vndrie_info->ie_len;
4033 }
4034 }
4035
4036 if (mgmt_ie_buf != NULL) {
4037 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4038 (memcmp(mgmt_ie_buf, curr_ie_buf,
4039 parsed_ie_buf_len) == 0)) {
4040 WL_TRACE("Previous mgmt IE is equals to current IE");
4041 goto exit;
4042 }
4043
4044 /* parse old vndr_ie */
4045 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4046
4047 /* make a command to delete old ie */
4048 for (i = 0; i < old_vndr_ies.count; i++) {
4049 vndrie_info = &old_vndr_ies.ie_info[i];
4050
4051 WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4052 vndrie_info->vndrie.id,
4053 vndrie_info->vndrie.len,
4054 vndrie_info->vndrie.oui[0],
4055 vndrie_info->vndrie.oui[1],
4056 vndrie_info->vndrie.oui[2]);
4057
4058 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4059 vndrie_info->ie_ptr,
4060 vndrie_info->ie_len,
4061 "del");
4062 curr_ie_buf += del_add_ie_buf_len;
4063 total_ie_buf_len += del_add_ie_buf_len;
4064 }
4065 }
4066
4067 *mgmt_ie_len = 0;
4068 /* Add if there is any extra IE */
4069 if (mgmt_ie_buf && parsed_ie_buf_len) {
4070 ptr = mgmt_ie_buf;
4071
4072 remained_buf_len = mgmt_ie_buf_len;
4073
4074 /* make a command to add new ie */
4075 for (i = 0; i < new_vndr_ies.count; i++) {
4076 vndrie_info = &new_vndr_ies.ie_info[i];
4077
4078 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4079 vndrie_info->vndrie.id,
4080 vndrie_info->vndrie.len,
4081 vndrie_info->vndrie.oui[0],
4082 vndrie_info->vndrie.oui[1],
4083 vndrie_info->vndrie.oui[2]);
4084
4085 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4086 vndrie_info->ie_ptr,
4087 vndrie_info->ie_len,
4088 "add");
4089 /* verify remained buf size before copy data */
4090 remained_buf_len -= vndrie_info->ie_len;
4091 if (remained_buf_len < 0) {
4092 WL_ERR("no space in mgmt_ie_buf: len left %d",
4093 remained_buf_len);
4094 break;
4095 }
4096
4097 /* save the parsed IE in wl struct */
4098 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4099 vndrie_info->ie_len);
4100 *mgmt_ie_len += vndrie_info->ie_len;
4101
4102 curr_ie_buf += del_add_ie_buf_len;
4103 total_ie_buf_len += del_add_ie_buf_len;
4104 }
4105 }
4106 if (total_ie_buf_len) {
4107 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "vndr_ie",
4108 iovar_ie_buf,
4109 total_ie_buf_len,
4110 cfg->extra_buf,
4111 WL_EXTRA_BUF_MAX, bssidx);
4112 if (err)
4113 WL_ERR("vndr ie set error : %d\n", err);
4114 }
4115
4116exit:
4117 kfree(iovar_ie_buf);
4118 return err;
4119}
4120
4121static s32
4122brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4123 struct cfg80211_ap_settings *settings)
4124{
4125 s32 ie_offset;
4126 struct brcmf_tlv *ssid_ie;
4127 struct brcmf_ssid_le ssid_le;
4128 s32 ioctl_value;
4129 s32 err = -EPERM;
4130 struct brcmf_tlv *rsn_ie;
4131 struct brcmf_vs_tlv *wpa_ie;
4132 struct brcmf_join_params join_params;
4133 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4134 s32 bssidx = 0;
4135
4136 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
4137 settings->channel_type, settings->beacon_interval,
4138 settings->dtim_period);
4139 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
4140 settings->ssid, settings->ssid_len, settings->auth_type,
4141 settings->inactivity_timeout);
4142
4143 if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) {
4144 WL_ERR("Not in AP creation mode\n");
4145 return -EPERM;
4146 }
4147
4148 memset(&ssid_le, 0, sizeof(ssid_le));
4149 if (settings->ssid == NULL || settings->ssid_len == 0) {
4150 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4151 ssid_ie = brcmf_parse_tlvs(
4152 (u8 *)&settings->beacon.head[ie_offset],
4153 settings->beacon.head_len - ie_offset,
4154 WLAN_EID_SSID);
4155 if (!ssid_ie)
4156 return -EINVAL;
4157
4158 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4159 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4160 WL_TRACE("SSID is (%s) in Head\n", ssid_le.SSID);
4161 } else {
4162 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4163 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4164 }
4165
4166 brcmf_set_mpc(ndev, 0);
4167 ioctl_value = 1;
4168 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_DOWN, &ioctl_value);
4169 if (err < 0) {
4170 WL_ERR("BRCMF_C_DOWN error %d\n", err);
4171 goto exit;
4172 }
4173 ioctl_value = 1;
4174 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &ioctl_value);
4175 if (err < 0) {
4176 WL_ERR("SET INFRA error %d\n", err);
4177 goto exit;
4178 }
4179 ioctl_value = 1;
4180 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4181 if (err < 0) {
4182 WL_ERR("setting AP mode failed %d\n", err);
4183 goto exit;
4184 }
4185
4186 /* find the RSN_IE */
4187 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4188 settings->beacon.tail_len, WLAN_EID_RSN);
4189
4190 /* find the WPA_IE */
4191 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4192 settings->beacon.tail_len);
4193
4194 kfree(cfg->ap_info->rsn_ie);
4195 cfg->ap_info->rsn_ie = NULL;
4196 kfree(cfg->ap_info->wpa_ie);
4197 cfg->ap_info->wpa_ie = NULL;
4198
4199 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4200 WL_TRACE("WPA(2) IE is found\n");
4201 if (wpa_ie != NULL) {
4202 /* WPA IE */
4203 err = brcmf_configure_wpaie(ndev, wpa_ie, false,
4204 bssidx);
4205 if (err < 0)
4206 goto exit;
4207 cfg->ap_info->wpa_ie = kmemdup(wpa_ie,
4208 wpa_ie->len +
4209 TLV_HDR_LEN,
4210 GFP_KERNEL);
4211 } else {
4212 /* RSN IE */
4213 err = brcmf_configure_wpaie(ndev,
4214 (struct brcmf_vs_tlv *)rsn_ie, true, bssidx);
4215 if (err < 0)
4216 goto exit;
4217 cfg->ap_info->rsn_ie = kmemdup(rsn_ie,
4218 rsn_ie->len +
4219 TLV_HDR_LEN,
4220 GFP_KERNEL);
4221 }
4222 cfg->ap_info->security_mode = true;
4223 } else {
4224 WL_TRACE("No WPA(2) IEs found\n");
4225 brcmf_configure_opensecurity(ndev, bssidx);
4226 cfg->ap_info->security_mode = false;
4227 }
4228 /* Set Beacon IEs to FW */
4229 err = brcmf_set_management_ie(cfg, ndev, bssidx,
4230 VNDR_IE_BEACON_FLAG,
4231 (u8 *)settings->beacon.tail,
4232 settings->beacon.tail_len);
4233 if (err)
4234 WL_ERR("Set Beacon IE Failed\n");
4235 else
4236 WL_TRACE("Applied Vndr IEs for Beacon\n");
4237
4238 /* Set Probe Response IEs to FW */
4239 err = brcmf_set_management_ie(cfg, ndev, bssidx,
4240 VNDR_IE_PRBRSP_FLAG,
4241 (u8 *)settings->beacon.proberesp_ies,
4242 settings->beacon.proberesp_ies_len);
4243 if (err)
4244 WL_ERR("Set Probe Resp IE Failed\n");
4245 else
4246 WL_TRACE("Applied Vndr IEs for Probe Resp\n");
4247
4248 if (settings->beacon_interval) {
4249 ioctl_value = settings->beacon_interval;
4250 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_BCNPRD,
4251 &ioctl_value);
4252 if (err < 0) {
4253 WL_ERR("Beacon Interval Set Error, %d\n", err);
4254 goto exit;
4255 }
4256 }
4257 if (settings->dtim_period) {
4258 ioctl_value = settings->dtim_period;
4259 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_DTIMPRD,
4260 &ioctl_value);
4261 if (err < 0) {
4262 WL_ERR("DTIM Interval Set Error, %d\n", err);
4263 goto exit;
4264 }
4265 }
4266 ioctl_value = 1;
4267 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4268 if (err < 0) {
4269 WL_ERR("BRCMF_C_UP error (%d)\n", err);
4270 goto exit;
4271 }
4272
4273 memset(&join_params, 0, sizeof(join_params));
4274 /* join parameters starts with ssid */
4275 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4276 /* create softap */
4277 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, &join_params,
4278 sizeof(join_params));
4279 if (err < 0) {
4280 WL_ERR("SET SSID error (%d)\n", err);
4281 goto exit;
4282 }
4283 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4284 set_bit(WL_STATUS_AP_CREATED, &cfg->status);
4285
4286exit:
4287 if (err)
4288 brcmf_set_mpc(ndev, 1);
4289 return err;
4290}
4291
4292static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4293{
4294 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4295 s32 ioctl_value;
4296 s32 err = -EPERM;
4297
4298 WL_TRACE("Enter\n");
4299
4300 if (cfg->conf->mode == WL_MODE_AP) {
4301 /* Due to most likely deauths outstanding we sleep */
4302 /* first to make sure they get processed by fw. */
4303 msleep(400);
4304 ioctl_value = 0;
4305 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4306 if (err < 0) {
4307 WL_ERR("setting AP mode failed %d\n", err);
4308 goto exit;
4309 }
4310 ioctl_value = 0;
4311 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4312 if (err < 0) {
4313 WL_ERR("BRCMF_C_UP error %d\n", err);
4314 goto exit;
4315 }
4316 brcmf_set_mpc(ndev, 1);
4317 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4318 clear_bit(WL_STATUS_AP_CREATED, &cfg->status);
4319 }
4320exit:
4321 return err;
4322}
4323
4324static int
4325brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4326 u8 *mac)
4327{
4328 struct brcmf_scb_val_le scbval;
4329 s32 err;
4330
4331 if (!mac)
4332 return -EFAULT;
4333
4334 WL_TRACE("Enter %pM\n", mac);
4335
4336 if (!check_sys_up(wiphy))
4337 return -EIO;
4338
4339 memcpy(&scbval.ea, mac, ETH_ALEN);
4340 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4341 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4342 &scbval, sizeof(scbval));
4343 if (err)
4344 WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4345
4346 WL_TRACE("Exit\n");
4347 return err;
4348}
4349
3538static struct cfg80211_ops wl_cfg80211_ops = { 4350static struct cfg80211_ops wl_cfg80211_ops = {
3539 .change_virtual_intf = brcmf_cfg80211_change_iface, 4351 .change_virtual_intf = brcmf_cfg80211_change_iface,
3540 .scan = brcmf_cfg80211_scan, 4352 .scan = brcmf_cfg80211_scan,
@@ -3558,6 +4370,9 @@ static struct cfg80211_ops wl_cfg80211_ops = {
3558 .set_pmksa = brcmf_cfg80211_set_pmksa, 4370 .set_pmksa = brcmf_cfg80211_set_pmksa,
3559 .del_pmksa = brcmf_cfg80211_del_pmksa, 4371 .del_pmksa = brcmf_cfg80211_del_pmksa,
3560 .flush_pmksa = brcmf_cfg80211_flush_pmksa, 4372 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4373 .start_ap = brcmf_cfg80211_start_ap,
4374 .stop_ap = brcmf_cfg80211_stop_ap,
4375 .del_station = brcmf_cfg80211_del_station,
3561#ifndef CONFIG_BRCMISCAN 4376#ifndef CONFIG_BRCMISCAN
3562 /* scheduled scan need e-scan, which is mutual exclusive with i-scan */ 4377 /* scheduled scan need e-scan, which is mutual exclusive with i-scan */
3563 .sched_scan_start = brcmf_cfg80211_sched_scan_start, 4378 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
@@ -3595,8 +4410,7 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3595#endif 4410#endif
3596} 4411}
3597 4412
3598static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, 4413static struct wireless_dev *brcmf_alloc_wdev(struct device *ndev)
3599 struct device *ndev)
3600{ 4414{
3601 struct wireless_dev *wdev; 4415 struct wireless_dev *wdev;
3602 s32 err = 0; 4416 s32 err = 0;
@@ -3605,9 +4419,8 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
3605 if (!wdev) 4419 if (!wdev)
3606 return ERR_PTR(-ENOMEM); 4420 return ERR_PTR(-ENOMEM);
3607 4421
3608 wdev->wiphy = 4422 wdev->wiphy = wiphy_new(&wl_cfg80211_ops,
3609 wiphy_new(&wl_cfg80211_ops, 4423 sizeof(struct brcmf_cfg80211_info));
3610 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
3611 if (!wdev->wiphy) { 4424 if (!wdev->wiphy) {
3612 WL_ERR("Could not allocate wiphy device\n"); 4425 WL_ERR("Could not allocate wiphy device\n");
3613 err = -ENOMEM; 4426 err = -ENOMEM;
@@ -3616,8 +4429,9 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
3616 set_wiphy_dev(wdev->wiphy, ndev); 4429 set_wiphy_dev(wdev->wiphy, ndev);
3617 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; 4430 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3618 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; 4431 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3619 wdev->wiphy->interface_modes = 4432 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3620 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 4433 BIT(NL80211_IFTYPE_ADHOC) |
4434 BIT(NL80211_IFTYPE_AP);
3621 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; 4435 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3622 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set 4436 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
3623 * it as 11a by default. 4437 * it as 11a by default.
@@ -3650,9 +4464,9 @@ wiphy_new_out:
3650 return ERR_PTR(err); 4464 return ERR_PTR(err);
3651} 4465}
3652 4466
3653static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv) 4467static void brcmf_free_wdev(struct brcmf_cfg80211_info *cfg)
3654{ 4468{
3655 struct wireless_dev *wdev = cfg_priv->wdev; 4469 struct wireless_dev *wdev = cfg->wdev;
3656 4470
3657 if (!wdev) { 4471 if (!wdev) {
3658 WL_ERR("wdev is invalid\n"); 4472 WL_ERR("wdev is invalid\n");
@@ -3661,10 +4475,10 @@ static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
3661 wiphy_unregister(wdev->wiphy); 4475 wiphy_unregister(wdev->wiphy);
3662 wiphy_free(wdev->wiphy); 4476 wiphy_free(wdev->wiphy);
3663 kfree(wdev); 4477 kfree(wdev);
3664 cfg_priv->wdev = NULL; 4478 cfg->wdev = NULL;
3665} 4479}
3666 4480
3667static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv, 4481static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg,
3668 const struct brcmf_event_msg *e) 4482 const struct brcmf_event_msg *e)
3669{ 4483{
3670 u32 event = be32_to_cpu(e->event_type); 4484 u32 event = be32_to_cpu(e->event_type);
@@ -3672,14 +4486,14 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
3672 4486
3673 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { 4487 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3674 WL_CONN("Processing set ssid\n"); 4488 WL_CONN("Processing set ssid\n");
3675 cfg_priv->link_up = true; 4489 cfg->link_up = true;
3676 return true; 4490 return true;
3677 } 4491 }
3678 4492
3679 return false; 4493 return false;
3680} 4494}
3681 4495
3682static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv, 4496static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg,
3683 const struct brcmf_event_msg *e) 4497 const struct brcmf_event_msg *e)
3684{ 4498{
3685 u32 event = be32_to_cpu(e->event_type); 4499 u32 event = be32_to_cpu(e->event_type);
@@ -3692,7 +4506,7 @@ static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
3692 return false; 4506 return false;
3693} 4507}
3694 4508
3695static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv, 4509static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
3696 const struct brcmf_event_msg *e) 4510 const struct brcmf_event_msg *e)
3697{ 4511{
3698 u32 event = be32_to_cpu(e->event_type); 4512 u32 event = be32_to_cpu(e->event_type);
@@ -3713,9 +4527,9 @@ static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
3713 return false; 4527 return false;
3714} 4528}
3715 4529
3716static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) 4530static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3717{ 4531{
3718 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4532 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3719 4533
3720 kfree(conn_info->req_ie); 4534 kfree(conn_info->req_ie);
3721 conn_info->req_ie = NULL; 4535 conn_info->req_ie = NULL;
@@ -3725,30 +4539,30 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
3725 conn_info->resp_ie_len = 0; 4539 conn_info->resp_ie_len = 0;
3726} 4540}
3727 4541
3728static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) 4542static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
3729{ 4543{
3730 struct net_device *ndev = cfg_to_ndev(cfg_priv); 4544 struct net_device *ndev = cfg_to_ndev(cfg);
3731 struct brcmf_cfg80211_assoc_ielen_le *assoc_info; 4545 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3732 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4546 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3733 u32 req_len; 4547 u32 req_len;
3734 u32 resp_len; 4548 u32 resp_len;
3735 s32 err = 0; 4549 s32 err = 0;
3736 4550
3737 brcmf_clear_assoc_ies(cfg_priv); 4551 brcmf_clear_assoc_ies(cfg);
3738 4552
3739 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf, 4553 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg->extra_buf,
3740 WL_ASSOC_INFO_MAX); 4554 WL_ASSOC_INFO_MAX);
3741 if (err) { 4555 if (err) {
3742 WL_ERR("could not get assoc info (%d)\n", err); 4556 WL_ERR("could not get assoc info (%d)\n", err);
3743 return err; 4557 return err;
3744 } 4558 }
3745 assoc_info = 4559 assoc_info =
3746 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf; 4560 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
3747 req_len = le32_to_cpu(assoc_info->req_len); 4561 req_len = le32_to_cpu(assoc_info->req_len);
3748 resp_len = le32_to_cpu(assoc_info->resp_len); 4562 resp_len = le32_to_cpu(assoc_info->resp_len);
3749 if (req_len) { 4563 if (req_len) {
3750 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies", 4564 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
3751 cfg_priv->extra_buf, 4565 cfg->extra_buf,
3752 WL_ASSOC_INFO_MAX); 4566 WL_ASSOC_INFO_MAX);
3753 if (err) { 4567 if (err) {
3754 WL_ERR("could not get assoc req (%d)\n", err); 4568 WL_ERR("could not get assoc req (%d)\n", err);
@@ -3756,7 +4570,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
3756 } 4570 }
3757 conn_info->req_ie_len = req_len; 4571 conn_info->req_ie_len = req_len;
3758 conn_info->req_ie = 4572 conn_info->req_ie =
3759 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len, 4573 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
3760 GFP_KERNEL); 4574 GFP_KERNEL);
3761 } else { 4575 } else {
3762 conn_info->req_ie_len = 0; 4576 conn_info->req_ie_len = 0;
@@ -3764,7 +4578,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
3764 } 4578 }
3765 if (resp_len) { 4579 if (resp_len) {
3766 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies", 4580 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
3767 cfg_priv->extra_buf, 4581 cfg->extra_buf,
3768 WL_ASSOC_INFO_MAX); 4582 WL_ASSOC_INFO_MAX);
3769 if (err) { 4583 if (err) {
3770 WL_ERR("could not get assoc resp (%d)\n", err); 4584 WL_ERR("could not get assoc resp (%d)\n", err);
@@ -3772,7 +4586,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
3772 } 4586 }
3773 conn_info->resp_ie_len = resp_len; 4587 conn_info->resp_ie_len = resp_len;
3774 conn_info->resp_ie = 4588 conn_info->resp_ie =
3775 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len, 4589 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
3776 GFP_KERNEL); 4590 GFP_KERNEL);
3777 } else { 4591 } else {
3778 conn_info->resp_ie_len = 0; 4592 conn_info->resp_ie_len = 0;
@@ -3785,12 +4599,13 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
3785} 4599}
3786 4600
3787static s32 4601static s32
3788brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, 4602brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3789 struct net_device *ndev, 4603 struct net_device *ndev,
3790 const struct brcmf_event_msg *e) 4604 const struct brcmf_event_msg *e)
3791{ 4605{
3792 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4606 struct brcmf_cfg80211_profile *profile = cfg->profile;
3793 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 4607 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4608 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3794 struct brcmf_channel_info_le channel_le; 4609 struct brcmf_channel_info_le channel_le;
3795 struct ieee80211_channel *notify_channel; 4610 struct ieee80211_channel *notify_channel;
3796 struct ieee80211_supported_band *band; 4611 struct ieee80211_supported_band *band;
@@ -3800,9 +4615,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
3800 4615
3801 WL_TRACE("Enter\n"); 4616 WL_TRACE("Enter\n");
3802 4617
3803 brcmf_get_assoc_ies(cfg_priv); 4618 brcmf_get_assoc_ies(cfg);
3804 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID); 4619 memcpy(profile->bssid, e->addr, ETH_ALEN);
3805 brcmf_update_bss_info(cfg_priv); 4620 brcmf_update_bss_info(cfg);
3806 4621
3807 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le, 4622 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
3808 sizeof(channel_le)); 4623 sizeof(channel_le));
@@ -3818,37 +4633,35 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
3818 freq = ieee80211_channel_to_frequency(target_channel, band->band); 4633 freq = ieee80211_channel_to_frequency(target_channel, band->band);
3819 notify_channel = ieee80211_get_channel(wiphy, freq); 4634 notify_channel = ieee80211_get_channel(wiphy, freq);
3820 4635
3821 cfg80211_roamed(ndev, notify_channel, 4636 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
3822 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
3823 conn_info->req_ie, conn_info->req_ie_len, 4637 conn_info->req_ie, conn_info->req_ie_len,
3824 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); 4638 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
3825 WL_CONN("Report roaming result\n"); 4639 WL_CONN("Report roaming result\n");
3826 4640
3827 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4641 set_bit(WL_STATUS_CONNECTED, &cfg->status);
3828 WL_TRACE("Exit\n"); 4642 WL_TRACE("Exit\n");
3829 return err; 4643 return err;
3830} 4644}
3831 4645
3832static s32 4646static s32
3833brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv, 4647brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
3834 struct net_device *ndev, const struct brcmf_event_msg *e, 4648 struct net_device *ndev, const struct brcmf_event_msg *e,
3835 bool completed) 4649 bool completed)
3836{ 4650{
3837 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4651 struct brcmf_cfg80211_profile *profile = cfg->profile;
4652 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3838 s32 err = 0; 4653 s32 err = 0;
3839 4654
3840 WL_TRACE("Enter\n"); 4655 WL_TRACE("Enter\n");
3841 4656
3842 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { 4657 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) {
3843 if (completed) { 4658 if (completed) {
3844 brcmf_get_assoc_ies(cfg_priv); 4659 brcmf_get_assoc_ies(cfg);
3845 brcmf_update_prof(cfg_priv, NULL, &e->addr, 4660 memcpy(profile->bssid, e->addr, ETH_ALEN);
3846 WL_PROF_BSSID); 4661 brcmf_update_bss_info(cfg);
3847 brcmf_update_bss_info(cfg_priv);
3848 } 4662 }
3849 cfg80211_connect_result(ndev, 4663 cfg80211_connect_result(ndev,
3850 (u8 *)brcmf_read_prof(cfg_priv, 4664 (u8 *)profile->bssid,
3851 WL_PROF_BSSID),
3852 conn_info->req_ie, 4665 conn_info->req_ie,
3853 conn_info->req_ie_len, 4666 conn_info->req_ie_len,
3854 conn_info->resp_ie, 4667 conn_info->resp_ie,
@@ -3857,7 +4670,7 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3857 WLAN_STATUS_AUTH_TIMEOUT, 4670 WLAN_STATUS_AUTH_TIMEOUT,
3858 GFP_KERNEL); 4671 GFP_KERNEL);
3859 if (completed) 4672 if (completed)
3860 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4673 set_bit(WL_STATUS_CONNECTED, &cfg->status);
3861 WL_CONN("Report connect result - connection %s\n", 4674 WL_CONN("Report connect result - connection %s\n",
3862 completed ? "succeeded" : "failed"); 4675 completed ? "succeeded" : "failed");
3863 } 4676 }
@@ -3866,52 +4679,93 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3866} 4679}
3867 4680
3868static s32 4681static s32
3869brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, 4682brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4683 struct net_device *ndev,
4684 const struct brcmf_event_msg *e, void *data)
4685{
4686 s32 err = 0;
4687 u32 event = be32_to_cpu(e->event_type);
4688 u32 reason = be32_to_cpu(e->reason);
4689 u32 len = be32_to_cpu(e->datalen);
4690 static int generation;
4691
4692 struct station_info sinfo;
4693
4694 WL_CONN("event %d, reason %d\n", event, reason);
4695 memset(&sinfo, 0, sizeof(sinfo));
4696
4697 sinfo.filled = 0;
4698 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4699 reason == BRCMF_E_STATUS_SUCCESS) {
4700 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4701 if (!data) {
4702 WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4703 return -EINVAL;
4704 }
4705 sinfo.assoc_req_ies = data;
4706 sinfo.assoc_req_ies_len = len;
4707 generation++;
4708 sinfo.generation = generation;
4709 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4710 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4711 (event == BRCMF_E_DEAUTH_IND) ||
4712 (event == BRCMF_E_DEAUTH)) {
4713 generation++;
4714 sinfo.generation = generation;
4715 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4716 }
4717 return err;
4718}
4719
4720static s32
4721brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
3870 struct net_device *ndev, 4722 struct net_device *ndev,
3871 const struct brcmf_event_msg *e, void *data) 4723 const struct brcmf_event_msg *e, void *data)
3872{ 4724{
4725 struct brcmf_cfg80211_profile *profile = cfg->profile;
3873 s32 err = 0; 4726 s32 err = 0;
3874 4727
3875 if (brcmf_is_linkup(cfg_priv, e)) { 4728 if (cfg->conf->mode == WL_MODE_AP) {
4729 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4730 } else if (brcmf_is_linkup(cfg, e)) {
3876 WL_CONN("Linkup\n"); 4731 WL_CONN("Linkup\n");
3877 if (brcmf_is_ibssmode(cfg_priv)) { 4732 if (brcmf_is_ibssmode(cfg)) {
3878 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr, 4733 memcpy(profile->bssid, e->addr, ETH_ALEN);
3879 WL_PROF_BSSID); 4734 wl_inform_ibss(cfg, ndev, e->addr);
3880 wl_inform_ibss(cfg_priv, ndev, e->addr);
3881 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); 4735 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3882 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4736 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3883 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4737 set_bit(WL_STATUS_CONNECTED, &cfg->status);
3884 } else 4738 } else
3885 brcmf_bss_connect_done(cfg_priv, ndev, e, true); 4739 brcmf_bss_connect_done(cfg, ndev, e, true);
3886 } else if (brcmf_is_linkdown(cfg_priv, e)) { 4740 } else if (brcmf_is_linkdown(cfg, e)) {
3887 WL_CONN("Linkdown\n"); 4741 WL_CONN("Linkdown\n");
3888 if (brcmf_is_ibssmode(cfg_priv)) { 4742 if (brcmf_is_ibssmode(cfg)) {
3889 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4743 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3890 if (test_and_clear_bit(WL_STATUS_CONNECTED, 4744 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3891 &cfg_priv->status)) 4745 &cfg->status))
3892 brcmf_link_down(cfg_priv); 4746 brcmf_link_down(cfg);
3893 } else { 4747 } else {
3894 brcmf_bss_connect_done(cfg_priv, ndev, e, false); 4748 brcmf_bss_connect_done(cfg, ndev, e, false);
3895 if (test_and_clear_bit(WL_STATUS_CONNECTED, 4749 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3896 &cfg_priv->status)) { 4750 &cfg->status)) {
3897 cfg80211_disconnected(ndev, 0, NULL, 0, 4751 cfg80211_disconnected(ndev, 0, NULL, 0,
3898 GFP_KERNEL); 4752 GFP_KERNEL);
3899 brcmf_link_down(cfg_priv); 4753 brcmf_link_down(cfg);
3900 } 4754 }
3901 } 4755 }
3902 brcmf_init_prof(cfg_priv->profile); 4756 brcmf_init_prof(cfg->profile);
3903 } else if (brcmf_is_nonetwork(cfg_priv, e)) { 4757 } else if (brcmf_is_nonetwork(cfg, e)) {
3904 if (brcmf_is_ibssmode(cfg_priv)) 4758 if (brcmf_is_ibssmode(cfg))
3905 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4759 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3906 else 4760 else
3907 brcmf_bss_connect_done(cfg_priv, ndev, e, false); 4761 brcmf_bss_connect_done(cfg, ndev, e, false);
3908 } 4762 }
3909 4763
3910 return err; 4764 return err;
3911} 4765}
3912 4766
3913static s32 4767static s32
3914brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv, 4768brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg,
3915 struct net_device *ndev, 4769 struct net_device *ndev,
3916 const struct brcmf_event_msg *e, void *data) 4770 const struct brcmf_event_msg *e, void *data)
3917{ 4771{
@@ -3920,17 +4774,17 @@ brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3920 u32 status = be32_to_cpu(e->status); 4774 u32 status = be32_to_cpu(e->status);
3921 4775
3922 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { 4776 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3923 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) 4777 if (test_bit(WL_STATUS_CONNECTED, &cfg->status))
3924 brcmf_bss_roaming_done(cfg_priv, ndev, e); 4778 brcmf_bss_roaming_done(cfg, ndev, e);
3925 else 4779 else
3926 brcmf_bss_connect_done(cfg_priv, ndev, e, true); 4780 brcmf_bss_connect_done(cfg, ndev, e, true);
3927 } 4781 }
3928 4782
3929 return err; 4783 return err;
3930} 4784}
3931 4785
3932static s32 4786static s32
3933brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv, 4787brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
3934 struct net_device *ndev, 4788 struct net_device *ndev,
3935 const struct brcmf_event_msg *e, void *data) 4789 const struct brcmf_event_msg *e, void *data)
3936{ 4790{
@@ -3949,7 +4803,7 @@ brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3949} 4803}
3950 4804
3951static s32 4805static s32
3952brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv, 4806brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
3953 struct net_device *ndev, 4807 struct net_device *ndev,
3954 const struct brcmf_event_msg *e, void *data) 4808 const struct brcmf_event_msg *e, void *data)
3955{ 4809{
@@ -3962,12 +4816,12 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3962 4816
3963 WL_TRACE("Enter\n"); 4817 WL_TRACE("Enter\n");
3964 4818
3965 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) { 4819 if (cfg->iscan_on && cfg->iscan_kickstart) {
3966 WL_TRACE("Exit\n"); 4820 WL_TRACE("Exit\n");
3967 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv)); 4821 return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
3968 } 4822 }
3969 4823
3970 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 4824 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
3971 WL_ERR("Scan complete while device not scanning\n"); 4825 WL_ERR("Scan complete while device not scanning\n");
3972 scan_abort = true; 4826 scan_abort = true;
3973 err = -EINVAL; 4827 err = -EINVAL;
@@ -3984,33 +4838,33 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3984 scan_channel = le32_to_cpu(channel_inform_le.scan_channel); 4838 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3985 if (scan_channel) 4839 if (scan_channel)
3986 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel); 4840 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3987 cfg_priv->bss_list = cfg_priv->scan_results; 4841 cfg->bss_list = cfg->scan_results;
3988 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list; 4842 bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list;
3989 4843
3990 memset(cfg_priv->scan_results, 0, len); 4844 memset(cfg->scan_results, 0, len);
3991 bss_list_le->buflen = cpu_to_le32(len); 4845 bss_list_le->buflen = cpu_to_le32(len);
3992 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS, 4846 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3993 cfg_priv->scan_results, len); 4847 cfg->scan_results, len);
3994 if (err) { 4848 if (err) {
3995 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); 4849 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3996 err = -EINVAL; 4850 err = -EINVAL;
3997 scan_abort = true; 4851 scan_abort = true;
3998 goto scan_done_out; 4852 goto scan_done_out;
3999 } 4853 }
4000 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen); 4854 cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
4001 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version); 4855 cfg->scan_results->version = le32_to_cpu(bss_list_le->version);
4002 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count); 4856 cfg->scan_results->count = le32_to_cpu(bss_list_le->count);
4003 4857
4004 err = brcmf_inform_bss(cfg_priv); 4858 err = brcmf_inform_bss(cfg);
4005 if (err) 4859 if (err)
4006 scan_abort = true; 4860 scan_abort = true;
4007 4861
4008scan_done_out: 4862scan_done_out:
4009 if (cfg_priv->scan_request) { 4863 if (cfg->scan_request) {
4010 WL_SCAN("calling cfg80211_scan_done\n"); 4864 WL_SCAN("calling cfg80211_scan_done\n");
4011 cfg80211_scan_done(cfg_priv->scan_request, scan_abort); 4865 cfg80211_scan_done(cfg->scan_request, scan_abort);
4012 brcmf_set_mpc(ndev, 1); 4866 brcmf_set_mpc(ndev, 1);
4013 cfg_priv->scan_request = NULL; 4867 cfg->scan_request = NULL;
4014 } 4868 }
4015 4869
4016 WL_TRACE("Exit\n"); 4870 WL_TRACE("Exit\n");
@@ -4033,74 +4887,85 @@ static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
4033 memset(el, 0, sizeof(*el)); 4887 memset(el, 0, sizeof(*el));
4034 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; 4888 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
4035 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; 4889 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
4890 el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status;
4891 el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status;
4892 el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status;
4893 el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status;
4894 el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status;
4036 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; 4895 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
4037 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; 4896 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
4038 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; 4897 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
4039 el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results; 4898 el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results;
4040} 4899}
4041 4900
4042static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv) 4901static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4043{ 4902{
4044 kfree(cfg_priv->scan_results); 4903 kfree(cfg->scan_results);
4045 cfg_priv->scan_results = NULL; 4904 cfg->scan_results = NULL;
4046 kfree(cfg_priv->bss_info); 4905 kfree(cfg->bss_info);
4047 cfg_priv->bss_info = NULL; 4906 cfg->bss_info = NULL;
4048 kfree(cfg_priv->conf); 4907 kfree(cfg->conf);
4049 cfg_priv->conf = NULL; 4908 cfg->conf = NULL;
4050 kfree(cfg_priv->profile); 4909 kfree(cfg->profile);
4051 cfg_priv->profile = NULL; 4910 cfg->profile = NULL;
4052 kfree(cfg_priv->scan_req_int); 4911 kfree(cfg->scan_req_int);
4053 cfg_priv->scan_req_int = NULL; 4912 cfg->scan_req_int = NULL;
4054 kfree(cfg_priv->escan_ioctl_buf); 4913 kfree(cfg->escan_ioctl_buf);
4055 cfg_priv->escan_ioctl_buf = NULL; 4914 cfg->escan_ioctl_buf = NULL;
4056 kfree(cfg_priv->dcmd_buf); 4915 kfree(cfg->dcmd_buf);
4057 cfg_priv->dcmd_buf = NULL; 4916 cfg->dcmd_buf = NULL;
4058 kfree(cfg_priv->extra_buf); 4917 kfree(cfg->extra_buf);
4059 cfg_priv->extra_buf = NULL; 4918 cfg->extra_buf = NULL;
4060 kfree(cfg_priv->iscan); 4919 kfree(cfg->iscan);
4061 cfg_priv->iscan = NULL; 4920 cfg->iscan = NULL;
4062 kfree(cfg_priv->pmk_list); 4921 kfree(cfg->pmk_list);
4063 cfg_priv->pmk_list = NULL; 4922 cfg->pmk_list = NULL;
4064} 4923 if (cfg->ap_info) {
4065 4924 kfree(cfg->ap_info->wpa_ie);
4066static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv) 4925 kfree(cfg->ap_info->rsn_ie);
4067{ 4926 kfree(cfg->ap_info);
4068 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); 4927 cfg->ap_info = NULL;
4069 if (!cfg_priv->scan_results) 4928 }
4929}
4930
4931static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4932{
4933 cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
4934 if (!cfg->scan_results)
4070 goto init_priv_mem_out; 4935 goto init_priv_mem_out;
4071 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL); 4936 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4072 if (!cfg_priv->conf) 4937 if (!cfg->conf)
4073 goto init_priv_mem_out; 4938 goto init_priv_mem_out;
4074 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL); 4939 cfg->profile = kzalloc(sizeof(*cfg->profile), GFP_KERNEL);
4075 if (!cfg_priv->profile) 4940 if (!cfg->profile)
4076 goto init_priv_mem_out; 4941 goto init_priv_mem_out;
4077 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); 4942 cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4078 if (!cfg_priv->bss_info) 4943 if (!cfg->bss_info)
4079 goto init_priv_mem_out; 4944 goto init_priv_mem_out;
4080 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int), 4945 cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int),
4081 GFP_KERNEL); 4946 GFP_KERNEL);
4082 if (!cfg_priv->scan_req_int) 4947 if (!cfg->scan_req_int)
4083 goto init_priv_mem_out; 4948 goto init_priv_mem_out;
4084 cfg_priv->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); 4949 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4085 if (!cfg_priv->escan_ioctl_buf) 4950 if (!cfg->escan_ioctl_buf)
4086 goto init_priv_mem_out; 4951 goto init_priv_mem_out;
4087 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL); 4952 cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
4088 if (!cfg_priv->dcmd_buf) 4953 if (!cfg->dcmd_buf)
4089 goto init_priv_mem_out; 4954 goto init_priv_mem_out;
4090 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); 4955 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4091 if (!cfg_priv->extra_buf) 4956 if (!cfg->extra_buf)
4092 goto init_priv_mem_out; 4957 goto init_priv_mem_out;
4093 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL); 4958 cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL);
4094 if (!cfg_priv->iscan) 4959 if (!cfg->iscan)
4095 goto init_priv_mem_out; 4960 goto init_priv_mem_out;
4096 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL); 4961 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4097 if (!cfg_priv->pmk_list) 4962 if (!cfg->pmk_list)
4098 goto init_priv_mem_out; 4963 goto init_priv_mem_out;
4099 4964
4100 return 0; 4965 return 0;
4101 4966
4102init_priv_mem_out: 4967init_priv_mem_out:
4103 brcmf_deinit_priv_mem(cfg_priv); 4968 brcmf_deinit_priv_mem(cfg);
4104 4969
4105 return -ENOMEM; 4970 return -ENOMEM;
4106} 4971}
@@ -4110,17 +4975,17 @@ init_priv_mem_out:
4110*/ 4975*/
4111 4976
4112static struct brcmf_cfg80211_event_q *brcmf_deq_event( 4977static struct brcmf_cfg80211_event_q *brcmf_deq_event(
4113 struct brcmf_cfg80211_priv *cfg_priv) 4978 struct brcmf_cfg80211_info *cfg)
4114{ 4979{
4115 struct brcmf_cfg80211_event_q *e = NULL; 4980 struct brcmf_cfg80211_event_q *e = NULL;
4116 4981
4117 spin_lock_irq(&cfg_priv->evt_q_lock); 4982 spin_lock_irq(&cfg->evt_q_lock);
4118 if (!list_empty(&cfg_priv->evt_q_list)) { 4983 if (!list_empty(&cfg->evt_q_list)) {
4119 e = list_first_entry(&cfg_priv->evt_q_list, 4984 e = list_first_entry(&cfg->evt_q_list,
4120 struct brcmf_cfg80211_event_q, evt_q_list); 4985 struct brcmf_cfg80211_event_q, evt_q_list);
4121 list_del(&e->evt_q_list); 4986 list_del(&e->evt_q_list);
4122 } 4987 }
4123 spin_unlock_irq(&cfg_priv->evt_q_lock); 4988 spin_unlock_irq(&cfg->evt_q_lock);
4124 4989
4125 return e; 4990 return e;
4126} 4991}
@@ -4132,7 +4997,7 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event(
4132*/ 4997*/
4133 4998
4134static s32 4999static s32
4135brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event, 5000brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event,
4136 const struct brcmf_event_msg *msg, void *data) 5001 const struct brcmf_event_msg *msg, void *data)
4137{ 5002{
4138 struct brcmf_cfg80211_event_q *e; 5003 struct brcmf_cfg80211_event_q *e;
@@ -4156,9 +5021,9 @@ brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
4156 if (data) 5021 if (data)
4157 memcpy(&e->edata, data, data_len); 5022 memcpy(&e->edata, data, data_len);
4158 5023
4159 spin_lock_irqsave(&cfg_priv->evt_q_lock, flags); 5024 spin_lock_irqsave(&cfg->evt_q_lock, flags);
4160 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list); 5025 list_add_tail(&e->evt_q_list, &cfg->evt_q_list);
4161 spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags); 5026 spin_unlock_irqrestore(&cfg->evt_q_lock, flags);
4162 5027
4163 return err; 5028 return err;
4164} 5029}
@@ -4170,12 +5035,12 @@ static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
4170 5035
4171static void brcmf_cfg80211_event_handler(struct work_struct *work) 5036static void brcmf_cfg80211_event_handler(struct work_struct *work)
4172{ 5037{
4173 struct brcmf_cfg80211_priv *cfg_priv = 5038 struct brcmf_cfg80211_info *cfg =
4174 container_of(work, struct brcmf_cfg80211_priv, 5039 container_of(work, struct brcmf_cfg80211_info,
4175 event_work); 5040 event_work);
4176 struct brcmf_cfg80211_event_q *e; 5041 struct brcmf_cfg80211_event_q *e;
4177 5042
4178 e = brcmf_deq_event(cfg_priv); 5043 e = brcmf_deq_event(cfg);
4179 if (unlikely(!e)) { 5044 if (unlikely(!e)) {
4180 WL_ERR("event queue empty...\n"); 5045 WL_ERR("event queue empty...\n");
4181 return; 5046 return;
@@ -4183,147 +5048,131 @@ static void brcmf_cfg80211_event_handler(struct work_struct *work)
4183 5048
4184 do { 5049 do {
4185 WL_INFO("event type (%d)\n", e->etype); 5050 WL_INFO("event type (%d)\n", e->etype);
4186 if (cfg_priv->el.handler[e->etype]) 5051 if (cfg->el.handler[e->etype])
4187 cfg_priv->el.handler[e->etype](cfg_priv, 5052 cfg->el.handler[e->etype](cfg,
4188 cfg_to_ndev(cfg_priv), 5053 cfg_to_ndev(cfg),
4189 &e->emsg, e->edata); 5054 &e->emsg, e->edata);
4190 else 5055 else
4191 WL_INFO("Unknown Event (%d): ignoring\n", e->etype); 5056 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
4192 brcmf_put_event(e); 5057 brcmf_put_event(e);
4193 } while ((e = brcmf_deq_event(cfg_priv))); 5058 } while ((e = brcmf_deq_event(cfg)));
4194 5059
4195} 5060}
4196 5061
4197static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv) 5062static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg)
4198{ 5063{
4199 spin_lock_init(&cfg_priv->evt_q_lock); 5064 spin_lock_init(&cfg->evt_q_lock);
4200 INIT_LIST_HEAD(&cfg_priv->evt_q_list); 5065 INIT_LIST_HEAD(&cfg->evt_q_list);
4201} 5066}
4202 5067
4203static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv) 5068static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg)
4204{ 5069{
4205 struct brcmf_cfg80211_event_q *e; 5070 struct brcmf_cfg80211_event_q *e;
4206 5071
4207 spin_lock_irq(&cfg_priv->evt_q_lock); 5072 spin_lock_irq(&cfg->evt_q_lock);
4208 while (!list_empty(&cfg_priv->evt_q_list)) { 5073 while (!list_empty(&cfg->evt_q_list)) {
4209 e = list_first_entry(&cfg_priv->evt_q_list, 5074 e = list_first_entry(&cfg->evt_q_list,
4210 struct brcmf_cfg80211_event_q, evt_q_list); 5075 struct brcmf_cfg80211_event_q, evt_q_list);
4211 list_del(&e->evt_q_list); 5076 list_del(&e->evt_q_list);
4212 kfree(e); 5077 kfree(e);
4213 } 5078 }
4214 spin_unlock_irq(&cfg_priv->evt_q_lock); 5079 spin_unlock_irq(&cfg->evt_q_lock);
4215} 5080}
4216 5081
4217static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv) 5082static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4218{ 5083{
4219 s32 err = 0; 5084 s32 err = 0;
4220 5085
4221 cfg_priv->scan_request = NULL; 5086 cfg->scan_request = NULL;
4222 cfg_priv->pwr_save = true; 5087 cfg->pwr_save = true;
4223#ifdef CONFIG_BRCMISCAN 5088#ifdef CONFIG_BRCMISCAN
4224 cfg_priv->iscan_on = true; /* iscan on & off switch. 5089 cfg->iscan_on = true; /* iscan on & off switch.
4225 we enable iscan per default */ 5090 we enable iscan per default */
4226 cfg_priv->escan_on = false; /* escan on & off switch. 5091 cfg->escan_on = false; /* escan on & off switch.
4227 we disable escan per default */ 5092 we disable escan per default */
4228#else 5093#else
4229 cfg_priv->iscan_on = false; /* iscan on & off switch. 5094 cfg->iscan_on = false; /* iscan on & off switch.
4230 we disable iscan per default */ 5095 we disable iscan per default */
4231 cfg_priv->escan_on = true; /* escan on & off switch. 5096 cfg->escan_on = true; /* escan on & off switch.
4232 we enable escan per default */ 5097 we enable escan per default */
4233#endif 5098#endif
4234 cfg_priv->roam_on = true; /* roam on & off switch. 5099 cfg->roam_on = true; /* roam on & off switch.
4235 we enable roam per default */ 5100 we enable roam per default */
4236 5101
4237 cfg_priv->iscan_kickstart = false; 5102 cfg->iscan_kickstart = false;
4238 cfg_priv->active_scan = true; /* we do active scan for 5103 cfg->active_scan = true; /* we do active scan for
4239 specific scan per default */ 5104 specific scan per default */
4240 cfg_priv->dongle_up = false; /* dongle is not up yet */ 5105 cfg->dongle_up = false; /* dongle is not up yet */
4241 brcmf_init_eq(cfg_priv); 5106 brcmf_init_eq(cfg);
4242 err = brcmf_init_priv_mem(cfg_priv); 5107 err = brcmf_init_priv_mem(cfg);
4243 if (err) 5108 if (err)
4244 return err; 5109 return err;
4245 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler); 5110 INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler);
4246 brcmf_init_eloop_handler(&cfg_priv->el); 5111 brcmf_init_eloop_handler(&cfg->el);
4247 mutex_init(&cfg_priv->usr_sync); 5112 mutex_init(&cfg->usr_sync);
4248 err = brcmf_init_iscan(cfg_priv); 5113 err = brcmf_init_iscan(cfg);
4249 if (err) 5114 if (err)
4250 return err; 5115 return err;
4251 brcmf_init_escan(cfg_priv); 5116 brcmf_init_escan(cfg);
4252 brcmf_init_conf(cfg_priv->conf); 5117 brcmf_init_conf(cfg->conf);
4253 brcmf_init_prof(cfg_priv->profile); 5118 brcmf_init_prof(cfg->profile);
4254 brcmf_link_down(cfg_priv); 5119 brcmf_link_down(cfg);
4255 5120
4256 return err; 5121 return err;
4257} 5122}
4258 5123
4259static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv) 5124static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4260{ 5125{
4261 cancel_work_sync(&cfg_priv->event_work); 5126 cancel_work_sync(&cfg->event_work);
4262 cfg_priv->dongle_up = false; /* dongle down */ 5127 cfg->dongle_up = false; /* dongle down */
4263 brcmf_flush_eq(cfg_priv); 5128 brcmf_flush_eq(cfg);
4264 brcmf_link_down(cfg_priv); 5129 brcmf_link_down(cfg);
4265 brcmf_abort_scanning(cfg_priv); 5130 brcmf_abort_scanning(cfg);
4266 brcmf_deinit_priv_mem(cfg_priv); 5131 brcmf_deinit_priv_mem(cfg);
4267} 5132}
4268 5133
4269struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, 5134struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
4270 struct device *busdev, 5135 struct device *busdev,
4271 struct brcmf_pub *drvr) 5136 struct brcmf_pub *drvr)
4272{ 5137{
4273 struct wireless_dev *wdev; 5138 struct wireless_dev *wdev;
4274 struct brcmf_cfg80211_priv *cfg_priv; 5139 struct brcmf_cfg80211_info *cfg;
4275 struct brcmf_cfg80211_iface *ci;
4276 struct brcmf_cfg80211_dev *cfg_dev;
4277 s32 err = 0; 5140 s32 err = 0;
4278 5141
4279 if (!ndev) { 5142 if (!ndev) {
4280 WL_ERR("ndev is invalid\n"); 5143 WL_ERR("ndev is invalid\n");
4281 return NULL; 5144 return NULL;
4282 } 5145 }
4283 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
4284 if (!cfg_dev)
4285 return NULL;
4286 5146
4287 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev); 5147 wdev = brcmf_alloc_wdev(busdev);
4288 if (IS_ERR(wdev)) { 5148 if (IS_ERR(wdev)) {
4289 kfree(cfg_dev);
4290 return NULL; 5149 return NULL;
4291 } 5150 }
4292 5151
4293 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS); 5152 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
4294 cfg_priv = wdev_to_cfg(wdev); 5153 cfg = wdev_to_cfg(wdev);
4295 cfg_priv->wdev = wdev; 5154 cfg->wdev = wdev;
4296 cfg_priv->pub = drvr; 5155 cfg->pub = drvr;
4297 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
4298 ci->cfg_priv = cfg_priv;
4299 ndev->ieee80211_ptr = wdev; 5156 ndev->ieee80211_ptr = wdev;
4300 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 5157 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
4301 wdev->netdev = ndev; 5158 wdev->netdev = ndev;
4302 err = wl_init_priv(cfg_priv); 5159 err = wl_init_priv(cfg);
4303 if (err) { 5160 if (err) {
4304 WL_ERR("Failed to init iwm_priv (%d)\n", err); 5161 WL_ERR("Failed to init iwm_priv (%d)\n", err);
4305 goto cfg80211_attach_out; 5162 goto cfg80211_attach_out;
4306 } 5163 }
4307 brcmf_set_drvdata(cfg_dev, ci);
4308 5164
4309 return cfg_dev; 5165 return cfg;
4310 5166
4311cfg80211_attach_out: 5167cfg80211_attach_out:
4312 brcmf_free_wdev(cfg_priv); 5168 brcmf_free_wdev(cfg);
4313 kfree(cfg_dev);
4314 return NULL; 5169 return NULL;
4315} 5170}
4316 5171
4317void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev) 5172void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4318{ 5173{
4319 struct brcmf_cfg80211_priv *cfg_priv; 5174 wl_deinit_priv(cfg);
4320 5175 brcmf_free_wdev(cfg);
4321 cfg_priv = brcmf_priv_get(cfg_dev);
4322
4323 wl_deinit_priv(cfg_priv);
4324 brcmf_free_wdev(cfg_priv);
4325 brcmf_set_drvdata(cfg_dev, NULL);
4326 kfree(cfg_dev);
4327} 5176}
4328 5177
4329void 5178void
@@ -4331,10 +5180,10 @@ brcmf_cfg80211_event(struct net_device *ndev,
4331 const struct brcmf_event_msg *e, void *data) 5180 const struct brcmf_event_msg *e, void *data)
4332{ 5181{
4333 u32 event_type = be32_to_cpu(e->event_type); 5182 u32 event_type = be32_to_cpu(e->event_type);
4334 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 5183 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
4335 5184
4336 if (!brcmf_enq_event(cfg_priv, event_type, e, data)) 5185 if (!brcmf_enq_event(cfg, event_type, e, data))
4337 schedule_work(&cfg_priv->event_work); 5186 schedule_work(&cfg->event_work);
4338} 5187}
4339 5188
4340static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype) 5189static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
@@ -4355,6 +5204,9 @@ static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
4355 case NL80211_IFTYPE_STATION: 5204 case NL80211_IFTYPE_STATION:
4356 infra = 1; 5205 infra = 1;
4357 break; 5206 break;
5207 case NL80211_IFTYPE_AP:
5208 infra = 1;
5209 break;
4358 default: 5210 default:
4359 err = -EINVAL; 5211 err = -EINVAL;
4360 WL_ERR("invalid type (%d)\n", iftype); 5212 WL_ERR("invalid type (%d)\n", iftype);
@@ -4527,14 +5379,14 @@ dongle_scantime_out:
4527 return err; 5379 return err;
4528} 5380}
4529 5381
4530static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv) 5382static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4531{ 5383{
4532 struct wiphy *wiphy; 5384 struct wiphy *wiphy;
4533 s32 phy_list; 5385 s32 phy_list;
4534 s8 phy; 5386 s8 phy;
4535 s32 err = 0; 5387 s32 err = 0;
4536 5388
4537 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST, 5389 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCM_GET_PHYLIST,
4538 &phy_list, sizeof(phy_list)); 5390 &phy_list, sizeof(phy_list));
4539 if (err) { 5391 if (err) {
4540 WL_ERR("error (%d)\n", err); 5392 WL_ERR("error (%d)\n", err);
@@ -4544,29 +5396,29 @@ static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
4544 phy = ((char *)&phy_list)[0]; 5396 phy = ((char *)&phy_list)[0];
4545 WL_INFO("%c phy\n", phy); 5397 WL_INFO("%c phy\n", phy);
4546 if (phy == 'n' || phy == 'a') { 5398 if (phy == 'n' || phy == 'a') {
4547 wiphy = cfg_to_wiphy(cfg_priv); 5399 wiphy = cfg_to_wiphy(cfg);
4548 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; 5400 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4549 } 5401 }
4550 5402
4551 return err; 5403 return err;
4552} 5404}
4553 5405
4554static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv) 5406static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4555{ 5407{
4556 return wl_update_wiphybands(cfg_priv); 5408 return wl_update_wiphybands(cfg);
4557} 5409}
4558 5410
4559static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv) 5411static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4560{ 5412{
4561 struct net_device *ndev; 5413 struct net_device *ndev;
4562 struct wireless_dev *wdev; 5414 struct wireless_dev *wdev;
4563 s32 power_mode; 5415 s32 power_mode;
4564 s32 err = 0; 5416 s32 err = 0;
4565 5417
4566 if (cfg_priv->dongle_up) 5418 if (cfg->dongle_up)
4567 return err; 5419 return err;
4568 5420
4569 ndev = cfg_to_ndev(cfg_priv); 5421 ndev = cfg_to_ndev(cfg);
4570 wdev = ndev->ieee80211_ptr; 5422 wdev = ndev->ieee80211_ptr;
4571 5423
4572 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, 5424 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
@@ -4576,21 +5428,21 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
4576 if (err) 5428 if (err)
4577 goto default_conf_out; 5429 goto default_conf_out;
4578 5430
4579 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF; 5431 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4580 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode); 5432 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
4581 if (err) 5433 if (err)
4582 goto default_conf_out; 5434 goto default_conf_out;
4583 WL_INFO("power save set to %s\n", 5435 WL_INFO("power save set to %s\n",
4584 (power_mode ? "enabled" : "disabled")); 5436 (power_mode ? "enabled" : "disabled"));
4585 5437
4586 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1), 5438 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
4587 WL_BEACON_TIMEOUT); 5439 WL_BEACON_TIMEOUT);
4588 if (err) 5440 if (err)
4589 goto default_conf_out; 5441 goto default_conf_out;
4590 err = brcmf_dongle_mode(ndev, wdev->iftype); 5442 err = brcmf_dongle_mode(ndev, wdev->iftype);
4591 if (err && err != -EINPROGRESS) 5443 if (err && err != -EINPROGRESS)
4592 goto default_conf_out; 5444 goto default_conf_out;
4593 err = brcmf_dongle_probecap(cfg_priv); 5445 err = brcmf_dongle_probecap(cfg);
4594 if (err) 5446 if (err)
4595 goto default_conf_out; 5447 goto default_conf_out;
4596 5448
@@ -4598,31 +5450,31 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
4598 5450
4599default_conf_out: 5451default_conf_out:
4600 5452
4601 cfg_priv->dongle_up = true; 5453 cfg->dongle_up = true;
4602 5454
4603 return err; 5455 return err;
4604 5456
4605} 5457}
4606 5458
4607static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv) 5459static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info *cfg)
4608{ 5460{
4609 char buf[10+IFNAMSIZ]; 5461 char buf[10+IFNAMSIZ];
4610 struct dentry *fd; 5462 struct dentry *fd;
4611 s32 err = 0; 5463 s32 err = 0;
4612 5464
4613 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name); 5465 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg)->name);
4614 cfg_priv->debugfsdir = debugfs_create_dir(buf, 5466 cfg->debugfsdir = debugfs_create_dir(buf,
4615 cfg_to_wiphy(cfg_priv)->debugfsdir); 5467 cfg_to_wiphy(cfg)->debugfsdir);
4616 5468
4617 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir, 5469 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg->debugfsdir,
4618 (u16 *)&cfg_priv->profile->beacon_interval); 5470 (u16 *)&cfg->profile->beacon_interval);
4619 if (!fd) { 5471 if (!fd) {
4620 err = -ENOMEM; 5472 err = -ENOMEM;
4621 goto err_out; 5473 goto err_out;
4622 } 5474 }
4623 5475
4624 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir, 5476 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg->debugfsdir,
4625 (u8 *)&cfg_priv->profile->dtim_period); 5477 (u8 *)&cfg->profile->dtim_period);
4626 if (!fd) { 5478 if (!fd) {
4627 err = -ENOMEM; 5479 err = -ENOMEM;
4628 goto err_out; 5480 goto err_out;
@@ -4632,40 +5484,40 @@ err_out:
4632 return err; 5484 return err;
4633} 5485}
4634 5486
4635static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv) 5487static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg)
4636{ 5488{
4637 debugfs_remove_recursive(cfg_priv->debugfsdir); 5489 debugfs_remove_recursive(cfg->debugfsdir);
4638 cfg_priv->debugfsdir = NULL; 5490 cfg->debugfsdir = NULL;
4639} 5491}
4640 5492
4641static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv) 5493static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
4642{ 5494{
4643 s32 err = 0; 5495 s32 err = 0;
4644 5496
4645 set_bit(WL_STATUS_READY, &cfg_priv->status); 5497 set_bit(WL_STATUS_READY, &cfg->status);
4646 5498
4647 brcmf_debugfs_add_netdev_params(cfg_priv); 5499 brcmf_debugfs_add_netdev_params(cfg);
4648 5500
4649 err = brcmf_config_dongle(cfg_priv); 5501 err = brcmf_config_dongle(cfg);
4650 if (err) 5502 if (err)
4651 return err; 5503 return err;
4652 5504
4653 brcmf_invoke_iscan(cfg_priv); 5505 brcmf_invoke_iscan(cfg);
4654 5506
4655 return err; 5507 return err;
4656} 5508}
4657 5509
4658static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv) 5510static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
4659{ 5511{
4660 /* 5512 /*
4661 * While going down, if associated with AP disassociate 5513 * While going down, if associated with AP disassociate
4662 * from AP to save power 5514 * from AP to save power
4663 */ 5515 */
4664 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) || 5516 if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
4665 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) && 5517 test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
4666 test_bit(WL_STATUS_READY, &cfg_priv->status)) { 5518 test_bit(WL_STATUS_READY, &cfg->status)) {
4667 WL_INFO("Disassociating from AP"); 5519 WL_INFO("Disassociating from AP");
4668 brcmf_link_down(cfg_priv); 5520 brcmf_link_down(cfg);
4669 5521
4670 /* Make sure WPA_Supplicant receives all the event 5522 /* Make sure WPA_Supplicant receives all the event
4671 generated due to DISASSOC call to the fw to keep 5523 generated due to DISASSOC call to the fw to keep
@@ -4674,36 +5526,32 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
4674 brcmf_delay(500); 5526 brcmf_delay(500);
4675 } 5527 }
4676 5528
4677 brcmf_abort_scanning(cfg_priv); 5529 brcmf_abort_scanning(cfg);
4678 clear_bit(WL_STATUS_READY, &cfg_priv->status); 5530 clear_bit(WL_STATUS_READY, &cfg->status);
4679 5531
4680 brcmf_debugfs_remove_netdev(cfg_priv); 5532 brcmf_debugfs_remove_netdev(cfg);
4681 5533
4682 return 0; 5534 return 0;
4683} 5535}
4684 5536
4685s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev) 5537s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
4686{ 5538{
4687 struct brcmf_cfg80211_priv *cfg_priv;
4688 s32 err = 0; 5539 s32 err = 0;
4689 5540
4690 cfg_priv = brcmf_priv_get(cfg_dev); 5541 mutex_lock(&cfg->usr_sync);
4691 mutex_lock(&cfg_priv->usr_sync); 5542 err = __brcmf_cfg80211_up(cfg);
4692 err = __brcmf_cfg80211_up(cfg_priv); 5543 mutex_unlock(&cfg->usr_sync);
4693 mutex_unlock(&cfg_priv->usr_sync);
4694 5544
4695 return err; 5545 return err;
4696} 5546}
4697 5547
4698s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev) 5548s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
4699{ 5549{
4700 struct brcmf_cfg80211_priv *cfg_priv;
4701 s32 err = 0; 5550 s32 err = 0;
4702 5551
4703 cfg_priv = brcmf_priv_get(cfg_dev); 5552 mutex_lock(&cfg->usr_sync);
4704 mutex_lock(&cfg_priv->usr_sync); 5553 err = __brcmf_cfg80211_down(cfg);
4705 err = __brcmf_cfg80211_down(cfg_priv); 5554 mutex_unlock(&cfg->usr_sync);
4706 mutex_unlock(&cfg_priv->usr_sync);
4707 5555
4708 return err; 5556 return err;
4709} 5557}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 52e408ed6f41..71ced174748a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -17,12 +17,6 @@
17#ifndef _wl_cfg80211_h_ 17#ifndef _wl_cfg80211_h_
18#define _wl_cfg80211_h_ 18#define _wl_cfg80211_h_
19 19
20struct brcmf_cfg80211_conf;
21struct brcmf_cfg80211_iface;
22struct brcmf_cfg80211_priv;
23struct brcmf_cfg80211_security;
24struct brcmf_cfg80211_ibss;
25
26#define WL_DBG_NONE 0 20#define WL_DBG_NONE 0
27#define WL_DBG_CONN (1 << 5) 21#define WL_DBG_CONN (1 << 5)
28#define WL_DBG_SCAN (1 << 4) 22#define WL_DBG_SCAN (1 << 4)
@@ -130,13 +124,18 @@ do { \
130#define WL_ESCAN_ACTION_CONTINUE 2 124#define WL_ESCAN_ACTION_CONTINUE 2
131#define WL_ESCAN_ACTION_ABORT 3 125#define WL_ESCAN_ACTION_ABORT 3
132 126
127#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
128#define IE_MAX_LEN 512
129
133/* dongle status */ 130/* dongle status */
134enum wl_status { 131enum wl_status {
135 WL_STATUS_READY, 132 WL_STATUS_READY,
136 WL_STATUS_SCANNING, 133 WL_STATUS_SCANNING,
137 WL_STATUS_SCAN_ABORTING, 134 WL_STATUS_SCAN_ABORTING,
138 WL_STATUS_CONNECTING, 135 WL_STATUS_CONNECTING,
139 WL_STATUS_CONNECTED 136 WL_STATUS_CONNECTED,
137 WL_STATUS_AP_CREATING,
138 WL_STATUS_AP_CREATED
140}; 139};
141 140
142/* wi-fi mode */ 141/* wi-fi mode */
@@ -176,23 +175,17 @@ struct brcmf_cfg80211_conf {
176 struct ieee80211_channel channel; 175 struct ieee80211_channel channel;
177}; 176};
178 177
178/* forward declaration */
179struct brcmf_cfg80211_info;
180
179/* cfg80211 main event loop */ 181/* cfg80211 main event loop */
180struct brcmf_cfg80211_event_loop { 182struct brcmf_cfg80211_event_loop {
181 s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv, 183 s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg,
182 struct net_device *ndev, 184 struct net_device *ndev,
183 const struct brcmf_event_msg *e, 185 const struct brcmf_event_msg *e,
184 void *data); 186 void *data);
185}; 187};
186 188
187/* representing interface of cfg80211 plane */
188struct brcmf_cfg80211_iface {
189 struct brcmf_cfg80211_priv *cfg_priv;
190};
191
192struct brcmf_cfg80211_dev {
193 void *driver_data; /* to store cfg80211 object information */
194};
195
196/* basic structure of scan request */ 189/* basic structure of scan request */
197struct brcmf_cfg80211_scan_req { 190struct brcmf_cfg80211_scan_req {
198 struct brcmf_ssid_le ssid_le; 191 struct brcmf_ssid_le ssid_le;
@@ -245,7 +238,7 @@ struct brcmf_cfg80211_profile {
245/* dongle iscan event loop */ 238/* dongle iscan event loop */
246struct brcmf_cfg80211_iscan_eloop { 239struct brcmf_cfg80211_iscan_eloop {
247 s32 (*handler[WL_SCAN_ERSULTS_LAST]) 240 s32 (*handler[WL_SCAN_ERSULTS_LAST])
248 (struct brcmf_cfg80211_priv *cfg_priv); 241 (struct brcmf_cfg80211_info *cfg);
249}; 242};
250 243
251/* dongle iscan controller */ 244/* dongle iscan controller */
@@ -295,6 +288,17 @@ struct escan_info {
295 struct net_device *ndev; 288 struct net_device *ndev;
296}; 289};
297 290
291/* Structure to hold WPS, WPA IEs for a AP */
292struct ap_info {
293 u8 probe_res_ie[IE_MAX_LEN];
294 u8 beacon_ie[IE_MAX_LEN];
295 u32 probe_res_ie_len;
296 u32 beacon_ie_len;
297 u8 *wpa_ie;
298 u8 *rsn_ie;
299 bool security_mode;
300};
301
298/** 302/**
299 * struct brcmf_pno_param_le - PNO scan configuration parameters 303 * struct brcmf_pno_param_le - PNO scan configuration parameters
300 * 304 *
@@ -377,7 +381,7 @@ struct brcmf_pno_scanresults_le {
377}; 381};
378 382
379/** 383/**
380 * struct brcmf_cfg80211_priv - dongle private data of cfg80211 interface 384 * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
381 * 385 *
382 * @wdev: representing wl cfg80211 device. 386 * @wdev: representing wl cfg80211 device.
383 * @conf: dongle configuration. 387 * @conf: dongle configuration.
@@ -417,9 +421,10 @@ struct brcmf_pno_scanresults_le {
417 * @escan_timeout: Timer for catch scan timeout. 421 * @escan_timeout: Timer for catch scan timeout.
418 * @escan_timeout_work: scan timeout worker. 422 * @escan_timeout_work: scan timeout worker.
419 * @escan_ioctl_buf: dongle command buffer for escan commands. 423 * @escan_ioctl_buf: dongle command buffer for escan commands.
424 * @ap_info: host ap information.
420 * @ci: used to link this structure to netdev private data. 425 * @ci: used to link this structure to netdev private data.
421 */ 426 */
422struct brcmf_cfg80211_priv { 427struct brcmf_cfg80211_info {
423 struct wireless_dev *wdev; 428 struct wireless_dev *wdev;
424 struct brcmf_cfg80211_conf *conf; 429 struct brcmf_cfg80211_conf *conf;
425 struct cfg80211_scan_request *scan_request; 430 struct cfg80211_scan_request *scan_request;
@@ -458,52 +463,52 @@ struct brcmf_cfg80211_priv {
458 struct timer_list escan_timeout; 463 struct timer_list escan_timeout;
459 struct work_struct escan_timeout_work; 464 struct work_struct escan_timeout_work;
460 u8 *escan_ioctl_buf; 465 u8 *escan_ioctl_buf;
461 u8 ci[0] __aligned(NETDEV_ALIGN); 466 struct ap_info *ap_info;
462}; 467};
463 468
464static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w) 469static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *w)
465{ 470{
466 return w->wdev->wiphy; 471 return w->wdev->wiphy;
467} 472}
468 473
469static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w) 474static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
470{ 475{
471 return (struct brcmf_cfg80211_priv *)(wiphy_priv(w)); 476 return (struct brcmf_cfg80211_info *)(wiphy_priv(w));
472} 477}
473 478
474static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd) 479static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd)
475{ 480{
476 return (struct brcmf_cfg80211_priv *)(wdev_priv(wd)); 481 return (struct brcmf_cfg80211_info *)(wdev_priv(wd));
477} 482}
478 483
479static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg) 484static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
480{ 485{
481 return cfg->wdev->netdev; 486 return cfg->wdev->netdev;
482} 487}
483 488
484static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev) 489static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
485{ 490{
486 return wdev_to_cfg(ndev->ieee80211_ptr); 491 return wdev_to_cfg(ndev->ieee80211_ptr);
487} 492}
488 493
489#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data)) 494#define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data))
490#define cfg_to_iscan(w) (w->iscan) 495#define cfg_to_iscan(w) (w->iscan)
491 496
492static inline struct 497static inline struct
493brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg) 498brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
494{ 499{
495 return &cfg->conn_info; 500 return &cfg->conn_info;
496} 501}
497 502
498extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, 503struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
499 struct device *busdev, 504 struct device *busdev,
500 struct brcmf_pub *drvr); 505 struct brcmf_pub *drvr);
501extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg); 506void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
502 507
503/* event handler from dongle */ 508/* event handler from dongle */
504extern void brcmf_cfg80211_event(struct net_device *ndev, 509void brcmf_cfg80211_event(struct net_device *ndev,
505 const struct brcmf_event_msg *e, void *data); 510 const struct brcmf_event_msg *e, void *data);
506extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev); 511s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg);
507extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev); 512s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg);
508 513
509#endif /* _wl_cfg80211_h_ */ 514#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 24e2582b467c..9402b93b9a36 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -302,6 +302,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
302 new_node->start_win = last_seq + 1; 302 new_node->start_win = last_seq + 1;
303 303
304 new_node->win_size = win_size; 304 new_node->win_size = win_size;
305 new_node->flags = 0;
305 306
306 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size, 307 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
307 GFP_KERNEL); 308 GFP_KERNEL);
@@ -457,13 +458,20 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
457 * If seq_num is less then starting win then ignore and drop the 458 * If seq_num is less then starting win then ignore and drop the
458 * packet 459 * packet
459 */ 460 */
460 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ 461 if (tbl->flags & RXREOR_FORCE_NO_DROP) {
461 if (seq_num >= ((start_win + TWOPOW11) & 462 dev_dbg(priv->adapter->dev,
462 (MAX_TID_VALUE - 1)) && (seq_num < start_win)) 463 "RXREOR_FORCE_NO_DROP when HS is activated\n");
464 tbl->flags &= ~RXREOR_FORCE_NO_DROP;
465 } else {
466 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {
467 if (seq_num >= ((start_win + TWOPOW11) &
468 (MAX_TID_VALUE - 1)) &&
469 seq_num < start_win)
470 return -1;
471 } else if ((seq_num < start_win) ||
472 (seq_num > (start_win + TWOPOW11))) {
463 return -1; 473 return -1;
464 } else if ((seq_num < start_win) || 474 }
465 (seq_num > (start_win + TWOPOW11))) {
466 return -1;
467 } 475 }
468 476
469 /* 477 /*
@@ -474,8 +482,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
474 seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); 482 seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
475 483
476 if (((end_win < start_win) && 484 if (((end_win < start_win) &&
477 (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) && 485 (seq_num < start_win) && (seq_num > end_win)) ||
478 (seq_num > end_win)) ||
479 ((end_win > start_win) && ((seq_num > end_win) || 486 ((end_win > start_win) && ((seq_num > end_win) ||
480 (seq_num < start_win)))) { 487 (seq_num < start_win)))) {
481 end_win = seq_num; 488 end_win = seq_num;
@@ -637,3 +644,29 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
637 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); 644 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
638 mwifiex_reset_11n_rx_seq_num(priv); 645 mwifiex_reset_11n_rx_seq_num(priv);
639} 646}
647
648/*
649 * This function updates all rx_reorder_tbl's flags.
650 */
651void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
652{
653 struct mwifiex_private *priv;
654 struct mwifiex_rx_reorder_tbl *tbl;
655 unsigned long lock_flags;
656 int i;
657
658 for (i = 0; i < adapter->priv_num; i++) {
659 priv = adapter->priv[i];
660 if (!priv)
661 continue;
662 if (list_empty(&priv->rx_reorder_tbl_ptr))
663 continue;
664
665 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags);
666 list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
667 tbl->flags = flags;
668 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags);
669 }
670
671 return;
672}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 72848591691a..4064041ac852 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -41,6 +41,10 @@
41#define BA_SETUP_MAX_PACKET_THRESHOLD 16 41#define BA_SETUP_MAX_PACKET_THRESHOLD 16
42#define BA_SETUP_PACKET_OFFSET 16 42#define BA_SETUP_PACKET_OFFSET 16
43 43
44enum mwifiex_rxreor_flags {
45 RXREOR_FORCE_NO_DROP = 1<<0,
46};
47
44static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) 48static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv)
45{ 49{
46 memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); 50 memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq));
@@ -73,5 +77,6 @@ struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct
73struct mwifiex_rx_reorder_tbl * 77struct mwifiex_rx_reorder_tbl *
74mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta); 78mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta);
75void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta); 79void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta);
80void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags);
76 81
77#endif /* _MWIFIEX_11N_RXREORDER_H_ */ 82#endif /* _MWIFIEX_11N_RXREORDER_H_ */
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c24824f8c8a1..2691620393ea 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -22,7 +22,7 @@
22 22
23static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = { 23static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
24 { 24 {
25 .max = 1, .types = BIT(NL80211_IFTYPE_STATION), 25 .max = 2, .types = BIT(NL80211_IFTYPE_STATION),
26 }, 26 },
27 { 27 {
28 .max = 1, .types = BIT(NL80211_IFTYPE_AP), 28 .max = 1, .types = BIT(NL80211_IFTYPE_AP),
@@ -77,8 +77,7 @@ static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
77 * NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW 77 * NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW
78 * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE 78 * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE
79 */ 79 */
80static u8 80u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
81mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
82{ 81{
83 switch (chan_type) { 82 switch (chan_type) {
84 case NL80211_CHAN_NO_HT: 83 case NL80211_CHAN_NO_HT:
@@ -139,6 +138,188 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
139} 138}
140 139
141/* 140/*
141 * This function forms an skb for management frame.
142 */
143static int
144mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
145{
146 u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
147 u16 pkt_len;
148 u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
149 struct timeval tv;
150
151 pkt_len = len + ETH_ALEN;
152
153 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN +
154 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
155 memcpy(skb_push(skb, sizeof(pkt_len)), &pkt_len, sizeof(pkt_len));
156
157 memcpy(skb_push(skb, sizeof(tx_control)),
158 &tx_control, sizeof(tx_control));
159
160 memcpy(skb_push(skb, sizeof(pkt_type)), &pkt_type, sizeof(pkt_type));
161
162 /* Add packet data and address4 */
163 memcpy(skb_put(skb, sizeof(struct ieee80211_hdr_3addr)), buf,
164 sizeof(struct ieee80211_hdr_3addr));
165 memcpy(skb_put(skb, ETH_ALEN), addr, ETH_ALEN);
166 memcpy(skb_put(skb, len - sizeof(struct ieee80211_hdr_3addr)),
167 buf + sizeof(struct ieee80211_hdr_3addr),
168 len - sizeof(struct ieee80211_hdr_3addr));
169
170 skb->priority = LOW_PRIO_TID;
171 do_gettimeofday(&tv);
172 skb->tstamp = timeval_to_ktime(tv);
173
174 return 0;
175}
176
177/*
178 * CFG802.11 operation handler to transmit a management frame.
179 */
180static int
181mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
182 struct ieee80211_channel *chan, bool offchan,
183 enum nl80211_channel_type channel_type,
184 bool channel_type_valid, unsigned int wait,
185 const u8 *buf, size_t len, bool no_cck,
186 bool dont_wait_for_ack, u64 *cookie)
187{
188 struct sk_buff *skb;
189 u16 pkt_len;
190 const struct ieee80211_mgmt *mgmt;
191 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
192
193 if (!buf || !len) {
194 wiphy_err(wiphy, "invalid buffer and length\n");
195 return -EFAULT;
196 }
197
198 mgmt = (const struct ieee80211_mgmt *)buf;
199 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA &&
200 ieee80211_is_probe_resp(mgmt->frame_control)) {
201 /* Since we support offload probe resp, we need to skip probe
202 * resp in AP or GO mode */
203 wiphy_dbg(wiphy,
204 "info: skip to send probe resp in AP or GO mode\n");
205 return 0;
206 }
207
208 pkt_len = len + ETH_ALEN;
209 skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
210 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
211 pkt_len + sizeof(pkt_len));
212
213 if (!skb) {
214 wiphy_err(wiphy, "allocate skb failed for management frame\n");
215 return -ENOMEM;
216 }
217
218 mwifiex_form_mgmt_frame(skb, buf, len);
219 mwifiex_queue_tx_pkt(priv, skb);
220
221 *cookie = random32() | 1;
222 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_ATOMIC);
223
224 wiphy_dbg(wiphy, "info: management frame transmitted\n");
225 return 0;
226}
227
228/*
229 * CFG802.11 operation handler to register a mgmt frame.
230 */
231static void
232mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
233 struct wireless_dev *wdev,
234 u16 frame_type, bool reg)
235{
236 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
237
238 if (reg)
239 priv->mgmt_frame_mask |= BIT(frame_type >> 4);
240 else
241 priv->mgmt_frame_mask &= ~BIT(frame_type >> 4);
242
243 mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG,
244 HostCmd_ACT_GEN_SET, 0, &priv->mgmt_frame_mask);
245
246 wiphy_dbg(wiphy, "info: mgmt frame registered\n");
247}
248
249/*
250 * CFG802.11 operation handler to remain on channel.
251 */
252static int
253mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
254 struct wireless_dev *wdev,
255 struct ieee80211_channel *chan,
256 enum nl80211_channel_type channel_type,
257 unsigned int duration, u64 *cookie)
258{
259 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
260 int ret;
261
262 if (!chan || !cookie) {
263 wiphy_err(wiphy, "Invalid parameter for ROC\n");
264 return -EINVAL;
265 }
266
267 if (priv->roc_cfg.cookie) {
268 wiphy_dbg(wiphy, "info: ongoing ROC, cookie = 0x%llu\n",
269 priv->roc_cfg.cookie);
270 return -EBUSY;
271 }
272
273 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan,
274 &channel_type, duration);
275
276 if (!ret) {
277 *cookie = random32() | 1;
278 priv->roc_cfg.cookie = *cookie;
279 priv->roc_cfg.chan = *chan;
280 priv->roc_cfg.chan_type = channel_type;
281
282 cfg80211_ready_on_channel(wdev, *cookie, chan, channel_type,
283 duration, GFP_ATOMIC);
284
285 wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie);
286 }
287
288 return ret;
289}
290
291/*
292 * CFG802.11 operation handler to cancel remain on channel.
293 */
294static int
295mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
296 struct wireless_dev *wdev, u64 cookie)
297{
298 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
299 int ret;
300
301 if (cookie != priv->roc_cfg.cookie)
302 return -ENOENT;
303
304 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
305 &priv->roc_cfg.chan,
306 &priv->roc_cfg.chan_type, 0);
307
308 if (!ret) {
309 cfg80211_remain_on_channel_expired(wdev, cookie,
310 &priv->roc_cfg.chan,
311 priv->roc_cfg.chan_type,
312 GFP_ATOMIC);
313
314 memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg));
315
316 wiphy_dbg(wiphy, "info: cancel ROC, cookie = 0x%llx\n", cookie);
317 }
318
319 return ret;
320}
321
322/*
142 * CFG802.11 operation handler to set Tx power. 323 * CFG802.11 operation handler to set Tx power.
143 */ 324 */
144static int 325static int
@@ -493,6 +674,76 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
493 return 0; 674 return 0;
494} 675}
495 676
677static int
678mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
679{
680 u16 mode = P2P_MODE_DISABLE;
681
682 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA)
683 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA);
684
685 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
686 HostCmd_ACT_GEN_SET, 0, &mode))
687 return -1;
688
689 return 0;
690}
691
692/*
693 * This function initializes the functionalities for P2P client.
694 * The P2P client initialization sequence is:
695 * disable -> device -> client
696 */
697static int
698mwifiex_cfg80211_init_p2p_client(struct mwifiex_private *priv)
699{
700 u16 mode;
701
702 if (mwifiex_cfg80211_deinit_p2p(priv))
703 return -1;
704
705 mode = P2P_MODE_DEVICE;
706 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
707 HostCmd_ACT_GEN_SET, 0, &mode))
708 return -1;
709
710 mode = P2P_MODE_CLIENT;
711 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
712 HostCmd_ACT_GEN_SET, 0, &mode))
713 return -1;
714
715 return 0;
716}
717
718/*
719 * This function initializes the functionalities for P2P GO.
720 * The P2P GO initialization sequence is:
721 * disable -> device -> GO
722 */
723static int
724mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
725{
726 u16 mode;
727
728 if (mwifiex_cfg80211_deinit_p2p(priv))
729 return -1;
730
731 mode = P2P_MODE_DEVICE;
732 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
733 HostCmd_ACT_GEN_SET, 0, &mode))
734 return -1;
735
736 mode = P2P_MODE_GO;
737 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
738 HostCmd_ACT_GEN_SET, 0, &mode))
739 return -1;
740
741 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
742 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_UAP);
743
744 return 0;
745}
746
496/* 747/*
497 * CFG802.11 operation handler to change interface type. 748 * CFG802.11 operation handler to change interface type.
498 */ 749 */
@@ -525,6 +776,16 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
525 switch (type) { 776 switch (type) {
526 case NL80211_IFTYPE_ADHOC: 777 case NL80211_IFTYPE_ADHOC:
527 break; 778 break;
779 case NL80211_IFTYPE_P2P_CLIENT:
780 if (mwifiex_cfg80211_init_p2p_client(priv))
781 return -EFAULT;
782 dev->ieee80211_ptr->iftype = type;
783 return 0;
784 case NL80211_IFTYPE_P2P_GO:
785 if (mwifiex_cfg80211_init_p2p_go(priv))
786 return -EFAULT;
787 dev->ieee80211_ptr->iftype = type;
788 return 0;
528 case NL80211_IFTYPE_UNSPECIFIED: 789 case NL80211_IFTYPE_UNSPECIFIED:
529 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name); 790 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
530 case NL80211_IFTYPE_STATION: /* This shouldn't happen */ 791 case NL80211_IFTYPE_STATION: /* This shouldn't happen */
@@ -550,6 +811,18 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
550 return -EOPNOTSUPP; 811 return -EOPNOTSUPP;
551 } 812 }
552 break; 813 break;
814 case NL80211_IFTYPE_P2P_CLIENT:
815 case NL80211_IFTYPE_P2P_GO:
816 switch (type) {
817 case NL80211_IFTYPE_STATION:
818 if (mwifiex_cfg80211_deinit_p2p(priv))
819 return -EFAULT;
820 dev->ieee80211_ptr->iftype = type;
821 return 0;
822 default:
823 return -EOPNOTSUPP;
824 }
825 break;
553 default: 826 default:
554 wiphy_err(wiphy, "%s: unknown iftype: %d\n", 827 wiphy_err(wiphy, "%s: unknown iftype: %d\n",
555 dev->name, dev->ieee80211_ptr->iftype); 828 dev->name, dev->ieee80211_ptr->iftype);
@@ -688,7 +961,6 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
688} 961}
689 962
690/* Supported rates to be advertised to the cfg80211 */ 963/* Supported rates to be advertised to the cfg80211 */
691
692static struct ieee80211_rate mwifiex_rates[] = { 964static struct ieee80211_rate mwifiex_rates[] = {
693 {.bitrate = 10, .hw_value = 2, }, 965 {.bitrate = 10, .hw_value = 2, },
694 {.bitrate = 20, .hw_value = 4, }, 966 {.bitrate = 20, .hw_value = 4, },
@@ -705,7 +977,6 @@ static struct ieee80211_rate mwifiex_rates[] = {
705}; 977};
706 978
707/* Channel definitions to be advertised to cfg80211 */ 979/* Channel definitions to be advertised to cfg80211 */
708
709static struct ieee80211_channel mwifiex_channels_2ghz[] = { 980static struct ieee80211_channel mwifiex_channels_2ghz[] = {
710 {.center_freq = 2412, .hw_value = 1, }, 981 {.center_freq = 2412, .hw_value = 1, },
711 {.center_freq = 2417, .hw_value = 2, }, 982 {.center_freq = 2417, .hw_value = 2, },
@@ -773,7 +1044,6 @@ static struct ieee80211_supported_band mwifiex_band_5ghz = {
773 1044
774 1045
775/* Supported crypto cipher suits to be advertised to cfg80211 */ 1046/* Supported crypto cipher suits to be advertised to cfg80211 */
776
777static const u32 mwifiex_cipher_suites[] = { 1047static const u32 mwifiex_cipher_suites[] = {
778 WLAN_CIPHER_SUITE_WEP40, 1048 WLAN_CIPHER_SUITE_WEP40,
779 WLAN_CIPHER_SUITE_WEP104, 1049 WLAN_CIPHER_SUITE_WEP104,
@@ -782,6 +1052,35 @@ static const u32 mwifiex_cipher_suites[] = {
782 WLAN_CIPHER_SUITE_AES_CMAC, 1052 WLAN_CIPHER_SUITE_AES_CMAC,
783}; 1053};
784 1054
1055/* Supported mgmt frame types to be advertised to cfg80211 */
1056static const struct ieee80211_txrx_stypes
1057mwifiex_mgmt_stypes[NUM_NL80211_IFTYPES] = {
1058 [NL80211_IFTYPE_STATION] = {
1059 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1060 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1061 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1062 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
1063 },
1064 [NL80211_IFTYPE_AP] = {
1065 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1066 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1067 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1068 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
1069 },
1070 [NL80211_IFTYPE_P2P_CLIENT] = {
1071 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1072 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1073 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1074 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
1075 },
1076 [NL80211_IFTYPE_P2P_GO] = {
1077 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1078 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1079 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1080 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
1081 },
1082};
1083
785/* 1084/*
786 * CFG802.11 operation handler for setting bit rates. 1085 * CFG802.11 operation handler for setting bit rates.
787 * 1086 *
@@ -874,7 +1173,7 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
874{ 1173{
875 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1174 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
876 1175
877 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 1176 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) {
878 wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__); 1177 wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__);
879 return -EINVAL; 1178 return -EINVAL;
880 } 1179 }
@@ -962,7 +1261,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
962 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1261 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
963 u8 config_bands = 0; 1262 u8 config_bands = 0;
964 1263
965 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) 1264 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
966 return -1; 1265 return -1;
967 if (mwifiex_set_mgmt_ies(priv, &params->beacon)) 1266 if (mwifiex_set_mgmt_ies(priv, &params->beacon))
968 return -1; 1267 return -1;
@@ -1032,6 +1331,12 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1032 1331
1033 mwifiex_set_ht_params(priv, bss_cfg, params); 1332 mwifiex_set_ht_params(priv, bss_cfg, params);
1034 1333
1334 if (params->inactivity_timeout > 0) {
1335 /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */
1336 bss_cfg->sta_ao_timer = 10 * params->inactivity_timeout;
1337 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout;
1338 }
1339
1035 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, 1340 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
1036 HostCmd_ACT_GEN_SET, 0, NULL)) { 1341 HostCmd_ACT_GEN_SET, 0, NULL)) {
1037 wiphy_err(wiphy, "Failed to stop the BSS\n"); 1342 wiphy_err(wiphy, "Failed to stop the BSS\n");
@@ -1497,8 +1802,9 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1497{ 1802{
1498 struct net_device *dev = request->wdev->netdev; 1803 struct net_device *dev = request->wdev->netdev;
1499 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1804 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1500 int i; 1805 int i, offset;
1501 struct ieee80211_channel *chan; 1806 struct ieee80211_channel *chan;
1807 struct ieee_types_header *ie;
1502 1808
1503 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); 1809 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1504 1810
@@ -1521,13 +1827,17 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1521 priv->user_scan_cfg->ssid_list = request->ssids; 1827 priv->user_scan_cfg->ssid_list = request->ssids;
1522 1828
1523 if (request->ie && request->ie_len) { 1829 if (request->ie && request->ie_len) {
1830 offset = 0;
1524 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) { 1831 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
1525 if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR) 1832 if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR)
1526 continue; 1833 continue;
1527 priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_SCAN; 1834 priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_SCAN;
1528 memcpy(&priv->vs_ie[i].ie, request->ie, 1835 ie = (struct ieee_types_header *)(request->ie + offset);
1529 request->ie_len); 1836 memcpy(&priv->vs_ie[i].ie, ie, sizeof(*ie) + ie->len);
1530 break; 1837 offset += sizeof(*ie) + ie->len;
1838
1839 if (offset >= request->ie_len)
1840 break;
1531 } 1841 }
1532 } 1842 }
1533 1843
@@ -1706,6 +2016,41 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1706 priv->bss_mode = type; 2016 priv->bss_mode = type;
1707 2017
1708 break; 2018 break;
2019 case NL80211_IFTYPE_P2P_CLIENT:
2020 priv = adapter->priv[MWIFIEX_BSS_TYPE_P2P];
2021
2022 if (priv->bss_mode) {
2023 wiphy_err(wiphy, "Can't create multiple P2P ifaces");
2024 return ERR_PTR(-EINVAL);
2025 }
2026
2027 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2028 if (!wdev)
2029 return ERR_PTR(-ENOMEM);
2030
2031 priv->wdev = wdev;
2032 wdev->wiphy = wiphy;
2033
2034 /* At start-up, wpa_supplicant tries to change the interface
2035 * to NL80211_IFTYPE_STATION if it is not managed mode.
2036 * So, we initialize it to STA mode.
2037 */
2038 wdev->iftype = NL80211_IFTYPE_STATION;
2039 priv->bss_mode = NL80211_IFTYPE_STATION;
2040
2041 /* Setting bss_type to P2P tells firmware that this interface
2042 * is receiving P2P peers found during find phase and doing
2043 * action frame handshake.
2044 */
2045 priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
2046
2047 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
2048 priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
2049 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
2050 priv->bss_started = 0;
2051 priv->bss_num = 0;
2052
2053 break;
1709 default: 2054 default:
1710 wiphy_err(wiphy, "type not supported\n"); 2055 wiphy_err(wiphy, "type not supported\n");
1711 return ERR_PTR(-EINVAL); 2056 return ERR_PTR(-EINVAL);
@@ -1813,6 +2158,10 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1813 .leave_ibss = mwifiex_cfg80211_leave_ibss, 2158 .leave_ibss = mwifiex_cfg80211_leave_ibss,
1814 .add_key = mwifiex_cfg80211_add_key, 2159 .add_key = mwifiex_cfg80211_add_key,
1815 .del_key = mwifiex_cfg80211_del_key, 2160 .del_key = mwifiex_cfg80211_del_key,
2161 .mgmt_tx = mwifiex_cfg80211_mgmt_tx,
2162 .mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register,
2163 .remain_on_channel = mwifiex_cfg80211_remain_on_channel,
2164 .cancel_remain_on_channel = mwifiex_cfg80211_cancel_remain_on_channel,
1816 .set_default_key = mwifiex_cfg80211_set_default_key, 2165 .set_default_key = mwifiex_cfg80211_set_default_key,
1817 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, 2166 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
1818 .set_tx_power = mwifiex_cfg80211_set_tx_power, 2167 .set_tx_power = mwifiex_cfg80211_set_tx_power,
@@ -1849,8 +2198,12 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
1849 } 2198 }
1850 wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH; 2199 wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
1851 wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; 2200 wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
2201 wiphy->mgmt_stypes = mwifiex_mgmt_stypes;
2202 wiphy->max_remain_on_channel_duration = 5000;
1852 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2203 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1853 BIT(NL80211_IFTYPE_ADHOC) | 2204 BIT(NL80211_IFTYPE_ADHOC) |
2205 BIT(NL80211_IFTYPE_P2P_CLIENT) |
2206 BIT(NL80211_IFTYPE_P2P_GO) |
1854 BIT(NL80211_IFTYPE_AP); 2207 BIT(NL80211_IFTYPE_AP);
1855 2208
1856 wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; 2209 wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
@@ -1870,17 +2223,20 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
1870 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 2223 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1871 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 2224 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
1872 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 2225 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
1873 WIPHY_FLAG_CUSTOM_REGULATORY; 2226 WIPHY_FLAG_CUSTOM_REGULATORY |
2227 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
1874 2228
1875 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom); 2229 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
1876 2230
1877 wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | 2231 wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
1878 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2; 2232 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
2233 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
1879 2234
1880 wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1; 2235 wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1;
1881 wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1; 2236 wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1;
1882 2237
1883 wiphy->features = NL80211_FEATURE_HT_IBSS; 2238 wiphy->features = NL80211_FEATURE_HT_IBSS |
2239 NL80211_FEATURE_INACTIVITY_TIMER;
1884 2240
1885 /* Reserve space for mwifiex specific private data for BSS */ 2241 /* Reserve space for mwifiex specific private data for BSS */
1886 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); 2242 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 225c1a4feeba..8d465107f52b 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1088,6 +1088,8 @@ mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated)
1088 if (activated) { 1088 if (activated) {
1089 if (priv->adapter->is_hs_configured) { 1089 if (priv->adapter->is_hs_configured) {
1090 priv->adapter->hs_activated = true; 1090 priv->adapter->hs_activated = true;
1091 mwifiex_update_rxreor_flags(priv->adapter,
1092 RXREOR_FORCE_NO_DROP);
1091 dev_dbg(priv->adapter->dev, "event: hs_activated\n"); 1093 dev_dbg(priv->adapter->dev, "event: hs_activated\n");
1092 priv->adapter->hs_activate_wait_q_woken = true; 1094 priv->adapter->hs_activate_wait_q_woken = true;
1093 wake_up_interruptible( 1095 wake_up_interruptible(
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 400d360ac91f..e9357d87d327 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -28,11 +28,14 @@
28#include <linux/ieee80211.h> 28#include <linux/ieee80211.h>
29 29
30 30
31#define MWIFIEX_MAX_BSS_NUM (2) 31#define MWIFIEX_MAX_BSS_NUM (3)
32 32
33#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd) 33#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd)
34 * + 4 byte alignment 34 * + 4 byte alignment
35 */ 35 */
36#define MWIFIEX_MGMT_FRAME_HEADER_SIZE 8 /* sizeof(pkt_type)
37 * + sizeof(tx_control)
38 */
36 39
37#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2 40#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
38#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16 41#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16
@@ -67,6 +70,7 @@
67enum mwifiex_bss_type { 70enum mwifiex_bss_type {
68 MWIFIEX_BSS_TYPE_STA = 0, 71 MWIFIEX_BSS_TYPE_STA = 0,
69 MWIFIEX_BSS_TYPE_UAP = 1, 72 MWIFIEX_BSS_TYPE_UAP = 1,
73 MWIFIEX_BSS_TYPE_P2P = 2,
70 MWIFIEX_BSS_TYPE_ANY = 0xff, 74 MWIFIEX_BSS_TYPE_ANY = 0xff,
71}; 75};
72 76
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index b8ce78e2ba47..dda588b35570 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -94,6 +94,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
94}; 94};
95 95
96#define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF))) 96#define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF)))
97#define CAL_RSSI(SNR, NF) ((s16)((s16)(SNR)+(s16)(NF)))
97 98
98#define UAP_BSS_PARAMS_I 0 99#define UAP_BSS_PARAMS_I 0
99#define UAP_CUSTOM_IE_I 1 100#define UAP_CUSTOM_IE_I 1
@@ -127,6 +128,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
127#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) 128#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
128#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) 129#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48)
129#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) 130#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51)
131#define TLV_TYPE_UAP_AO_TIMER (PROPRIETARY_TLV_BASE_ID + 57)
130#define TLV_TYPE_UAP_WEP_KEY (PROPRIETARY_TLV_BASE_ID + 59) 132#define TLV_TYPE_UAP_WEP_KEY (PROPRIETARY_TLV_BASE_ID + 59)
131#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) 133#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
132#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) 134#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64)
@@ -141,6 +143,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
141#define TLV_TYPE_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 105) 143#define TLV_TYPE_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 105)
142#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113) 144#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113)
143#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114) 145#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114)
146#define TLV_TYPE_UAP_PS_AO_TIMER (PROPRIETARY_TLV_BASE_ID + 123)
144#define TLV_TYPE_PWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 145) 147#define TLV_TYPE_PWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 145)
145#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146) 148#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146)
146 149
@@ -260,9 +263,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
260#define HostCmd_CMD_TX_RATE_CFG 0x00d6 263#define HostCmd_CMD_TX_RATE_CFG 0x00d6
261#define HostCmd_CMD_802_11_PS_MODE_ENH 0x00e4 264#define HostCmd_CMD_802_11_PS_MODE_ENH 0x00e4
262#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5 265#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5
266#define HostCmd_CMD_P2P_MODE_CFG 0x00eb
263#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed 267#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed
264#define HostCmd_CMD_SET_BSS_MODE 0x00f7 268#define HostCmd_CMD_SET_BSS_MODE 0x00f7
265#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa 269#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
270#define HostCmd_CMD_MGMT_FRAME_REG 0x010c
271#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d
266 272
267#define PROTOCOL_NO_SECURITY 0x01 273#define PROTOCOL_NO_SECURITY 0x01
268#define PROTOCOL_STATIC_WEP 0x02 274#define PROTOCOL_STATIC_WEP 0x02
@@ -288,9 +294,17 @@ enum ENH_PS_MODES {
288 DIS_AUTO_PS = 0xfe, 294 DIS_AUTO_PS = 0xfe,
289}; 295};
290 296
297enum P2P_MODES {
298 P2P_MODE_DISABLE = 0,
299 P2P_MODE_DEVICE = 1,
300 P2P_MODE_GO = 2,
301 P2P_MODE_CLIENT = 3,
302};
303
291#define HostCmd_RET_BIT 0x8000 304#define HostCmd_RET_BIT 0x8000
292#define HostCmd_ACT_GEN_GET 0x0000 305#define HostCmd_ACT_GEN_GET 0x0000
293#define HostCmd_ACT_GEN_SET 0x0001 306#define HostCmd_ACT_GEN_SET 0x0001
307#define HostCmd_ACT_GEN_REMOVE 0x0004
294#define HostCmd_ACT_BITWISE_SET 0x0002 308#define HostCmd_ACT_BITWISE_SET 0x0002
295#define HostCmd_ACT_BITWISE_CLR 0x0003 309#define HostCmd_ACT_BITWISE_CLR 0x0003
296#define HostCmd_RESULT_OK 0x0000 310#define HostCmd_RESULT_OK 0x0000
@@ -388,6 +402,7 @@ enum ENH_PS_MODES {
388#define EVENT_BW_CHANGE 0x00000048 402#define EVENT_BW_CHANGE 0x00000048
389#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c 403#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c
390#define EVENT_HOSTWAKE_STAIE 0x0000004d 404#define EVENT_HOSTWAKE_STAIE 0x0000004d
405#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
391 406
392#define EVENT_ID_MASK 0xffff 407#define EVENT_ID_MASK 0xffff
393#define BSS_NUM_MASK 0xf 408#define BSS_NUM_MASK 0xf
@@ -1331,11 +1346,35 @@ struct host_cmd_tlv_channel_band {
1331 u8 channel; 1346 u8 channel;
1332} __packed; 1347} __packed;
1333 1348
1349struct host_cmd_tlv_ageout_timer {
1350 struct host_cmd_tlv tlv;
1351 __le32 sta_ao_timer;
1352} __packed;
1353
1334struct host_cmd_ds_version_ext { 1354struct host_cmd_ds_version_ext {
1335 u8 version_str_sel; 1355 u8 version_str_sel;
1336 char version_str[128]; 1356 char version_str[128];
1337} __packed; 1357} __packed;
1338 1358
1359struct host_cmd_ds_mgmt_frame_reg {
1360 __le16 action;
1361 __le32 mask;
1362} __packed;
1363
1364struct host_cmd_ds_p2p_mode_cfg {
1365 __le16 action;
1366 __le16 mode;
1367} __packed;
1368
1369struct host_cmd_ds_remain_on_chan {
1370 __le16 action;
1371 u8 status;
1372 u8 reserved;
1373 u8 band_cfg;
1374 u8 channel;
1375 __le32 duration;
1376} __packed;
1377
1339struct host_cmd_ds_802_11_ibss_status { 1378struct host_cmd_ds_802_11_ibss_status {
1340 __le16 action; 1379 __le16 action;
1341 __le16 enable; 1380 __le16 enable;
@@ -1347,6 +1386,7 @@ struct host_cmd_ds_802_11_ibss_status {
1347 1386
1348#define CONNECTION_TYPE_INFRA 0 1387#define CONNECTION_TYPE_INFRA 0
1349#define CONNECTION_TYPE_ADHOC 1 1388#define CONNECTION_TYPE_ADHOC 1
1389#define CONNECTION_TYPE_AP 2
1350 1390
1351struct host_cmd_ds_set_bss_mode { 1391struct host_cmd_ds_set_bss_mode {
1352 u8 con_type; 1392 u8 con_type;
@@ -1444,6 +1484,9 @@ struct host_cmd_ds_command {
1444 struct host_cmd_ds_wmm_get_status get_wmm_status; 1484 struct host_cmd_ds_wmm_get_status get_wmm_status;
1445 struct host_cmd_ds_802_11_key_material key_material; 1485 struct host_cmd_ds_802_11_key_material key_material;
1446 struct host_cmd_ds_version_ext verext; 1486 struct host_cmd_ds_version_ext verext;
1487 struct host_cmd_ds_mgmt_frame_reg reg_mask;
1488 struct host_cmd_ds_remain_on_chan roc_cfg;
1489 struct host_cmd_ds_p2p_mode_cfg mode_cfg;
1447 struct host_cmd_ds_802_11_ibss_status ibss_coalescing; 1490 struct host_cmd_ds_802_11_ibss_status ibss_coalescing;
1448 struct host_cmd_ds_mac_reg_access mac_reg; 1491 struct host_cmd_ds_mac_reg_access mac_reg;
1449 struct host_cmd_ds_bbp_reg_access bbp_reg; 1492 struct host_cmd_ds_bbp_reg_access bbp_reg;
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index fa3a80fb8c01..e38342f86c51 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -114,9 +114,6 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
114 cpu_to_le16(mask); 114 cpu_to_le16(mask);
115 115
116 ie->ie_index = cpu_to_le16(index); 116 ie->ie_index = cpu_to_le16(index);
117 ie->ie_length = priv->mgmt_ie[index].ie_length;
118 memcpy(&ie->ie_buffer, &priv->mgmt_ie[index].ie_buffer,
119 le16_to_cpu(priv->mgmt_ie[index].ie_length));
120 } else { 117 } else {
121 if (mask != MWIFIEX_DELETE_MASK) 118 if (mask != MWIFIEX_DELETE_MASK)
122 return -1; 119 return -1;
@@ -214,30 +211,35 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv,
214 return ret; 211 return ret;
215} 212}
216 213
217/* This function checks if WPS IE is present in passed buffer and copies it to 214/* This function checks if the vendor specified IE is present in passed buffer
218 * mwifiex_ie structure. 215 * and copies it to mwifiex_ie structure.
219 * Function takes pointer to struct mwifiex_ie pointer as argument. 216 * Function takes pointer to struct mwifiex_ie pointer as argument.
220 * If WPS IE is present memory is allocated for mwifiex_ie pointer and filled 217 * If the vendor specified IE is present then memory is allocated for
221 * in with WPS IE. Caller should take care of freeing this memory. 218 * mwifiex_ie pointer and filled in with IE. Caller should take care of freeing
219 * this memory.
222 */ 220 */
223static int mwifiex_update_wps_ie(const u8 *ies, int ies_len, 221static int mwifiex_update_vs_ie(const u8 *ies, int ies_len,
224 struct mwifiex_ie **ie_ptr, u16 mask) 222 struct mwifiex_ie **ie_ptr, u16 mask,
223 unsigned int oui, u8 oui_type)
225{ 224{
226 struct ieee_types_header *wps_ie; 225 struct ieee_types_header *vs_ie;
227 struct mwifiex_ie *ie = NULL; 226 struct mwifiex_ie *ie = *ie_ptr;
228 const u8 *vendor_ie; 227 const u8 *vendor_ie;
229 228
230 vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 229 vendor_ie = cfg80211_find_vendor_ie(oui, oui_type, ies, ies_len);
231 WLAN_OUI_TYPE_MICROSOFT_WPS,
232 ies, ies_len);
233 if (vendor_ie) { 230 if (vendor_ie) {
234 ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); 231 if (!*ie_ptr) {
235 if (!ie) 232 *ie_ptr = kzalloc(sizeof(struct mwifiex_ie),
236 return -ENOMEM; 233 GFP_KERNEL);
234 if (!*ie_ptr)
235 return -ENOMEM;
236 ie = *ie_ptr;
237 }
237 238
238 wps_ie = (struct ieee_types_header *)vendor_ie; 239 vs_ie = (struct ieee_types_header *)vendor_ie;
239 memcpy(ie->ie_buffer, wps_ie, wps_ie->len + 2); 240 memcpy(ie->ie_buffer + le16_to_cpu(ie->ie_length),
240 ie->ie_length = cpu_to_le16(wps_ie->len + 2); 241 vs_ie, vs_ie->len + 2);
242 le16_add_cpu(&ie->ie_length, vs_ie->len + 2);
241 ie->mgmt_subtype_mask = cpu_to_le16(mask); 243 ie->mgmt_subtype_mask = cpu_to_le16(mask);
242 ie->ie_index = cpu_to_le16(MWIFIEX_AUTO_IDX_MASK); 244 ie->ie_index = cpu_to_le16(MWIFIEX_AUTO_IDX_MASK);
243 } 245 }
@@ -257,20 +259,40 @@ static int mwifiex_set_mgmt_beacon_data_ies(struct mwifiex_private *priv,
257 u16 ar_idx = MWIFIEX_AUTO_IDX_MASK; 259 u16 ar_idx = MWIFIEX_AUTO_IDX_MASK;
258 int ret = 0; 260 int ret = 0;
259 261
260 if (data->beacon_ies && data->beacon_ies_len) 262 if (data->beacon_ies && data->beacon_ies_len) {
261 mwifiex_update_wps_ie(data->beacon_ies, data->beacon_ies_len, 263 mwifiex_update_vs_ie(data->beacon_ies, data->beacon_ies_len,
262 &beacon_ie, MGMT_MASK_BEACON); 264 &beacon_ie, MGMT_MASK_BEACON,
265 WLAN_OUI_MICROSOFT,
266 WLAN_OUI_TYPE_MICROSOFT_WPS);
267 mwifiex_update_vs_ie(data->beacon_ies, data->beacon_ies_len,
268 &beacon_ie, MGMT_MASK_BEACON,
269 WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P);
270 }
263 271
264 if (data->proberesp_ies && data->proberesp_ies_len) 272 if (data->proberesp_ies && data->proberesp_ies_len) {
265 mwifiex_update_wps_ie(data->proberesp_ies, 273 mwifiex_update_vs_ie(data->proberesp_ies,
266 data->proberesp_ies_len, &pr_ie, 274 data->proberesp_ies_len, &pr_ie,
267 MGMT_MASK_PROBE_RESP); 275 MGMT_MASK_PROBE_RESP, WLAN_OUI_MICROSOFT,
276 WLAN_OUI_TYPE_MICROSOFT_WPS);
277 mwifiex_update_vs_ie(data->proberesp_ies,
278 data->proberesp_ies_len, &pr_ie,
279 MGMT_MASK_PROBE_RESP,
280 WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P);
281 }
268 282
269 if (data->assocresp_ies && data->assocresp_ies_len) 283 if (data->assocresp_ies && data->assocresp_ies_len) {
270 mwifiex_update_wps_ie(data->assocresp_ies, 284 mwifiex_update_vs_ie(data->assocresp_ies,
271 data->assocresp_ies_len, &ar_ie, 285 data->assocresp_ies_len, &ar_ie,
272 MGMT_MASK_ASSOC_RESP | 286 MGMT_MASK_ASSOC_RESP |
273 MGMT_MASK_REASSOC_RESP); 287 MGMT_MASK_REASSOC_RESP,
288 WLAN_OUI_MICROSOFT,
289 WLAN_OUI_TYPE_MICROSOFT_WPS);
290 mwifiex_update_vs_ie(data->assocresp_ies,
291 data->assocresp_ies_len, &ar_ie,
292 MGMT_MASK_ASSOC_RESP |
293 MGMT_MASK_REASSOC_RESP, WLAN_OUI_WFA,
294 WLAN_OUI_TYPE_WFA_P2P);
295 }
274 296
275 if (beacon_ie || pr_ie || ar_ie) { 297 if (beacon_ie || pr_ie || ar_ie) {
276 ret = mwifiex_update_uap_custom_ie(priv, beacon_ie, 298 ret = mwifiex_update_uap_custom_ie(priv, beacon_ie,
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index b2ba262f8a13..b5d37a8caa09 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -144,7 +144,7 @@ done:
144 * Additionally, it also initializes all the locks and sets up all the 144 * Additionally, it also initializes all the locks and sets up all the
145 * lists. 145 * lists.
146 */ 146 */
147static int mwifiex_init_priv(struct mwifiex_private *priv) 147int mwifiex_init_priv(struct mwifiex_private *priv)
148{ 148{
149 u32 i; 149 u32 i;
150 150
@@ -214,6 +214,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
214 priv->wps_ie = NULL; 214 priv->wps_ie = NULL;
215 priv->wps_ie_len = 0; 215 priv->wps_ie_len = 0;
216 priv->ap_11n_enabled = 0; 216 priv->ap_11n_enabled = 0;
217 memset(&priv->roc_cfg, 0, sizeof(priv->roc_cfg));
217 218
218 priv->scan_block = false; 219 priv->scan_block = false;
219 220
@@ -648,6 +649,17 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
648} 649}
649 650
650/* 651/*
652 * This function frees the private structure, including cleans
653 * up the TX and RX queues and frees the BSS priority tables.
654 */
655void mwifiex_free_priv(struct mwifiex_private *priv)
656{
657 mwifiex_clean_txrx(priv);
658 mwifiex_delete_bss_prio_tbl(priv);
659 mwifiex_free_curr_bcn(priv);
660}
661
662/*
651 * This function is used to shutdown the driver. 663 * This function is used to shutdown the driver.
652 * 664 *
653 * The following operations are performed sequentially - 665 * The following operations are performed sequentially -
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 8688535e95eb..4e31c6013ebe 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -105,6 +105,8 @@ struct mwifiex_uap_bss_param {
105 struct wep_key wep_cfg[NUM_WEP_KEYS]; 105 struct wep_key wep_cfg[NUM_WEP_KEYS];
106 struct ieee80211_ht_cap ht_cap; 106 struct ieee80211_ht_cap ht_cap;
107 u8 rates[MWIFIEX_SUPPORTED_RATES]; 107 u8 rates[MWIFIEX_SUPPORTED_RATES];
108 u32 sta_ao_timer;
109 u32 ps_sta_ao_timer;
108}; 110};
109 111
110enum { 112enum {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index bfd6667be01e..eb22dd248d54 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -369,6 +369,13 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
369 dev_err(adapter->dev, "cannot create default AP interface\n"); 369 dev_err(adapter->dev, "cannot create default AP interface\n");
370 goto err_add_intf; 370 goto err_add_intf;
371 } 371 }
372
373 /* Create P2P interface by default */
374 if (!mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d",
375 NL80211_IFTYPE_P2P_CLIENT, NULL, NULL)) {
376 dev_err(adapter->dev, "cannot create default P2P interface\n");
377 goto err_add_intf;
378 }
372 rtnl_unlock(); 379 rtnl_unlock();
373 380
374 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); 381 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
@@ -469,6 +476,27 @@ mwifiex_close(struct net_device *dev)
469} 476}
470 477
471/* 478/*
479 * Add buffer into wmm tx queue and queue work to transmit it.
480 */
481int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
482{
483 mwifiex_wmm_add_buf_txqueue(priv, skb);
484 atomic_inc(&priv->adapter->tx_pending);
485
486 if (priv->adapter->scan_delay_cnt)
487 atomic_set(&priv->adapter->is_tx_received, true);
488
489 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
490 mwifiex_set_trans_start(priv->netdev);
491 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
492 }
493
494 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
495
496 return 0;
497}
498
499/*
472 * CFG802.11 network device handler for data transmission. 500 * CFG802.11 network device handler for data transmission.
473 */ 501 */
474static int 502static int
@@ -516,18 +544,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
516 tx_info->bss_type = priv->bss_type; 544 tx_info->bss_type = priv->bss_type;
517 mwifiex_fill_buffer(skb); 545 mwifiex_fill_buffer(skb);
518 546
519 mwifiex_wmm_add_buf_txqueue(priv, skb); 547 mwifiex_queue_tx_pkt(priv, skb);
520 atomic_inc(&priv->adapter->tx_pending);
521
522 if (priv->adapter->scan_delay_cnt)
523 atomic_set(&priv->adapter->is_tx_received, true);
524
525 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
526 mwifiex_set_trans_start(dev);
527 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
528 }
529
530 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
531 548
532 return 0; 549 return 0;
533} 550}
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 90b64b015447..bfb3fa69805c 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -98,6 +98,8 @@ enum {
98#define MWIFIEX_OUI_NOT_PRESENT 0 98#define MWIFIEX_OUI_NOT_PRESENT 0
99#define MWIFIEX_OUI_PRESENT 1 99#define MWIFIEX_OUI_PRESENT 1
100 100
101#define PKT_TYPE_MGMT 0xE5
102
101/* 103/*
102 * Do not check for data_received for USB, as data_received 104 * Do not check for data_received for USB, as data_received
103 * is handled in mwifiex_usb_recv for USB 105 * is handled in mwifiex_usb_recv for USB
@@ -368,6 +370,12 @@ struct wps {
368 u8 session_enable; 370 u8 session_enable;
369}; 371};
370 372
373struct mwifiex_roc_cfg {
374 u64 cookie;
375 struct ieee80211_channel chan;
376 enum nl80211_channel_type chan_type;
377};
378
371struct mwifiex_adapter; 379struct mwifiex_adapter;
372struct mwifiex_private; 380struct mwifiex_private;
373 381
@@ -494,6 +502,8 @@ struct mwifiex_private {
494 u16 rsn_idx; 502 u16 rsn_idx;
495 struct timer_list scan_delay_timer; 503 struct timer_list scan_delay_timer;
496 u8 ap_11n_enabled; 504 u8 ap_11n_enabled;
505 u32 mgmt_frame_mask;
506 struct mwifiex_roc_cfg roc_cfg;
497}; 507};
498 508
499enum mwifiex_ba_status { 509enum mwifiex_ba_status {
@@ -525,6 +535,7 @@ struct mwifiex_rx_reorder_tbl {
525 int win_size; 535 int win_size;
526 void **rx_reorder_ptr; 536 void **rx_reorder_ptr;
527 struct reorder_tmr_cnxt timer_context; 537 struct reorder_tmr_cnxt timer_context;
538 u8 flags;
528}; 539};
529 540
530struct mwifiex_bss_prio_node { 541struct mwifiex_bss_prio_node {
@@ -726,6 +737,9 @@ void mwifiex_stop_net_dev_queue(struct net_device *netdev,
726void mwifiex_wake_up_net_dev_queue(struct net_device *netdev, 737void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
727 struct mwifiex_adapter *adapter); 738 struct mwifiex_adapter *adapter);
728 739
740int mwifiex_init_priv(struct mwifiex_private *priv);
741void mwifiex_free_priv(struct mwifiex_private *priv);
742
729int mwifiex_init_fw(struct mwifiex_adapter *adapter); 743int mwifiex_init_fw(struct mwifiex_adapter *adapter);
730 744
731int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter); 745int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter);
@@ -738,6 +752,9 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *);
738 752
739int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); 753int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb);
740 754
755int mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter,
756 struct sk_buff *skb);
757
741int mwifiex_process_event(struct mwifiex_adapter *adapter); 758int mwifiex_process_event(struct mwifiex_adapter *adapter);
742 759
743int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, 760int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
@@ -960,6 +977,14 @@ mwifiex_netdev_get_priv(struct net_device *dev)
960 return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); 977 return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev));
961} 978}
962 979
980/*
981 * This function checks if a skb holds a management frame.
982 */
983static inline bool mwifiex_is_skb_mgmt_frame(struct sk_buff *skb)
984{
985 return (*(u32 *)skb->data == PKT_TYPE_MGMT);
986}
987
963int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, 988int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
964 u32 func_init_shutdown); 989 u32 func_init_shutdown);
965int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8); 990int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
@@ -992,6 +1017,13 @@ int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
992 1017
993int mwifiex_get_ver_ext(struct mwifiex_private *priv); 1018int mwifiex_get_ver_ext(struct mwifiex_private *priv);
994 1019
1020int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1021 struct ieee80211_channel *chan,
1022 enum nl80211_channel_type *channel_type,
1023 unsigned int duration);
1024
1025int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role);
1026
995int mwifiex_get_stats_info(struct mwifiex_private *priv, 1027int mwifiex_get_stats_info(struct mwifiex_private *priv,
996 struct mwifiex_ds_get_stats *log); 1028 struct mwifiex_ds_get_stats *log);
997 1029
@@ -1022,6 +1054,8 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
1022 1054
1023int mwifiex_main_process(struct mwifiex_adapter *); 1055int mwifiex_main_process(struct mwifiex_adapter *);
1024 1056
1057int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb);
1058
1025int mwifiex_get_bss_info(struct mwifiex_private *, 1059int mwifiex_get_bss_info(struct mwifiex_private *,
1026 struct mwifiex_bss_info *); 1060 struct mwifiex_bss_info *);
1027int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, 1061int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
@@ -1032,6 +1066,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1032int mwifiex_check_network_compatibility(struct mwifiex_private *priv, 1066int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1033 struct mwifiex_bssdescriptor *bss_desc); 1067 struct mwifiex_bssdescriptor *bss_desc);
1034 1068
1069u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type);
1070
1035struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, 1071struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1036 const char *name, 1072 const char *name,
1037 enum nl80211_iftype type, 1073 enum nl80211_iftype type,
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 9e077e5fc64a..e36a75988f87 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -614,9 +614,8 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
614 614
615 /* Increment the TLV header length by the size 615 /* Increment the TLV header length by the size
616 appended */ 616 appended */
617 chan_tlv_out->header.len = 617 le16_add_cpu(&chan_tlv_out->header.len,
618 cpu_to_le16(le16_to_cpu(chan_tlv_out->header.len) + 618 sizeof(chan_tlv_out->chan_scan_param));
619 (sizeof(chan_tlv_out->chan_scan_param)));
620 619
621 /* 620 /*
622 * The tlv buffer length is set to the number of bytes 621 * The tlv buffer length is set to the number of bytes
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 3a4161cfeed7..5d87195390f8 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1167,6 +1167,31 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1167 S_DS_GEN); 1167 S_DS_GEN);
1168 ret = 0; 1168 ret = 0;
1169 break; 1169 break;
1170 case HostCmd_CMD_MGMT_FRAME_REG:
1171 cmd_ptr->command = cpu_to_le16(cmd_no);
1172 cmd_ptr->params.reg_mask.action = cpu_to_le16(cmd_action);
1173 cmd_ptr->params.reg_mask.mask = cpu_to_le32(*(u32 *)data_buf);
1174 cmd_ptr->size =
1175 cpu_to_le16(sizeof(struct host_cmd_ds_mgmt_frame_reg) +
1176 S_DS_GEN);
1177 ret = 0;
1178 break;
1179 case HostCmd_CMD_REMAIN_ON_CHAN:
1180 cmd_ptr->command = cpu_to_le16(cmd_no);
1181 memcpy(&cmd_ptr->params, data_buf,
1182 sizeof(struct host_cmd_ds_remain_on_chan));
1183 cmd_ptr->size =
1184 cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan) +
1185 S_DS_GEN);
1186 break;
1187 case HostCmd_CMD_P2P_MODE_CFG:
1188 cmd_ptr->command = cpu_to_le16(cmd_no);
1189 cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action);
1190 cmd_ptr->params.mode_cfg.mode = cpu_to_le16(*(u16 *)data_buf);
1191 cmd_ptr->size =
1192 cpu_to_le16(sizeof(struct host_cmd_ds_p2p_mode_cfg) +
1193 S_DS_GEN);
1194 break;
1170 case HostCmd_CMD_FUNC_INIT: 1195 case HostCmd_CMD_FUNC_INIT:
1171 if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET) 1196 if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET)
1172 priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY; 1197 priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY;
@@ -1236,6 +1261,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1236 else if (priv->bss_mode == NL80211_IFTYPE_STATION) 1261 else if (priv->bss_mode == NL80211_IFTYPE_STATION)
1237 cmd_ptr->params.bss_mode.con_type = 1262 cmd_ptr->params.bss_mode.con_type =
1238 CONNECTION_TYPE_INFRA; 1263 CONNECTION_TYPE_INFRA;
1264 else if (priv->bss_mode == NL80211_IFTYPE_AP)
1265 cmd_ptr->params.bss_mode.con_type = CONNECTION_TYPE_AP;
1239 cmd_ptr->size = cpu_to_le16(sizeof(struct 1266 cmd_ptr->size = cpu_to_le16(sizeof(struct
1240 host_cmd_ds_set_bss_mode) + S_DS_GEN); 1267 host_cmd_ds_set_bss_mode) + S_DS_GEN);
1241 ret = 0; 1268 ret = 0;
@@ -1285,35 +1312,35 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1285 1312
1286 if (first_sta) { 1313 if (first_sta) {
1287 if (priv->adapter->iface_type == MWIFIEX_PCIE) { 1314 if (priv->adapter->iface_type == MWIFIEX_PCIE) {
1288 ret = mwifiex_send_cmd_async(priv, 1315 ret = mwifiex_send_cmd_sync(priv,
1289 HostCmd_CMD_PCIE_DESC_DETAILS, 1316 HostCmd_CMD_PCIE_DESC_DETAILS,
1290 HostCmd_ACT_GEN_SET, 0, NULL); 1317 HostCmd_ACT_GEN_SET, 0, NULL);
1291 if (ret) 1318 if (ret)
1292 return -1; 1319 return -1;
1293 } 1320 }
1294 1321
1295 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT, 1322 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_FUNC_INIT,
1296 HostCmd_ACT_GEN_SET, 0, NULL); 1323 HostCmd_ACT_GEN_SET, 0, NULL);
1297 if (ret) 1324 if (ret)
1298 return -1; 1325 return -1;
1299 /* Read MAC address from HW */ 1326 /* Read MAC address from HW */
1300 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC, 1327 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC,
1301 HostCmd_ACT_GEN_GET, 0, NULL); 1328 HostCmd_ACT_GEN_GET, 0, NULL);
1302 if (ret) 1329 if (ret)
1303 return -1; 1330 return -1;
1304 1331
1305 /* Reconfigure tx buf size */ 1332 /* Reconfigure tx buf size */
1306 ret = mwifiex_send_cmd_async(priv, 1333 ret = mwifiex_send_cmd_sync(priv,
1307 HostCmd_CMD_RECONFIGURE_TX_BUFF, 1334 HostCmd_CMD_RECONFIGURE_TX_BUFF,
1308 HostCmd_ACT_GEN_SET, 0, 1335 HostCmd_ACT_GEN_SET, 0,
1309 &priv->adapter->tx_buf_size); 1336 &priv->adapter->tx_buf_size);
1310 if (ret) 1337 if (ret)
1311 return -1; 1338 return -1;
1312 1339
1313 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 1340 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1314 /* Enable IEEE PS by default */ 1341 /* Enable IEEE PS by default */
1315 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; 1342 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1316 ret = mwifiex_send_cmd_async( 1343 ret = mwifiex_send_cmd_sync(
1317 priv, HostCmd_CMD_802_11_PS_MODE_ENH, 1344 priv, HostCmd_CMD_802_11_PS_MODE_ENH,
1318 EN_AUTO_PS, BITMAP_STA_PS, NULL); 1345 EN_AUTO_PS, BITMAP_STA_PS, NULL);
1319 if (ret) 1346 if (ret)
@@ -1322,21 +1349,21 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1322 } 1349 }
1323 1350
1324 /* get tx rate */ 1351 /* get tx rate */
1325 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG, 1352 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG,
1326 HostCmd_ACT_GEN_GET, 0, NULL); 1353 HostCmd_ACT_GEN_GET, 0, NULL);
1327 if (ret) 1354 if (ret)
1328 return -1; 1355 return -1;
1329 priv->data_rate = 0; 1356 priv->data_rate = 0;
1330 1357
1331 /* get tx power */ 1358 /* get tx power */
1332 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_RF_TX_PWR, 1359 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_TX_PWR,
1333 HostCmd_ACT_GEN_GET, 0, NULL); 1360 HostCmd_ACT_GEN_GET, 0, NULL);
1334 if (ret) 1361 if (ret)
1335 return -1; 1362 return -1;
1336 1363
1337 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { 1364 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
1338 /* set ibss coalescing_status */ 1365 /* set ibss coalescing_status */
1339 ret = mwifiex_send_cmd_async( 1366 ret = mwifiex_send_cmd_sync(
1340 priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 1367 priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
1341 HostCmd_ACT_GEN_SET, 0, &enable); 1368 HostCmd_ACT_GEN_SET, 0, &enable);
1342 if (ret) 1369 if (ret)
@@ -1346,16 +1373,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1346 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); 1373 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
1347 amsdu_aggr_ctrl.enable = true; 1374 amsdu_aggr_ctrl.enable = true;
1348 /* Send request to firmware */ 1375 /* Send request to firmware */
1349 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, 1376 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
1350 HostCmd_ACT_GEN_SET, 0, 1377 HostCmd_ACT_GEN_SET, 0,
1351 &amsdu_aggr_ctrl); 1378 &amsdu_aggr_ctrl);
1352 if (ret) 1379 if (ret)
1353 return -1; 1380 return -1;
1354 /* MAC Control must be the last command in init_fw */ 1381 /* MAC Control must be the last command in init_fw */
1355 /* set MAC Control */ 1382 /* set MAC Control */
1356 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 1383 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
1357 HostCmd_ACT_GEN_SET, 0, 1384 HostCmd_ACT_GEN_SET, 0,
1358 &priv->curr_pkt_filter); 1385 &priv->curr_pkt_filter);
1359 if (ret) 1386 if (ret)
1360 return -1; 1387 return -1;
1361 1388
@@ -1364,10 +1391,10 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1364 /* Enable auto deep sleep */ 1391 /* Enable auto deep sleep */
1365 auto_ds.auto_ds = DEEP_SLEEP_ON; 1392 auto_ds.auto_ds = DEEP_SLEEP_ON;
1366 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; 1393 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
1367 ret = mwifiex_send_cmd_async(priv, 1394 ret = mwifiex_send_cmd_sync(priv,
1368 HostCmd_CMD_802_11_PS_MODE_ENH, 1395 HostCmd_CMD_802_11_PS_MODE_ENH,
1369 EN_AUTO_PS, BITMAP_AUTO_DS, 1396 EN_AUTO_PS, BITMAP_AUTO_DS,
1370 &auto_ds); 1397 &auto_ds);
1371 if (ret) 1398 if (ret)
1372 return -1; 1399 return -1;
1373 } 1400 }
@@ -1375,23 +1402,24 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1375 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 1402 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1376 /* Send cmd to FW to enable/disable 11D function */ 1403 /* Send cmd to FW to enable/disable 11D function */
1377 state_11d = ENABLE_11D; 1404 state_11d = ENABLE_11D;
1378 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB, 1405 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
1379 HostCmd_ACT_GEN_SET, DOT11D_I, 1406 HostCmd_ACT_GEN_SET, DOT11D_I,
1380 &state_11d); 1407 &state_11d);
1381 if (ret) 1408 if (ret)
1382 dev_err(priv->adapter->dev, 1409 dev_err(priv->adapter->dev,
1383 "11D: failed to enable 11D\n"); 1410 "11D: failed to enable 11D\n");
1384 } 1411 }
1385 1412
1413 /* set last_init_cmd before sending the command */
1414 priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG;
1415
1386 /* Send cmd to FW to configure 11n specific configuration 1416 /* Send cmd to FW to configure 11n specific configuration
1387 * (Short GI, Channel BW, Green field support etc.) for transmit 1417 * (Short GI, Channel BW, Green field support etc.) for transmit
1388 */ 1418 */
1389 tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG; 1419 tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG;
1390 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_CFG, 1420 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_11N_CFG,
1391 HostCmd_ACT_GEN_SET, 0, &tx_cfg); 1421 HostCmd_ACT_GEN_SET, 0, &tx_cfg);
1392 1422
1393 /* set last_init_cmd */
1394 priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG;
1395 ret = -EINPROGRESS; 1423 ret = -EINPROGRESS;
1396 1424
1397 return ret; 1425 return ret;
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 31f80e10e29e..e380171c4c5d 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -654,6 +654,38 @@ static int mwifiex_ret_ver_ext(struct mwifiex_private *priv,
654} 654}
655 655
656/* 656/*
657 * This function handles the command response of remain on channel.
658 */
659static int
660mwifiex_ret_remain_on_chan(struct mwifiex_private *priv,
661 struct host_cmd_ds_command *resp,
662 struct host_cmd_ds_remain_on_chan *roc_cfg)
663{
664 struct host_cmd_ds_remain_on_chan *resp_cfg = &resp->params.roc_cfg;
665
666 if (roc_cfg)
667 memcpy(roc_cfg, resp_cfg, sizeof(*roc_cfg));
668
669 return 0;
670}
671
672/*
673 * This function handles the command response of P2P mode cfg.
674 */
675static int
676mwifiex_ret_p2p_mode_cfg(struct mwifiex_private *priv,
677 struct host_cmd_ds_command *resp,
678 void *data_buf)
679{
680 struct host_cmd_ds_p2p_mode_cfg *mode_cfg = &resp->params.mode_cfg;
681
682 if (data_buf)
683 *((u16 *)data_buf) = le16_to_cpu(mode_cfg->mode);
684
685 return 0;
686}
687
688/*
657 * This function handles the command response of register access. 689 * This function handles the command response of register access.
658 * 690 *
659 * The register value and offset are returned to the user. For EEPROM 691 * The register value and offset are returned to the user. For EEPROM
@@ -875,6 +907,13 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
875 case HostCmd_CMD_VERSION_EXT: 907 case HostCmd_CMD_VERSION_EXT:
876 ret = mwifiex_ret_ver_ext(priv, resp, data_buf); 908 ret = mwifiex_ret_ver_ext(priv, resp, data_buf);
877 break; 909 break;
910 case HostCmd_CMD_REMAIN_ON_CHAN:
911 ret = mwifiex_ret_remain_on_chan(priv, resp, data_buf);
912 break;
913 case HostCmd_CMD_P2P_MODE_CFG:
914 ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf);
915 break;
916 case HostCmd_CMD_MGMT_FRAME_REG:
878 case HostCmd_CMD_FUNC_INIT: 917 case HostCmd_CMD_FUNC_INIT:
879 case HostCmd_CMD_FUNC_SHUTDOWN: 918 case HostCmd_CMD_FUNC_SHUTDOWN:
880 break; 919 break;
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index dff51d55271c..aafde30e714a 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -410,6 +410,18 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
410 dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause); 410 dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause);
411 break; 411 break;
412 412
413 case EVENT_REMAIN_ON_CHAN_EXPIRED:
414 dev_dbg(adapter->dev, "event: Remain on channel expired\n");
415 cfg80211_remain_on_channel_expired(priv->wdev,
416 priv->roc_cfg.cookie,
417 &priv->roc_cfg.chan,
418 priv->roc_cfg.chan_type,
419 GFP_ATOMIC);
420
421 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
422
423 break;
424
413 default: 425 default:
414 dev_dbg(adapter->dev, "event: unknown event id: %#x\n", 426 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
415 eventcause); 427 eventcause);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 731562f026f5..0c9f70b2cbe6 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -1043,6 +1043,65 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
1043 return 0; 1043 return 0;
1044} 1044}
1045 1045
1046int
1047mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1048 struct ieee80211_channel *chan,
1049 enum nl80211_channel_type *ct,
1050 unsigned int duration)
1051{
1052 struct host_cmd_ds_remain_on_chan roc_cfg;
1053 u8 sc;
1054
1055 memset(&roc_cfg, 0, sizeof(roc_cfg));
1056 roc_cfg.action = cpu_to_le16(action);
1057 if (action == HostCmd_ACT_GEN_SET) {
1058 roc_cfg.band_cfg = chan->band;
1059 sc = mwifiex_chan_type_to_sec_chan_offset(*ct);
1060 roc_cfg.band_cfg |= (sc << 2);
1061
1062 roc_cfg.channel =
1063 ieee80211_frequency_to_channel(chan->center_freq);
1064 roc_cfg.duration = cpu_to_le32(duration);
1065 }
1066 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_REMAIN_ON_CHAN,
1067 action, 0, &roc_cfg)) {
1068 dev_err(priv->adapter->dev, "failed to remain on channel\n");
1069 return -1;
1070 }
1071
1072 return roc_cfg.status;
1073}
1074
1075int
1076mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role)
1077{
1078 if (GET_BSS_ROLE(priv) == bss_role) {
1079 dev_dbg(priv->adapter->dev,
1080 "info: already in the desired role.\n");
1081 return 0;
1082 }
1083
1084 mwifiex_free_priv(priv);
1085 mwifiex_init_priv(priv);
1086
1087 priv->bss_role = bss_role;
1088 switch (bss_role) {
1089 case MWIFIEX_BSS_ROLE_UAP:
1090 priv->bss_mode = NL80211_IFTYPE_AP;
1091 break;
1092 case MWIFIEX_BSS_ROLE_STA:
1093 case MWIFIEX_BSS_ROLE_ANY:
1094 default:
1095 priv->bss_mode = NL80211_IFTYPE_STATION;
1096 break;
1097 }
1098
1099 mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE,
1100 HostCmd_ACT_GEN_SET, 0, NULL);
1101
1102 return mwifiex_sta_init_cmd(priv, false);
1103}
1104
1046/* 1105/*
1047 * Sends IOCTL request to get statistics information. 1106 * Sends IOCTL request to get statistics information.
1048 * 1107 *
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index d91d5c08c73a..07d32b73783e 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -174,6 +174,12 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
174 dev_err(adapter->dev, "Rx of A-MSDU failed"); 174 dev_err(adapter->dev, "Rx of A-MSDU failed");
175 } 175 }
176 return 0; 176 return 0;
177 } else if (rx_pkt_type == PKT_TYPE_MGMT) {
178 ret = mwifiex_process_mgmt_packet(adapter, skb);
179 if (ret)
180 dev_err(adapter->dev, "Rx of mgmt packet failed");
181 dev_kfree_skb_any(skb);
182 return ret;
177 } 183 }
178 184
179 /* 185 /*
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 0a046d3a0c16..7b581af24f5f 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -48,6 +48,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
48 struct txpd *local_tx_pd; 48 struct txpd *local_tx_pd;
49 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); 49 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
50 u8 pad; 50 u8 pad;
51 u16 pkt_type, pkt_offset;
51 52
52 if (!skb->len) { 53 if (!skb->len) {
53 dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); 54 dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
@@ -55,6 +56,8 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
55 return skb->data; 56 return skb->data;
56 } 57 }
57 58
59 pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
60
58 /* If skb->data is not aligned; add padding */ 61 /* If skb->data is not aligned; add padding */
59 pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; 62 pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
60 63
@@ -93,7 +96,14 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
93 } 96 }
94 97
95 /* Offset of actual data */ 98 /* Offset of actual data */
96 local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) + pad); 99 pkt_offset = sizeof(struct txpd) + pad;
100 if (pkt_type == PKT_TYPE_MGMT) {
101 /* Set the packet type and add header for management frame */
102 local_tx_pd->tx_pkt_type = cpu_to_le16(pkt_type);
103 pkt_offset += MWIFIEX_MGMT_FRAME_HEADER_SIZE;
104 }
105
106 local_tx_pd->tx_pkt_offset = cpu_to_le16(pkt_offset);
97 107
98 /* make space for INTF_HEADER_LEN */ 108 /* make space for INTF_HEADER_LEN */
99 skb_push(skb, INTF_HEADER_LEN); 109 skb_push(skb, INTF_HEADER_LEN);
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 8a627d856d18..d95a2d558fcf 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -343,6 +343,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
343 struct host_cmd_tlv_encrypt_protocol *encrypt_protocol; 343 struct host_cmd_tlv_encrypt_protocol *encrypt_protocol;
344 struct host_cmd_tlv_auth_type *auth_type; 344 struct host_cmd_tlv_auth_type *auth_type;
345 struct host_cmd_tlv_rates *tlv_rates; 345 struct host_cmd_tlv_rates *tlv_rates;
346 struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer;
346 struct mwifiex_ie_types_htcap *htcap; 347 struct mwifiex_ie_types_htcap *htcap;
347 struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; 348 struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
348 int i; 349 int i;
@@ -497,6 +498,27 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
497 tlv += sizeof(struct mwifiex_ie_types_htcap); 498 tlv += sizeof(struct mwifiex_ie_types_htcap);
498 } 499 }
499 500
501 if (bss_cfg->sta_ao_timer) {
502 ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
503 ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER);
504 ao_timer->tlv.len = cpu_to_le16(sizeof(*ao_timer) -
505 sizeof(struct host_cmd_tlv));
506 ao_timer->sta_ao_timer = cpu_to_le32(bss_cfg->sta_ao_timer);
507 cmd_size += sizeof(*ao_timer);
508 tlv += sizeof(*ao_timer);
509 }
510
511 if (bss_cfg->ps_sta_ao_timer) {
512 ps_ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
513 ps_ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_PS_AO_TIMER);
514 ps_ao_timer->tlv.len = cpu_to_le16(sizeof(*ps_ao_timer) -
515 sizeof(struct host_cmd_tlv));
516 ps_ao_timer->sta_ao_timer =
517 cpu_to_le32(bss_cfg->ps_sta_ao_timer);
518 cmd_size += sizeof(*ps_ao_timer);
519 tlv += sizeof(*ps_ao_timer);
520 }
521
500 *param_size = cmd_size; 522 *param_size = cmd_size;
501 523
502 return 0; 524 return 0;
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index df17d08715fe..0966ac24b3b4 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -217,6 +217,12 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter,
217 } 217 }
218 218
219 return 0; 219 return 0;
220 } else if (rx_pkt_type == PKT_TYPE_MGMT) {
221 ret = mwifiex_process_mgmt_packet(adapter, skb);
222 if (ret)
223 dev_err(adapter->dev, "Rx of mgmt packet failed");
224 dev_kfree_skb_any(skb);
225 return ret;
220 } 226 }
221 227
222 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN); 228 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
@@ -278,6 +284,7 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
278 struct uap_txpd *txpd; 284 struct uap_txpd *txpd;
279 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); 285 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
280 int pad, len; 286 int pad, len;
287 u16 pkt_type;
281 288
282 if (!skb->len) { 289 if (!skb->len) {
283 dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); 290 dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
@@ -285,6 +292,8 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
285 return skb->data; 292 return skb->data;
286 } 293 }
287 294
295 pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
296
288 /* If skb->data is not aligned, add padding */ 297 /* If skb->data is not aligned, add padding */
289 pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; 298 pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
290 299
@@ -312,6 +321,12 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
312 cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]); 321 cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]);
313 322
314 /* Offset of actual data */ 323 /* Offset of actual data */
324 if (pkt_type == PKT_TYPE_MGMT) {
325 /* Set the packet type and add header for management frame */
326 txpd->tx_pkt_type = cpu_to_le16(pkt_type);
327 len += MWIFIEX_MGMT_FRAME_HEADER_SIZE;
328 }
329
315 txpd->tx_pkt_offset = cpu_to_le16(len); 330 txpd->tx_pkt_offset = cpu_to_le16(len);
316 331
317 /* make space for INTF_HEADER_LEN */ 332 /* make space for INTF_HEADER_LEN */
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 2864c74bdb6f..ae88f80cf86b 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -142,6 +142,46 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
142} 142}
143 143
144/* 144/*
145 * This function processes the received management packet and send it
146 * to the kernel.
147 */
148int
149mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter,
150 struct sk_buff *skb)
151{
152 struct rxpd *rx_pd;
153 struct mwifiex_private *priv;
154 u16 pkt_len;
155
156 if (!skb)
157 return -1;
158
159 rx_pd = (struct rxpd *)skb->data;
160 priv = mwifiex_get_priv_by_id(adapter, rx_pd->bss_num, rx_pd->bss_type);
161 if (!priv)
162 return -1;
163
164 skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
165 skb_pull(skb, sizeof(pkt_len));
166
167 pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
168
169 /* Remove address4 */
170 memmove(skb->data + sizeof(struct ieee80211_hdr_3addr),
171 skb->data + sizeof(struct ieee80211_hdr),
172 pkt_len - sizeof(struct ieee80211_hdr));
173
174 pkt_len -= ETH_ALEN + sizeof(pkt_len);
175 rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
176
177 cfg80211_rx_mgmt(priv->wdev, priv->roc_cfg.chan.center_freq,
178 CAL_RSSI(rx_pd->snr, rx_pd->nf),
179 skb->data, pkt_len, GFP_ATOMIC);
180
181 return 0;
182}
183
184/*
145 * This function processes the received packet before sending it to the 185 * This function processes the received packet before sending it to the
146 * kernel. 186 * kernel.
147 * 187 *
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 766d45294c86..600d8194610e 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -462,7 +462,7 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
462 for (i = 0; i < adapter->priv_num; ++i) { 462 for (i = 0; i < adapter->priv_num; ++i) {
463 priv = adapter->priv[i]; 463 priv = adapter->priv[i];
464 if (priv && atomic_read(&priv->wmm.tx_pkts_queued)) 464 if (priv && atomic_read(&priv->wmm.tx_pkts_queued))
465 return false; 465 return false;
466 } 466 }
467 467
468 return true; 468 return true;
@@ -648,7 +648,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
648 u8 ra[ETH_ALEN], tid_down; 648 u8 ra[ETH_ALEN], tid_down;
649 unsigned long flags; 649 unsigned long flags;
650 650
651 if (!priv->media_connected) { 651 if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) {
652 dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); 652 dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
653 mwifiex_write_data_complete(adapter, skb, -1); 653 mwifiex_write_data_complete(adapter, skb, -1);
654 return; 654 return;
@@ -663,7 +663,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
663 /* In case of infra as we have already created the list during 663 /* In case of infra as we have already created the list during
664 association we just don't have to call get_queue_raptr, we will 664 association we just don't have to call get_queue_raptr, we will
665 have only 1 raptr for a tid in case of infra */ 665 have only 1 raptr for a tid in case of infra */
666 if (!mwifiex_queuing_ra_based(priv)) { 666 if (!mwifiex_queuing_ra_based(priv) &&
667 !mwifiex_is_skb_mgmt_frame(skb)) {
667 if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list)) 668 if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list))
668 ra_list = list_first_entry( 669 ra_list = list_first_entry(
669 &priv->wmm.tid_tbl_ptr[tid_down].ra_list, 670 &priv->wmm.tid_tbl_ptr[tid_down].ra_list,
@@ -672,7 +673,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
672 ra_list = NULL; 673 ra_list = NULL;
673 } else { 674 } else {
674 memcpy(ra, skb->data, ETH_ALEN); 675 memcpy(ra, skb->data, ETH_ALEN);
675 if (ra[0] & 0x01) 676 if (ra[0] & 0x01 || mwifiex_is_skb_mgmt_frame(skb))
676 memset(ra, 0xff, ETH_ALEN); 677 memset(ra, 0xff, ETH_ALEN);
677 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra); 678 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra);
678 } 679 }
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index f429fc110cb0..dadf1dbb002a 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -32,7 +32,6 @@
32#include "../wlcore/acx.h" 32#include "../wlcore/acx.h"
33#include "../wlcore/tx.h" 33#include "../wlcore/tx.h"
34#include "../wlcore/rx.h" 34#include "../wlcore/rx.h"
35#include "../wlcore/io.h"
36#include "../wlcore/boot.h" 35#include "../wlcore/boot.h"
37 36
38#include "wl12xx.h" 37#include "wl12xx.h"
@@ -1185,9 +1184,16 @@ static int wl12xx_enable_interrupts(struct wl1271 *wl)
1185 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, 1184 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1186 WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK)); 1185 WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK));
1187 if (ret < 0) 1186 if (ret < 0)
1188 goto out; 1187 goto disable_interrupts;
1189 1188
1190 ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); 1189 ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1190 if (ret < 0)
1191 goto disable_interrupts;
1192
1193 return ret;
1194
1195disable_interrupts:
1196 wlcore_disable_interrupts(wl);
1191 1197
1192out: 1198out:
1193 return ret; 1199 return ret;
@@ -1583,7 +1589,10 @@ static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1583 return wlcore_set_key(wl, cmd, vif, sta, key_conf); 1589 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1584} 1590}
1585 1591
1592static int wl12xx_setup(struct wl1271 *wl);
1593
1586static struct wlcore_ops wl12xx_ops = { 1594static struct wlcore_ops wl12xx_ops = {
1595 .setup = wl12xx_setup,
1587 .identify_chip = wl12xx_identify_chip, 1596 .identify_chip = wl12xx_identify_chip,
1588 .identify_fw = wl12xx_identify_fw, 1597 .identify_fw = wl12xx_identify_fw,
1589 .boot = wl12xx_boot, 1598 .boot = wl12xx_boot,
@@ -1624,26 +1633,15 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1624 }, 1633 },
1625}; 1634};
1626 1635
1627static int __devinit wl12xx_probe(struct platform_device *pdev) 1636static int wl12xx_setup(struct wl1271 *wl)
1628{ 1637{
1629 struct wl12xx_platform_data *pdata = pdev->dev.platform_data; 1638 struct wl12xx_priv *priv = wl->priv;
1630 struct wl1271 *wl; 1639 struct wl12xx_platform_data *pdata = wl->pdev->dev.platform_data;
1631 struct ieee80211_hw *hw;
1632 struct wl12xx_priv *priv;
1633
1634 hw = wlcore_alloc_hw(sizeof(*priv));
1635 if (IS_ERR(hw)) {
1636 wl1271_error("can't allocate hw");
1637 return PTR_ERR(hw);
1638 }
1639 1640
1640 wl = hw->priv;
1641 priv = wl->priv;
1642 wl->ops = &wl12xx_ops;
1643 wl->ptable = wl12xx_ptable;
1644 wl->rtable = wl12xx_rtable; 1641 wl->rtable = wl12xx_rtable;
1645 wl->num_tx_desc = 16; 1642 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
1646 wl->num_rx_desc = 8; 1643 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
1644 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
1647 wl->band_rate_to_idx = wl12xx_band_rate_to_idx; 1645 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1648 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; 1646 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1649 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; 1647 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
@@ -1695,7 +1693,36 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
1695 wl1271_error("Invalid tcxo parameter %s", tcxo_param); 1693 wl1271_error("Invalid tcxo parameter %s", tcxo_param);
1696 } 1694 }
1697 1695
1698 return wlcore_probe(wl, pdev); 1696 return 0;
1697}
1698
1699static int __devinit wl12xx_probe(struct platform_device *pdev)
1700{
1701 struct wl1271 *wl;
1702 struct ieee80211_hw *hw;
1703 int ret;
1704
1705 hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv),
1706 WL12XX_AGGR_BUFFER_SIZE);
1707 if (IS_ERR(hw)) {
1708 wl1271_error("can't allocate hw");
1709 ret = PTR_ERR(hw);
1710 goto out;
1711 }
1712
1713 wl = hw->priv;
1714 wl->ops = &wl12xx_ops;
1715 wl->ptable = wl12xx_ptable;
1716 ret = wlcore_probe(wl, pdev);
1717 if (ret)
1718 goto out_free;
1719
1720 return ret;
1721
1722out_free:
1723 wlcore_free_hw(wl);
1724out:
1725 return ret;
1699} 1726}
1700 1727
1701static const struct platform_device_id wl12xx_id_table[] __devinitconst = { 1728static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
@@ -1714,17 +1741,7 @@ static struct platform_driver wl12xx_driver = {
1714 } 1741 }
1715}; 1742};
1716 1743
1717static int __init wl12xx_init(void) 1744module_platform_driver(wl12xx_driver);
1718{
1719 return platform_driver_register(&wl12xx_driver);
1720}
1721module_init(wl12xx_init);
1722
1723static void __exit wl12xx_exit(void)
1724{
1725 platform_driver_unregister(&wl12xx_driver);
1726}
1727module_exit(wl12xx_exit);
1728 1745
1729module_param_named(fref, fref_param, charp, 0); 1746module_param_named(fref, fref_param, charp, 0);
1730MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52"); 1747MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52");
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index 26990fb4edea..7182bbf6625d 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -38,6 +38,13 @@
38#define WL128X_SUBTYPE_VER 2 38#define WL128X_SUBTYPE_VER 2
39#define WL128X_MINOR_VER 115 39#define WL128X_MINOR_VER 115
40 40
41#define WL12XX_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
42
43#define WL12XX_NUM_TX_DESCRIPTORS 16
44#define WL12XX_NUM_RX_DESCRIPTORS 8
45
46#define WL12XX_NUM_MAC_ADDRESSES 2
47
41struct wl127x_rx_mem_pool_addr { 48struct wl127x_rx_mem_pool_addr {
42 u32 addr; 49 u32 addr;
43 u32 addr_extra; 50 u32 addr_extra;
diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c
index 3ce6f1039af3..7f1669cdea09 100644
--- a/drivers/net/wireless/ti/wl18xx/debugfs.c
+++ b/drivers/net/wireless/ti/wl18xx/debugfs.c
@@ -220,7 +220,7 @@ static ssize_t clear_fw_stats_write(struct file *file,
220 220
221 mutex_lock(&wl->mutex); 221 mutex_lock(&wl->mutex);
222 222
223 if (wl->state == WL1271_STATE_OFF) 223 if (unlikely(wl->state != WLCORE_STATE_ON))
224 goto out; 224 goto out;
225 225
226 ret = wl18xx_acx_clear_statistics(wl); 226 ret = wl18xx_acx_clear_statistics(wl);
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 31cf6eba3a9e..a39682a7c25f 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -45,7 +45,6 @@
45static char *ht_mode_param = NULL; 45static char *ht_mode_param = NULL;
46static char *board_type_param = NULL; 46static char *board_type_param = NULL;
47static bool checksum_param = false; 47static bool checksum_param = false;
48static bool enable_11a_param = true;
49static int num_rx_desc_param = -1; 48static int num_rx_desc_param = -1;
50 49
51/* phy paramters */ 50/* phy paramters */
@@ -415,7 +414,7 @@ static struct wlcore_conf wl18xx_conf = {
415 .snr_threshold = 0, 414 .snr_threshold = 0,
416 }, 415 },
417 .ht = { 416 .ht = {
418 .rx_ba_win_size = 10, 417 .rx_ba_win_size = 32,
419 .tx_ba_win_size = 64, 418 .tx_ba_win_size = 64,
420 .inactivity_timeout = 10000, 419 .inactivity_timeout = 10000,
421 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP, 420 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
@@ -505,8 +504,8 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
505 .rdl = 0x01, 504 .rdl = 0x01,
506 .auto_detect = 0x00, 505 .auto_detect = 0x00,
507 .dedicated_fem = FEM_NONE, 506 .dedicated_fem = FEM_NONE,
508 .low_band_component = COMPONENT_2_WAY_SWITCH, 507 .low_band_component = COMPONENT_3_WAY_SWITCH,
509 .low_band_component_type = 0x06, 508 .low_band_component_type = 0x04,
510 .high_band_component = COMPONENT_2_WAY_SWITCH, 509 .high_band_component = COMPONENT_2_WAY_SWITCH,
511 .high_band_component_type = 0x09, 510 .high_band_component_type = 0x09,
512 .tcxo_ldo_voltage = 0x00, 511 .tcxo_ldo_voltage = 0x00,
@@ -812,6 +811,13 @@ static int wl18xx_enable_interrupts(struct wl1271 *wl)
812 811
813 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, 812 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
814 WL1271_ACX_INTR_ALL & ~intr_mask); 813 WL1271_ACX_INTR_ALL & ~intr_mask);
814 if (ret < 0)
815 goto disable_interrupts;
816
817 return ret;
818
819disable_interrupts:
820 wlcore_disable_interrupts(wl);
815 821
816out: 822out:
817 return ret; 823 return ret;
@@ -1202,6 +1208,12 @@ static int wl18xx_handle_static_data(struct wl1271 *wl,
1202 struct wl18xx_static_data_priv *static_data_priv = 1208 struct wl18xx_static_data_priv *static_data_priv =
1203 (struct wl18xx_static_data_priv *) static_data->priv; 1209 (struct wl18xx_static_data_priv *) static_data->priv;
1204 1210
1211 strncpy(wl->chip.phy_fw_ver_str, static_data_priv->phy_version,
1212 sizeof(wl->chip.phy_fw_ver_str));
1213
1214 /* make sure the string is NULL-terminated */
1215 wl->chip.phy_fw_ver_str[sizeof(wl->chip.phy_fw_ver_str) - 1] = '\0';
1216
1205 wl1271_info("PHY firmware version: %s", static_data_priv->phy_version); 1217 wl1271_info("PHY firmware version: %s", static_data_priv->phy_version);
1206 1218
1207 return 0; 1219 return 0;
@@ -1240,13 +1252,6 @@ static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1240 if (!change_spare) 1252 if (!change_spare)
1241 return wlcore_set_key(wl, cmd, vif, sta, key_conf); 1253 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1242 1254
1243 /*
1244 * stop the queues and flush to ensure the next packets are
1245 * in sync with FW spare block accounting
1246 */
1247 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
1248 wl1271_tx_flush(wl);
1249
1250 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf); 1255 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1251 if (ret < 0) 1256 if (ret < 0)
1252 goto out; 1257 goto out;
@@ -1269,7 +1274,6 @@ static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1269 } 1274 }
1270 1275
1271out: 1276out:
1272 wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
1273 return ret; 1277 return ret;
1274} 1278}
1275 1279
@@ -1292,7 +1296,10 @@ static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1292 return buf_offset; 1296 return buf_offset;
1293} 1297}
1294 1298
1299static int wl18xx_setup(struct wl1271 *wl);
1300
1295static struct wlcore_ops wl18xx_ops = { 1301static struct wlcore_ops wl18xx_ops = {
1302 .setup = wl18xx_setup,
1296 .identify_chip = wl18xx_identify_chip, 1303 .identify_chip = wl18xx_identify_chip,
1297 .boot = wl18xx_boot, 1304 .boot = wl18xx_boot,
1298 .plt_init = wl18xx_plt_init, 1305 .plt_init = wl18xx_plt_init,
@@ -1373,27 +1380,15 @@ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1373 }, 1380 },
1374}; 1381};
1375 1382
1376static int __devinit wl18xx_probe(struct platform_device *pdev) 1383static int wl18xx_setup(struct wl1271 *wl)
1377{ 1384{
1378 struct wl1271 *wl; 1385 struct wl18xx_priv *priv = wl->priv;
1379 struct ieee80211_hw *hw;
1380 struct wl18xx_priv *priv;
1381 int ret; 1386 int ret;
1382 1387
1383 hw = wlcore_alloc_hw(sizeof(*priv));
1384 if (IS_ERR(hw)) {
1385 wl1271_error("can't allocate hw");
1386 ret = PTR_ERR(hw);
1387 goto out;
1388 }
1389
1390 wl = hw->priv;
1391 priv = wl->priv;
1392 wl->ops = &wl18xx_ops;
1393 wl->ptable = wl18xx_ptable;
1394 wl->rtable = wl18xx_rtable; 1388 wl->rtable = wl18xx_rtable;
1395 wl->num_tx_desc = 32; 1389 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1396 wl->num_rx_desc = 32; 1390 wl->num_rx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1391 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1397 wl->band_rate_to_idx = wl18xx_band_rate_to_idx; 1392 wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1398 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; 1393 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
1399 wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; 1394 wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
@@ -1404,9 +1399,9 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
1404 if (num_rx_desc_param != -1) 1399 if (num_rx_desc_param != -1)
1405 wl->num_rx_desc = num_rx_desc_param; 1400 wl->num_rx_desc = num_rx_desc_param;
1406 1401
1407 ret = wl18xx_conf_init(wl, &pdev->dev); 1402 ret = wl18xx_conf_init(wl, wl->dev);
1408 if (ret < 0) 1403 if (ret < 0)
1409 goto out_free; 1404 return ret;
1410 1405
1411 /* If the module param is set, update it in conf */ 1406 /* If the module param is set, update it in conf */
1412 if (board_type_param) { 1407 if (board_type_param) {
@@ -1423,27 +1418,14 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
1423 } else { 1418 } else {
1424 wl1271_error("invalid board type '%s'", 1419 wl1271_error("invalid board type '%s'",
1425 board_type_param); 1420 board_type_param);
1426 ret = -EINVAL; 1421 return -EINVAL;
1427 goto out_free;
1428 } 1422 }
1429 } 1423 }
1430 1424
1431 /* HACK! Just for now we hardcode COM8 and HDK to 0x06 */ 1425 if (priv->conf.phy.board_type >= NUM_BOARD_TYPES) {
1432 switch (priv->conf.phy.board_type) {
1433 case BOARD_TYPE_HDK_18XX:
1434 case BOARD_TYPE_COM8_18XX:
1435 priv->conf.phy.low_band_component_type = 0x06;
1436 break;
1437 case BOARD_TYPE_FPGA_18XX:
1438 case BOARD_TYPE_DVP_18XX:
1439 case BOARD_TYPE_EVB_18XX:
1440 priv->conf.phy.low_band_component_type = 0x05;
1441 break;
1442 default:
1443 wl1271_error("invalid board type '%d'", 1426 wl1271_error("invalid board type '%d'",
1444 priv->conf.phy.board_type); 1427 priv->conf.phy.board_type);
1445 ret = -EINVAL; 1428 return -EINVAL;
1446 goto out_free;
1447 } 1429 }
1448 1430
1449 if (low_band_component_param != -1) 1431 if (low_band_component_param != -1)
@@ -1475,22 +1457,21 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
1475 priv->conf.ht.mode = HT_MODE_SISO20; 1457 priv->conf.ht.mode = HT_MODE_SISO20;
1476 else { 1458 else {
1477 wl1271_error("invalid ht_mode '%s'", ht_mode_param); 1459 wl1271_error("invalid ht_mode '%s'", ht_mode_param);
1478 ret = -EINVAL; 1460 return -EINVAL;
1479 goto out_free;
1480 } 1461 }
1481 } 1462 }
1482 1463
1483 if (priv->conf.ht.mode == HT_MODE_DEFAULT) { 1464 if (priv->conf.ht.mode == HT_MODE_DEFAULT) {
1484 /* 1465 /*
1485 * Only support mimo with multiple antennas. Fall back to 1466 * Only support mimo with multiple antennas. Fall back to
1486 * siso20. 1467 * siso40.
1487 */ 1468 */
1488 if (wl18xx_is_mimo_supported(wl)) 1469 if (wl18xx_is_mimo_supported(wl))
1489 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, 1470 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1490 &wl18xx_mimo_ht_cap_2ghz); 1471 &wl18xx_mimo_ht_cap_2ghz);
1491 else 1472 else
1492 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, 1473 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1493 &wl18xx_siso20_ht_cap); 1474 &wl18xx_siso40_ht_cap_2ghz);
1494 1475
1495 /* 5Ghz is always wide */ 1476 /* 5Ghz is always wide */
1496 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, 1477 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
@@ -1512,9 +1493,34 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
1512 wl18xx_ops.init_vif = NULL; 1493 wl18xx_ops.init_vif = NULL;
1513 } 1494 }
1514 1495
1515 wl->enable_11a = enable_11a_param; 1496 /* Enable 11a Band only if we have 5G antennas */
1497 wl->enable_11a = (priv->conf.phy.number_of_assembled_ant5 != 0);
1498
1499 return 0;
1500}
1516 1501
1517 return wlcore_probe(wl, pdev); 1502static int __devinit wl18xx_probe(struct platform_device *pdev)
1503{
1504 struct wl1271 *wl;
1505 struct ieee80211_hw *hw;
1506 int ret;
1507
1508 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
1509 WL18XX_AGGR_BUFFER_SIZE);
1510 if (IS_ERR(hw)) {
1511 wl1271_error("can't allocate hw");
1512 ret = PTR_ERR(hw);
1513 goto out;
1514 }
1515
1516 wl = hw->priv;
1517 wl->ops = &wl18xx_ops;
1518 wl->ptable = wl18xx_ptable;
1519 ret = wlcore_probe(wl, pdev);
1520 if (ret)
1521 goto out_free;
1522
1523 return ret;
1518 1524
1519out_free: 1525out_free:
1520 wlcore_free_hw(wl); 1526 wlcore_free_hw(wl);
@@ -1538,18 +1544,7 @@ static struct platform_driver wl18xx_driver = {
1538 } 1544 }
1539}; 1545};
1540 1546
1541static int __init wl18xx_init(void) 1547module_platform_driver(wl18xx_driver);
1542{
1543 return platform_driver_register(&wl18xx_driver);
1544}
1545module_init(wl18xx_init);
1546
1547static void __exit wl18xx_exit(void)
1548{
1549 platform_driver_unregister(&wl18xx_driver);
1550}
1551module_exit(wl18xx_exit);
1552
1553module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); 1548module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR);
1554MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20"); 1549MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");
1555 1550
@@ -1560,9 +1555,6 @@ MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
1560module_param_named(checksum, checksum_param, bool, S_IRUSR); 1555module_param_named(checksum, checksum_param, bool, S_IRUSR);
1561MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)"); 1556MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)");
1562 1557
1563module_param_named(enable_11a, enable_11a_param, bool, S_IRUSR);
1564MODULE_PARM_DESC(enable_11a, "Enable 11a (5GHz): boolean (defaults to true)");
1565
1566module_param_named(dc2dc, dc2dc_param, int, S_IRUSR); 1558module_param_named(dc2dc, dc2dc_param, int, S_IRUSR);
1567MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)"); 1559MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)");
1568 1560
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index 6452396fa1d4..96a1e438d677 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -33,6 +33,13 @@
33 33
34#define WL18XX_CMD_MAX_SIZE 740 34#define WL18XX_CMD_MAX_SIZE 740
35 35
36#define WL18XX_AGGR_BUFFER_SIZE (13 * PAGE_SIZE)
37
38#define WL18XX_NUM_TX_DESCRIPTORS 32
39#define WL18XX_NUM_RX_DESCRIPTORS 32
40
41#define WL18XX_NUM_MAC_ADDRESSES 3
42
36struct wl18xx_priv { 43struct wl18xx_priv {
37 /* buffer for sending commands to FW */ 44 /* buffer for sending commands to FW */
38 u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; 45 u8 cmd_buf[WL18XX_CMD_MAX_SIZE];
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 20e1bd923832..eaef3f41b252 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -59,6 +59,9 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
59 u16 status; 59 u16 status;
60 u16 poll_count = 0; 60 u16 poll_count = 0;
61 61
62 if (WARN_ON(unlikely(wl->state == WLCORE_STATE_RESTARTING)))
63 return -EIO;
64
62 cmd = buf; 65 cmd = buf;
63 cmd->id = cpu_to_le16(id); 66 cmd->id = cpu_to_le16(id);
64 cmd->status = 0; 67 cmd->status = 0;
@@ -990,7 +993,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
990 993
991 ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV, 994 ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV,
992 skb->data, skb->len, 995 skb->data, skb->len,
993 CMD_TEMPL_KLV_IDX_NULL_DATA, 996 wlvif->sta.klv_template_id,
994 wlvif->basic_rate); 997 wlvif->basic_rate);
995 998
996out: 999out:
@@ -1785,10 +1788,17 @@ int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1785 wlvif->bss_type == BSS_TYPE_IBSS))) 1788 wlvif->bss_type == BSS_TYPE_IBSS)))
1786 return -EINVAL; 1789 return -EINVAL;
1787 1790
1788 ret = wl12xx_cmd_role_start_dev(wl, wlvif); 1791 ret = wl12xx_cmd_role_enable(wl,
1792 wl12xx_wlvif_to_vif(wlvif)->addr,
1793 WL1271_ROLE_DEVICE,
1794 &wlvif->dev_role_id);
1789 if (ret < 0) 1795 if (ret < 0)
1790 goto out; 1796 goto out;
1791 1797
1798 ret = wl12xx_cmd_role_start_dev(wl, wlvif);
1799 if (ret < 0)
1800 goto out_disable;
1801
1792 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id); 1802 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
1793 if (ret < 0) 1803 if (ret < 0)
1794 goto out_stop; 1804 goto out_stop;
@@ -1797,6 +1807,8 @@ int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1797 1807
1798out_stop: 1808out_stop:
1799 wl12xx_cmd_role_stop_dev(wl, wlvif); 1809 wl12xx_cmd_role_stop_dev(wl, wlvif);
1810out_disable:
1811 wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
1800out: 1812out:
1801 return ret; 1813 return ret;
1802} 1814}
@@ -1824,6 +1836,11 @@ int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1824 ret = wl12xx_cmd_role_stop_dev(wl, wlvif); 1836 ret = wl12xx_cmd_role_stop_dev(wl, wlvif);
1825 if (ret < 0) 1837 if (ret < 0)
1826 goto out; 1838 goto out;
1839
1840 ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
1841 if (ret < 0)
1842 goto out;
1843
1827out: 1844out:
1828 return ret; 1845 return ret;
1829} 1846}
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index 4ef0b095f0d6..2409f3d71f63 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -157,11 +157,6 @@ enum wl1271_commands {
157 157
158#define MAX_CMD_PARAMS 572 158#define MAX_CMD_PARAMS 572
159 159
160enum {
161 CMD_TEMPL_KLV_IDX_NULL_DATA = 0,
162 CMD_TEMPL_KLV_IDX_MAX = 4
163};
164
165enum cmd_templ { 160enum cmd_templ {
166 CMD_TEMPL_NULL_DATA = 0, 161 CMD_TEMPL_NULL_DATA = 0,
167 CMD_TEMPL_BEACON, 162 CMD_TEMPL_BEACON,
diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h
index d77224f2ac6b..9e40760bafe1 100644
--- a/drivers/net/wireless/ti/wlcore/conf.h
+++ b/drivers/net/wireless/ti/wlcore/conf.h
@@ -412,8 +412,7 @@ struct conf_rx_settings {
412#define CONF_TX_RATE_RETRY_LIMIT 10 412#define CONF_TX_RATE_RETRY_LIMIT 10
413 413
414/* basic rates for p2p operations (probe req/resp, etc.) */ 414/* basic rates for p2p operations (probe req/resp, etc.) */
415#define CONF_TX_RATE_MASK_BASIC_P2P (CONF_HW_BIT_RATE_6MBPS | \ 415#define CONF_TX_RATE_MASK_BASIC_P2P CONF_HW_BIT_RATE_6MBPS
416 CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS)
417 416
418/* 417/*
419 * Rates supported for data packets when operating as AP. Note the absence 418 * Rates supported for data packets when operating as AP. Note the absence
diff --git a/drivers/net/wireless/ti/wlcore/debug.h b/drivers/net/wireless/ti/wlcore/debug.h
index 6b800b3cbea5..db4bf5a68ce2 100644
--- a/drivers/net/wireless/ti/wlcore/debug.h
+++ b/drivers/net/wireless/ti/wlcore/debug.h
@@ -28,7 +28,7 @@
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/printk.h> 29#include <linux/printk.h>
30 30
31#define DRIVER_NAME "wl12xx" 31#define DRIVER_NAME "wlcore"
32#define DRIVER_PREFIX DRIVER_NAME ": " 32#define DRIVER_PREFIX DRIVER_NAME ": "
33 33
34enum { 34enum {
@@ -73,11 +73,21 @@ extern u32 wl12xx_debug_level;
73#define wl1271_info(fmt, arg...) \ 73#define wl1271_info(fmt, arg...) \
74 pr_info(DRIVER_PREFIX fmt "\n", ##arg) 74 pr_info(DRIVER_PREFIX fmt "\n", ##arg)
75 75
76/* define the debug macro differently if dynamic debug is supported */
77#if defined(CONFIG_DYNAMIC_DEBUG)
76#define wl1271_debug(level, fmt, arg...) \ 78#define wl1271_debug(level, fmt, arg...) \
77 do { \ 79 do { \
78 if (level & wl12xx_debug_level) \ 80 if (unlikely(level & wl12xx_debug_level)) \
79 pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \ 81 dynamic_pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \
82 } while (0)
83#else
84#define wl1271_debug(level, fmt, arg...) \
85 do { \
86 if (unlikely(level & wl12xx_debug_level)) \
87 printk(KERN_DEBUG pr_fmt(DRIVER_PREFIX fmt "\n"), \
88 ##arg); \
80 } while (0) 89 } while (0)
90#endif
81 91
82/* TODO: use pr_debug_hex_dump when it becomes available */ 92/* TODO: use pr_debug_hex_dump when it becomes available */
83#define wl1271_dump(level, prefix, buf, len) \ 93#define wl1271_dump(level, prefix, buf, len) \
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index 80dbc5304fac..c86bb00c2488 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -62,11 +62,14 @@ void wl1271_debugfs_update_stats(struct wl1271 *wl)
62 62
63 mutex_lock(&wl->mutex); 63 mutex_lock(&wl->mutex);
64 64
65 if (unlikely(wl->state != WLCORE_STATE_ON))
66 goto out;
67
65 ret = wl1271_ps_elp_wakeup(wl); 68 ret = wl1271_ps_elp_wakeup(wl);
66 if (ret < 0) 69 if (ret < 0)
67 goto out; 70 goto out;
68 71
69 if (wl->state == WL1271_STATE_ON && !wl->plt && 72 if (!wl->plt &&
70 time_after(jiffies, wl->stats.fw_stats_update + 73 time_after(jiffies, wl->stats.fw_stats_update +
71 msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) { 74 msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
72 wl1271_acx_statistics(wl, wl->stats.fw_stats); 75 wl1271_acx_statistics(wl, wl->stats.fw_stats);
@@ -286,7 +289,7 @@ static ssize_t dynamic_ps_timeout_write(struct file *file,
286 289
287 wl->conf.conn.dynamic_ps_timeout = value; 290 wl->conf.conn.dynamic_ps_timeout = value;
288 291
289 if (wl->state == WL1271_STATE_OFF) 292 if (unlikely(wl->state != WLCORE_STATE_ON))
290 goto out; 293 goto out;
291 294
292 ret = wl1271_ps_elp_wakeup(wl); 295 ret = wl1271_ps_elp_wakeup(wl);
@@ -353,7 +356,7 @@ static ssize_t forced_ps_write(struct file *file,
353 356
354 wl->conf.conn.forced_ps = value; 357 wl->conf.conn.forced_ps = value;
355 358
356 if (wl->state == WL1271_STATE_OFF) 359 if (unlikely(wl->state != WLCORE_STATE_ON))
357 goto out; 360 goto out;
358 361
359 ret = wl1271_ps_elp_wakeup(wl); 362 ret = wl1271_ps_elp_wakeup(wl);
@@ -486,6 +489,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
486 DRIVER_STATE_PRINT_HEX(platform_quirks); 489 DRIVER_STATE_PRINT_HEX(platform_quirks);
487 DRIVER_STATE_PRINT_HEX(chip.id); 490 DRIVER_STATE_PRINT_HEX(chip.id);
488 DRIVER_STATE_PRINT_STR(chip.fw_ver_str); 491 DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
492 DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
489 DRIVER_STATE_PRINT_INT(sched_scanning); 493 DRIVER_STATE_PRINT_INT(sched_scanning);
490 494
491#undef DRIVER_STATE_PRINT_INT 495#undef DRIVER_STATE_PRINT_INT
@@ -999,7 +1003,7 @@ static ssize_t sleep_auth_write(struct file *file,
999 1003
1000 wl->conf.conn.sta_sleep_auth = value; 1004 wl->conf.conn.sta_sleep_auth = value;
1001 1005
1002 if (wl->state == WL1271_STATE_OFF) { 1006 if (unlikely(wl->state != WLCORE_STATE_ON)) {
1003 /* this will show up on "read" in case we are off */ 1007 /* this will show up on "read" in case we are off */
1004 wl->sleep_auth = value; 1008 wl->sleep_auth = value;
1005 goto out; 1009 goto out;
@@ -1060,14 +1064,16 @@ static ssize_t dev_mem_read(struct file *file,
1060 1064
1061 mutex_lock(&wl->mutex); 1065 mutex_lock(&wl->mutex);
1062 1066
1063 if (wl->state == WL1271_STATE_OFF) { 1067 if (unlikely(wl->state == WLCORE_STATE_OFF)) {
1064 ret = -EFAULT; 1068 ret = -EFAULT;
1065 goto skip_read; 1069 goto skip_read;
1066 } 1070 }
1067 1071
1068 ret = wl1271_ps_elp_wakeup(wl); 1072 /*
1069 if (ret < 0) 1073 * Don't fail if elp_wakeup returns an error, so the device's memory
1070 goto skip_read; 1074 * could be read even if the FW crashed
1075 */
1076 wl1271_ps_elp_wakeup(wl);
1071 1077
1072 /* store current partition and switch partition */ 1078 /* store current partition and switch partition */
1073 memcpy(&old_part, &wl->curr_part, sizeof(old_part)); 1079 memcpy(&old_part, &wl->curr_part, sizeof(old_part));
@@ -1145,14 +1151,16 @@ static ssize_t dev_mem_write(struct file *file, const char __user *user_buf,
1145 1151
1146 mutex_lock(&wl->mutex); 1152 mutex_lock(&wl->mutex);
1147 1153
1148 if (wl->state == WL1271_STATE_OFF) { 1154 if (unlikely(wl->state == WLCORE_STATE_OFF)) {
1149 ret = -EFAULT; 1155 ret = -EFAULT;
1150 goto skip_write; 1156 goto skip_write;
1151 } 1157 }
1152 1158
1153 ret = wl1271_ps_elp_wakeup(wl); 1159 /*
1154 if (ret < 0) 1160 * Don't fail if elp_wakeup returns an error, so the device's memory
1155 goto skip_write; 1161 * could be read even if the FW crashed
1162 */
1163 wl1271_ps_elp_wakeup(wl);
1156 1164
1157 /* store current partition and switch partition */ 1165 /* store current partition and switch partition */
1158 memcpy(&old_part, &wl->curr_part, sizeof(old_part)); 1166 memcpy(&old_part, &wl->curr_part, sizeof(old_part));
diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c
index a3c867786df8..32d157f62f31 100644
--- a/drivers/net/wireless/ti/wlcore/init.c
+++ b/drivers/net/wireless/ti/wlcore/init.c
@@ -141,7 +141,7 @@ int wl1271_init_templates_config(struct wl1271 *wl)
141 if (ret < 0) 141 if (ret < 0)
142 return ret; 142 return ret;
143 143
144 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 144 for (i = 0; i < WLCORE_MAX_KLV_TEMPLATES; i++) {
145 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 145 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
146 CMD_TEMPL_KLV, NULL, 146 CMD_TEMPL_KLV, NULL,
147 sizeof(struct ieee80211_qos_hdr), 147 sizeof(struct ieee80211_qos_hdr),
@@ -371,15 +371,7 @@ static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl,
371 struct ieee80211_vif *vif) 371 struct ieee80211_vif *vif)
372{ 372{
373 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 373 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
374 int ret, i; 374 int ret;
375
376 /* disable all keep-alive templates */
377 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
378 ret = wl1271_acx_keep_alive_config(wl, wlvif, i,
379 ACX_KEEP_ALIVE_TPL_INVALID);
380 if (ret < 0)
381 return ret;
382 }
383 375
384 /* disable the keep-alive feature */ 376 /* disable the keep-alive feature */
385 ret = wl1271_acx_keep_alive_mode(wl, wlvif, false); 377 ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h
index 259149f36fae..f48530fec14f 100644
--- a/drivers/net/wireless/ti/wlcore/io.h
+++ b/drivers/net/wireless/ti/wlcore/io.h
@@ -64,7 +64,7 @@ static inline int __must_check wlcore_raw_write(struct wl1271 *wl, int addr,
64 return -EIO; 64 return -EIO;
65 65
66 ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed); 66 ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed);
67 if (ret && wl->state != WL1271_STATE_OFF) 67 if (ret && wl->state != WLCORE_STATE_OFF)
68 set_bit(WL1271_FLAG_IO_FAILED, &wl->flags); 68 set_bit(WL1271_FLAG_IO_FAILED, &wl->flags);
69 69
70 return ret; 70 return ret;
@@ -80,7 +80,7 @@ static inline int __must_check wlcore_raw_read(struct wl1271 *wl, int addr,
80 return -EIO; 80 return -EIO;
81 81
82 ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed); 82 ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed);
83 if (ret && wl->state != WL1271_STATE_OFF) 83 if (ret && wl->state != WLCORE_STATE_OFF)
84 set_bit(WL1271_FLAG_IO_FAILED, &wl->flags); 84 set_bit(WL1271_FLAG_IO_FAILED, &wl->flags);
85 85
86 return ret; 86 return ret;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index ff830cf50c70..25530c8760cb 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -248,7 +248,7 @@ static void wl12xx_tx_watchdog_work(struct work_struct *work)
248 248
249 mutex_lock(&wl->mutex); 249 mutex_lock(&wl->mutex);
250 250
251 if (unlikely(wl->state == WL1271_STATE_OFF)) 251 if (unlikely(wl->state != WLCORE_STATE_ON))
252 goto out; 252 goto out;
253 253
254 /* Tx went out in the meantime - everything is ok */ 254 /* Tx went out in the meantime - everything is ok */
@@ -512,7 +512,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
512 512
513 wl1271_debug(DEBUG_IRQ, "IRQ work"); 513 wl1271_debug(DEBUG_IRQ, "IRQ work");
514 514
515 if (unlikely(wl->state == WL1271_STATE_OFF)) 515 if (unlikely(wl->state != WLCORE_STATE_ON))
516 goto out; 516 goto out;
517 517
518 ret = wl1271_ps_elp_wakeup(wl); 518 ret = wl1271_ps_elp_wakeup(wl);
@@ -696,7 +696,7 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
696 * we can't call wl12xx_get_vif_count() here because 696 * we can't call wl12xx_get_vif_count() here because
697 * wl->mutex is taken, so use the cached last_vif_count value 697 * wl->mutex is taken, so use the cached last_vif_count value
698 */ 698 */
699 if (wl->last_vif_count > 1) { 699 if (wl->last_vif_count > 1 && wl->mr_fw_name) {
700 fw_type = WL12XX_FW_TYPE_MULTI; 700 fw_type = WL12XX_FW_TYPE_MULTI;
701 fw_name = wl->mr_fw_name; 701 fw_name = wl->mr_fw_name;
702 } else { 702 } else {
@@ -744,38 +744,14 @@ out:
744 return ret; 744 return ret;
745} 745}
746 746
747static void wl1271_fetch_nvs(struct wl1271 *wl)
748{
749 const struct firmware *fw;
750 int ret;
751
752 ret = request_firmware(&fw, WL12XX_NVS_NAME, wl->dev);
753
754 if (ret < 0) {
755 wl1271_debug(DEBUG_BOOT, "could not get nvs file %s: %d",
756 WL12XX_NVS_NAME, ret);
757 return;
758 }
759
760 wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
761
762 if (!wl->nvs) {
763 wl1271_error("could not allocate memory for the nvs file");
764 goto out;
765 }
766
767 wl->nvs_len = fw->size;
768
769out:
770 release_firmware(fw);
771}
772
773void wl12xx_queue_recovery_work(struct wl1271 *wl) 747void wl12xx_queue_recovery_work(struct wl1271 *wl)
774{ 748{
775 WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); 749 WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
776 750
777 /* Avoid a recursive recovery */ 751 /* Avoid a recursive recovery */
778 if (!test_and_set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { 752 if (wl->state == WLCORE_STATE_ON) {
753 wl->state = WLCORE_STATE_RESTARTING;
754 set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
779 wlcore_disable_interrupts_nosync(wl); 755 wlcore_disable_interrupts_nosync(wl);
780 ieee80211_queue_work(wl->hw, &wl->recovery_work); 756 ieee80211_queue_work(wl->hw, &wl->recovery_work);
781 } 757 }
@@ -913,7 +889,7 @@ static void wl1271_recovery_work(struct work_struct *work)
913 889
914 mutex_lock(&wl->mutex); 890 mutex_lock(&wl->mutex);
915 891
916 if (wl->state != WL1271_STATE_ON || wl->plt) 892 if (wl->state == WLCORE_STATE_OFF || wl->plt)
917 goto out_unlock; 893 goto out_unlock;
918 894
919 if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) { 895 if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) {
@@ -1081,7 +1057,7 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
1081 1057
1082 wl1271_notice("power up"); 1058 wl1271_notice("power up");
1083 1059
1084 if (wl->state != WL1271_STATE_OFF) { 1060 if (wl->state != WLCORE_STATE_OFF) {
1085 wl1271_error("cannot go into PLT state because not " 1061 wl1271_error("cannot go into PLT state because not "
1086 "in off state: %d", wl->state); 1062 "in off state: %d", wl->state);
1087 ret = -EBUSY; 1063 ret = -EBUSY;
@@ -1102,7 +1078,7 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
1102 if (ret < 0) 1078 if (ret < 0)
1103 goto power_off; 1079 goto power_off;
1104 1080
1105 wl->state = WL1271_STATE_ON; 1081 wl->state = WLCORE_STATE_ON;
1106 wl1271_notice("firmware booted in PLT mode %s (%s)", 1082 wl1271_notice("firmware booted in PLT mode %s (%s)",
1107 PLT_MODE[plt_mode], 1083 PLT_MODE[plt_mode],
1108 wl->chip.fw_ver_str); 1084 wl->chip.fw_ver_str);
@@ -1171,7 +1147,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
1171 wl1271_power_off(wl); 1147 wl1271_power_off(wl);
1172 wl->flags = 0; 1148 wl->flags = 0;
1173 wl->sleep_auth = WL1271_PSM_ILLEGAL; 1149 wl->sleep_auth = WL1271_PSM_ILLEGAL;
1174 wl->state = WL1271_STATE_OFF; 1150 wl->state = WLCORE_STATE_OFF;
1175 wl->plt = false; 1151 wl->plt = false;
1176 wl->plt_mode = PLT_OFF; 1152 wl->plt_mode = PLT_OFF;
1177 wl->rx_counter = 0; 1153 wl->rx_counter = 0;
@@ -1602,12 +1578,6 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1602 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 1578 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1603 goto out; 1579 goto out;
1604 1580
1605 if ((wl->conf.conn.suspend_wake_up_event ==
1606 wl->conf.conn.wake_up_event) &&
1607 (wl->conf.conn.suspend_listen_interval ==
1608 wl->conf.conn.listen_interval))
1609 goto out;
1610
1611 ret = wl1271_ps_elp_wakeup(wl); 1581 ret = wl1271_ps_elp_wakeup(wl);
1612 if (ret < 0) 1582 if (ret < 0)
1613 goto out; 1583 goto out;
@@ -1616,6 +1586,12 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1616 if (ret < 0) 1586 if (ret < 0)
1617 goto out_sleep; 1587 goto out_sleep;
1618 1588
1589 if ((wl->conf.conn.suspend_wake_up_event ==
1590 wl->conf.conn.wake_up_event) &&
1591 (wl->conf.conn.suspend_listen_interval ==
1592 wl->conf.conn.listen_interval))
1593 goto out_sleep;
1594
1619 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1595 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
1620 wl->conf.conn.suspend_wake_up_event, 1596 wl->conf.conn.suspend_wake_up_event,
1621 wl->conf.conn.suspend_listen_interval); 1597 wl->conf.conn.suspend_listen_interval);
@@ -1671,11 +1647,7 @@ static void wl1271_configure_resume(struct wl1271 *wl,
1671 if ((!is_ap) && (!is_sta)) 1647 if ((!is_ap) && (!is_sta))
1672 return; 1648 return;
1673 1649
1674 if (is_sta && 1650 if (is_sta && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1675 ((wl->conf.conn.suspend_wake_up_event ==
1676 wl->conf.conn.wake_up_event) &&
1677 (wl->conf.conn.suspend_listen_interval ==
1678 wl->conf.conn.listen_interval)))
1679 return; 1651 return;
1680 1652
1681 ret = wl1271_ps_elp_wakeup(wl); 1653 ret = wl1271_ps_elp_wakeup(wl);
@@ -1685,6 +1657,12 @@ static void wl1271_configure_resume(struct wl1271 *wl,
1685 if (is_sta) { 1657 if (is_sta) {
1686 wl1271_configure_wowlan(wl, NULL); 1658 wl1271_configure_wowlan(wl, NULL);
1687 1659
1660 if ((wl->conf.conn.suspend_wake_up_event ==
1661 wl->conf.conn.wake_up_event) &&
1662 (wl->conf.conn.suspend_listen_interval ==
1663 wl->conf.conn.listen_interval))
1664 goto out_sleep;
1665
1688 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1666 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
1689 wl->conf.conn.wake_up_event, 1667 wl->conf.conn.wake_up_event,
1690 wl->conf.conn.listen_interval); 1668 wl->conf.conn.listen_interval);
@@ -1697,6 +1675,7 @@ static void wl1271_configure_resume(struct wl1271 *wl,
1697 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); 1675 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
1698 } 1676 }
1699 1677
1678out_sleep:
1700 wl1271_ps_elp_sleep(wl); 1679 wl1271_ps_elp_sleep(wl);
1701} 1680}
1702 1681
@@ -1833,7 +1812,7 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1833{ 1812{
1834 int i; 1813 int i;
1835 1814
1836 if (wl->state == WL1271_STATE_OFF) { 1815 if (wl->state == WLCORE_STATE_OFF) {
1837 if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, 1816 if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS,
1838 &wl->flags)) 1817 &wl->flags))
1839 wlcore_enable_interrupts(wl); 1818 wlcore_enable_interrupts(wl);
@@ -1845,7 +1824,7 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1845 * this must be before the cancel_work calls below, so that the work 1824 * this must be before the cancel_work calls below, so that the work
1846 * functions don't perform further work. 1825 * functions don't perform further work.
1847 */ 1826 */
1848 wl->state = WL1271_STATE_OFF; 1827 wl->state = WLCORE_STATE_OFF;
1849 1828
1850 /* 1829 /*
1851 * Use the nosync variant to disable interrupts, so the mutex could be 1830 * Use the nosync variant to disable interrupts, so the mutex could be
@@ -1856,6 +1835,8 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1856 mutex_unlock(&wl->mutex); 1835 mutex_unlock(&wl->mutex);
1857 1836
1858 wlcore_synchronize_interrupts(wl); 1837 wlcore_synchronize_interrupts(wl);
1838 if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
1839 cancel_work_sync(&wl->recovery_work);
1859 wl1271_flush_deferred_work(wl); 1840 wl1271_flush_deferred_work(wl);
1860 cancel_delayed_work_sync(&wl->scan_complete_work); 1841 cancel_delayed_work_sync(&wl->scan_complete_work);
1861 cancel_work_sync(&wl->netstack_work); 1842 cancel_work_sync(&wl->netstack_work);
@@ -1958,6 +1939,27 @@ static void wl12xx_free_rate_policy(struct wl1271 *wl, u8 *idx)
1958 *idx = WL12XX_MAX_RATE_POLICIES; 1939 *idx = WL12XX_MAX_RATE_POLICIES;
1959} 1940}
1960 1941
1942static int wlcore_allocate_klv_template(struct wl1271 *wl, u8 *idx)
1943{
1944 u8 policy = find_first_zero_bit(wl->klv_templates_map,
1945 WLCORE_MAX_KLV_TEMPLATES);
1946 if (policy >= WLCORE_MAX_KLV_TEMPLATES)
1947 return -EBUSY;
1948
1949 __set_bit(policy, wl->klv_templates_map);
1950 *idx = policy;
1951 return 0;
1952}
1953
1954static void wlcore_free_klv_template(struct wl1271 *wl, u8 *idx)
1955{
1956 if (WARN_ON(*idx >= WLCORE_MAX_KLV_TEMPLATES))
1957 return;
1958
1959 __clear_bit(*idx, wl->klv_templates_map);
1960 *idx = WLCORE_MAX_KLV_TEMPLATES;
1961}
1962
1961static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1963static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1962{ 1964{
1963 switch (wlvif->bss_type) { 1965 switch (wlvif->bss_type) {
@@ -2022,6 +2024,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
2022 wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx); 2024 wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx);
2023 wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx); 2025 wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx);
2024 wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx); 2026 wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
2027 wlcore_allocate_klv_template(wl, &wlvif->sta.klv_template_id);
2025 wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC; 2028 wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
2026 wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC; 2029 wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC;
2027 wlvif->rate_set = CONF_TX_RATE_MASK_BASIC; 2030 wlvif->rate_set = CONF_TX_RATE_MASK_BASIC;
@@ -2098,7 +2101,7 @@ irq_disable:
2098 /* Unlocking the mutex in the middle of handling is 2101 /* Unlocking the mutex in the middle of handling is
2099 inherently unsafe. In this case we deem it safe to do, 2102 inherently unsafe. In this case we deem it safe to do,
2100 because we need to let any possibly pending IRQ out of 2103 because we need to let any possibly pending IRQ out of
2101 the system (and while we are WL1271_STATE_OFF the IRQ 2104 the system (and while we are WLCORE_STATE_OFF the IRQ
2102 work function will not do anything.) Also, any other 2105 work function will not do anything.) Also, any other
2103 possible concurrent operations will fail due to the 2106 possible concurrent operations will fail due to the
2104 current state, hence the wl1271 struct should be safe. */ 2107 current state, hence the wl1271 struct should be safe. */
@@ -2133,7 +2136,7 @@ power_off:
2133 wl1271_debug(DEBUG_MAC80211, "11a is %ssupported", 2136 wl1271_debug(DEBUG_MAC80211, "11a is %ssupported",
2134 wl->enable_11a ? "" : "not "); 2137 wl->enable_11a ? "" : "not ");
2135 2138
2136 wl->state = WL1271_STATE_ON; 2139 wl->state = WLCORE_STATE_ON;
2137out: 2140out:
2138 return booted; 2141 return booted;
2139} 2142}
@@ -2167,7 +2170,11 @@ static bool wl12xx_need_fw_change(struct wl1271 *wl,
2167 wl->last_vif_count = vif_count; 2170 wl->last_vif_count = vif_count;
2168 2171
2169 /* no need for fw change if the device is OFF */ 2172 /* no need for fw change if the device is OFF */
2170 if (wl->state == WL1271_STATE_OFF) 2173 if (wl->state == WLCORE_STATE_OFF)
2174 return false;
2175
2176 /* no need for fw change if a single fw is used */
2177 if (!wl->mr_fw_name)
2171 return false; 2178 return false;
2172 2179
2173 if (vif_count > 1 && current_fw == WL12XX_FW_TYPE_NORMAL) 2180 if (vif_count > 1 && current_fw == WL12XX_FW_TYPE_NORMAL)
@@ -2249,7 +2256,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2249 * TODO: after the nvs issue will be solved, move this block 2256 * TODO: after the nvs issue will be solved, move this block
2250 * to start(), and make sure here the driver is ON. 2257 * to start(), and make sure here the driver is ON.
2251 */ 2258 */
2252 if (wl->state == WL1271_STATE_OFF) { 2259 if (wl->state == WLCORE_STATE_OFF) {
2253 /* 2260 /*
2254 * we still need this in order to configure the fw 2261 * we still need this in order to configure the fw
2255 * while uploading the nvs 2262 * while uploading the nvs
@@ -2263,21 +2270,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2263 } 2270 }
2264 } 2271 }
2265 2272
2266 if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
2267 wlvif->bss_type == BSS_TYPE_IBSS) {
2268 /*
2269 * The device role is a special role used for
2270 * rx and tx frames prior to association (as
2271 * the STA role can get packets only from
2272 * its associated bssid)
2273 */
2274 ret = wl12xx_cmd_role_enable(wl, vif->addr,
2275 WL1271_ROLE_DEVICE,
2276 &wlvif->dev_role_id);
2277 if (ret < 0)
2278 goto out;
2279 }
2280
2281 ret = wl12xx_cmd_role_enable(wl, vif->addr, 2273 ret = wl12xx_cmd_role_enable(wl, vif->addr,
2282 role_type, &wlvif->role_id); 2274 role_type, &wlvif->role_id);
2283 if (ret < 0) 2275 if (ret < 0)
@@ -2316,7 +2308,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2316 return; 2308 return;
2317 2309
2318 /* because of hardware recovery, we may get here twice */ 2310 /* because of hardware recovery, we may get here twice */
2319 if (wl->state != WL1271_STATE_ON) 2311 if (wl->state == WLCORE_STATE_OFF)
2320 return; 2312 return;
2321 2313
2322 wl1271_info("down"); 2314 wl1271_info("down");
@@ -2346,10 +2338,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2346 wlvif->bss_type == BSS_TYPE_IBSS) { 2338 wlvif->bss_type == BSS_TYPE_IBSS) {
2347 if (wl12xx_dev_role_started(wlvif)) 2339 if (wl12xx_dev_role_started(wlvif))
2348 wl12xx_stop_dev(wl, wlvif); 2340 wl12xx_stop_dev(wl, wlvif);
2349
2350 ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
2351 if (ret < 0)
2352 goto deinit;
2353 } 2341 }
2354 2342
2355 ret = wl12xx_cmd_role_disable(wl, &wlvif->role_id); 2343 ret = wl12xx_cmd_role_disable(wl, &wlvif->role_id);
@@ -2368,6 +2356,7 @@ deinit:
2368 wl12xx_free_rate_policy(wl, &wlvif->sta.basic_rate_idx); 2356 wl12xx_free_rate_policy(wl, &wlvif->sta.basic_rate_idx);
2369 wl12xx_free_rate_policy(wl, &wlvif->sta.ap_rate_idx); 2357 wl12xx_free_rate_policy(wl, &wlvif->sta.ap_rate_idx);
2370 wl12xx_free_rate_policy(wl, &wlvif->sta.p2p_rate_idx); 2358 wl12xx_free_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
2359 wlcore_free_klv_template(wl, &wlvif->sta.klv_template_id);
2371 } else { 2360 } else {
2372 wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID; 2361 wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
2373 wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID; 2362 wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
@@ -2432,12 +2421,11 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
2432 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 2421 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
2433 struct wl12xx_vif *iter; 2422 struct wl12xx_vif *iter;
2434 struct vif_counter_data vif_count; 2423 struct vif_counter_data vif_count;
2435 bool cancel_recovery = true;
2436 2424
2437 wl12xx_get_vif_count(hw, vif, &vif_count); 2425 wl12xx_get_vif_count(hw, vif, &vif_count);
2438 mutex_lock(&wl->mutex); 2426 mutex_lock(&wl->mutex);
2439 2427
2440 if (wl->state == WL1271_STATE_OFF || 2428 if (wl->state == WLCORE_STATE_OFF ||
2441 !test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) 2429 !test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
2442 goto out; 2430 goto out;
2443 2431
@@ -2457,12 +2445,9 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
2457 wl12xx_force_active_psm(wl); 2445 wl12xx_force_active_psm(wl);
2458 set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); 2446 set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
2459 wl12xx_queue_recovery_work(wl); 2447 wl12xx_queue_recovery_work(wl);
2460 cancel_recovery = false;
2461 } 2448 }
2462out: 2449out:
2463 mutex_unlock(&wl->mutex); 2450 mutex_unlock(&wl->mutex);
2464 if (cancel_recovery)
2465 cancel_work_sync(&wl->recovery_work);
2466} 2451}
2467 2452
2468static int wl12xx_op_change_interface(struct ieee80211_hw *hw, 2453static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
@@ -2536,7 +2521,7 @@ static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2536 goto out; 2521 goto out;
2537 2522
2538 ret = wl1271_acx_keep_alive_config(wl, wlvif, 2523 ret = wl1271_acx_keep_alive_config(wl, wlvif,
2539 CMD_TEMPL_KLV_IDX_NULL_DATA, 2524 wlvif->sta.klv_template_id,
2540 ACX_KEEP_ALIVE_TPL_VALID); 2525 ACX_KEEP_ALIVE_TPL_VALID);
2541 if (ret < 0) 2526 if (ret < 0)
2542 goto out; 2527 goto out;
@@ -2556,6 +2541,11 @@ static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2556 ieee80211_chswitch_done(vif, false); 2541 ieee80211_chswitch_done(vif, false);
2557 } 2542 }
2558 2543
2544 /* invalidate keep-alive template */
2545 wl1271_acx_keep_alive_config(wl, wlvif,
2546 wlvif->sta.klv_template_id,
2547 ACX_KEEP_ALIVE_TPL_INVALID);
2548
2559 /* to stop listening to a channel, we disconnect */ 2549 /* to stop listening to a channel, we disconnect */
2560 ret = wl12xx_cmd_role_stop_sta(wl, wlvif); 2550 ret = wl12xx_cmd_role_stop_sta(wl, wlvif);
2561 if (ret < 0) 2551 if (ret < 0)
@@ -2596,11 +2586,6 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2596 ret = wl1271_acx_sta_rate_policies(wl, wlvif); 2586 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
2597 if (ret < 0) 2587 if (ret < 0)
2598 goto out; 2588 goto out;
2599 ret = wl1271_acx_keep_alive_config(
2600 wl, wlvif, CMD_TEMPL_KLV_IDX_NULL_DATA,
2601 ACX_KEEP_ALIVE_TPL_INVALID);
2602 if (ret < 0)
2603 goto out;
2604 clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); 2589 clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
2605 } else { 2590 } else {
2606 /* The current firmware only supports sched_scan in idle */ 2591 /* The current firmware only supports sched_scan in idle */
@@ -2772,7 +2757,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
2772 if (changed & IEEE80211_CONF_CHANGE_POWER) 2757 if (changed & IEEE80211_CONF_CHANGE_POWER)
2773 wl->power_level = conf->power_level; 2758 wl->power_level = conf->power_level;
2774 2759
2775 if (unlikely(wl->state == WL1271_STATE_OFF)) 2760 if (unlikely(wl->state != WLCORE_STATE_ON))
2776 goto out; 2761 goto out;
2777 2762
2778 ret = wl1271_ps_elp_wakeup(wl); 2763 ret = wl1271_ps_elp_wakeup(wl);
@@ -2806,10 +2791,6 @@ static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
2806{ 2791{
2807 struct wl1271_filter_params *fp; 2792 struct wl1271_filter_params *fp;
2808 struct netdev_hw_addr *ha; 2793 struct netdev_hw_addr *ha;
2809 struct wl1271 *wl = hw->priv;
2810
2811 if (unlikely(wl->state == WL1271_STATE_OFF))
2812 return 0;
2813 2794
2814 fp = kzalloc(sizeof(*fp), GFP_ATOMIC); 2795 fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
2815 if (!fp) { 2796 if (!fp) {
@@ -2858,7 +2839,7 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
2858 *total &= WL1271_SUPPORTED_FILTERS; 2839 *total &= WL1271_SUPPORTED_FILTERS;
2859 changed &= WL1271_SUPPORTED_FILTERS; 2840 changed &= WL1271_SUPPORTED_FILTERS;
2860 2841
2861 if (unlikely(wl->state == WL1271_STATE_OFF)) 2842 if (unlikely(wl->state != WLCORE_STATE_ON))
2862 goto out; 2843 goto out;
2863 2844
2864 ret = wl1271_ps_elp_wakeup(wl); 2845 ret = wl1271_ps_elp_wakeup(wl);
@@ -3082,8 +3063,45 @@ static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3082 struct ieee80211_key_conf *key_conf) 3063 struct ieee80211_key_conf *key_conf)
3083{ 3064{
3084 struct wl1271 *wl = hw->priv; 3065 struct wl1271 *wl = hw->priv;
3066 int ret;
3067 bool might_change_spare =
3068 key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
3069 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
3085 3070
3086 return wlcore_hw_set_key(wl, cmd, vif, sta, key_conf); 3071 if (might_change_spare) {
3072 /*
3073 * stop the queues and flush to ensure the next packets are
3074 * in sync with FW spare block accounting
3075 */
3076 mutex_lock(&wl->mutex);
3077 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
3078 mutex_unlock(&wl->mutex);
3079
3080 wl1271_tx_flush(wl);
3081 }
3082
3083 mutex_lock(&wl->mutex);
3084
3085 if (unlikely(wl->state != WLCORE_STATE_ON)) {
3086 ret = -EAGAIN;
3087 goto out_wake_queues;
3088 }
3089
3090 ret = wl1271_ps_elp_wakeup(wl);
3091 if (ret < 0)
3092 goto out_wake_queues;
3093
3094 ret = wlcore_hw_set_key(wl, cmd, vif, sta, key_conf);
3095
3096 wl1271_ps_elp_sleep(wl);
3097
3098out_wake_queues:
3099 if (might_change_spare)
3100 wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
3101
3102 mutex_unlock(&wl->mutex);
3103
3104 return ret;
3087} 3105}
3088 3106
3089int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, 3107int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
@@ -3105,17 +3123,6 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3105 key_conf->keylen, key_conf->flags); 3123 key_conf->keylen, key_conf->flags);
3106 wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); 3124 wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
3107 3125
3108 mutex_lock(&wl->mutex);
3109
3110 if (unlikely(wl->state == WL1271_STATE_OFF)) {
3111 ret = -EAGAIN;
3112 goto out_unlock;
3113 }
3114
3115 ret = wl1271_ps_elp_wakeup(wl);
3116 if (ret < 0)
3117 goto out_unlock;
3118
3119 switch (key_conf->cipher) { 3126 switch (key_conf->cipher) {
3120 case WLAN_CIPHER_SUITE_WEP40: 3127 case WLAN_CIPHER_SUITE_WEP40:
3121 case WLAN_CIPHER_SUITE_WEP104: 3128 case WLAN_CIPHER_SUITE_WEP104:
@@ -3145,8 +3152,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3145 default: 3152 default:
3146 wl1271_error("Unknown key algo 0x%x", key_conf->cipher); 3153 wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
3147 3154
3148 ret = -EOPNOTSUPP; 3155 return -EOPNOTSUPP;
3149 goto out_sleep;
3150 } 3156 }
3151 3157
3152 switch (cmd) { 3158 switch (cmd) {
@@ -3157,7 +3163,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3157 tx_seq_32, tx_seq_16, sta); 3163 tx_seq_32, tx_seq_16, sta);
3158 if (ret < 0) { 3164 if (ret < 0) {
3159 wl1271_error("Could not add or replace key"); 3165 wl1271_error("Could not add or replace key");
3160 goto out_sleep; 3166 return ret;
3161 } 3167 }
3162 3168
3163 /* 3169 /*
@@ -3171,7 +3177,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3171 ret = wl1271_cmd_build_arp_rsp(wl, wlvif); 3177 ret = wl1271_cmd_build_arp_rsp(wl, wlvif);
3172 if (ret < 0) { 3178 if (ret < 0) {
3173 wl1271_warning("build arp rsp failed: %d", ret); 3179 wl1271_warning("build arp rsp failed: %d", ret);
3174 goto out_sleep; 3180 return ret;
3175 } 3181 }
3176 } 3182 }
3177 break; 3183 break;
@@ -3183,22 +3189,15 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3183 0, 0, sta); 3189 0, 0, sta);
3184 if (ret < 0) { 3190 if (ret < 0) {
3185 wl1271_error("Could not remove key"); 3191 wl1271_error("Could not remove key");
3186 goto out_sleep; 3192 return ret;
3187 } 3193 }
3188 break; 3194 break;
3189 3195
3190 default: 3196 default:
3191 wl1271_error("Unsupported key cmd 0x%x", cmd); 3197 wl1271_error("Unsupported key cmd 0x%x", cmd);
3192 ret = -EOPNOTSUPP; 3198 return -EOPNOTSUPP;
3193 break;
3194 } 3199 }
3195 3200
3196out_sleep:
3197 wl1271_ps_elp_sleep(wl);
3198
3199out_unlock:
3200 mutex_unlock(&wl->mutex);
3201
3202 return ret; 3201 return ret;
3203} 3202}
3204EXPORT_SYMBOL_GPL(wlcore_set_key); 3203EXPORT_SYMBOL_GPL(wlcore_set_key);
@@ -3221,7 +3220,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3221 3220
3222 mutex_lock(&wl->mutex); 3221 mutex_lock(&wl->mutex);
3223 3222
3224 if (wl->state == WL1271_STATE_OFF) { 3223 if (unlikely(wl->state != WLCORE_STATE_ON)) {
3225 /* 3224 /*
3226 * We cannot return -EBUSY here because cfg80211 will expect 3225 * We cannot return -EBUSY here because cfg80211 will expect
3227 * a call to ieee80211_scan_completed if we do - in this case 3226 * a call to ieee80211_scan_completed if we do - in this case
@@ -3261,7 +3260,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3261 3260
3262 mutex_lock(&wl->mutex); 3261 mutex_lock(&wl->mutex);
3263 3262
3264 if (wl->state == WL1271_STATE_OFF) 3263 if (unlikely(wl->state != WLCORE_STATE_ON))
3265 goto out; 3264 goto out;
3266 3265
3267 if (wl->scan.state == WL1271_SCAN_STATE_IDLE) 3266 if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
@@ -3310,7 +3309,7 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
3310 3309
3311 mutex_lock(&wl->mutex); 3310 mutex_lock(&wl->mutex);
3312 3311
3313 if (wl->state == WL1271_STATE_OFF) { 3312 if (unlikely(wl->state != WLCORE_STATE_ON)) {
3314 ret = -EAGAIN; 3313 ret = -EAGAIN;
3315 goto out; 3314 goto out;
3316 } 3315 }
@@ -3347,7 +3346,7 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
3347 3346
3348 mutex_lock(&wl->mutex); 3347 mutex_lock(&wl->mutex);
3349 3348
3350 if (wl->state == WL1271_STATE_OFF) 3349 if (unlikely(wl->state != WLCORE_STATE_ON))
3351 goto out; 3350 goto out;
3352 3351
3353 ret = wl1271_ps_elp_wakeup(wl); 3352 ret = wl1271_ps_elp_wakeup(wl);
@@ -3368,7 +3367,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
3368 3367
3369 mutex_lock(&wl->mutex); 3368 mutex_lock(&wl->mutex);
3370 3369
3371 if (unlikely(wl->state == WL1271_STATE_OFF)) { 3370 if (unlikely(wl->state != WLCORE_STATE_ON)) {
3372 ret = -EAGAIN; 3371 ret = -EAGAIN;
3373 goto out; 3372 goto out;
3374 } 3373 }
@@ -3397,7 +3396,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3397 3396
3398 mutex_lock(&wl->mutex); 3397 mutex_lock(&wl->mutex);
3399 3398
3400 if (unlikely(wl->state == WL1271_STATE_OFF)) { 3399 if (unlikely(wl->state != WLCORE_STATE_ON)) {
3401 ret = -EAGAIN; 3400 ret = -EAGAIN;
3402 goto out; 3401 goto out;
3403 } 3402 }
@@ -4173,7 +4172,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
4173 4172
4174 mutex_lock(&wl->mutex); 4173 mutex_lock(&wl->mutex);
4175 4174
4176 if (unlikely(wl->state == WL1271_STATE_OFF)) 4175 if (unlikely(wl->state != WLCORE_STATE_ON))
4177 goto out; 4176 goto out;
4178 4177
4179 if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))) 4178 if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
@@ -4257,7 +4256,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
4257 4256
4258 mutex_lock(&wl->mutex); 4257 mutex_lock(&wl->mutex);
4259 4258
4260 if (unlikely(wl->state == WL1271_STATE_OFF)) 4259 if (unlikely(wl->state != WLCORE_STATE_ON))
4261 goto out; 4260 goto out;
4262 4261
4263 ret = wl1271_ps_elp_wakeup(wl); 4262 ret = wl1271_ps_elp_wakeup(wl);
@@ -4456,7 +4455,7 @@ static int wl12xx_op_sta_state(struct ieee80211_hw *hw,
4456 4455
4457 mutex_lock(&wl->mutex); 4456 mutex_lock(&wl->mutex);
4458 4457
4459 if (unlikely(wl->state == WL1271_STATE_OFF)) { 4458 if (unlikely(wl->state != WLCORE_STATE_ON)) {
4460 ret = -EBUSY; 4459 ret = -EBUSY;
4461 goto out; 4460 goto out;
4462 } 4461 }
@@ -4495,7 +4494,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
4495 4494
4496 mutex_lock(&wl->mutex); 4495 mutex_lock(&wl->mutex);
4497 4496
4498 if (unlikely(wl->state == WL1271_STATE_OFF)) { 4497 if (unlikely(wl->state != WLCORE_STATE_ON)) {
4499 ret = -EAGAIN; 4498 ret = -EAGAIN;
4500 goto out; 4499 goto out;
4501 } 4500 }
@@ -4613,7 +4612,7 @@ static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw,
4613 mask->control[i].legacy, 4612 mask->control[i].legacy,
4614 i); 4613 i);
4615 4614
4616 if (unlikely(wl->state == WL1271_STATE_OFF)) 4615 if (unlikely(wl->state != WLCORE_STATE_ON))
4617 goto out; 4616 goto out;
4618 4617
4619 if (wlvif->bss_type == BSS_TYPE_STA_BSS && 4618 if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
@@ -4649,12 +4648,14 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
4649 4648
4650 mutex_lock(&wl->mutex); 4649 mutex_lock(&wl->mutex);
4651 4650
4652 if (unlikely(wl->state == WL1271_STATE_OFF)) { 4651 if (unlikely(wl->state == WLCORE_STATE_OFF)) {
4653 wl12xx_for_each_wlvif_sta(wl, wlvif) { 4652 wl12xx_for_each_wlvif_sta(wl, wlvif) {
4654 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 4653 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
4655 ieee80211_chswitch_done(vif, false); 4654 ieee80211_chswitch_done(vif, false);
4656 } 4655 }
4657 goto out; 4656 goto out;
4657 } else if (unlikely(wl->state != WLCORE_STATE_ON)) {
4658 goto out;
4658 } 4659 }
4659 4660
4660 ret = wl1271_ps_elp_wakeup(wl); 4661 ret = wl1271_ps_elp_wakeup(wl);
@@ -4689,7 +4690,7 @@ static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
4689 4690
4690 mutex_lock(&wl->mutex); 4691 mutex_lock(&wl->mutex);
4691 4692
4692 if (unlikely(wl->state == WL1271_STATE_OFF)) 4693 if (unlikely(wl->state != WLCORE_STATE_ON))
4693 goto out; 4694 goto out;
4694 4695
4695 /* packets are considered pending if in the TX queue or the FW */ 4696 /* packets are considered pending if in the TX queue or the FW */
@@ -4938,7 +4939,7 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
4938 4939
4939 wl->sg_enabled = res; 4940 wl->sg_enabled = res;
4940 4941
4941 if (wl->state == WL1271_STATE_OFF) 4942 if (unlikely(wl->state != WLCORE_STATE_ON))
4942 goto out; 4943 goto out;
4943 4944
4944 ret = wl1271_ps_elp_wakeup(wl); 4945 ret = wl1271_ps_elp_wakeup(wl);
@@ -5056,7 +5057,7 @@ static void wl1271_connection_loss_work(struct work_struct *work)
5056 5057
5057 mutex_lock(&wl->mutex); 5058 mutex_lock(&wl->mutex);
5058 5059
5059 if (unlikely(wl->state == WL1271_STATE_OFF)) 5060 if (unlikely(wl->state != WLCORE_STATE_ON))
5060 goto out; 5061 goto out;
5061 5062
5062 /* Call mac80211 connection loss */ 5063 /* Call mac80211 connection loss */
@@ -5070,18 +5071,17 @@ out:
5070 mutex_unlock(&wl->mutex); 5071 mutex_unlock(&wl->mutex);
5071} 5072}
5072 5073
5073static void wl12xx_derive_mac_addresses(struct wl1271 *wl, 5074static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic)
5074 u32 oui, u32 nic, int n)
5075{ 5075{
5076 int i; 5076 int i;
5077 5077
5078 wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x, n %d", 5078 wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x",
5079 oui, nic, n); 5079 oui, nic);
5080 5080
5081 if (nic + n - 1 > 0xffffff) 5081 if (nic + WLCORE_NUM_MAC_ADDRESSES - wl->num_mac_addr > 0xffffff)
5082 wl1271_warning("NIC part of the MAC address wraps around!"); 5082 wl1271_warning("NIC part of the MAC address wraps around!");
5083 5083
5084 for (i = 0; i < n; i++) { 5084 for (i = 0; i < wl->num_mac_addr; i++) {
5085 wl->addresses[i].addr[0] = (u8)(oui >> 16); 5085 wl->addresses[i].addr[0] = (u8)(oui >> 16);
5086 wl->addresses[i].addr[1] = (u8)(oui >> 8); 5086 wl->addresses[i].addr[1] = (u8)(oui >> 8);
5087 wl->addresses[i].addr[2] = (u8) oui; 5087 wl->addresses[i].addr[2] = (u8) oui;
@@ -5091,7 +5091,22 @@ static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
5091 nic++; 5091 nic++;
5092 } 5092 }
5093 5093
5094 wl->hw->wiphy->n_addresses = n; 5094 /* we may be one address short at the most */
5095 WARN_ON(wl->num_mac_addr + 1 < WLCORE_NUM_MAC_ADDRESSES);
5096
5097 /*
5098 * turn on the LAA bit in the first address and use it as
5099 * the last address.
5100 */
5101 if (wl->num_mac_addr < WLCORE_NUM_MAC_ADDRESSES) {
5102 int idx = WLCORE_NUM_MAC_ADDRESSES - 1;
5103 memcpy(&wl->addresses[idx], &wl->addresses[0],
5104 sizeof(wl->addresses[0]));
5105 /* LAA bit */
5106 wl->addresses[idx].addr[2] |= BIT(1);
5107 }
5108
5109 wl->hw->wiphy->n_addresses = WLCORE_NUM_MAC_ADDRESSES;
5095 wl->hw->wiphy->addresses = wl->addresses; 5110 wl->hw->wiphy->addresses = wl->addresses;
5096} 5111}
5097 5112
@@ -5130,8 +5145,7 @@ static int wl1271_register_hw(struct wl1271 *wl)
5130 if (wl->mac80211_registered) 5145 if (wl->mac80211_registered)
5131 return 0; 5146 return 0;
5132 5147
5133 wl1271_fetch_nvs(wl); 5148 if (wl->nvs_len >= 12) {
5134 if (wl->nvs != NULL) {
5135 /* NOTE: The wl->nvs->nvs element must be first, in 5149 /* NOTE: The wl->nvs->nvs element must be first, in
5136 * order to simplify the casting, we assume it is at 5150 * order to simplify the casting, we assume it is at
5137 * the beginning of the wl->nvs structure. 5151 * the beginning of the wl->nvs structure.
@@ -5151,7 +5165,7 @@ static int wl1271_register_hw(struct wl1271 *wl)
5151 nic_addr = wl->fuse_nic_addr + 1; 5165 nic_addr = wl->fuse_nic_addr + 1;
5152 } 5166 }
5153 5167
5154 wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr, 2); 5168 wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr);
5155 5169
5156 ret = ieee80211_register_hw(wl->hw); 5170 ret = ieee80211_register_hw(wl->hw);
5157 if (ret < 0) { 5171 if (ret < 0) {
@@ -5181,7 +5195,7 @@ static void wl1271_unregister_hw(struct wl1271 *wl)
5181 5195
5182static const struct ieee80211_iface_limit wlcore_iface_limits[] = { 5196static const struct ieee80211_iface_limit wlcore_iface_limits[] = {
5183 { 5197 {
5184 .max = 2, 5198 .max = 3,
5185 .types = BIT(NL80211_IFTYPE_STATION), 5199 .types = BIT(NL80211_IFTYPE_STATION),
5186 }, 5200 },
5187 { 5201 {
@@ -5196,7 +5210,7 @@ static const struct ieee80211_iface_combination
5196wlcore_iface_combinations[] = { 5210wlcore_iface_combinations[] = {
5197 { 5211 {
5198 .num_different_channels = 1, 5212 .num_different_channels = 1,
5199 .max_interfaces = 2, 5213 .max_interfaces = 3,
5200 .limits = wlcore_iface_limits, 5214 .limits = wlcore_iface_limits,
5201 .n_limits = ARRAY_SIZE(wlcore_iface_limits), 5215 .n_limits = ARRAY_SIZE(wlcore_iface_limits),
5202 }, 5216 },
@@ -5312,7 +5326,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5312 5326
5313#define WL1271_DEFAULT_CHANNEL 0 5327#define WL1271_DEFAULT_CHANNEL 0
5314 5328
5315struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) 5329struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size)
5316{ 5330{
5317 struct ieee80211_hw *hw; 5331 struct ieee80211_hw *hw;
5318 struct wl1271 *wl; 5332 struct wl1271 *wl;
@@ -5392,17 +5406,19 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size)
5392 5406
5393 spin_lock_init(&wl->wl_lock); 5407 spin_lock_init(&wl->wl_lock);
5394 5408
5395 wl->state = WL1271_STATE_OFF; 5409 wl->state = WLCORE_STATE_OFF;
5396 wl->fw_type = WL12XX_FW_TYPE_NONE; 5410 wl->fw_type = WL12XX_FW_TYPE_NONE;
5397 mutex_init(&wl->mutex); 5411 mutex_init(&wl->mutex);
5398 mutex_init(&wl->flush_mutex); 5412 mutex_init(&wl->flush_mutex);
5413 init_completion(&wl->nvs_loading_complete);
5399 5414
5400 order = get_order(WL1271_AGGR_BUFFER_SIZE); 5415 order = get_order(aggr_buf_size);
5401 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); 5416 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
5402 if (!wl->aggr_buf) { 5417 if (!wl->aggr_buf) {
5403 ret = -ENOMEM; 5418 ret = -ENOMEM;
5404 goto err_wq; 5419 goto err_wq;
5405 } 5420 }
5421 wl->aggr_buf_size = aggr_buf_size;
5406 5422
5407 wl->dummy_packet = wl12xx_alloc_dummy_packet(wl); 5423 wl->dummy_packet = wl12xx_alloc_dummy_packet(wl);
5408 if (!wl->dummy_packet) { 5424 if (!wl->dummy_packet) {
@@ -5465,8 +5481,7 @@ int wlcore_free_hw(struct wl1271 *wl)
5465 device_remove_file(wl->dev, &dev_attr_bt_coex_state); 5481 device_remove_file(wl->dev, &dev_attr_bt_coex_state);
5466 free_page((unsigned long)wl->fwlog); 5482 free_page((unsigned long)wl->fwlog);
5467 dev_kfree_skb(wl->dummy_packet); 5483 dev_kfree_skb(wl->dummy_packet);
5468 free_pages((unsigned long)wl->aggr_buf, 5484 free_pages((unsigned long)wl->aggr_buf, get_order(wl->aggr_buf_size));
5469 get_order(WL1271_AGGR_BUFFER_SIZE));
5470 5485
5471 wl1271_debugfs_exit(wl); 5486 wl1271_debugfs_exit(wl);
5472 5487
@@ -5516,17 +5531,32 @@ static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
5516 return IRQ_WAKE_THREAD; 5531 return IRQ_WAKE_THREAD;
5517} 5532}
5518 5533
5519int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) 5534static void wlcore_nvs_cb(const struct firmware *fw, void *context)
5520{ 5535{
5536 struct wl1271 *wl = context;
5537 struct platform_device *pdev = wl->pdev;
5521 struct wl12xx_platform_data *pdata = pdev->dev.platform_data; 5538 struct wl12xx_platform_data *pdata = pdev->dev.platform_data;
5522 unsigned long irqflags; 5539 unsigned long irqflags;
5523 int ret; 5540 int ret;
5524 5541
5525 if (!wl->ops || !wl->ptable) { 5542 if (fw) {
5526 ret = -EINVAL; 5543 wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
5527 goto out_free_hw; 5544 if (!wl->nvs) {
5545 wl1271_error("Could not allocate nvs data");
5546 goto out;
5547 }
5548 wl->nvs_len = fw->size;
5549 } else {
5550 wl1271_debug(DEBUG_BOOT, "Could not get nvs file %s",
5551 WL12XX_NVS_NAME);
5552 wl->nvs = NULL;
5553 wl->nvs_len = 0;
5528 } 5554 }
5529 5555
5556 ret = wl->ops->setup(wl);
5557 if (ret < 0)
5558 goto out_free_nvs;
5559
5530 BUG_ON(wl->num_tx_desc > WLCORE_MAX_TX_DESCRIPTORS); 5560 BUG_ON(wl->num_tx_desc > WLCORE_MAX_TX_DESCRIPTORS);
5531 5561
5532 /* adjust some runtime configuration parameters */ 5562 /* adjust some runtime configuration parameters */
@@ -5535,11 +5565,8 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5535 wl->irq = platform_get_irq(pdev, 0); 5565 wl->irq = platform_get_irq(pdev, 0);
5536 wl->platform_quirks = pdata->platform_quirks; 5566 wl->platform_quirks = pdata->platform_quirks;
5537 wl->set_power = pdata->set_power; 5567 wl->set_power = pdata->set_power;
5538 wl->dev = &pdev->dev;
5539 wl->if_ops = pdata->ops; 5568 wl->if_ops = pdata->ops;
5540 5569
5541 platform_set_drvdata(pdev, wl);
5542
5543 if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) 5570 if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
5544 irqflags = IRQF_TRIGGER_RISING; 5571 irqflags = IRQF_TRIGGER_RISING;
5545 else 5572 else
@@ -5550,7 +5577,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5550 pdev->name, wl); 5577 pdev->name, wl);
5551 if (ret < 0) { 5578 if (ret < 0) {
5552 wl1271_error("request_irq() failed: %d", ret); 5579 wl1271_error("request_irq() failed: %d", ret);
5553 goto out_free_hw; 5580 goto out_free_nvs;
5554 } 5581 }
5555 5582
5556#ifdef CONFIG_PM 5583#ifdef CONFIG_PM
@@ -5609,6 +5636,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5609 goto out_hw_pg_ver; 5636 goto out_hw_pg_ver;
5610 } 5637 }
5611 5638
5639 wl->initialized = true;
5612 goto out; 5640 goto out;
5613 5641
5614out_hw_pg_ver: 5642out_hw_pg_ver:
@@ -5623,10 +5651,33 @@ out_unreg:
5623out_irq: 5651out_irq:
5624 free_irq(wl->irq, wl); 5652 free_irq(wl->irq, wl);
5625 5653
5626out_free_hw: 5654out_free_nvs:
5627 wlcore_free_hw(wl); 5655 kfree(wl->nvs);
5628 5656
5629out: 5657out:
5658 release_firmware(fw);
5659 complete_all(&wl->nvs_loading_complete);
5660}
5661
5662int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5663{
5664 int ret;
5665
5666 if (!wl->ops || !wl->ptable)
5667 return -EINVAL;
5668
5669 wl->dev = &pdev->dev;
5670 wl->pdev = pdev;
5671 platform_set_drvdata(pdev, wl);
5672
5673 ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
5674 WL12XX_NVS_NAME, &pdev->dev, GFP_KERNEL,
5675 wl, wlcore_nvs_cb);
5676 if (ret < 0) {
5677 wl1271_error("request_firmware_nowait failed: %d", ret);
5678 complete_all(&wl->nvs_loading_complete);
5679 }
5680
5630 return ret; 5681 return ret;
5631} 5682}
5632EXPORT_SYMBOL_GPL(wlcore_probe); 5683EXPORT_SYMBOL_GPL(wlcore_probe);
@@ -5635,6 +5686,10 @@ int __devexit wlcore_remove(struct platform_device *pdev)
5635{ 5686{
5636 struct wl1271 *wl = platform_get_drvdata(pdev); 5687 struct wl1271 *wl = platform_get_drvdata(pdev);
5637 5688
5689 wait_for_completion(&wl->nvs_loading_complete);
5690 if (!wl->initialized)
5691 return 0;
5692
5638 if (wl->irq_wake_enabled) { 5693 if (wl->irq_wake_enabled) {
5639 device_init_wakeup(wl->dev, 0); 5694 device_init_wakeup(wl->dev, 0);
5640 disable_irq_wake(wl->irq); 5695 disable_irq_wake(wl->irq);
@@ -5665,3 +5720,4 @@ MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck.");
5665MODULE_LICENSE("GPL"); 5720MODULE_LICENSE("GPL");
5666MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); 5721MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
5667MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 5722MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
5723MODULE_FIRMWARE(WL12XX_NVS_NAME);
diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 46d36fd30eba..4d1414a673fb 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -28,7 +28,7 @@
28 28
29#define WL1271_WAKEUP_TIMEOUT 500 29#define WL1271_WAKEUP_TIMEOUT 500
30 30
31#define ELP_ENTRY_DELAY 5 31#define ELP_ENTRY_DELAY 30
32 32
33void wl1271_elp_work(struct work_struct *work) 33void wl1271_elp_work(struct work_struct *work)
34{ 34{
@@ -44,7 +44,7 @@ void wl1271_elp_work(struct work_struct *work)
44 44
45 mutex_lock(&wl->mutex); 45 mutex_lock(&wl->mutex);
46 46
47 if (unlikely(wl->state == WL1271_STATE_OFF)) 47 if (unlikely(wl->state != WLCORE_STATE_ON))
48 goto out; 48 goto out;
49 49
50 /* our work might have been already cancelled */ 50 /* our work might have been already cancelled */
@@ -98,11 +98,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
98 return; 98 return;
99 } 99 }
100 100
101 if (wl->conf.conn.forced_ps) 101 timeout = ELP_ENTRY_DELAY;
102 timeout = ELP_ENTRY_DELAY;
103 else
104 timeout = wl->conf.conn.dynamic_ps_timeout;
105
106 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 102 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
107 msecs_to_jiffies(timeout)); 103 msecs_to_jiffies(timeout));
108} 104}
diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c
index f55e2f9e7ac5..9ee0ec6fd1db 100644
--- a/drivers/net/wireless/ti/wlcore/rx.c
+++ b/drivers/net/wireless/ti/wlcore/rx.c
@@ -221,7 +221,7 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
221 pkt_len = wlcore_rx_get_buf_size(wl, des); 221 pkt_len = wlcore_rx_get_buf_size(wl, des);
222 align_pkt_len = wlcore_rx_get_align_buf_size(wl, 222 align_pkt_len = wlcore_rx_get_align_buf_size(wl,
223 pkt_len); 223 pkt_len);
224 if (buf_size + align_pkt_len > WL1271_AGGR_BUFFER_SIZE) 224 if (buf_size + align_pkt_len > wl->aggr_buf_size)
225 break; 225 break;
226 buf_size += align_pkt_len; 226 buf_size += align_pkt_len;
227 rx_counter++; 227 rx_counter++;
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index dbeca1bfbb2c..d00501493dfe 100644
--- a/drivers/net/wireless/ti/wlcore/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -46,7 +46,7 @@ void wl1271_scan_complete_work(struct work_struct *work)
46 46
47 mutex_lock(&wl->mutex); 47 mutex_lock(&wl->mutex);
48 48
49 if (wl->state == WL1271_STATE_OFF) 49 if (unlikely(wl->state != WLCORE_STATE_ON))
50 goto out; 50 goto out;
51 51
52 if (wl->scan.state == WL1271_SCAN_STATE_IDLE) 52 if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
@@ -184,11 +184,7 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
184 if (passive) 184 if (passive)
185 scan_options |= WL1271_SCAN_OPT_PASSIVE; 185 scan_options |= WL1271_SCAN_OPT_PASSIVE;
186 186
187 if (wlvif->bss_type == BSS_TYPE_AP_BSS || 187 cmd->params.role_id = wlvif->role_id;
188 test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
189 cmd->params.role_id = wlvif->role_id;
190 else
191 cmd->params.role_id = wlvif->dev_role_id;
192 188
193 if (WARN_ON(cmd->params.role_id == WL12XX_INVALID_ROLE_ID)) { 189 if (WARN_ON(cmd->params.role_id == WL12XX_INVALID_ROLE_ID)) {
194 ret = -EINVAL; 190 ret = -EINVAL;
@@ -593,7 +589,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
593 goto out; 589 goto out;
594 } 590 }
595 591
596 cmd->role_id = wlvif->dev_role_id; 592 cmd->role_id = wlvif->role_id;
597 if (!n_match_ssids) { 593 if (!n_match_ssids) {
598 /* No filter, with ssids */ 594 /* No filter, with ssids */
599 type = SCAN_SSID_FILTER_DISABLED; 595 type = SCAN_SSID_FILTER_DISABLED;
@@ -683,7 +679,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
683 if (!cfg) 679 if (!cfg)
684 return -ENOMEM; 680 return -ENOMEM;
685 681
686 cfg->role_id = wlvif->dev_role_id; 682 cfg->role_id = wlvif->role_id;
687 cfg->rssi_threshold = c->rssi_threshold; 683 cfg->rssi_threshold = c->rssi_threshold;
688 cfg->snr_threshold = c->snr_threshold; 684 cfg->snr_threshold = c->snr_threshold;
689 cfg->n_probe_reqs = c->num_probe_reqs; 685 cfg->n_probe_reqs = c->num_probe_reqs;
@@ -718,7 +714,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
718 if (!force_passive && cfg->active[0]) { 714 if (!force_passive && cfg->active[0]) {
719 u8 band = IEEE80211_BAND_2GHZ; 715 u8 band = IEEE80211_BAND_2GHZ;
720 ret = wl12xx_cmd_build_probe_req(wl, wlvif, 716 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
721 wlvif->dev_role_id, band, 717 wlvif->role_id, band,
722 req->ssids[0].ssid, 718 req->ssids[0].ssid,
723 req->ssids[0].ssid_len, 719 req->ssids[0].ssid_len,
724 ies->ie[band], 720 ies->ie[band],
@@ -732,7 +728,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
732 if (!force_passive && cfg->active[1]) { 728 if (!force_passive && cfg->active[1]) {
733 u8 band = IEEE80211_BAND_5GHZ; 729 u8 band = IEEE80211_BAND_5GHZ;
734 ret = wl12xx_cmd_build_probe_req(wl, wlvif, 730 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
735 wlvif->dev_role_id, band, 731 wlvif->role_id, band,
736 req->ssids[0].ssid, 732 req->ssids[0].ssid,
737 req->ssids[0].ssid_len, 733 req->ssids[0].ssid_len,
738 ies->ie[band], 734 ies->ie[band],
@@ -774,7 +770,7 @@ int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif)
774 if (!start) 770 if (!start)
775 return -ENOMEM; 771 return -ENOMEM;
776 772
777 start->role_id = wlvif->dev_role_id; 773 start->role_id = wlvif->role_id;
778 start->tag = WL1271_SCAN_DEFAULT_TAG; 774 start->tag = WL1271_SCAN_DEFAULT_TAG;
779 775
780 ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start, 776 ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start,
@@ -810,7 +806,7 @@ void wl1271_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif)
810 return; 806 return;
811 } 807 }
812 808
813 stop->role_id = wlvif->dev_role_id; 809 stop->role_id = wlvif->role_id;
814 stop->tag = WL1271_SCAN_DEFAULT_TAG; 810 stop->tag = WL1271_SCAN_DEFAULT_TAG;
815 811
816 ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop, 812 ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index 8da4ed243ebc..a519bc3adec1 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -66,7 +66,13 @@
66/* HW limitation: maximum possible chunk size is 4095 bytes */ 66/* HW limitation: maximum possible chunk size is 4095 bytes */
67#define WSPI_MAX_CHUNK_SIZE 4092 67#define WSPI_MAX_CHUNK_SIZE 4092
68 68
69#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) 69/*
70 * only support SPI for 12xx - this code should be reworked when 18xx
71 * support is introduced
72 */
73#define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
74
75#define WSPI_MAX_NUM_OF_CHUNKS (SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
70 76
71struct wl12xx_spi_glue { 77struct wl12xx_spi_glue {
72 struct device *dev; 78 struct device *dev;
@@ -271,7 +277,7 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
271 u32 chunk_len; 277 u32 chunk_len;
272 int i; 278 int i;
273 279
274 WARN_ON(len > WL1271_AGGR_BUFFER_SIZE); 280 WARN_ON(len > SPI_AGGR_BUFFER_SIZE);
275 281
276 spi_message_init(&m); 282 spi_message_init(&m);
277 memset(t, 0, sizeof(t)); 283 memset(t, 0, sizeof(t));
diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c
index 49e5ee1525c9..f3442762d884 100644
--- a/drivers/net/wireless/ti/wlcore/testmode.c
+++ b/drivers/net/wireless/ti/wlcore/testmode.c
@@ -92,7 +92,7 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])
92 92
93 mutex_lock(&wl->mutex); 93 mutex_lock(&wl->mutex);
94 94
95 if (wl->state == WL1271_STATE_OFF) { 95 if (unlikely(wl->state != WLCORE_STATE_ON)) {
96 ret = -EINVAL; 96 ret = -EINVAL;
97 goto out; 97 goto out;
98 } 98 }
@@ -164,7 +164,7 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
164 164
165 mutex_lock(&wl->mutex); 165 mutex_lock(&wl->mutex);
166 166
167 if (wl->state == WL1271_STATE_OFF) { 167 if (unlikely(wl->state != WLCORE_STATE_ON)) {
168 ret = -EINVAL; 168 ret = -EINVAL;
169 goto out; 169 goto out;
170 } 170 }
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 1a2f31c289c5..a90d3cd09408 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -193,7 +193,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
193 int id, ret = -EBUSY, ac; 193 int id, ret = -EBUSY, ac;
194 u32 spare_blocks; 194 u32 spare_blocks;
195 195
196 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) 196 if (buf_offset + total_len > wl->aggr_buf_size)
197 return -EAGAIN; 197 return -EAGAIN;
198 198
199 spare_blocks = wlcore_hw_get_spare_blocks(wl, is_gem); 199 spare_blocks = wlcore_hw_get_spare_blocks(wl, is_gem);
@@ -319,8 +319,12 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
319 if (hlid == wlvif->ap.global_hlid) 319 if (hlid == wlvif->ap.global_hlid)
320 rate_idx = wlvif->ap.mgmt_rate_idx; 320 rate_idx = wlvif->ap.mgmt_rate_idx;
321 else if (hlid == wlvif->ap.bcast_hlid || 321 else if (hlid == wlvif->ap.bcast_hlid ||
322 skb->protocol == cpu_to_be16(ETH_P_PAE)) 322 skb->protocol == cpu_to_be16(ETH_P_PAE) ||
323 /* send AP bcast and EAPOLs using the min basic rate */ 323 !ieee80211_is_data(frame_control))
324 /*
325 * send non-data, bcast and EAPOLs using the
326 * min basic rate
327 */
324 rate_idx = wlvif->ap.bcast_rate_idx; 328 rate_idx = wlvif->ap.bcast_rate_idx;
325 else 329 else
326 rate_idx = wlvif->ap.ucast_rate_idx[ac]; 330 rate_idx = wlvif->ap.ucast_rate_idx[ac];
@@ -687,7 +691,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl)
687 int bus_ret = 0; 691 int bus_ret = 0;
688 u8 hlid; 692 u8 hlid;
689 693
690 if (unlikely(wl->state == WL1271_STATE_OFF)) 694 if (unlikely(wl->state != WLCORE_STATE_ON))
691 return 0; 695 return 0;
692 696
693 while ((skb = wl1271_skb_dequeue(wl, &hlid))) { 697 while ((skb = wl1271_skb_dequeue(wl, &hlid))) {
@@ -1072,39 +1076,54 @@ void wl12xx_tx_reset(struct wl1271 *wl)
1072/* caller must *NOT* hold wl->mutex */ 1076/* caller must *NOT* hold wl->mutex */
1073void wl1271_tx_flush(struct wl1271 *wl) 1077void wl1271_tx_flush(struct wl1271 *wl)
1074{ 1078{
1075 unsigned long timeout; 1079 unsigned long timeout, start_time;
1076 int i; 1080 int i;
1077 timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); 1081 start_time = jiffies;
1082 timeout = start_time + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT);
1078 1083
1079 /* only one flush should be in progress, for consistent queue state */ 1084 /* only one flush should be in progress, for consistent queue state */
1080 mutex_lock(&wl->flush_mutex); 1085 mutex_lock(&wl->flush_mutex);
1081 1086
1087 mutex_lock(&wl->mutex);
1088 if (wl->tx_frames_cnt == 0 && wl1271_tx_total_queue_count(wl) == 0) {
1089 mutex_unlock(&wl->mutex);
1090 goto out;
1091 }
1092
1082 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); 1093 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH);
1083 1094
1084 while (!time_after(jiffies, timeout)) { 1095 while (!time_after(jiffies, timeout)) {
1085 mutex_lock(&wl->mutex); 1096 wl1271_debug(DEBUG_MAC80211, "flushing tx buffer: %d %d",
1086 wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d",
1087 wl->tx_frames_cnt, 1097 wl->tx_frames_cnt,
1088 wl1271_tx_total_queue_count(wl)); 1098 wl1271_tx_total_queue_count(wl));
1099
1100 /* force Tx and give the driver some time to flush data */
1101 mutex_unlock(&wl->mutex);
1102 if (wl1271_tx_total_queue_count(wl))
1103 wl1271_tx_work(&wl->tx_work);
1104 msleep(20);
1105 mutex_lock(&wl->mutex);
1106
1089 if ((wl->tx_frames_cnt == 0) && 1107 if ((wl->tx_frames_cnt == 0) &&
1090 (wl1271_tx_total_queue_count(wl) == 0)) { 1108 (wl1271_tx_total_queue_count(wl) == 0)) {
1091 mutex_unlock(&wl->mutex); 1109 wl1271_debug(DEBUG_MAC80211, "tx flush took %d ms",
1092 goto out; 1110 jiffies_to_msecs(jiffies - start_time));
1111 goto out_wake;
1093 } 1112 }
1094 mutex_unlock(&wl->mutex);
1095 msleep(1);
1096 } 1113 }
1097 1114
1098 wl1271_warning("Unable to flush all TX buffers, timed out."); 1115 wl1271_warning("Unable to flush all TX buffers, "
1116 "timed out (timeout %d ms",
1117 WL1271_TX_FLUSH_TIMEOUT / 1000);
1099 1118
1100 /* forcibly flush all Tx buffers on our queues */ 1119 /* forcibly flush all Tx buffers on our queues */
1101 mutex_lock(&wl->mutex);
1102 for (i = 0; i < WL12XX_MAX_LINKS; i++) 1120 for (i = 0; i < WL12XX_MAX_LINKS; i++)
1103 wl1271_tx_reset_link_queues(wl, i); 1121 wl1271_tx_reset_link_queues(wl, i);
1104 mutex_unlock(&wl->mutex);
1105 1122
1106out: 1123out_wake:
1107 wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); 1124 wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH);
1125 mutex_unlock(&wl->mutex);
1126out:
1108 mutex_unlock(&wl->flush_mutex); 1127 mutex_unlock(&wl->flush_mutex);
1109} 1128}
1110EXPORT_SYMBOL_GPL(wl1271_tx_flush); 1129EXPORT_SYMBOL_GPL(wl1271_tx_flush);
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 0ce7a8ebbd46..68584aa0f2b0 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -31,12 +31,19 @@
31/* The maximum number of Tx descriptors in all chip families */ 31/* The maximum number of Tx descriptors in all chip families */
32#define WLCORE_MAX_TX_DESCRIPTORS 32 32#define WLCORE_MAX_TX_DESCRIPTORS 32
33 33
34/*
35 * We always allocate this number of mac addresses. If we don't
36 * have enough allocated addresses, the LAA bit is used
37 */
38#define WLCORE_NUM_MAC_ADDRESSES 3
39
34/* forward declaration */ 40/* forward declaration */
35struct wl1271_tx_hw_descr; 41struct wl1271_tx_hw_descr;
36enum wl_rx_buf_align; 42enum wl_rx_buf_align;
37struct wl1271_rx_descriptor; 43struct wl1271_rx_descriptor;
38 44
39struct wlcore_ops { 45struct wlcore_ops {
46 int (*setup)(struct wl1271 *wl);
40 int (*identify_chip)(struct wl1271 *wl); 47 int (*identify_chip)(struct wl1271 *wl);
41 int (*identify_fw)(struct wl1271 *wl); 48 int (*identify_fw)(struct wl1271 *wl);
42 int (*boot)(struct wl1271 *wl); 49 int (*boot)(struct wl1271 *wl);
@@ -139,10 +146,12 @@ struct wl1271_stats {
139}; 146};
140 147
141struct wl1271 { 148struct wl1271 {
149 bool initialized;
142 struct ieee80211_hw *hw; 150 struct ieee80211_hw *hw;
143 bool mac80211_registered; 151 bool mac80211_registered;
144 152
145 struct device *dev; 153 struct device *dev;
154 struct platform_device *pdev;
146 155
147 void *if_priv; 156 void *if_priv;
148 157
@@ -153,7 +162,7 @@ struct wl1271 {
153 162
154 spinlock_t wl_lock; 163 spinlock_t wl_lock;
155 164
156 enum wl1271_state state; 165 enum wlcore_state state;
157 enum wl12xx_fw_type fw_type; 166 enum wl12xx_fw_type fw_type;
158 bool plt; 167 bool plt;
159 enum plt_mode plt_mode; 168 enum plt_mode plt_mode;
@@ -181,7 +190,7 @@ struct wl1271 {
181 u32 fuse_nic_addr; 190 u32 fuse_nic_addr;
182 191
183 /* we have up to 2 MAC addresses */ 192 /* we have up to 2 MAC addresses */
184 struct mac_address addresses[2]; 193 struct mac_address addresses[WLCORE_NUM_MAC_ADDRESSES];
185 int channel; 194 int channel;
186 u8 system_hlid; 195 u8 system_hlid;
187 196
@@ -190,6 +199,8 @@ struct wl1271 {
190 unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; 199 unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
191 unsigned long rate_policies_map[ 200 unsigned long rate_policies_map[
192 BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)]; 201 BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)];
202 unsigned long klv_templates_map[
203 BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)];
193 204
194 struct list_head wlvif_list; 205 struct list_head wlvif_list;
195 206
@@ -237,6 +248,7 @@ struct wl1271 {
237 248
238 /* Intermediate buffer, used for packet aggregation */ 249 /* Intermediate buffer, used for packet aggregation */
239 u8 *aggr_buf; 250 u8 *aggr_buf;
251 u32 aggr_buf_size;
240 252
241 /* Reusable dummy packet template */ 253 /* Reusable dummy packet template */
242 struct sk_buff *dummy_packet; 254 struct sk_buff *dummy_packet;
@@ -393,13 +405,18 @@ struct wl1271 {
393 /* sleep auth value currently configured to FW */ 405 /* sleep auth value currently configured to FW */
394 int sleep_auth; 406 int sleep_auth;
395 407
408 /* the number of allocated MAC addresses in this chip */
409 int num_mac_addr;
410
396 /* the minimum FW version required for the driver to work */ 411 /* the minimum FW version required for the driver to work */
397 unsigned int min_fw_ver[NUM_FW_VER]; 412 unsigned int min_fw_ver[NUM_FW_VER];
413
414 struct completion nvs_loading_complete;
398}; 415};
399 416
400int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); 417int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
401int __devexit wlcore_remove(struct platform_device *pdev); 418int __devexit wlcore_remove(struct platform_device *pdev);
402struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size); 419struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size);
403int wlcore_free_hw(struct wl1271 *wl); 420int wlcore_free_hw(struct wl1271 *wl);
404int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, 421int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
405 struct ieee80211_vif *vif, 422 struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index c0505635bb00..6678d4b18611 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -66,6 +66,7 @@
66#define WLCORE_NUM_BANDS 2 66#define WLCORE_NUM_BANDS 2
67 67
68#define WL12XX_MAX_RATE_POLICIES 16 68#define WL12XX_MAX_RATE_POLICIES 16
69#define WLCORE_MAX_KLV_TEMPLATES 4
69 70
70/* Defined by FW as 0. Will not be freed or allocated. */ 71/* Defined by FW as 0. Will not be freed or allocated. */
71#define WL12XX_SYSTEM_HLID 0 72#define WL12XX_SYSTEM_HLID 0
@@ -83,11 +84,10 @@
83#define WL1271_AP_BSS_INDEX 0 84#define WL1271_AP_BSS_INDEX 0
84#define WL1271_AP_DEF_BEACON_EXP 20 85#define WL1271_AP_DEF_BEACON_EXP 20
85 86
86#define WL1271_AGGR_BUFFER_SIZE (5 * PAGE_SIZE) 87enum wlcore_state {
87 88 WLCORE_STATE_OFF,
88enum wl1271_state { 89 WLCORE_STATE_RESTARTING,
89 WL1271_STATE_OFF, 90 WLCORE_STATE_ON,
90 WL1271_STATE_ON,
91}; 91};
92 92
93enum wl12xx_fw_type { 93enum wl12xx_fw_type {
@@ -124,6 +124,7 @@ struct wl1271_chip {
124 u32 id; 124 u32 id;
125 char fw_ver_str[ETHTOOL_BUSINFO_LEN]; 125 char fw_ver_str[ETHTOOL_BUSINFO_LEN];
126 unsigned int fw_ver[NUM_FW_VER]; 126 unsigned int fw_ver[NUM_FW_VER];
127 char phy_fw_ver_str[ETHTOOL_BUSINFO_LEN];
127}; 128};
128 129
129#define NUM_TX_QUEUES 4 130#define NUM_TX_QUEUES 4
@@ -337,6 +338,8 @@ struct wl12xx_vif {
337 u8 ap_rate_idx; 338 u8 ap_rate_idx;
338 u8 p2p_rate_idx; 339 u8 p2p_rate_idx;
339 340
341 u8 klv_template_id;
342
340 bool qos; 343 bool qos;
341 } sta; 344 } sta;
342 struct { 345 struct {