aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/htc_drv_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c485
1 files changed, 331 insertions, 154 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 6bb59958f71e..db8c0c044e9e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -24,17 +24,6 @@ static struct dentry *ath9k_debugfs_root;
24/* Utilities */ 24/* Utilities */
25/*************/ 25/*************/
26 26
27void ath_update_txpow(struct ath9k_htc_priv *priv)
28{
29 struct ath_hw *ah = priv->ah;
30
31 if (priv->curtxpow != priv->txpowlimit) {
32 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit, false);
33 /* read back in case value is clamped */
34 priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
35 }
36}
37
38/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */ 27/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
39static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, 28static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
40 struct ath9k_channel *ichan) 29 struct ath9k_channel *ichan)
@@ -116,12 +105,88 @@ void ath9k_ps_work(struct work_struct *work)
116 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); 105 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
117} 106}
118 107
108static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
109{
110 struct ath9k_htc_priv *priv = data;
111 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
112
113 if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon)
114 priv->reconfig_beacon = true;
115
116 if (bss_conf->assoc) {
117 priv->rearm_ani = true;
118 priv->reconfig_beacon = true;
119 }
120}
121
122static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
123{
124 priv->rearm_ani = false;
125 priv->reconfig_beacon = false;
126
127 ieee80211_iterate_active_interfaces_atomic(priv->hw,
128 ath9k_htc_vif_iter, priv);
129 if (priv->rearm_ani)
130 ath9k_htc_start_ani(priv);
131
132 if (priv->reconfig_beacon) {
133 ath9k_htc_ps_wakeup(priv);
134 ath9k_htc_beacon_reconfig(priv);
135 ath9k_htc_ps_restore(priv);
136 }
137}
138
139static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
140{
141 struct ath9k_vif_iter_data *iter_data = data;
142 int i;
143
144 for (i = 0; i < ETH_ALEN; i++)
145 iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
146}
147
148static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
149 struct ieee80211_vif *vif)
150{
151 struct ath_common *common = ath9k_hw_common(priv->ah);
152 struct ath9k_vif_iter_data iter_data;
153
154 /*
155 * Use the hardware MAC address as reference, the hardware uses it
156 * together with the BSSID mask when matching addresses.
157 */
158 iter_data.hw_macaddr = common->macaddr;
159 memset(&iter_data.mask, 0xff, ETH_ALEN);
160
161 if (vif)
162 ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);
163
164 /* Get list of all active MAC addresses */
165 ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter,
166 &iter_data);
167
168 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
169 ath_hw_setbssidmask(common);
170}
171
172static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)
173{
174 if (priv->num_ibss_vif)
175 priv->ah->opmode = NL80211_IFTYPE_ADHOC;
176 else if (priv->num_ap_vif)
177 priv->ah->opmode = NL80211_IFTYPE_AP;
178 else
179 priv->ah->opmode = NL80211_IFTYPE_STATION;
180
181 ath9k_hw_setopmode(priv->ah);
182}
183
119void ath9k_htc_reset(struct ath9k_htc_priv *priv) 184void ath9k_htc_reset(struct ath9k_htc_priv *priv)
120{ 185{
121 struct ath_hw *ah = priv->ah; 186 struct ath_hw *ah = priv->ah;
122 struct ath_common *common = ath9k_hw_common(ah); 187 struct ath_common *common = ath9k_hw_common(ah);
123 struct ieee80211_channel *channel = priv->hw->conf.channel; 188 struct ieee80211_channel *channel = priv->hw->conf.channel;
124 struct ath9k_hw_cal_data *caldata; 189 struct ath9k_hw_cal_data *caldata = NULL;
125 enum htc_phymode mode; 190 enum htc_phymode mode;
126 __be16 htc_mode; 191 __be16 htc_mode;
127 u8 cmd_rsp; 192 u8 cmd_rsp;
@@ -130,16 +195,14 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
130 mutex_lock(&priv->mutex); 195 mutex_lock(&priv->mutex);
131 ath9k_htc_ps_wakeup(priv); 196 ath9k_htc_ps_wakeup(priv);
132 197
133 if (priv->op_flags & OP_ASSOCIATED) 198 ath9k_htc_stop_ani(priv);
134 cancel_delayed_work_sync(&priv->ath9k_ani_work);
135
136 ieee80211_stop_queues(priv->hw); 199 ieee80211_stop_queues(priv->hw);
137 htc_stop(priv->htc); 200 htc_stop(priv->htc);
138 WMI_CMD(WMI_DISABLE_INTR_CMDID); 201 WMI_CMD(WMI_DISABLE_INTR_CMDID);
139 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); 202 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
140 WMI_CMD(WMI_STOP_RECV_CMDID); 203 WMI_CMD(WMI_STOP_RECV_CMDID);
141 204
142 caldata = &priv->caldata[channel->hw_value]; 205 caldata = &priv->caldata;
143 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); 206 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
144 if (ret) { 207 if (ret) {
145 ath_err(common, 208 ath_err(common,
@@ -147,7 +210,8 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
147 channel->center_freq, ret); 210 channel->center_freq, ret);
148 } 211 }
149 212
150 ath_update_txpow(priv); 213 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
214 &priv->curtxpow);
151 215
152 WMI_CMD(WMI_START_RECV_CMDID); 216 WMI_CMD(WMI_START_RECV_CMDID);
153 ath9k_host_rx_init(priv); 217 ath9k_host_rx_init(priv);
@@ -158,12 +222,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
158 222
159 WMI_CMD(WMI_ENABLE_INTR_CMDID); 223 WMI_CMD(WMI_ENABLE_INTR_CMDID);
160 htc_start(priv->htc); 224 htc_start(priv->htc);
161 225 ath9k_htc_vif_reconfig(priv);
162 if (priv->op_flags & OP_ASSOCIATED) {
163 ath9k_htc_beacon_config(priv, priv->vif);
164 ath_start_ani(priv);
165 }
166
167 ieee80211_wake_queues(priv->hw); 226 ieee80211_wake_queues(priv->hw);
168 227
169 ath9k_htc_ps_restore(priv); 228 ath9k_htc_ps_restore(priv);
@@ -179,7 +238,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
179 struct ieee80211_conf *conf = &common->hw->conf; 238 struct ieee80211_conf *conf = &common->hw->conf;
180 bool fastcc; 239 bool fastcc;
181 struct ieee80211_channel *channel = hw->conf.channel; 240 struct ieee80211_channel *channel = hw->conf.channel;
182 struct ath9k_hw_cal_data *caldata; 241 struct ath9k_hw_cal_data *caldata = NULL;
183 enum htc_phymode mode; 242 enum htc_phymode mode;
184 __be16 htc_mode; 243 __be16 htc_mode;
185 u8 cmd_rsp; 244 u8 cmd_rsp;
@@ -202,7 +261,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
202 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf), 261 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
203 fastcc); 262 fastcc);
204 263
205 caldata = &priv->caldata[channel->hw_value]; 264 if (!fastcc)
265 caldata = &priv->caldata;
206 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); 266 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
207 if (ret) { 267 if (ret) {
208 ath_err(common, 268 ath_err(common,
@@ -211,7 +271,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
211 goto err; 271 goto err;
212 } 272 }
213 273
214 ath_update_txpow(priv); 274 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
275 &priv->curtxpow);
215 276
216 WMI_CMD(WMI_START_RECV_CMDID); 277 WMI_CMD(WMI_START_RECV_CMDID);
217 if (ret) 278 if (ret)
@@ -230,11 +291,23 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
230 goto err; 291 goto err;
231 292
232 htc_start(priv->htc); 293 htc_start(priv->htc);
294
295 if (!(priv->op_flags & OP_SCANNING) &&
296 !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
297 ath9k_htc_vif_reconfig(priv);
298
233err: 299err:
234 ath9k_htc_ps_restore(priv); 300 ath9k_htc_ps_restore(priv);
235 return ret; 301 return ret;
236} 302}
237 303
304/*
305 * Monitor mode handling is a tad complicated because the firmware requires
306 * an interface to be created exclusively, while mac80211 doesn't associate
307 * an interface with the mode.
308 *
309 * So, for now, only one monitor interface can be configured.
310 */
238static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) 311static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
239{ 312{
240 struct ath_common *common = ath9k_hw_common(priv->ah); 313 struct ath_common *common = ath9k_hw_common(priv->ah);
@@ -244,9 +317,10 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
244 317
245 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); 318 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
246 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); 319 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
247 hvif.index = 0; /* Should do for now */ 320 hvif.index = priv->mon_vif_idx;
248 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); 321 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
249 priv->nvifs--; 322 priv->nvifs--;
323 priv->vif_slot &= ~(1 << priv->mon_vif_idx);
250} 324}
251 325
252static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) 326static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
@@ -254,70 +328,87 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
254 struct ath_common *common = ath9k_hw_common(priv->ah); 328 struct ath_common *common = ath9k_hw_common(priv->ah);
255 struct ath9k_htc_target_vif hvif; 329 struct ath9k_htc_target_vif hvif;
256 struct ath9k_htc_target_sta tsta; 330 struct ath9k_htc_target_sta tsta;
257 int ret = 0; 331 int ret = 0, sta_idx;
258 u8 cmd_rsp; 332 u8 cmd_rsp;
259 333
260 if (priv->nvifs > 0) 334 if ((priv->nvifs >= ATH9K_HTC_MAX_VIF) ||
261 return -ENOBUFS; 335 (priv->nstations >= ATH9K_HTC_MAX_STA)) {
336 ret = -ENOBUFS;
337 goto err_vif;
338 }
262 339
263 if (priv->nstations >= ATH9K_HTC_MAX_STA) 340 sta_idx = ffz(priv->sta_slot);
264 return -ENOBUFS; 341 if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) {
342 ret = -ENOBUFS;
343 goto err_vif;
344 }
265 345
266 /* 346 /*
267 * Add an interface. 347 * Add an interface.
268 */ 348 */
269
270 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); 349 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
271 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); 350 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
272 351
273 hvif.opmode = cpu_to_be32(HTC_M_MONITOR); 352 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
274 priv->ah->opmode = NL80211_IFTYPE_MONITOR; 353 hvif.index = ffz(priv->vif_slot);
275 hvif.index = priv->nvifs;
276 354
277 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); 355 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
278 if (ret) 356 if (ret)
279 return ret; 357 goto err_vif;
358
359 /*
360 * Assign the monitor interface index as a special case here.
361 * This is needed when the interface is brought down.
362 */
363 priv->mon_vif_idx = hvif.index;
364 priv->vif_slot |= (1 << hvif.index);
365
366 /*
367 * Set the hardware mode to monitor only if there are no
368 * other interfaces.
369 */
370 if (!priv->nvifs)
371 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
280 372
281 priv->nvifs++; 373 priv->nvifs++;
282 374
283 /* 375 /*
284 * Associate a station with the interface for packet injection. 376 * Associate a station with the interface for packet injection.
285 */ 377 */
286
287 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta)); 378 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
288 379
289 memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN); 380 memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
290 381
291 tsta.is_vif_sta = 1; 382 tsta.is_vif_sta = 1;
292 tsta.sta_index = priv->nstations; 383 tsta.sta_index = sta_idx;
293 tsta.vif_index = hvif.index; 384 tsta.vif_index = hvif.index;
294 tsta.maxampdu = 0xffff; 385 tsta.maxampdu = 0xffff;
295 386
296 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); 387 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
297 if (ret) { 388 if (ret) {
298 ath_err(common, "Unable to add station entry for monitor mode\n"); 389 ath_err(common, "Unable to add station entry for monitor mode\n");
299 goto err_vif; 390 goto err_sta;
300 } 391 }
301 392
393 priv->sta_slot |= (1 << sta_idx);
302 priv->nstations++; 394 priv->nstations++;
303 395 priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx;
304 /*
305 * Set chainmask etc. on the target.
306 */
307 ret = ath9k_htc_update_cap_target(priv);
308 if (ret)
309 ath_dbg(common, ATH_DBG_CONFIG,
310 "Failed to update capability in target\n");
311
312 priv->ah->is_monitoring = true; 396 priv->ah->is_monitoring = true;
313 397
398 ath_dbg(common, ATH_DBG_CONFIG,
399 "Attached a monitor interface at idx: %d, sta idx: %d\n",
400 priv->mon_vif_idx, sta_idx);
401
314 return 0; 402 return 0;
315 403
316err_vif: 404err_sta:
317 /* 405 /*
318 * Remove the interface from the target. 406 * Remove the interface from the target.
319 */ 407 */
320 __ath9k_htc_remove_monitor_interface(priv); 408 __ath9k_htc_remove_monitor_interface(priv);
409err_vif:
410 ath_dbg(common, ATH_DBG_FATAL, "Unable to attach a monitor interface\n");
411
321 return ret; 412 return ret;
322} 413}
323 414
@@ -329,7 +420,7 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
329 420
330 __ath9k_htc_remove_monitor_interface(priv); 421 __ath9k_htc_remove_monitor_interface(priv);
331 422
332 sta_idx = 0; /* Only single interface, for now */ 423 sta_idx = priv->vif_sta_pos[priv->mon_vif_idx];
333 424
334 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx); 425 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
335 if (ret) { 426 if (ret) {
@@ -337,9 +428,14 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
337 return ret; 428 return ret;
338 } 429 }
339 430
431 priv->sta_slot &= ~(1 << sta_idx);
340 priv->nstations--; 432 priv->nstations--;
341 priv->ah->is_monitoring = false; 433 priv->ah->is_monitoring = false;
342 434
435 ath_dbg(common, ATH_DBG_CONFIG,
436 "Removed a monitor interface at idx: %d, sta idx: %d\n",
437 priv->mon_vif_idx, sta_idx);
438
343 return 0; 439 return 0;
344} 440}
345 441
@@ -351,12 +447,16 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
351 struct ath9k_htc_target_sta tsta; 447 struct ath9k_htc_target_sta tsta;
352 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv; 448 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
353 struct ath9k_htc_sta *ista; 449 struct ath9k_htc_sta *ista;
354 int ret; 450 int ret, sta_idx;
355 u8 cmd_rsp; 451 u8 cmd_rsp;
356 452
357 if (priv->nstations >= ATH9K_HTC_MAX_STA) 453 if (priv->nstations >= ATH9K_HTC_MAX_STA)
358 return -ENOBUFS; 454 return -ENOBUFS;
359 455
456 sta_idx = ffz(priv->sta_slot);
457 if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA))
458 return -ENOBUFS;
459
360 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta)); 460 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
361 461
362 if (sta) { 462 if (sta) {
@@ -366,13 +466,13 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
366 tsta.associd = common->curaid; 466 tsta.associd = common->curaid;
367 tsta.is_vif_sta = 0; 467 tsta.is_vif_sta = 0;
368 tsta.valid = true; 468 tsta.valid = true;
369 ista->index = priv->nstations; 469 ista->index = sta_idx;
370 } else { 470 } else {
371 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); 471 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
372 tsta.is_vif_sta = 1; 472 tsta.is_vif_sta = 1;
373 } 473 }
374 474
375 tsta.sta_index = priv->nstations; 475 tsta.sta_index = sta_idx;
376 tsta.vif_index = avp->index; 476 tsta.vif_index = avp->index;
377 tsta.maxampdu = 0xffff; 477 tsta.maxampdu = 0xffff;
378 if (sta && sta->ht_cap.ht_supported) 478 if (sta && sta->ht_cap.ht_supported)
@@ -387,12 +487,21 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
387 return ret; 487 return ret;
388 } 488 }
389 489
390 if (sta) 490 if (sta) {
391 ath_dbg(common, ATH_DBG_CONFIG, 491 ath_dbg(common, ATH_DBG_CONFIG,
392 "Added a station entry for: %pM (idx: %d)\n", 492 "Added a station entry for: %pM (idx: %d)\n",
393 sta->addr, tsta.sta_index); 493 sta->addr, tsta.sta_index);
494 } else {
495 ath_dbg(common, ATH_DBG_CONFIG,
496 "Added a station entry for VIF %d (idx: %d)\n",
497 avp->index, tsta.sta_index);
498 }
394 499
500 priv->sta_slot |= (1 << sta_idx);
395 priv->nstations++; 501 priv->nstations++;
502 if (!sta)
503 priv->vif_sta_pos[avp->index] = sta_idx;
504
396 return 0; 505 return 0;
397} 506}
398 507
@@ -401,6 +510,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
401 struct ieee80211_sta *sta) 510 struct ieee80211_sta *sta)
402{ 511{
403 struct ath_common *common = ath9k_hw_common(priv->ah); 512 struct ath_common *common = ath9k_hw_common(priv->ah);
513 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
404 struct ath9k_htc_sta *ista; 514 struct ath9k_htc_sta *ista;
405 int ret; 515 int ret;
406 u8 cmd_rsp, sta_idx; 516 u8 cmd_rsp, sta_idx;
@@ -409,7 +519,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
409 ista = (struct ath9k_htc_sta *) sta->drv_priv; 519 ista = (struct ath9k_htc_sta *) sta->drv_priv;
410 sta_idx = ista->index; 520 sta_idx = ista->index;
411 } else { 521 } else {
412 sta_idx = 0; 522 sta_idx = priv->vif_sta_pos[avp->index];
413 } 523 }
414 524
415 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx); 525 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
@@ -421,12 +531,19 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
421 return ret; 531 return ret;
422 } 532 }
423 533
424 if (sta) 534 if (sta) {
425 ath_dbg(common, ATH_DBG_CONFIG, 535 ath_dbg(common, ATH_DBG_CONFIG,
426 "Removed a station entry for: %pM (idx: %d)\n", 536 "Removed a station entry for: %pM (idx: %d)\n",
427 sta->addr, sta_idx); 537 sta->addr, sta_idx);
538 } else {
539 ath_dbg(common, ATH_DBG_CONFIG,
540 "Removed a station entry for VIF %d (idx: %d)\n",
541 avp->index, sta_idx);
542 }
428 543
544 priv->sta_slot &= ~(1 << sta_idx);
429 priv->nstations--; 545 priv->nstations--;
546
430 return 0; 547 return 0;
431} 548}
432 549
@@ -808,7 +925,7 @@ void ath9k_htc_debug_remove_root(void)
808/* ANI */ 925/* ANI */
809/*******/ 926/*******/
810 927
811void ath_start_ani(struct ath9k_htc_priv *priv) 928void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
812{ 929{
813 struct ath_common *common = ath9k_hw_common(priv->ah); 930 struct ath_common *common = ath9k_hw_common(priv->ah);
814 unsigned long timestamp = jiffies_to_msecs(jiffies); 931 unsigned long timestamp = jiffies_to_msecs(jiffies);
@@ -817,15 +934,22 @@ void ath_start_ani(struct ath9k_htc_priv *priv)
817 common->ani.shortcal_timer = timestamp; 934 common->ani.shortcal_timer = timestamp;
818 common->ani.checkani_timer = timestamp; 935 common->ani.checkani_timer = timestamp;
819 936
820 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work, 937 priv->op_flags |= OP_ANI_RUNNING;
938
939 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
821 msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); 940 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
822} 941}
823 942
824void ath9k_ani_work(struct work_struct *work) 943void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)
944{
945 cancel_delayed_work_sync(&priv->ani_work);
946 priv->op_flags &= ~OP_ANI_RUNNING;
947}
948
949void ath9k_htc_ani_work(struct work_struct *work)
825{ 950{
826 struct ath9k_htc_priv *priv = 951 struct ath9k_htc_priv *priv =
827 container_of(work, struct ath9k_htc_priv, 952 container_of(work, struct ath9k_htc_priv, ani_work.work);
828 ath9k_ani_work.work);
829 struct ath_hw *ah = priv->ah; 953 struct ath_hw *ah = priv->ah;
830 struct ath_common *common = ath9k_hw_common(ah); 954 struct ath_common *common = ath9k_hw_common(ah);
831 bool longcal = false; 955 bool longcal = false;
@@ -834,7 +958,8 @@ void ath9k_ani_work(struct work_struct *work)
834 unsigned int timestamp = jiffies_to_msecs(jiffies); 958 unsigned int timestamp = jiffies_to_msecs(jiffies);
835 u32 cal_interval, short_cal_interval; 959 u32 cal_interval, short_cal_interval;
836 960
837 short_cal_interval = ATH_STA_SHORT_CALINTERVAL; 961 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
962 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
838 963
839 /* Only calibrate if awake */ 964 /* Only calibrate if awake */
840 if (ah->power_mode != ATH9K_PM_AWAKE) 965 if (ah->power_mode != ATH9K_PM_AWAKE)
@@ -903,7 +1028,7 @@ set_timer:
903 if (!common->ani.caldone) 1028 if (!common->ani.caldone)
904 cal_interval = min(cal_interval, (u32)short_cal_interval); 1029 cal_interval = min(cal_interval, (u32)short_cal_interval);
905 1030
906 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work, 1031 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
907 msecs_to_jiffies(cal_interval)); 1032 msecs_to_jiffies(cal_interval));
908} 1033}
909 1034
@@ -911,7 +1036,7 @@ set_timer:
911/* mac80211 Callbacks */ 1036/* mac80211 Callbacks */
912/**********************/ 1037/**********************/
913 1038
914static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 1039static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
915{ 1040{
916 struct ieee80211_hdr *hdr; 1041 struct ieee80211_hdr *hdr;
917 struct ath9k_htc_priv *priv = hw->priv; 1042 struct ath9k_htc_priv *priv = hw->priv;
@@ -924,7 +1049,7 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
924 padsize = padpos & 3; 1049 padsize = padpos & 3;
925 if (padsize && skb->len > padpos) { 1050 if (padsize && skb->len > padpos) {
926 if (skb_headroom(skb) < padsize) 1051 if (skb_headroom(skb) < padsize)
927 return -1; 1052 goto fail_tx;
928 skb_push(skb, padsize); 1053 skb_push(skb, padsize);
929 memmove(skb->data, skb->data + padsize, padpos); 1054 memmove(skb->data, skb->data + padsize, padpos);
930 } 1055 }
@@ -945,11 +1070,10 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
945 goto fail_tx; 1070 goto fail_tx;
946 } 1071 }
947 1072
948 return 0; 1073 return;
949 1074
950fail_tx: 1075fail_tx:
951 dev_kfree_skb_any(skb); 1076 dev_kfree_skb_any(skb);
952 return 0;
953} 1077}
954 1078
955static int ath9k_htc_start(struct ieee80211_hw *hw) 1079static int ath9k_htc_start(struct ieee80211_hw *hw)
@@ -987,7 +1111,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
987 return ret; 1111 return ret;
988 } 1112 }
989 1113
990 ath_update_txpow(priv); 1114 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
1115 &priv->curtxpow);
991 1116
992 mode = ath9k_htc_get_curmode(priv, init_channel); 1117 mode = ath9k_htc_get_curmode(priv, init_channel);
993 htc_mode = cpu_to_be16(mode); 1118 htc_mode = cpu_to_be16(mode);
@@ -997,6 +1122,11 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
997 1122
998 ath9k_host_rx_init(priv); 1123 ath9k_host_rx_init(priv);
999 1124
1125 ret = ath9k_htc_update_cap_target(priv);
1126 if (ret)
1127 ath_dbg(common, ATH_DBG_CONFIG,
1128 "Failed to update capability in target\n");
1129
1000 priv->op_flags &= ~OP_INVALID; 1130 priv->op_flags &= ~OP_INVALID;
1001 htc_start(priv->htc); 1131 htc_start(priv->htc);
1002 1132
@@ -1051,25 +1181,21 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1051 cancel_work_sync(&priv->fatal_work); 1181 cancel_work_sync(&priv->fatal_work);
1052 cancel_work_sync(&priv->ps_work); 1182 cancel_work_sync(&priv->ps_work);
1053 cancel_delayed_work_sync(&priv->ath9k_led_blink_work); 1183 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1184 ath9k_htc_stop_ani(priv);
1054 ath9k_led_stop_brightness(priv); 1185 ath9k_led_stop_brightness(priv);
1055 1186
1056 mutex_lock(&priv->mutex); 1187 mutex_lock(&priv->mutex);
1057 1188
1058 /* Remove monitor interface here */
1059 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1060 if (ath9k_htc_remove_monitor_interface(priv))
1061 ath_err(common, "Unable to remove monitor interface\n");
1062 else
1063 ath_dbg(common, ATH_DBG_CONFIG,
1064 "Monitor interface removed\n");
1065 }
1066
1067 if (ah->btcoex_hw.enabled) { 1189 if (ah->btcoex_hw.enabled) {
1068 ath9k_hw_btcoex_disable(ah); 1190 ath9k_hw_btcoex_disable(ah);
1069 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 1191 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1070 ath_htc_cancel_btcoex_work(priv); 1192 ath_htc_cancel_btcoex_work(priv);
1071 } 1193 }
1072 1194
1195 /* Remove a monitor interface if it's present. */
1196 if (priv->ah->is_monitoring)
1197 ath9k_htc_remove_monitor_interface(priv);
1198
1073 ath9k_hw_phy_disable(ah); 1199 ath9k_hw_phy_disable(ah);
1074 ath9k_hw_disable(ah); 1200 ath9k_hw_disable(ah);
1075 ath9k_htc_ps_restore(priv); 1201 ath9k_htc_ps_restore(priv);
@@ -1093,10 +1219,24 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1093 1219
1094 mutex_lock(&priv->mutex); 1220 mutex_lock(&priv->mutex);
1095 1221
1096 /* Only one interface for now */ 1222 if (priv->nvifs >= ATH9K_HTC_MAX_VIF) {
1097 if (priv->nvifs > 0) { 1223 mutex_unlock(&priv->mutex);
1098 ret = -ENOBUFS; 1224 return -ENOBUFS;
1099 goto out; 1225 }
1226
1227 if (priv->num_ibss_vif ||
1228 (priv->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
1229 ath_err(common, "IBSS coexistence with other modes is not allowed\n");
1230 mutex_unlock(&priv->mutex);
1231 return -ENOBUFS;
1232 }
1233
1234 if (((vif->type == NL80211_IFTYPE_AP) ||
1235 (vif->type == NL80211_IFTYPE_ADHOC)) &&
1236 ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) {
1237 ath_err(common, "Max. number of beaconing interfaces reached\n");
1238 mutex_unlock(&priv->mutex);
1239 return -ENOBUFS;
1100 } 1240 }
1101 1241
1102 ath9k_htc_ps_wakeup(priv); 1242 ath9k_htc_ps_wakeup(priv);
@@ -1110,6 +1250,9 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1110 case NL80211_IFTYPE_ADHOC: 1250 case NL80211_IFTYPE_ADHOC:
1111 hvif.opmode = cpu_to_be32(HTC_M_IBSS); 1251 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1112 break; 1252 break;
1253 case NL80211_IFTYPE_AP:
1254 hvif.opmode = cpu_to_be32(HTC_M_HOSTAP);
1255 break;
1113 default: 1256 default:
1114 ath_err(common, 1257 ath_err(common,
1115 "Interface type %d not yet supported\n", vif->type); 1258 "Interface type %d not yet supported\n", vif->type);
@@ -1117,34 +1260,39 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1117 goto out; 1260 goto out;
1118 } 1261 }
1119 1262
1120 ath_dbg(common, ATH_DBG_CONFIG,
1121 "Attach a VIF of type: %d\n", vif->type);
1122
1123 priv->ah->opmode = vif->type;
1124
1125 /* Index starts from zero on the target */ 1263 /* Index starts from zero on the target */
1126 avp->index = hvif.index = priv->nvifs; 1264 avp->index = hvif.index = ffz(priv->vif_slot);
1127 hvif.rtsthreshold = cpu_to_be16(2304); 1265 hvif.rtsthreshold = cpu_to_be16(2304);
1128 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); 1266 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1129 if (ret) 1267 if (ret)
1130 goto out; 1268 goto out;
1131 1269
1132 priv->nvifs++;
1133
1134 /* 1270 /*
1135 * We need a node in target to tx mgmt frames 1271 * We need a node in target to tx mgmt frames
1136 * before association. 1272 * before association.
1137 */ 1273 */
1138 ret = ath9k_htc_add_station(priv, vif, NULL); 1274 ret = ath9k_htc_add_station(priv, vif, NULL);
1139 if (ret) 1275 if (ret) {
1276 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1140 goto out; 1277 goto out;
1278 }
1141 1279
1142 ret = ath9k_htc_update_cap_target(priv); 1280 ath9k_htc_set_bssid_mask(priv, vif);
1143 if (ret)
1144 ath_dbg(common, ATH_DBG_CONFIG,
1145 "Failed to update capability in target\n");
1146 1281
1282 priv->vif_slot |= (1 << avp->index);
1283 priv->nvifs++;
1147 priv->vif = vif; 1284 priv->vif = vif;
1285
1286 INC_VIF(priv, vif->type);
1287 ath9k_htc_set_opmode(priv);
1288
1289 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1290 !(priv->op_flags & OP_ANI_RUNNING))
1291 ath9k_htc_start_ani(priv);
1292
1293 ath_dbg(common, ATH_DBG_CONFIG,
1294 "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index);
1295
1148out: 1296out:
1149 ath9k_htc_ps_restore(priv); 1297 ath9k_htc_ps_restore(priv);
1150 mutex_unlock(&priv->mutex); 1298 mutex_unlock(&priv->mutex);
@@ -1162,8 +1310,6 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1162 int ret = 0; 1310 int ret = 0;
1163 u8 cmd_rsp; 1311 u8 cmd_rsp;
1164 1312
1165 ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
1166
1167 mutex_lock(&priv->mutex); 1313 mutex_lock(&priv->mutex);
1168 ath9k_htc_ps_wakeup(priv); 1314 ath9k_htc_ps_wakeup(priv);
1169 1315
@@ -1172,10 +1318,27 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1172 hvif.index = avp->index; 1318 hvif.index = avp->index;
1173 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); 1319 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1174 priv->nvifs--; 1320 priv->nvifs--;
1321 priv->vif_slot &= ~(1 << avp->index);
1175 1322
1176 ath9k_htc_remove_station(priv, vif, NULL); 1323 ath9k_htc_remove_station(priv, vif, NULL);
1177 priv->vif = NULL; 1324 priv->vif = NULL;
1178 1325
1326 DEC_VIF(priv, vif->type);
1327 ath9k_htc_set_opmode(priv);
1328
1329 /*
1330 * Stop ANI only if there are no associated station interfaces.
1331 */
1332 if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
1333 priv->rearm_ani = false;
1334 ieee80211_iterate_active_interfaces_atomic(priv->hw,
1335 ath9k_htc_vif_iter, priv);
1336 if (!priv->rearm_ani)
1337 ath9k_htc_stop_ani(priv);
1338 }
1339
1340 ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index);
1341
1179 ath9k_htc_ps_restore(priv); 1342 ath9k_htc_ps_restore(priv);
1180 mutex_unlock(&priv->mutex); 1343 mutex_unlock(&priv->mutex);
1181} 1344}
@@ -1211,13 +1374,11 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1211 * IEEE80211_CONF_CHANGE_CHANNEL is handled. 1374 * IEEE80211_CONF_CHANGE_CHANNEL is handled.
1212 */ 1375 */
1213 if (changed & IEEE80211_CONF_CHANGE_MONITOR) { 1376 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1214 if (conf->flags & IEEE80211_CONF_MONITOR) { 1377 if ((conf->flags & IEEE80211_CONF_MONITOR) &&
1215 if (ath9k_htc_add_monitor_interface(priv)) 1378 !priv->ah->is_monitoring)
1216 ath_err(common, "Failed to set monitor mode\n"); 1379 ath9k_htc_add_monitor_interface(priv);
1217 else 1380 else if (priv->ah->is_monitoring)
1218 ath_dbg(common, ATH_DBG_CONFIG, 1381 ath9k_htc_remove_monitor_interface(priv);
1219 "HW opmode set to Monitor mode\n");
1220 }
1221 } 1382 }
1222 1383
1223 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1384 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
@@ -1252,7 +1413,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1252 1413
1253 if (changed & IEEE80211_CONF_CHANGE_POWER) { 1414 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1254 priv->txpowlimit = 2 * conf->power_level; 1415 priv->txpowlimit = 2 * conf->power_level;
1255 ath_update_txpow(priv); 1416 ath9k_cmn_update_txpow(priv->ah, priv->curtxpow,
1417 priv->txpowlimit, &priv->curtxpow);
1256 } 1418 }
1257 1419
1258 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 1420 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
@@ -1439,66 +1601,81 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1439 struct ath9k_htc_priv *priv = hw->priv; 1601 struct ath9k_htc_priv *priv = hw->priv;
1440 struct ath_hw *ah = priv->ah; 1602 struct ath_hw *ah = priv->ah;
1441 struct ath_common *common = ath9k_hw_common(ah); 1603 struct ath_common *common = ath9k_hw_common(ah);
1604 bool set_assoc;
1442 1605
1443 mutex_lock(&priv->mutex); 1606 mutex_lock(&priv->mutex);
1444 ath9k_htc_ps_wakeup(priv); 1607 ath9k_htc_ps_wakeup(priv);
1445 1608
1609 /*
1610 * Set the HW AID/BSSID only for the first station interface
1611 * or in IBSS mode.
1612 */
1613 set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) ||
1614 ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
1615 (priv->num_sta_vif == 1)));
1616
1617
1446 if (changed & BSS_CHANGED_ASSOC) { 1618 if (changed & BSS_CHANGED_ASSOC) {
1447 common->curaid = bss_conf->assoc ? 1619 if (set_assoc) {
1448 bss_conf->aid : 0; 1620 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1449 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", 1621 bss_conf->assoc);
1450 bss_conf->assoc); 1622
1451 1623 common->curaid = bss_conf->assoc ?
1452 if (bss_conf->assoc) { 1624 bss_conf->aid : 0;
1453 priv->op_flags |= OP_ASSOCIATED; 1625
1454 ath_start_ani(priv); 1626 if (bss_conf->assoc)
1455 } else { 1627 ath9k_htc_start_ani(priv);
1456 priv->op_flags &= ~OP_ASSOCIATED; 1628 else
1457 cancel_delayed_work_sync(&priv->ath9k_ani_work); 1629 ath9k_htc_stop_ani(priv);
1458 } 1630 }
1459 } 1631 }
1460 1632
1461 if (changed & BSS_CHANGED_BSSID) { 1633 if (changed & BSS_CHANGED_BSSID) {
1462 /* Set BSSID */ 1634 if (set_assoc) {
1463 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); 1635 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1464 ath9k_hw_write_associd(ah); 1636 ath9k_hw_write_associd(ah);
1465 1637
1466 ath_dbg(common, ATH_DBG_CONFIG, 1638 ath_dbg(common, ATH_DBG_CONFIG,
1467 "BSSID: %pM aid: 0x%x\n", 1639 "BSSID: %pM aid: 0x%x\n",
1468 common->curbssid, common->curaid); 1640 common->curbssid, common->curaid);
1641 }
1469 } 1642 }
1470 1643
1471 if ((changed & BSS_CHANGED_BEACON_INT) || 1644 if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
1472 (changed & BSS_CHANGED_BEACON) || 1645 ath_dbg(common, ATH_DBG_CONFIG,
1473 ((changed & BSS_CHANGED_BEACON_ENABLED) && 1646 "Beacon enabled for BSS: %pM\n", bss_conf->bssid);
1474 bss_conf->enable_beacon)) {
1475 priv->op_flags |= OP_ENABLE_BEACON; 1647 priv->op_flags |= OP_ENABLE_BEACON;
1476 ath9k_htc_beacon_config(priv, vif); 1648 ath9k_htc_beacon_config(priv, vif);
1477 } 1649 }
1478 1650
1479 if ((changed & BSS_CHANGED_BEACON_ENABLED) && 1651 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
1480 !bss_conf->enable_beacon) { 1652 /*
1481 priv->op_flags &= ~OP_ENABLE_BEACON; 1653 * Disable SWBA interrupt only if there are no
1482 ath9k_htc_beacon_config(priv, vif); 1654 * AP/IBSS interfaces.
1483 } 1655 */
1484 1656 if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) {
1485 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 1657 ath_dbg(common, ATH_DBG_CONFIG,
1486 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", 1658 "Beacon disabled for BSS: %pM\n",
1487 bss_conf->use_short_preamble); 1659 bss_conf->bssid);
1488 if (bss_conf->use_short_preamble) 1660 priv->op_flags &= ~OP_ENABLE_BEACON;
1489 priv->op_flags |= OP_PREAMBLE_SHORT; 1661 ath9k_htc_beacon_config(priv, vif);
1490 else 1662 }
1491 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1492 } 1663 }
1493 1664
1494 if (changed & BSS_CHANGED_ERP_CTS_PROT) { 1665 if (changed & BSS_CHANGED_BEACON_INT) {
1495 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", 1666 /*
1496 bss_conf->use_cts_prot); 1667 * Reset the HW TSF for the first AP interface.
1497 if (bss_conf->use_cts_prot && 1668 */
1498 hw->conf.channel->band != IEEE80211_BAND_5GHZ) 1669 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1499 priv->op_flags |= OP_PROTECT_ENABLE; 1670 (priv->nvifs == 1) &&
1500 else 1671 (priv->num_ap_vif == 1) &&
1501 priv->op_flags &= ~OP_PROTECT_ENABLE; 1672 (vif->type == NL80211_IFTYPE_AP)) {
1673 priv->op_flags |= OP_TSF_RESET;
1674 }
1675 ath_dbg(common, ATH_DBG_CONFIG,
1676 "Beacon interval changed for BSS: %pM\n",
1677 bss_conf->bssid);
1678 ath9k_htc_beacon_config(priv, vif);
1502 } 1679 }
1503 1680
1504 if (changed & BSS_CHANGED_ERP_SLOT) { 1681 if (changed & BSS_CHANGED_ERP_SLOT) {
@@ -1557,12 +1734,14 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1557 struct ieee80211_vif *vif, 1734 struct ieee80211_vif *vif,
1558 enum ieee80211_ampdu_mlme_action action, 1735 enum ieee80211_ampdu_mlme_action action,
1559 struct ieee80211_sta *sta, 1736 struct ieee80211_sta *sta,
1560 u16 tid, u16 *ssn) 1737 u16 tid, u16 *ssn, u8 buf_size)
1561{ 1738{
1562 struct ath9k_htc_priv *priv = hw->priv; 1739 struct ath9k_htc_priv *priv = hw->priv;
1563 struct ath9k_htc_sta *ista; 1740 struct ath9k_htc_sta *ista;
1564 int ret = 0; 1741 int ret = 0;
1565 1742
1743 mutex_lock(&priv->mutex);
1744
1566 switch (action) { 1745 switch (action) {
1567 case IEEE80211_AMPDU_RX_START: 1746 case IEEE80211_AMPDU_RX_START:
1568 break; 1747 break;
@@ -1587,6 +1766,8 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1587 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); 1766 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
1588 } 1767 }
1589 1768
1769 mutex_unlock(&priv->mutex);
1770
1590 return ret; 1771 return ret;
1591} 1772}
1592 1773
@@ -1599,8 +1780,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1599 priv->op_flags |= OP_SCANNING; 1780 priv->op_flags |= OP_SCANNING;
1600 spin_unlock_bh(&priv->beacon_lock); 1781 spin_unlock_bh(&priv->beacon_lock);
1601 cancel_work_sync(&priv->ps_work); 1782 cancel_work_sync(&priv->ps_work);
1602 if (priv->op_flags & OP_ASSOCIATED) 1783 ath9k_htc_stop_ani(priv);
1603 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1604 mutex_unlock(&priv->mutex); 1784 mutex_unlock(&priv->mutex);
1605} 1785}
1606 1786
@@ -1609,14 +1789,11 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1609 struct ath9k_htc_priv *priv = hw->priv; 1789 struct ath9k_htc_priv *priv = hw->priv;
1610 1790
1611 mutex_lock(&priv->mutex); 1791 mutex_lock(&priv->mutex);
1612 ath9k_htc_ps_wakeup(priv);
1613 spin_lock_bh(&priv->beacon_lock); 1792 spin_lock_bh(&priv->beacon_lock);
1614 priv->op_flags &= ~OP_SCANNING; 1793 priv->op_flags &= ~OP_SCANNING;
1615 spin_unlock_bh(&priv->beacon_lock); 1794 spin_unlock_bh(&priv->beacon_lock);
1616 if (priv->op_flags & OP_ASSOCIATED) { 1795 ath9k_htc_ps_wakeup(priv);
1617 ath9k_htc_beacon_config(priv, priv->vif); 1796 ath9k_htc_vif_reconfig(priv);
1618 ath_start_ani(priv);
1619 }
1620 ath9k_htc_ps_restore(priv); 1797 ath9k_htc_ps_restore(priv);
1621 mutex_unlock(&priv->mutex); 1798 mutex_unlock(&priv->mutex);
1622} 1799}