diff options
author | Oleksij Rempel <linux@rempel-privat.de> | 2014-03-01 15:15:56 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-03-17 13:13:07 -0400 |
commit | cbbdf2ae2d67b333d7a4db5ce8b7391b3de1256d (patch) | |
tree | 90f550ed4b22b81615bbf32ae53e0f8034734a0a | |
parent | a2030b9dbce8db1261a0a7985217361a992a8949 (diff) |
ath9k: move ath9k_beacon_config_sta to common-beacon
Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 80 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common-beacon.c | 126 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common-beacon.h | 21 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.h | 1 |
5 files changed, 153 insertions, 78 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index b58fe99ef745..8e1c7b0fe76c 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -52,7 +52,8 @@ obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o | |||
52 | 52 | ||
53 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o | 53 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o |
54 | ath9k_common-y:= common.o \ | 54 | ath9k_common-y:= common.o \ |
55 | common-init.o | 55 | common-init.o \ |
56 | common-beacon.o | ||
56 | 57 | ||
57 | ath9k_htc-y += htc_hst.o \ | 58 | ath9k_htc-y += htc_hst.o \ |
58 | hif_usb.o \ | 59 | hif_usb.o \ |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 637267187929..9333fa1c031f 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -505,87 +505,13 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc, | |||
505 | ath9k_beacon_init(sc, nexttbtt, intval, false); | 505 | ath9k_beacon_init(sc, nexttbtt, intval, false); |
506 | } | 506 | } |
507 | 507 | ||
508 | /* | 508 | static void ath9k_beacon_config_sta(struct ath_hw *ah, |
509 | * This sets up the beacon timers according to the timestamp of the last | ||
510 | * received beacon and the current TSF, configures PCF and DTIM | ||
511 | * handling, programs the sleep registers so the hardware will wakeup in | ||
512 | * time to receive beacons, and configures the beacon miss handling so | ||
513 | * we'll receive a BMISS interrupt when we stop seeing beacons from the AP | ||
514 | * we've associated with. | ||
515 | */ | ||
516 | static void ath9k_beacon_config_sta(struct ath_softc *sc, | ||
517 | struct ath_beacon_config *conf) | 509 | struct ath_beacon_config *conf) |
518 | { | 510 | { |
519 | struct ath_hw *ah = sc->sc_ah; | ||
520 | struct ath_common *common = ath9k_hw_common(ah); | ||
521 | struct ath9k_beacon_state bs; | 511 | struct ath9k_beacon_state bs; |
522 | int dtim_intval; | ||
523 | u32 nexttbtt = 0, intval; | ||
524 | u64 tsf; | ||
525 | 512 | ||
526 | /* No need to configure beacon if we are not associated */ | 513 | if (ath9k_cmn_beacon_config_sta(ah, conf, &bs) == -EPERM) |
527 | if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) { | ||
528 | ath_dbg(common, BEACON, | ||
529 | "STA is not yet associated..skipping beacon config\n"); | ||
530 | return; | 514 | return; |
531 | } | ||
532 | |||
533 | memset(&bs, 0, sizeof(bs)); | ||
534 | intval = conf->beacon_interval; | ||
535 | |||
536 | /* | ||
537 | * Setup dtim parameters according to | ||
538 | * last beacon we received (which may be none). | ||
539 | */ | ||
540 | dtim_intval = intval * conf->dtim_period; | ||
541 | |||
542 | /* | ||
543 | * Pull nexttbtt forward to reflect the current | ||
544 | * TSF and calculate dtim state for the result. | ||
545 | */ | ||
546 | tsf = ath9k_hw_gettsf64(ah); | ||
547 | nexttbtt = ath9k_get_next_tbtt(sc, tsf, intval); | ||
548 | |||
549 | bs.bs_intval = TU_TO_USEC(intval); | ||
550 | bs.bs_dtimperiod = conf->dtim_period * bs.bs_intval; | ||
551 | bs.bs_nexttbtt = nexttbtt; | ||
552 | bs.bs_nextdtim = nexttbtt; | ||
553 | if (conf->dtim_period > 1) | ||
554 | bs.bs_nextdtim = ath9k_get_next_tbtt(sc, tsf, dtim_intval); | ||
555 | |||
556 | /* | ||
557 | * Calculate the number of consecutive beacons to miss* before taking | ||
558 | * a BMISS interrupt. The configuration is specified in TU so we only | ||
559 | * need calculate based on the beacon interval. Note that we clamp the | ||
560 | * result to at most 15 beacons. | ||
561 | */ | ||
562 | bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval); | ||
563 | if (bs.bs_bmissthreshold > 15) | ||
564 | bs.bs_bmissthreshold = 15; | ||
565 | else if (bs.bs_bmissthreshold <= 0) | ||
566 | bs.bs_bmissthreshold = 1; | ||
567 | |||
568 | /* | ||
569 | * Calculate sleep duration. The configuration is given in ms. | ||
570 | * We ensure a multiple of the beacon period is used. Also, if the sleep | ||
571 | * duration is greater than the DTIM period then it makes senses | ||
572 | * to make it a multiple of that. | ||
573 | * | ||
574 | * XXX fixed at 100ms | ||
575 | */ | ||
576 | |||
577 | bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100), | ||
578 | intval)); | ||
579 | if (bs.bs_sleepduration > bs.bs_dtimperiod) | ||
580 | bs.bs_sleepduration = bs.bs_dtimperiod; | ||
581 | |||
582 | /* TSF out of range threshold fixed at 1 second */ | ||
583 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | ||
584 | |||
585 | ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n", | ||
586 | bs.bs_bmissthreshold, bs.bs_sleepduration); | ||
587 | |||
588 | /* Set the computed STA beacon timers */ | ||
589 | 515 | ||
590 | ath9k_hw_disable_interrupts(ah); | 516 | ath9k_hw_disable_interrupts(ah); |
591 | ath9k_hw_set_sta_beacon_timers(ah, &bs); | 517 | ath9k_hw_set_sta_beacon_timers(ah, &bs); |
@@ -777,7 +703,7 @@ void ath9k_set_beacon(struct ath_softc *sc) | |||
777 | ath9k_beacon_config_adhoc(sc, cur_conf); | 703 | ath9k_beacon_config_adhoc(sc, cur_conf); |
778 | break; | 704 | break; |
779 | case NL80211_IFTYPE_STATION: | 705 | case NL80211_IFTYPE_STATION: |
780 | ath9k_beacon_config_sta(sc, cur_conf); | 706 | ath9k_beacon_config_sta(sc->sc_ah, cur_conf); |
781 | break; | 707 | break; |
782 | default: | 708 | default: |
783 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); | 709 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/common-beacon.c b/drivers/net/wireless/ath/ath9k/common-beacon.c new file mode 100644 index 000000000000..35cc9fddfb35 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/common-beacon.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2011 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 "common.h" | ||
18 | |||
19 | #define FUDGE 2 | ||
20 | |||
21 | /* Calculate the modulo of a 64 bit TSF snapshot with a TU divisor */ | ||
22 | static u32 ath9k_mod_tsf64_tu(u64 tsf, u32 div_tu) | ||
23 | { | ||
24 | u32 tsf_mod, tsf_hi, tsf_lo, mod_hi, mod_lo; | ||
25 | |||
26 | tsf_mod = tsf & (BIT(10) - 1); | ||
27 | tsf_hi = tsf >> 32; | ||
28 | tsf_lo = ((u32) tsf) >> 10; | ||
29 | |||
30 | mod_hi = tsf_hi % div_tu; | ||
31 | mod_lo = ((mod_hi << 22) + tsf_lo) % div_tu; | ||
32 | |||
33 | return (mod_lo << 10) | tsf_mod; | ||
34 | } | ||
35 | |||
36 | static u32 ath9k_get_next_tbtt(struct ath_hw *ah, u64 tsf, | ||
37 | unsigned int interval) | ||
38 | { | ||
39 | unsigned int offset; | ||
40 | |||
41 | tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time); | ||
42 | offset = ath9k_mod_tsf64_tu(tsf, interval); | ||
43 | |||
44 | return (u32) tsf + TU_TO_USEC(interval) - offset; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * This sets up the beacon timers according to the timestamp of the last | ||
49 | * received beacon and the current TSF, configures PCF and DTIM | ||
50 | * handling, programs the sleep registers so the hardware will wakeup in | ||
51 | * time to receive beacons, and configures the beacon miss handling so | ||
52 | * we'll receive a BMISS interrupt when we stop seeing beacons from the AP | ||
53 | * we've associated with. | ||
54 | */ | ||
55 | int ath9k_cmn_beacon_config_sta(struct ath_hw *ah, | ||
56 | struct ath_beacon_config *conf, | ||
57 | struct ath9k_beacon_state *bs) | ||
58 | { | ||
59 | struct ath_common *common = ath9k_hw_common(ah); | ||
60 | int dtim_intval; | ||
61 | u64 tsf; | ||
62 | |||
63 | /* No need to configure beacon if we are not associated */ | ||
64 | if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) { | ||
65 | ath_dbg(common, BEACON, | ||
66 | "STA is not yet associated..skipping beacon config\n"); | ||
67 | return -EPERM; | ||
68 | } | ||
69 | |||
70 | memset(bs, 0, sizeof(*bs)); | ||
71 | conf->intval = conf->beacon_interval; | ||
72 | |||
73 | /* | ||
74 | * Setup dtim parameters according to | ||
75 | * last beacon we received (which may be none). | ||
76 | */ | ||
77 | dtim_intval = conf->intval * conf->dtim_period; | ||
78 | |||
79 | /* | ||
80 | * Pull nexttbtt forward to reflect the current | ||
81 | * TSF and calculate dtim state for the result. | ||
82 | */ | ||
83 | tsf = ath9k_hw_gettsf64(ah); | ||
84 | conf->nexttbtt = ath9k_get_next_tbtt(ah, tsf, conf->intval); | ||
85 | |||
86 | bs->bs_intval = TU_TO_USEC(conf->intval); | ||
87 | bs->bs_dtimperiod = conf->dtim_period * bs->bs_intval; | ||
88 | bs->bs_nexttbtt = conf->nexttbtt; | ||
89 | bs->bs_nextdtim = conf->nexttbtt; | ||
90 | if (conf->dtim_period > 1) | ||
91 | bs->bs_nextdtim = ath9k_get_next_tbtt(ah, tsf, dtim_intval); | ||
92 | |||
93 | /* | ||
94 | * Calculate the number of consecutive beacons to miss* before taking | ||
95 | * a BMISS interrupt. The configuration is specified in TU so we only | ||
96 | * need calculate based on the beacon interval. Note that we clamp the | ||
97 | * result to at most 15 beacons. | ||
98 | */ | ||
99 | bs->bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, conf->intval); | ||
100 | if (bs->bs_bmissthreshold > 15) | ||
101 | bs->bs_bmissthreshold = 15; | ||
102 | else if (bs->bs_bmissthreshold <= 0) | ||
103 | bs->bs_bmissthreshold = 1; | ||
104 | |||
105 | /* | ||
106 | * Calculate sleep duration. The configuration is given in ms. | ||
107 | * We ensure a multiple of the beacon period is used. Also, if the sleep | ||
108 | * duration is greater than the DTIM period then it makes senses | ||
109 | * to make it a multiple of that. | ||
110 | * | ||
111 | * XXX fixed at 100ms | ||
112 | */ | ||
113 | |||
114 | bs->bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100), | ||
115 | conf->intval)); | ||
116 | if (bs->bs_sleepduration > bs->bs_dtimperiod) | ||
117 | bs->bs_sleepduration = bs->bs_dtimperiod; | ||
118 | |||
119 | /* TSF out of range threshold fixed at 1 second */ | ||
120 | bs->bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | ||
121 | |||
122 | ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n", | ||
123 | bs->bs_bmissthreshold, bs->bs_sleepduration); | ||
124 | return 0; | ||
125 | } | ||
126 | EXPORT_SYMBOL(ath9k_cmn_beacon_config_sta); | ||
diff --git a/drivers/net/wireless/ath/ath9k/common-beacon.h b/drivers/net/wireless/ath/ath9k/common-beacon.h new file mode 100644 index 000000000000..51cbcb5c4b9f --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/common-beacon.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009-2011 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 | struct ath_beacon_config; | ||
18 | |||
19 | int ath9k_cmn_beacon_config_sta(struct ath_hw *ah, | ||
20 | struct ath_beacon_config *conf, | ||
21 | struct ath9k_beacon_state *bs); | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index eccc718e2b20..ca38116838f0 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "hw-ops.h" | 22 | #include "hw-ops.h" |
23 | 23 | ||
24 | #include "common-init.h" | 24 | #include "common-init.h" |
25 | #include "common-beacon.h" | ||
25 | 26 | ||
26 | /* Common header for Atheros 802.11n base driver cores */ | 27 | /* Common header for Atheros 802.11n base driver cores */ |
27 | 28 | ||