summaryrefslogtreecommitdiff
path: root/package/madwifi/patches/305-pureg_fix.patch
blob: cbe98e0ca937e67c4df69898e29f20f9b11c444c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
diff -urN madwifi-ng-r2377-20070526.old/ath/if_ath.c madwifi-ng-r2377-20070526.dev/ath/if_ath.c
--- madwifi-ng-r2377-20070526.old/ath/if_ath.c	2007-05-26 18:51:09.426654472 +0200
+++ madwifi-ng-r2377-20070526.dev/ath/if_ath.c	2007-05-26 18:51:09.440652344 +0200
@@ -3383,7 +3383,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 | 
diff -urN madwifi-ng-r2377-20070526.old/net80211/ieee80211_input.c madwifi-ng-r2377-20070526.dev/net80211/ieee80211_input.c
--- madwifi-ng-r2377-20070526.old/net80211/ieee80211_input.c	2007-05-26 18:51:09.429654016 +0200
+++ madwifi-ng-r2377-20070526.dev/net80211/ieee80211_input.c	2007-05-26 18:51:09.443651888 +0200
@@ -343,11 +343,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_bss->ni_bssid) &&
-			    !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) {
+			    !IEEE80211_ADDR_EQ(bssid, dev->broadcast) &&
+				(subtype != IEEE80211_FC0_SUBTYPE_BEACON)) {
 				/*
 				 * allow MGT frames to vap->iv_xrvap.
 				 * this will allow roaming between  XR and normal vaps
@@ -366,7 +367,8 @@
 			}
 #else
 			if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) &&
-			    !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) {
+			    !IEEE80211_ADDR_EQ(bssid, dev->broadcast) &&
+				(subtype != IEEE80211_FC0_SUBTYPE_BEACON)) {
 				/* not interested in */
 				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
 					bssid, NULL, "%s", "not to bss");
@@ -2593,7 +2595,7 @@
 	u_int8_t *frm, *efrm;
 	u_int8_t *ssid, *rates, *xrates, *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;
 
 	wh = (struct ieee80211_frame *) skb->data;
@@ -2615,11 +2617,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;
 		}
@@ -2702,6 +2708,7 @@
 					break;
 				}
 				scan.erp = frm[2];
+				has_erp = 1;
 				break;
 			case IEEE80211_ELEMID_RSN:
 				scan.rsn = frm;
@@ -2855,7 +2862,7 @@
 			    vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) {
 				mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);
 			}
-			
+
 			/*
 			 * If scanning, pass the info to the scan module.
 			 * Otherwise, check if it's the right time to do
@@ -2877,6 +2884,20 @@
 				ieee80211_bg_scan(vap);
 			return;
 		}
+
+		/* 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.
 		 */
diff -urN madwifi-ng-r2377-20070526.old/net80211/ieee80211_node.c madwifi-ng-r2377-20070526.dev/net80211/ieee80211_node.c
--- madwifi-ng-r2377-20070526.old/net80211/ieee80211_node.c	2007-05-26 18:51:09.430653864 +0200
+++ madwifi-ng-r2377-20070526.dev/net80211/ieee80211_node.c	2007-05-26 18:51:09.444651736 +0200
@@ -332,10 +332,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));
 }
diff -urN madwifi-ng-r2377-20070526.old/net80211/ieee80211_proto.c madwifi-ng-r2377-20070526.dev/net80211/ieee80211_proto.c
--- madwifi-ng-r2377-20070526.old/net80211/ieee80211_proto.c	2007-05-26 18:51:09.431653712 +0200
+++ madwifi-ng-r2377-20070526.dev/net80211/ieee80211_proto.c	2007-05-26 18:51:09.445651584 +0200
@@ -586,6 +586,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
diff -urN madwifi-ng-r2377-20070526.old/net80211/ieee80211_var.h madwifi-ng-r2377-20070526.dev/net80211/ieee80211_var.h
--- madwifi-ng-r2377-20070526.old/net80211/ieee80211_var.h	2007-05-26 18:51:09.321670432 +0200
+++ madwifi-ng-r2377-20070526.dev/net80211/ieee80211_var.h	2007-05-26 18:51:09.445651584 +0200
@@ -584,6 +584,8 @@
 void ieee80211_build_countryie(struct ieee80211com *);
 int ieee80211_media_setup(struct ieee80211com *, struct ifmedia *, u_int32_t,
 	ifm_change_cb_t, ifm_stat_cb_t);
+void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs);
+		
 
 /* Key update synchronization methods.  XXX should not be visible. */
 static __inline void