Backported r12989 for 8.09
[openwrt/svn-archive/archive.git] / package / madwifi / patches-testing / 301-pureg_fix.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -4251,7 +4251,9 @@
4 rfilt |= HAL_RX_FILTER_PROM;
5 if (ic->ic_opmode == IEEE80211_M_STA ||
6 sc->sc_opmode == HAL_M_IBSS || /* NB: AHDEMO too */
7 - (sc->sc_nostabeacons) || sc->sc_scanning)
8 + (sc->sc_nostabeacons) || sc->sc_scanning ||
9 + ((ic->ic_opmode == IEEE80211_M_HOSTAP) &&
10 + (ic->ic_protmode != IEEE80211_PROT_NONE)))
11 rfilt |= HAL_RX_FILTER_BEACON;
12 if (sc->sc_nmonvaps > 0)
13 rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
14 --- a/net80211/ieee80211_input.c
15 +++ b/net80211/ieee80211_input.c
16 @@ -325,11 +325,12 @@
17 bssid = wh->i_addr3;
18 }
19 /*
20 - * Validate the bssid.
21 + * Validate the bssid. Let beacons get through though for 11g protection mode.
22 */
23 -#ifdef ATH_SUPERG_XR
24 if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) &&
25 - !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) {
26 + !IEEE80211_ADDR_EQ(bssid, dev->broadcast) &&
27 + (subtype != IEEE80211_FC0_SUBTYPE_BEACON)) {
28 +#ifdef ATH_SUPERG_XR
29 /*
30 * allow MGT frames to vap->iv_xrvap.
31 * this will allow roaming between XR and normal vaps
32 @@ -345,18 +346,14 @@
33 vap->iv_stats.is_rx_wrongbss++;
34 goto out;
35 }
36 - }
37 #else
38 - if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) &&
39 - !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) {
40 /* not interested in */
41 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
42 bssid, NULL, "%s", "not to bss");
43 vap->iv_stats.is_rx_wrongbss++;
44 goto out;
45 - }
46 -
47 #endif
48 + }
49 break;
50 case IEEE80211_M_WDS:
51 if (skb->len < sizeof(struct ieee80211_frame_addr4)) {
52 @@ -3019,7 +3016,7 @@
53 u_int8_t *frm, *efrm;
54 u_int8_t *ssid, *rates, *xrates, *suppchan, *wpa, *rsn, *wme, *ath;
55 u_int8_t rate;
56 - int reassoc, resp, allocbs = 0;
57 + int reassoc, resp, allocbs = 0, has_erp = 0;
58 u_int8_t qosinfo;
59
60 if (ni_or_null == NULL)
61 @@ -3049,11 +3046,15 @@
62 * o station mode when associated (to collect state
63 * updates such as 802.11g slot time), or
64 * o adhoc mode (to discover neighbors)
65 + * o ap mode in protection mode (beacons only)
66 * Frames otherwise received are discarded.
67 */
68 if (!((ic->ic_flags & IEEE80211_F_SCAN) ||
69 (vap->iv_opmode == IEEE80211_M_STA && ni->ni_associd) ||
70 - vap->iv_opmode == IEEE80211_M_IBSS)) {
71 + (vap->iv_opmode == IEEE80211_M_IBSS) ||
72 + ((subtype == IEEE80211_FC0_SUBTYPE_BEACON) &&
73 + (vap->iv_opmode == IEEE80211_M_HOSTAP) &&
74 + (ic->ic_protmode != IEEE80211_PROT_NONE)))) {
75 vap->iv_stats.is_rx_mgtdiscard++;
76 return 0;
77 }
78 @@ -3137,6 +3138,7 @@
79 break;
80 }
81 scan.erp = frm[2];
82 + has_erp = 1;
83 break;
84 case IEEE80211_ELEMID_RSN:
85 scan.rsn = frm;
86 @@ -3374,6 +3376,20 @@
87 ieee80211_bg_scan(vap);
88 return 0;
89 }
90 +
91 + /* Update AP protection mode when in 11G mode */
92 + if ((vap->iv_opmode == IEEE80211_M_HOSTAP) &&
93 + IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
94 +
95 + /* Assume no ERP IE == 11b AP */
96 + if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
97 + !(ic->ic_flags & IEEE80211_F_USEPROT)) {
98 +
99 + ic->ic_flags |= IEEE80211_F_USEPROT;
100 + ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
101 + }
102 + }
103 +
104 /*
105 * If scanning, just pass information to the scan module.
106 */
107 --- a/net80211/ieee80211_node.c
108 +++ b/net80211/ieee80211_node.c
109 @@ -345,10 +345,16 @@
110 /* Update country ie information */
111 ieee80211_build_countryie(ic);
112
113 - if (IEEE80211_IS_CHAN_HALF(chan))
114 + if (IEEE80211_IS_CHAN_HALF(chan)) {
115 ni->ni_rates = ic->ic_sup_half_rates;
116 - else if (IEEE80211_IS_CHAN_QUARTER(chan))
117 + } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
118 ni->ni_rates = ic->ic_sup_quarter_rates;
119 + }
120 +
121 + if ((vap->iv_flags & IEEE80211_F_PUREG) &&
122 + IEEE80211_IS_CHAN_ANYG(chan)) {
123 + ieee80211_setpuregbasicrates(&ni->ni_rates);
124 + }
125
126 (void) ieee80211_sta_join1(PASS_NODE(ni));
127 }
128 --- a/net80211/ieee80211_proto.c
129 +++ b/net80211/ieee80211_proto.c
130 @@ -599,6 +599,28 @@
131 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_TURBO_G (mixed b/g) */
132 };
133
134 +static const struct ieee80211_rateset basicpureg[] = {
135 + { 7, {2, 4, 11, 22, 12, 24, 48 } },
136 +};
137 +
138 +/*
139 + * Mark basic rates for the 11g rate table based on the pureg setting
140 + */
141 +void
142 +ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs)
143 +{
144 + int i, j;
145 +
146 + for (i = 0; i < rs->rs_nrates; i++) {
147 + rs->rs_rates[i] &= IEEE80211_RATE_VAL;
148 + for (j = 0; j < basicpureg[0].rs_nrates; j++)
149 + if (basicpureg[0].rs_rates[j] == rs->rs_rates[i]) {
150 + rs->rs_rates[i] |= IEEE80211_RATE_BASIC;
151 + break;
152 + }
153 + }
154 +}
155 +
156 /*
157 * Mark the basic rates for the 11g rate table based on the
158 * specified mode. For 11b compatibility we mark only 11b
159 --- a/net80211/ieee80211_var.h
160 +++ b/net80211/ieee80211_var.h
161 @@ -712,6 +712,7 @@
162 void ieee80211_build_sc_ie(struct ieee80211com *);
163 void ieee80211_dfs_action(struct ieee80211com *);
164 void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *);
165 +void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs);
166
167 /*
168 * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers.