diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00.h')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 708 |
1 files changed, 554 insertions, 154 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 6c1ff4c15c8..d13f25cd70d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> + Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> + Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> <http://rt2x00.serialmonkey.com> @@ -14,9 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the - Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + along with this program; if not, see <http://www.gnu.org/licenses/>. */ /* @@ -28,6 +27,7 @@ #define RT2X00_H #include <linux/bitops.h> +#include <linux/interrupt.h> #include <linux/skbuff.h> #include <linux/workqueue.h> #include <linux/firmware.h> @@ -35,10 +35,14 @@ #include <linux/mutex.h> #include <linux/etherdevice.h> #include <linux/input-polldev.h> +#include <linux/kfifo.h> +#include <linux/hrtimer.h> +#include <linux/average.h> #include <net/mac80211.h> #include "rt2x00debug.h" +#include "rt2x00dump.h" #include "rt2x00leds.h" #include "rt2x00reg.h" #include "rt2x00queue.h" @@ -49,49 +53,36 @@ #define DRV_VERSION "2.3.0" #define DRV_PROJECT "http://rt2x00.serialmonkey.com" -/* - * Debug definitions. +/* Debug definitions. * Debug output has to be enabled during compile time. */ -#define DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, __args...) \ - printk(__kernlvl "%s -> %s: %s - " __msg, \ - wiphy_name((__dev)->hw->wiphy), __func__, __lvl, ##__args) - -#define DEBUG_PRINTK_PROBE(__kernlvl, __lvl, __msg, __args...) \ - printk(__kernlvl "%s -> %s: %s - " __msg, \ - KBUILD_MODNAME, __func__, __lvl, ##__args) - #ifdef CONFIG_RT2X00_DEBUG -#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args); -#else -#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ - do { } while (0) +#define DEBUG #endif /* CONFIG_RT2X00_DEBUG */ -/* - * Various debug levels. - * The debug levels PANIC and ERROR both indicate serious problems, - * for this reason they should never be ignored. - * The special ERROR_PROBE message is for messages that are generated - * when the rt2x00_dev is not yet initialized. +/* Utility printing macros + * rt2x00_probe_err is for messages when rt2x00_dev is uninitialized */ -#define PANIC(__dev, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, KERN_CRIT, "Panic", __msg, ##__args) -#define ERROR(__dev, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, KERN_ERR, "Error", __msg, ##__args) -#define ERROR_PROBE(__msg, __args...) \ - DEBUG_PRINTK_PROBE(KERN_ERR, "Error", __msg, ##__args) -#define WARNING(__dev, __msg, __args...) \ - DEBUG_PRINTK(__dev, KERN_WARNING, "Warning", __msg, ##__args) -#define NOTICE(__dev, __msg, __args...) \ - DEBUG_PRINTK(__dev, KERN_NOTICE, "Notice", __msg, ##__args) -#define INFO(__dev, __msg, __args...) \ - DEBUG_PRINTK(__dev, KERN_INFO, "Info", __msg, ##__args) -#define DEBUG(__dev, __msg, __args...) \ - DEBUG_PRINTK(__dev, KERN_DEBUG, "Debug", __msg, ##__args) -#define EEPROM(__dev, __msg, __args...) \ - DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) +#define rt2x00_probe_err(fmt, ...) \ + printk(KERN_ERR KBUILD_MODNAME ": %s: Error - " fmt, \ + __func__, ##__VA_ARGS__) +#define rt2x00_err(dev, fmt, ...) \ + wiphy_err((dev)->hw->wiphy, "%s: Error - " fmt, \ + __func__, ##__VA_ARGS__) +#define rt2x00_warn(dev, fmt, ...) \ + wiphy_warn((dev)->hw->wiphy, "%s: Warning - " fmt, \ + __func__, ##__VA_ARGS__) +#define rt2x00_info(dev, fmt, ...) \ + wiphy_info((dev)->hw->wiphy, "%s: Info - " fmt, \ + __func__, ##__VA_ARGS__) + +/* Various debug levels */ +#define rt2x00_dbg(dev, fmt, ...) \ + wiphy_dbg((dev)->hw->wiphy, "%s: Debug - " fmt, \ + __func__, ##__VA_ARGS__) +#define rt2x00_eeprom_dbg(dev, fmt, ...) \ + wiphy_dbg((dev)->hw->wiphy, "%s: EEPROM recovery - " fmt, \ + __func__, ##__VA_ARGS__) /* * Duration calculations @@ -146,19 +137,9 @@ #define SHORT_EIFS ( SIFS + SHORT_DIFS + \ 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_PCIE, RT2X00_CHIP_INTF_USB, RT2X00_CHIP_INTF_SOC, }; @@ -175,17 +156,21 @@ struct rt2x00_chip { #define RT2570 0x2570 #define RT2661 0x2661 #define RT2573 0x2573 -#define RT2860 0x2860 /* 2.4GHz PCI/CB */ -#define RT2870 0x2870 +#define RT2860 0x2860 /* 2.4GHz */ #define RT2872 0x2872 /* WSOC */ #define RT2883 0x2883 /* WSOC */ #define RT3070 0x3070 #define RT3071 0x3071 #define RT3090 0x3090 /* 2.4GHz PCIe */ +#define RT3290 0x3290 +#define RT3352 0x3352 /* WSOC */ #define RT3390 0x3390 #define RT3572 0x3572 -#define RT3593 0x3593 /* PCIe */ +#define RT3593 0x3593 #define RT3883 0x3883 /* WSOC */ +#define RT5390 0x5390 /* 2.4GHz */ +#define RT5392 0x5392 /* 2.4GHz */ +#define RT5592 0x5592 u16 rf; u16 rev; @@ -211,8 +196,10 @@ struct channel_info { unsigned int flags; #define GEOGRAPHY_ALLOWED 0x00000001 - short tx_power1; - short tx_power2; + short max_power; + short default_power1; + short default_power2; + short default_power3; }; /* @@ -221,6 +208,8 @@ struct channel_info { struct antenna_setup { enum antenna rx; enum antenna tx; + u8 rx_chain_num; + u8 tx_chain_num; }; /* @@ -296,7 +285,7 @@ struct link_ant { * Similar to the avg_rssi in the link_qual structure * this value is updated by using the walking average. */ - struct avg_val rssi_ant; + struct ewma rssi_ant; }; /* @@ -325,36 +314,44 @@ struct link { /* * Currently active average RSSI value */ - struct avg_val avg_rssi; + struct ewma avg_rssi; /* * Work structure for scheduling periodic link tuning. */ struct delayed_work work; -}; -/* - * Interface structure - * Per interface configuration details, this structure - * is allocated as the private data for ieee80211_vif. - */ -struct rt2x00_intf { /* - * All fields within the rt2x00_intf structure - * must be protected with a spinlock. + * Work structure for scheduling periodic watchdog monitoring. + * This work must be scheduled on the kernel workqueue, while + * all other work structures must be queued on the mac80211 + * workqueue. This guarantees that the watchdog can schedule + * other work structures and wait for their completion in order + * to bring the device/driver back into the desired state. */ - spinlock_t lock; + struct delayed_work watchdog_work; /* - * MAC of the device. + * Work structure for scheduling periodic AGC adjustments. */ - u8 mac[ETH_ALEN]; + struct delayed_work agc_work; /* - * BBSID of the AP to associate with. + * Work structure for scheduling periodic VCO calibration. */ - u8 bssid[ETH_ALEN]; + struct delayed_work vco_work; +}; +enum rt2x00_delayed_flags { + DELAYED_UPDATE_BEACON, +}; + +/* + * Interface structure + * Per interface configuration details, this structure + * is allocated as the private data for ieee80211_vif. + */ +struct rt2x00_intf { /* * beacon->skb must be protected with the mutex. */ @@ -366,20 +363,19 @@ struct rt2x00_intf { * dedicated beacon entry. */ struct queue_entry *beacon; + bool enable_beacon; /* * Actions that needed rescheduling. */ - unsigned int delayed_flags; -#define DELAYED_UPDATE_BEACON 0x00000001 + unsigned long delayed_flags; /* * Software sequence counter, this is only required * for hardware which doesn't support hardware * sequence counting. */ - spinlock_t seqlock; - u16 seqno; + atomic_t seqno; }; static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) @@ -449,6 +445,7 @@ struct rt2x00lib_erp { short eifs; u16 beacon_int; + u16 ht_opmode; }; /* @@ -461,11 +458,12 @@ struct rt2x00lib_crypto { const u8 *address; u32 bssidx; - u32 aid; u8 key[16]; u8 tx_mic[8]; u8 rx_mic[8]; + + int wcid; }; /* @@ -479,13 +477,13 @@ struct rt2x00intf_conf { enum nl80211_iftype type; /* - * TSF sync value, this is dependant on the operation type. + * TSF sync value, this is dependent on the operation type. */ enum tsf_sync sync; /* - * The MAC and BSSID addressess are simple array of bytes, - * these arrays are little endian, so when sending the addressess + * The MAC and BSSID addresses are simple array of bytes, + * these arrays are little endian, so when sending the addresses * to the drivers, copy the it into a endian-signed variable. * * Note that all devices (except rt2500usb) have 32 bits @@ -500,6 +498,19 @@ struct rt2x00intf_conf { }; /* + * Private structure for storing STA details + * wcid: Wireless Client ID + */ +struct rt2x00_sta { + int wcid; +}; + +static inline struct rt2x00_sta* sta_to_rt2x00_sta(struct ieee80211_sta *sta) +{ + return (struct rt2x00_sta *)sta->drv_priv; +} + +/* * rt2x00lib callback functions. */ struct rt2x00lib_ops { @@ -509,6 +520,15 @@ struct rt2x00lib_ops { irq_handler_t irq_handler; /* + * TX status tasklet handler. + */ + void (*txstatus_tasklet) (unsigned long data); + void (*pretbtt_tasklet) (unsigned long data); + void (*tbtt_tasklet) (unsigned long data); + void (*rxdone_tasklet) (unsigned long data); + void (*autowake_tasklet) (unsigned long data); + + /* * Device init handlers. */ int (*probe_hw) (struct rt2x00_dev *rt2x00dev); @@ -542,22 +562,30 @@ struct rt2x00lib_ops { struct link_qual *qual); void (*link_tuner) (struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); + void (*gain_calibration) (struct rt2x00_dev *rt2x00dev); + void (*vco_calibration) (struct rt2x00_dev *rt2x00dev); + + /* + * Data queue handlers. + */ + void (*watchdog) (struct rt2x00_dev *rt2x00dev); + void (*start_queue) (struct data_queue *queue); + void (*kick_queue) (struct data_queue *queue); + void (*stop_queue) (struct data_queue *queue); + void (*flush_queue) (struct data_queue *queue, bool drop); + void (*tx_dma_done) (struct queue_entry *entry); /* * TX control handlers */ - void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, + void (*write_tx_desc) (struct queue_entry *entry, + struct txentry_desc *txdesc); + void (*write_tx_data) (struct queue_entry *entry, struct txentry_desc *txdesc); - int (*write_tx_data) (struct queue_entry *entry, - struct txentry_desc *txdesc); void (*write_beacon) (struct queue_entry *entry, struct txentry_desc *txdesc); + void (*clear_beacon) (struct queue_entry *entry); 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 @@ -585,12 +613,18 @@ struct rt2x00lib_ops { #define CONFIG_UPDATE_BSSID ( 1 << 3 ) void (*config_erp) (struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp); + struct rt2x00lib_erp *erp, + u32 changed); void (*config_ant) (struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant); void (*config) (struct rt2x00_dev *rt2x00dev, struct rt2x00lib_conf *libconf, const unsigned int changed_flags); + int (*sta_add) (struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); + int (*sta_remove) (struct rt2x00_dev *rt2x00dev, + int wcid); }; /* @@ -598,17 +632,14 @@ struct rt2x00lib_ops { */ struct rt2x00_ops { const char *name; - const unsigned int max_sta_intf; + const unsigned int drv_data_size; const unsigned int max_ap_intf; 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; - const struct data_queue_desc *atim; + void (*queue_init)(struct data_queue *queue); const struct rt2x00lib_ops *lib; + const void *drv; const struct ieee80211_ops *hw; #ifdef CONFIG_RT2X00_LIB_DEBUGFS const struct rt2x00debug *debugfs; @@ -616,46 +647,79 @@ struct rt2x00_ops { }; /* - * rt2x00 device flags + * rt2x00 state flags */ -enum rt2x00_flags { +enum rt2x00_state_flags { /* - * Device state flags + * Device flags */ DEVICE_STATE_PRESENT, DEVICE_STATE_REGISTERED_HW, DEVICE_STATE_INITIALIZED, DEVICE_STATE_STARTED, DEVICE_STATE_ENABLED_RADIO, + DEVICE_STATE_SCANNING, /* - * Driver requirements + * Driver configuration */ - DRIVER_REQUIRE_FIRMWARE, - DRIVER_REQUIRE_BEACON_GUARD, - DRIVER_REQUIRE_ATIM_QUEUE, - DRIVER_REQUIRE_DMA, - DRIVER_REQUIRE_COPY_IV, - DRIVER_REQUIRE_L2PAD, + CONFIG_CHANNEL_HT40, + CONFIG_POWERSAVING, + CONFIG_HT_DISABLED, + CONFIG_QOS_DISABLED, /* - * Driver features + * Mark we currently are sequentially reading TX_STA_FIFO register + * FIXME: this is for only rt2800usb, should go to private data */ - CONFIG_SUPPORT_HW_BUTTON, - CONFIG_SUPPORT_HW_CRYPTO, - DRIVER_SUPPORT_CONTROL_FILTERS, - DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, + TX_STATUS_READING, +}; - /* - * Driver configuration - */ - CONFIG_FRAME_TYPE, - CONFIG_RF_SEQUENCE, - CONFIG_EXTERNAL_LNA_A, - CONFIG_EXTERNAL_LNA_BG, - CONFIG_DOUBLE_ANTENNA, - CONFIG_DISABLE_LINK_TUNING, - CONFIG_CHANNEL_HT40, +/* + * rt2x00 capability flags + */ +enum rt2x00_capability_flags { + /* + * Requirements + */ + REQUIRE_FIRMWARE, + REQUIRE_BEACON_GUARD, + REQUIRE_ATIM_QUEUE, + REQUIRE_DMA, + REQUIRE_COPY_IV, + REQUIRE_L2PAD, + REQUIRE_TXSTATUS_FIFO, + REQUIRE_TASKLET_CONTEXT, + REQUIRE_SW_SEQNO, + REQUIRE_HT_TX_DESC, + REQUIRE_PS_AUTOWAKE, + REQUIRE_DELAYED_RFKILL, + + /* + * Capabilities + */ + CAPABILITY_HW_BUTTON, + CAPABILITY_HW_CRYPTO, + CAPABILITY_POWER_LIMIT, + CAPABILITY_CONTROL_FILTERS, + CAPABILITY_CONTROL_FILTER_PSPOLL, + CAPABILITY_PRE_TBTT_INTERRUPT, + CAPABILITY_LINK_TUNING, + CAPABILITY_FRAME_TYPE, + CAPABILITY_RF_SEQUENCE, + CAPABILITY_EXTERNAL_LNA_A, + CAPABILITY_EXTERNAL_LNA_BG, + CAPABILITY_DOUBLE_ANTENNA, + CAPABILITY_BT_COEXIST, + CAPABILITY_VCO_RECALIBRATION, +}; + +/* + * Interface combinations + */ +enum { + IF_COMB_AP = 0, + NUM_IF_COMB, }; /* @@ -677,11 +741,17 @@ struct rt2x00_dev { const struct rt2x00_ops *ops; /* + * Driver data. + */ + void *drv_data; + + /* * IEEE80211 control structure. */ struct ieee80211_hw *hw; struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; enum ieee80211_band curr_band; + int curr_freq; /* * If enabled, the debugfs interface structures @@ -703,13 +773,20 @@ struct rt2x00_dev { #endif /* CONFIG_RT2X00_LIB_LEDS */ /* - * Device flags. - * In these flags the current status and some - * of the device capabilities are stored. + * Device state flags. + * In these flags the current status is stored. + * Access to these flags should occur atomically. */ unsigned long flags; /* + * Device capabiltiy flags. + * In these flags the device/driver capabilities are stored. + * Access to these flags should occur non-atomically. + */ + unsigned long cap_flags; + + /* * Device information, Bus IRQ and name (PCI, SoC) */ int irq; @@ -764,10 +841,18 @@ struct rt2x00_dev { * - Open ap interface count. * - Open sta interface count. * - Association count. + * - Beaconing enabled count. */ unsigned int intf_ap_count; unsigned int intf_sta_count; unsigned int intf_associated; + unsigned int intf_beaconing; + + /* + * Interface combinations + */ + struct ieee80211_iface_limit if_limits_ap; + struct ieee80211_iface_combination if_combinations[NUM_IF_COMB]; /* * Link quality @@ -811,32 +896,37 @@ struct rt2x00_dev { u8 rssi_offset; /* - * Frequency offset (for rt61pci & rt73usb). + * Frequency offset. */ u8 freq_offset; /* - * Calibration information (for rt2800usb & rt2800pci). - * [0] -> BW20 - * [1] -> BW40 + * Association id. */ - u8 calibration[2]; + u16 aid; /* * Beacon interval. */ u16 beacon_int; + /** + * Timestamp of last received beacon + */ + unsigned long last_beacon; + /* * Low level statistics which will have * to be kept up to date while device is running. */ struct ieee80211_low_level_stats low_level_stats; - /* - * RX configuration information. + /** + * Work queue for all work which should not be placed + * on the mac80211 workqueue (because of dependencies + * between various work structures). */ - struct ieee80211_rx_status rx_status; + struct workqueue_struct *workqueue; /* * Scheduled work. @@ -846,15 +936,26 @@ struct rt2x00_dev { */ struct work_struct intf_work; + /** + * Scheduled work for TX/RX done handling (USB devices) + */ + struct work_struct rxdone_work; + struct work_struct txdone_work; + + /* + * Powersaving work + */ + struct delayed_work autowakeup_work; + struct work_struct sleep_work; + /* - * Data queue arrays for RX, TX and Beacon. - * The Beacon array also contains the Atim queue - * if that is supported by the device. + * Data queue arrays for RX, TX, Beacon and ATIM. */ unsigned int data_queues; struct data_queue *rx; struct data_queue *tx; struct data_queue *bcn; + struct data_queue *atim; /* * Firmware image. @@ -862,9 +963,56 @@ struct rt2x00_dev { const struct firmware *fw; /* - * Driver specific data. + * FIFO for storing tx status reports between isr and tasklet. + */ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); + + /* + * Timer to ensure tx status reports are read (rt2800usb). + */ + struct hrtimer txstatus_timer; + + /* + * Tasklet for processing tx status reports (rt2800pci). + */ + struct tasklet_struct txstatus_tasklet; + struct tasklet_struct pretbtt_tasklet; + struct tasklet_struct tbtt_tasklet; + struct tasklet_struct rxdone_tasklet; + struct tasklet_struct autowake_tasklet; + + /* + * Used for VCO periodic calibration. */ - void *priv; + int rf_channel; + + /* + * Protect the interrupt mask register. + */ + spinlock_t irqmask_lock; + + /* + * List of BlockAckReq TX entries that need driver BlockAck processing. + */ + struct list_head bar_list; + spinlock_t bar_list_lock; + + /* Extra TX headroom required for alignment purposes. */ + unsigned int extra_tx_headroom; +}; + +struct rt2x00_bar_list_entry { + struct list_head list; + struct rcu_head head; + + struct queue_entry *entry; + int block_acked; + + /* Relevant parts of the IEEE80211 BAR header */ + __u8 ra[6]; + __u8 ta[6]; + __le16 control; + __le16 start_seq_num; }; /* @@ -873,7 +1021,7 @@ struct rt2x00_dev { * in those cases REGISTER_BUSY_COUNT attempts should be * taken with a REGISTER_BUSY_DELAY interval. */ -#define REGISTER_BUSY_COUNT 5 +#define REGISTER_BUSY_COUNT 100 #define REGISTER_BUSY_DELAY 100 /* @@ -895,8 +1043,7 @@ static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev, } /* - * Generic EEPROM access. - * The EEPROM is being accessed by word index. + * Generic EEPROM access. The EEPROM is being accessed by word or byte index. */ static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev, const unsigned int word) @@ -916,6 +1063,12 @@ static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev, rt2x00dev->eeprom[word] = cpu_to_le16(data); } +static inline u8 rt2x00_eeprom_byte(struct rt2x00_dev *rt2x00dev, + const unsigned int byte) +{ + return *(((u8 *)rt2x00dev->eeprom) + byte); +} + /* * Chipset handlers */ @@ -926,9 +1079,27 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, rt2x00dev->chip.rf = rf; rt2x00dev->chip.rev = rev; - INFO(rt2x00dev, - "Chipset detected - rt: %04x, rf: %04x, rev: %04x.\n", - rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev); + rt2x00_info(rt2x00dev, "Chipset detected - rt: %04x, rf: %04x, rev: %04x\n", + rt2x00dev->chip.rt, rt2x00dev->chip.rf, + rt2x00dev->chip.rev); +} + +static inline void rt2x00_set_rt(struct rt2x00_dev *rt2x00dev, + const u16 rt, const u16 rev) +{ + rt2x00dev->chip.rt = rt; + rt2x00dev->chip.rev = rev; + + rt2x00_info(rt2x00dev, "RT chipset %04x, rev %04x detected\n", + rt2x00dev->chip.rt, rt2x00dev->chip.rev); +} + +static inline void rt2x00_set_rf(struct rt2x00_dev *rt2x00dev, const u16 rf) +{ + rt2x00dev->chip.rf = rf; + + rt2x00_info(rt2x00dev, "RF chipset %04x detected\n", + rt2x00dev->chip.rf); } static inline bool rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt) @@ -978,7 +1149,13 @@ static inline bool rt2x00_intf(struct rt2x00_dev *rt2x00dev, static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev) { - return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); + return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI) || + rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); +} + +static inline bool rt2x00_is_pcie(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); } static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev) @@ -991,20 +1168,126 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev) return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); } +/* Helpers for capability flags */ + +static inline bool +rt2x00_has_cap_flag(struct rt2x00_dev *rt2x00dev, + enum rt2x00_capability_flags cap_flag) +{ + return test_bit(cap_flag, &rt2x00dev->cap_flags); +} + +static inline bool +rt2x00_has_cap_hw_crypto(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_HW_CRYPTO); +} + +static inline bool +rt2x00_has_cap_power_limit(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_POWER_LIMIT); +} + +static inline bool +rt2x00_has_cap_control_filters(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_CONTROL_FILTERS); +} + +static inline bool +rt2x00_has_cap_control_filter_pspoll(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_CONTROL_FILTER_PSPOLL); +} + +static inline bool +rt2x00_has_cap_pre_tbtt_interrupt(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_PRE_TBTT_INTERRUPT); +} + +static inline bool +rt2x00_has_cap_link_tuning(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_LINK_TUNING); +} + +static inline bool +rt2x00_has_cap_frame_type(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_FRAME_TYPE); +} + +static inline bool +rt2x00_has_cap_rf_sequence(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_RF_SEQUENCE); +} + +static inline bool +rt2x00_has_cap_external_lna_a(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_LNA_A); +} + +static inline bool +rt2x00_has_cap_external_lna_bg(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_LNA_BG); +} + +static inline bool +rt2x00_has_cap_double_antenna(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_DOUBLE_ANTENNA); +} + +static inline bool +rt2x00_has_cap_bt_coexist(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_BT_COEXIST); +} + +static inline bool +rt2x00_has_cap_vco_recalibration(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_VCO_RECALIBRATION); +} + /** * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to map. + * @entry: Pointer to &struct queue_entry + * + * Returns -ENOMEM if mapping fail, 0 otherwise. + */ +int rt2x00queue_map_txskb(struct queue_entry *entry); + +/** + * rt2x00queue_unmap_skb - Unmap a skb from DMA. + * @entry: Pointer to &struct queue_entry */ -void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); +void rt2x00queue_unmap_skb(struct queue_entry *entry); /** - * rt2x00queue_get_queue - Convert queue index to queue pointer + * rt2x00queue_get_tx_queue - Convert tx queue index to queue pointer * @rt2x00dev: Pointer to &struct rt2x00_dev. * @queue: rt2x00 queue index (see &enum data_queue_qid). + * + * Returns NULL for non tx queues. */ -struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue); +static inline struct data_queue * +rt2x00queue_get_tx_queue(struct rt2x00_dev *rt2x00dev, + const enum data_queue_qid queue) +{ + if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) + return &rt2x00dev->tx[queue]; + + if (queue == QID_ATIM) + return rt2x00dev->atim; + + return NULL; +} /** * rt2x00queue_get_entry - Get queue entry where the given index points to. @@ -1014,19 +1297,122 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, enum queue_index index); +/** + * rt2x00queue_pause_queue - Pause a data queue + * @queue: Pointer to &struct data_queue. + * + * This function will pause the data queue locally, preventing + * new frames to be added to the queue (while the hardware is + * still allowed to run). + */ +void rt2x00queue_pause_queue(struct data_queue *queue); + +/** + * rt2x00queue_unpause_queue - unpause a data queue + * @queue: Pointer to &struct data_queue. + * + * This function will unpause the data queue locally, allowing + * new frames to be added to the queue again. + */ +void rt2x00queue_unpause_queue(struct data_queue *queue); + +/** + * rt2x00queue_start_queue - Start a data queue + * @queue: Pointer to &struct data_queue. + * + * This function will start handling all pending frames in the queue. + */ +void rt2x00queue_start_queue(struct data_queue *queue); + +/** + * rt2x00queue_stop_queue - Halt a data queue + * @queue: Pointer to &struct data_queue. + * + * This function will stop all pending frames in the queue. + */ +void rt2x00queue_stop_queue(struct data_queue *queue); + +/** + * rt2x00queue_flush_queue - Flush a data queue + * @queue: Pointer to &struct data_queue. + * @drop: True to drop all pending frames. + * + * This function will flush the queue. After this call + * the queue is guaranteed to be empty. + */ +void rt2x00queue_flush_queue(struct data_queue *queue, bool drop); + +/** + * rt2x00queue_start_queues - Start all data queues + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * + * This function will loop through all available queues to start them + */ +void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev); + +/** + * rt2x00queue_stop_queues - Halt all data queues + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * + * This function will loop through all available queues to stop + * any pending frames. + */ +void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev); + +/** + * rt2x00queue_flush_queues - Flush all data queues + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @drop: True to drop all pending frames. + * + * This function will loop through all available queues to flush + * any pending frames. + */ +void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop); + +/* + * Debugfs handlers. + */ +/** + * rt2x00debug_dump_frame - Dump a frame to userspace through debugfs. + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @type: The type of frame that is being dumped. + * @skb: The skb containing the frame to be dumped. + */ +#ifdef CONFIG_RT2X00_LIB_DEBUGFS +void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, + enum rt2x00_dump_type type, struct sk_buff *skb); +#else +static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, + enum rt2x00_dump_type type, + struct sk_buff *skb) +{ +} +#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ + +/* + * Utility functions. + */ +u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif); + /* * Interrupt context handlers. */ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); +void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); +void rt2x00lib_dmastart(struct queue_entry *entry); +void rt2x00lib_dmadone(struct queue_entry *entry); void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc); -void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry); +void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); +void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp); /* * mac80211 handlers. */ -int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +void rt2x00mac_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb); int rt2x00mac_start(struct ieee80211_hw *hw); void rt2x00mac_stop(struct ieee80211_hw *hw); int rt2x00mac_add_interface(struct ieee80211_hw *hw, @@ -1047,15 +1433,29 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, #else #define rt2x00mac_set_key NULL #endif /* CONFIG_RT2X00_LIB_CRYPTO */ +int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw); +void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw); int rt2x00mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); -int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue, +int rt2x00mac_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); +void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop); +int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); +int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); +void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, + u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); +bool rt2x00mac_tx_frames_pending(struct ieee80211_hw *hw); /* * Driver allocation handlers. |
