diff options
Diffstat (limited to 'package/madwifi/patches-testing/301-pureg_fix.patch')
-rw-r--r-- | package/madwifi/patches-testing/301-pureg_fix.patch | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/package/madwifi/patches-testing/301-pureg_fix.patch b/package/madwifi/patches-testing/301-pureg_fix.patch new file mode 100644 index 0000000000..fb6cefe364 --- /dev/null +++ b/package/madwifi/patches-testing/301-pureg_fix.patch @@ -0,0 +1,168 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -4251,7 +4251,9 @@ + rfilt |= HAL_RX_FILTER_PROM; + if (ic->ic_opmode == IEEE80211_M_STA || + sc->sc_opmode == HAL_M_IBSS || /* NB: AHDEMO too */ +- (sc->sc_nostabeacons) || sc->sc_scanning) ++ (sc->sc_nostabeacons) || sc->sc_scanning || ++ ((ic->ic_opmode == IEEE80211_M_HOSTAP) && ++ (ic->ic_protmode != IEEE80211_PROT_NONE))) + rfilt |= HAL_RX_FILTER_BEACON; + if (sc->sc_nmonvaps > 0) + rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON | +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -325,11 +325,12 @@ + bssid = wh->i_addr3; + } + /* +- * Validate the bssid. ++ * Validate the bssid. Let beacons get through though for 11g protection mode. + */ +-#ifdef ATH_SUPERG_XR + if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) && +- !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) { ++ !IEEE80211_ADDR_EQ(bssid, dev->broadcast) && ++ (subtype != IEEE80211_FC0_SUBTYPE_BEACON)) { ++#ifdef ATH_SUPERG_XR + /* + * allow MGT frames to vap->iv_xrvap. + * this will allow roaming between XR and normal vaps +@@ -345,18 +346,14 @@ + vap->iv_stats.is_rx_wrongbss++; + goto out; + } +- } + #else +- if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) && +- !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) { + /* not interested in */ + IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, + bssid, NULL, "%s", "not to bss"); + vap->iv_stats.is_rx_wrongbss++; + goto out; +- } +- + #endif ++ } + break; + case IEEE80211_M_WDS: + if (skb->len < sizeof(struct ieee80211_frame_addr4)) { +@@ -3019,7 +3016,7 @@ + u_int8_t *frm, *efrm; + u_int8_t *ssid, *rates, *xrates, *suppchan, *wpa, *rsn, *wme, *ath; + u_int8_t rate; +- int reassoc, resp, allocbs = 0; ++ int reassoc, resp, allocbs = 0, has_erp = 0; + u_int8_t qosinfo; + + if (ni_or_null == NULL) +@@ -3049,11 +3046,15 @@ + * o station mode when associated (to collect state + * updates such as 802.11g slot time), or + * o adhoc mode (to discover neighbors) ++ * o ap mode in protection mode (beacons only) + * Frames otherwise received are discarded. + */ + if (!((ic->ic_flags & IEEE80211_F_SCAN) || + (vap->iv_opmode == IEEE80211_M_STA && ni->ni_associd) || +- vap->iv_opmode == IEEE80211_M_IBSS)) { ++ (vap->iv_opmode == IEEE80211_M_IBSS) || ++ ((subtype == IEEE80211_FC0_SUBTYPE_BEACON) && ++ (vap->iv_opmode == IEEE80211_M_HOSTAP) && ++ (ic->ic_protmode != IEEE80211_PROT_NONE)))) { + vap->iv_stats.is_rx_mgtdiscard++; + return 0; + } +@@ -3137,6 +3138,7 @@ + break; + } + scan.erp = frm[2]; ++ has_erp = 1; + break; + case IEEE80211_ELEMID_RSN: + scan.rsn = frm; +@@ -3374,6 +3376,20 @@ + ieee80211_bg_scan(vap); + return 0; + } ++ ++ /* Update AP protection mode when in 11G mode */ ++ if ((vap->iv_opmode == IEEE80211_M_HOSTAP) && ++ IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { ++ ++ /* Assume no ERP IE == 11b AP */ ++ if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && ++ !(ic->ic_flags & IEEE80211_F_USEPROT)) { ++ ++ ic->ic_flags |= IEEE80211_F_USEPROT; ++ ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ } ++ } ++ + /* + * If scanning, just pass information to the scan module. + */ +--- a/net80211/ieee80211_node.c ++++ b/net80211/ieee80211_node.c +@@ -345,10 +345,16 @@ + /* Update country ie information */ + ieee80211_build_countryie(ic); + +- if (IEEE80211_IS_CHAN_HALF(chan)) ++ if (IEEE80211_IS_CHAN_HALF(chan)) { + ni->ni_rates = ic->ic_sup_half_rates; +- else if (IEEE80211_IS_CHAN_QUARTER(chan)) ++ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) { + ni->ni_rates = ic->ic_sup_quarter_rates; ++ } ++ ++ if ((vap->iv_flags & IEEE80211_F_PUREG) && ++ IEEE80211_IS_CHAN_ANYG(chan)) { ++ ieee80211_setpuregbasicrates(&ni->ni_rates); ++ } + + (void) ieee80211_sta_join1(PASS_NODE(ni)); + } +--- a/net80211/ieee80211_proto.c ++++ b/net80211/ieee80211_proto.c +@@ -599,6 +599,28 @@ + { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_TURBO_G (mixed b/g) */ + }; + ++static const struct ieee80211_rateset basicpureg[] = { ++ { 7, {2, 4, 11, 22, 12, 24, 48 } }, ++}; ++ ++/* ++ * Mark basic rates for the 11g rate table based on the pureg setting ++ */ ++void ++ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs) ++{ ++ int i, j; ++ ++ for (i = 0; i < rs->rs_nrates; i++) { ++ rs->rs_rates[i] &= IEEE80211_RATE_VAL; ++ for (j = 0; j < basicpureg[0].rs_nrates; j++) ++ if (basicpureg[0].rs_rates[j] == rs->rs_rates[i]) { ++ rs->rs_rates[i] |= IEEE80211_RATE_BASIC; ++ break; ++ } ++ } ++} ++ + /* + * Mark the basic rates for the 11g rate table based on the + * specified mode. For 11b compatibility we mark only 11b +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -712,6 +712,7 @@ + void ieee80211_build_sc_ie(struct ieee80211com *); + void ieee80211_dfs_action(struct ieee80211com *); + void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *); ++void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs); + + /* + * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers. |