aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-12 16:52:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-15 16:48:25 -0400
commit25d834e16294c8dfd923dae6bdb8a055391a99a5 (patch)
treeb9d756464d89949651e5acd1df97846af3028df0 /net/mac80211/util.c
parent9c31fd635ddfae6eb61712491770befa2ce1fdde (diff)
mac80211: fix virtual interfaces vs. injection
Currently, virtual interface pointers passed to drivers might be from monitor interfaces and as such completely uninitialised because we do not tell the driver about monitor interfaces when those are created. Instead of passing them, we should therefore indicate to the driver that there is no information; do that by passing a NULL value and adjust drivers to cope with it. As a result, some mac80211 API functions also need to cope with a NULL vif pointer so drivers can still call them unconditionally. Also, when injecting frames we really don't want to pass NULL all the time, if we know we are the source address of a frame and have a local interface for that address, we can to use that interface. This also helps with processing the frame correctly for that interface which will help the 802.11w implementation. It's not entirely correct for VLANs or WDS interfaces because there the MAC address isn't unique, but it's already a lot better than what we do now. Finally, when injecting without a matching local interface, don't assign sequence numbers at all. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 6eb222369bcb..f32561ec224c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -231,16 +231,21 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
231 struct ieee80211_rate *rate) 231 struct ieee80211_rate *rate)
232{ 232{
233 struct ieee80211_local *local = hw_to_local(hw); 233 struct ieee80211_local *local = hw_to_local(hw);
234 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 234 struct ieee80211_sub_if_data *sdata;
235 u16 dur; 235 u16 dur;
236 int erp; 236 int erp;
237 bool short_preamble = false;
237 238
238 erp = 0; 239 erp = 0;
239 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 240 if (vif) {
240 erp = rate->flags & IEEE80211_RATE_ERP_G; 241 sdata = vif_to_sdata(vif);
242 short_preamble = sdata->bss_conf.use_short_preamble;
243 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
244 erp = rate->flags & IEEE80211_RATE_ERP_G;
245 }
241 246
242 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp, 247 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp,
243 sdata->bss_conf.use_short_preamble); 248 short_preamble);
244 249
245 return cpu_to_le16(dur); 250 return cpu_to_le16(dur);
246} 251}
@@ -252,7 +257,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
252{ 257{
253 struct ieee80211_local *local = hw_to_local(hw); 258 struct ieee80211_local *local = hw_to_local(hw);
254 struct ieee80211_rate *rate; 259 struct ieee80211_rate *rate;
255 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 260 struct ieee80211_sub_if_data *sdata;
256 bool short_preamble; 261 bool short_preamble;
257 int erp; 262 int erp;
258 u16 dur; 263 u16 dur;
@@ -260,13 +265,17 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
260 265
261 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 266 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
262 267
263 short_preamble = sdata->bss_conf.use_short_preamble; 268 short_preamble = false;
264 269
265 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 270 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
266 271
267 erp = 0; 272 erp = 0;
268 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 273 if (vif) {
269 erp = rate->flags & IEEE80211_RATE_ERP_G; 274 sdata = vif_to_sdata(vif);
275 short_preamble = sdata->bss_conf.use_short_preamble;
276 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
277 erp = rate->flags & IEEE80211_RATE_ERP_G;
278 }
270 279
271 /* CTS duration */ 280 /* CTS duration */
272 dur = ieee80211_frame_duration(local, 10, rate->bitrate, 281 dur = ieee80211_frame_duration(local, 10, rate->bitrate,
@@ -289,7 +298,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
289{ 298{
290 struct ieee80211_local *local = hw_to_local(hw); 299 struct ieee80211_local *local = hw_to_local(hw);
291 struct ieee80211_rate *rate; 300 struct ieee80211_rate *rate;
292 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 301 struct ieee80211_sub_if_data *sdata;
293 bool short_preamble; 302 bool short_preamble;
294 int erp; 303 int erp;
295 u16 dur; 304 u16 dur;
@@ -297,12 +306,16 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
297 306
298 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 307 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
299 308
300 short_preamble = sdata->bss_conf.use_short_preamble; 309 short_preamble = false;
301 310
302 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 311 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
303 erp = 0; 312 erp = 0;
304 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 313 if (vif) {
305 erp = rate->flags & IEEE80211_RATE_ERP_G; 314 sdata = vif_to_sdata(vif);
315 short_preamble = sdata->bss_conf.use_short_preamble;
316 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
317 erp = rate->flags & IEEE80211_RATE_ERP_G;
318 }
306 319
307 /* Data frame duration */ 320 /* Data frame duration */
308 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, 321 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate,