diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2008-08-07 01:24:57 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-07 09:49:44 -0400 |
commit | 86b89eed9aca2a4a335b9c1bf7380f9183db431f (patch) | |
tree | de9861a36de404fc74d8d7fbb87bd66e73891de4 /drivers/net/wireless/ath9k/regd.c | |
parent | 3b95978ddadbab594aad6280bfa660a49948af86 (diff) |
ath9k: Revamp wireless mode usage
Use a single enum for managing modes, store supported modes by
the HW in a bitmask.
Register legacy rates with mac80211 only at init.
Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/regd.c')
-rw-r--r-- | drivers/net/wireless/ath9k/regd.c | 107 |
1 files changed, 51 insertions, 56 deletions
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 05e10c485fa4..62e28887ccd3 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c | |||
@@ -131,46 +131,45 @@ static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, | |||
131 | return false; | 131 | return false; |
132 | } | 132 | } |
133 | 133 | ||
134 | static u32 | 134 | static void |
135 | ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, | 135 | ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, |
136 | struct country_code_to_enum_rd *country, | 136 | struct country_code_to_enum_rd *country, |
137 | struct regDomain *rd5GHz) | 137 | struct regDomain *rd5GHz, |
138 | unsigned long *modes_allowed) | ||
138 | { | 139 | { |
139 | u32 modesAvail; | 140 | bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX); |
140 | 141 | ||
141 | modesAvail = ah->ah_caps.wireless_modes; | 142 | if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) && |
143 | (!country->allow11g)) | ||
144 | clear_bit(ATH9K_MODE_11G, modes_allowed); | ||
142 | 145 | ||
143 | if ((modesAvail & ATH9K_MODE_SEL_11G) && (!country->allow11g)) | 146 | if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) && |
144 | modesAvail &= ~ATH9K_MODE_SEL_11G; | ||
145 | if ((modesAvail & ATH9K_MODE_SEL_11A) && | ||
146 | (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a))) | 147 | (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a))) |
147 | modesAvail &= ~ATH9K_MODE_SEL_11A; | 148 | clear_bit(ATH9K_MODE_11A, modes_allowed); |
148 | 149 | ||
149 | if ((modesAvail & ATH9K_MODE_SEL_11NG_HT20) | 150 | if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes) |
150 | && (!country->allow11ng20)) | 151 | && (!country->allow11ng20)) |
151 | modesAvail &= ~ATH9K_MODE_SEL_11NG_HT20; | 152 | clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed); |
152 | 153 | ||
153 | if ((modesAvail & ATH9K_MODE_SEL_11NA_HT20) | 154 | if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes) |
154 | && (!country->allow11na20)) | 155 | && (!country->allow11na20)) |
155 | modesAvail &= ~ATH9K_MODE_SEL_11NA_HT20; | 156 | clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed); |
156 | 157 | ||
157 | if ((modesAvail & ATH9K_MODE_SEL_11NG_HT40PLUS) && | 158 | if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) && |
158 | (!country->allow11ng40)) | 159 | (!country->allow11ng40)) |
159 | modesAvail &= ~ATH9K_MODE_SEL_11NG_HT40PLUS; | 160 | clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed); |
160 | 161 | ||
161 | if ((modesAvail & ATH9K_MODE_SEL_11NG_HT40MINUS) && | 162 | if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) && |
162 | (!country->allow11ng40)) | 163 | (!country->allow11ng40)) |
163 | modesAvail &= ~ATH9K_MODE_SEL_11NG_HT40MINUS; | 164 | clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed); |
164 | 165 | ||
165 | if ((modesAvail & ATH9K_MODE_SEL_11NA_HT40PLUS) && | 166 | if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) && |
166 | (!country->allow11na40)) | 167 | (!country->allow11na40)) |
167 | modesAvail &= ~ATH9K_MODE_SEL_11NA_HT40PLUS; | 168 | clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed); |
168 | 169 | ||
169 | if ((modesAvail & ATH9K_MODE_SEL_11NA_HT40MINUS) && | 170 | if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) && |
170 | (!country->allow11na40)) | 171 | (!country->allow11na40)) |
171 | modesAvail &= ~ATH9K_MODE_SEL_11NA_HT40MINUS; | 172 | clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed); |
172 | |||
173 | return modesAvail; | ||
174 | } | 173 | } |
175 | 174 | ||
176 | bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) | 175 | bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) |
@@ -545,10 +544,10 @@ ath9k_regd_add_channel(struct ath_hal *ah, | |||
545 | } | 544 | } |
546 | } | 545 | } |
547 | 546 | ||
548 | if (cm->mode & (ATH9K_MODE_SEL_11A | | 547 | if ((cm->mode == ATH9K_MODE_11A) || |
549 | ATH9K_MODE_SEL_11NA_HT20 | | 548 | (cm->mode == ATH9K_MODE_11NA_HT20) || |
550 | ATH9K_MODE_SEL_11NA_HT40PLUS | | 549 | (cm->mode == ATH9K_MODE_11NA_HT40PLUS) || |
551 | ATH9K_MODE_SEL_11NA_HT40MINUS)) { | 550 | (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) { |
552 | if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A)) | 551 | if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A)) |
553 | privFlags |= CHANNEL_DISALLOW_ADHOC; | 552 | privFlags |= CHANNEL_DISALLOW_ADHOC; |
554 | } | 553 | } |
@@ -618,10 +617,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
618 | u32 maxchans, | 617 | u32 maxchans, |
619 | u32 *nchans, u8 *regclassids, | 618 | u32 *nchans, u8 *regclassids, |
620 | u32 maxregids, u32 *nregids, u16 cc, | 619 | u32 maxregids, u32 *nregids, u16 cc, |
621 | u32 modeSelect, bool enableOutdoor, | 620 | bool enableOutdoor, |
622 | bool enableExtendedChannels) | 621 | bool enableExtendedChannels) |
623 | { | 622 | { |
624 | u32 modesAvail; | ||
625 | u16 maxChan = 7000; | 623 | u16 maxChan = 7000; |
626 | struct country_code_to_enum_rd *country = NULL; | 624 | struct country_code_to_enum_rd *country = NULL; |
627 | struct regDomain rd5GHz, rd2GHz; | 625 | struct regDomain rd5GHz, rd2GHz; |
@@ -631,11 +629,13 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
631 | u8 ctl; | 629 | u8 ctl; |
632 | int regdmn; | 630 | int regdmn; |
633 | u16 chanSep; | 631 | u16 chanSep; |
632 | unsigned long *modes_avail; | ||
633 | DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX); | ||
634 | 634 | ||
635 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u mode 0x%x%s%s\n", | 635 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u %s %s\n", |
636 | __func__, cc, modeSelect, | 636 | __func__, cc, |
637 | enableOutdoor ? " Enable outdoor" : " ", | 637 | enableOutdoor ? "Enable outdoor" : "", |
638 | enableExtendedChannels ? " Enable ecm" : ""); | 638 | enableExtendedChannels ? "Enable ecm" : ""); |
639 | 639 | ||
640 | if (!ath9k_regd_is_ccode_valid(ah, cc)) { | 640 | if (!ath9k_regd_is_ccode_valid(ah, cc)) { |
641 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 641 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
@@ -726,9 +726,11 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
726 | } | 726 | } |
727 | 727 | ||
728 | if (country == NULL) { | 728 | if (country == NULL) { |
729 | modesAvail = ah->ah_caps.wireless_modes; | 729 | modes_avail = ah->ah_caps.wireless_modes; |
730 | } else { | 730 | } else { |
731 | modesAvail = ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz); | 731 | ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed); |
732 | modes_avail = modes_allowed; | ||
733 | |||
732 | if (!enableOutdoor) | 734 | if (!enableOutdoor) |
733 | maxChan = country->outdoorChanStart; | 735 | maxChan = country->outdoorChanStart; |
734 | } | 736 | } |
@@ -745,19 +747,12 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
745 | struct RegDmnFreqBand *fband = NULL, *freqs; | 747 | struct RegDmnFreqBand *fband = NULL, *freqs; |
746 | int8_t low_adj = 0, hi_adj = 0; | 748 | int8_t low_adj = 0, hi_adj = 0; |
747 | 749 | ||
748 | if ((cm->mode & modeSelect) == 0) { | 750 | if (!test_bit(cm->mode, modes_avail)) { |
749 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 751 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
750 | "%s: skip mode 0x%x flags 0x%x\n", | 752 | "%s: !avail mode %d flags 0x%x\n", |
751 | __func__, cm->mode, cm->flags); | 753 | __func__, cm->mode, cm->flags); |
752 | continue; | 754 | continue; |
753 | } | 755 | } |
754 | if ((cm->mode & modesAvail) == 0) { | ||
755 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
756 | "%s: !avail mode 0x%x (0x%x) flags 0x%x\n", | ||
757 | __func__, modesAvail, cm->mode, | ||
758 | cm->flags); | ||
759 | continue; | ||
760 | } | ||
761 | if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { | 756 | if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { |
762 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 757 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
763 | "%s: channels 0x%x not supported " | 758 | "%s: channels 0x%x not supported " |
@@ -767,25 +762,25 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
767 | } | 762 | } |
768 | 763 | ||
769 | switch (cm->mode) { | 764 | switch (cm->mode) { |
770 | case ATH9K_MODE_SEL_11A: | 765 | case ATH9K_MODE_11A: |
771 | case ATH9K_MODE_SEL_11NA_HT20: | 766 | case ATH9K_MODE_11NA_HT20: |
772 | case ATH9K_MODE_SEL_11NA_HT40PLUS: | 767 | case ATH9K_MODE_11NA_HT40PLUS: |
773 | case ATH9K_MODE_SEL_11NA_HT40MINUS: | 768 | case ATH9K_MODE_11NA_HT40MINUS: |
774 | rd = &rd5GHz; | 769 | rd = &rd5GHz; |
775 | channelBM = rd->chan11a; | 770 | channelBM = rd->chan11a; |
776 | freqs = ®Dmn5GhzFreq[0]; | 771 | freqs = ®Dmn5GhzFreq[0]; |
777 | ctl = rd->conformanceTestLimit; | 772 | ctl = rd->conformanceTestLimit; |
778 | break; | 773 | break; |
779 | case ATH9K_MODE_SEL_11B: | 774 | case ATH9K_MODE_11B: |
780 | rd = &rd2GHz; | 775 | rd = &rd2GHz; |
781 | channelBM = rd->chan11b; | 776 | channelBM = rd->chan11b; |
782 | freqs = ®Dmn2GhzFreq[0]; | 777 | freqs = ®Dmn2GhzFreq[0]; |
783 | ctl = rd->conformanceTestLimit | CTL_11B; | 778 | ctl = rd->conformanceTestLimit | CTL_11B; |
784 | break; | 779 | break; |
785 | case ATH9K_MODE_SEL_11G: | 780 | case ATH9K_MODE_11G: |
786 | case ATH9K_MODE_SEL_11NG_HT20: | 781 | case ATH9K_MODE_11NG_HT20: |
787 | case ATH9K_MODE_SEL_11NG_HT40PLUS: | 782 | case ATH9K_MODE_11NG_HT40PLUS: |
788 | case ATH9K_MODE_SEL_11NG_HT40MINUS: | 783 | case ATH9K_MODE_11NG_HT40MINUS: |
789 | rd = &rd2GHz; | 784 | rd = &rd2GHz; |
790 | channelBM = rd->chan11g; | 785 | channelBM = rd->chan11g; |
791 | freqs = ®Dmn2Ghz11gFreq[0]; | 786 | freqs = ®Dmn2Ghz11gFreq[0]; |
@@ -801,13 +796,13 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
801 | if (ath9k_regd_is_chan_bm_zero(channelBM)) | 796 | if (ath9k_regd_is_chan_bm_zero(channelBM)) |
802 | continue; | 797 | continue; |
803 | 798 | ||
804 | if ((cm->mode == ATH9K_MODE_SEL_11NA_HT40PLUS) || | 799 | if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) || |
805 | (cm->mode == ATH9K_MODE_SEL_11NG_HT40PLUS)) { | 800 | (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) { |
806 | hi_adj = -20; | 801 | hi_adj = -20; |
807 | } | 802 | } |
808 | 803 | ||
809 | if ((cm->mode == ATH9K_MODE_SEL_11NA_HT40MINUS) || | 804 | if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) || |
810 | (cm->mode == ATH9K_MODE_SEL_11NG_HT40MINUS)) { | 805 | (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) { |
811 | low_adj = 20; | 806 | low_adj = 20; |
812 | } | 807 | } |
813 | 808 | ||