rt2x00: Correctly initialize AID during set_key()
[pandora-kernel.git] / drivers / net / wireless / rt2x00 / rt2x00mac.c
index 9311833..38edee5 100644 (file)
@@ -39,7 +39,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
        unsigned int data_length;
        int retval = 0;
 
-       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+       if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
                data_length = sizeof(struct ieee80211_cts);
        else
                data_length = sizeof(struct ieee80211_rts);
@@ -64,11 +64,11 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
         */
        memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
        rts_info = IEEE80211_SKB_CB(skb);
-       rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;
-       rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
+       rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS;
+       rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT;
        rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
 
-       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+       if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
                rts_info->flags |= IEEE80211_TX_CTL_NO_ACK;
        else
                rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
@@ -79,12 +79,10 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
         * RTS/CTS frame should use the length of the frame plus any
         * encryption overhead that will be added by the hardware.
         */
-#ifdef CONFIG_RT2X00_LIB_CRYPTO
        if (!frag_skb->do_not_encrypt)
                data_length += rt2x00crypto_tx_overhead(tx_info);
-#endif /* CONFIG_RT2X00_LIB_CRYPTO */
 
-       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+       if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
                ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
                                        frag_skb->data, data_length, tx_info,
                                        (struct ieee80211_cts *)(skb->data));
@@ -132,8 +130,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                ERROR(rt2x00dev,
                      "Attempt to send packet over invalid queue %d.\n"
                      "Please file bug report to %s.\n", qid, DRV_PROJECT);
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
+               goto exit_fail;
        }
 
        /*
@@ -146,8 +143,8 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
         * inside the hardware.
         */
        frame_control = le16_to_cpu(ieee80211hdr->frame_control);
-       if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
-                              IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&
+       if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
+                                               IEEE80211_TX_RC_USE_CTS_PROTECT)) &&
            !rt2x00dev->ops->hw->set_rts_threshold) {
                if (rt2x00queue_available(queue) <= 1)
                        goto exit_fail;
@@ -339,7 +336,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
-       int radio_on;
        int status;
 
        /*
@@ -349,15 +345,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
        if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
                return 0;
 
-       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
-               rt2x00dev->ops->lib->set_retry_limit(hw,
-                       conf->short_frame_max_tx_count,
-                       conf->long_frame_max_tx_count);
-       }
-       changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
-       if (!changed)
-               return 0;
-
        /*
         * Only change device state when the radio is enabled. It does not
         * matter what parameters we have configured when the radio is disabled
@@ -365,7 +352,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
         * some configuration parameters (e.g. channel and antenna values) can
         * only be set when the radio is enabled.
         */
-       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);
@@ -379,7 +365,18 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
                 * When we've just turned on the radio, we want to reprogram
                 * everything to ensure a consistent state
                 */
-               rt2x00lib_config(rt2x00dev, conf, !radio_on);
+               rt2x00lib_config(rt2x00dev, conf, changed);
+
+               /*
+                * The radio was enabled, configure the antenna to the
+                * default settings, the link tuner will later start
+                * continue configuring the antenna based on the software
+                * diversity. But for non-diversity configurations, we need
+                * to have configured the correct state now.
+                */
+               if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED)
+                       rt2x00lib_config_antenna(rt2x00dev,
+                                                &rt2x00dev->default_ant);
 
                /* Turn RX back on */
                rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
@@ -490,12 +487,15 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                      struct ieee80211_key_conf *key)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct ieee80211_sta *sta;
        int (*set_key) (struct rt2x00_dev *rt2x00dev,
                        struct rt2x00lib_crypto *crypto,
                        struct ieee80211_key_conf *key);
        struct rt2x00lib_crypto crypto;
 
-       if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return 0;
+       else if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
                return -EOPNOTSUPP;
        else if (key->keylen > 32)
                return -ENOSPC;
@@ -537,6 +537,17 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        } else
                memcpy(&crypto.key, &key->key[0], key->keylen);
 
+       /*
+        * Discover the Association ID from mac80211.
+        * Some drivers need this information when updating the
+        * hardware key (either adding or removing).
+        */
+       rcu_read_lock();
+       sta = ieee80211_find_sta(hw, address);
+       if (sta)
+               crypto.aid = sta->aid;
+       rcu_read_unlock();
+
        /*
         * Each BSS has a maximum of 4 shared keys.
         * Shared key index values:
@@ -635,7 +646,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
         * When the erp information has changed, we should perform
         * additional configuration steps. For all other changes we are done.
         */
-       if (changes & (BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_CTS_PROT)) {
+       if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) {
                if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
                        rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
                else
@@ -643,7 +654,6 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        spin_lock(&intf->lock);
-       memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
        if (delayed) {
                intf->delayed_flags |= delayed;
                schedule_work(&rt2x00dev->intf_work);