Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[safe/jmp/linux-2.6] / drivers / net / wireless / rt2x00 / rt2x00.h
index 39ecf3b..dcfc8c2 100644 (file)
@@ -1,5 +1,6 @@
 /*
-       Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+       Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+       Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
        <http://rt2x00.serialmonkey.com>
 
        This program is free software; you can redistribute it and/or modify
@@ -33,6 +34,7 @@
 #include <linux/leds.h>
 #include <linux/mutex.h>
 #include <linux/etherdevice.h>
+#include <linux/input-polldev.h>
 
 #include <net/mac80211.h>
 
@@ -44,7 +46,7 @@
 /*
  * Module information.
  */
-#define DRV_VERSION    "2.2.3"
+#define DRV_VERSION    "2.3.0"
 #define DRV_PROJECT    "http://rt2x00.serialmonkey.com"
 
 /*
 #define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
 
 /*
+ * Determine the alignment requirement,
+ * to make sure the 802.11 payload is padded to a 4-byte boundrary
+ * we must determine the address of the payload and calculate the
+ * amount of bytes needed to move the data.
+ */
+#define ALIGN_SIZE(__skb, __header) \
+       (  ((unsigned long)((__skb)->data + (__header))) & 3 )
+
+/*
+ * Constants for extra TX headroom for alignment purposes.
+ */
+#define RT2X00_ALIGN_SIZE      4 /* Only whole frame needs alignment */
+#define RT2X00_L2PAD_SIZE      8 /* Both header & payload need alignment */
+
+/*
  * Standard timing and size defines.
  * These values should follow the ieee80211 specifications.
  */
                                  GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
 
 /*
+ * Structure for average calculation
+ * The avg field contains the actual average value,
+ * but avg_weight is internally used during calculations
+ * to prevent rounding errors.
+ */
+struct avg_val {
+       int avg;
+       int avg_weight;
+};
+
+enum rt2x00_chip_intf {
+       RT2X00_CHIP_INTF_PCI,
+       RT2X00_CHIP_INTF_USB,
+};
+
+/*
  * Chipset identification
  * The chipset on the device is composed of a RT and RF chip.
  * The chipset combination is important for determining device capabilities.
@@ -137,9 +170,20 @@ struct rt2x00_chip {
 #define RT2561         0x0302
 #define RT2661         0x0401
 #define RT2571         0x1300
+#define RT2860         0x0601  /* 2.4GHz PCI/CB */
+#define RT2860D                0x0681  /* 2.4GHz, 5GHz PCI/CB */
+#define RT2890         0x0701  /* 2.4GHz PCIe */
+#define RT2890D                0x0781  /* 2.4GHz, 5GHz PCIe */
+#define RT2880         0x2880  /* WSOC */
+#define RT3052         0x3052  /* WSOC */
+#define RT3090         0x3090  /* 2.4GHz PCIe */
+#define RT2870         0x1600
+#define RT3070         0x1800
 
        u16 rf;
        u32 rev;
