3 @@ -4158,7 +4158,9 @@ ath_calcrxfilter(struct ath_softc *sc)
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 @@ -346,11 +346,12 @@ ieee80211_input(struct ieee80211vap * va
20 - * Validate the bssid.
21 + * Validate the bssid. Let beacons get through though for 11g protection mode.
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)) {
30 * allow MGT frames to vap->iv_xrvap.
31 * this will allow roaming between XR and normal vaps
32 @@ -366,18 +367,14 @@ ieee80211_input(struct ieee80211vap * va
33 vap->iv_stats.is_rx_wrongbss++;
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++;
51 if (skb->len < sizeof(struct ieee80211_frame_addr4)) {
52 @@ -3066,7 +3063,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
54 u_int8_t *ssid, *rates, *xrates, *suppchan, *wpa, *rsn, *wme, *ath;
56 - int reassoc, resp, allocbs = 0;
57 + int reassoc, resp, allocbs = 0, has_erp = 0;
60 if (ni_or_null == NULL)
61 @@ -3096,11 +3093,15 @@ ieee80211_recv_mgmt(struct ieee80211vap
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.
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++;
78 @@ -3184,6 +3185,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
84 case IEEE80211_ELEMID_RSN:
86 @@ -3421,6 +3423,20 @@ ieee80211_recv_mgmt(struct ieee80211vap
87 ieee80211_bg_scan(vap);
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)) {
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)) {
99 + ic->ic_flags |= IEEE80211_F_USEPROT;
100 + ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
105 * If scanning, just pass information to the scan module.
107 --- a/net80211/ieee80211_node.c
108 +++ b/net80211/ieee80211_node.c
109 @@ -383,10 +383,16 @@ ieee80211_create_ibss(struct ieee80211va
110 /* Update country ie information */
111 ieee80211_build_countryie(ic);
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;
121 + if ((vap->iv_flags & IEEE80211_F_PUREG) &&
122 + IEEE80211_IS_CHAN_ANYG(chan)) {
123 + ieee80211_setpuregbasicrates(&ni->ni_rates);
126 (void) ieee80211_sta_join1(PASS_NODE(ni));
128 --- a/net80211/ieee80211_proto.c
129 +++ b/net80211/ieee80211_proto.c
130 @@ -595,6 +595,28 @@ static const struct ieee80211_rateset ba
131 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_TURBO_G (mixed b/g) */
134 +static const struct ieee80211_rateset basicpureg[] = {
135 + { 7, {2, 4, 11, 22, 12, 24, 48 } },
139 + * Mark basic rates for the 11g rate table based on the pureg setting
142 +ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs)
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;
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 @@ -708,6 +708,7 @@ int ieee80211_media_setup(struct ieee802
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);
168 * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers.