diff options
author | David S. Miller <davem@davemloft.net> | 2010-01-19 14:43:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-19 14:43:42 -0500 |
commit | 6373464288cab09bc641be301d8d30fc9f64ba71 (patch) | |
tree | c1bc92dc630aa15da2e12bc0d09c92169817a702 /drivers/net/wireless/ath/ath9k | |
parent | 6d955180b2f9ccff444df06265160868cabb289a (diff) | |
parent | 730dd70549e0ec755dd55615ba5cfc38a482a947 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
drivers/net/wireless/iwlwifi/iwl-core.h
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ahb.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 76 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 118 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.h | 32 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/gpio.c | 428 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 110 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 861 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.h | 34 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 1326 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/pci.c | 58 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/virtual.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 18 |
17 files changed, 1709 insertions, 1429 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 03a1106ad72..5774cea23a3 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -25,7 +25,7 @@ config ATH9K | |||
25 | 25 | ||
26 | config ATH9K_DEBUGFS | 26 | config ATH9K_DEBUGFS |
27 | bool "Atheros ath9k debugging" | 27 | bool "Atheros ath9k debugging" |
28 | depends on ATH9K | 28 | depends on ATH9K && DEBUG_FS |
29 | ---help--- | 29 | ---help--- |
30 | Say Y, if you need access to ath9k's statistics for | 30 | Say Y, if you need access to ath9k's statistics for |
31 | interrupts, rate control, etc. | 31 | interrupts, rate control, etc. |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4985b2b1b0a..6b50d5eb9ec 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -1,4 +1,6 @@ | |||
1 | ath9k-y += beacon.o \ | 1 | ath9k-y += beacon.o \ |
2 | gpio.o \ | ||
3 | init.o \ | ||
2 | main.o \ | 4 | main.o \ |
3 | recv.o \ | 5 | recv.o \ |
4 | xmit.o \ | 6 | xmit.o \ |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 329e6bc137a..9e62a569e81 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -121,16 +121,19 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
121 | sc->mem = mem; | 121 | sc->mem = mem; |
122 | sc->irq = irq; | 122 | sc->irq = irq; |
123 | 123 | ||
124 | ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); | 124 | /* Will be cleared in ath9k_start() */ |
125 | sc->sc_flags |= SC_OP_INVALID; | ||
126 | |||
127 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | ||
125 | if (ret) { | 128 | if (ret) { |
126 | dev_err(&pdev->dev, "failed to initialize device\n"); | 129 | dev_err(&pdev->dev, "request_irq failed\n"); |
127 | goto err_free_hw; | 130 | goto err_free_hw; |
128 | } | 131 | } |
129 | 132 | ||
130 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 133 | ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); |
131 | if (ret) { | 134 | if (ret) { |
132 | dev_err(&pdev->dev, "request_irq failed\n"); | 135 | dev_err(&pdev->dev, "failed to initialize device\n"); |
133 | goto err_detach; | 136 | goto err_irq; |
134 | } | 137 | } |
135 | 138 | ||
136 | ah = sc->sc_ah; | 139 | ah = sc->sc_ah; |
@@ -143,8 +146,8 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
143 | 146 | ||
144 | return 0; | 147 | return 0; |
145 | 148 | ||
146 | err_detach: | 149 | err_irq: |
147 | ath_detach(sc); | 150 | free_irq(irq, sc); |
148 | err_free_hw: | 151 | err_free_hw: |
149 | ieee80211_free_hw(hw); | 152 | ieee80211_free_hw(hw); |
150 | platform_set_drvdata(pdev, NULL); | 153 | platform_set_drvdata(pdev, NULL); |
@@ -161,8 +164,12 @@ static int ath_ahb_remove(struct platform_device *pdev) | |||
161 | if (hw) { | 164 | if (hw) { |
162 | struct ath_wiphy *aphy = hw->priv; | 165 | struct ath_wiphy *aphy = hw->priv; |
163 | struct ath_softc *sc = aphy->sc; | 166 | struct ath_softc *sc = aphy->sc; |
167 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
164 | 168 | ||
165 | ath_cleanup(sc); | 169 | ath9k_deinit_device(sc); |
170 | free_irq(sc->irq, sc); | ||
171 | ieee80211_free_hw(sc->hw); | ||
172 | ath_bus_cleanup(common); | ||
166 | platform_set_drvdata(pdev, NULL); | 173 | platform_set_drvdata(pdev, NULL); |
167 | } | 174 | } |
168 | 175 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 9f1f523e02e..bf3d4c4bfa5 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -33,11 +33,11 @@ struct ath_node; | |||
33 | 33 | ||
34 | /* Macro to expand scalars to 64-bit objects */ | 34 | /* Macro to expand scalars to 64-bit objects */ |
35 | 35 | ||
36 | #define ito64(x) (sizeof(x) == 8) ? \ | 36 | #define ito64(x) (sizeof(x) == 1) ? \ |
37 | (((unsigned long long int)(x)) & (0xff)) : \ | 37 | (((unsigned long long int)(x)) & (0xff)) : \ |
38 | (sizeof(x) == 16) ? \ | 38 | (sizeof(x) == 2) ? \ |
39 | (((unsigned long long int)(x)) & 0xffff) : \ | 39 | (((unsigned long long int)(x)) & 0xffff) : \ |
40 | ((sizeof(x) == 32) ? \ | 40 | ((sizeof(x) == 4) ? \ |
41 | (((unsigned long long int)(x)) & 0xffffffff) : \ | 41 | (((unsigned long long int)(x)) & 0xffffffff) : \ |
42 | (unsigned long long int)(x)) | 42 | (unsigned long long int)(x)) |
43 | 43 | ||
@@ -341,6 +341,12 @@ int ath_beaconq_config(struct ath_softc *sc); | |||
341 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ | 341 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ |
342 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | 342 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ |
343 | 343 | ||
344 | void ath_ani_calibrate(unsigned long data); | ||
345 | |||
346 | /**********/ | ||
347 | /* BTCOEX */ | ||
348 | /**********/ | ||
349 | |||
344 | /* Defines the BT AR_BT_COEX_WGHT used */ | 350 | /* Defines the BT AR_BT_COEX_WGHT used */ |
345 | enum ath_stomp_type { | 351 | enum ath_stomp_type { |
346 | ATH_BTCOEX_NO_STOMP, | 352 | ATH_BTCOEX_NO_STOMP, |
@@ -361,6 +367,10 @@ struct ath_btcoex { | |||
361 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | 367 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ |
362 | }; | 368 | }; |
363 | 369 | ||
370 | int ath_init_btcoex_timer(struct ath_softc *sc); | ||
371 | void ath9k_btcoex_timer_resume(struct ath_softc *sc); | ||
372 | void ath9k_btcoex_timer_pause(struct ath_softc *sc); | ||
373 | |||
364 | /********************/ | 374 | /********************/ |
365 | /* LED Control */ | 375 | /* LED Control */ |
366 | /********************/ | 376 | /********************/ |
@@ -385,6 +395,9 @@ struct ath_led { | |||
385 | bool registered; | 395 | bool registered; |
386 | }; | 396 | }; |
387 | 397 | ||
398 | void ath_init_leds(struct ath_softc *sc); | ||
399 | void ath_deinit_leds(struct ath_softc *sc); | ||
400 | |||
388 | /********************/ | 401 | /********************/ |
389 | /* Main driver core */ | 402 | /* Main driver core */ |
390 | /********************/ | 403 | /********************/ |
@@ -403,26 +416,28 @@ struct ath_led { | |||
403 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | 416 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ |
404 | #define ATH_RATE_DUMMY_MARKER 0 | 417 | #define ATH_RATE_DUMMY_MARKER 0 |
405 | 418 | ||
406 | #define SC_OP_INVALID BIT(0) | 419 | #define SC_OP_INVALID BIT(0) |
407 | #define SC_OP_BEACONS BIT(1) | 420 | #define SC_OP_BEACONS BIT(1) |
408 | #define SC_OP_RXAGGR BIT(2) | 421 | #define SC_OP_RXAGGR BIT(2) |
409 | #define SC_OP_TXAGGR BIT(3) | 422 | #define SC_OP_TXAGGR BIT(3) |
410 | #define SC_OP_FULL_RESET BIT(4) | 423 | #define SC_OP_FULL_RESET BIT(4) |
411 | #define SC_OP_PREAMBLE_SHORT BIT(5) | 424 | #define SC_OP_PREAMBLE_SHORT BIT(5) |
412 | #define SC_OP_PROTECT_ENABLE BIT(6) | 425 | #define SC_OP_PROTECT_ENABLE BIT(6) |
413 | #define SC_OP_RXFLUSH BIT(7) | 426 | #define SC_OP_RXFLUSH BIT(7) |
414 | #define SC_OP_LED_ASSOCIATED BIT(8) | 427 | #define SC_OP_LED_ASSOCIATED BIT(8) |
415 | #define SC_OP_WAIT_FOR_BEACON BIT(12) | 428 | #define SC_OP_LED_ON BIT(9) |
416 | #define SC_OP_LED_ON BIT(13) | 429 | #define SC_OP_SCANNING BIT(10) |
417 | #define SC_OP_SCANNING BIT(14) | 430 | #define SC_OP_TSF_RESET BIT(11) |
418 | #define SC_OP_TSF_RESET BIT(15) | 431 | #define SC_OP_BT_PRIORITY_DETECTED BIT(12) |
419 | #define SC_OP_WAIT_FOR_CAB BIT(16) | 432 | |
420 | #define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17) | 433 | /* Powersave flags */ |
421 | #define SC_OP_WAIT_FOR_TX_ACK BIT(18) | 434 | #define PS_WAIT_FOR_BEACON BIT(0) |
422 | #define SC_OP_BEACON_SYNC BIT(19) | 435 | #define PS_WAIT_FOR_CAB BIT(1) |
423 | #define SC_OP_BT_PRIORITY_DETECTED BIT(21) | 436 | #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) |
424 | #define SC_OP_NULLFUNC_COMPLETED BIT(22) | 437 | #define PS_WAIT_FOR_TX_ACK BIT(3) |
425 | #define SC_OP_PS_ENABLED BIT(23) | 438 | #define PS_BEACON_SYNC BIT(4) |
439 | #define PS_NULLFUNC_COMPLETED BIT(5) | ||
440 | #define PS_ENABLED BIT(6) | ||
426 | 441 | ||
427 | struct ath_wiphy; | 442 | struct ath_wiphy; |
428 | struct ath_rate_table; | 443 | struct ath_rate_table; |
@@ -458,6 +473,7 @@ struct ath_softc { | |||
458 | 473 | ||
459 | u32 intrstatus; | 474 | u32 intrstatus; |
460 | u32 sc_flags; /* SC_OP_* */ | 475 | u32 sc_flags; /* SC_OP_* */ |
476 | u16 ps_flags; /* PS_* */ | ||
461 | u16 curtxpow; | 477 | u16 curtxpow; |
462 | u8 nbcnvifs; | 478 | u8 nbcnvifs; |
463 | u16 nvifs; | 479 | u16 nvifs; |
@@ -508,6 +524,7 @@ struct ath_wiphy { | |||
508 | int chan_is_ht; | 524 | int chan_is_ht; |
509 | }; | 525 | }; |
510 | 526 | ||
527 | void ath9k_tasklet(unsigned long data); | ||
511 | int ath_reset(struct ath_softc *sc, bool retry_tx); | 528 | int ath_reset(struct ath_softc *sc, bool retry_tx); |
512 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); | 529 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); |
513 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); | 530 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); |
@@ -524,15 +541,15 @@ static inline void ath_bus_cleanup(struct ath_common *common) | |||
524 | } | 541 | } |
525 | 542 | ||
526 | extern struct ieee80211_ops ath9k_ops; | 543 | extern struct ieee80211_ops ath9k_ops; |
544 | extern int modparam_nohwcrypt; | ||
527 | 545 | ||
528 | irqreturn_t ath_isr(int irq, void *dev); | 546 | irqreturn_t ath_isr(int irq, void *dev); |
529 | void ath_cleanup(struct ath_softc *sc); | 547 | int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, |
530 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
531 | const struct ath_bus_ops *bus_ops); | 548 | const struct ath_bus_ops *bus_ops); |
532 | void ath_detach(struct ath_softc *sc); | 549 | void ath9k_deinit_device(struct ath_softc *sc); |
533 | const char *ath_mac_bb_name(u32 mac_bb_version); | 550 | const char *ath_mac_bb_name(u32 mac_bb_version); |
534 | const char *ath_rf_name(u16 rf_version); | 551 | const char *ath_rf_name(u16 rf_version); |
535 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | 552 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); |
536 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | 553 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, |
537 | struct ath9k_channel *ichan); | 554 | struct ath9k_channel *ichan); |
538 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); | 555 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); |
@@ -541,6 +558,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
541 | 558 | ||
542 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); | 559 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); |
543 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); | 560 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); |
561 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); | ||
544 | 562 | ||
545 | #ifdef CONFIG_PCI | 563 | #ifdef CONFIG_PCI |
546 | int ath_pci_init(void); | 564 | int ath_pci_init(void); |
@@ -582,4 +600,8 @@ void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); | |||
582 | void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); | 600 | void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); |
583 | 601 | ||
584 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); | 602 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); |
603 | |||
604 | void ath_start_rfkill_poll(struct ath_softc *sc); | ||
605 | extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); | ||
606 | |||
585 | #endif /* ATH9K_H */ | 607 | #endif /* ATH9K_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 1660ef17aaf..422454fe4ff 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -480,7 +480,8 @@ void ath_beacon_tasklet(unsigned long data) | |||
480 | sc->beacon.updateslot = COMMIT; /* commit next beacon */ | 480 | sc->beacon.updateslot = COMMIT; /* commit next beacon */ |
481 | sc->beacon.slotupdate = slot; | 481 | sc->beacon.slotupdate = slot; |
482 | } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { | 482 | } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { |
483 | ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime); | 483 | ah->slottime = sc->beacon.slottime; |
484 | ath9k_hw_init_global_settings(ah); | ||
484 | sc->beacon.updateslot = OK; | 485 | sc->beacon.updateslot = OK; |
485 | } | 486 | } |
486 | if (bfaddr != 0) { | 487 | if (bfaddr != 0) { |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 592f1b70f55..9489b6b25b5 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -580,6 +580,116 @@ static const struct file_operations fops_xmit = { | |||
580 | .owner = THIS_MODULE | 580 | .owner = THIS_MODULE |
581 | }; | 581 | }; |
582 | 582 | ||
583 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
584 | size_t count, loff_t *ppos) | ||
585 | { | ||
586 | #define PHY_ERR(s, p) \ | ||
587 | len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \ | ||
588 | sc->debug.stats.rxstats.phy_err_stats[p]); | ||
589 | |||
590 | struct ath_softc *sc = file->private_data; | ||
591 | char *buf; | ||
592 | unsigned int len = 0, size = 1152; | ||
593 | ssize_t retval = 0; | ||
594 | |||
595 | buf = kzalloc(size, GFP_KERNEL); | ||
596 | if (buf == NULL) | ||
597 | return 0; | ||
598 | |||
599 | len += snprintf(buf + len, size - len, | ||
600 | "%18s : %10u\n", "CRC ERR", | ||
601 | sc->debug.stats.rxstats.crc_err); | ||
602 | len += snprintf(buf + len, size - len, | ||
603 | "%18s : %10u\n", "DECRYPT CRC ERR", | ||
604 | sc->debug.stats.rxstats.decrypt_crc_err); | ||
605 | len += snprintf(buf + len, size - len, | ||
606 | "%18s : %10u\n", "PHY ERR", | ||
607 | sc->debug.stats.rxstats.phy_err); | ||
608 | len += snprintf(buf + len, size - len, | ||
609 | "%18s : %10u\n", "MIC ERR", | ||
610 | sc->debug.stats.rxstats.mic_err); | ||
611 | len += snprintf(buf + len, size - len, | ||
612 | "%18s : %10u\n", "PRE-DELIM CRC ERR", | ||
613 | sc->debug.stats.rxstats.pre_delim_crc_err); | ||
614 | len += snprintf(buf + len, size - len, | ||
615 | "%18s : %10u\n", "POST-DELIM CRC ERR", | ||
616 | sc->debug.stats.rxstats.post_delim_crc_err); | ||
617 | len += snprintf(buf + len, size - len, | ||
618 | "%18s : %10u\n", "DECRYPT BUSY ERR", | ||
619 | sc->debug.stats.rxstats.decrypt_busy_err); | ||
620 | |||
621 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); | ||
622 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); | ||
623 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); | ||
624 | PHY_ERR("RATE", ATH9K_PHYERR_RATE); | ||
625 | PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH); | ||
626 | PHY_ERR("RADAR", ATH9K_PHYERR_RADAR); | ||
627 | PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE); | ||
628 | PHY_ERR("TOR", ATH9K_PHYERR_TOR); | ||
629 | PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING); | ||
630 | PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); | ||
631 | PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); | ||
632 | PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); | ||
633 | PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP); | ||
634 | PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE); | ||
635 | PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART); | ||
636 | PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT); | ||
637 | PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING); | ||
638 | PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC); | ||
639 | PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL); | ||
640 | PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE); | ||
641 | PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART); | ||
642 | PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); | ||
643 | PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP); | ||
644 | PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR); | ||
645 | PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); | ||
646 | PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); | ||
647 | |||
648 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
649 | kfree(buf); | ||
650 | |||
651 | return retval; | ||
652 | |||
653 | #undef PHY_ERR | ||
654 | } | ||
655 | |||
656 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf) | ||
657 | { | ||
658 | #define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ | ||
659 | #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ | ||
660 | |||
661 | struct ath_desc *ds = bf->bf_desc; | ||
662 | u32 phyerr; | ||
663 | |||
664 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) | ||
665 | RX_STAT_INC(crc_err); | ||
666 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) | ||
667 | RX_STAT_INC(decrypt_crc_err); | ||
668 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) | ||
669 | RX_STAT_INC(mic_err); | ||
670 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE) | ||
671 | RX_STAT_INC(pre_delim_crc_err); | ||
672 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST) | ||
673 | RX_STAT_INC(post_delim_crc_err); | ||
674 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY) | ||
675 | RX_STAT_INC(decrypt_busy_err); | ||
676 | |||
677 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) { | ||
678 | RX_STAT_INC(phy_err); | ||
679 | phyerr = ds->ds_rxstat.rs_phyerr & 0x24; | ||
680 | RX_PHY_ERR_INC(phyerr); | ||
681 | } | ||
682 | |||
683 | #undef RX_STAT_INC | ||
684 | #undef RX_PHY_ERR_INC | ||
685 | } | ||
686 | |||
687 | static const struct file_operations fops_recv = { | ||
688 | .read = read_file_recv, | ||
689 | .open = ath9k_debugfs_open, | ||
690 | .owner = THIS_MODULE | ||
691 | }; | ||
692 | |||
583 | int ath9k_init_debug(struct ath_hw *ah) | 693 | int ath9k_init_debug(struct ath_hw *ah) |
584 | { | 694 | { |
585 | struct ath_common *common = ath9k_hw_common(ah); | 695 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -632,6 +742,13 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
632 | if (!sc->debug.debugfs_xmit) | 742 | if (!sc->debug.debugfs_xmit) |
633 | goto err; | 743 | goto err; |
634 | 744 | ||
745 | sc->debug.debugfs_recv = debugfs_create_file("recv", | ||
746 | S_IRUSR, | ||
747 | sc->debug.debugfs_phy, | ||
748 | sc, &fops_recv); | ||
749 | if (!sc->debug.debugfs_recv) | ||
750 | goto err; | ||
751 | |||
635 | return 0; | 752 | return 0; |
636 | err: | 753 | err: |
637 | ath9k_exit_debug(ah); | 754 | ath9k_exit_debug(ah); |
@@ -643,6 +760,7 @@ void ath9k_exit_debug(struct ath_hw *ah) | |||
643 | struct ath_common *common = ath9k_hw_common(ah); | 760 | struct ath_common *common = ath9k_hw_common(ah); |
644 | struct ath_softc *sc = (struct ath_softc *) common->priv; | 761 | struct ath_softc *sc = (struct ath_softc *) common->priv; |
645 | 762 | ||
763 | debugfs_remove(sc->debug.debugfs_recv); | ||
646 | debugfs_remove(sc->debug.debugfs_xmit); | 764 | debugfs_remove(sc->debug.debugfs_xmit); |
647 | debugfs_remove(sc->debug.debugfs_wiphy); | 765 | debugfs_remove(sc->debug.debugfs_wiphy); |
648 | debugfs_remove(sc->debug.debugfs_rcstat); | 766 | debugfs_remove(sc->debug.debugfs_rcstat); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 536663e3ee1..86780e68b31 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -116,10 +116,35 @@ struct ath_tx_stats { | |||
116 | u32 delim_underrun; | 116 | u32 delim_underrun; |
117 | }; | 117 | }; |
118 | 118 | ||
119 | /** | ||
120 | * struct ath_rx_stats - RX Statistics | ||
121 | * @crc_err: No. of frames with incorrect CRC value | ||
122 | * @decrypt_crc_err: No. of frames whose CRC check failed after | ||
123 | decryption process completed | ||
124 | * @phy_err: No. of frames whose reception failed because the PHY | ||
125 | encountered an error | ||
126 | * @mic_err: No. of frames with incorrect TKIP MIC verification failure | ||
127 | * @pre_delim_crc_err: Pre-Frame delimiter CRC error detections | ||
128 | * @post_delim_crc_err: Post-Frame delimiter CRC error detections | ||
129 | * @decrypt_busy_err: Decryption interruptions counter | ||
130 | * @phy_err_stats: Individual PHY error statistics | ||
131 | */ | ||
132 | struct ath_rx_stats { | ||
133 | u32 crc_err; | ||
134 | u32 decrypt_crc_err; | ||
135 | u32 phy_err; | ||
136 | u32 mic_err; | ||
137 | u32 pre_delim_crc_err; | ||
138 | u32 post_delim_crc_err; | ||
139 | u32 decrypt_busy_err; | ||
140 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; | ||
141 | }; | ||
142 | |||
119 | struct ath_stats { | 143 | struct ath_stats { |
120 | struct ath_interrupt_stats istats; | 144 | struct ath_interrupt_stats istats; |
121 | struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; | 145 | struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; |
122 | struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; | 146 | struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; |
147 | struct ath_rx_stats rxstats; | ||
123 | }; | 148 | }; |
124 | 149 | ||
125 | struct ath9k_debug { | 150 | struct ath9k_debug { |
@@ -130,6 +155,7 @@ struct ath9k_debug { | |||
130 | struct dentry *debugfs_rcstat; | 155 | struct dentry *debugfs_rcstat; |
131 | struct dentry *debugfs_wiphy; | 156 | struct dentry *debugfs_wiphy; |
132 | struct dentry *debugfs_xmit; | 157 | struct dentry *debugfs_xmit; |
158 | struct dentry *debugfs_recv; | ||
133 | struct ath_stats stats; | 159 | struct ath_stats stats; |
134 | }; | 160 | }; |
135 | 161 | ||
@@ -142,6 +168,7 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | |||
142 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); | 168 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); |
143 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | 169 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, |
144 | struct ath_buf *bf); | 170 | struct ath_buf *bf); |
171 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf); | ||
145 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 172 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, |
146 | int xretries, int retries, u8 per); | 173 | int xretries, int retries, u8 per); |
147 | 174 | ||
@@ -181,6 +208,11 @@ static inline void ath_debug_stat_tx(struct ath_softc *sc, | |||
181 | { | 208 | { |
182 | } | 209 | } |
183 | 210 | ||
211 | static inline void ath_debug_stat_rx(struct ath_softc *sc, | ||
212 | struct ath_buf *bf) | ||
213 | { | ||
214 | } | ||
215 | |||
184 | static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 216 | static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, |
185 | int xretries, int retries, u8 per) | 217 | int xretries, int retries, u8 per) |
186 | { | 218 | { |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c new file mode 100644 index 00000000000..e204bd25ff6 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -0,0 +1,428 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | |||
19 | /********************************/ | ||
20 | /* LED functions */ | ||
21 | /********************************/ | ||
22 | |||
23 | static void ath_led_blink_work(struct work_struct *work) | ||
24 | { | ||
25 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
26 | ath_led_blink_work.work); | ||
27 | |||
28 | if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) | ||
29 | return; | ||
30 | |||
31 | if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
32 | (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
33 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
34 | else | ||
35 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
36 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); | ||
37 | |||
38 | ieee80211_queue_delayed_work(sc->hw, | ||
39 | &sc->ath_led_blink_work, | ||
40 | (sc->sc_flags & SC_OP_LED_ON) ? | ||
41 | msecs_to_jiffies(sc->led_off_duration) : | ||
42 | msecs_to_jiffies(sc->led_on_duration)); | ||
43 | |||
44 | sc->led_on_duration = sc->led_on_cnt ? | ||
45 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : | ||
46 | ATH_LED_ON_DURATION_IDLE; | ||
47 | sc->led_off_duration = sc->led_off_cnt ? | ||
48 | max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) : | ||
49 | ATH_LED_OFF_DURATION_IDLE; | ||
50 | sc->led_on_cnt = sc->led_off_cnt = 0; | ||
51 | if (sc->sc_flags & SC_OP_LED_ON) | ||
52 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
53 | else | ||
54 | sc->sc_flags |= SC_OP_LED_ON; | ||
55 | } | ||
56 | |||
57 | static void ath_led_brightness(struct led_classdev *led_cdev, | ||
58 | enum led_brightness brightness) | ||
59 | { | ||
60 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | ||
61 | struct ath_softc *sc = led->sc; | ||
62 | |||
63 | switch (brightness) { | ||
64 | case LED_OFF: | ||
65 | if (led->led_type == ATH_LED_ASSOC || | ||
66 | led->led_type == ATH_LED_RADIO) { | ||
67 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
68 | (led->led_type == ATH_LED_RADIO)); | ||
69 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
70 | if (led->led_type == ATH_LED_RADIO) | ||
71 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
72 | } else { | ||
73 | sc->led_off_cnt++; | ||
74 | } | ||
75 | break; | ||
76 | case LED_FULL: | ||
77 | if (led->led_type == ATH_LED_ASSOC) { | ||
78 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; | ||
79 | ieee80211_queue_delayed_work(sc->hw, | ||
80 | &sc->ath_led_blink_work, 0); | ||
81 | } else if (led->led_type == ATH_LED_RADIO) { | ||
82 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
83 | sc->sc_flags |= SC_OP_LED_ON; | ||
84 | } else { | ||
85 | sc->led_on_cnt++; | ||
86 | } | ||
87 | break; | ||
88 | default: | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | static int ath_register_led(struct ath_softc *sc, struct ath_led *led, | ||
94 | char *trigger) | ||
95 | { | ||
96 | int ret; | ||
97 | |||
98 | led->sc = sc; | ||
99 | led->led_cdev.name = led->name; | ||
100 | led->led_cdev.default_trigger = trigger; | ||
101 | led->led_cdev.brightness_set = ath_led_brightness; | ||
102 | |||
103 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); | ||
104 | if (ret) | ||
105 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | ||
106 | "Failed to register led:%s", led->name); | ||
107 | else | ||
108 | led->registered = 1; | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static void ath_unregister_led(struct ath_led *led) | ||
113 | { | ||
114 | if (led->registered) { | ||
115 | led_classdev_unregister(&led->led_cdev); | ||
116 | led->registered = 0; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | void ath_deinit_leds(struct ath_softc *sc) | ||
121 | { | ||
122 | ath_unregister_led(&sc->assoc_led); | ||
123 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
124 | ath_unregister_led(&sc->tx_led); | ||
125 | ath_unregister_led(&sc->rx_led); | ||
126 | ath_unregister_led(&sc->radio_led); | ||
127 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
128 | } | ||
129 | |||
130 | void ath_init_leds(struct ath_softc *sc) | ||
131 | { | ||
132 | char *trigger; | ||
133 | int ret; | ||
134 | |||
135 | if (AR_SREV_9287(sc->sc_ah)) | ||
136 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; | ||
137 | else | ||
138 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | ||
139 | |||
140 | /* Configure gpio 1 for output */ | ||
141 | ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, | ||
142 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
143 | /* LED off, active low */ | ||
144 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
145 | |||
146 | INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); | ||
147 | |||
148 | trigger = ieee80211_get_radio_led_name(sc->hw); | ||
149 | snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), | ||
150 | "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); | ||
151 | ret = ath_register_led(sc, &sc->radio_led, trigger); | ||
152 | sc->radio_led.led_type = ATH_LED_RADIO; | ||
153 | if (ret) | ||
154 | goto fail; | ||
155 | |||
156 | trigger = ieee80211_get_assoc_led_name(sc->hw); | ||
157 | snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), | ||
158 | "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); | ||
159 | ret = ath_register_led(sc, &sc->assoc_led, trigger); | ||
160 | sc->assoc_led.led_type = ATH_LED_ASSOC; | ||
161 | if (ret) | ||
162 | goto fail; | ||
163 | |||
164 | trigger = ieee80211_get_tx_led_name(sc->hw); | ||
165 | snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), | ||
166 | "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); | ||
167 | ret = ath_register_led(sc, &sc->tx_led, trigger); | ||
168 | sc->tx_led.led_type = ATH_LED_TX; | ||
169 | if (ret) | ||
170 | goto fail; | ||
171 | |||
172 | trigger = ieee80211_get_rx_led_name(sc->hw); | ||
173 | snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), | ||
174 | "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); | ||
175 | ret = ath_register_led(sc, &sc->rx_led, trigger); | ||
176 | sc->rx_led.led_type = ATH_LED_RX; | ||
177 | if (ret) | ||
178 | goto fail; | ||
179 | |||
180 | return; | ||
181 | |||
182 | fail: | ||
183 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | ||
184 | ath_deinit_leds(sc); | ||
185 | } | ||
186 | |||
187 | /*******************/ | ||
188 | /* Rfkill */ | ||
189 | /*******************/ | ||
190 | |||
191 | static bool ath_is_rfkill_set(struct ath_softc *sc) | ||
192 | { | ||
193 | struct ath_hw *ah = sc->sc_ah; | ||
194 | |||
195 | return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) == | ||
196 | ah->rfkill_polarity; | ||
197 | } | ||
198 | |||
199 | void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) | ||
200 | { | ||
201 | struct ath_wiphy *aphy = hw->priv; | ||
202 | struct ath_softc *sc = aphy->sc; | ||
203 | bool blocked = !!ath_is_rfkill_set(sc); | ||
204 | |||
205 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); | ||
206 | } | ||
207 | |||
208 | void ath_start_rfkill_poll(struct ath_softc *sc) | ||
209 | { | ||
210 | struct ath_hw *ah = sc->sc_ah; | ||
211 | |||
212 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
213 | wiphy_rfkill_start_polling(sc->hw->wiphy); | ||
214 | } | ||
215 | |||
216 | /******************/ | ||
217 | /* BTCOEX */ | ||
218 | /******************/ | ||
219 | |||
220 | /* | ||
221 | * Detects if there is any priority bt traffic | ||
222 | */ | ||
223 | static void ath_detect_bt_priority(struct ath_softc *sc) | ||
224 | { | ||
225 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
226 | struct ath_hw *ah = sc->sc_ah; | ||
227 | |||
228 | if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio)) | ||
229 | btcoex->bt_priority_cnt++; | ||
230 | |||
231 | if (time_after(jiffies, btcoex->bt_priority_time + | ||
232 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | ||
233 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | ||
234 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, | ||
235 | "BT priority traffic detected"); | ||
236 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | ||
237 | } else { | ||
238 | sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; | ||
239 | } | ||
240 | |||
241 | btcoex->bt_priority_cnt = 0; | ||
242 | btcoex->bt_priority_time = jiffies; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * Configures appropriate weight based on stomp type. | ||
248 | */ | ||
249 | static void ath9k_btcoex_bt_stomp(struct ath_softc *sc, | ||
250 | enum ath_stomp_type stomp_type) | ||
251 | { | ||
252 | struct ath_hw *ah = sc->sc_ah; | ||
253 | |||
254 | switch (stomp_type) { | ||
255 | case ATH_BTCOEX_STOMP_ALL: | ||
256 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
257 | AR_STOMP_ALL_WLAN_WGHT); | ||
258 | break; | ||
259 | case ATH_BTCOEX_STOMP_LOW: | ||
260 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
261 | AR_STOMP_LOW_WLAN_WGHT); | ||
262 | break; | ||
263 | case ATH_BTCOEX_STOMP_NONE: | ||
264 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
265 | AR_STOMP_NONE_WLAN_WGHT); | ||
266 | break; | ||
267 | default: | ||
268 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
269 | "Invalid Stomptype\n"); | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | ath9k_hw_btcoex_enable(ah); | ||
274 | } | ||
275 | |||
276 | static void ath9k_gen_timer_start(struct ath_hw *ah, | ||
277 | struct ath_gen_timer *timer, | ||
278 | u32 timer_next, | ||
279 | u32 timer_period) | ||
280 | { | ||
281 | struct ath_common *common = ath9k_hw_common(ah); | ||
282 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
283 | |||
284 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | ||
285 | |||
286 | if ((sc->imask & ATH9K_INT_GENTIMER) == 0) { | ||
287 | ath9k_hw_set_interrupts(ah, 0); | ||
288 | sc->imask |= ATH9K_INT_GENTIMER; | ||
289 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | ||
294 | { | ||
295 | struct ath_common *common = ath9k_hw_common(ah); | ||
296 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
297 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | ||
298 | |||
299 | ath9k_hw_gen_timer_stop(ah, timer); | ||
300 | |||
301 | /* if no timer is enabled, turn off interrupt mask */ | ||
302 | if (timer_table->timer_mask.val == 0) { | ||
303 | ath9k_hw_set_interrupts(ah, 0); | ||
304 | sc->imask &= ~ATH9K_INT_GENTIMER; | ||
305 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
306 | } | ||
307 | } | ||
308 | |||
309 | /* | ||
310 | * This is the master bt coex timer which runs for every | ||
311 | * 45ms, bt traffic will be given priority during 55% of this | ||
312 | * period while wlan gets remaining 45% | ||
313 | */ | ||
314 | static void ath_btcoex_period_timer(unsigned long data) | ||
315 | { | ||
316 | struct ath_softc *sc = (struct ath_softc *) data; | ||
317 | struct ath_hw *ah = sc->sc_ah; | ||
318 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
319 | |||
320 | ath_detect_bt_priority(sc); | ||
321 | |||
322 | spin_lock_bh(&btcoex->btcoex_lock); | ||
323 | |||
324 | ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type); | ||
325 | |||
326 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
327 | |||
328 | if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) { | ||
329 | if (btcoex->hw_timer_enabled) | ||
330 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
331 | |||
332 | ath9k_gen_timer_start(ah, | ||
333 | btcoex->no_stomp_timer, | ||
334 | (ath9k_hw_gettsf32(ah) + | ||
335 | btcoex->btcoex_no_stomp), | ||
336 | btcoex->btcoex_no_stomp * 10); | ||
337 | btcoex->hw_timer_enabled = true; | ||
338 | } | ||
339 | |||
340 | mod_timer(&btcoex->period_timer, jiffies + | ||
341 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * Generic tsf based hw timer which configures weight | ||
346 | * registers to time slice between wlan and bt traffic | ||
347 | */ | ||
348 | static void ath_btcoex_no_stomp_timer(void *arg) | ||
349 | { | ||
350 | struct ath_softc *sc = (struct ath_softc *)arg; | ||
351 | struct ath_hw *ah = sc->sc_ah; | ||
352 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
353 | |||
354 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
355 | "no stomp timer running \n"); | ||
356 | |||
357 | spin_lock_bh(&btcoex->btcoex_lock); | ||
358 | |||
359 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW) | ||
360 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); | ||
361 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | ||
362 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); | ||
363 | |||
364 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
365 | } | ||
366 | |||
367 | int ath_init_btcoex_timer(struct ath_softc *sc) | ||
368 | { | ||
369 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
370 | |||
371 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; | ||
372 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | ||
373 | btcoex->btcoex_period / 100; | ||
374 | |||
375 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | ||
376 | (unsigned long) sc); | ||
377 | |||
378 | spin_lock_init(&btcoex->btcoex_lock); | ||
379 | |||
380 | btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah, | ||
381 | ath_btcoex_no_stomp_timer, | ||
382 | ath_btcoex_no_stomp_timer, | ||
383 | (void *) sc, AR_FIRST_NDP_TIMER); | ||
384 | |||
385 | if (!btcoex->no_stomp_timer) | ||
386 | return -ENOMEM; | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | /* | ||
392 | * (Re)start btcoex timers | ||
393 | */ | ||
394 | void ath9k_btcoex_timer_resume(struct ath_softc *sc) | ||
395 | { | ||
396 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
397 | struct ath_hw *ah = sc->sc_ah; | ||
398 | |||
399 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
400 | "Starting btcoex timers"); | ||
401 | |||
402 | /* make sure duty cycle timer is also stopped when resuming */ | ||
403 | if (btcoex->hw_timer_enabled) | ||
404 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
405 | |||
406 | btcoex->bt_priority_cnt = 0; | ||
407 | btcoex->bt_priority_time = jiffies; | ||
408 | sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; | ||
409 | |||
410 | mod_timer(&btcoex->period_timer, jiffies); | ||
411 | } | ||
412 | |||
413 | |||
414 | /* | ||
415 | * Pause btcoex timer and bt duty cycle timer | ||
416 | */ | ||
417 | void ath9k_btcoex_timer_pause(struct ath_softc *sc) | ||
418 | { | ||
419 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
420 | struct ath_hw *ah = sc->sc_ah; | ||
421 | |||
422 | del_timer_sync(&btcoex->period_timer); | ||
423 | |||
424 | if (btcoex->hw_timer_enabled) | ||
425 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
426 | |||
427 | btcoex->hw_timer_enabled = false; | ||
428 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9474f9f6d40..0b1dd10f1d8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -52,28 +52,6 @@ module_exit(ath9k_exit); | |||
52 | /* Helper Functions */ | 52 | /* Helper Functions */ |
53 | /********************/ | 53 | /********************/ |
54 | 54 | ||
55 | static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks) | ||
56 | { | ||
57 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
58 | |||
59 | if (!ah->curchan) /* should really check for CCK instead */ | ||
60 | return clks / ATH9K_CLOCK_RATE_CCK; | ||
61 | if (conf->channel->band == IEEE80211_BAND_2GHZ) | ||
62 | return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM; | ||
63 | |||
64 | return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
65 | } | ||
66 | |||
67 | static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks) | ||
68 | { | ||
69 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
70 | |||
71 | if (conf_is_ht40(conf)) | ||
72 | return ath9k_hw_mac_usec(ah, clks) / 2; | ||
73 | else | ||
74 | return ath9k_hw_mac_usec(ah, clks); | ||
75 | } | ||
76 | |||
77 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) | 55 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) |
78 | { | 56 | { |
79 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | 57 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
@@ -413,8 +391,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
413 | ah->beacon_interval = 100; | 391 | ah->beacon_interval = 100; |
414 | ah->enable_32kHz_clock = DONT_USE_32KHZ; | 392 | ah->enable_32kHz_clock = DONT_USE_32KHZ; |
415 | ah->slottime = (u32) -1; | 393 | ah->slottime = (u32) -1; |
416 | ah->acktimeout = (u32) -1; | ||
417 | ah->ctstimeout = (u32) -1; | ||
418 | ah->globaltxtimeout = (u32) -1; | 394 | ah->globaltxtimeout = (u32) -1; |
419 | ah->power_mode = ATH9K_PM_UNDEFINED; | 395 | ah->power_mode = ATH9K_PM_UNDEFINED; |
420 | } | 396 | } |
@@ -1180,34 +1156,25 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
1180 | } | 1156 | } |
1181 | } | 1157 | } |
1182 | 1158 | ||
1183 | static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) | 1159 | static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) |
1184 | { | 1160 | { |
1185 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { | 1161 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1186 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | 1162 | val = min(val, (u32) 0xFFFF); |
1187 | "bad ack timeout %u\n", us); | 1163 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val); |
1188 | ah->acktimeout = (u32) -1; | ||
1189 | return false; | ||
1190 | } else { | ||
1191 | REG_RMW_FIELD(ah, AR_TIME_OUT, | ||
1192 | AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us)); | ||
1193 | ah->acktimeout = us; | ||
1194 | return true; | ||
1195 | } | ||
1196 | } | 1164 | } |
1197 | 1165 | ||
1198 | static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) | 1166 | static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) |
1199 | { | 1167 | { |
1200 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { | 1168 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1201 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | 1169 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK)); |
1202 | "bad cts timeout %u\n", us); | 1170 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val); |
1203 | ah->ctstimeout = (u32) -1; | 1171 | } |
1204 | return false; | 1172 | |
1205 | } else { | 1173 | static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) |
1206 | REG_RMW_FIELD(ah, AR_TIME_OUT, | 1174 | { |
1207 | AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); | 1175 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1208 | ah->ctstimeout = us; | 1176 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS)); |
1209 | return true; | 1177 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val); |
1210 | } | ||
1211 | } | 1178 | } |
1212 | 1179 | ||
1213 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | 1180 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) |
@@ -1224,25 +1191,37 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | |||
1224 | } | 1191 | } |
1225 | } | 1192 | } |
1226 | 1193 | ||
1227 | static void ath9k_hw_init_user_settings(struct ath_hw *ah) | 1194 | void ath9k_hw_init_global_settings(struct ath_hw *ah) |
1228 | { | 1195 | { |
1196 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
1197 | int acktimeout; | ||
1198 | int slottime; | ||
1199 | int sifstime; | ||
1200 | |||
1229 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", | 1201 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", |
1230 | ah->misc_mode); | 1202 | ah->misc_mode); |
1231 | 1203 | ||
1232 | if (ah->misc_mode != 0) | 1204 | if (ah->misc_mode != 0) |
1233 | REG_WRITE(ah, AR_PCU_MISC, | 1205 | REG_WRITE(ah, AR_PCU_MISC, |
1234 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); | 1206 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); |
1235 | if (ah->slottime != (u32) -1) | 1207 | |
1236 | ath9k_hw_setslottime(ah, ah->slottime); | 1208 | if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) |
1237 | if (ah->acktimeout != (u32) -1) | 1209 | sifstime = 16; |
1238 | ath9k_hw_set_ack_timeout(ah, ah->acktimeout); | 1210 | else |
1239 | if (ah->ctstimeout != (u32) -1) | 1211 | sifstime = 10; |
1240 | ath9k_hw_set_cts_timeout(ah, ah->ctstimeout); | 1212 | |
1213 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ | ||
1214 | slottime = ah->slottime + 3 * ah->coverage_class; | ||
1215 | acktimeout = slottime + sifstime; | ||
1216 | ath9k_hw_setslottime(ah, slottime); | ||
1217 | ath9k_hw_set_ack_timeout(ah, acktimeout); | ||
1218 | ath9k_hw_set_cts_timeout(ah, acktimeout); | ||
1241 | if (ah->globaltxtimeout != (u32) -1) | 1219 | if (ah->globaltxtimeout != (u32) -1) |
1242 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); | 1220 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); |
1243 | } | 1221 | } |
1222 | EXPORT_SYMBOL(ath9k_hw_init_global_settings); | ||
1244 | 1223 | ||
1245 | void ath9k_hw_detach(struct ath_hw *ah) | 1224 | void ath9k_hw_deinit(struct ath_hw *ah) |
1246 | { | 1225 | { |
1247 | struct ath_common *common = ath9k_hw_common(ah); | 1226 | struct ath_common *common = ath9k_hw_common(ah); |
1248 | 1227 | ||
@@ -1260,7 +1239,7 @@ free_hw: | |||
1260 | kfree(ah); | 1239 | kfree(ah); |
1261 | ah = NULL; | 1240 | ah = NULL; |
1262 | } | 1241 | } |
1263 | EXPORT_SYMBOL(ath9k_hw_detach); | 1242 | EXPORT_SYMBOL(ath9k_hw_deinit); |
1264 | 1243 | ||
1265 | /*******/ | 1244 | /*******/ |
1266 | /* INI */ | 1245 | /* INI */ |
@@ -2061,7 +2040,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2061 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | 2040 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) |
2062 | ath9k_enable_rfkill(ah); | 2041 | ath9k_enable_rfkill(ah); |
2063 | 2042 | ||
2064 | ath9k_hw_init_user_settings(ah); | 2043 | ath9k_hw_init_global_settings(ah); |
2065 | 2044 | ||
2066 | if (AR_SREV_9287_12_OR_LATER(ah)) { | 2045 | if (AR_SREV_9287_12_OR_LATER(ah)) { |
2067 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, | 2046 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, |
@@ -3658,21 +3637,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp) | |||
3658 | } | 3637 | } |
3659 | EXPORT_SYMBOL(ath9k_hw_extend_tsf); | 3638 | EXPORT_SYMBOL(ath9k_hw_extend_tsf); |
3660 | 3639 | ||
3661 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) | ||
3662 | { | ||
3663 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { | ||
3664 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | ||
3665 | "bad slot time %u\n", us); | ||
3666 | ah->slottime = (u32) -1; | ||
3667 | return false; | ||
3668 | } else { | ||
3669 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us)); | ||
3670 | ah->slottime = us; | ||
3671 | return true; | ||
3672 | } | ||
3673 | } | ||
3674 | EXPORT_SYMBOL(ath9k_hw_setslottime); | ||
3675 | |||
3676 | void ath9k_hw_set11nmac2040(struct ath_hw *ah) | 3640 | void ath9k_hw_set11nmac2040(struct ath_hw *ah) |
3677 | { | 3641 | { |
3678 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | 3642 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 8849450dc59..ab1f1981d85 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -551,10 +551,9 @@ struct ath_hw { | |||
551 | u32 *bank6Temp; | 551 | u32 *bank6Temp; |
552 | 552 | ||
553 | int16_t txpower_indexoffset; | 553 | int16_t txpower_indexoffset; |
554 | int coverage_class; | ||
554 | u32 beacon_interval; | 555 | u32 beacon_interval; |
555 | u32 slottime; | 556 | u32 slottime; |
556 | u32 acktimeout; | ||
557 | u32 ctstimeout; | ||
558 | u32 globaltxtimeout; | 557 | u32 globaltxtimeout; |
559 | 558 | ||
560 | /* ANI */ | 559 | /* ANI */ |
@@ -616,7 +615,7 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah) | |||
616 | 615 | ||
617 | /* Initialization, Detach, Reset */ | 616 | /* Initialization, Detach, Reset */ |
618 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); | 617 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); |
619 | void ath9k_hw_detach(struct ath_hw *ah); | 618 | void ath9k_hw_deinit(struct ath_hw *ah); |
620 | int ath9k_hw_init(struct ath_hw *ah); | 619 | int ath9k_hw_init(struct ath_hw *ah); |
621 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 620 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
622 | bool bChannelChange); | 621 | bool bChannelChange); |
@@ -668,7 +667,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | |||
668 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | 667 | void ath9k_hw_reset_tsf(struct ath_hw *ah); |
669 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | 668 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); |
670 | u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp); | 669 | u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp); |
671 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); | 670 | void ath9k_hw_init_global_settings(struct ath_hw *ah); |
672 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); | 671 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); |
673 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | 672 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); |
674 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | 673 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c new file mode 100644 index 00000000000..5f78d7a5ff2 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -0,0 +1,861 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | |||
19 | static char *dev_info = "ath9k"; | ||
20 | |||
21 | MODULE_AUTHOR("Atheros Communications"); | ||
22 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | ||
23 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | ||
24 | MODULE_LICENSE("Dual BSD/GPL"); | ||
25 | |||
26 | static unsigned int ath9k_debug = ATH_DBG_DEFAULT; | ||
27 | module_param_named(debug, ath9k_debug, uint, 0); | ||
28 | MODULE_PARM_DESC(debug, "Debugging mask"); | ||
29 | |||
30 | int modparam_nohwcrypt; | ||
31 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | ||
32 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | ||
33 | |||
34 | /* We use the hw_value as an index into our private channel structure */ | ||
35 | |||
36 | #define CHAN2G(_freq, _idx) { \ | ||
37 | .center_freq = (_freq), \ | ||
38 | .hw_value = (_idx), \ | ||
39 | .max_power = 20, \ | ||
40 | } | ||
41 | |||
42 | #define CHAN5G(_freq, _idx) { \ | ||
43 | .band = IEEE80211_BAND_5GHZ, \ | ||
44 | .center_freq = (_freq), \ | ||
45 | .hw_value = (_idx), \ | ||
46 | .max_power = 20, \ | ||
47 | } | ||
48 | |||
49 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
50 | * on 5 MHz steps, we support the channels which we know | ||
51 | * we have calibration data for all cards though to make | ||
52 | * this static */ | ||
53 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
54 | CHAN2G(2412, 0), /* Channel 1 */ | ||
55 | CHAN2G(2417, 1), /* Channel 2 */ | ||
56 | CHAN2G(2422, 2), /* Channel 3 */ | ||
57 | CHAN2G(2427, 3), /* Channel 4 */ | ||
58 | CHAN2G(2432, 4), /* Channel 5 */ | ||
59 | CHAN2G(2437, 5), /* Channel 6 */ | ||
60 | CHAN2G(2442, 6), /* Channel 7 */ | ||
61 | CHAN2G(2447, 7), /* Channel 8 */ | ||
62 | CHAN2G(2452, 8), /* Channel 9 */ | ||
63 | CHAN2G(2457, 9), /* Channel 10 */ | ||
64 | CHAN2G(2462, 10), /* Channel 11 */ | ||
65 | CHAN2G(2467, 11), /* Channel 12 */ | ||
66 | CHAN2G(2472, 12), /* Channel 13 */ | ||
67 | CHAN2G(2484, 13), /* Channel 14 */ | ||
68 | }; | ||
69 | |||
70 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
71 | * on 5 MHz steps, we support the channels which we know | ||
72 | * we have calibration data for all cards though to make | ||
73 | * this static */ | ||
74 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
75 | /* _We_ call this UNII 1 */ | ||
76 | CHAN5G(5180, 14), /* Channel 36 */ | ||
77 | CHAN5G(5200, 15), /* Channel 40 */ | ||
78 | CHAN5G(5220, 16), /* Channel 44 */ | ||
79 | CHAN5G(5240, 17), /* Channel 48 */ | ||
80 | /* _We_ call this UNII 2 */ | ||
81 | CHAN5G(5260, 18), /* Channel 52 */ | ||
82 | CHAN5G(5280, 19), /* Channel 56 */ | ||
83 | CHAN5G(5300, 20), /* Channel 60 */ | ||
84 | CHAN5G(5320, 21), /* Channel 64 */ | ||
85 | /* _We_ call this "Middle band" */ | ||
86 | CHAN5G(5500, 22), /* Channel 100 */ | ||
87 | CHAN5G(5520, 23), /* Channel 104 */ | ||
88 | CHAN5G(5540, 24), /* Channel 108 */ | ||
89 | CHAN5G(5560, 25), /* Channel 112 */ | ||
90 | CHAN5G(5580, 26), /* Channel 116 */ | ||
91 | CHAN5G(5600, 27), /* Channel 120 */ | ||
92 | CHAN5G(5620, 28), /* Channel 124 */ | ||
93 | CHAN5G(5640, 29), /* Channel 128 */ | ||
94 | CHAN5G(5660, 30), /* Channel 132 */ | ||
95 | CHAN5G(5680, 31), /* Channel 136 */ | ||
96 | CHAN5G(5700, 32), /* Channel 140 */ | ||
97 | /* _We_ call this UNII 3 */ | ||
98 | CHAN5G(5745, 33), /* Channel 149 */ | ||
99 | CHAN5G(5765, 34), /* Channel 153 */ | ||
100 | CHAN5G(5785, 35), /* Channel 157 */ | ||
101 | CHAN5G(5805, 36), /* Channel 161 */ | ||
102 | CHAN5G(5825, 37), /* Channel 165 */ | ||
103 | }; | ||
104 | |||
105 | /* Atheros hardware rate code addition for short premble */ | ||
106 | #define SHPCHECK(__hw_rate, __flags) \ | ||
107 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) | ||
108 | |||
109 | #define RATE(_bitrate, _hw_rate, _flags) { \ | ||
110 | .bitrate = (_bitrate), \ | ||
111 | .flags = (_flags), \ | ||
112 | .hw_value = (_hw_rate), \ | ||
113 | .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ | ||
114 | } | ||
115 | |||
116 | static struct ieee80211_rate ath9k_legacy_rates[] = { | ||
117 | RATE(10, 0x1b, 0), | ||
118 | RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), | ||
119 | RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), | ||
120 | RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), | ||
121 | RATE(60, 0x0b, 0), | ||
122 | RATE(90, 0x0f, 0), | ||
123 | RATE(120, 0x0a, 0), | ||
124 | RATE(180, 0x0e, 0), | ||
125 | RATE(240, 0x09, 0), | ||
126 | RATE(360, 0x0d, 0), | ||
127 | RATE(480, 0x08, 0), | ||
128 | RATE(540, 0x0c, 0), | ||
129 | }; | ||
130 | |||
131 | static void ath9k_deinit_softc(struct ath_softc *sc); | ||
132 | |||
133 | /* | ||
134 | * Read and write, they both share the same lock. We do this to serialize | ||
135 | * reads and writes on Atheros 802.11n PCI devices only. This is required | ||
136 | * as the FIFO on these devices can only accept sanely 2 requests. | ||
137 | */ | ||
138 | |||
139 | static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) | ||
140 | { | ||
141 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
142 | struct ath_common *common = ath9k_hw_common(ah); | ||
143 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
144 | |||
145 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
146 | unsigned long flags; | ||
147 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
148 | iowrite32(val, sc->mem + reg_offset); | ||
149 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
150 | } else | ||
151 | iowrite32(val, sc->mem + reg_offset); | ||
152 | } | ||
153 | |||
154 | static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | ||
155 | { | ||
156 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
157 | struct ath_common *common = ath9k_hw_common(ah); | ||
158 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
159 | u32 val; | ||
160 | |||
161 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
162 | unsigned long flags; | ||
163 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
164 | val = ioread32(sc->mem + reg_offset); | ||
165 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
166 | } else | ||
167 | val = ioread32(sc->mem + reg_offset); | ||
168 | return val; | ||
169 | } | ||
170 | |||
171 | static const struct ath_ops ath9k_common_ops = { | ||
172 | .read = ath9k_ioread32, | ||
173 | .write = ath9k_iowrite32, | ||
174 | }; | ||
175 | |||
176 | /**************************/ | ||
177 | /* Initialization */ | ||
178 | /**************************/ | ||
179 | |||
180 | static void setup_ht_cap(struct ath_softc *sc, | ||
181 | struct ieee80211_sta_ht_cap *ht_info) | ||
182 | { | ||
183 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
184 | u8 tx_streams, rx_streams; | ||
185 | |||
186 | ht_info->ht_supported = true; | ||
187 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
188 | IEEE80211_HT_CAP_SM_PS | | ||
189 | IEEE80211_HT_CAP_SGI_40 | | ||
190 | IEEE80211_HT_CAP_DSSSCCK40; | ||
191 | |||
192 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
193 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
194 | |||
195 | /* set up supported mcs set */ | ||
196 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
197 | tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? | ||
198 | 1 : 2; | ||
199 | rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? | ||
200 | 1 : 2; | ||
201 | |||
202 | if (tx_streams != rx_streams) { | ||
203 | ath_print(common, ATH_DBG_CONFIG, | ||
204 | "TX streams %d, RX streams: %d\n", | ||
205 | tx_streams, rx_streams); | ||
206 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
207 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | ||
208 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
209 | } | ||
210 | |||
211 | ht_info->mcs.rx_mask[0] = 0xff; | ||
212 | if (rx_streams >= 2) | ||
213 | ht_info->mcs.rx_mask[1] = 0xff; | ||
214 | |||
215 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
216 | } | ||
217 | |||
218 | static int ath9k_reg_notifier(struct wiphy *wiphy, | ||
219 | struct regulatory_request *request) | ||
220 | { | ||
221 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
222 | struct ath_wiphy *aphy = hw->priv; | ||
223 | struct ath_softc *sc = aphy->sc; | ||
224 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); | ||
225 | |||
226 | return ath_reg_notifier_apply(wiphy, request, reg); | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * This function will allocate both the DMA descriptor structure, and the | ||
231 | * buffers it contains. These are used to contain the descriptors used | ||
232 | * by the system. | ||
233 | */ | ||
234 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | ||
235 | struct list_head *head, const char *name, | ||
236 | int nbuf, int ndesc) | ||
237 | { | ||
238 | #define DS2PHYS(_dd, _ds) \ | ||
239 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) | ||
240 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) | ||
241 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) | ||
242 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
243 | struct ath_desc *ds; | ||
244 | struct ath_buf *bf; | ||
245 | int i, bsize, error; | ||
246 | |||
247 | ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | ||
248 | name, nbuf, ndesc); | ||
249 | |||
250 | INIT_LIST_HEAD(head); | ||
251 | /* ath_desc must be a multiple of DWORDs */ | ||
252 | if ((sizeof(struct ath_desc) % 4) != 0) { | ||
253 | ath_print(common, ATH_DBG_FATAL, | ||
254 | "ath_desc not DWORD aligned\n"); | ||
255 | BUG_ON((sizeof(struct ath_desc) % 4) != 0); | ||
256 | error = -ENOMEM; | ||
257 | goto fail; | ||
258 | } | ||
259 | |||
260 | dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; | ||
261 | |||
262 | /* | ||
263 | * Need additional DMA memory because we can't use | ||
264 | * descriptors that cross the 4K page boundary. Assume | ||
265 | * one skipped descriptor per 4K page. | ||
266 | */ | ||
267 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
268 | u32 ndesc_skipped = | ||
269 | ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); | ||
270 | u32 dma_len; | ||
271 | |||
272 | while (ndesc_skipped) { | ||
273 | dma_len = ndesc_skipped * sizeof(struct ath_desc); | ||
274 | dd->dd_desc_len += dma_len; | ||
275 | |||
276 | ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); | ||
277 | }; | ||
278 | } | ||
279 | |||
280 | /* allocate descriptors */ | ||
281 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | ||
282 | &dd->dd_desc_paddr, GFP_KERNEL); | ||
283 | if (dd->dd_desc == NULL) { | ||
284 | error = -ENOMEM; | ||
285 | goto fail; | ||
286 | } | ||
287 | ds = dd->dd_desc; | ||
288 | ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | ||
289 | name, ds, (u32) dd->dd_desc_len, | ||
290 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | ||
291 | |||
292 | /* allocate buffers */ | ||
293 | bsize = sizeof(struct ath_buf) * nbuf; | ||
294 | bf = kzalloc(bsize, GFP_KERNEL); | ||
295 | if (bf == NULL) { | ||
296 | error = -ENOMEM; | ||
297 | goto fail2; | ||
298 | } | ||
299 | dd->dd_bufptr = bf; | ||
300 | |||
301 | for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { | ||
302 | bf->bf_desc = ds; | ||
303 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
304 | |||
305 | if (!(sc->sc_ah->caps.hw_caps & | ||
306 | ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
307 | /* | ||
308 | * Skip descriptor addresses which can cause 4KB | ||
309 | * boundary crossing (addr + length) with a 32 dword | ||
310 | * descriptor fetch. | ||
311 | */ | ||
312 | while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { | ||
313 | BUG_ON((caddr_t) bf->bf_desc >= | ||
314 | ((caddr_t) dd->dd_desc + | ||
315 | dd->dd_desc_len)); | ||
316 | |||
317 | ds += ndesc; | ||
318 | bf->bf_desc = ds; | ||
319 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
320 | } | ||
321 | } | ||
322 | list_add_tail(&bf->list, head); | ||
323 | } | ||
324 | return 0; | ||
325 | fail2: | ||
326 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
327 | dd->dd_desc_paddr); | ||
328 | fail: | ||
329 | memset(dd, 0, sizeof(*dd)); | ||
330 | return error; | ||
331 | #undef ATH_DESC_4KB_BOUND_CHECK | ||
332 | #undef ATH_DESC_4KB_BOUND_NUM_SKIPPED | ||
333 | #undef DS2PHYS | ||
334 | } | ||
335 | |||
336 | static void ath9k_init_crypto(struct ath_softc *sc) | ||
337 | { | ||
338 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
339 | int i = 0; | ||
340 | |||
341 | /* Get the hardware key cache size. */ | ||
342 | common->keymax = sc->sc_ah->caps.keycache_size; | ||
343 | if (common->keymax > ATH_KEYMAX) { | ||
344 | ath_print(common, ATH_DBG_ANY, | ||
345 | "Warning, using only %u entries in %u key cache\n", | ||
346 | ATH_KEYMAX, common->keymax); | ||
347 | common->keymax = ATH_KEYMAX; | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * Reset the key cache since some parts do not | ||
352 | * reset the contents on initial power up. | ||
353 | */ | ||
354 | for (i = 0; i < common->keymax; i++) | ||
355 | ath9k_hw_keyreset(sc->sc_ah, (u16) i); | ||
356 | |||
357 | if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, | ||
358 | ATH9K_CIPHER_TKIP, NULL)) { | ||
359 | /* | ||
360 | * Whether we should enable h/w TKIP MIC. | ||
361 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | ||
362 | * report WMM capable, so it's always safe to turn on | ||
363 | * TKIP MIC in this case. | ||
364 | */ | ||
365 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL); | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * Check whether the separate key cache entries | ||
370 | * are required to handle both tx+rx MIC keys. | ||
371 | * With split mic keys the number of stations is limited | ||
372 | * to 27 otherwise 59. | ||
373 | */ | ||
374 | if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, | ||
375 | ATH9K_CIPHER_TKIP, NULL) | ||
376 | && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, | ||
377 | ATH9K_CIPHER_MIC, NULL) | ||
378 | && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT, | ||
379 | 0, NULL)) | ||
380 | common->splitmic = 1; | ||
381 | |||
382 | /* turn on mcast key search if possible */ | ||
383 | if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | ||
384 | (void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, | ||
385 | 1, 1, NULL); | ||
386 | |||
387 | } | ||
388 | |||
389 | static int ath9k_init_btcoex(struct ath_softc *sc) | ||
390 | { | ||
391 | int r, qnum; | ||
392 | |||
393 | switch (sc->sc_ah->btcoex_hw.scheme) { | ||
394 | case ATH_BTCOEX_CFG_NONE: | ||
395 | break; | ||
396 | case ATH_BTCOEX_CFG_2WIRE: | ||
397 | ath9k_hw_btcoex_init_2wire(sc->sc_ah); | ||
398 | break; | ||
399 | case ATH_BTCOEX_CFG_3WIRE: | ||
400 | ath9k_hw_btcoex_init_3wire(sc->sc_ah); | ||
401 | r = ath_init_btcoex_timer(sc); | ||
402 | if (r) | ||
403 | return -1; | ||
404 | qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); | ||
405 | ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); | ||
406 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
407 | break; | ||
408 | default: | ||
409 | WARN_ON(1); | ||
410 | break; | ||
411 | } | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static int ath9k_init_queues(struct ath_softc *sc) | ||
417 | { | ||
418 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
419 | int i = 0; | ||
420 | |||
421 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
422 | sc->tx.hwq_map[i] = -1; | ||
423 | |||
424 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); | ||
425 | if (sc->beacon.beaconq == -1) { | ||
426 | ath_print(common, ATH_DBG_FATAL, | ||
427 | "Unable to setup a beacon xmit queue\n"); | ||
428 | goto err; | ||
429 | } | ||
430 | |||
431 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | ||
432 | if (sc->beacon.cabq == NULL) { | ||
433 | ath_print(common, ATH_DBG_FATAL, | ||
434 | "Unable to setup CAB xmit queue\n"); | ||
435 | goto err; | ||
436 | } | ||
437 | |||
438 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | ||
439 | ath_cabq_update(sc); | ||
440 | |||
441 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | ||
442 | ath_print(common, ATH_DBG_FATAL, | ||
443 | "Unable to setup xmit queue for BK traffic\n"); | ||
444 | goto err; | ||
445 | } | ||
446 | |||
447 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | ||
448 | ath_print(common, ATH_DBG_FATAL, | ||
449 | "Unable to setup xmit queue for BE traffic\n"); | ||
450 | goto err; | ||
451 | } | ||
452 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | ||
453 | ath_print(common, ATH_DBG_FATAL, | ||
454 | "Unable to setup xmit queue for VI traffic\n"); | ||
455 | goto err; | ||
456 | } | ||
457 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | ||
458 | ath_print(common, ATH_DBG_FATAL, | ||
459 | "Unable to setup xmit queue for VO traffic\n"); | ||
460 | goto err; | ||
461 | } | ||
462 | |||
463 | return 0; | ||
464 | |||
465 | err: | ||
466 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
467 | if (ATH_TXQ_SETUP(sc, i)) | ||
468 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
469 | |||
470 | return -EIO; | ||
471 | } | ||
472 | |||
473 | static void ath9k_init_channels_rates(struct ath_softc *sc) | ||
474 | { | ||
475 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { | ||
476 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; | ||
477 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
478 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
479 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
480 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
481 | sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
482 | ARRAY_SIZE(ath9k_legacy_rates); | ||
483 | } | ||
484 | |||
485 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { | ||
486 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; | ||
487 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
488 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
489 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
490 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
491 | ath9k_legacy_rates + 4; | ||
492 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | ||
493 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | static void ath9k_init_misc(struct ath_softc *sc) | ||
498 | { | ||
499 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
500 | int i = 0; | ||
501 | |||
502 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
503 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | ||
504 | |||
505 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | ||
506 | |||
507 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
508 | sc->sc_flags |= SC_OP_TXAGGR; | ||
509 | sc->sc_flags |= SC_OP_RXAGGR; | ||
510 | } | ||
511 | |||
512 | common->tx_chainmask = sc->sc_ah->caps.tx_chainmask; | ||
513 | common->rx_chainmask = sc->sc_ah->caps.rx_chainmask; | ||
514 | |||
515 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | ||
516 | sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); | ||
517 | |||
518 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
519 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
520 | |||
521 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | ||
522 | |||
523 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | ||
524 | sc->beacon.bslot[i] = NULL; | ||
525 | sc->beacon.bslot_aphy[i] = NULL; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
530 | const struct ath_bus_ops *bus_ops) | ||
531 | { | ||
532 | struct ath_hw *ah = NULL; | ||
533 | struct ath_common *common; | ||
534 | int ret = 0, i; | ||
535 | int csz = 0; | ||
536 | |||
537 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | ||
538 | if (!ah) | ||
539 | return -ENOMEM; | ||
540 | |||
541 | ah->hw_version.devid = devid; | ||
542 | ah->hw_version.subsysid = subsysid; | ||
543 | sc->sc_ah = ah; | ||
544 | |||
545 | common = ath9k_hw_common(ah); | ||
546 | common->ops = &ath9k_common_ops; | ||
547 | common->bus_ops = bus_ops; | ||
548 | common->ah = ah; | ||
549 | common->hw = sc->hw; | ||
550 | common->priv = sc; | ||
551 | common->debug_mask = ath9k_debug; | ||
552 | |||
553 | spin_lock_init(&sc->wiphy_lock); | ||
554 | spin_lock_init(&sc->sc_resetlock); | ||
555 | spin_lock_init(&sc->sc_serial_rw); | ||
556 | spin_lock_init(&sc->sc_pm_lock); | ||
557 | mutex_init(&sc->mutex); | ||
558 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | ||
559 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | ||
560 | (unsigned long)sc); | ||
561 | |||
562 | /* | ||
563 | * Cache line size is used to size and align various | ||
564 | * structures used to communicate with the hardware. | ||
565 | */ | ||
566 | ath_read_cachesize(common, &csz); | ||
567 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
568 | |||
569 | ret = ath9k_hw_init(ah); | ||
570 | if (ret) { | ||
571 | ath_print(common, ATH_DBG_FATAL, | ||
572 | "Unable to initialize hardware; " | ||
573 | "initialization status: %d\n", ret); | ||
574 | goto err_hw; | ||
575 | } | ||
576 | |||
577 | ret = ath9k_init_debug(ah); | ||
578 | if (ret) { | ||
579 | ath_print(common, ATH_DBG_FATAL, | ||
580 | "Unable to create debugfs files\n"); | ||
581 | goto err_debug; | ||
582 | } | ||
583 | |||
584 | ret = ath9k_init_queues(sc); | ||
585 | if (ret) | ||
586 | goto err_queues; | ||
587 | |||
588 | ret = ath9k_init_btcoex(sc); | ||
589 | if (ret) | ||
590 | goto err_btcoex; | ||
591 | |||
592 | ath9k_init_crypto(sc); | ||
593 | ath9k_init_channels_rates(sc); | ||
594 | ath9k_init_misc(sc); | ||
595 | |||
596 | return 0; | ||
597 | |||
598 | err_btcoex: | ||
599 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
600 | if (ATH_TXQ_SETUP(sc, i)) | ||
601 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
602 | err_queues: | ||
603 | ath9k_exit_debug(ah); | ||
604 | err_debug: | ||
605 | ath9k_hw_deinit(ah); | ||
606 | err_hw: | ||
607 | tasklet_kill(&sc->intr_tq); | ||
608 | tasklet_kill(&sc->bcon_tasklet); | ||
609 | |||
610 | kfree(ah); | ||
611 | sc->sc_ah = NULL; | ||
612 | |||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
617 | { | ||
618 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
619 | |||
620 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
621 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
622 | IEEE80211_HW_SIGNAL_DBM | | ||
623 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
624 | IEEE80211_HW_SUPPORTS_PS | | ||
625 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
626 | IEEE80211_HW_SPECTRUM_MGMT; | ||
627 | |||
628 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) | ||
629 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
630 | |||
631 | hw->wiphy->interface_modes = | ||
632 | BIT(NL80211_IFTYPE_AP) | | ||
633 | BIT(NL80211_IFTYPE_STATION) | | ||
634 | BIT(NL80211_IFTYPE_ADHOC) | | ||
635 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
636 | |||
637 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
638 | |||
639 | hw->queues = 4; | ||
640 | hw->max_rates = 4; | ||
641 | hw->channel_change_time = 5000; | ||
642 | hw->max_listen_interval = 10; | ||
643 | /* Hardware supports 10 but we use 4 */ | ||
644 | hw->max_rate_tries = 4; | ||
645 | hw->sta_data_size = sizeof(struct ath_node); | ||
646 | hw->vif_data_size = sizeof(struct ath_vif); | ||
647 | |||
648 | hw->rate_control_algorithm = "ath9k_rate_control"; | ||
649 | |||
650 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | ||
651 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
652 | &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
653 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
654 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
655 | &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
656 | |||
657 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
658 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | ||
659 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
660 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
661 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
662 | } | ||
663 | |||
664 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | ||
665 | } | ||
666 | |||
667 | int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
668 | const struct ath_bus_ops *bus_ops) | ||
669 | { | ||
670 | struct ieee80211_hw *hw = sc->hw; | ||
671 | struct ath_common *common; | ||
672 | struct ath_hw *ah; | ||
673 | int error = 0; | ||
674 | struct ath_regulatory *reg; | ||
675 | |||
676 | /* Bring up device */ | ||
677 | error = ath9k_init_softc(devid, sc, subsysid, bus_ops); | ||
678 | if (error != 0) | ||
679 | goto error_init; | ||
680 | |||
681 | ah = sc->sc_ah; | ||
682 | common = ath9k_hw_common(ah); | ||
683 | ath9k_set_hw_capab(sc, hw); | ||
684 | |||
685 | /* Initialize regulatory */ | ||
686 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, | ||
687 | ath9k_reg_notifier); | ||
688 | if (error) | ||
689 | goto error_regd; | ||
690 | |||
691 | reg = &common->regulatory; | ||
692 | |||
693 | /* Setup TX DMA */ | ||
694 | error = ath_tx_init(sc, ATH_TXBUF); | ||
695 | if (error != 0) | ||
696 | goto error_tx; | ||
697 | |||
698 | /* Setup RX DMA */ | ||
699 | error = ath_rx_init(sc, ATH_RXBUF); | ||
700 | if (error != 0) | ||
701 | goto error_rx; | ||
702 | |||
703 | /* Register with mac80211 */ | ||
704 | error = ieee80211_register_hw(hw); | ||
705 | if (error) | ||
706 | goto error_register; | ||
707 | |||
708 | /* Handle world regulatory */ | ||
709 | if (!ath_is_world_regd(reg)) { | ||
710 | error = regulatory_hint(hw->wiphy, reg->alpha2); | ||
711 | if (error) | ||
712 | goto error_world; | ||
713 | } | ||
714 | |||
715 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | ||
716 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | ||
717 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
718 | |||
719 | ath_init_leds(sc); | ||
720 | ath_start_rfkill_poll(sc); | ||
721 | |||
722 | return 0; | ||
723 | |||
724 | error_world: | ||
725 | ieee80211_unregister_hw(hw); | ||
726 | error_register: | ||
727 | ath_rx_cleanup(sc); | ||
728 | error_rx: | ||
729 | ath_tx_cleanup(sc); | ||
730 | error_tx: | ||
731 | /* Nothing */ | ||
732 | error_regd: | ||
733 | ath9k_deinit_softc(sc); | ||
734 | error_init: | ||
735 | return error; | ||
736 | } | ||
737 | |||
738 | /*****************************/ | ||
739 | /* De-Initialization */ | ||
740 | /*****************************/ | ||
741 | |||
742 | static void ath9k_deinit_softc(struct ath_softc *sc) | ||
743 | { | ||
744 | int i = 0; | ||
745 | |||
746 | if ((sc->btcoex.no_stomp_timer) && | ||
747 | sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | ||
748 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); | ||
749 | |||
750 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
751 | if (ATH_TXQ_SETUP(sc, i)) | ||
752 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
753 | |||
754 | ath9k_exit_debug(sc->sc_ah); | ||
755 | ath9k_hw_deinit(sc->sc_ah); | ||
756 | |||
757 | tasklet_kill(&sc->intr_tq); | ||
758 | tasklet_kill(&sc->bcon_tasklet); | ||
759 | } | ||
760 | |||
761 | void ath9k_deinit_device(struct ath_softc *sc) | ||
762 | { | ||
763 | struct ieee80211_hw *hw = sc->hw; | ||
764 | int i = 0; | ||
765 | |||
766 | ath9k_ps_wakeup(sc); | ||
767 | |||
768 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | ||
769 | ath_deinit_leds(sc); | ||
770 | |||
771 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
772 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
773 | if (aphy == NULL) | ||
774 | continue; | ||
775 | sc->sec_wiphy[i] = NULL; | ||
776 | ieee80211_unregister_hw(aphy->hw); | ||
777 | ieee80211_free_hw(aphy->hw); | ||
778 | } | ||
779 | kfree(sc->sec_wiphy); | ||
780 | |||
781 | ieee80211_unregister_hw(hw); | ||
782 | ath_rx_cleanup(sc); | ||
783 | ath_tx_cleanup(sc); | ||
784 | ath9k_deinit_softc(sc); | ||
785 | } | ||
786 | |||
787 | void ath_descdma_cleanup(struct ath_softc *sc, | ||
788 | struct ath_descdma *dd, | ||
789 | struct list_head *head) | ||
790 | { | ||
791 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
792 | dd->dd_desc_paddr); | ||
793 | |||
794 | INIT_LIST_HEAD(head); | ||
795 | kfree(dd->dd_bufptr); | ||
796 | memset(dd, 0, sizeof(*dd)); | ||
797 | } | ||
798 | |||
799 | /************************/ | ||
800 | /* Module Hooks */ | ||
801 | /************************/ | ||
802 | |||
803 | static int __init ath9k_init(void) | ||
804 | { | ||
805 | int error; | ||
806 | |||
807 | /* Register rate control algorithm */ | ||
808 | error = ath_rate_control_register(); | ||
809 | if (error != 0) { | ||
810 | printk(KERN_ERR | ||
811 | "ath9k: Unable to register rate control " | ||
812 | "algorithm: %d\n", | ||
813 | error); | ||
814 | goto err_out; | ||
815 | } | ||
816 | |||
817 | error = ath9k_debug_create_root(); | ||
818 | if (error) { | ||
819 | printk(KERN_ERR | ||
820 | "ath9k: Unable to create debugfs root: %d\n", | ||
821 | error); | ||
822 | goto err_rate_unregister; | ||
823 | } | ||
824 | |||
825 | error = ath_pci_init(); | ||
826 | if (error < 0) { | ||
827 | printk(KERN_ERR | ||
828 | "ath9k: No PCI devices found, driver not installed.\n"); | ||
829 | error = -ENODEV; | ||
830 | goto err_remove_root; | ||
831 | } | ||
832 | |||
833 | error = ath_ahb_init(); | ||
834 | if (error < 0) { | ||
835 | error = -ENODEV; | ||
836 | goto err_pci_exit; | ||
837 | } | ||
838 | |||
839 | return 0; | ||
840 | |||
841 | err_pci_exit: | ||
842 | ath_pci_exit(); | ||
843 | |||
844 | err_remove_root: | ||
845 | ath9k_debug_remove_root(); | ||
846 | err_rate_unregister: | ||
847 | ath_rate_control_unregister(); | ||
848 | err_out: | ||
849 | return error; | ||
850 | } | ||
851 | module_init(ath9k_init); | ||
852 | |||
853 | static void __exit ath9k_exit(void) | ||
854 | { | ||
855 | ath_ahb_exit(); | ||
856 | ath_pci_exit(); | ||
857 | ath9k_debug_remove_root(); | ||
858 | ath_rate_control_unregister(); | ||
859 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | ||
860 | } | ||
861 | module_exit(ath9k_exit); | ||
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index e185479e295..29851e6376a 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -167,6 +167,40 @@ struct ath_rx_status { | |||
167 | #define ATH9K_RXKEYIX_INVALID ((u8)-1) | 167 | #define ATH9K_RXKEYIX_INVALID ((u8)-1) |
168 | #define ATH9K_TXKEYIX_INVALID ((u32)-1) | 168 | #define ATH9K_TXKEYIX_INVALID ((u32)-1) |
169 | 169 | ||
170 | enum ath9k_phyerr { | ||
171 | ATH9K_PHYERR_UNDERRUN = 0, /* Transmit underrun */ | ||
172 | ATH9K_PHYERR_TIMING = 1, /* Timing error */ | ||
173 | ATH9K_PHYERR_PARITY = 2, /* Illegal parity */ | ||
174 | ATH9K_PHYERR_RATE = 3, /* Illegal rate */ | ||
175 | ATH9K_PHYERR_LENGTH = 4, /* Illegal length */ | ||
176 | ATH9K_PHYERR_RADAR = 5, /* Radar detect */ | ||
177 | ATH9K_PHYERR_SERVICE = 6, /* Illegal service */ | ||
178 | ATH9K_PHYERR_TOR = 7, /* Transmit override receive */ | ||
179 | |||
180 | ATH9K_PHYERR_OFDM_TIMING = 17, | ||
181 | ATH9K_PHYERR_OFDM_SIGNAL_PARITY = 18, | ||
182 | ATH9K_PHYERR_OFDM_RATE_ILLEGAL = 19, | ||
183 | ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL = 20, | ||
184 | ATH9K_PHYERR_OFDM_POWER_DROP = 21, | ||
185 | ATH9K_PHYERR_OFDM_SERVICE = 22, | ||
186 | ATH9K_PHYERR_OFDM_RESTART = 23, | ||
187 | ATH9K_PHYERR_FALSE_RADAR_EXT = 24, | ||
188 | |||
189 | ATH9K_PHYERR_CCK_TIMING = 25, | ||
190 | ATH9K_PHYERR_CCK_HEADER_CRC = 26, | ||
191 | ATH9K_PHYERR_CCK_RATE_ILLEGAL = 27, | ||
192 | ATH9K_PHYERR_CCK_SERVICE = 30, | ||
193 | ATH9K_PHYERR_CCK_RESTART = 31, | ||
194 | ATH9K_PHYERR_CCK_LENGTH_ILLEGAL = 32, | ||
195 | ATH9K_PHYERR_CCK_POWER_DROP = 33, | ||
196 | |||
197 | ATH9K_PHYERR_HT_CRC_ERROR = 34, | ||
198 | ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35, | ||
199 | ATH9K_PHYERR_HT_RATE_ILLEGAL = 36, | ||
200 | |||
201 | ATH9K_PHYERR_MAX = 37, | ||
202 | }; | ||
203 | |||
170 | struct ath_desc { | 204 | struct ath_desc { |
171 | u32 ds_link; | 205 | u32 ds_link; |
172 | u32 ds_data; | 206 | u32 ds_data; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 79fbbda1549..c0c571c2e8c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -18,118 +18,6 @@ | |||
18 | #include "ath9k.h" | 18 | #include "ath9k.h" |
19 | #include "btcoex.h" | 19 | #include "btcoex.h" |
20 | 20 | ||
21 | static char *dev_info = "ath9k"; | ||
22 | |||
23 | MODULE_AUTHOR("Atheros Communications"); | ||
24 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | ||
25 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | ||
26 | MODULE_LICENSE("Dual BSD/GPL"); | ||
27 | |||
28 | static int modparam_nohwcrypt; | ||
29 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | ||
30 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | ||
31 | |||
32 | static unsigned int ath9k_debug = ATH_DBG_DEFAULT; | ||
33 | module_param_named(debug, ath9k_debug, uint, 0); | ||
34 | MODULE_PARM_DESC(debug, "Debugging mask"); | ||
35 | |||
36 | /* We use the hw_value as an index into our private channel structure */ | ||
37 | |||
38 | #define CHAN2G(_freq, _idx) { \ | ||
39 | .center_freq = (_freq), \ | ||
40 | .hw_value = (_idx), \ | ||
41 | .max_power = 20, \ | ||
42 | } | ||
43 | |||
44 | #define CHAN5G(_freq, _idx) { \ | ||
45 | .band = IEEE80211_BAND_5GHZ, \ | ||
46 | .center_freq = (_freq), \ | ||
47 | .hw_value = (_idx), \ | ||
48 | .max_power = 20, \ | ||
49 | } | ||
50 | |||
51 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
52 | * on 5 MHz steps, we support the channels which we know | ||
53 | * we have calibration data for all cards though to make | ||
54 | * this static */ | ||
55 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
56 | CHAN2G(2412, 0), /* Channel 1 */ | ||
57 | CHAN2G(2417, 1), /* Channel 2 */ | ||
58 | CHAN2G(2422, 2), /* Channel 3 */ | ||
59 | CHAN2G(2427, 3), /* Channel 4 */ | ||
60 | CHAN2G(2432, 4), /* Channel 5 */ | ||
61 | CHAN2G(2437, 5), /* Channel 6 */ | ||
62 | CHAN2G(2442, 6), /* Channel 7 */ | ||
63 | CHAN2G(2447, 7), /* Channel 8 */ | ||
64 | CHAN2G(2452, 8), /* Channel 9 */ | ||
65 | CHAN2G(2457, 9), /* Channel 10 */ | ||
66 | CHAN2G(2462, 10), /* Channel 11 */ | ||
67 | CHAN2G(2467, 11), /* Channel 12 */ | ||
68 | CHAN2G(2472, 12), /* Channel 13 */ | ||
69 | CHAN2G(2484, 13), /* Channel 14 */ | ||
70 | }; | ||
71 | |||
72 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
73 | * on 5 MHz steps, we support the channels which we know | ||
74 | * we have calibration data for all cards though to make | ||
75 | * this static */ | ||
76 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
77 | /* _We_ call this UNII 1 */ | ||
78 | CHAN5G(5180, 14), /* Channel 36 */ | ||
79 | CHAN5G(5200, 15), /* Channel 40 */ | ||
80 | CHAN5G(5220, 16), /* Channel 44 */ | ||
81 | CHAN5G(5240, 17), /* Channel 48 */ | ||
82 | /* _We_ call this UNII 2 */ | ||
83 | CHAN5G(5260, 18), /* Channel 52 */ | ||
84 | CHAN5G(5280, 19), /* Channel 56 */ | ||
85 | CHAN5G(5300, 20), /* Channel 60 */ | ||
86 | CHAN5G(5320, 21), /* Channel 64 */ | ||
87 | /* _We_ call this "Middle band" */ | ||
88 | CHAN5G(5500, 22), /* Channel 100 */ | ||
89 | CHAN5G(5520, 23), /* Channel 104 */ | ||
90 | CHAN5G(5540, 24), /* Channel 108 */ | ||
91 | CHAN5G(5560, 25), /* Channel 112 */ | ||
92 | CHAN5G(5580, 26), /* Channel 116 */ | ||
93 | CHAN5G(5600, 27), /* Channel 120 */ | ||
94 | CHAN5G(5620, 28), /* Channel 124 */ | ||
95 | CHAN5G(5640, 29), /* Channel 128 */ | ||
96 | CHAN5G(5660, 30), /* Channel 132 */ | ||
97 | CHAN5G(5680, 31), /* Channel 136 */ | ||
98 | CHAN5G(5700, 32), /* Channel 140 */ | ||
99 | /* _We_ call this UNII 3 */ | ||
100 | CHAN5G(5745, 33), /* Channel 149 */ | ||
101 | CHAN5G(5765, 34), /* Channel 153 */ | ||
102 | CHAN5G(5785, 35), /* Channel 157 */ | ||
103 | CHAN5G(5805, 36), /* Channel 161 */ | ||
104 | CHAN5G(5825, 37), /* Channel 165 */ | ||
105 | }; | ||
106 | |||
107 | /* Atheros hardware rate code addition for short premble */ | ||
108 | #define SHPCHECK(__hw_rate, __flags) \ | ||
109 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) | ||
110 | |||
111 | #define RATE(_bitrate, _hw_rate, _flags) { \ | ||
112 | .bitrate = (_bitrate), \ | ||
113 | .flags = (_flags), \ | ||
114 | .hw_value = (_hw_rate), \ | ||
115 | .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ | ||
116 | } | ||
117 | |||
118 | static struct ieee80211_rate ath9k_legacy_rates[] = { | ||
119 | RATE(10, 0x1b, 0), | ||
120 | RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), | ||
121 | RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), | ||
122 | RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), | ||
123 | RATE(60, 0x0b, 0), | ||
124 | RATE(90, 0x0f, 0), | ||
125 | RATE(120, 0x0a, 0), | ||
126 | RATE(180, 0x0e, 0), | ||
127 | RATE(240, 0x09, 0), | ||
128 | RATE(360, 0x0d, 0), | ||
129 | RATE(480, 0x08, 0), | ||
130 | RATE(540, 0x0c, 0), | ||
131 | }; | ||
132 | |||
133 | static void ath_cache_conf_rate(struct ath_softc *sc, | 21 | static void ath_cache_conf_rate(struct ath_softc *sc, |
134 | struct ieee80211_conf *conf) | 22 | struct ieee80211_conf *conf) |
135 | { | 23 | { |
@@ -221,7 +109,7 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, | |||
221 | return channel; | 109 | return channel; |
222 | } | 110 | } |
223 | 111 | ||
224 | static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) | 112 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) |
225 | { | 113 | { |
226 | unsigned long flags; | 114 | unsigned long flags; |
227 | bool ret; | 115 | bool ret; |
@@ -256,10 +144,10 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
256 | goto unlock; | 144 | goto unlock; |
257 | 145 | ||
258 | if (sc->ps_enabled && | 146 | if (sc->ps_enabled && |
259 | !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 147 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | |
260 | SC_OP_WAIT_FOR_CAB | | 148 | PS_WAIT_FOR_CAB | |
261 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 149 | PS_WAIT_FOR_PSPOLL_DATA | |
262 | SC_OP_WAIT_FOR_TX_ACK))) | 150 | PS_WAIT_FOR_TX_ACK))) |
263 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | 151 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); |
264 | 152 | ||
265 | unlock: | 153 | unlock: |
@@ -349,7 +237,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
349 | * When the task is complete, it reschedules itself depending on the | 237 | * When the task is complete, it reschedules itself depending on the |
350 | * appropriate interval that was calculated. | 238 | * appropriate interval that was calculated. |
351 | */ | 239 | */ |
352 | static void ath_ani_calibrate(unsigned long data) | 240 | void ath_ani_calibrate(unsigned long data) |
353 | { | 241 | { |
354 | struct ath_softc *sc = (struct ath_softc *)data; | 242 | struct ath_softc *sc = (struct ath_softc *)data; |
355 | struct ath_hw *ah = sc->sc_ah; | 243 | struct ath_hw *ah = sc->sc_ah; |
@@ -504,7 +392,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
504 | ath_tx_node_cleanup(sc, an); | 392 | ath_tx_node_cleanup(sc, an); |
505 | } | 393 | } |
506 | 394 | ||
507 | static void ath9k_tasklet(unsigned long data) | 395 | void ath9k_tasklet(unsigned long data) |
508 | { | 396 | { |
509 | struct ath_softc *sc = (struct ath_softc *)data; | 397 | struct ath_softc *sc = (struct ath_softc *)data; |
510 | struct ath_hw *ah = sc->sc_ah; | 398 | struct ath_hw *ah = sc->sc_ah; |
@@ -536,7 +424,7 @@ static void ath9k_tasklet(unsigned long data) | |||
536 | */ | 424 | */ |
537 | ath_print(common, ATH_DBG_PS, | 425 | ath_print(common, ATH_DBG_PS, |
538 | "TSFOOR - Sync with next Beacon\n"); | 426 | "TSFOOR - Sync with next Beacon\n"); |
539 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC; | 427 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; |
540 | } | 428 | } |
541 | 429 | ||
542 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 430 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
@@ -637,7 +525,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
637 | * receive frames */ | 525 | * receive frames */ |
638 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | 526 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
639 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 527 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
640 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; | 528 | sc->ps_flags |= PS_WAIT_FOR_BEACON; |
641 | } | 529 | } |
642 | 530 | ||
643 | chip_reset: | 531 | chip_reset: |
@@ -924,44 +812,6 @@ static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf | |||
924 | } | 812 | } |
925 | } | 813 | } |
926 | 814 | ||
927 | static void setup_ht_cap(struct ath_softc *sc, | ||
928 | struct ieee80211_sta_ht_cap *ht_info) | ||
929 | { | ||
930 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
931 | u8 tx_streams, rx_streams; | ||
932 | |||
933 | ht_info->ht_supported = true; | ||
934 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
935 | IEEE80211_HT_CAP_SM_PS | | ||
936 | IEEE80211_HT_CAP_SGI_40 | | ||
937 | IEEE80211_HT_CAP_DSSSCCK40; | ||
938 | |||
939 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
940 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
941 | |||
942 | /* set up supported mcs set */ | ||
943 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
944 | tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? | ||
945 | 1 : 2; | ||
946 | rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? | ||
947 | 1 : 2; | ||
948 | |||
949 | if (tx_streams != rx_streams) { | ||
950 | ath_print(common, ATH_DBG_CONFIG, | ||
951 | "TX streams %d, RX streams: %d\n", | ||
952 | tx_streams, rx_streams); | ||
953 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
954 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | ||
955 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
956 | } | ||
957 | |||
958 | ht_info->mcs.rx_mask[0] = 0xff; | ||
959 | if (rx_streams >= 2) | ||
960 | ht_info->mcs.rx_mask[1] = 0xff; | ||
961 | |||
962 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
963 | } | ||
964 | |||
965 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | 815 | static void ath9k_bss_assoc_info(struct ath_softc *sc, |
966 | struct ieee80211_vif *vif, | 816 | struct ieee80211_vif *vif, |
967 | struct ieee80211_bss_conf *bss_conf) | 817 | struct ieee80211_bss_conf *bss_conf) |
@@ -983,7 +833,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
983 | * on the receipt of the first Beacon frame (i.e., | 833 | * on the receipt of the first Beacon frame (i.e., |
984 | * after time sync with the AP). | 834 | * after time sync with the AP). |
985 | */ | 835 | */ |
986 | sc->sc_flags |= SC_OP_BEACON_SYNC; | 836 | sc->ps_flags |= PS_BEACON_SYNC; |
987 | 837 | ||
988 | /* Configure the beacon */ | 838 | /* Configure the beacon */ |
989 | ath_beacon_config(sc, vif); | 839 | ath_beacon_config(sc, vif); |
@@ -1000,174 +850,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
1000 | } | 850 | } |
1001 | } | 851 | } |
1002 | 852 | ||
1003 | /********************************/ | ||
1004 | /* LED functions */ | ||
1005 | /********************************/ | ||
1006 | |||
1007 | static void ath_led_blink_work(struct work_struct *work) | ||
1008 | { | ||
1009 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
1010 | ath_led_blink_work.work); | ||
1011 | |||
1012 | if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) | ||
1013 | return; | ||
1014 | |||
1015 | if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
1016 | (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
1017 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
1018 | else | ||
1019 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
1020 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); | ||
1021 | |||
1022 | ieee80211_queue_delayed_work(sc->hw, | ||
1023 | &sc->ath_led_blink_work, | ||
1024 | (sc->sc_flags & SC_OP_LED_ON) ? | ||
1025 | msecs_to_jiffies(sc->led_off_duration) : | ||
1026 | msecs_to_jiffies(sc->led_on_duration)); | ||
1027 | |||
1028 | sc->led_on_duration = sc->led_on_cnt ? | ||
1029 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : | ||
1030 | ATH_LED_ON_DURATION_IDLE; | ||
1031 | sc->led_off_duration = sc->led_off_cnt ? | ||
1032 | max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) : | ||
1033 | ATH_LED_OFF_DURATION_IDLE; | ||
1034 | sc->led_on_cnt = sc->led_off_cnt = 0; | ||
1035 | if (sc->sc_flags & SC_OP_LED_ON) | ||
1036 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
1037 | else | ||
1038 | sc->sc_flags |= SC_OP_LED_ON; | ||
1039 | } | ||
1040 | |||
1041 | static void ath_led_brightness(struct led_classdev *led_cdev, | ||
1042 | enum led_brightness brightness) | ||
1043 | { | ||
1044 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | ||
1045 | struct ath_softc *sc = led->sc; | ||
1046 | |||
1047 | switch (brightness) { | ||
1048 | case LED_OFF: | ||
1049 | if (led->led_type == ATH_LED_ASSOC || | ||
1050 | led->led_type == ATH_LED_RADIO) { | ||
1051 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
1052 | (led->led_type == ATH_LED_RADIO)); | ||
1053 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
1054 | if (led->led_type == ATH_LED_RADIO) | ||
1055 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
1056 | } else { | ||
1057 | sc->led_off_cnt++; | ||
1058 | } | ||
1059 | break; | ||
1060 | case LED_FULL: | ||
1061 | if (led->led_type == ATH_LED_ASSOC) { | ||
1062 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; | ||
1063 | ieee80211_queue_delayed_work(sc->hw, | ||
1064 | &sc->ath_led_blink_work, 0); | ||
1065 | } else if (led->led_type == ATH_LED_RADIO) { | ||
1066 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
1067 | sc->sc_flags |= SC_OP_LED_ON; | ||
1068 | } else { | ||
1069 | sc->led_on_cnt++; | ||
1070 | } | ||
1071 | break; | ||
1072 | default: | ||
1073 | break; | ||
1074 | } | ||
1075 | } | ||
1076 | |||
1077 | static int ath_register_led(struct ath_softc *sc, struct ath_led *led, | ||
1078 | char *trigger) | ||
1079 | { | ||
1080 | int ret; | ||
1081 | |||
1082 | led->sc = sc; | ||
1083 | led->led_cdev.name = led->name; | ||
1084 | led->led_cdev.default_trigger = trigger; | ||
1085 | led->led_cdev.brightness_set = ath_led_brightness; | ||
1086 | |||
1087 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); | ||
1088 | if (ret) | ||
1089 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | ||
1090 | "Failed to register led:%s", led->name); | ||
1091 | else | ||
1092 | led->registered = 1; | ||
1093 | return ret; | ||
1094 | } | ||
1095 | |||
1096 | static void ath_unregister_led(struct ath_led *led) | ||
1097 | { | ||
1098 | if (led->registered) { | ||
1099 | led_classdev_unregister(&led->led_cdev); | ||
1100 | led->registered = 0; | ||
1101 | } | ||
1102 | } | ||
1103 | |||
1104 | static void ath_deinit_leds(struct ath_softc *sc) | ||
1105 | { | ||
1106 | ath_unregister_led(&sc->assoc_led); | ||
1107 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
1108 | ath_unregister_led(&sc->tx_led); | ||
1109 | ath_unregister_led(&sc->rx_led); | ||
1110 | ath_unregister_led(&sc->radio_led); | ||
1111 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
1112 | } | ||
1113 | |||
1114 | static void ath_init_leds(struct ath_softc *sc) | ||
1115 | { | ||
1116 | char *trigger; | ||
1117 | int ret; | ||
1118 | |||
1119 | if (AR_SREV_9287(sc->sc_ah)) | ||
1120 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; | ||
1121 | else | ||
1122 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | ||
1123 | |||
1124 | /* Configure gpio 1 for output */ | ||
1125 | ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, | ||
1126 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
1127 | /* LED off, active low */ | ||
1128 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
1129 | |||
1130 | INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); | ||
1131 | |||
1132 | trigger = ieee80211_get_radio_led_name(sc->hw); | ||
1133 | snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), | ||
1134 | "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); | ||
1135 | ret = ath_register_led(sc, &sc->radio_led, trigger); | ||
1136 | sc->radio_led.led_type = ATH_LED_RADIO; | ||
1137 | if (ret) | ||
1138 | goto fail; | ||
1139 | |||
1140 | trigger = ieee80211_get_assoc_led_name(sc->hw); | ||
1141 | snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), | ||
1142 | "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); | ||
1143 | ret = ath_register_led(sc, &sc->assoc_led, trigger); | ||
1144 | sc->assoc_led.led_type = ATH_LED_ASSOC; | ||
1145 | if (ret) | ||
1146 | goto fail; | ||
1147 | |||
1148 | trigger = ieee80211_get_tx_led_name(sc->hw); | ||
1149 | snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), | ||
1150 | "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); | ||
1151 | ret = ath_register_led(sc, &sc->tx_led, trigger); | ||
1152 | sc->tx_led.led_type = ATH_LED_TX; | ||
1153 | if (ret) | ||
1154 | goto fail; | ||
1155 | |||
1156 | trigger = ieee80211_get_rx_led_name(sc->hw); | ||
1157 | snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), | ||
1158 | "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); | ||
1159 | ret = ath_register_led(sc, &sc->rx_led, trigger); | ||
1160 | sc->rx_led.led_type = ATH_LED_RX; | ||
1161 | if (ret) | ||
1162 | goto fail; | ||
1163 | |||
1164 | return; | ||
1165 | |||
1166 | fail: | ||
1167 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | ||
1168 | ath_deinit_leds(sc); | ||
1169 | } | ||
1170 | |||
1171 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | 853 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) |
1172 | { | 854 | { |
1173 | struct ath_hw *ah = sc->sc_ah; | 855 | struct ath_hw *ah = sc->sc_ah; |
@@ -1252,710 +934,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1252 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 934 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
1253 | } | 935 | } |
1254 | 936 | ||
1255 | /*******************/ | ||
1256 | /* Rfkill */ | ||
1257 | /*******************/ | ||
1258 | |||
1259 | static bool ath_is_rfkill_set(struct ath_softc *sc) | ||
1260 | { | ||
1261 | struct ath_hw *ah = sc->sc_ah; | ||
1262 | |||
1263 | return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) == | ||
1264 | ah->rfkill_polarity; | ||
1265 | } | ||
1266 | |||
1267 | static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) | ||
1268 | { | ||
1269 | struct ath_wiphy *aphy = hw->priv; | ||
1270 | struct ath_softc *sc = aphy->sc; | ||
1271 | bool blocked = !!ath_is_rfkill_set(sc); | ||
1272 | |||
1273 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); | ||
1274 | } | ||
1275 | |||
1276 | static void ath_start_rfkill_poll(struct ath_softc *sc) | ||
1277 | { | ||
1278 | struct ath_hw *ah = sc->sc_ah; | ||
1279 | |||
1280 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1281 | wiphy_rfkill_start_polling(sc->hw->wiphy); | ||
1282 | } | ||
1283 | |||
1284 | static void ath9k_uninit_hw(struct ath_softc *sc) | ||
1285 | { | ||
1286 | struct ath_hw *ah = sc->sc_ah; | ||
1287 | |||
1288 | BUG_ON(!ah); | ||
1289 | |||
1290 | ath9k_exit_debug(ah); | ||
1291 | ath9k_hw_detach(ah); | ||
1292 | sc->sc_ah = NULL; | ||
1293 | } | ||
1294 | |||
1295 | static void ath_clean_core(struct ath_softc *sc) | ||
1296 | { | ||
1297 | struct ieee80211_hw *hw = sc->hw; | ||
1298 | struct ath_hw *ah = sc->sc_ah; | ||
1299 | int i = 0; | ||
1300 | |||
1301 | ath9k_ps_wakeup(sc); | ||
1302 | |||
1303 | dev_dbg(sc->dev, "Detach ATH hw\n"); | ||
1304 | |||
1305 | ath_deinit_leds(sc); | ||
1306 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | ||
1307 | |||
1308 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
1309 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
1310 | if (aphy == NULL) | ||
1311 | continue; | ||
1312 | sc->sec_wiphy[i] = NULL; | ||
1313 | ieee80211_unregister_hw(aphy->hw); | ||
1314 | ieee80211_free_hw(aphy->hw); | ||
1315 | } | ||
1316 | ieee80211_unregister_hw(hw); | ||
1317 | ath_rx_cleanup(sc); | ||
1318 | ath_tx_cleanup(sc); | ||
1319 | |||
1320 | tasklet_kill(&sc->intr_tq); | ||
1321 | tasklet_kill(&sc->bcon_tasklet); | ||
1322 | |||
1323 | if (!(sc->sc_flags & SC_OP_INVALID)) | ||
1324 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | ||
1325 | |||
1326 | /* cleanup tx queues */ | ||
1327 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1328 | if (ATH_TXQ_SETUP(sc, i)) | ||
1329 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1330 | |||
1331 | if ((sc->btcoex.no_stomp_timer) && | ||
1332 | ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | ||
1333 | ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer); | ||
1334 | } | ||
1335 | |||
1336 | void ath_detach(struct ath_softc *sc) | ||
1337 | { | ||
1338 | ath_clean_core(sc); | ||
1339 | ath9k_uninit_hw(sc); | ||
1340 | } | ||
1341 | |||
1342 | void ath_cleanup(struct ath_softc *sc) | ||
1343 | { | ||
1344 | struct ath_hw *ah = sc->sc_ah; | ||
1345 | struct ath_common *common = ath9k_hw_common(ah); | ||
1346 | |||
1347 | ath_clean_core(sc); | ||
1348 | free_irq(sc->irq, sc); | ||
1349 | ath_bus_cleanup(common); | ||
1350 | kfree(sc->sec_wiphy); | ||
1351 | ieee80211_free_hw(sc->hw); | ||
1352 | |||
1353 | ath9k_uninit_hw(sc); | ||
1354 | } | ||
1355 | |||
1356 | static int ath9k_reg_notifier(struct wiphy *wiphy, | ||
1357 | struct regulatory_request *request) | ||
1358 | { | ||
1359 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
1360 | struct ath_wiphy *aphy = hw->priv; | ||
1361 | struct ath_softc *sc = aphy->sc; | ||
1362 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); | ||
1363 | |||
1364 | return ath_reg_notifier_apply(wiphy, request, reg); | ||
1365 | } | ||
1366 | |||
1367 | /* | ||
1368 | * Detects if there is any priority bt traffic | ||
1369 | */ | ||
1370 | static void ath_detect_bt_priority(struct ath_softc *sc) | ||
1371 | { | ||
1372 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1373 | struct ath_hw *ah = sc->sc_ah; | ||
1374 | |||
1375 | if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio)) | ||
1376 | btcoex->bt_priority_cnt++; | ||
1377 | |||
1378 | if (time_after(jiffies, btcoex->bt_priority_time + | ||
1379 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | ||
1380 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | ||
1381 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, | ||
1382 | "BT priority traffic detected"); | ||
1383 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | ||
1384 | } else { | ||
1385 | sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; | ||
1386 | } | ||
1387 | |||
1388 | btcoex->bt_priority_cnt = 0; | ||
1389 | btcoex->bt_priority_time = jiffies; | ||
1390 | } | ||
1391 | } | ||
1392 | |||
1393 | /* | ||
1394 | * Configures appropriate weight based on stomp type. | ||
1395 | */ | ||
1396 | static void ath9k_btcoex_bt_stomp(struct ath_softc *sc, | ||
1397 | enum ath_stomp_type stomp_type) | ||
1398 | { | ||
1399 | struct ath_hw *ah = sc->sc_ah; | ||
1400 | |||
1401 | switch (stomp_type) { | ||
1402 | case ATH_BTCOEX_STOMP_ALL: | ||
1403 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1404 | AR_STOMP_ALL_WLAN_WGHT); | ||
1405 | break; | ||
1406 | case ATH_BTCOEX_STOMP_LOW: | ||
1407 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1408 | AR_STOMP_LOW_WLAN_WGHT); | ||
1409 | break; | ||
1410 | case ATH_BTCOEX_STOMP_NONE: | ||
1411 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1412 | AR_STOMP_NONE_WLAN_WGHT); | ||
1413 | break; | ||
1414 | default: | ||
1415 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
1416 | "Invalid Stomptype\n"); | ||
1417 | break; | ||
1418 | } | ||
1419 | |||
1420 | ath9k_hw_btcoex_enable(ah); | ||
1421 | } | ||
1422 | |||
1423 | static void ath9k_gen_timer_start(struct ath_hw *ah, | ||
1424 | struct ath_gen_timer *timer, | ||
1425 | u32 timer_next, | ||
1426 | u32 timer_period) | ||
1427 | { | ||
1428 | struct ath_common *common = ath9k_hw_common(ah); | ||
1429 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1430 | |||
1431 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | ||
1432 | |||
1433 | if ((sc->imask & ATH9K_INT_GENTIMER) == 0) { | ||
1434 | ath9k_hw_set_interrupts(ah, 0); | ||
1435 | sc->imask |= ATH9K_INT_GENTIMER; | ||
1436 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | ||
1441 | { | ||
1442 | struct ath_common *common = ath9k_hw_common(ah); | ||
1443 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1444 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | ||
1445 | |||
1446 | ath9k_hw_gen_timer_stop(ah, timer); | ||
1447 | |||
1448 | /* if no timer is enabled, turn off interrupt mask */ | ||
1449 | if (timer_table->timer_mask.val == 0) { | ||
1450 | ath9k_hw_set_interrupts(ah, 0); | ||
1451 | sc->imask &= ~ATH9K_INT_GENTIMER; | ||
1452 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
1453 | } | ||
1454 | } | ||
1455 | |||
1456 | /* | ||
1457 | * This is the master bt coex timer which runs for every | ||
1458 | * 45ms, bt traffic will be given priority during 55% of this | ||
1459 | * period while wlan gets remaining 45% | ||
1460 | */ | ||
1461 | static void ath_btcoex_period_timer(unsigned long data) | ||
1462 | { | ||
1463 | struct ath_softc *sc = (struct ath_softc *) data; | ||
1464 | struct ath_hw *ah = sc->sc_ah; | ||
1465 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1466 | |||
1467 | ath_detect_bt_priority(sc); | ||
1468 | |||
1469 | spin_lock_bh(&btcoex->btcoex_lock); | ||
1470 | |||
1471 | ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type); | ||
1472 | |||
1473 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
1474 | |||
1475 | if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) { | ||
1476 | if (btcoex->hw_timer_enabled) | ||
1477 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
1478 | |||
1479 | ath9k_gen_timer_start(ah, | ||
1480 | btcoex->no_stomp_timer, | ||
1481 | (ath9k_hw_gettsf32(ah) + | ||
1482 | btcoex->btcoex_no_stomp), | ||
1483 | btcoex->btcoex_no_stomp * 10); | ||
1484 | btcoex->hw_timer_enabled = true; | ||
1485 | } | ||
1486 | |||
1487 | mod_timer(&btcoex->period_timer, jiffies + | ||
1488 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | ||
1489 | } | ||
1490 | |||
1491 | /* | ||
1492 | * Generic tsf based hw timer which configures weight | ||
1493 | * registers to time slice between wlan and bt traffic | ||
1494 | */ | ||
1495 | static void ath_btcoex_no_stomp_timer(void *arg) | ||
1496 | { | ||
1497 | struct ath_softc *sc = (struct ath_softc *)arg; | ||
1498 | struct ath_hw *ah = sc->sc_ah; | ||
1499 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1500 | |||
1501 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
1502 | "no stomp timer running \n"); | ||
1503 | |||
1504 | spin_lock_bh(&btcoex->btcoex_lock); | ||
1505 | |||
1506 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW) | ||
1507 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); | ||
1508 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | ||
1509 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); | ||
1510 | |||
1511 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
1512 | } | ||
1513 | |||
1514 | static int ath_init_btcoex_timer(struct ath_softc *sc) | ||
1515 | { | ||
1516 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1517 | |||
1518 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; | ||
1519 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | ||
1520 | btcoex->btcoex_period / 100; | ||
1521 | |||
1522 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | ||
1523 | (unsigned long) sc); | ||
1524 | |||
1525 | spin_lock_init(&btcoex->btcoex_lock); | ||
1526 | |||
1527 | btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah, | ||
1528 | ath_btcoex_no_stomp_timer, | ||
1529 | ath_btcoex_no_stomp_timer, | ||
1530 | (void *) sc, AR_FIRST_NDP_TIMER); | ||
1531 | |||
1532 | if (!btcoex->no_stomp_timer) | ||
1533 | return -ENOMEM; | ||
1534 | |||
1535 | return 0; | ||
1536 | } | ||
1537 | |||
1538 | /* | ||
1539 | * Read and write, they both share the same lock. We do this to serialize | ||
1540 | * reads and writes on Atheros 802.11n PCI devices only. This is required | ||
1541 | * as the FIFO on these devices can only accept sanely 2 requests. After | ||
1542 | * that the device goes bananas. Serializing the reads/writes prevents this | ||
1543 | * from happening. | ||
1544 | */ | ||
1545 | |||
1546 | static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) | ||
1547 | { | ||
1548 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
1549 | struct ath_common *common = ath9k_hw_common(ah); | ||
1550 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1551 | |||
1552 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
1553 | unsigned long flags; | ||
1554 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
1555 | iowrite32(val, sc->mem + reg_offset); | ||
1556 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
1557 | } else | ||
1558 | iowrite32(val, sc->mem + reg_offset); | ||
1559 | } | ||
1560 | |||
1561 | static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | ||
1562 | { | ||
1563 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
1564 | struct ath_common *common = ath9k_hw_common(ah); | ||
1565 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1566 | u32 val; | ||
1567 | |||
1568 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
1569 | unsigned long flags; | ||
1570 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
1571 | val = ioread32(sc->mem + reg_offset); | ||
1572 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
1573 | } else | ||
1574 | val = ioread32(sc->mem + reg_offset); | ||
1575 | return val; | ||
1576 | } | ||
1577 | |||
1578 | static const struct ath_ops ath9k_common_ops = { | ||
1579 | .read = ath9k_ioread32, | ||
1580 | .write = ath9k_iowrite32, | ||
1581 | }; | ||
1582 | |||
1583 | /* | ||
1584 | * Initialize and fill ath_softc, ath_sofct is the | ||
1585 | * "Software Carrier" struct. Historically it has existed | ||
1586 | * to allow the separation between hardware specific | ||
1587 | * variables (now in ath_hw) and driver specific variables. | ||
1588 | */ | ||
1589 | static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
1590 | const struct ath_bus_ops *bus_ops) | ||
1591 | { | ||
1592 | struct ath_hw *ah = NULL; | ||
1593 | struct ath_common *common; | ||
1594 | int r = 0, i; | ||
1595 | int csz = 0; | ||
1596 | int qnum; | ||
1597 | |||
1598 | /* XXX: hardware will not be ready until ath_open() being called */ | ||
1599 | sc->sc_flags |= SC_OP_INVALID; | ||
1600 | |||
1601 | spin_lock_init(&sc->wiphy_lock); | ||
1602 | spin_lock_init(&sc->sc_resetlock); | ||
1603 | spin_lock_init(&sc->sc_serial_rw); | ||
1604 | spin_lock_init(&sc->sc_pm_lock); | ||
1605 | mutex_init(&sc->mutex); | ||
1606 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | ||
1607 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | ||
1608 | (unsigned long)sc); | ||
1609 | |||
1610 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | ||
1611 | if (!ah) | ||
1612 | return -ENOMEM; | ||
1613 | |||
1614 | ah->hw_version.devid = devid; | ||
1615 | ah->hw_version.subsysid = subsysid; | ||
1616 | sc->sc_ah = ah; | ||
1617 | |||
1618 | common = ath9k_hw_common(ah); | ||
1619 | common->ops = &ath9k_common_ops; | ||
1620 | common->bus_ops = bus_ops; | ||
1621 | common->ah = ah; | ||
1622 | common->hw = sc->hw; | ||
1623 | common->priv = sc; | ||
1624 | common->debug_mask = ath9k_debug; | ||
1625 | |||
1626 | /* | ||
1627 | * Cache line size is used to size and align various | ||
1628 | * structures used to communicate with the hardware. | ||
1629 | */ | ||
1630 | ath_read_cachesize(common, &csz); | ||
1631 | /* XXX assert csz is non-zero */ | ||
1632 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
1633 | |||
1634 | r = ath9k_hw_init(ah); | ||
1635 | if (r) { | ||
1636 | ath_print(common, ATH_DBG_FATAL, | ||
1637 | "Unable to initialize hardware; " | ||
1638 | "initialization status: %d\n", r); | ||
1639 | goto bad_free_hw; | ||
1640 | } | ||
1641 | |||
1642 | if (ath9k_init_debug(ah) < 0) { | ||
1643 | ath_print(common, ATH_DBG_FATAL, | ||
1644 | "Unable to create debugfs files\n"); | ||
1645 | goto bad_free_hw; | ||
1646 | } | ||
1647 | |||
1648 | /* Get the hardware key cache size. */ | ||
1649 | common->keymax = ah->caps.keycache_size; | ||
1650 | if (common->keymax > ATH_KEYMAX) { | ||
1651 | ath_print(common, ATH_DBG_ANY, | ||
1652 | "Warning, using only %u entries in %u key cache\n", | ||
1653 | ATH_KEYMAX, common->keymax); | ||
1654 | common->keymax = ATH_KEYMAX; | ||
1655 | } | ||
1656 | |||
1657 | /* | ||
1658 | * Reset the key cache since some parts do not | ||
1659 | * reset the contents on initial power up. | ||
1660 | */ | ||
1661 | for (i = 0; i < common->keymax; i++) | ||
1662 | ath9k_hw_keyreset(ah, (u16) i); | ||
1663 | |||
1664 | /* default to MONITOR mode */ | ||
1665 | sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; | ||
1666 | |||
1667 | /* | ||
1668 | * Allocate hardware transmit queues: one queue for | ||
1669 | * beacon frames and one data queue for each QoS | ||
1670 | * priority. Note that the hal handles reseting | ||
1671 | * these queues at the needed time. | ||
1672 | */ | ||
1673 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah); | ||
1674 | if (sc->beacon.beaconq == -1) { | ||
1675 | ath_print(common, ATH_DBG_FATAL, | ||
1676 | "Unable to setup a beacon xmit queue\n"); | ||
1677 | r = -EIO; | ||
1678 | goto bad2; | ||
1679 | } | ||
1680 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | ||
1681 | if (sc->beacon.cabq == NULL) { | ||
1682 | ath_print(common, ATH_DBG_FATAL, | ||
1683 | "Unable to setup CAB xmit queue\n"); | ||
1684 | r = -EIO; | ||
1685 | goto bad2; | ||
1686 | } | ||
1687 | |||
1688 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | ||
1689 | ath_cabq_update(sc); | ||
1690 | |||
1691 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
1692 | sc->tx.hwq_map[i] = -1; | ||
1693 | |||
1694 | /* Setup data queues */ | ||
1695 | /* NB: ensure BK queue is the lowest priority h/w queue */ | ||
1696 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | ||
1697 | ath_print(common, ATH_DBG_FATAL, | ||
1698 | "Unable to setup xmit queue for BK traffic\n"); | ||
1699 | r = -EIO; | ||
1700 | goto bad2; | ||
1701 | } | ||
1702 | |||
1703 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | ||
1704 | ath_print(common, ATH_DBG_FATAL, | ||
1705 | "Unable to setup xmit queue for BE traffic\n"); | ||
1706 | r = -EIO; | ||
1707 | goto bad2; | ||
1708 | } | ||
1709 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | ||
1710 | ath_print(common, ATH_DBG_FATAL, | ||
1711 | "Unable to setup xmit queue for VI traffic\n"); | ||
1712 | r = -EIO; | ||
1713 | goto bad2; | ||
1714 | } | ||
1715 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | ||
1716 | ath_print(common, ATH_DBG_FATAL, | ||
1717 | "Unable to setup xmit queue for VO traffic\n"); | ||
1718 | r = -EIO; | ||
1719 | goto bad2; | ||
1720 | } | ||
1721 | |||
1722 | /* Initializes the noise floor to a reasonable default value. | ||
1723 | * Later on this will be updated during ANI processing. */ | ||
1724 | |||
1725 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
1726 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | ||
1727 | |||
1728 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1729 | ATH9K_CIPHER_TKIP, NULL)) { | ||
1730 | /* | ||
1731 | * Whether we should enable h/w TKIP MIC. | ||
1732 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | ||
1733 | * report WMM capable, so it's always safe to turn on | ||
1734 | * TKIP MIC in this case. | ||
1735 | */ | ||
1736 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, | ||
1737 | 0, 1, NULL); | ||
1738 | } | ||
1739 | |||
1740 | /* | ||
1741 | * Check whether the separate key cache entries | ||
1742 | * are required to handle both tx+rx MIC keys. | ||
1743 | * With split mic keys the number of stations is limited | ||
1744 | * to 27 otherwise 59. | ||
1745 | */ | ||
1746 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1747 | ATH9K_CIPHER_TKIP, NULL) | ||
1748 | && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1749 | ATH9K_CIPHER_MIC, NULL) | ||
1750 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, | ||
1751 | 0, NULL)) | ||
1752 | common->splitmic = 1; | ||
1753 | |||
1754 | /* turn on mcast key search if possible */ | ||
1755 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | ||
1756 | (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1, | ||
1757 | 1, NULL); | ||
1758 | |||
1759 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | ||
1760 | |||
1761 | /* 11n Capabilities */ | ||
1762 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
1763 | sc->sc_flags |= SC_OP_TXAGGR; | ||
1764 | sc->sc_flags |= SC_OP_RXAGGR; | ||
1765 | } | ||
1766 | |||
1767 | common->tx_chainmask = ah->caps.tx_chainmask; | ||
1768 | common->rx_chainmask = ah->caps.rx_chainmask; | ||
1769 | |||
1770 | ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | ||
1771 | sc->rx.defant = ath9k_hw_getdefantenna(ah); | ||
1772 | |||
1773 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
1774 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
1775 | |||
1776 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ | ||
1777 | |||
1778 | /* initialize beacon slots */ | ||
1779 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | ||
1780 | sc->beacon.bslot[i] = NULL; | ||
1781 | sc->beacon.bslot_aphy[i] = NULL; | ||
1782 | } | ||
1783 | |||
1784 | /* setup channels and rates */ | ||
1785 | |||
1786 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { | ||
1787 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; | ||
1788 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
1789 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
1790 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
1791 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
1792 | sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
1793 | ARRAY_SIZE(ath9k_legacy_rates); | ||
1794 | } | ||
1795 | |||
1796 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { | ||
1797 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; | ||
1798 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
1799 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
1800 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
1801 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
1802 | ath9k_legacy_rates + 4; | ||
1803 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | ||
1804 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | ||
1805 | } | ||
1806 | |||
1807 | switch (ah->btcoex_hw.scheme) { | ||
1808 | case ATH_BTCOEX_CFG_NONE: | ||
1809 | break; | ||
1810 | case ATH_BTCOEX_CFG_2WIRE: | ||
1811 | ath9k_hw_btcoex_init_2wire(ah); | ||
1812 | break; | ||
1813 | case ATH_BTCOEX_CFG_3WIRE: | ||
1814 | ath9k_hw_btcoex_init_3wire(ah); | ||
1815 | r = ath_init_btcoex_timer(sc); | ||
1816 | if (r) | ||
1817 | goto bad2; | ||
1818 | qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); | ||
1819 | ath9k_hw_init_btcoex_hw(ah, qnum); | ||
1820 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
1821 | break; | ||
1822 | default: | ||
1823 | WARN_ON(1); | ||
1824 | break; | ||
1825 | } | ||
1826 | |||
1827 | return 0; | ||
1828 | bad2: | ||
1829 | /* cleanup tx queues */ | ||
1830 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1831 | if (ATH_TXQ_SETUP(sc, i)) | ||
1832 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1833 | |||
1834 | bad_free_hw: | ||
1835 | ath9k_uninit_hw(sc); | ||
1836 | return r; | ||
1837 | } | ||
1838 | |||
1839 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
1840 | { | ||
1841 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
1842 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
1843 | IEEE80211_HW_SIGNAL_DBM | | ||
1844 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
1845 | IEEE80211_HW_SUPPORTS_PS | | ||
1846 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
1847 | IEEE80211_HW_SPECTRUM_MGMT; | ||
1848 | |||
1849 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) | ||
1850 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
1851 | |||
1852 | hw->wiphy->interface_modes = | ||
1853 | BIT(NL80211_IFTYPE_AP) | | ||
1854 | BIT(NL80211_IFTYPE_STATION) | | ||
1855 | BIT(NL80211_IFTYPE_ADHOC) | | ||
1856 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
1857 | |||
1858 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1859 | |||
1860 | hw->queues = 4; | ||
1861 | hw->max_rates = 4; | ||
1862 | hw->channel_change_time = 5000; | ||
1863 | hw->max_listen_interval = 10; | ||
1864 | /* Hardware supports 10 but we use 4 */ | ||
1865 | hw->max_rate_tries = 4; | ||
1866 | hw->sta_data_size = sizeof(struct ath_node); | ||
1867 | hw->vif_data_size = sizeof(struct ath_vif); | ||
1868 | |||
1869 | hw->rate_control_algorithm = "ath9k_rate_control"; | ||
1870 | |||
1871 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | ||
1872 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
1873 | &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
1874 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
1875 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
1876 | &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
1877 | } | ||
1878 | |||
1879 | /* Device driver core initialization */ | ||
1880 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
1881 | const struct ath_bus_ops *bus_ops) | ||
1882 | { | ||
1883 | struct ieee80211_hw *hw = sc->hw; | ||
1884 | struct ath_common *common; | ||
1885 | struct ath_hw *ah; | ||
1886 | int error = 0, i; | ||
1887 | struct ath_regulatory *reg; | ||
1888 | |||
1889 | dev_dbg(sc->dev, "Attach ATH hw\n"); | ||
1890 | |||
1891 | error = ath_init_softc(devid, sc, subsysid, bus_ops); | ||
1892 | if (error != 0) | ||
1893 | return error; | ||
1894 | |||
1895 | ah = sc->sc_ah; | ||
1896 | common = ath9k_hw_common(ah); | ||
1897 | |||
1898 | /* get mac address from hardware and set in mac80211 */ | ||
1899 | |||
1900 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | ||
1901 | |||
1902 | ath_set_hw_capab(sc, hw); | ||
1903 | |||
1904 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, | ||
1905 | ath9k_reg_notifier); | ||
1906 | if (error) | ||
1907 | return error; | ||
1908 | |||
1909 | reg = &common->regulatory; | ||
1910 | |||
1911 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
1912 | if (test_bit(ATH9K_MODE_11G, ah->caps.wireless_modes)) | ||
1913 | setup_ht_cap(sc, | ||
1914 | &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
1915 | if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) | ||
1916 | setup_ht_cap(sc, | ||
1917 | &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
1918 | } | ||
1919 | |||
1920 | /* initialize tx/rx engine */ | ||
1921 | error = ath_tx_init(sc, ATH_TXBUF); | ||
1922 | if (error != 0) | ||
1923 | goto error_attach; | ||
1924 | |||
1925 | error = ath_rx_init(sc, ATH_RXBUF); | ||
1926 | if (error != 0) | ||
1927 | goto error_attach; | ||
1928 | |||
1929 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | ||
1930 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | ||
1931 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
1932 | |||
1933 | error = ieee80211_register_hw(hw); | ||
1934 | |||
1935 | if (!ath_is_world_regd(reg)) { | ||
1936 | error = regulatory_hint(hw->wiphy, reg->alpha2); | ||
1937 | if (error) | ||
1938 | goto error_attach; | ||
1939 | } | ||
1940 | |||
1941 | /* Initialize LED control */ | ||
1942 | ath_init_leds(sc); | ||
1943 | |||
1944 | ath_start_rfkill_poll(sc); | ||
1945 | |||
1946 | return 0; | ||
1947 | |||
1948 | error_attach: | ||
1949 | /* cleanup tx queues */ | ||
1950 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1951 | if (ATH_TXQ_SETUP(sc, i)) | ||
1952 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1953 | |||
1954 | ath9k_uninit_hw(sc); | ||
1955 | |||
1956 | return error; | ||
1957 | } | ||
1958 | |||
1959 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 937 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
1960 | { | 938 | { |
1961 | struct ath_hw *ah = sc->sc_ah; | 939 | struct ath_hw *ah = sc->sc_ah; |
@@ -1966,6 +944,8 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1966 | /* Stop ANI */ | 944 | /* Stop ANI */ |
1967 | del_timer_sync(&common->ani.timer); | 945 | del_timer_sync(&common->ani.timer); |
1968 | 946 | ||
947 | ieee80211_stop_queues(hw); | ||
948 | |||
1969 | ath9k_hw_set_interrupts(ah, 0); | 949 | ath9k_hw_set_interrupts(ah, 0); |
1970 | ath_drain_all_txq(sc, retry_tx); | 950 | ath_drain_all_txq(sc, retry_tx); |
1971 | ath_stoprecv(sc); | 951 | ath_stoprecv(sc); |
@@ -2007,131 +987,14 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
2007 | } | 987 | } |
2008 | } | 988 | } |
2009 | 989 | ||
990 | ieee80211_wake_queues(hw); | ||
991 | |||
2010 | /* Start ANI */ | 992 | /* Start ANI */ |
2011 | ath_start_ani(common); | 993 | ath_start_ani(common); |
2012 | 994 | ||
2013 | return r; | 995 | return r; |
2014 | } | 996 | } |
2015 | 997 | ||
2016 | /* | ||
2017 | * This function will allocate both the DMA descriptor structure, and the | ||
2018 | * buffers it contains. These are used to contain the descriptors used | ||
2019 | * by the system. | ||
2020 | */ | ||
2021 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | ||
2022 | struct list_head *head, const char *name, | ||
2023 | int nbuf, int ndesc) | ||
2024 | { | ||
2025 | #define DS2PHYS(_dd, _ds) \ | ||
2026 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) | ||
2027 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) | ||
2028 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) | ||
2029 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2030 | struct ath_desc *ds; | ||
2031 | struct ath_buf *bf; | ||
2032 | int i, bsize, error; | ||
2033 | |||
2034 | ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | ||
2035 | name, nbuf, ndesc); | ||
2036 | |||
2037 | INIT_LIST_HEAD(head); | ||
2038 | /* ath_desc must be a multiple of DWORDs */ | ||
2039 | if ((sizeof(struct ath_desc) % 4) != 0) { | ||
2040 | ath_print(common, ATH_DBG_FATAL, | ||
2041 | "ath_desc not DWORD aligned\n"); | ||
2042 | BUG_ON((sizeof(struct ath_desc) % 4) != 0); | ||
2043 | error = -ENOMEM; | ||
2044 | goto fail; | ||
2045 | } | ||
2046 | |||
2047 | dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; | ||
2048 | |||
2049 | /* | ||
2050 | * Need additional DMA memory because we can't use | ||
2051 | * descriptors that cross the 4K page boundary. Assume | ||
2052 | * one skipped descriptor per 4K page. | ||
2053 | */ | ||
2054 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
2055 | u32 ndesc_skipped = | ||
2056 | ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); | ||
2057 | u32 dma_len; | ||
2058 | |||
2059 | while (ndesc_skipped) { | ||
2060 | dma_len = ndesc_skipped * sizeof(struct ath_desc); | ||
2061 | dd->dd_desc_len += dma_len; | ||
2062 | |||
2063 | ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); | ||
2064 | }; | ||
2065 | } | ||
2066 | |||
2067 | /* allocate descriptors */ | ||
2068 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | ||
2069 | &dd->dd_desc_paddr, GFP_KERNEL); | ||
2070 | if (dd->dd_desc == NULL) { | ||
2071 | error = -ENOMEM; | ||
2072 | goto fail; | ||
2073 | } | ||
2074 | ds = dd->dd_desc; | ||
2075 | ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | ||
2076 | name, ds, (u32) dd->dd_desc_len, | ||
2077 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | ||
2078 | |||
2079 | /* allocate buffers */ | ||
2080 | bsize = sizeof(struct ath_buf) * nbuf; | ||
2081 | bf = kzalloc(bsize, GFP_KERNEL); | ||
2082 | if (bf == NULL) { | ||
2083 | error = -ENOMEM; | ||
2084 | goto fail2; | ||
2085 | } | ||
2086 | dd->dd_bufptr = bf; | ||
2087 | |||
2088 | for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { | ||
2089 | bf->bf_desc = ds; | ||
2090 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
2091 | |||
2092 | if (!(sc->sc_ah->caps.hw_caps & | ||
2093 | ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
2094 | /* | ||
2095 | * Skip descriptor addresses which can cause 4KB | ||
2096 | * boundary crossing (addr + length) with a 32 dword | ||
2097 | * descriptor fetch. | ||
2098 | */ | ||
2099 | while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { | ||
2100 | BUG_ON((caddr_t) bf->bf_desc >= | ||
2101 | ((caddr_t) dd->dd_desc + | ||
2102 | dd->dd_desc_len)); | ||
2103 | |||
2104 | ds += ndesc; | ||
2105 | bf->bf_desc = ds; | ||
2106 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
2107 | } | ||
2108 | } | ||
2109 | list_add_tail(&bf->list, head); | ||
2110 | } | ||
2111 | return 0; | ||
2112 | fail2: | ||
2113 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
2114 | dd->dd_desc_paddr); | ||
2115 | fail: | ||
2116 | memset(dd, 0, sizeof(*dd)); | ||
2117 | return error; | ||
2118 | #undef ATH_DESC_4KB_BOUND_CHECK | ||
2119 | #undef ATH_DESC_4KB_BOUND_NUM_SKIPPED | ||
2120 | #undef DS2PHYS | ||
2121 | } | ||
2122 | |||
2123 | void ath_descdma_cleanup(struct ath_softc *sc, | ||
2124 | struct ath_descdma *dd, | ||
2125 | struct list_head *head) | ||
2126 | { | ||
2127 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
2128 | dd->dd_desc_paddr); | ||
2129 | |||
2130 | INIT_LIST_HEAD(head); | ||
2131 | kfree(dd->dd_bufptr); | ||
2132 | memset(dd, 0, sizeof(*dd)); | ||
2133 | } | ||
2134 | |||
2135 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) | 998 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) |
2136 | { | 999 | { |
2137 | int qnum; | 1000 | int qnum; |
@@ -2210,28 +1073,6 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
2210 | /* mac80211 callbacks */ | 1073 | /* mac80211 callbacks */ |
2211 | /**********************/ | 1074 | /**********************/ |
2212 | 1075 | ||
2213 | /* | ||
2214 | * (Re)start btcoex timers | ||
2215 | */ | ||
2216 | static void ath9k_btcoex_timer_resume(struct ath_softc *sc) | ||
2217 | { | ||
2218 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
2219 | struct ath_hw *ah = sc->sc_ah; | ||
2220 | |||
2221 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
2222 | "Starting btcoex timers"); | ||
2223 | |||
2224 | /* make sure duty cycle timer is also stopped when resuming */ | ||
2225 | if (btcoex->hw_timer_enabled) | ||
2226 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
2227 | |||
2228 | btcoex->bt_priority_cnt = 0; | ||
2229 | btcoex->bt_priority_time = jiffies; | ||
2230 | sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; | ||
2231 | |||
2232 | mod_timer(&btcoex->period_timer, jiffies); | ||
2233 | } | ||
2234 | |||
2235 | static int ath9k_start(struct ieee80211_hw *hw) | 1076 | static int ath9k_start(struct ieee80211_hw *hw) |
2236 | { | 1077 | { |
2237 | struct ath_wiphy *aphy = hw->priv; | 1078 | struct ath_wiphy *aphy = hw->priv; |
@@ -2401,11 +1242,11 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2401 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 1242 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
2402 | ath_print(common, ATH_DBG_PS, | 1243 | ath_print(common, ATH_DBG_PS, |
2403 | "Sending PS-Poll to pick a buffered frame\n"); | 1244 | "Sending PS-Poll to pick a buffered frame\n"); |
2404 | sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA; | 1245 | sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA; |
2405 | } else { | 1246 | } else { |
2406 | ath_print(common, ATH_DBG_PS, | 1247 | ath_print(common, ATH_DBG_PS, |
2407 | "Wake up to complete TX\n"); | 1248 | "Wake up to complete TX\n"); |
2408 | sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK; | 1249 | sc->ps_flags |= PS_WAIT_FOR_TX_ACK; |
2409 | } | 1250 | } |
2410 | /* | 1251 | /* |
2411 | * The actual restore operation will happen only after | 1252 | * The actual restore operation will happen only after |
@@ -2458,22 +1299,6 @@ exit: | |||
2458 | return 0; | 1299 | return 0; |
2459 | } | 1300 | } |
2460 | 1301 | ||
2461 | /* | ||
2462 | * Pause btcoex timer and bt duty cycle timer | ||
2463 | */ | ||
2464 | static void ath9k_btcoex_timer_pause(struct ath_softc *sc) | ||
2465 | { | ||
2466 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
2467 | struct ath_hw *ah = sc->sc_ah; | ||
2468 | |||
2469 | del_timer_sync(&btcoex->period_timer); | ||
2470 | |||
2471 | if (btcoex->hw_timer_enabled) | ||
2472 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
2473 | |||
2474 | btcoex->hw_timer_enabled = false; | ||
2475 | } | ||
2476 | |||
2477 | static void ath9k_stop(struct ieee80211_hw *hw) | 1302 | static void ath9k_stop(struct ieee80211_hw *hw) |
2478 | { | 1303 | { |
2479 | struct ath_wiphy *aphy = hw->priv; | 1304 | struct ath_wiphy *aphy = hw->priv; |
@@ -2717,7 +1542,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2717 | */ | 1542 | */ |
2718 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 1543 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
2719 | if (conf->flags & IEEE80211_CONF_PS) { | 1544 | if (conf->flags & IEEE80211_CONF_PS) { |
2720 | sc->sc_flags |= SC_OP_PS_ENABLED; | 1545 | sc->ps_flags |= PS_ENABLED; |
2721 | if (!(ah->caps.hw_caps & | 1546 | if (!(ah->caps.hw_caps & |
2722 | ATH9K_HW_CAP_AUTOSLEEP)) { | 1547 | ATH9K_HW_CAP_AUTOSLEEP)) { |
2723 | if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { | 1548 | if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { |
@@ -2730,23 +1555,23 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2730 | * At this point we know hardware has received an ACK | 1555 | * At this point we know hardware has received an ACK |
2731 | * of a previously sent null data frame. | 1556 | * of a previously sent null data frame. |
2732 | */ | 1557 | */ |
2733 | if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) { | 1558 | if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) { |
2734 | sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; | 1559 | sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; |
2735 | sc->ps_enabled = true; | 1560 | sc->ps_enabled = true; |
2736 | ath9k_hw_setrxabort(sc->sc_ah, 1); | 1561 | ath9k_hw_setrxabort(sc->sc_ah, 1); |
2737 | } | 1562 | } |
2738 | } else { | 1563 | } else { |
2739 | sc->ps_enabled = false; | 1564 | sc->ps_enabled = false; |
2740 | sc->sc_flags &= ~(SC_OP_PS_ENABLED | | 1565 | sc->ps_flags &= ~(PS_ENABLED | |
2741 | SC_OP_NULLFUNC_COMPLETED); | 1566 | PS_NULLFUNC_COMPLETED); |
2742 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | 1567 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
2743 | if (!(ah->caps.hw_caps & | 1568 | if (!(ah->caps.hw_caps & |
2744 | ATH9K_HW_CAP_AUTOSLEEP)) { | 1569 | ATH9K_HW_CAP_AUTOSLEEP)) { |
2745 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 1570 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
2746 | sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | | 1571 | sc->ps_flags &= ~(PS_WAIT_FOR_BEACON | |
2747 | SC_OP_WAIT_FOR_CAB | | 1572 | PS_WAIT_FOR_CAB | |
2748 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 1573 | PS_WAIT_FOR_PSPOLL_DATA | |
2749 | SC_OP_WAIT_FOR_TX_ACK); | 1574 | PS_WAIT_FOR_TX_ACK); |
2750 | if (sc->imask & ATH9K_INT_TIM_TIMER) { | 1575 | if (sc->imask & ATH9K_INT_TIM_TIMER) { |
2751 | sc->imask &= ~ATH9K_INT_TIM_TIMER; | 1576 | sc->imask &= ~ATH9K_INT_TIM_TIMER; |
2752 | ath9k_hw_set_interrupts(sc->sc_ah, | 1577 | ath9k_hw_set_interrupts(sc->sc_ah, |
@@ -2756,6 +1581,14 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2756 | } | 1581 | } |
2757 | } | 1582 | } |
2758 | 1583 | ||
1584 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | ||
1585 | if (conf->flags & IEEE80211_CONF_MONITOR) { | ||
1586 | ath_print(common, ATH_DBG_CONFIG, | ||
1587 | "HW opmode set to Monitor mode\n"); | ||
1588 | sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; | ||
1589 | } | ||
1590 | } | ||
1591 | |||
2759 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1592 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
2760 | struct ieee80211_channel *curchan = hw->conf.channel; | 1593 | struct ieee80211_channel *curchan = hw->conf.channel; |
2761 | int pos = curchan->hw_value; | 1594 | int pos = curchan->hw_value; |
@@ -2956,6 +1789,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2956 | struct ath_hw *ah = sc->sc_ah; | 1789 | struct ath_hw *ah = sc->sc_ah; |
2957 | struct ath_common *common = ath9k_hw_common(ah); | 1790 | struct ath_common *common = ath9k_hw_common(ah); |
2958 | struct ath_vif *avp = (void *)vif->drv_priv; | 1791 | struct ath_vif *avp = (void *)vif->drv_priv; |
1792 | int slottime; | ||
2959 | int error; | 1793 | int error; |
2960 | 1794 | ||
2961 | mutex_lock(&sc->mutex); | 1795 | mutex_lock(&sc->mutex); |
@@ -2991,6 +1825,25 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2991 | ath_beacon_config(sc, vif); | 1825 | ath_beacon_config(sc, vif); |
2992 | } | 1826 | } |
2993 | 1827 | ||
1828 | if (changed & BSS_CHANGED_ERP_SLOT) { | ||
1829 | if (bss_conf->use_short_slot) | ||
1830 | slottime = 9; | ||
1831 | else | ||
1832 | slottime = 20; | ||
1833 | if (vif->type == NL80211_IFTYPE_AP) { | ||
1834 | /* | ||
1835 | * Defer update, so that connected stations can adjust | ||
1836 | * their settings at the same time. | ||
1837 | * See beacon.c for more details | ||
1838 | */ | ||
1839 | sc->beacon.slottime = slottime; | ||
1840 | sc->beacon.updateslot = UPDATE; | ||
1841 | } else { | ||
1842 | ah->slottime = slottime; | ||
1843 | ath9k_hw_init_global_settings(ah); | ||
1844 | } | ||
1845 | } | ||
1846 | |||
2994 | /* Disable transmission of beacons */ | 1847 | /* Disable transmission of beacons */ |
2995 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) | 1848 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) |
2996 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1849 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
@@ -3161,6 +2014,18 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
3161 | mutex_unlock(&sc->mutex); | 2014 | mutex_unlock(&sc->mutex); |
3162 | } | 2015 | } |
3163 | 2016 | ||
2017 | static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | ||
2018 | { | ||
2019 | struct ath_wiphy *aphy = hw->priv; | ||
2020 | struct ath_softc *sc = aphy->sc; | ||
2021 | struct ath_hw *ah = sc->sc_ah; | ||
2022 | |||
2023 | mutex_lock(&sc->mutex); | ||
2024 | ah->coverage_class = coverage_class; | ||
2025 | ath9k_hw_init_global_settings(ah); | ||
2026 | mutex_unlock(&sc->mutex); | ||
2027 | } | ||
2028 | |||
3164 | struct ieee80211_ops ath9k_ops = { | 2029 | struct ieee80211_ops ath9k_ops = { |
3165 | .tx = ath9k_tx, | 2030 | .tx = ath9k_tx, |
3166 | .start = ath9k_start, | 2031 | .start = ath9k_start, |
@@ -3180,64 +2045,5 @@ struct ieee80211_ops ath9k_ops = { | |||
3180 | .sw_scan_start = ath9k_sw_scan_start, | 2045 | .sw_scan_start = ath9k_sw_scan_start, |
3181 | .sw_scan_complete = ath9k_sw_scan_complete, | 2046 | .sw_scan_complete = ath9k_sw_scan_complete, |
3182 | .rfkill_poll = ath9k_rfkill_poll_state, | 2047 | .rfkill_poll = ath9k_rfkill_poll_state, |
2048 | .set_coverage_class = ath9k_set_coverage_class, | ||
3183 | }; | 2049 | }; |
3184 | |||
3185 | static int __init ath9k_init(void) | ||
3186 | { | ||
3187 | int error; | ||
3188 | |||
3189 | /* Register rate control algorithm */ | ||
3190 | error = ath_rate_control_register(); | ||
3191 | if (error != 0) { | ||
3192 | printk(KERN_ERR | ||
3193 | "ath9k: Unable to register rate control " | ||
3194 | "algorithm: %d\n", | ||
3195 | error); | ||
3196 | goto err_out; | ||
3197 | } | ||
3198 | |||
3199 | error = ath9k_debug_create_root(); | ||
3200 | if (error) { | ||
3201 | printk(KERN_ERR | ||
3202 | "ath9k: Unable to create debugfs root: %d\n", | ||
3203 | error); | ||
3204 | goto err_rate_unregister; | ||
3205 | } | ||
3206 | |||
3207 | error = ath_pci_init(); | ||
3208 | if (error < 0) { | ||
3209 | printk(KERN_ERR | ||
3210 | "ath9k: No PCI devices found, driver not installed.\n"); | ||
3211 | error = -ENODEV; | ||
3212 | goto err_remove_root; | ||
3213 | } | ||
3214 | |||
3215 | error = ath_ahb_init(); | ||
3216 | if (error < 0) { | ||
3217 | error = -ENODEV; | ||
3218 | goto err_pci_exit; | ||
3219 | } | ||
3220 | |||
3221 | return 0; | ||
3222 | |||
3223 | err_pci_exit: | ||
3224 | ath_pci_exit(); | ||
3225 | |||
3226 | err_remove_root: | ||
3227 | ath9k_debug_remove_root(); | ||
3228 | err_rate_unregister: | ||
3229 | ath_rate_control_unregister(); | ||
3230 | err_out: | ||
3231 | return error; | ||
3232 | } | ||
3233 | module_init(ath9k_init); | ||
3234 | |||
3235 | static void __exit ath9k_exit(void) | ||
3236 | { | ||
3237 | ath_ahb_exit(); | ||
3238 | ath_pci_exit(); | ||
3239 | ath9k_debug_remove_root(); | ||
3240 | ath_rate_control_unregister(); | ||
3241 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | ||
3242 | } | ||
3243 | module_exit(ath9k_exit); | ||
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index ee617205cb4..fe2c3a644a6 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -113,25 +113,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
113 | u16 subsysid; | 113 | u16 subsysid; |
114 | u32 val; | 114 | u32 val; |
115 | int ret = 0; | 115 | int ret = 0; |
116 | struct ath_hw *ah; | ||
117 | char hw_name[64]; | 116 | char hw_name[64]; |
118 | 117 | ||
119 | if (pci_enable_device(pdev)) | 118 | if (pci_enable_device(pdev)) |
120 | return -EIO; | 119 | return -EIO; |
121 | 120 | ||
122 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 121 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
123 | |||
124 | if (ret) { | 122 | if (ret) { |
125 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); | 123 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); |
126 | goto bad; | 124 | goto err_dma; |
127 | } | 125 | } |
128 | 126 | ||
129 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | 127 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
130 | |||
131 | if (ret) { | 128 | if (ret) { |
132 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | 129 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " |
133 | "DMA enable failed\n"); | 130 | "DMA enable failed\n"); |
134 | goto bad; | 131 | goto err_dma; |
135 | } | 132 | } |
136 | 133 | ||
137 | /* | 134 | /* |
@@ -171,22 +168,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
171 | if (ret) { | 168 | if (ret) { |
172 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); | 169 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); |
173 | ret = -ENODEV; | 170 | ret = -ENODEV; |
174 | goto bad; | 171 | goto err_region; |
175 | } | 172 | } |
176 | 173 | ||
177 | mem = pci_iomap(pdev, 0, 0); | 174 | mem = pci_iomap(pdev, 0, 0); |
178 | if (!mem) { | 175 | if (!mem) { |
179 | printk(KERN_ERR "PCI memory map error\n") ; | 176 | printk(KERN_ERR "PCI memory map error\n") ; |
180 | ret = -EIO; | 177 | ret = -EIO; |
181 | goto bad1; | 178 | goto err_iomap; |
182 | } | 179 | } |
183 | 180 | ||
184 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + | 181 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + |
185 | sizeof(struct ath_softc), &ath9k_ops); | 182 | sizeof(struct ath_softc), &ath9k_ops); |
186 | if (!hw) { | 183 | if (!hw) { |
187 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | 184 | dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); |
188 | ret = -ENOMEM; | 185 | ret = -ENOMEM; |
189 | goto bad2; | 186 | goto err_alloc_hw; |
190 | } | 187 | } |
191 | 188 | ||
192 | SET_IEEE80211_DEV(hw, &pdev->dev); | 189 | SET_IEEE80211_DEV(hw, &pdev->dev); |
@@ -201,25 +198,25 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
201 | sc->dev = &pdev->dev; | 198 | sc->dev = &pdev->dev; |
202 | sc->mem = mem; | 199 | sc->mem = mem; |
203 | 200 | ||
204 | pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); | 201 | /* Will be cleared in ath9k_start() */ |
205 | ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); | 202 | sc->sc_flags |= SC_OP_INVALID; |
206 | if (ret) { | ||
207 | dev_err(&pdev->dev, "failed to initialize device\n"); | ||
208 | goto bad3; | ||
209 | } | ||
210 | |||
211 | /* setup interrupt service routine */ | ||
212 | 203 | ||
213 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 204 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
214 | if (ret) { | 205 | if (ret) { |
215 | dev_err(&pdev->dev, "request_irq failed\n"); | 206 | dev_err(&pdev->dev, "request_irq failed\n"); |
216 | goto bad4; | 207 | goto err_irq; |
217 | } | 208 | } |
218 | 209 | ||
219 | sc->irq = pdev->irq; | 210 | sc->irq = pdev->irq; |
220 | 211 | ||
221 | ah = sc->sc_ah; | 212 | pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); |
222 | ath9k_hw_name(ah, hw_name, sizeof(hw_name)); | 213 | ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); |
214 | if (ret) { | ||
215 | dev_err(&pdev->dev, "Failed to initialize device\n"); | ||
216 | goto err_init; | ||
217 | } | ||
218 | |||
219 | ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); | ||
223 | printk(KERN_INFO | 220 | printk(KERN_INFO |
224 | "%s: %s mem=0x%lx, irq=%d\n", | 221 | "%s: %s mem=0x%lx, irq=%d\n", |
225 | wiphy_name(hw->wiphy), | 222 | wiphy_name(hw->wiphy), |
@@ -227,15 +224,18 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
227 | (unsigned long)mem, pdev->irq); | 224 | (unsigned long)mem, pdev->irq); |
228 | 225 | ||
229 | return 0; | 226 | return 0; |
230 | bad4: | 227 | |
231 | ath_detach(sc); | 228 | err_init: |
232 | bad3: | 229 | free_irq(sc->irq, sc); |
230 | err_irq: | ||
233 | ieee80211_free_hw(hw); | 231 | ieee80211_free_hw(hw); |
234 | bad2: | 232 | err_alloc_hw: |
235 | pci_iounmap(pdev, mem); | 233 | pci_iounmap(pdev, mem); |
236 | bad1: | 234 | err_iomap: |
237 | pci_release_region(pdev, 0); | 235 | pci_release_region(pdev, 0); |
238 | bad: | 236 | err_region: |
237 | /* Nothing */ | ||
238 | err_dma: | ||
239 | pci_disable_device(pdev); | 239 | pci_disable_device(pdev); |
240 | return ret; | 240 | return ret; |
241 | } | 241 | } |
@@ -245,8 +245,12 @@ static void ath_pci_remove(struct pci_dev *pdev) | |||
245 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 245 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
246 | struct ath_wiphy *aphy = hw->priv; | 246 | struct ath_wiphy *aphy = hw->priv; |
247 | struct ath_softc *sc = aphy->sc; | 247 | struct ath_softc *sc = aphy->sc; |
248 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
248 | 249 | ||
249 | ath_cleanup(sc); | 250 | ath9k_deinit_device(sc); |
251 | free_irq(sc->irq, sc); | ||
252 | ieee80211_free_hw(sc->hw); | ||
253 | ath_bus_cleanup(common); | ||
250 | } | 254 | } |
251 | 255 | ||
252 | #ifdef CONFIG_PM | 256 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 477365e5ae6..40b5d05edcc 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -364,10 +364,10 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
364 | if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) | 364 | if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) |
365 | return; /* not from our current AP */ | 365 | return; /* not from our current AP */ |
366 | 366 | ||
367 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | 367 | sc->ps_flags &= ~PS_WAIT_FOR_BEACON; |
368 | 368 | ||
369 | if (sc->sc_flags & SC_OP_BEACON_SYNC) { | 369 | if (sc->ps_flags & PS_BEACON_SYNC) { |
370 | sc->sc_flags &= ~SC_OP_BEACON_SYNC; | 370 | sc->ps_flags &= ~PS_BEACON_SYNC; |
371 | ath_print(common, ATH_DBG_PS, | 371 | ath_print(common, ATH_DBG_PS, |
372 | "Reconfigure Beacon timers based on " | 372 | "Reconfigure Beacon timers based on " |
373 | "timestamp from the AP\n"); | 373 | "timestamp from the AP\n"); |
@@ -384,17 +384,17 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
384 | */ | 384 | */ |
385 | ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating " | 385 | ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating " |
386 | "buffered broadcast/multicast frame(s)\n"); | 386 | "buffered broadcast/multicast frame(s)\n"); |
387 | sc->sc_flags |= SC_OP_WAIT_FOR_CAB | SC_OP_WAIT_FOR_BEACON; | 387 | sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON; |
388 | return; | 388 | return; |
389 | } | 389 | } |
390 | 390 | ||
391 | if (sc->sc_flags & SC_OP_WAIT_FOR_CAB) { | 391 | if (sc->ps_flags & PS_WAIT_FOR_CAB) { |
392 | /* | 392 | /* |
393 | * This can happen if a broadcast frame is dropped or the AP | 393 | * This can happen if a broadcast frame is dropped or the AP |
394 | * fails to send a frame indicating that all CAB frames have | 394 | * fails to send a frame indicating that all CAB frames have |
395 | * been delivered. | 395 | * been delivered. |
396 | */ | 396 | */ |
397 | sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB; | 397 | sc->ps_flags &= ~PS_WAIT_FOR_CAB; |
398 | ath_print(common, ATH_DBG_PS, | 398 | ath_print(common, ATH_DBG_PS, |
399 | "PS wait for CAB frames timed out\n"); | 399 | "PS wait for CAB frames timed out\n"); |
400 | } | 400 | } |
@@ -408,10 +408,10 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) | |||
408 | hdr = (struct ieee80211_hdr *)skb->data; | 408 | hdr = (struct ieee80211_hdr *)skb->data; |
409 | 409 | ||
410 | /* Process Beacon and CAB receive in PS state */ | 410 | /* Process Beacon and CAB receive in PS state */ |
411 | if ((sc->sc_flags & SC_OP_WAIT_FOR_BEACON) && | 411 | if ((sc->ps_flags & PS_WAIT_FOR_BEACON) && |
412 | ieee80211_is_beacon(hdr->frame_control)) | 412 | ieee80211_is_beacon(hdr->frame_control)) |
413 | ath_rx_ps_beacon(sc, skb); | 413 | ath_rx_ps_beacon(sc, skb); |
414 | else if ((sc->sc_flags & SC_OP_WAIT_FOR_CAB) && | 414 | else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && |
415 | (ieee80211_is_data(hdr->frame_control) || | 415 | (ieee80211_is_data(hdr->frame_control) || |
416 | ieee80211_is_action(hdr->frame_control)) && | 416 | ieee80211_is_action(hdr->frame_control)) && |
417 | is_multicast_ether_addr(hdr->addr1) && | 417 | is_multicast_ether_addr(hdr->addr1) && |
@@ -420,20 +420,20 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) | |||
420 | * No more broadcast/multicast frames to be received at this | 420 | * No more broadcast/multicast frames to be received at this |
421 | * point. | 421 | * point. |
422 | */ | 422 | */ |
423 | sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB; | 423 | sc->ps_flags &= ~PS_WAIT_FOR_CAB; |
424 | ath_print(common, ATH_DBG_PS, | 424 | ath_print(common, ATH_DBG_PS, |
425 | "All PS CAB frames received, back to sleep\n"); | 425 | "All PS CAB frames received, back to sleep\n"); |
426 | } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) && | 426 | } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) && |
427 | !is_multicast_ether_addr(hdr->addr1) && | 427 | !is_multicast_ether_addr(hdr->addr1) && |
428 | !ieee80211_has_morefrags(hdr->frame_control)) { | 428 | !ieee80211_has_morefrags(hdr->frame_control)) { |
429 | sc->sc_flags &= ~SC_OP_WAIT_FOR_PSPOLL_DATA; | 429 | sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA; |
430 | ath_print(common, ATH_DBG_PS, | 430 | ath_print(common, ATH_DBG_PS, |
431 | "Going back to sleep after having received " | 431 | "Going back to sleep after having received " |
432 | "PS-Poll data (0x%x)\n", | 432 | "PS-Poll data (0x%x)\n", |
433 | sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 433 | sc->ps_flags & (PS_WAIT_FOR_BEACON | |
434 | SC_OP_WAIT_FOR_CAB | | 434 | PS_WAIT_FOR_CAB | |
435 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 435 | PS_WAIT_FOR_PSPOLL_DATA | |
436 | SC_OP_WAIT_FOR_TX_ACK)); | 436 | PS_WAIT_FOR_TX_ACK)); |
437 | } | 437 | } |
438 | } | 438 | } |
439 | 439 | ||
@@ -571,6 +571,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
571 | hw = ath_get_virt_hw(sc, hdr); | 571 | hw = ath_get_virt_hw(sc, hdr); |
572 | rx_stats = &ds->ds_rxstat; | 572 | rx_stats = &ds->ds_rxstat; |
573 | 573 | ||
574 | ath_debug_stat_rx(sc, bf); | ||
575 | |||
574 | /* | 576 | /* |
575 | * If we're asked to flush receive queue, directly | 577 | * If we're asked to flush receive queue, directly |
576 | * chain it back at the queue without processing it. | 578 | * chain it back at the queue without processing it. |
@@ -631,9 +633,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
631 | sc->rx.rxotherant = 0; | 633 | sc->rx.rxotherant = 0; |
632 | } | 634 | } |
633 | 635 | ||
634 | if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 636 | if (unlikely(sc->ps_flags & (PS_WAIT_FOR_BEACON | |
635 | SC_OP_WAIT_FOR_CAB | | 637 | PS_WAIT_FOR_CAB | |
636 | SC_OP_WAIT_FOR_PSPOLL_DATA))) | 638 | PS_WAIT_FOR_PSPOLL_DATA))) |
637 | ath_rx_ps(sc, skb); | 639 | ath_rx_ps(sc, skb); |
638 | 640 | ||
639 | ath_rx_send_to_mac80211(hw, sc, skb, rxs); | 641 | ath_rx_send_to_mac80211(hw, sc, skb, rxs); |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index cd26caaf44e..a43fbf84dab 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -152,7 +152,7 @@ int ath9k_wiphy_add(struct ath_softc *sc) | |||
152 | 152 | ||
153 | SET_IEEE80211_PERM_ADDR(hw, addr); | 153 | SET_IEEE80211_PERM_ADDR(hw, addr); |
154 | 154 | ||
155 | ath_set_hw_capab(sc, hw); | 155 | ath9k_set_hw_capab(sc, hw); |
156 | 156 | ||
157 | error = ieee80211_register_hw(hw); | 157 | error = ieee80211_register_hw(hw); |
158 | 158 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index fa12b9060b0..a821bb687b3 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1648,7 +1648,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1648 | /* tag if this is a nullfunc frame to enable PS when AP acks it */ | 1648 | /* tag if this is a nullfunc frame to enable PS when AP acks it */ |
1649 | if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { | 1649 | if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { |
1650 | bf->bf_isnullfunc = true; | 1650 | bf->bf_isnullfunc = true; |
1651 | sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; | 1651 | sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; |
1652 | } else | 1652 | } else |
1653 | bf->bf_isnullfunc = false; | 1653 | bf->bf_isnullfunc = false; |
1654 | 1654 | ||
@@ -1858,15 +1858,15 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1858 | skb_pull(skb, padsize); | 1858 | skb_pull(skb, padsize); |
1859 | } | 1859 | } |
1860 | 1860 | ||
1861 | if (sc->sc_flags & SC_OP_WAIT_FOR_TX_ACK) { | 1861 | if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { |
1862 | sc->sc_flags &= ~SC_OP_WAIT_FOR_TX_ACK; | 1862 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; |
1863 | ath_print(common, ATH_DBG_PS, | 1863 | ath_print(common, ATH_DBG_PS, |
1864 | "Going back to sleep after having " | 1864 | "Going back to sleep after having " |
1865 | "received TX status (0x%x)\n", | 1865 | "received TX status (0x%x)\n", |
1866 | sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 1866 | sc->ps_flags & (PS_WAIT_FOR_BEACON | |
1867 | SC_OP_WAIT_FOR_CAB | | 1867 | PS_WAIT_FOR_CAB | |
1868 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 1868 | PS_WAIT_FOR_PSPOLL_DATA | |
1869 | SC_OP_WAIT_FOR_TX_ACK)); | 1869 | PS_WAIT_FOR_TX_ACK)); |
1870 | } | 1870 | } |
1871 | 1871 | ||
1872 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) | 1872 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) |
@@ -2053,11 +2053,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2053 | */ | 2053 | */ |
2054 | if (bf->bf_isnullfunc && | 2054 | if (bf->bf_isnullfunc && |
2055 | (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { | 2055 | (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { |
2056 | if ((sc->sc_flags & SC_OP_PS_ENABLED)) { | 2056 | if ((sc->ps_flags & PS_ENABLED)) { |
2057 | sc->ps_enabled = true; | 2057 | sc->ps_enabled = true; |
2058 | ath9k_hw_setrxabort(sc->sc_ah, 1); | 2058 | ath9k_hw_setrxabort(sc->sc_ah, 1); |
2059 | } else | 2059 | } else |
2060 | sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED; | 2060 | sc->ps_flags |= PS_NULLFUNC_COMPLETED; |
2061 | } | 2061 | } |
2062 | 2062 | ||
2063 | /* | 2063 | /* |