+
+       enum rt2x00_chip_intf intf;
 };
 
 /*
@@ -177,52 +221,41 @@ struct antenna_setup {
  */
 struct link_qual {
        /*
-        * Statistics required for Link tuning.
-        * For the average RSSI value we use the "Walking average" approach.
-        * When adding RSSI to the average value the following calculation
-        * is needed:
-        *
-        *        avg_rssi = ((avg_rssi * 7) + rssi) / 8;
-        *
-        * The advantage of this approach is that we only need 1 variable
-        * to store the average in (No need for a count and a total).
-        * But more importantly, normal average values will over time
-        * move less and less towards newly added values this results
-        * that with link tuning, the device can have a very good RSSI
-        * for a few minutes but when the device is moved away from the AP
-        * the average will not decrease fast enough to compensate.
-        * The walking average compensates this and will move towards
-        * the new values correctly allowing a effective link tuning.
-        */
-       int avg_rssi;
+        * Statistics required for Link tuning by driver
+        * The rssi value is provided by rt2x00lib during the
+        * link_tuner() callback function.
+        * The false_cca field is filled during the link_stats()
+        * callback function and could be used during the
+        * link_tuner() callback function.
+        */
+       int rssi;
        int false_cca;
 
        /*
-        * Statistics required for Signal quality calculation.
-        * For calculating the Signal quality we have to determine
-        * the total number of success and failed RX and TX frames.
-        * After that we also use the average RSSI value to help
-        * determining the signal quality.
-        * For the calculation we will use the following algorithm:
-        *
-        *         rssi_percentage = (avg_rssi * 100) / rssi_offset
-        *         rx_percentage = (rx_success * 100) / rx_total
-        *         tx_percentage = (tx_success * 100) / tx_total
-        *         avg_signal = ((WEIGHT_RSSI * avg_rssi) +
-        *                       (WEIGHT_TX * tx_percentage) +
-        *                       (WEIGHT_RX * rx_percentage)) / 100
+        * VGC levels
+        * Hardware driver will tune the VGC level during each call
+        * to the link_tuner() callback function. This vgc_level is
+        * is determined based on the link quality statistics like
+        * average RSSI and the false CCA count.
         *
-        * This value should then be checked to not be greated then 100.
+        * In some cases the drivers need to differentiate between
+        * the currently "desired" VGC level and the level configured
+        * in the hardware. The latter is important to reduce the
+        * number of BBP register reads to reduce register access
+        * overhead. For this reason we store both values here.
+        */
+       u8 vgc_level;
+       u8 vgc_level_reg;
+
+       /*
+        * Statistics required for Signal quality calculation.
+        * These fields might be changed during the link_stats()
+        * callback function.
         */
-       int rx_percentage;
        int rx_success;
        int rx_failed;
-       int tx_percentage;
        int tx_success;
        int tx_failed;
-#define WEIGHT_RSSI    20
-#define WEIGHT_RX      40
-#define WEIGHT_TX      40
 };
 
 /*
@@ -245,21 +278,18 @@ struct link_ant {
        struct antenna_setup active;
 
        /*
-        * RSSI information for the different antenna's.
-        * These statistics are used to determine when
-        * to switch antenna when using software diversity.
-        *
-        *        rssi[0] -> Antenna A RSSI
-        *        rssi[1] -> Antenna B RSSI
+        * RSSI history information for the antenna.
+        * Used to determine when to switch antenna
+        * when using software diversity.
         */
-       int rssi_history[2];
+       int rssi_history;
 
        /*
         * Current RSSI average of the currently active antenna.
         * Similar to the avg_rssi in the link_qual structure
         * this value is updated by using the walking average.
         */
-       int rssi_ant;
+       struct avg_val rssi_ant;
 };
 
 /*
@@ -286,9 +316,9 @@ struct link {
        struct link_ant ant;
 
        /*
-        * Active VGC level
+        * Currently active average RSSI value
         */
