diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 3af42733941..56829fad347 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -117,7 +117,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * Note that we can only stop the TX queues inside the TX path * due to possible race conditions in mac80211. */ - if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) goto exit_fail; /* @@ -175,7 +175,7 @@ int rt2x00mac_start(struct ieee80211_hw *hw) { struct rt2x00_dev *rt2x00dev = hw->priv; - if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; return rt2x00lib_start(rt2x00dev); @@ -186,7 +186,7 @@ void rt2x00mac_stop(struct ieee80211_hw *hw) { struct rt2x00_dev *rt2x00dev = hw->priv; - if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return; rt2x00lib_stop(rt2x00dev); @@ -206,8 +206,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, * Don't allow interfaces to be added * the device has disappeared. */ - if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || - !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || + !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) return -ENODEV; switch (conf->type) { @@ -256,7 +256,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, */ for (i = 0; i < queue->limit; i++) { entry = &queue->entries[i]; - if (!__test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) + if (!test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) break; } @@ -310,7 +310,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, * either the device has disappeared or when * no interface is present. */ - if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) return; @@ -324,7 +324,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, * Release beacon entry so it is available for * new interfaces again. */ - __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); + clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); /* * Make sure the bssid and mac address registers @@ -338,45 +338,45 @@ EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) { struct rt2x00_dev *rt2x00dev = hw->priv; - int force_reconfig; + int radio_on; + int status; /* * Mac80211 might be calling this function while we are trying * to remove the device or perhaps suspending it. */ - if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; /* - * Check if we need to disable the radio, - * if this is not the case, at least the RX must be disabled. + * Only change device state when the radio is enabled. It does not + * matter what parameters we have configured when the radio is disabled + * because we won't be able to send or receive anyway. Also note that + * some configuration parameters (e.g. channel and antenna values) can + * only be set when the radio is enabled. */ - if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) { - if (!conf->radio_enabled) - rt2x00lib_disable_radio(rt2x00dev); - else - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); - } + radio_on = test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags); + if (conf->radio_enabled) { + /* For programming the values, we have to turn RX off */ + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); - /* - * When the DEVICE_DIRTY_CONFIG flag is set, the device has recently - * been started and the configuration must be forced upon the hardware. - * Otherwise registers will not be intialized correctly and could - * result in non-working hardware because essential registers aren't - * initialized. - */ - force_reconfig = - __test_and_clear_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags); + /* Enable the radio */ + status = rt2x00lib_enable_radio(rt2x00dev); + if (unlikely(status)) + return status; - rt2x00lib_config(rt2x00dev, conf, force_reconfig); + /* + * When we've just turned on the radio, we want to reprogram + * everything to ensure a consistent state + */ + rt2x00lib_config(rt2x00dev, conf, !radio_on); - /* - * Reenable RX only if the radio should be on. - */ - if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) + /* Turn RX back on */ rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); - else if (conf->radio_enabled) - return rt2x00lib_enable_radio(rt2x00dev); + } else { + /* Disable the radio */ + rt2x00lib_disable_radio(rt2x00dev); + } return 0; } @@ -395,7 +395,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, * Mac80211 might be calling this function while we are trying * to remove the device or perhaps suspending it. */ - if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; spin_lock(&intf->lock); @@ -666,10 +666,11 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, queue->cw_max = 10; /* cw_min: 2^10 = 1024. */ queue->aifs = params->aifs; + queue->txop = params->txop; INFO(rt2x00dev, - "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", - queue_idx, queue->cw_min, queue->cw_max, queue->aifs); + "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d.\n", + queue_idx, queue->cw_min, queue->cw_max, queue->aifs, queue->txop); return 0; } |