aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/regd.c
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2008-08-07 01:24:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-07 09:49:44 -0400
commit86b89eed9aca2a4a335b9c1bf7380f9183db431f (patch)
treede9861a36de404fc74d8d7fbb87bd66e73891de4 /drivers/net/wireless/ath9k/regd.c
parent3b95978ddadbab594aad6280bfa660a49948af86 (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.c107
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
134static u32 134static void
135ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, 135ath9k_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
176bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) 175bool 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 = &regDmn5GhzFreq[0]; 771 freqs = &regDmn5GhzFreq[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 = &regDmn2GhzFreq[0]; 777 freqs = &regDmn2GhzFreq[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 = &regDmn2Ghz11gFreq[0]; 786 freqs = &regDmn2Ghz11gFreq[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