-       int vgc_level;
+       struct avg_val avg_rssi;
 
        /*
         * Work structure for scheduling periodic link tuning.
@@ -297,55 +327,6 @@ struct link {
 };
 
 /*
- * Small helper macro to work with moving/walking averages.
- */
-#define MOVING_AVERAGE(__avg, __val, __samples) \
-       ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
-
-/*
- * When we lack RSSI information return something less then -80 to
- * tell the driver to tune the device to maximum sensitivity.
- */
-#define DEFAULT_RSSI   ( -128 )
-
-/*
- * Link quality access functions.
- */
-static inline int rt2x00_get_link_rssi(struct link *link)
-{
-       if (link->qual.avg_rssi && link->qual.rx_success)
-               return link->qual.avg_rssi;
-       return DEFAULT_RSSI;
-}
-
-static inline int rt2x00_get_link_ant_rssi(struct link *link)
-{
-       if (link->ant.rssi_ant && link->qual.rx_success)
-               return link->ant.rssi_ant;
-       return DEFAULT_RSSI;
-}
-
-static inline void rt2x00_reset_link_ant_rssi(struct link *link)
-{
-       link->ant.rssi_ant = 0;
-}
-
-static inline int rt2x00_get_link_ant_rssi_history(struct link *link,
-                                                  enum antenna ant)
-{
-       if (link->ant.rssi_history[ant - ANTENNA_A])
-               return link->ant.rssi_history[ant - ANTENNA_A];
-       return DEFAULT_RSSI;
-}
-
-static inline int rt2x00_update_ant_rssi(struct link *link, int rssi)
-{
-       int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A];
-       link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi;
-       return old_rssi;
-}
-
-/*
  * Interface structure
  * Per interface configuration details, this structure
  * is allocated as the private data for ieee80211_vif.
@@ -368,6 +349,11 @@ struct rt2x00_intf {
        u8 bssid[ETH_ALEN];
 
        /*
+        * beacon->skb must be protected with the mutex.
+        */
+       struct mutex beacon_skb_mutex;
+
+       /*
         * Entry in the beacon queue which belongs to
         * this interface. Each interface has its own
         * dedicated beacon entry.
@@ -379,8 +365,6 @@ struct rt2x00_intf {
         */
        unsigned int delayed_flags;
 #define DELAYED_UPDATE_BEACON          0x00000001
-#define DELAYED_CONFIG_ERP             0x00000002
-#define DELAYED_LED_ASSOC              0x00000004
 
        /*
         * Software sequence counter, this is only required
@@ -409,6 +393,7 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
  *     for @tx_power_a, @tx_power_bg and @channels.
  * @channels: Device/chipset specific channel values (See &struct rf_channel).
  * @channels_info: Additional information for channels (See &struct channel_info).
+ * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
  */
 struct hw_mode_spec {
        unsigned int supported_bands;
@@ -422,6 +407,8 @@ struct hw_mode_spec {
        unsigned int num_channels;
        const struct rf_channel *channels;
        const struct channel_info *channels_info;
+
+       struct ieee80211_sta_ht_cap ht;
 };
 
 /*
@@ -445,10 +432,7 @@ struct rt2x00lib_erp {
        int short_preamble;
        int cts_protection;
 
-       int ack_timeout;
-       int ack_consume_time;
-
-       u64 basic_rates;
+       u32 basic_rates;
 
        int slot_time;
 
@@ -456,6 +440,8 @@ struct rt2x00lib_erp {
        short pifs;
        short difs;
        short eifs;
+
+       u16 beacon_int;
 };
 
 /*
@@ -520,9 +506,10 @@ struct rt2x00lib_ops {
         */
        int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
        char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev);
