diff options
Diffstat (limited to 'package/rt2x00/src/rt2x00.h')
-rw-r--r-- | package/rt2x00/src/rt2x00.h | 138 |
1 files changed, 86 insertions, 52 deletions
diff --git a/package/rt2x00/src/rt2x00.h b/package/rt2x00/src/rt2x00.h index dbea6acf6a..33b5094358 100644 --- a/package/rt2x00/src/rt2x00.h +++ b/package/rt2x00/src/rt2x00.h @@ -29,21 +29,17 @@ #define RT2X00_H #include <linux/bitops.h> +#include <linux/prefetch.h> #include <linux/skbuff.h> #include <linux/workqueue.h> #include <net/mac80211.h> -#include "rt2x00lib.h" -#include "rt2x00debug.h" - /* * Module information. + * DRV_NAME should be set within the individual module source files. */ -#ifndef DRV_NAME -#define DRV_NAME "rt2x00" -#endif /* DRV_NAME */ -#define DRV_VERSION "2.0.1" +#define DRV_VERSION "2.0.2" #define DRV_PROJECT "http://rt2x00.serialmonkey.com" /* @@ -142,7 +138,7 @@ /* * Interval defines */ -#define LINK_TUNE_INTERVAL ( 1 * HZ ) +#define LINK_TUNE_INTERVAL ( round_jiffies(HZ) ) #define RFKILL_POLL_INTERVAL ( HZ / 4 ) /* @@ -392,7 +388,6 @@ struct data_entry { #define ENTRY_TXD_MORE_FRAG 5 #define ENTRY_TXD_REQ_TIMESTAMP 6 #define ENTRY_TXD_REQ_ACK 7 -#define ENTRY_TXD_NEW_SEQ 8 /* * Ring we belong to. @@ -570,16 +565,25 @@ struct link { u32 count; /* - * RSSI statistics. - */ - u32 count_rssi; - u32 total_rssi; - - /* * Misc statistics. + * 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 means 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. */ - u32 curr_noise; - u32 false_cca; + int avg_rssi; + int false_cca; /* * Work structure for scheduling periodic link tuning. @@ -637,6 +641,33 @@ static inline int is_monitor_present(struct interface *intf) } /* + * Details about the supported modes, rates and channels + * of a particular chipset. This is used by rt2x00lib + * to build the ieee80211_hw_mode array for mac80211. + */ +struct hw_mode_spec { + /* + * Number of modes, rates and channels. + */ + int num_modes; + int num_rates; + int num_channels; + + /* + * txpower values. + */ + const u8 *tx_power_a; + const u8 *tx_power_bg; + u8 tx_power_default; + + /* + * Device/chipset specific value. + */ + const u32 *chan_val_a; + const u32 *chan_val_bg; +}; + +/* * rt2x00lib callback functions. */ struct rt2x00lib_ops { @@ -665,7 +696,7 @@ struct rt2x00lib_ops { int (*set_device_state)(struct rt2x00_dev *rt2x00dev, enum dev_state state); int (*rfkill_poll)(struct rt2x00_dev *rt2x00dev); - void (*link_tuner)(struct rt2x00_dev *rt2x00dev, int rssi); + void (*link_tuner)(struct rt2x00_dev *rt2x00dev); /* * TX control handlers @@ -681,12 +712,18 @@ struct rt2x00lib_ops { void (*kick_tx_queue)(struct rt2x00_dev *rt2x00dev, int queue); /* + * RX control handlers + */ + int (*fill_rxdone)(struct data_entry *entry, + int *signal, int *rssi, int *ofdm); + + /* * Configuration handlers. */ void (*config_type)(struct rt2x00_dev *rt2x00dev, const int type); void (*config_phymode)(struct rt2x00_dev *rt2x00dev, const int phy); void (*config_channel)(struct rt2x00_dev *rt2x00dev, const int value, - const int channel, const int txpower); + const int channel, const int txpower); void (*config_mac_addr)(struct rt2x00_dev *rt2x00dev, u8 *mac); void (*config_bssid)(struct rt2x00_dev *rt2x00dev, u8 *bssid); void (*config_promisc)(struct rt2x00_dev *rt2x00dev, const int promisc); @@ -723,7 +760,6 @@ struct rt2x00_dev { * macro's should be used for correct typecasting. */ void *dev; - struct device *device; #define rt2x00dev_pci(__dev) ( (struct pci_dev*)(__dev)->dev ) #define rt2x00dev_usb(__dev) ( (struct usb_interface*)(__dev)->dev ) @@ -796,12 +832,9 @@ struct rt2x00_dev { * If enabled, the debugfs interface structures * required for deregistration of debugfs. */ +#ifdef CONFIG_RT2X00_LIB_DEBUGFS const struct rt2x00debug_intf *debugfs_intf; - - /* - * Queue for deferred work. - */ - struct workqueue_struct *workqueue; +#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ /* * Interface configuration. @@ -844,9 +877,9 @@ struct rt2x00_dev { u8 led_mode; /* - * EEPROM bus width (PCI devices only). + * Rssi <-> Dbm offset */ - u8 eeprom_width; + u8 rssi_offset; /* * Frequency offset (for rt61pci & rt73usb). @@ -907,14 +940,22 @@ static inline struct data_ring* rt2x00_get_ring( * The 1 + Atim check will assure that the address directly after * the ring array is obtained and the for-each loop exits correctly. */ -#define ring_for_each(__dev, __entry) \ - for ((__entry) = (__dev)->rx; \ - (__entry) != &(__dev)->bcn[1 + \ - test_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags)]; \ - (__entry)++) +#define ring_end(__dev) \ + &(__dev)->bcn[1 + test_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags)] + +#define ring_loop(__entry, __start, __end) \ + for ((__entry) = (__start); \ + prefetch(&(__entry)[1]), (__entry) != (__end); \ + (__entry) = &(__entry)[1]) + +#define ring_for_each(__dev, __entry) \ + ring_loop(__entry, (__dev)->rx, ring_end(__dev)) + +#define txring_for_each(__dev, __entry) \ + ring_loop(__entry, (__dev)->tx, (__dev)->bcn) -#define txring_for_each(__dev, __entry) \ - for ((__entry) = (__dev)->tx; (__entry) != (__dev)->bcn; (__entry)++) +#define txringall_for_each(__dev, __entry) \ + ring_loop(__entry, (__dev)->tx, ring_end(__dev)) /* * EEPROM access. @@ -944,11 +985,10 @@ static inline void rt2x00_eeprom_write(const struct rt2x00_dev *rt2x00dev, static inline void rt2x00_start_link_tune(struct rt2x00_dev *rt2x00dev) { rt2x00dev->link.count = 0; - rt2x00dev->link.count_rssi = 0; - rt2x00dev->link.total_rssi = 0; - rt2x00dev->link.curr_noise = 0; + rt2x00dev->link.avg_rssi = 0; + rt2x00dev->link.false_cca = 0; - queue_delayed_work(rt2x00dev->workqueue, + queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, LINK_TUNE_INTERVAL); } @@ -956,26 +996,20 @@ static inline void rt2x00_stop_link_tune(struct rt2x00_dev *rt2x00dev) { if (work_pending(&rt2x00dev->link.work.work)) cancel_rearming_delayed_workqueue( - rt2x00dev->workqueue, &rt2x00dev->link.work); + rt2x00dev->hw->workqueue, &rt2x00dev->link.work); } -static inline void rt2x00_update_link_rssi(struct link *link, u32 rssi) +static inline void rt2x00_update_link_rssi(struct link *link, int rssi) { - link->count_rssi++; - link->total_rssi += rssi; + if (!link->avg_rssi) + link->avg_rssi = rssi; + else + link->avg_rssi = ((link->avg_rssi * 7) + rssi) / 8; } -static inline u32 rt2x00_get_link_rssi(struct link *link) +static inline int rt2x00_get_link_rssi(struct link *link) { - u32 average = 0; - - if (link->count_rssi && link->total_rssi) - average = link->total_rssi / link->count_rssi; - - link->count_rssi = 0; - link->total_rssi = 0; - - return average; + return link->avg_rssi; } /* |