diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 588 |
1 files changed, 272 insertions, 316 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c0c3464d3a86..8a1691db166d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -23,7 +23,7 @@ static void ath_update_txpow(struct ath_softc *sc) | |||
23 | struct ath_hw *ah = sc->sc_ah; | 23 | struct ath_hw *ah = sc->sc_ah; |
24 | 24 | ||
25 | if (sc->curtxpow != sc->config.txpowlimit) { | 25 | if (sc->curtxpow != sc->config.txpowlimit) { |
26 | ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit); | 26 | ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); |
27 | /* read back in case value is clamped */ | 27 | /* read back in case value is clamped */ |
28 | sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; | 28 | sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; |
29 | } | 29 | } |
@@ -234,6 +234,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
234 | 234 | ||
235 | ath9k_ps_wakeup(sc); | 235 | ath9k_ps_wakeup(sc); |
236 | 236 | ||
237 | spin_lock_bh(&sc->sc_pcu_lock); | ||
238 | |||
237 | /* | 239 | /* |
238 | * This is only performed if the channel settings have | 240 | * This is only performed if the channel settings have |
239 | * actually changed. | 241 | * actually changed. |
@@ -243,11 +245,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
243 | * hardware at the new frequency, and then re-enable | 245 | * hardware at the new frequency, and then re-enable |
244 | * the relevant bits of the h/w. | 246 | * the relevant bits of the h/w. |
245 | */ | 247 | */ |
246 | ath9k_hw_set_interrupts(ah, 0); | 248 | ath9k_hw_disable_interrupts(ah); |
247 | stopped = ath_drain_all_txq(sc, false); | 249 | stopped = ath_drain_all_txq(sc, false); |
248 | 250 | ||
249 | spin_lock_bh(&sc->rx.pcu_lock); | ||
250 | |||
251 | if (!ath_stoprecv(sc)) | 251 | if (!ath_stoprecv(sc)) |
252 | stopped = false; | 252 | stopped = false; |
253 | 253 | ||
@@ -261,36 +261,26 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
261 | if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) | 261 | if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) |
262 | caldata = &aphy->caldata; | 262 | caldata = &aphy->caldata; |
263 | 263 | ||
264 | ath_print(common, ATH_DBG_CONFIG, | 264 | ath_dbg(common, ATH_DBG_CONFIG, |
265 | "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", | 265 | "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", |
266 | sc->sc_ah->curchan->channel, | 266 | sc->sc_ah->curchan->channel, |
267 | channel->center_freq, conf_is_ht40(conf), | 267 | channel->center_freq, conf_is_ht40(conf), |
268 | fastcc); | 268 | fastcc); |
269 | |||
270 | spin_lock_bh(&sc->sc_resetlock); | ||
271 | 269 | ||
272 | r = ath9k_hw_reset(ah, hchan, caldata, fastcc); | 270 | r = ath9k_hw_reset(ah, hchan, caldata, fastcc); |
273 | if (r) { | 271 | if (r) { |
274 | ath_print(common, ATH_DBG_FATAL, | 272 | ath_err(common, |
275 | "Unable to reset channel (%u MHz), " | 273 | "Unable to reset channel (%u MHz), reset status %d\n", |
276 | "reset status %d\n", | 274 | channel->center_freq, r); |
277 | channel->center_freq, r); | ||
278 | spin_unlock_bh(&sc->sc_resetlock); | ||
279 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
280 | goto ps_restore; | 275 | goto ps_restore; |
281 | } | 276 | } |
282 | spin_unlock_bh(&sc->sc_resetlock); | ||
283 | 277 | ||
284 | if (ath_startrecv(sc) != 0) { | 278 | if (ath_startrecv(sc) != 0) { |
285 | ath_print(common, ATH_DBG_FATAL, | 279 | ath_err(common, "Unable to restart recv logic\n"); |
286 | "Unable to restart recv logic\n"); | ||
287 | r = -EIO; | 280 | r = -EIO; |
288 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
289 | goto ps_restore; | 281 | goto ps_restore; |
290 | } | 282 | } |
291 | 283 | ||
292 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
293 | |||
294 | ath_update_txpow(sc); | 284 | ath_update_txpow(sc); |
295 | ath9k_hw_set_interrupts(ah, ah->imask); | 285 | ath9k_hw_set_interrupts(ah, ah->imask); |
296 | 286 | ||
@@ -301,6 +291,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
301 | } | 291 | } |
302 | 292 | ||
303 | ps_restore: | 293 | ps_restore: |
294 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
295 | |||
304 | ath9k_ps_restore(sc); | 296 | ath9k_ps_restore(sc); |
305 | return r; | 297 | return r; |
306 | } | 298 | } |
@@ -328,6 +320,42 @@ static void ath_paprd_activate(struct ath_softc *sc) | |||
328 | ath9k_ps_restore(sc); | 320 | ath9k_ps_restore(sc); |
329 | } | 321 | } |
330 | 322 | ||
323 | static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) | ||
324 | { | ||
325 | struct ieee80211_hw *hw = sc->hw; | ||
326 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
327 | struct ath_tx_control txctl; | ||
328 | int time_left; | ||
329 | |||
330 | memset(&txctl, 0, sizeof(txctl)); | ||
331 | txctl.txq = sc->tx.txq_map[WME_AC_BE]; | ||
332 | |||
333 | memset(tx_info, 0, sizeof(*tx_info)); | ||
334 | tx_info->band = hw->conf.channel->band; | ||
335 | tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
336 | tx_info->control.rates[0].idx = 0; | ||
337 | tx_info->control.rates[0].count = 1; | ||
338 | tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; | ||
339 | tx_info->control.rates[1].idx = -1; | ||
340 | |||
341 | init_completion(&sc->paprd_complete); | ||
342 | sc->paprd_pending = true; | ||
343 | txctl.paprd = BIT(chain); | ||
344 | if (ath_tx_start(hw, skb, &txctl) != 0) | ||
345 | return false; | ||
346 | |||
347 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | ||
348 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | ||
349 | sc->paprd_pending = false; | ||
350 | |||
351 | if (!time_left) | ||
352 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, | ||
353 | "Timeout waiting for paprd training on TX chain %d\n", | ||
354 | chain); | ||
355 | |||
356 | return !!time_left; | ||
357 | } | ||
358 | |||
331 | void ath_paprd_calibrate(struct work_struct *work) | 359 | void ath_paprd_calibrate(struct work_struct *work) |
332 | { | 360 | { |
333 | struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); | 361 | struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); |
@@ -335,28 +363,23 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
335 | struct ath_hw *ah = sc->sc_ah; | 363 | struct ath_hw *ah = sc->sc_ah; |
336 | struct ieee80211_hdr *hdr; | 364 | struct ieee80211_hdr *hdr; |
337 | struct sk_buff *skb = NULL; | 365 | struct sk_buff *skb = NULL; |
338 | struct ieee80211_tx_info *tx_info; | ||
339 | int band = hw->conf.channel->band; | ||
340 | struct ieee80211_supported_band *sband = &sc->sbands[band]; | ||
341 | struct ath_tx_control txctl; | ||
342 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 366 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
343 | struct ath_common *common = ath9k_hw_common(ah); | 367 | struct ath_common *common = ath9k_hw_common(ah); |
344 | int qnum, ftype; | 368 | int ftype; |
345 | int chain_ok = 0; | 369 | int chain_ok = 0; |
346 | int chain; | 370 | int chain; |
347 | int len = 1800; | 371 | int len = 1800; |
348 | int time_left; | ||
349 | int i; | ||
350 | 372 | ||
351 | if (!caldata) | 373 | if (!caldata) |
352 | return; | 374 | return; |
353 | 375 | ||
376 | if (ar9003_paprd_init_table(ah) < 0) | ||
377 | return; | ||
378 | |||
354 | skb = alloc_skb(len, GFP_KERNEL); | 379 | skb = alloc_skb(len, GFP_KERNEL); |
355 | if (!skb) | 380 | if (!skb) |
356 | return; | 381 | return; |
357 | 382 | ||
358 | tx_info = IEEE80211_SKB_CB(skb); | ||
359 | |||
360 | skb_put(skb, len); | 383 | skb_put(skb, len); |
361 | memset(skb->data, 0, len); | 384 | memset(skb->data, 0, len); |
362 | hdr = (struct ieee80211_hdr *)skb->data; | 385 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -367,40 +390,25 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
367 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); | 390 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); |
368 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); | 391 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); |
369 | 392 | ||
370 | memset(&txctl, 0, sizeof(txctl)); | ||
371 | qnum = sc->tx.hwq_map[WME_AC_BE]; | ||
372 | txctl.txq = &sc->tx.txq[qnum]; | ||
373 | |||
374 | ath9k_ps_wakeup(sc); | 393 | ath9k_ps_wakeup(sc); |
375 | ar9003_paprd_init_table(ah); | ||
376 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | 394 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
377 | if (!(common->tx_chainmask & BIT(chain))) | 395 | if (!(common->tx_chainmask & BIT(chain))) |
378 | continue; | 396 | continue; |
379 | 397 | ||
380 | chain_ok = 0; | 398 | chain_ok = 0; |
381 | memset(tx_info, 0, sizeof(*tx_info)); | ||
382 | tx_info->band = band; | ||
383 | 399 | ||
384 | for (i = 0; i < 4; i++) { | 400 | ath_dbg(common, ATH_DBG_CALIBRATE, |
385 | tx_info->control.rates[i].idx = sband->n_bitrates - 1; | 401 | "Sending PAPRD frame for thermal measurement " |
386 | tx_info->control.rates[i].count = 6; | 402 | "on chain %d\n", chain); |
387 | } | 403 | if (!ath_paprd_send_frame(sc, skb, chain)) |
404 | goto fail_paprd; | ||
388 | 405 | ||
389 | init_completion(&sc->paprd_complete); | ||
390 | ar9003_paprd_setup_gain_table(ah, chain); | 406 | ar9003_paprd_setup_gain_table(ah, chain); |
391 | txctl.paprd = BIT(chain); | ||
392 | if (ath_tx_start(hw, skb, &txctl) != 0) | ||
393 | break; | ||
394 | 407 | ||
395 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | 408 | ath_dbg(common, ATH_DBG_CALIBRATE, |
396 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | 409 | "Sending PAPRD training frame on chain %d\n", chain); |
397 | if (!time_left) { | 410 | if (!ath_paprd_send_frame(sc, skb, chain)) |
398 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
399 | "Timeout waiting for paprd training on " | ||
400 | "TX chain %d\n", | ||
401 | chain); | ||
402 | goto fail_paprd; | 411 | goto fail_paprd; |
403 | } | ||
404 | 412 | ||
405 | if (!ar9003_paprd_is_done(ah)) | 413 | if (!ar9003_paprd_is_done(ah)) |
406 | break; | 414 | break; |
@@ -457,7 +465,7 @@ void ath_ani_calibrate(unsigned long data) | |||
457 | /* Long calibration runs independently of short calibration. */ | 465 | /* Long calibration runs independently of short calibration. */ |
458 | if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { | 466 | if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { |
459 | longcal = true; | 467 | longcal = true; |
460 | ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); | 468 | ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); |
461 | common->ani.longcal_timer = timestamp; | 469 | common->ani.longcal_timer = timestamp; |
462 | } | 470 | } |
463 | 471 | ||
@@ -465,8 +473,8 @@ void ath_ani_calibrate(unsigned long data) | |||
465 | if (!common->ani.caldone) { | 473 | if (!common->ani.caldone) { |
466 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { | 474 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { |
467 | shortcal = true; | 475 | shortcal = true; |
468 | ath_print(common, ATH_DBG_ANI, | 476 | ath_dbg(common, ATH_DBG_ANI, |
469 | "shortcal @%lu\n", jiffies); | 477 | "shortcal @%lu\n", jiffies); |
470 | common->ani.shortcal_timer = timestamp; | 478 | common->ani.shortcal_timer = timestamp; |
471 | common->ani.resetcal_timer = timestamp; | 479 | common->ani.resetcal_timer = timestamp; |
472 | } | 480 | } |
@@ -525,49 +533,25 @@ set_timer: | |||
525 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { | 533 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { |
526 | if (!ah->caldata->paprd_done) | 534 | if (!ah->caldata->paprd_done) |
527 | ieee80211_queue_work(sc->hw, &sc->paprd_work); | 535 | ieee80211_queue_work(sc->hw, &sc->paprd_work); |
528 | else | 536 | else if (!ah->paprd_table_write_done) |
529 | ath_paprd_activate(sc); | 537 | ath_paprd_activate(sc); |
530 | } | 538 | } |
531 | } | 539 | } |
532 | 540 | ||
533 | /* | ||
534 | * Update tx/rx chainmask. For legacy association, | ||
535 | * hard code chainmask to 1x1, for 11n association, use | ||
536 | * the chainmask configuration, for bt coexistence, use | ||
537 | * the chainmask configuration even in legacy mode. | ||
538 | */ | ||
539 | void ath_update_chainmask(struct ath_softc *sc, int is_ht) | ||
540 | { | ||
541 | struct ath_hw *ah = sc->sc_ah; | ||
542 | struct ath_common *common = ath9k_hw_common(ah); | ||
543 | |||
544 | if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht || | ||
545 | (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) { | ||
546 | common->tx_chainmask = ah->caps.tx_chainmask; | ||
547 | common->rx_chainmask = ah->caps.rx_chainmask; | ||
548 | } else { | ||
549 | common->tx_chainmask = 1; | ||
550 | common->rx_chainmask = 1; | ||
551 | } | ||
552 | |||
553 | ath_print(common, ATH_DBG_CONFIG, | ||
554 | "tx chmask: %d, rx chmask: %d\n", | ||
555 | common->tx_chainmask, | ||
556 | common->rx_chainmask); | ||
557 | } | ||
558 | |||
559 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | 541 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) |
560 | { | 542 | { |
561 | struct ath_node *an; | 543 | struct ath_node *an; |
562 | 544 | struct ath_hw *ah = sc->sc_ah; | |
563 | an = (struct ath_node *)sta->drv_priv; | 545 | an = (struct ath_node *)sta->drv_priv; |
564 | 546 | ||
547 | if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM) | ||
548 | sc->sc_flags |= SC_OP_ENABLE_APM; | ||
549 | |||
565 | if (sc->sc_flags & SC_OP_TXAGGR) { | 550 | if (sc->sc_flags & SC_OP_TXAGGR) { |
566 | ath_tx_node_init(sc, an); | 551 | ath_tx_node_init(sc, an); |
567 | an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + | 552 | an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + |
568 | sta->ht_cap.ampdu_factor); | 553 | sta->ht_cap.ampdu_factor); |
569 | an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); | 554 | an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); |
570 | an->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
571 | } | 555 | } |
572 | } | 556 | } |
573 | 557 | ||
@@ -615,6 +599,8 @@ void ath9k_tasklet(unsigned long data) | |||
615 | return; | 599 | return; |
616 | } | 600 | } |
617 | 601 | ||
602 | spin_lock_bh(&sc->sc_pcu_lock); | ||
603 | |||
618 | if (!ath9k_hw_check_alive(ah)) | 604 | if (!ath9k_hw_check_alive(ah)) |
619 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | 605 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); |
620 | 606 | ||
@@ -625,15 +611,12 @@ void ath9k_tasklet(unsigned long data) | |||
625 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | 611 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); |
626 | 612 | ||
627 | if (status & rxmask) { | 613 | if (status & rxmask) { |
628 | spin_lock_bh(&sc->rx.pcu_lock); | ||
629 | |||
630 | /* Check for high priority Rx first */ | 614 | /* Check for high priority Rx first */ |
631 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | 615 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && |
632 | (status & ATH9K_INT_RXHP)) | 616 | (status & ATH9K_INT_RXHP)) |
633 | ath_rx_tasklet(sc, 0, true); | 617 | ath_rx_tasklet(sc, 0, true); |
634 | 618 | ||
635 | ath_rx_tasklet(sc, 0, false); | 619 | ath_rx_tasklet(sc, 0, false); |
636 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
637 | } | 620 | } |
638 | 621 | ||
639 | if (status & ATH9K_INT_TX) { | 622 | if (status & ATH9K_INT_TX) { |
@@ -648,8 +631,8 @@ void ath9k_tasklet(unsigned long data) | |||
648 | * TSF sync does not look correct; remain awake to sync with | 631 | * TSF sync does not look correct; remain awake to sync with |
649 | * the next Beacon. | 632 | * the next Beacon. |
650 | */ | 633 | */ |
651 | ath_print(common, ATH_DBG_PS, | 634 | ath_dbg(common, ATH_DBG_PS, |
652 | "TSFOOR - Sync with next Beacon\n"); | 635 | "TSFOOR - Sync with next Beacon\n"); |
653 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; | 636 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; |
654 | } | 637 | } |
655 | 638 | ||
@@ -658,7 +641,9 @@ void ath9k_tasklet(unsigned long data) | |||
658 | ath_gen_timer_isr(sc->sc_ah); | 641 | ath_gen_timer_isr(sc->sc_ah); |
659 | 642 | ||
660 | /* re-enable hardware interrupt */ | 643 | /* re-enable hardware interrupt */ |
661 | ath9k_hw_set_interrupts(ah, ah->imask); | 644 | ath9k_hw_enable_interrupts(ah); |
645 | |||
646 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
662 | ath9k_ps_restore(sc); | 647 | ath9k_ps_restore(sc); |
663 | } | 648 | } |
664 | 649 | ||
@@ -757,7 +742,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
757 | * interrupt; otherwise it will continue to | 742 | * interrupt; otherwise it will continue to |
758 | * fire. | 743 | * fire. |
759 | */ | 744 | */ |
760 | ath9k_hw_set_interrupts(ah, 0); | 745 | ath9k_hw_disable_interrupts(ah); |
761 | /* | 746 | /* |
762 | * Let the hal handle the event. We assume | 747 | * Let the hal handle the event. We assume |
763 | * it will clear whatever condition caused | 748 | * it will clear whatever condition caused |
@@ -766,11 +751,13 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
766 | spin_lock(&common->cc_lock); | 751 | spin_lock(&common->cc_lock); |
767 | ath9k_hw_proc_mib_event(ah); | 752 | ath9k_hw_proc_mib_event(ah); |
768 | spin_unlock(&common->cc_lock); | 753 | spin_unlock(&common->cc_lock); |
769 | ath9k_hw_set_interrupts(ah, ah->imask); | 754 | ath9k_hw_enable_interrupts(ah); |
770 | } | 755 | } |
771 | 756 | ||
772 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | 757 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) |
773 | if (status & ATH9K_INT_TIM_TIMER) { | 758 | if (status & ATH9K_INT_TIM_TIMER) { |
759 | if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle)) | ||
760 | goto chip_reset; | ||
774 | /* Clear RxAbort bit so that we can | 761 | /* Clear RxAbort bit so that we can |
775 | * receive frames */ | 762 | * receive frames */ |
776 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | 763 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
@@ -783,8 +770,8 @@ chip_reset: | |||
783 | ath_debug_stat_interrupt(sc, status); | 770 | ath_debug_stat_interrupt(sc, status); |
784 | 771 | ||
785 | if (sched) { | 772 | if (sched) { |
786 | /* turn off every interrupt except SWBA */ | 773 | /* turn off every interrupt */ |
787 | ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA)); | 774 | ath9k_hw_disable_interrupts(ah); |
788 | tasklet_schedule(&sc->intr_tq); | 775 | tasklet_schedule(&sc->intr_tq); |
789 | } | 776 | } |
790 | 777 | ||
@@ -836,16 +823,18 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, | |||
836 | } | 823 | } |
837 | 824 | ||
838 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | 825 | static void ath9k_bss_assoc_info(struct ath_softc *sc, |
826 | struct ieee80211_hw *hw, | ||
839 | struct ieee80211_vif *vif, | 827 | struct ieee80211_vif *vif, |
840 | struct ieee80211_bss_conf *bss_conf) | 828 | struct ieee80211_bss_conf *bss_conf) |
841 | { | 829 | { |
830 | struct ath_wiphy *aphy = hw->priv; | ||
842 | struct ath_hw *ah = sc->sc_ah; | 831 | struct ath_hw *ah = sc->sc_ah; |
843 | struct ath_common *common = ath9k_hw_common(ah); | 832 | struct ath_common *common = ath9k_hw_common(ah); |
844 | 833 | ||
845 | if (bss_conf->assoc) { | 834 | if (bss_conf->assoc) { |
846 | ath_print(common, ATH_DBG_CONFIG, | 835 | ath_dbg(common, ATH_DBG_CONFIG, |
847 | "Bss Info ASSOC %d, bssid: %pM\n", | 836 | "Bss Info ASSOC %d, bssid: %pM\n", |
848 | bss_conf->aid, common->curbssid); | 837 | bss_conf->aid, common->curbssid); |
849 | 838 | ||
850 | /* New association, store aid */ | 839 | /* New association, store aid */ |
851 | common->curaid = bss_conf->aid; | 840 | common->curaid = bss_conf->aid; |
@@ -862,12 +851,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
862 | ath_beacon_config(sc, vif); | 851 | ath_beacon_config(sc, vif); |
863 | 852 | ||
864 | /* Reset rssi stats */ | 853 | /* Reset rssi stats */ |
854 | aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
865 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 855 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
866 | 856 | ||
867 | sc->sc_flags |= SC_OP_ANI_RUN; | 857 | sc->sc_flags |= SC_OP_ANI_RUN; |
868 | ath_start_ani(common); | 858 | ath_start_ani(common); |
869 | } else { | 859 | } else { |
870 | ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); | 860 | ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); |
871 | common->curaid = 0; | 861 | common->curaid = 0; |
872 | /* Stop ANI */ | 862 | /* Stop ANI */ |
873 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 863 | sc->sc_flags &= ~SC_OP_ANI_RUN; |
@@ -883,31 +873,25 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
883 | int r; | 873 | int r; |
884 | 874 | ||
885 | ath9k_ps_wakeup(sc); | 875 | ath9k_ps_wakeup(sc); |
876 | spin_lock_bh(&sc->sc_pcu_lock); | ||
877 | |||
886 | ath9k_hw_configpcipowersave(ah, 0, 0); | 878 | ath9k_hw_configpcipowersave(ah, 0, 0); |
887 | 879 | ||
888 | if (!ah->curchan) | 880 | if (!ah->curchan) |
889 | ah->curchan = ath_get_curchannel(sc, sc->hw); | 881 | ah->curchan = ath_get_curchannel(sc, sc->hw); |
890 | 882 | ||
891 | spin_lock_bh(&sc->rx.pcu_lock); | ||
892 | spin_lock_bh(&sc->sc_resetlock); | ||
893 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); | 883 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
894 | if (r) { | 884 | if (r) { |
895 | ath_print(common, ATH_DBG_FATAL, | 885 | ath_err(common, |
896 | "Unable to reset channel (%u MHz), " | 886 | "Unable to reset channel (%u MHz), reset status %d\n", |
897 | "reset status %d\n", | 887 | channel->center_freq, r); |
898 | channel->center_freq, r); | ||
899 | } | 888 | } |
900 | spin_unlock_bh(&sc->sc_resetlock); | ||
901 | 889 | ||
902 | ath_update_txpow(sc); | 890 | ath_update_txpow(sc); |
903 | if (ath_startrecv(sc) != 0) { | 891 | if (ath_startrecv(sc) != 0) { |
904 | ath_print(common, ATH_DBG_FATAL, | 892 | ath_err(common, "Unable to restart recv logic\n"); |
905 | "Unable to restart recv logic\n"); | 893 | goto out; |
906 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
907 | return; | ||
908 | } | 894 | } |
909 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
910 | |||
911 | if (sc->sc_flags & SC_OP_BEACONS) | 895 | if (sc->sc_flags & SC_OP_BEACONS) |
912 | ath_beacon_config(sc, NULL); /* restart beacons */ | 896 | ath_beacon_config(sc, NULL); /* restart beacons */ |
913 | 897 | ||
@@ -920,6 +904,9 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
920 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); | 904 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); |
921 | 905 | ||
922 | ieee80211_wake_queues(hw); | 906 | ieee80211_wake_queues(hw); |
907 | out: | ||
908 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
909 | |||
923 | ath9k_ps_restore(sc); | 910 | ath9k_ps_restore(sc); |
924 | } | 911 | } |
925 | 912 | ||
@@ -930,6 +917,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
930 | int r; | 917 | int r; |
931 | 918 | ||
932 | ath9k_ps_wakeup(sc); | 919 | ath9k_ps_wakeup(sc); |
920 | spin_lock_bh(&sc->sc_pcu_lock); | ||
921 | |||
933 | ieee80211_stop_queues(hw); | 922 | ieee80211_stop_queues(hw); |
934 | 923 | ||
935 | /* | 924 | /* |
@@ -942,34 +931,30 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
942 | } | 931 | } |
943 | 932 | ||
944 | /* Disable interrupts */ | 933 | /* Disable interrupts */ |
945 | ath9k_hw_set_interrupts(ah, 0); | 934 | ath9k_hw_disable_interrupts(ah); |
946 | 935 | ||
947 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ | 936 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ |
948 | 937 | ||
949 | spin_lock_bh(&sc->rx.pcu_lock); | ||
950 | |||
951 | ath_stoprecv(sc); /* turn off frame recv */ | 938 | ath_stoprecv(sc); /* turn off frame recv */ |
952 | ath_flushrecv(sc); /* flush recv queue */ | 939 | ath_flushrecv(sc); /* flush recv queue */ |
953 | 940 | ||
954 | if (!ah->curchan) | 941 | if (!ah->curchan) |
955 | ah->curchan = ath_get_curchannel(sc, hw); | 942 | ah->curchan = ath_get_curchannel(sc, hw); |
956 | 943 | ||
957 | spin_lock_bh(&sc->sc_resetlock); | ||
958 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); | 944 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
959 | if (r) { | 945 | if (r) { |
960 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 946 | ath_err(ath9k_hw_common(sc->sc_ah), |
961 | "Unable to reset channel (%u MHz), " | 947 | "Unable to reset channel (%u MHz), reset status %d\n", |
962 | "reset status %d\n", | 948 | channel->center_freq, r); |
963 | channel->center_freq, r); | ||
964 | } | 949 | } |
965 | spin_unlock_bh(&sc->sc_resetlock); | ||
966 | 950 | ||
967 | ath9k_hw_phy_disable(ah); | 951 | ath9k_hw_phy_disable(ah); |
968 | 952 | ||
969 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
970 | |||
971 | ath9k_hw_configpcipowersave(ah, 1, 1); | 953 | ath9k_hw_configpcipowersave(ah, 1, 1); |
954 | |||
955 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
972 | ath9k_ps_restore(sc); | 956 | ath9k_ps_restore(sc); |
957 | |||
973 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 958 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
974 | } | 959 | } |
975 | 960 | ||
@@ -983,28 +968,23 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
983 | /* Stop ANI */ | 968 | /* Stop ANI */ |
984 | del_timer_sync(&common->ani.timer); | 969 | del_timer_sync(&common->ani.timer); |
985 | 970 | ||
971 | spin_lock_bh(&sc->sc_pcu_lock); | ||
972 | |||
986 | ieee80211_stop_queues(hw); | 973 | ieee80211_stop_queues(hw); |
987 | 974 | ||
988 | ath9k_hw_set_interrupts(ah, 0); | 975 | ath9k_hw_disable_interrupts(ah); |
989 | ath_drain_all_txq(sc, retry_tx); | 976 | ath_drain_all_txq(sc, retry_tx); |
990 | 977 | ||
991 | spin_lock_bh(&sc->rx.pcu_lock); | ||
992 | |||
993 | ath_stoprecv(sc); | 978 | ath_stoprecv(sc); |
994 | ath_flushrecv(sc); | 979 | ath_flushrecv(sc); |
995 | 980 | ||
996 | spin_lock_bh(&sc->sc_resetlock); | ||
997 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); | 981 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); |
998 | if (r) | 982 | if (r) |
999 | ath_print(common, ATH_DBG_FATAL, | 983 | ath_err(common, |
1000 | "Unable to reset hardware; reset status %d\n", r); | 984 | "Unable to reset hardware; reset status %d\n", r); |
1001 | spin_unlock_bh(&sc->sc_resetlock); | ||
1002 | 985 | ||
1003 | if (ath_startrecv(sc) != 0) | 986 | if (ath_startrecv(sc) != 0) |
1004 | ath_print(common, ATH_DBG_FATAL, | 987 | ath_err(common, "Unable to start recv logic\n"); |
1005 | "Unable to start recv logic\n"); | ||
1006 | |||
1007 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
1008 | 988 | ||
1009 | /* | 989 | /* |
1010 | * We may be doing a reset in response to a request | 990 | * We may be doing a reset in response to a request |
@@ -1030,6 +1010,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1030 | } | 1010 | } |
1031 | 1011 | ||
1032 | ieee80211_wake_queues(hw); | 1012 | ieee80211_wake_queues(hw); |
1013 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1033 | 1014 | ||
1034 | /* Start ANI */ | 1015 | /* Start ANI */ |
1035 | ath_start_ani(common); | 1016 | ath_start_ani(common); |
@@ -1037,56 +1018,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1037 | return r; | 1018 | return r; |
1038 | } | 1019 | } |
1039 | 1020 | ||
1040 | static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) | ||
1041 | { | ||
1042 | int qnum; | ||
1043 | |||
1044 | switch (queue) { | ||
1045 | case 0: | ||
1046 | qnum = sc->tx.hwq_map[WME_AC_VO]; | ||
1047 | break; | ||
1048 | case 1: | ||
1049 | qnum = sc->tx.hwq_map[WME_AC_VI]; | ||
1050 | break; | ||
1051 | case 2: | ||
1052 | qnum = sc->tx.hwq_map[WME_AC_BE]; | ||
1053 | break; | ||
1054 | case 3: | ||
1055 | qnum = sc->tx.hwq_map[WME_AC_BK]; | ||
1056 | break; | ||
1057 | default: | ||
1058 | qnum = sc->tx.hwq_map[WME_AC_BE]; | ||
1059 | break; | ||
1060 | } | ||
1061 | |||
1062 | return qnum; | ||
1063 | } | ||
1064 | |||
1065 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) | ||
1066 | { | ||
1067 | int qnum; | ||
1068 | |||
1069 | switch (queue) { | ||
1070 | case WME_AC_VO: | ||
1071 | qnum = 0; | ||
1072 | break; | ||
1073 | case WME_AC_VI: | ||
1074 | qnum = 1; | ||
1075 | break; | ||
1076 | case WME_AC_BE: | ||
1077 | qnum = 2; | ||
1078 | break; | ||
1079 | case WME_AC_BK: | ||
1080 | qnum = 3; | ||
1081 | break; | ||
1082 | default: | ||
1083 | qnum = -1; | ||
1084 | break; | ||
1085 | } | ||
1086 | |||
1087 | return qnum; | ||
1088 | } | ||
1089 | |||
1090 | /* XXX: Remove me once we don't depend on ath9k_channel for all | 1021 | /* XXX: Remove me once we don't depend on ath9k_channel for all |
1091 | * this redundant data */ | 1022 | * this redundant data */ |
1092 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | 1023 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, |
@@ -1125,9 +1056,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1125 | struct ath9k_channel *init_channel; | 1056 | struct ath9k_channel *init_channel; |
1126 | int r; | 1057 | int r; |
1127 | 1058 | ||
1128 | ath_print(common, ATH_DBG_CONFIG, | 1059 | ath_dbg(common, ATH_DBG_CONFIG, |
1129 | "Starting driver with initial channel: %d MHz\n", | 1060 | "Starting driver with initial channel: %d MHz\n", |
1130 | curchan->center_freq); | 1061 | curchan->center_freq); |
1131 | 1062 | ||
1132 | mutex_lock(&sc->mutex); | 1063 | mutex_lock(&sc->mutex); |
1133 | 1064 | ||
@@ -1168,19 +1099,15 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1168 | * be followed by initialization of the appropriate bits | 1099 | * be followed by initialization of the appropriate bits |
1169 | * and then setup of the interrupt mask. | 1100 | * and then setup of the interrupt mask. |
1170 | */ | 1101 | */ |
1171 | spin_lock_bh(&sc->rx.pcu_lock); | 1102 | spin_lock_bh(&sc->sc_pcu_lock); |
1172 | spin_lock_bh(&sc->sc_resetlock); | ||
1173 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); | 1103 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); |
1174 | if (r) { | 1104 | if (r) { |
1175 | ath_print(common, ATH_DBG_FATAL, | 1105 | ath_err(common, |
1176 | "Unable to reset hardware; reset status %d " | 1106 | "Unable to reset hardware; reset status %d (freq %u MHz)\n", |
1177 | "(freq %u MHz)\n", r, | 1107 | r, curchan->center_freq); |
1178 | curchan->center_freq); | 1108 | spin_unlock_bh(&sc->sc_pcu_lock); |
1179 | spin_unlock_bh(&sc->sc_resetlock); | ||
1180 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
1181 | goto mutex_unlock; | 1109 | goto mutex_unlock; |
1182 | } | 1110 | } |
1183 | spin_unlock_bh(&sc->sc_resetlock); | ||
1184 | 1111 | ||
1185 | /* | 1112 | /* |
1186 | * This is needed only to setup initial state | 1113 | * This is needed only to setup initial state |
@@ -1196,13 +1123,12 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1196 | * here except setup the interrupt mask. | 1123 | * here except setup the interrupt mask. |
1197 | */ | 1124 | */ |
1198 | if (ath_startrecv(sc) != 0) { | 1125 | if (ath_startrecv(sc) != 0) { |
1199 | ath_print(common, ATH_DBG_FATAL, | 1126 | ath_err(common, "Unable to start recv logic\n"); |
1200 | "Unable to start recv logic\n"); | ||
1201 | r = -EIO; | 1127 | r = -EIO; |
1202 | spin_unlock_bh(&sc->rx.pcu_lock); | 1128 | spin_unlock_bh(&sc->sc_pcu_lock); |
1203 | goto mutex_unlock; | 1129 | goto mutex_unlock; |
1204 | } | 1130 | } |
1205 | spin_unlock_bh(&sc->rx.pcu_lock); | 1131 | spin_unlock_bh(&sc->sc_pcu_lock); |
1206 | 1132 | ||
1207 | /* Setup our intr mask. */ | 1133 | /* Setup our intr mask. */ |
1208 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | | 1134 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | |
@@ -1244,7 +1170,14 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1244 | ath9k_btcoex_timer_resume(sc); | 1170 | ath9k_btcoex_timer_resume(sc); |
1245 | } | 1171 | } |
1246 | 1172 | ||
1247 | pm_qos_update_request(&sc->pm_qos_req, 55); | 1173 | /* User has the option to provide pm-qos value as a module |
1174 | * parameter rather than using the default value of | ||
1175 | * 'ATH9K_PM_QOS_DEFAULT_VALUE'. | ||
1176 | */ | ||
1177 | pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value); | ||
1178 | |||
1179 | if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) | ||
1180 | common->bus_ops->extn_synch_en(common); | ||
1248 | 1181 | ||
1249 | mutex_unlock: | 1182 | mutex_unlock: |
1250 | mutex_unlock(&sc->mutex); | 1183 | mutex_unlock(&sc->mutex); |
@@ -1255,19 +1188,16 @@ mutex_unlock: | |||
1255 | static int ath9k_tx(struct ieee80211_hw *hw, | 1188 | static int ath9k_tx(struct ieee80211_hw *hw, |
1256 | struct sk_buff *skb) | 1189 | struct sk_buff *skb) |
1257 | { | 1190 | { |
1258 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1259 | struct ath_wiphy *aphy = hw->priv; | 1191 | struct ath_wiphy *aphy = hw->priv; |
1260 | struct ath_softc *sc = aphy->sc; | 1192 | struct ath_softc *sc = aphy->sc; |
1261 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1193 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1262 | struct ath_tx_control txctl; | 1194 | struct ath_tx_control txctl; |
1263 | int padpos, padsize; | ||
1264 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1195 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1265 | int qnum; | ||
1266 | 1196 | ||
1267 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { | 1197 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { |
1268 | ath_print(common, ATH_DBG_XMIT, | 1198 | ath_dbg(common, ATH_DBG_XMIT, |
1269 | "ath9k: %s: TX in unexpected wiphy state " | 1199 | "ath9k: %s: TX in unexpected wiphy state %d\n", |
1270 | "%d\n", wiphy_name(hw->wiphy), aphy->state); | 1200 | wiphy_name(hw->wiphy), aphy->state); |
1271 | goto exit; | 1201 | goto exit; |
1272 | } | 1202 | } |
1273 | 1203 | ||
@@ -1279,8 +1209,8 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
1279 | if (ieee80211_is_data(hdr->frame_control) && | 1209 | if (ieee80211_is_data(hdr->frame_control) && |
1280 | !ieee80211_is_nullfunc(hdr->frame_control) && | 1210 | !ieee80211_is_nullfunc(hdr->frame_control) && |
1281 | !ieee80211_has_pm(hdr->frame_control)) { | 1211 | !ieee80211_has_pm(hdr->frame_control)) { |
1282 | ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame " | 1212 | ath_dbg(common, ATH_DBG_PS, |
1283 | "while in PS mode\n"); | 1213 | "Add PM=1 for a TX frame while in PS mode\n"); |
1284 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | 1214 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); |
1285 | } | 1215 | } |
1286 | } | 1216 | } |
@@ -1295,12 +1225,12 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
1295 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | 1225 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) |
1296 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 1226 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
1297 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 1227 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
1298 | ath_print(common, ATH_DBG_PS, | 1228 | ath_dbg(common, ATH_DBG_PS, |
1299 | "Sending PS-Poll to pick a buffered frame\n"); | 1229 | "Sending PS-Poll to pick a buffered frame\n"); |
1300 | sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA; | 1230 | sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA; |
1301 | } else { | 1231 | } else { |
1302 | ath_print(common, ATH_DBG_PS, | 1232 | ath_dbg(common, ATH_DBG_PS, |
1303 | "Wake up to complete TX\n"); | 1233 | "Wake up to complete TX\n"); |
1304 | sc->ps_flags |= PS_WAIT_FOR_TX_ACK; | 1234 | sc->ps_flags |= PS_WAIT_FOR_TX_ACK; |
1305 | } | 1235 | } |
1306 | /* | 1236 | /* |
@@ -1312,36 +1242,12 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
1312 | } | 1242 | } |
1313 | 1243 | ||
1314 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | 1244 | memset(&txctl, 0, sizeof(struct ath_tx_control)); |
1245 | txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; | ||
1315 | 1246 | ||
1316 | /* | 1247 | ath_dbg(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); |
1317 | * As a temporary workaround, assign seq# here; this will likely need | ||
1318 | * to be cleaned up to work better with Beacon transmission and virtual | ||
1319 | * BSSes. | ||
1320 | */ | ||
1321 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
1322 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
1323 | sc->tx.seq_no += 0x10; | ||
1324 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
1325 | hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); | ||
1326 | } | ||
1327 | |||
1328 | /* Add the padding after the header if this is not already done */ | ||
1329 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
1330 | padsize = padpos & 3; | ||
1331 | if (padsize && skb->len>padpos) { | ||
1332 | if (skb_headroom(skb) < padsize) | ||
1333 | return -1; | ||
1334 | skb_push(skb, padsize); | ||
1335 | memmove(skb->data, skb->data + padsize, padpos); | ||
1336 | } | ||
1337 | |||
1338 | qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); | ||
1339 | txctl.txq = &sc->tx.txq[qnum]; | ||
1340 | |||
1341 | ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); | ||
1342 | 1248 | ||
1343 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 1249 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
1344 | ath_print(common, ATH_DBG_XMIT, "TX failed\n"); | 1250 | ath_dbg(common, ATH_DBG_XMIT, "TX failed\n"); |
1345 | goto exit; | 1251 | goto exit; |
1346 | } | 1252 | } |
1347 | 1253 | ||
@@ -1381,7 +1287,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1381 | } | 1287 | } |
1382 | 1288 | ||
1383 | if (sc->sc_flags & SC_OP_INVALID) { | 1289 | if (sc->sc_flags & SC_OP_INVALID) { |
1384 | ath_print(common, ATH_DBG_ANY, "Device not present\n"); | 1290 | ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); |
1385 | mutex_unlock(&sc->mutex); | 1291 | mutex_unlock(&sc->mutex); |
1386 | return; | 1292 | return; |
1387 | } | 1293 | } |
@@ -1400,26 +1306,29 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1400 | ath9k_btcoex_timer_pause(sc); | 1306 | ath9k_btcoex_timer_pause(sc); |
1401 | } | 1307 | } |
1402 | 1308 | ||
1309 | spin_lock_bh(&sc->sc_pcu_lock); | ||
1310 | |||
1403 | /* make sure h/w will not generate any interrupt | 1311 | /* make sure h/w will not generate any interrupt |
1404 | * before setting the invalid flag. */ | 1312 | * before setting the invalid flag. */ |
1405 | ath9k_hw_set_interrupts(ah, 0); | 1313 | ath9k_hw_disable_interrupts(ah); |
1406 | 1314 | ||
1407 | spin_lock_bh(&sc->rx.pcu_lock); | ||
1408 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 1315 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
1409 | ath_drain_all_txq(sc, false); | 1316 | ath_drain_all_txq(sc, false); |
1410 | ath_stoprecv(sc); | 1317 | ath_stoprecv(sc); |
1411 | ath9k_hw_phy_disable(ah); | 1318 | ath9k_hw_phy_disable(ah); |
1412 | } else | 1319 | } else |
1413 | sc->rx.rxlink = NULL; | 1320 | sc->rx.rxlink = NULL; |
1414 | spin_unlock_bh(&sc->rx.pcu_lock); | ||
1415 | 1321 | ||
1416 | /* disable HAL and put h/w to sleep */ | 1322 | /* disable HAL and put h/w to sleep */ |
1417 | ath9k_hw_disable(ah); | 1323 | ath9k_hw_disable(ah); |
1418 | ath9k_hw_configpcipowersave(ah, 1, 1); | 1324 | ath9k_hw_configpcipowersave(ah, 1, 1); |
1325 | |||
1326 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
1327 | |||
1419 | ath9k_ps_restore(sc); | 1328 | ath9k_ps_restore(sc); |
1420 | 1329 | ||
1421 | /* Finally, put the chip in FULL SLEEP mode */ | 1330 | sc->ps_idle = true; |
1422 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 1331 | ath_radio_disable(sc, hw); |
1423 | 1332 | ||
1424 | sc->sc_flags |= SC_OP_INVALID; | 1333 | sc->sc_flags |= SC_OP_INVALID; |
1425 | 1334 | ||
@@ -1427,7 +1336,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1427 | 1336 | ||
1428 | mutex_unlock(&sc->mutex); | 1337 | mutex_unlock(&sc->mutex); |
1429 | 1338 | ||
1430 | ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); | 1339 | ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); |
1431 | } | 1340 | } |
1432 | 1341 | ||
1433 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 1342 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
@@ -1460,14 +1369,14 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1460 | ic_opmode = vif->type; | 1369 | ic_opmode = vif->type; |
1461 | break; | 1370 | break; |
1462 | default: | 1371 | default: |
1463 | ath_print(common, ATH_DBG_FATAL, | 1372 | ath_err(common, "Interface type %d not yet supported\n", |
1464 | "Interface type %d not yet supported\n", vif->type); | 1373 | vif->type); |
1465 | ret = -EOPNOTSUPP; | 1374 | ret = -EOPNOTSUPP; |
1466 | goto out; | 1375 | goto out; |
1467 | } | 1376 | } |
1468 | 1377 | ||
1469 | ath_print(common, ATH_DBG_CONFIG, | 1378 | ath_dbg(common, ATH_DBG_CONFIG, |
1470 | "Attach a VIF of type: %d\n", ic_opmode); | 1379 | "Attach a VIF of type: %d\n", ic_opmode); |
1471 | 1380 | ||
1472 | /* Set the VIF opmode */ | 1381 | /* Set the VIF opmode */ |
1473 | avp->av_opmode = ic_opmode; | 1382 | avp->av_opmode = ic_opmode; |
@@ -1513,15 +1422,80 @@ out: | |||
1513 | return ret; | 1422 | return ret; |
1514 | } | 1423 | } |
1515 | 1424 | ||
1425 | static void ath9k_reclaim_beacon(struct ath_softc *sc, | ||
1426 | struct ieee80211_vif *vif) | ||
1427 | { | ||
1428 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1429 | |||
1430 | /* Disable SWBA interrupt */ | ||
1431 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
1432 | ath9k_ps_wakeup(sc); | ||
1433 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1434 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
1435 | tasklet_kill(&sc->bcon_tasklet); | ||
1436 | ath9k_ps_restore(sc); | ||
1437 | |||
1438 | ath_beacon_return(sc, avp); | ||
1439 | sc->sc_flags &= ~SC_OP_BEACONS; | ||
1440 | |||
1441 | if (sc->nbcnvifs > 0) { | ||
1442 | /* Re-enable beaconing */ | ||
1443 | sc->sc_ah->imask |= ATH9K_INT_SWBA; | ||
1444 | ath9k_ps_wakeup(sc); | ||
1445 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1446 | ath9k_ps_restore(sc); | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | static int ath9k_change_interface(struct ieee80211_hw *hw, | ||
1451 | struct ieee80211_vif *vif, | ||
1452 | enum nl80211_iftype new_type, | ||
1453 | bool p2p) | ||
1454 | { | ||
1455 | struct ath_wiphy *aphy = hw->priv; | ||
1456 | struct ath_softc *sc = aphy->sc; | ||
1457 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1458 | |||
1459 | ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n"); | ||
1460 | mutex_lock(&sc->mutex); | ||
1461 | |||
1462 | switch (new_type) { | ||
1463 | case NL80211_IFTYPE_AP: | ||
1464 | case NL80211_IFTYPE_ADHOC: | ||
1465 | if (sc->nbcnvifs >= ATH_BCBUF) { | ||
1466 | ath_err(common, "No beacon slot available\n"); | ||
1467 | return -ENOBUFS; | ||
1468 | } | ||
1469 | break; | ||
1470 | case NL80211_IFTYPE_STATION: | ||
1471 | /* Stop ANI */ | ||
1472 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
1473 | del_timer_sync(&common->ani.timer); | ||
1474 | if ((vif->type == NL80211_IFTYPE_AP) || | ||
1475 | (vif->type == NL80211_IFTYPE_ADHOC)) | ||
1476 | ath9k_reclaim_beacon(sc, vif); | ||
1477 | break; | ||
1478 | default: | ||
1479 | ath_err(common, "Interface type %d not yet supported\n", | ||
1480 | vif->type); | ||
1481 | mutex_unlock(&sc->mutex); | ||
1482 | return -ENOTSUPP; | ||
1483 | } | ||
1484 | vif->type = new_type; | ||
1485 | vif->p2p = p2p; | ||
1486 | |||
1487 | mutex_unlock(&sc->mutex); | ||
1488 | return 0; | ||
1489 | } | ||
1490 | |||
1516 | static void ath9k_remove_interface(struct ieee80211_hw *hw, | 1491 | static void ath9k_remove_interface(struct ieee80211_hw *hw, |
1517 | struct ieee80211_vif *vif) | 1492 | struct ieee80211_vif *vif) |
1518 | { | 1493 | { |
1519 | struct ath_wiphy *aphy = hw->priv; | 1494 | struct ath_wiphy *aphy = hw->priv; |
1520 | struct ath_softc *sc = aphy->sc; | 1495 | struct ath_softc *sc = aphy->sc; |
1521 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1496 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1522 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1523 | 1497 | ||
1524 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1498 | ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
1525 | 1499 | ||
1526 | mutex_lock(&sc->mutex); | 1500 | mutex_lock(&sc->mutex); |
1527 | 1501 | ||
@@ -1532,26 +1506,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1532 | /* Reclaim beacon resources */ | 1506 | /* Reclaim beacon resources */ |
1533 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 1507 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
1534 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 1508 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
1535 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | 1509 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) |
1536 | /* Disable SWBA interrupt */ | 1510 | ath9k_reclaim_beacon(sc, vif); |
1537 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
1538 | ath9k_ps_wakeup(sc); | ||
1539 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1540 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
1541 | ath9k_ps_restore(sc); | ||
1542 | tasklet_kill(&sc->bcon_tasklet); | ||
1543 | } | ||
1544 | |||
1545 | ath_beacon_return(sc, avp); | ||
1546 | sc->sc_flags &= ~SC_OP_BEACONS; | ||
1547 | |||
1548 | if (sc->nbcnvifs) { | ||
1549 | /* Re-enable SWBA interrupt */ | ||
1550 | sc->sc_ah->imask |= ATH9K_INT_SWBA; | ||
1551 | ath9k_ps_wakeup(sc); | ||
1552 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1553 | ath9k_ps_restore(sc); | ||
1554 | } | ||
1555 | 1511 | ||
1556 | sc->nvifs--; | 1512 | sc->nvifs--; |
1557 | 1513 | ||
@@ -1631,8 +1587,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1631 | if (enable_radio) { | 1587 | if (enable_radio) { |
1632 | sc->ps_idle = false; | 1588 | sc->ps_idle = false; |
1633 | ath_radio_enable(sc, hw); | 1589 | ath_radio_enable(sc, hw); |
1634 | ath_print(common, ATH_DBG_CONFIG, | 1590 | ath_dbg(common, ATH_DBG_CONFIG, |
1635 | "not-idle: enabling radio\n"); | 1591 | "not-idle: enabling radio\n"); |
1636 | } | 1592 | } |
1637 | } | 1593 | } |
1638 | 1594 | ||
@@ -1654,12 +1610,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1654 | 1610 | ||
1655 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | 1611 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { |
1656 | if (conf->flags & IEEE80211_CONF_MONITOR) { | 1612 | if (conf->flags & IEEE80211_CONF_MONITOR) { |
1657 | ath_print(common, ATH_DBG_CONFIG, | 1613 | ath_dbg(common, ATH_DBG_CONFIG, |
1658 | "Monitor mode is enabled\n"); | 1614 | "Monitor mode is enabled\n"); |
1659 | sc->sc_ah->is_monitoring = true; | 1615 | sc->sc_ah->is_monitoring = true; |
1660 | } else { | 1616 | } else { |
1661 | ath_print(common, ATH_DBG_CONFIG, | 1617 | ath_dbg(common, ATH_DBG_CONFIG, |
1662 | "Monitor mode is disabled\n"); | 1618 | "Monitor mode is disabled\n"); |
1663 | sc->sc_ah->is_monitoring = false; | 1619 | sc->sc_ah->is_monitoring = false; |
1664 | } | 1620 | } |
1665 | } | 1621 | } |
@@ -1691,14 +1647,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1691 | goto skip_chan_change; | 1647 | goto skip_chan_change; |
1692 | } | 1648 | } |
1693 | 1649 | ||
1694 | ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 1650 | ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
1695 | curchan->center_freq); | 1651 | curchan->center_freq); |
1696 | 1652 | ||
1697 | /* XXX: remove me eventualy */ | 1653 | /* XXX: remove me eventualy */ |
1698 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); | 1654 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); |
1699 | 1655 | ||
1700 | ath_update_chainmask(sc, conf_is_ht(conf)); | ||
1701 | |||
1702 | /* update survey stats for the old channel before switching */ | 1656 | /* update survey stats for the old channel before switching */ |
1703 | spin_lock_irqsave(&common->cc_lock, flags); | 1657 | spin_lock_irqsave(&common->cc_lock, flags); |
1704 | ath_update_survey_stats(sc); | 1658 | ath_update_survey_stats(sc); |
@@ -1725,8 +1679,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1725 | } | 1679 | } |
1726 | 1680 | ||
1727 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { | 1681 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { |
1728 | ath_print(common, ATH_DBG_FATAL, | 1682 | ath_err(common, "Unable to set channel\n"); |
1729 | "Unable to set channel\n"); | ||
1730 | mutex_unlock(&sc->mutex); | 1683 | mutex_unlock(&sc->mutex); |
1731 | return -EINVAL; | 1684 | return -EINVAL; |
1732 | } | 1685 | } |
@@ -1751,7 +1704,7 @@ skip_chan_change: | |||
1751 | spin_unlock_bh(&sc->wiphy_lock); | 1704 | spin_unlock_bh(&sc->wiphy_lock); |
1752 | 1705 | ||
1753 | if (disable_radio) { | 1706 | if (disable_radio) { |
1754 | ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); | 1707 | ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); |
1755 | sc->ps_idle = true; | 1708 | sc->ps_idle = true; |
1756 | ath_radio_disable(sc, hw); | 1709 | ath_radio_disable(sc, hw); |
1757 | } | 1710 | } |
@@ -1790,8 +1743,8 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
1790 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); | 1743 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); |
1791 | ath9k_ps_restore(sc); | 1744 | ath9k_ps_restore(sc); |
1792 | 1745 | ||
1793 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, | 1746 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, |
1794 | "Set HW RX filter: 0x%x\n", rfilt); | 1747 | "Set HW RX filter: 0x%x\n", rfilt); |
1795 | } | 1748 | } |
1796 | 1749 | ||
1797 | static int ath9k_sta_add(struct ieee80211_hw *hw, | 1750 | static int ath9k_sta_add(struct ieee80211_hw *hw, |
@@ -1824,12 +1777,15 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1824 | struct ath_wiphy *aphy = hw->priv; | 1777 | struct ath_wiphy *aphy = hw->priv; |
1825 | struct ath_softc *sc = aphy->sc; | 1778 | struct ath_softc *sc = aphy->sc; |
1826 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1779 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1780 | struct ath_txq *txq; | ||
1827 | struct ath9k_tx_queue_info qi; | 1781 | struct ath9k_tx_queue_info qi; |
1828 | int ret = 0, qnum; | 1782 | int ret = 0; |
1829 | 1783 | ||
1830 | if (queue >= WME_NUM_AC) | 1784 | if (queue >= WME_NUM_AC) |
1831 | return 0; | 1785 | return 0; |
1832 | 1786 | ||
1787 | txq = sc->tx.txq_map[queue]; | ||
1788 | |||
1833 | mutex_lock(&sc->mutex); | 1789 | mutex_lock(&sc->mutex); |
1834 | 1790 | ||
1835 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | 1791 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); |
@@ -1838,20 +1794,18 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1838 | qi.tqi_cwmin = params->cw_min; | 1794 | qi.tqi_cwmin = params->cw_min; |
1839 | qi.tqi_cwmax = params->cw_max; | 1795 | qi.tqi_cwmax = params->cw_max; |
1840 | qi.tqi_burstTime = params->txop; | 1796 | qi.tqi_burstTime = params->txop; |
1841 | qnum = ath_get_hal_qnum(queue, sc); | ||
1842 | 1797 | ||
1843 | ath_print(common, ATH_DBG_CONFIG, | 1798 | ath_dbg(common, ATH_DBG_CONFIG, |
1844 | "Configure tx [queue/halq] [%d/%d], " | 1799 | "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", |
1845 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | 1800 | queue, txq->axq_qnum, params->aifs, params->cw_min, |
1846 | queue, qnum, params->aifs, params->cw_min, | 1801 | params->cw_max, params->txop); |
1847 | params->cw_max, params->txop); | ||
1848 | 1802 | ||
1849 | ret = ath_txq_update(sc, qnum, &qi); | 1803 | ret = ath_txq_update(sc, txq->axq_qnum, &qi); |
1850 | if (ret) | 1804 | if (ret) |
1851 | ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); | 1805 | ath_err(common, "TXQ Update failed\n"); |
1852 | 1806 | ||
1853 | if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) | 1807 | if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) |
1854 | if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret) | 1808 | if (queue == WME_AC_BE && !ret) |
1855 | ath_beaconq_config(sc); | 1809 | ath_beaconq_config(sc); |
1856 | 1810 | ||
1857 | mutex_unlock(&sc->mutex); | 1811 | mutex_unlock(&sc->mutex); |
@@ -1875,7 +1829,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1875 | 1829 | ||
1876 | mutex_lock(&sc->mutex); | 1830 | mutex_lock(&sc->mutex); |
1877 | ath9k_ps_wakeup(sc); | 1831 | ath9k_ps_wakeup(sc); |
1878 | ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n"); | 1832 | ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); |
1879 | 1833 | ||
1880 | switch (cmd) { | 1834 | switch (cmd) { |
1881 | case SET_KEY: | 1835 | case SET_KEY: |
@@ -1930,13 +1884,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1930 | /* Set aggregation protection mode parameters */ | 1884 | /* Set aggregation protection mode parameters */ |
1931 | sc->config.ath_aggr_prot = 0; | 1885 | sc->config.ath_aggr_prot = 0; |
1932 | 1886 | ||
1933 | /* Only legacy IBSS for now */ | 1887 | ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", |
1934 | if (vif->type == NL80211_IFTYPE_ADHOC) | 1888 | common->curbssid, common->curaid); |
1935 | ath_update_chainmask(sc, 0); | ||
1936 | |||
1937 | ath_print(common, ATH_DBG_CONFIG, | ||
1938 | "BSSID: %pM aid: 0x%x\n", | ||
1939 | common->curbssid, common->curaid); | ||
1940 | 1889 | ||
1941 | /* need to reconfigure the beacon */ | 1890 | /* need to reconfigure the beacon */ |
1942 | sc->sc_flags &= ~SC_OP_BEACONS ; | 1891 | sc->sc_flags &= ~SC_OP_BEACONS ; |
@@ -1992,8 +1941,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1992 | } | 1941 | } |
1993 | 1942 | ||
1994 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 1943 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
1995 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | 1944 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", |
1996 | bss_conf->use_short_preamble); | 1945 | bss_conf->use_short_preamble); |
1997 | if (bss_conf->use_short_preamble) | 1946 | if (bss_conf->use_short_preamble) |
1998 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; | 1947 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; |
1999 | else | 1948 | else |
@@ -2001,8 +1950,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2001 | } | 1950 | } |
2002 | 1951 | ||
2003 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | 1952 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { |
2004 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", | 1953 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", |
2005 | bss_conf->use_cts_prot); | 1954 | bss_conf->use_cts_prot); |
2006 | if (bss_conf->use_cts_prot && | 1955 | if (bss_conf->use_cts_prot && |
2007 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) | 1956 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) |
2008 | sc->sc_flags |= SC_OP_PROTECT_ENABLE; | 1957 | sc->sc_flags |= SC_OP_PROTECT_ENABLE; |
@@ -2011,9 +1960,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2011 | } | 1960 | } |
2012 | 1961 | ||
2013 | if (changed & BSS_CHANGED_ASSOC) { | 1962 | if (changed & BSS_CHANGED_ASSOC) { |
2014 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | 1963 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", |
2015 | bss_conf->assoc); | 1964 | bss_conf->assoc); |
2016 | ath9k_bss_assoc_info(sc, vif, bss_conf); | 1965 | ath9k_bss_assoc_info(sc, hw, vif, bss_conf); |
2017 | } | 1966 | } |
2018 | 1967 | ||
2019 | mutex_unlock(&sc->mutex); | 1968 | mutex_unlock(&sc->mutex); |
@@ -2026,7 +1975,9 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw) | |||
2026 | struct ath_softc *sc = aphy->sc; | 1975 | struct ath_softc *sc = aphy->sc; |
2027 | 1976 | ||
2028 | mutex_lock(&sc->mutex); | 1977 | mutex_lock(&sc->mutex); |
1978 | ath9k_ps_wakeup(sc); | ||
2029 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | 1979 | tsf = ath9k_hw_gettsf64(sc->sc_ah); |
1980 | ath9k_ps_restore(sc); | ||
2030 | mutex_unlock(&sc->mutex); | 1981 | mutex_unlock(&sc->mutex); |
2031 | 1982 | ||
2032 | return tsf; | 1983 | return tsf; |
@@ -2038,7 +1989,9 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | |||
2038 | struct ath_softc *sc = aphy->sc; | 1989 | struct ath_softc *sc = aphy->sc; |
2039 | 1990 | ||
2040 | mutex_lock(&sc->mutex); | 1991 | mutex_lock(&sc->mutex); |
1992 | ath9k_ps_wakeup(sc); | ||
2041 | ath9k_hw_settsf64(sc->sc_ah, tsf); | 1993 | ath9k_hw_settsf64(sc->sc_ah, tsf); |
1994 | ath9k_ps_restore(sc); | ||
2042 | mutex_unlock(&sc->mutex); | 1995 | mutex_unlock(&sc->mutex); |
2043 | } | 1996 | } |
2044 | 1997 | ||
@@ -2076,6 +2029,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2076 | case IEEE80211_AMPDU_RX_STOP: | 2029 | case IEEE80211_AMPDU_RX_STOP: |
2077 | break; | 2030 | break; |
2078 | case IEEE80211_AMPDU_TX_START: | 2031 | case IEEE80211_AMPDU_TX_START: |
2032 | if (!(sc->sc_flags & SC_OP_TXAGGR)) | ||
2033 | return -EOPNOTSUPP; | ||
2034 | |||
2079 | ath9k_ps_wakeup(sc); | 2035 | ath9k_ps_wakeup(sc); |
2080 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); | 2036 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); |
2081 | if (!ret) | 2037 | if (!ret) |
@@ -2094,8 +2050,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2094 | ath9k_ps_restore(sc); | 2050 | ath9k_ps_restore(sc); |
2095 | break; | 2051 | break; |
2096 | default: | 2052 | default: |
2097 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 2053 | ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); |
2098 | "Unknown AMPDU action\n"); | ||
2099 | } | 2054 | } |
2100 | 2055 | ||
2101 | local_bh_enable(); | 2056 | local_bh_enable(); |
@@ -2195,6 +2150,7 @@ struct ieee80211_ops ath9k_ops = { | |||
2195 | .start = ath9k_start, | 2150 | .start = ath9k_start, |
2196 | .stop = ath9k_stop, | 2151 | .stop = ath9k_stop, |
2197 | .add_interface = ath9k_add_interface, | 2152 | .add_interface = ath9k_add_interface, |
2153 | .change_interface = ath9k_change_interface, | ||
2198 | .remove_interface = ath9k_remove_interface, | 2154 | .remove_interface = ath9k_remove_interface, |
2199 | .config = ath9k_config, | 2155 | .config = ath9k_config, |
2200 | .configure_filter = ath9k_configure_filter, | 2156 | .configure_filter = ath9k_configure_filter, |