rt2x00: Fix beacon de-synchronization while update beacon
[pandora-kernel.git] / drivers / net / wireless / rt2x00 / rt73usb.c
index 853b2b2..4d94b65 100644 (file)
@@ -183,7 +183,6 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
@@ -191,9 +190,6 @@ static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
        rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
        return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
 }
-#else
-#define rt73usb_rfkill_poll    NULL
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt73usb_brightness_set(struct led_classdev *led_cdev,
@@ -497,7 +493,7 @@ static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
                           !(filter_flags & FIF_PLCPFAIL));
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
-                          !(filter_flags & FIF_CONTROL));
+                          !(filter_flags & (FIF_CONTROL | FIF_PSPOLL)));
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
                           !(filter_flags & FIF_PROMISC_IN_BSS));
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
@@ -566,15 +562,22 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
 
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
+       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
        rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
                           !!erp->short_preamble);
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
 
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
 
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+                          erp->beacon_int * 16);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
        rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
        rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
        rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
@@ -834,25 +837,6 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
 }
 
-static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
-                                   struct rt2x00lib_conf *libconf)
-{
-       u32 reg;
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
-                          libconf->conf->beacon_int * 16);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
-}
-
 static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
                                struct rt2x00lib_conf *libconf)
 {
@@ -864,7 +848,7 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_SLEEP) {
                rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
                rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
-                                  libconf->conf->beacon_int - 10);
+                                  rt2x00dev->beacon_int - 10);
                rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
                                   libconf->conf->listen_interval - 1);
                rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
@@ -906,8 +890,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
                rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                rt73usb_config_retry_limit(rt2x00dev, libconf);
-       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               rt73usb_config_duration(rt2x00dev, libconf);
        if (flags & IEEE80211_CONF_CHANGE_PS)
                rt73usb_config_ps(rt2x00dev, libconf);
 }
@@ -1545,8 +1527,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
         * otherwise we might be sending out invalid data.
         */
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
-       rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
@@ -1846,7 +1826,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
        rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
 
-       if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
+       if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) ||
+           rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
                ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
                return -ENODEV;
        }
@@ -1876,10 +1857,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Detect if this device has an hardware controlled radio.
         */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
        if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
                __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
        /*
         * Read frequency offset.
@@ -2162,6 +2141,12 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
        if (retval)
                return retval;
 
+       /*
+        * This device has multiple filters for control frames,
+        * but has no a separate filter for PS Poll frames.
+        */
+       __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+
        /*
         * This device requires firmware.
         */
@@ -2259,14 +2244,15 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .add_interface          = rt2x00mac_add_interface,
        .remove_interface       = rt2x00mac_remove_interface,
        .config                 = rt2x00mac_config,
-       .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
+       .set_tim                = rt2x00mac_set_tim,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt73usb_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt73usb_get_tsf,
+       .rfkill_poll            = rt2x00mac_rfkill_poll,
 };
 
 static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {