aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-09-17 01:29:23 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:57 -0400
commit4150c57212ad134765dd78c654a4b9906252b66d (patch)
treec37ab7a3f75532a623ed00339782d769514422d2 /drivers/net/wireless/rt2x00/rt2x00dev.c
parent070ac3a2651e3c1c4d277c5f1981517427c386a7 (diff)
[PATCH] mac80211: revamp interface and filter configuration
Drivers are currently supposed to keep track of monitor interfaces if they allow so-called "hard" monitor, and they are also supposed to keep track of multicast etc. This patch changes that, replaces the set_multicast_list() callback with a new configure_filter() callback that takes filter flags (FIF_*) instead of interface flags (IFF_*). For a driver, this means it should open the filter as much as necessary to get all frames requested by the filter flags. Accordingly, the filter flags are named "positively", e.g. FIF_ALLMULTI. Multicast filtering is a bit special in that drivers that have no multicast address filters need to allow multicast frames through when either the FIF_ALLMULTI flag is set or when the mc_count value is positive. At the same time, drivers are no longer notified about monitor interfaces at all, this means they now need to implement the start() and stop() callbacks and the new change_filter_flags() callback. Also, the start()/stop() ordering changed, start() is now called *before* any add_interface() as it really should be, and stop() after any remove_interface(). The patch also changes the behaviour of setting the bssid to multicast for scanning when IEEE80211_HW_NO_PROBE_FILTERING is set; the IEEE80211_HW_NO_PROBE_FILTERING flag is removed and the filter flag FIF_BCN_PRBRESP_PROMISC introduced. This is a lot more efficient for hardware like b43 that supports it and other hardware can still set the BSSID to all-ones. Driver modifications by Johannes Berg (b43 & iwlwifi), Michael Wu (rtl8187, adm8211, and p54), Larry Finger (b43legacy), and Ivo van Doorn (rt2x00). Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index cd82eeface8f..bbccb8933876 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -135,10 +135,12 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
135 return; 135 return;
136 136
137 /* 137 /*
138 * Stop beacon generation. 138 * Stop all scheduled work.
139 */ 139 */
140 if (work_pending(&rt2x00dev->beacon_work)) 140 if (work_pending(&rt2x00dev->beacon_work))
141 cancel_work_sync(&rt2x00dev->beacon_work); 141 cancel_work_sync(&rt2x00dev->beacon_work);
142 if (work_pending(&rt2x00dev->filter_work))
143 cancel_work_sync(&rt2x00dev->filter_work);
142 144
143 /* 145 /*
144 * Stop the TX queues. 146 * Stop the TX queues.
@@ -257,6 +259,17 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
257 LINK_TUNE_INTERVAL); 259 LINK_TUNE_INTERVAL);
258} 260}
259 261
262static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
263{
264 struct rt2x00_dev *rt2x00dev =
265 container_of(work, struct rt2x00_dev, filter_work);
266
267 rt2x00dev->ops->hw->configure_filter(rt2x00dev->hw,
268 rt2x00dev->interface.filter,
269 &rt2x00dev->interface.filter,
270 0, NULL);
271}
272
260/* 273/*
261 * Interrupt context handlers. 274 * Interrupt context handlers.
262 */ 275 */
@@ -337,7 +350,7 @@ void rt2x00lib_txdone(struct data_entry *entry,
337EXPORT_SYMBOL_GPL(rt2x00lib_txdone); 350EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
338 351
339void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, 352void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
340 const int signal, const int rssi, const int ofdm) 353 struct rxdata_entry_desc *desc)
341{ 354{
342 struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; 355 struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev;
343 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; 356 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
@@ -358,22 +371,24 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
358 * the signal is the PLCP value. If it was received with 371 * the signal is the PLCP value. If it was received with
359 * a CCK bitrate the signal is the rate in 0.5kbit/s. 372 * a CCK bitrate the signal is the rate in 0.5kbit/s.
360 */ 373 */
361 if (!ofdm) 374 if (!desc->ofdm)
362 val = DEVICE_GET_RATE_FIELD(rate->val, RATE); 375 val = DEVICE_GET_RATE_FIELD(rate->val, RATE);
363 else 376 else
364 val = DEVICE_GET_RATE_FIELD(rate->val, PLCP); 377 val = DEVICE_GET_RATE_FIELD(rate->val, PLCP);
365 378
366 if (val == signal) { 379 if (val == desc->signal) {
367 val = rate->val; 380 val = rate->val;
368 break; 381 break;
369 } 382 }
370 } 383 }
371 384
372 rt2x00_update_link_rssi(&rt2x00dev->link, rssi); 385 rt2x00_update_link_rssi(&rt2x00dev->link, desc->rssi);
373 rt2x00dev->link.rx_success++; 386 rt2x00dev->link.rx_success++;
374 rx_status->rate = val; 387 rx_status->rate = val;
375 rx_status->signal = rt2x00lib_calculate_link_signal(rt2x00dev, rssi); 388 rx_status->signal =
376 rx_status->ssi = rssi; 389 rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi);
390 rx_status->ssi = desc->rssi;
391 rx_status->flag = desc->flags;
377 392
378 /* 393 /*
379 * Send frame to mac80211 394 * Send frame to mac80211
@@ -391,7 +406,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
391 unsigned int length, 406 unsigned int length,
392 struct ieee80211_tx_control *control) 407 struct ieee80211_tx_control *control)
393{ 408{
394 struct data_entry_desc desc; 409 struct txdata_entry_desc desc;
395 struct data_ring *ring; 410 struct data_ring *ring;
396 int tx_rate; 411 int tx_rate;
397 int bitrate; 412 int bitrate;
@@ -956,6 +971,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
956 * Initialize configuration work. 971 * Initialize configuration work.
957 */ 972 */
958 INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled); 973 INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled);
974 INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
959 INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); 975 INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
960 976
961 /* 977 /*
@@ -1098,7 +1114,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1098 rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); 1114 rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
1099 rt2x00lib_config_bssid(rt2x00dev, intf->bssid); 1115 rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
1100 rt2x00lib_config_type(rt2x00dev, intf->type); 1116 rt2x00lib_config_type(rt2x00dev, intf->type);
1101 rt2x00lib_config_packet_filter(rt2x00dev, intf->filter);
1102 1117
1103 /* 1118 /*
1104 * When in Master or Ad-hoc mode, 1119 * When in Master or Ad-hoc mode,