rt2x00: Fix for rt2800usb for SHARED_KEY_TABLE initializations
[pandora-kernel.git] / drivers / net / wireless / rt2x00 / rt2x00mac.c
index c4c06b4..3011aea 100644 (file)
@@ -73,7 +73,8 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
        else
                rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
 
-       skb->do_not_encrypt = 1;
+       /* Disable hardware encryption */
+       rts_info->control.hw_key = NULL;
 
        /*
         * RTS/CTS frame should use the length of the frame plus any
@@ -273,6 +274,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 
        spin_lock_init(&intf->lock);
        spin_lock_init(&intf->seqlock);
+       mutex_init(&intf->beacon_skb_mutex);
        intf->beacon = entry;
 
        if (conf->type == NL80211_IFTYPE_AP)
@@ -337,54 +339,38 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
-       int status;
 
        /*
-        * Mac80211 might be calling this function while we are trying
+        * mac80211 might be calling this function while we are trying
         * to remove the device or perhaps suspending it.
         */
        if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
                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
-        * 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.
+        * Some configuration parameters (e.g. channel and antenna values) can
+        * only be set when the radio is enabled, but do require the RX to
+        * be off.
         */
-       if (conf->radio_enabled) {
-               /* For programming the values, we have to turn RX off */
-               rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+       rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
 
-               /* Enable the radio */
-               status = rt2x00lib_enable_radio(rt2x00dev);
-               if (unlikely(status))
-                       return status;
+       /*
+        * When we've just turned on the radio, we want to reprogram
+        * everything to ensure a consistent state
+        */
+       rt2x00lib_config(rt2x00dev, conf, changed);
 
-               /*
-                * When we've just turned on the radio, we want to reprogram
-                * everything to ensure a consistent state
-                */
-               rt2x00lib_config(rt2x00dev, conf, changed);
+       /*
+        * After the radio has been enabled we need to configure
+        * the antenna to the default settings. rt2x00lib_config_antenna()
+        * should determine if any action should be taken based on
+        * checking if diversity has been enabled or no antenna changes
+        * have been made since the last configuration change.
+        */
+       rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
 
-               /*
-                * 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);
-       } else {
-               /* Disable the radio */
-               rt2x00lib_disable_radio(rt2x00dev);
-       }
+       /* Turn RX back on */
+       rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
 
        return 0;
 }
@@ -393,7 +379,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_config);
 void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
                                unsigned int changed_flags,
                                unsigned int *total_flags,
-                               int mc_count, struct dev_addr_list *mc_list)
+                               u64 multicast)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
 
@@ -406,6 +392,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
            FIF_FCSFAIL |
            FIF_PLCPFAIL |
            FIF_CONTROL |
+           FIF_PSPOLL |
            FIF_OTHER_BSS |
            FIF_PROMISC_IN_BSS;
 
@@ -420,6 +407,22 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
 
+       /*
+        * If the device has a single filter for all control frames,
+        * FIF_CONTROL and FIF_PSPOLL flags imply each other.
+        * And if the device has more than one filter for control frames
+        * of different types, but has no a separate filter for PS Poll frames,
+        * FIF_CONTROL flag implies FIF_PSPOLL.
+        */
+       if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags)) {
+               if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL)
+                       *total_flags |= FIF_CONTROL | FIF_PSPOLL;
+       }
+       if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags)) {
+               if (*total_flags & FIF_CONTROL)
+                       *total_flags |= FIF_PSPOLL;
+       }
+
        /*
         * Check if there is any work left for us.
         */
@@ -430,10 +433,20 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
        if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
                rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
        else
-               queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
+               ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->filter_work);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
 
+int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+                     bool set)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+
+       rt2x00lib_beacondone(rt2x00dev);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
+
 #ifdef CONFIG_RT2X00_LIB_CRYPTO
 static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
 {
@@ -576,7 +589,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
        int update_bssid = 0;
 
        /*
-        * Mac80211 might be calling this function while we are trying
+        * mac80211 might be calling this function while we are trying
         * to remove the device or perhaps suspending it.
         */
        if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
@@ -687,3 +700,12 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_conf_tx);
+
+void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+       bool active = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+
+       wiphy_rfkill_set_hw_state(hw->wiphy, !active);
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);