-       u16 (*get_firmware_crc) (const void *data, const size_t len);
-       int (*load_firmware) (struct rt2x00_dev *rt2x00dev, const void *data,
-                             const size_t len);
+       int (*check_firmware) (struct rt2x00_dev *rt2x00dev,
+                              const u8 *data, const size_t len);
+       int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
+                             const u8 *data, const size_t len);
 
        /*
         * Device initialization/deinitialization handlers.
@@ -544,8 +531,10 @@ struct rt2x00lib_ops {
        int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev);
        void (*link_stats) (struct rt2x00_dev *rt2x00dev,
                            struct link_qual *qual);
-       void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
-       void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
+       void (*reset_tuner) (struct rt2x00_dev *rt2x00dev,
+                            struct link_qual *qual);
+       void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
+                           struct link_qual *qual, const u32 count);
 
        /*
         * TX control handlers
@@ -558,6 +547,8 @@ struct rt2x00lib_ops {
        int (*get_tx_data_len) (struct queue_entry *entry);
        void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
                               const enum data_queue_qid queue);
+       void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev,
+                              const enum data_queue_qid queue);
 
        /*
         * RX control handlers
@@ -603,6 +594,7 @@ struct rt2x00_ops {
        const unsigned int eeprom_size;
        const unsigned int rf_size;
        const unsigned int tx_queues;
+       const unsigned int extra_tx_headroom;
        const struct data_queue_desc *rx;
        const struct data_queue_desc *tx;
        const struct data_queue_desc *bcn;
@@ -625,9 +617,7 @@ enum rt2x00_flags {
        DEVICE_STATE_REGISTERED_HW,
        DEVICE_STATE_INITIALIZED,
        DEVICE_STATE_STARTED,
-       DEVICE_STATE_STARTED_SUSPEND,
        DEVICE_STATE_ENABLED_RADIO,
-       DEVICE_STATE_DISABLED_RADIO_HW,
 
        /*
         * Driver requirements
@@ -635,14 +625,17 @@ enum rt2x00_flags {
        DRIVER_REQUIRE_FIRMWARE,
        DRIVER_REQUIRE_BEACON_GUARD,
        DRIVER_REQUIRE_ATIM_QUEUE,
-       DRIVER_REQUIRE_SCHEDULED,
        DRIVER_REQUIRE_DMA,
+       DRIVER_REQUIRE_COPY_IV,
+       DRIVER_REQUIRE_L2PAD,
 
        /*
         * Driver features
         */
        CONFIG_SUPPORT_HW_BUTTON,
        CONFIG_SUPPORT_HW_CRYPTO,
+       DRIVER_SUPPORT_CONTROL_FILTERS,
+       DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL,
 
        /*
         * Driver configuration
@@ -653,7 +646,7 @@ enum rt2x00_flags {
        CONFIG_EXTERNAL_LNA_BG,
        CONFIG_DOUBLE_ANTENNA,
        CONFIG_DISABLE_LINK_TUNING,
-       CONFIG_CRYPTO_COPY_IV,
+       CONFIG_CHANNEL_HT40,
 };
 
 /*
@@ -665,7 +658,7 @@ struct rt2x00_dev {
         * The structure stored in here depends on the
         * system bus (PCI or USB).
         * When accessing this variable, the rt2x00dev_{pci,usb}
-        * macro's should be used for correct typecasting.
+        * macros should be used for correct typecasting.
         */
        struct device *dev;
 
