diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00.h')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 241 |
1 files changed, 176 insertions, 65 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c8f16f1..05927b9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -31,6 +31,8 @@ #include <linux/skbuff.h> #include <linux/workqueue.h> #include <linux/firmware.h> +#include <linux/mutex.h> +#include <linux/etherdevice.h> #include <net/mac80211.h> @@ -40,9 +42,8 @@ /* * Module information. - * DRV_NAME should be set within the individual module source files. */ -#define DRV_VERSION "2.0.10" +#define DRV_VERSION "2.0.14" #define DRV_PROJECT "http://rt2x00.serialmonkey.com" /* @@ -55,7 +56,7 @@ #define DEBUG_PRINTK_PROBE(__kernlvl, __lvl, __msg, __args...) \ printk(__kernlvl "%s -> %s: %s - " __msg, \ - DRV_NAME, __FUNCTION__, __lvl, ##__args) + KBUILD_MODNAME, __FUNCTION__, __lvl, ##__args) #ifdef CONFIG_RT2X00_DEBUG #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ @@ -133,20 +134,26 @@ */ static inline int is_rts_frame(u16 fc) { - return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS)); + return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS)); } static inline int is_cts_frame(u16 fc) { - return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS)); + return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS)); } static inline int is_probe_resp(u16 fc) { - return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)); + return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)); +} + +static inline int is_beacon(u16 fc) +{ + return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)); } /* @@ -180,18 +187,17 @@ struct rf_channel { }; /* - * To optimize the quality of the link we need to store - * the quality of received frames and periodically - * optimize the link. + * Antenna setup values. */ -struct link { - /* - * Link tuner counter - * The number of times the link has been tuned - * since the radio has been switched on. - */ - u32 count; +struct antenna_setup { + enum antenna rx; + enum antenna tx; +}; +/* + * Quality statistics about the currently active link. + */ +struct link_qual { /* * Statistics required for Link tuning. * For the average RSSI value we use the "Walking average" approach. @@ -211,7 +217,6 @@ struct link { * the new values correctly allowing a effective link tuning. */ int avg_rssi; - int vgc_level; int false_cca; /* @@ -240,6 +245,72 @@ struct link { #define WEIGHT_RSSI 20 #define WEIGHT_RX 40 #define WEIGHT_TX 40 +}; + +/* + * Antenna settings about the currently active link. + */ +struct link_ant { + /* + * Antenna flags + */ + unsigned int flags; +#define ANTENNA_RX_DIVERSITY 0x00000001 +#define ANTENNA_TX_DIVERSITY 0x00000002 +#define ANTENNA_MODE_SAMPLE 0x00000004 + + /* + * Currently active TX/RX antenna setup. + * When software diversity is used, this will indicate + * which antenna is actually used at this time. + */ + 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 + */ + int rssi_history[2]; + + /* + * 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; +}; + +/* + * To optimize the quality of the link we need to store + * the quality of received frames and periodically + * optimize the link. + */ +struct link { + /* + * Link tuner counter + * The number of times the link has been tuned + * since the radio has been switched on. + */ + u32 count; + + /* + * Quality measurement values. + */ + struct link_qual qual; + + /* + * TX/RX antenna setup. + */ + struct link_ant ant; + + /* + * Active VGC level + */ + int vgc_level; /* * Work structure for scheduling periodic link tuning. @@ -248,36 +319,47 @@ struct link { }; /* - * Clear all counters inside the link structure. - * This can be easiest achieved by memsetting everything - * except for the work structure at the end. + * Small helper macro to work with moving/walking averages. */ -static inline void rt2x00_clear_link(struct link *link) -{ - memset(link, 0x00, sizeof(*link) - sizeof(link->work)); - link->rx_percentage = 50; - link->tx_percentage = 50; -} +#define MOVING_AVERAGE(__avg, __val, __samples) \ + ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) ) /* - * Update the rssi using the walking average approach. + * When we lack RSSI information return something less then -80 to + * tell the driver to tune the device to maximum sensitivity. */ -static inline void rt2x00_update_link_rssi(struct link *link, int rssi) -{ - if (!link->avg_rssi) - link->avg_rssi = rssi; - else - link->avg_rssi = ((link->avg_rssi * 7) + rssi) / 8; -} +#define DEFAULT_RSSI ( -128 ) /* - * When the avg_rssi is unset or no frames have been received), - * we need to return the default value which needs to be less - * than -80 so the device will select the maximum sensitivity. + * Link quality access functions. */ static inline int rt2x00_get_link_rssi(struct link *link) { - return (link->avg_rssi && link->rx_success) ? link->avg_rssi : -128; + 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 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; } /* @@ -290,14 +372,12 @@ struct interface { * to us by the 80211 stack, and is used to request * new beacons. */ - int id; + struct ieee80211_vif *id; /* * Current working type (IEEE80211_IF_TYPE_*). - * When set to INVALID_INTERFACE, no interface is configured. */ int type; -#define INVALID_INTERFACE IEEE80211_IF_TYPE_INVALID /* * MAC of the device. @@ -308,11 +388,6 @@ struct interface { * BBSID of the AP to associate with. */ u8 bssid[ETH_ALEN]; - - /* - * Store the packet filter mode for the current interface. - */ - unsigned int filter; }; static inline int is_interface_present(struct interface *intf) @@ -362,6 +437,8 @@ struct rt2x00lib_conf { struct ieee80211_conf *conf; struct rf_channel rf; + struct antenna_setup ant; + int phymode; int basic_rates; @@ -397,12 +474,21 @@ struct rt2x00lib_ops { void (*uninitialize) (struct rt2x00_dev *rt2x00dev); /* + * Ring initialization handlers + */ + void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, + struct data_entry *entry); + void (*init_txentry) (struct rt2x00_dev *rt2x00dev, + struct data_entry *entry); + + /* * Radio control handlers. */ int (*set_device_state) (struct rt2x00_dev *rt2x00dev, enum dev_state state); int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev); - void (*link_stats) (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); @@ -410,10 +496,8 @@ struct rt2x00lib_ops { * TX control handlers */ void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, + struct sk_buff *skb, struct txdata_entry_desc *desc, - struct ieee80211_hdr *ieee80211hdr, - unsigned int length, struct ieee80211_tx_control *control); int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, struct data_ring *ring, struct sk_buff *skb, @@ -545,7 +629,7 @@ struct rt2x00_dev { * required for deregistration of debugfs. */ #ifdef CONFIG_RT2X00_LIB_DEBUGFS - const struct rt2x00debug_intf *debugfs_intf; + struct rt2x00debug_intf *debugfs_intf; #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ /* @@ -566,6 +650,13 @@ struct rt2x00_dev { struct hw_mode_spec spec; /* + * This is the default TX/RX antenna setup as indicated + * by the device's EEPROM. When mac80211 sets its + * antenna value to 0 we should be using these values. + */ + struct antenna_setup default_ant; + + /* * Register pointers * csr_addr: Base register address. (PCI) * csr_cache: CSR cache for usb_control_msg. (USB) @@ -574,6 +665,25 @@ struct rt2x00_dev { void *csr_cache; /* + * Mutex to protect register accesses on USB devices. + * There are 2 reasons this is needed, one is to ensure + * use of the csr_cache (for USB devices) by one thread + * isn't corrupted by another thread trying to access it. + * The other is that access to BBP and RF registers + * require multiple BUS transactions and if another thread + * attempted to access one of those registers at the same + * time one of the writes could silently fail. + */ + struct mutex usb_cache_mutex; + + /* + * Current packet filter configuration for the device. + * This contains all currently active FIF_* flags send + * to us by mac80211 during configure_filter(). + */ + unsigned int packet_filter; + + /* * Interface configuration. */ struct interface interface; @@ -697,13 +807,13 @@ struct rt2x00_dev { * Generic RF access. * The RF is being accessed by word index. */ -static inline void rt2x00_rf_read(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 *data) { *data = rt2x00dev->rf[word]; } -static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 data) { rt2x00dev->rf[word] = data; @@ -713,19 +823,19 @@ static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev, * Generic EEPROM access. * The EEPROM is being accessed by word index. */ -static inline void *rt2x00_eeprom_addr(const struct rt2x00_dev *rt2x00dev, +static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev, const unsigned int word) { return (void *)&rt2x00dev->eeprom[word]; } -static inline void rt2x00_eeprom_read(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00_eeprom_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u16 *data) { *data = le16_to_cpu(rt2x00dev->eeprom[word]); } -static inline void rt2x00_eeprom_write(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, u16 data) { rt2x00dev->eeprom[word] = cpu_to_le16(data); @@ -804,9 +914,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, * TX descriptor initializer */ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, - struct ieee80211_hdr *ieee80211hdr, - unsigned int length, + struct sk_buff *skb, struct ieee80211_tx_control *control); /* @@ -821,14 +929,17 @@ 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, struct ieee80211_conf *conf); -int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id, +int rt2x00mac_config_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_if_conf *conf); int rt2x00mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, struct ieee80211_tx_queue_stats *stats); -void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, - int cts_protection, int preamble); +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, int queue, const struct ieee80211_tx_queue_params *params); |