aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c75
1 files changed, 61 insertions, 14 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index abbd857ec759..235e037e6509 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -273,16 +273,24 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
273 mutex_init(&intf->beacon_skb_mutex); 273 mutex_init(&intf->beacon_skb_mutex);
274 intf->beacon = entry; 274 intf->beacon = entry;
275 275
276 if (vif->type == NL80211_IFTYPE_AP)
277 memcpy(&intf->bssid, vif->addr, ETH_ALEN);
278 memcpy(&intf->mac, vif->addr, ETH_ALEN);
279
280 /* 276 /*
281 * The MAC adddress must be configured after the device 277 * The MAC adddress must be configured after the device
282 * has been initialized. Otherwise the device can reset 278 * has been initialized. Otherwise the device can reset
283 * the MAC registers. 279 * the MAC registers.
280 * The BSSID address must only be configured in AP mode,
281 * however we should not send an empty BSSID address for
282 * STA interfaces at this time, since this can cause
283 * invalid behavior in the device.
284 */ 284 */
285 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, intf->mac, NULL); 285 memcpy(&intf->mac, vif->addr, ETH_ALEN);
286 if (vif->type == NL80211_IFTYPE_AP) {
287 memcpy(&intf->bssid, vif->addr, ETH_ALEN);
288 rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
289 intf->mac, intf->bssid);
290 } else {
291 rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
292 intf->mac, NULL);
293 }
286 294
287 /* 295 /*
288 * Some filters depend on the current working mode. We can force 296 * Some filters depend on the current working mode. We can force
@@ -346,9 +354,11 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
346 /* 354 /*
347 * Some configuration parameters (e.g. channel and antenna values) can 355 * Some configuration parameters (e.g. channel and antenna values) can
348 * only be set when the radio is enabled, but do require the RX to 356 * only be set when the radio is enabled, but do require the RX to
349 * be off. 357 * be off. During this period we should keep link tuning enabled,
358 * if for any reason the link tuner must be reset, this will be
359 * handled by rt2x00lib_config().
350 */ 360 */
351 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); 361 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK);
352 362
353 /* 363 /*
354 * When we've just turned on the radio, we want to reprogram 364 * When we've just turned on the radio, we want to reprogram
@@ -366,7 +376,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
366 rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); 376 rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
367 377
368 /* Turn RX back on */ 378 /* Turn RX back on */
369 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); 379 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
370 380
371 return 0; 381 return 0;
372} 382}
@@ -430,12 +440,36 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
430} 440}
431EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); 441EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
432 442
443static void rt2x00mac_set_tim_iter(void *data, u8 *mac,
444 struct ieee80211_vif *vif)
445{
446 struct rt2x00_intf *intf = vif_to_intf(vif);
447
448 if (vif->type != NL80211_IFTYPE_AP &&
449 vif->type != NL80211_IFTYPE_ADHOC &&
450 vif->type != NL80211_IFTYPE_MESH_POINT &&
451 vif->type != NL80211_IFTYPE_WDS)
452 return;
453
454 spin_lock(&intf->lock);
455 intf->delayed_flags |= DELAYED_UPDATE_BEACON;
456 spin_unlock(&intf->lock);
457}
458
433int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 459int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
434 bool set) 460 bool set)
435{ 461{
436 struct rt2x00_dev *rt2x00dev = hw->priv; 462 struct rt2x00_dev *rt2x00dev = hw->priv;
437 463
438 rt2x00lib_beacondone(rt2x00dev); 464 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
465 return 0;
466
467 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw,
468 rt2x00mac_set_tim_iter,
469 rt2x00dev);
470
471 /* queue work to upodate the beacon template */
472 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
439 return 0; 473 return 0;
440} 474}
441EXPORT_SYMBOL_GPL(rt2x00mac_set_tim); 475EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
@@ -539,6 +573,22 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
539EXPORT_SYMBOL_GPL(rt2x00mac_set_key); 573EXPORT_SYMBOL_GPL(rt2x00mac_set_key);
540#endif /* CONFIG_RT2X00_LIB_CRYPTO */ 574#endif /* CONFIG_RT2X00_LIB_CRYPTO */
541 575
576void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw)
577{
578 struct rt2x00_dev *rt2x00dev = hw->priv;
579 __set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
580 rt2x00link_stop_tuner(rt2x00dev);
581}
582EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start);
583
584void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw)
585{
586 struct rt2x00_dev *rt2x00dev = hw->priv;
587 __clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
588 rt2x00link_start_tuner(rt2x00dev);
589}
590EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_complete);
591
542int rt2x00mac_get_stats(struct ieee80211_hw *hw, 592int rt2x00mac_get_stats(struct ieee80211_hw *hw,
543 struct ieee80211_low_level_stats *stats) 593 struct ieee80211_low_level_stats *stats)
544{ 594{
@@ -562,7 +612,6 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
562{ 612{
563 struct rt2x00_dev *rt2x00dev = hw->priv; 613 struct rt2x00_dev *rt2x00dev = hw->priv;
564 struct rt2x00_intf *intf = vif_to_intf(vif); 614 struct rt2x00_intf *intf = vif_to_intf(vif);
565 int update_bssid = 0;
566 615
567 /* 616 /*
568 * mac80211 might be calling this function while we are trying 617 * mac80211 might be calling this function while we are trying
@@ -577,10 +626,8 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
577 * conf->bssid can be NULL if coming from the internal 626 * conf->bssid can be NULL if coming from the internal
578 * beacon update routine. 627 * beacon update routine.
579 */ 628 */
580 if (changes & BSS_CHANGED_BSSID) { 629 if (changes & BSS_CHANGED_BSSID)
581 update_bssid = 1;
582 memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN); 630 memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN);
583 }
584 631
585 spin_unlock(&intf->lock); 632 spin_unlock(&intf->lock);
586 633
@@ -592,7 +639,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
592 */ 639 */
593 if (changes & BSS_CHANGED_BSSID) 640 if (changes & BSS_CHANGED_BSSID)
594 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, 641 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
595 update_bssid ? bss_conf->bssid : NULL); 642 bss_conf->bssid);
596 643
597 /* 644 /*
598 * Update the beacon. 645 * Update the beacon.