@@ -682,18 +675,6 @@ struct rt2x00_dev {
        enum ieee80211_band curr_band;
 
        /*
-        * rfkill structure for RF state switching support.
-        * This will only be compiled in when required.
-        */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
-       unsigned long rfkill_state;
-#define RFKILL_STATE_ALLOCATED         1
-#define RFKILL_STATE_REGISTERED                2
-       struct rfkill *rfkill;
-       struct delayed_work rfkill_work;
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
-
-       /*
         * If enabled, the debugfs interface structures
         * required for deregistration of debugfs.
         */
@@ -720,6 +701,12 @@ struct rt2x00_dev {
        unsigned long flags;
 
        /*
+        * Device information, Bus IRQ and name (PCI, SoC)
+        */
+       int irq;
+       const char *name;
+
+       /*
         * Chipset identification.
         */
        struct rt2x00_chip chip;
@@ -820,6 +807,18 @@ struct rt2x00_dev {
        u8 freq_offset;
 
        /*
+        * Calibration information (for rt2800usb & rt2800pci).
+        * [0] -> BW20
+        * [1] -> BW40
+        */
+       u8 calibration[2];
+
+       /*
+        * Beacon interval.
+        */
+       u16 beacon_int;
+
+       /*
         * Low level statistics which will have
         * to be kept up to date while device is running.
         */
@@ -837,7 +836,6 @@ struct rt2x00_dev {
         * due to RTNL locking requirements.
         */
        struct work_struct intf_work;
-       struct work_struct filter_work;
 
        /*
         * Data queue arrays for RX, TX and Beacon.
@@ -853,22 +851,38 @@ struct rt2x00_dev {
         * Firmware image.
         */
        const struct firmware *fw;
+
+       /*
+        * Driver specific data.
+        */
+       void *priv;
 };
 
 /*
+ * Register defines.
+ * Some registers require multiple attempts before success,
+ * in those cases REGISTER_BUSY_COUNT attempts should be
+ * taken with a REGISTER_BUSY_DELAY interval.
+ */
+#define REGISTER_BUSY_COUNT    5
+#define REGISTER_BUSY_DELAY    100
+
+/*
  * Generic RF access.
  * The RF is being accessed by word index.
  */
 static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev,
                                  const unsigned int word, u32 *data)
 {
-       *data = rt2x00dev->rf[word];
+       BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32));
+       *data = rt2x00dev->rf[word - 1];
 }
 
 static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev,
                                   const unsigned int word, u32 data)
 {
-       rt2x00dev->rf[word] = data;
+       BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32));
+       rt2x00dev->rf[word - 1] = data;
 }
 
 /*
@@ -899,15 +913,30 @@ static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev,
 static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
                                   const u16 rt, const u16 rf, const u32 rev)
 {
-       INFO(rt2x00dev,
-            "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n",
-            rt, rf, rev);
-
        rt2x00dev->chip.rt = rt;
        rt2x00dev->chip.rf = rf;
        rt2x00dev->chip.rev = rev;
 }
 
+static inline void rt2x00_set_chip_rt(struct rt2x00_dev *rt2x00dev,
+                                     const u16 rt)
+{
+       rt2x00dev->chip.rt = rt;
+}
+
+static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev,
+                                     const u16 rf, const u32 rev)
+{
+       rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev);
+}
+
+static inline void rt2x00_print_chip(struct rt2x00_dev *rt2x00dev)
+{
+       INFO(rt2x00dev,
+            "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n",
+            rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev);
+}
+
 static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip)
 {
        return (chipset->rt == chip);
@@ -918,16 +947,37 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip)
        return (chipset->rf == chip);
 }
 
-static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset)
+static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset)
 {
        return chipset->rev;
 }
 
-static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
-                                  const u32 rev)
+static inline bool rt2x00_check_rev(const struct rt2x00_chip *chipset,
+                                   const u32 mask, const u32 rev)
+{
+       return ((chipset->rev & mask) == rev);
+}
+
+static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev,
+                                       enum rt2x00_chip_intf intf)
+{
+       rt2x00dev->chip.intf = intf;
+}
+
+static inline bool rt2x00_intf(const struct rt2x00_chip *chipset,
+                              enum rt2x00_chip_intf intf)
+{
+       return (chipset->intf == intf);
+}
+
+static inline bool rt2x00_intf_is_pci(struct rt2x00_dev *rt2x00dev)
+{
+       return rt2x00_intf(&rt2x00dev->chip, RT2X00_CHIP_INTF_PCI);
+}
+
+static inline bool rt2x00_intf_is_usb(struct rt2x00_dev *rt2x00dev)
 {
-       return (((chipset->rev & 0xffff0) == rev) &&
-               !!(chipset->rev & 0x0000f));
+       return rt2x00_intf(&rt2x00dev->chip, RT2X00_CHIP_INTF_USB);
 }
 
 /**
@@ -973,16 +1023,15 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
                                struct ieee80211_if_init_conf *conf);
 int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
-int rt2x00mac_config_interface(struct ieee80211_hw *hw,
-                              struct ieee80211_vif *vif,
-                              struct ieee80211_if_conf *conf);
 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);
+int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+                     bool set);
 #ifdef CONFIG_RT2X00_LIB_CRYPTO
 int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-                     const u8 *local_address, const u8 *address,
+                     struct ieee80211_vif *vif, struct ieee80211_sta *sta,
                      struct ieee80211_key_conf *key);
 #else
 #define rt2x00mac_set_key      NULL
@@ -997,6 +1046,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
                                u32 changes);
 int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
                      const struct ieee80211_tx_queue_params *params);
+void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
 
 /*
  * Driver allocation handlers.