diff options
Diffstat (limited to 'drivers/net/wireless/ath5k')
-rw-r--r-- | drivers/net/wireless/ath5k/Kconfig | 37 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/Makefile | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/ath5k.h | 170 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 575 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/base.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/debug.c | 92 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/debug.h | 29 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/hw.c | 797 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/hw.h | 150 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/initvals.c | 473 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/phy.c | 387 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reg.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/regdom.c | 121 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/regdom.h | 500 |
14 files changed, 1899 insertions, 1462 deletions
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath5k/Kconfig new file mode 100644 index 000000000000..f1f2aea2eab4 --- /dev/null +++ b/drivers/net/wireless/ath5k/Kconfig @@ -0,0 +1,37 @@ +config ATH5K + tristate "Atheros 5xxx wireless cards support" + depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL + ---help--- + This module adds support for wireless adapters based on + Atheros 5xxx chipset. + + Currently the following chip versions are supported: + + MAC: AR5211 AR5212 + PHY: RF5111/2111 RF5112/2112 RF5413/2413 + + This driver uses the kernel's mac80211 subsystem. + + If you choose to build a module, it'll be called ath5k. Say M if + unsure. + +config ATH5K_DEBUG + bool "Atheros 5xxx debugging" + depends on ATH5K + ---help--- + Atheros 5xxx debugging messages. + + Say Y, if and you will get debug options for ath5k. + To use this, you need to mount debugfs: + + mkdir /debug/ + mount -t debugfs debug /debug/ + + You will get access to files under: + /debug/ath5k/phy0/ + + To enable debug, pass the debug level to the debug module + parameter. For example: + + modprobe ath5k debug=0x00000400 + diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile index 321641f99e13..564ecd0c5d4b 100644 --- a/drivers/net/wireless/ath5k/Makefile +++ b/drivers/net/wireless/ath5k/Makefile @@ -1,2 +1,6 @@ -ath5k-objs = base.o hw.o regdom.o initvals.o phy.o debug.o -obj-$(CONFIG_ATH5K) += ath5k.o +ath5k-y += base.o +ath5k-y += hw.o +ath5k-y += initvals.o +ath5k-y += phy.o +ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o +obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 69dea3392612..ba35c30d203c 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h @@ -30,7 +30,6 @@ #include <net/mac80211.h> #include "hw.h" -#include "regdom.h" /* PCI IDs */ #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ @@ -141,7 +140,9 @@ enum ath5k_radio { AR5K_RF5110 = 0, AR5K_RF5111 = 1, AR5K_RF5112 = 2, - AR5K_RF5413 = 3, + AR5K_RF2413 = 3, + AR5K_RF5413 = 4, + AR5K_RF2425 = 5, }; /* @@ -169,12 +170,15 @@ struct ath5k_srev_name { #define AR5K_SREV_VER_AR5212 0x50 #define AR5K_SREV_VER_AR5213 0x55 #define AR5K_SREV_VER_AR5213A 0x59 -#define AR5K_SREV_VER_AR2424 0xa0 -#define AR5K_SREV_VER_AR5424 0xa3 +#define AR5K_SREV_VER_AR2413 0x78 +#define AR5K_SREV_VER_AR2414 0x79 +#define AR5K_SREV_VER_AR2424 0xa0 /* PCI-E */ +#define AR5K_SREV_VER_AR5424 0xa3 /* PCI-E */ #define AR5K_SREV_VER_AR5413 0xa4 #define AR5K_SREV_VER_AR5414 0xa5 -#define AR5K_SREV_VER_AR5416 0xc0 /* ? */ -#define AR5K_SREV_VER_AR5418 0xca +#define AR5K_SREV_VER_AR5416 0xc0 /* PCI-E */ +#define AR5K_SREV_VER_AR5418 0xca /* PCI-E */ +#define AR5K_SREV_VER_AR2425 0xe2 /* PCI-E */ #define AR5K_SREV_RAD_5110 0x00 #define AR5K_SREV_RAD_5111 0x10 @@ -184,8 +188,9 @@ struct ath5k_srev_name { #define AR5K_SREV_RAD_5112A 0x35 #define AR5K_SREV_RAD_2112 0x40 #define AR5K_SREV_RAD_2112A 0x45 +#define AR5K_SREV_RAD_SC0 0x56 /* Found on 2413/2414 */ #define AR5K_SREV_RAD_SC1 0x63 /* Found on 5413/5414 */ -#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424/5424 */ +#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424-5/5424 */ #define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */ /* IEEE defs */ @@ -251,26 +256,31 @@ struct ath5k_srev_name { */ #define MODULATION_TURBO 0x00000080 -enum ath5k_vendor_mode { - MODE_ATHEROS_TURBO = NUM_IEEE80211_MODES+1, - MODE_ATHEROS_TURBOG +enum ath5k_driver_mode { + AR5K_MODE_11A = 0, + AR5K_MODE_11A_TURBO = 1, + AR5K_MODE_11B = 2, + AR5K_MODE_11G = 3, + AR5K_MODE_11G_TURBO = 4, + AR5K_MODE_XR = 0, + AR5K_MODE_MAX = 5 }; -/* Number of supported mac80211 enum ieee80211_phymode modes by this driver */ -#define NUM_DRIVER_MODES 3 - /* adding this flag to rate_code enables short preamble, see ar5212_reg.h */ #define AR5K_SET_SHORT_PREAMBLE 0x04 -#define HAS_SHPREAMBLE(_ix) (rt->rates[_ix].modulation == IEEE80211_RATE_CCK_2) -#define SHPREAMBLE_FLAG(_ix) (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0) +#define HAS_SHPREAMBLE(_ix) \ + (rt->rates[_ix].modulation == IEEE80211_RATE_SHORT_PREAMBLE) +#define SHPREAMBLE_FLAG(_ix) \ + (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0) + /****************\ TX DEFINITIONS \****************/ /* - * Tx Descriptor + * TX Status */ struct ath5k_tx_status { u16 ts_seqnum; @@ -418,7 +428,7 @@ enum ath5k_dmasize { \****************/ /* - * Rx Descriptor + * RX Status */ struct ath5k_rx_status { u16 rs_datalen; @@ -440,16 +450,6 @@ struct ath5k_rx_status { #define AR5K_RXKEYIX_INVALID ((u8) - 1) #define AR5K_TXKEYIX_INVALID ((u32) - 1) -struct ath5k_mib_stats { - u32 ackrcv_bad; - u32 rts_bad; - u32 rts_good; - u32 fcs_bad; - u32 beacons; -}; - - - /**************************\ BEACON TIMERS DEFINITIONS @@ -492,29 +492,23 @@ struct ath5k_beacon_state { #define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10) - /********************\ COMMON DEFINITIONS \********************/ /* - * Atheros descriptor + * Atheros hardware descriptor + * This is read and written to by the hardware */ struct ath5k_desc { - u32 ds_link; - u32 ds_data; - u32 ds_ctl0; - u32 ds_ctl1; - u32 ds_hw[4]; + u32 ds_link; /* physical address of the next descriptor */ + u32 ds_data; /* physical address of data buffer (skb) */ union { - struct ath5k_rx_status rx; - struct ath5k_tx_status tx; - } ds_us; - -#define ds_rxstat ds_us.rx -#define ds_txstat ds_us.tx - + struct ath5k_hw_5210_tx_desc ds_tx5210; + struct ath5k_hw_5212_tx_desc ds_tx5212; + struct ath5k_hw_all_rx_desc ds_rx; + } ud; } __packed; #define AR5K_RXDESC_INTREQ 0x0020 @@ -560,8 +554,8 @@ struct ath5k_desc { * Used internaly in OpenHAL (ar5211.c/ar5212.c * for reset_tx_queue). Also see struct struct ieee80211_channel. */ -#define IS_CHAN_XR(_c) ((_c.val & CHANNEL_XR) != 0) -#define IS_CHAN_B(_c) ((_c.val & CHANNEL_B) != 0) +#define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0) +#define IS_CHAN_B(_c) ((_c.hw_value & CHANNEL_B) != 0) /* * The following structure will be used to map 2GHz channels to @@ -584,7 +578,7 @@ struct ath5k_athchan_2ghz { /** * struct ath5k_rate - rate structure - * @valid: is this a valid rate for the current mode + * @valid: is this a valid rate for rate control (remove) * @modulation: respective mac80211 modulation * @rate_kbps: rate in kbit/s * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on @@ -643,47 +637,48 @@ struct ath5k_rate_table { /* * Rate tables... + * TODO: CLEAN THIS !!! */ #define AR5K_RATES_11A { 8, { \ 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \ 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \ 255, 255, 255, 255, 255, 255, 255, 255 }, { \ - { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 0 }, \ - { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 0 }, \ - { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 2 }, \ - { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 2 }, \ - { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 4 }, \ - { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 4 }, \ - { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 4 }, \ - { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 4 } } \ + { 1, 0, 6000, 11, 140, 0 }, \ + { 1, 0, 9000, 15, 18, 0 }, \ + { 1, 0, 12000, 10, 152, 2 }, \ + { 1, 0, 18000, 14, 36, 2 }, \ + { 1, 0, 24000, 9, 176, 4 }, \ + { 1, 0, 36000, 13, 72, 4 }, \ + { 1, 0, 48000, 8, 96, 4 }, \ + { 1, 0, 54000, 12, 108, 4 } } \ } #define AR5K_RATES_11B { 4, { \ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ 3, 2, 1, 0, 255, 255, 255, 255 }, { \ - { 1, IEEE80211_RATE_CCK, 1000, 27, 130, 0 }, \ - { 1, IEEE80211_RATE_CCK_2, 2000, 26, 132, 1 }, \ - { 1, IEEE80211_RATE_CCK_2, 5500, 25, 139, 1 }, \ - { 1, IEEE80211_RATE_CCK_2, 11000, 24, 150, 1 } } \ + { 1, 0, 1000, 27, 130, 0 }, \ + { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 132, 1 }, \ + { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 139, 1 }, \ + { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 150, 1 } } \ } #define AR5K_RATES_11G { 12, { \ 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \ 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \ 3, 2, 1, 0, 255, 255, 255, 255 }, { \ - { 1, IEEE80211_RATE_CCK, 1000, 27, 2, 0 }, \ - { 1, IEEE80211_RATE_CCK_2, 2000, 26, 4, 1 }, \ - { 1, IEEE80211_RATE_CCK_2, 5500, 25, 11, 1 }, \ - { 1, IEEE80211_RATE_CCK_2, 11000, 24, 22, 1 }, \ - { 0, IEEE80211_RATE_OFDM, 6000, 11, 12, 4 }, \ - { 0, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \ - { 1, IEEE80211_RATE_OFDM, 12000, 10, 24, 6 }, \ - { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \ - { 1, IEEE80211_RATE_OFDM, 24000, 9, 48, 8 }, \ - { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \ - { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \ - { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \ + { 1, 0, 1000, 27, 2, 0 }, \ + { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 4, 1 }, \ + { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 11, 1 }, \ + { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 22, 1 }, \ + { 0, 0, 6000, 11, 12, 4 }, \ + { 0, 0, 9000, 15, 18, 4 }, \ + { 1, 0, 12000, 10, 24, 6 }, \ + { 1, 0, 18000, 14, 36, 6 }, \ + { 1, 0, 24000, 9, 48, 8 }, \ + { 1, 0, 36000, 13, 72, 8 }, \ + { 1, 0, 48000, 8, 96, 8 }, \ + { 1, 0, 54000, 12, 108, 8 } } \ } #define AR5K_RATES_TURBO { 8, { \ @@ -708,14 +703,14 @@ struct ath5k_rate_table { { 1, MODULATION_XR, 1000, 2, 139, 1 }, \ { 1, MODULATION_XR, 2000, 6, 150, 2 }, \ { 1, MODULATION_XR, 3000, 1, 150, 3 }, \ - { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 4 }, \ - { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \ - { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 6 }, \ - { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \ - { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 8 }, \ - { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \ - { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \ - { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \ + { 1, 0, 6000, 11, 140, 4 }, \ + { 1, 0, 9000, 15, 18, 4 }, \ + { 1, 0, 12000, 10, 152, 6 }, \ + { 1, 0, 18000, 14, 36, 6 }, \ + { 1, 0, 24000, 9, 176, 8 }, \ + { 1, 0, 36000, 13, 72, 8 }, \ + { 1, 0, 48000, 8, 96, 8 }, \ + { 1, 0, 54000, 12, 108, 8 } } \ } /* @@ -890,12 +885,14 @@ enum ath5k_capability_type { AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */ }; + +/* XXX: we *may* move cap_range stuff to struct wiphy */ struct ath5k_capabilities { /* * Supported PHY modes * (ie. CHANNEL_A, CHANNEL_B, ...) */ - DECLARE_BITMAP(cap_mode, NUM_DRIVER_MODES); + DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX); /* * Frequency range (without regulation restrictions) @@ -908,14 +905,6 @@ struct ath5k_capabilities { } cap_range; /* - * Active regulation domain settings - */ - struct { - enum ath5k_regdom reg_current; - enum ath5k_regdom reg_hw; - } cap_regdomain; - - /* * Values stored in the EEPROM (some of them...) */ struct ath5k_eeprom_info cap_eeprom; @@ -963,6 +952,7 @@ struct ath5k_hw { u16 ah_phy_revision; u16 ah_radio_5ghz_revision; u16 ah_radio_2ghz_revision; + u32 ah_phy_spending; enum ath5k_version ah_version; enum ath5k_radio ah_radio; @@ -1038,8 +1028,10 @@ struct ath5k_hw { int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); - int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *); - int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *); + int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, + struct ath5k_tx_status *); + int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *, + struct ath5k_rx_status *); }; /* @@ -1070,6 +1062,7 @@ extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); extern enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask); +extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats); /* EEPROM access functions */ extern int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain); /* Protocol Control Unit Functions */ @@ -1098,7 +1091,6 @@ extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_be extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah); extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr); #endif -extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ath5k_mib_stats *statistics); /* ACK bit rate */ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); /* ACK/CTS Timeouts */ @@ -1129,8 +1121,6 @@ extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); -/* Regulatory Domain/Channels Setup */ -extern u16 ath5k_get_regdomain(struct ath5k_hw *ah); /* Misc functions */ extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index bef967ce34a6..e18305b781c9 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -80,7 +80,7 @@ MODULE_AUTHOR("Nick Kossifidis"); MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_VERSION("0.1.1 (EXPERIMENTAL)"); +MODULE_VERSION("0.5.0 (EXPERIMENTAL)"); /* Known PCI ids */ @@ -118,12 +118,15 @@ static struct ath5k_srev_name srev_names[] = { { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 }, { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 }, { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A }, + { "2413", AR5K_VERSION_VER, AR5K_SREV_VER_AR2413 }, + { "2414", AR5K_VERSION_VER, AR5K_SREV_VER_AR2414 }, { "2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424 }, { "5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424 }, { "5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413 }, { "5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414 }, { "5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416 }, { "5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418 }, + { "2425", AR5K_VERSION_VER, AR5K_SREV_VER_AR2425 }, { "xxxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN }, { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, @@ -132,6 +135,7 @@ static struct ath5k_srev_name srev_names[] = { { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, + { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC0 }, { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1 }, { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2 }, { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, @@ -240,6 +244,8 @@ static int ath5k_chan_set(struct ath5k_softc *sc, static void ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode); static void ath5k_mode_setup(struct ath5k_softc *sc); +static void ath5k_set_total_hw_rates(struct ath5k_softc *sc); + /* Descriptor setup */ static int ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev); @@ -278,7 +284,8 @@ static int ath5k_rx_start(struct ath5k_softc *sc); static void ath5k_rx_stop(struct ath5k_softc *sc); static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, - struct sk_buff *skb); + struct sk_buff *skb, + struct ath5k_rx_status *rs); static void ath5k_tasklet_rx(unsigned long data); /* Tx handling */ static void ath5k_tx_processq(struct ath5k_softc *sc, @@ -511,35 +518,46 @@ ath5k_pci_probe(struct pci_dev *pdev, sc->ah->ah_mac_srev, sc->ah->ah_phy_revision); - if(!sc->ah->ah_single_chip){ + if (!sc->ah->ah_single_chip) { /* Single chip radio (!RF5111) */ - if(sc->ah->ah_radio_5ghz_revision && !sc->ah->ah_radio_2ghz_revision) { + if (sc->ah->ah_radio_5ghz_revision && + !sc->ah->ah_radio_2ghz_revision) { /* No 5GHz support -> report 2GHz radio */ - if(!test_bit(MODE_IEEE80211A, sc->ah->ah_capabilities.cap_mode)){ + if (!test_bit(AR5K_MODE_11A, + sc->ah->ah_capabilities.cap_mode)) { ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - /* No 2GHz support (5110 and some 5Ghz only cards) -> report 5Ghz radio */ - } else if(!test_bit(MODE_IEEE80211B, sc->ah->ah_capabilities.cap_mode)){ + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + /* No 2GHz support (5110 and some + * 5Ghz only cards) -> report 5Ghz radio */ + } else if (!test_bit(AR5K_MODE_11B, + sc->ah->ah_capabilities.cap_mode)) { ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); /* Multiband radio */ } else { ATH5K_INFO(sc, "RF%s multiband radio found" " (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); } } - /* Multi chip radio (RF5111 - RF2111) -> report both 2GHz/5GHz radios */ - else if(sc->ah->ah_radio_5ghz_revision && sc->ah->ah_radio_2ghz_revision){ + /* Multi chip radio (RF5111 - RF2111) -> + * report both 2GHz/5GHz radios */ + else if (sc->ah->ah_radio_5ghz_revision && + sc->ah->ah_radio_2ghz_revision){ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_2ghz_revision), - sc->ah->ah_radio_2ghz_revision); + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_2ghz_revision), + sc->ah->ah_radio_2ghz_revision); } } @@ -693,11 +711,14 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) goto err; } + /* Set *_rates so we can map hw rate index */ + ath5k_set_total_hw_rates(sc); + /* NB: setup here so ath5k_rate_update is happy */ - if (test_bit(MODE_IEEE80211A, ah->ah_modes)) - ath5k_setcurmode(sc, MODE_IEEE80211A); + if (test_bit(AR5K_MODE_11A, ah->ah_modes)) + ath5k_setcurmode(sc, AR5K_MODE_11A); else - ath5k_setcurmode(sc, MODE_IEEE80211B); + ath5k_setcurmode(sc, AR5K_MODE_11B); /* * Allocate tx+rx descriptors and populate the lists. @@ -837,12 +858,9 @@ ath5k_copy_rates(struct ieee80211_rate *rates, return 0; for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) { - if (!rt->rates[i].valid) - continue; - rates->rate = rt->rates[i].rate_kbps / 100; - rates->val = rt->rates[i].rate_code; - rates->flags = rt->rates[i].modulation; - rates++; + rates[count].bitrate = rt->rates[i].rate_kbps / 100; + rates[count].hw_value = rt->rates[i].rate_code; + rates[count].flags = rt->rates[i].modulation; count++; max--; } @@ -856,43 +874,22 @@ ath5k_copy_channels(struct ath5k_hw *ah, unsigned int mode, unsigned int max) { - static const struct { unsigned int mode, mask, chan; } map[] = { - [MODE_IEEE80211A] = { CHANNEL_OFDM, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_A }, - [MODE_ATHEROS_TURBO] = { CHANNEL_OFDM|CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_T }, - [MODE_IEEE80211B] = { CHANNEL_CCK, CHANNEL_CCK, CHANNEL_B }, - [MODE_IEEE80211G] = { CHANNEL_OFDM, CHANNEL_OFDM, CHANNEL_G }, - [MODE_ATHEROS_TURBOG] = { CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_TG }, - }; - static const struct ath5k_regchannel chans_2ghz[] = - IEEE80211_CHANNELS_2GHZ; - static const struct ath5k_regchannel chans_5ghz[] = - IEEE80211_CHANNELS_5GHZ; - const struct ath5k_regchannel *chans; - enum ath5k_regdom dmn; - unsigned int i, count, size, chfreq, all, f, ch; + unsigned int i, count, size, chfreq, freq, ch; if (!test_bit(mode, ah->ah_modes)) return 0; - all = ah->ah_regdomain == DMN_DEFAULT || CHAN_DEBUG == 1; - switch (mode) { - case MODE_IEEE80211A: - case MODE_ATHEROS_TURBO: + case AR5K_MODE_11A: + case AR5K_MODE_11A_TURBO: /* 1..220, but 2GHz frequencies are filtered by check_channel */ - size = all ? 220 : ARRAY_SIZE(chans_5ghz); - chans = chans_5ghz; - dmn = ath5k_regdom2flag(ah->ah_regdomain, - IEEE80211_CHANNELS_5GHZ_MIN); + size = 220 ; chfreq = CHANNEL_5GHZ; break; - case MODE_IEEE80211B: - case MODE_IEEE80211G: - case MODE_ATHEROS_TURBOG: - size = all ? 26 : ARRAY_SIZE(chans_2ghz); - chans = chans_2ghz; - dmn = ath5k_regdom2flag(ah->ah_regdomain, - IEEE80211_CHANNELS_2GHZ_MIN); + case AR5K_MODE_11B: + case AR5K_MODE_11G: + case AR5K_MODE_11G_TURBO: + size = 26; chfreq = CHANNEL_2GHZ; break; default: @@ -901,25 +898,31 @@ ath5k_copy_channels(struct ath5k_hw *ah, } for (i = 0, count = 0; i < size && max > 0; i++) { - ch = all ? i + 1 : chans[i].chan; - f = ath5k_ieee2mhz(ch); - /* Check if channel is supported by the chipset */ - if (!ath5k_channel_ok(ah, f, chfreq)) - continue; + ch = i + 1 ; + freq = ath5k_ieee2mhz(ch); - /* Match regulation domain */ - if (!all && !(IEEE80211_DMN(chans[i].domain) & - IEEE80211_DMN(dmn))) + /* Check if channel is supported by the chipset */ + if (!ath5k_channel_ok(ah, freq, chfreq)) continue; - if (!all && (chans[i].mode & map[mode].mask) != map[mode].mode) - continue; + /* Write channel info and increment counter */ + channels[count].center_freq = freq; + channels[count].band = (chfreq == CHANNEL_2GHZ) ? + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + switch (mode) { + case AR5K_MODE_11A: + case AR5K_MODE_11G: + channels[count].hw_value = chfreq | CHANNEL_OFDM; + break; + case AR5K_MODE_11A_TURBO: + case AR5K_MODE_11G_TURBO: + channels[count].hw_value = chfreq | + CHANNEL_OFDM | CHANNEL_TURBO; + break; + case AR5K_MODE_11B: + channels[count].hw_value = CHANNEL_B; + } - /* Write channel and increment counter */ - channels->chan = ch; - channels->freq = f; - channels->val = map[mode].chan; - channels++; count++; max--; } @@ -927,95 +930,78 @@ ath5k_copy_channels(struct ath5k_hw *ah, return count; } -/* Only tries to register modes our EEPROM says it can support */ -#define REGISTER_MODE(m) do { \ - ret = ath5k_register_mode(hw, m); \ - if (ret) \ - return ret; \ -} while (0) \ - -static inline int -ath5k_register_mode(struct ieee80211_hw *hw, u8 m) -{ - struct ath5k_softc *sc = hw->priv; - struct ieee80211_hw_mode *modes = sc->modes; - unsigned int i; - int ret; - - if (!test_bit(m, sc->ah->ah_capabilities.cap_mode)) - return 0; - - for (i = 0; i < NUM_DRIVER_MODES; i++) { - if (modes[i].mode != m || !modes[i].num_channels) - continue; - ret = ieee80211_register_hwmode(hw, &modes[i]); - if (ret) { - ATH5K_ERR(sc, "can't register hwmode %u\n", m); - return ret; - } - return 0; - } - BUG(); -} - static int ath5k_getchannels(struct ieee80211_hw *hw) { struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; - struct ieee80211_hw_mode *modes = sc->modes; - unsigned int i, max_r, max_c; - int ret; + struct ieee80211_supported_band *sbands = sc->sbands; + const struct ath5k_rate_table *hw_rates; + unsigned int max_r, max_c, count_r, count_c; + int mode2g = AR5K_MODE_11G; - BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3); - - /* The order here does not matter */ - modes[0].mode = MODE_IEEE80211G; - modes[1].mode = MODE_IEEE80211B; - modes[2].mode = MODE_IEEE80211A; + BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); max_r = ARRAY_SIZE(sc->rates); max_c = ARRAY_SIZE(sc->channels); + count_r = count_c = 0; - for (i = 0; i < NUM_DRIVER_MODES; i++) { - struct ieee80211_hw_mode *mode = &modes[i]; - const struct ath5k_rate_table *hw_rates; + /* 2GHz band */ + if (!test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { + mode2g = AR5K_MODE_11B; + if (!test_bit(AR5K_MODE_11B, + sc->ah->ah_capabilities.cap_mode)) + mode2g = -1; + } - if (i == 0) { - modes[0].rates = sc->rates; - modes->channels = sc->channels; - } else { - struct ieee80211_hw_mode *prev_mode = &modes[i-1]; - int prev_num_r = prev_mode->num_rates; - int prev_num_c = prev_mode->num_channels; - mode->rates = &prev_mode->rates[prev_num_r]; - mode->channels = &prev_mode->channels[prev_num_c]; - } + if (mode2g > 0) { + struct ieee80211_supported_band *sband = + &sbands[IEEE80211_BAND_2GHZ]; + + sband->bitrates = sc->rates; + sband->channels = sc->channels; + + sband->band = IEEE80211_BAND_2GHZ; + sband->n_channels = ath5k_copy_channels(ah, sband->channels, + mode2g, max_c); + + hw_rates = ath5k_hw_get_rate_table(ah, mode2g); + sband->n_bitrates = ath5k_copy_rates(sband->bitrates, + hw_rates, max_r); + + count_c = sband->n_channels; + count_r = sband->n_bitrates; + + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + + max_r -= count_r; + max_c -= count_c; - hw_rates = ath5k_hw_get_rate_table(ah, mode->mode); - mode->num_rates = ath5k_copy_rates(mode->rates, hw_rates, - max_r); - mode->num_channels = ath5k_copy_channels(ah, mode->channels, - mode->mode, max_c); - max_r -= mode->num_rates; - max_c -= mode->num_channels; } - /* We try to register all modes this driver supports. We don't bother - * with MODE_IEEE80211B for AR5212 as MODE_IEEE80211G already accounts - * for that as per mac80211. Then, REGISTER_MODE() will will actually - * check the eeprom reading for more reliable capability information. - * Order matters here as per mac80211's latest preference. This will - * all hopefullly soon go away. */ + /* 5GHz band */ - REGISTER_MODE(MODE_IEEE80211G); - if (ah->ah_version != AR5K_AR5212) - REGISTER_MODE(MODE_IEEE80211B); - REGISTER_MODE(MODE_IEEE80211A); + if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { + struct ieee80211_supported_band *sband = + &sbands[IEEE80211_BAND_5GHZ]; - ath5k_debug_dump_modes(sc, modes); + sband->bitrates = &sc->rates[count_r]; + sband->channels = &sc->channels[count_c]; - return ret; + sband->band = IEEE80211_BAND_5GHZ; + sband->n_channels = ath5k_copy_channels(ah, sband->channels, + AR5K_MODE_11A, max_c); + + hw_rates = ath5k_hw_get_rate_table(ah, AR5K_MODE_11A); + sband->n_bitrates = ath5k_copy_rates(sband->bitrates, + hw_rates, max_r); + + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; + } + + ath5k_debug_dump_bands(sc); + + return 0; } /* @@ -1030,11 +1016,15 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) struct ath5k_hw *ah = sc->ah; int ret; - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "%u (%u MHz) -> %u (%u MHz)\n", - sc->curchan->chan, sc->curchan->freq, - chan->chan, chan->freq); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", + sc->curchan->center_freq, chan->center_freq); + + if (chan->center_freq != sc->curchan->center_freq || + chan->hw_value != sc->curchan->hw_value) { + + sc->curchan = chan; + sc->curband = &sc->sbands[chan->band]; - if (chan->freq != sc->curchan->freq || chan->val != sc->curchan->val) { /* * To switch channels clear any pending DMA operations; * wait long enough for the RX fifo to drain, reset the @@ -1044,13 +1034,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) ath5k_hw_set_intr(ah, 0); /* disable interrupts */ ath5k_txq_cleanup(sc); /* clear pending tx frames */ ath5k_rx_stop(sc); /* turn off frame recv */ - ret = ath5k_hw_reset(ah, sc->opmode, chan, true); + ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); if (ret) { - ATH5K_ERR(sc, "%s: unable to reset channel %u " - "(%u Mhz)\n", __func__, chan->chan, chan->freq); + ATH5K_ERR(sc, "%s: unable to reset channel " + "(%u Mhz)\n", __func__, chan->center_freq); return ret; } - sc->curchan = chan; + ath5k_hw_set_txpower_limit(sc->ah, 0); /* @@ -1081,6 +1071,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) return 0; } +/* + * TODO: CLEAN THIS !!! + */ static void ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) { @@ -1121,10 +1114,6 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) continue; } sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD; - if (SHPREAMBLE_FLAG(ix) || rt->rates[ix].modulation == - IEEE80211_RATE_OFDM) - sc->hwmap[i].txflags |= - IEEE80211_RADIOTAP_F_SHORTPRE; /* receive frames include FCS */ sc->hwmap[i].rxflags = sc->hwmap[i].txflags | IEEE80211_RADIOTAP_F_FCS; @@ -1142,6 +1131,12 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) } sc->curmode = mode; + + if (mode == AR5K_MODE_11A) { + sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; + } else { + sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; + } } static void @@ -1164,6 +1159,72 @@ ath5k_mode_setup(struct ath5k_softc *sc) ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); } +/* + * Match the hw provided rate index (through descriptors) + * to an index for sc->curband->bitrates, so it can be used + * by the stack. + * + * This one is a little bit tricky but i think i'm right + * about this... + * + * We have 4 rate tables in the following order: + * XR (4 rates) + * 802.11a (8 rates) + * 802.11b (4 rates) + * 802.11g (12 rates) + * that make the hw rate table. + * + * Lets take a 5211 for example that supports a and b modes only. + * First comes the 802.11a table and then 802.11b (total 12 rates). + * When hw returns eg. 11 it points to the last 802.11b rate (11Mbit), + * if it returns 2 it points to the second 802.11a rate etc. + * + * Same goes for 5212 who has xr/a/b/g support (total 28 rates). + * First comes the XR table, then 802.11a, 802.11b and 802.11g. + * When hw returns eg. 27 it points to the last 802.11g rate (54Mbits) etc + */ +static void +ath5k_set_total_hw_rates(struct ath5k_softc *sc) { + + struct ath5k_hw *ah = sc->ah; + + if (test_bit(AR5K_MODE_11A, ah->ah_modes)) + sc->a_rates = 8; + + if (test_bit(AR5K_MODE_11B, ah->ah_modes)) + sc->b_rates = 4; + + if (test_bit(AR5K_MODE_11G, ah->ah_modes)) + sc->g_rates = 12; + + /* XXX: Need to see what what happens when + xr disable bits in eeprom are set */ + if (ah->ah_version >= AR5K_AR5212) + sc->xr_rates = 4; + +} + +static inline int +ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) { + + int mac80211_rix; + + if(sc->curband->band == IEEE80211_BAND_2GHZ) { + /* We setup a g ratetable for both b/g modes */ + mac80211_rix = + hw_rix - sc->b_rates - sc->a_rates - sc->xr_rates; + } else { + mac80211_rix = hw_rix - sc->xr_rates; + } + + /* Something went wrong, fallback to basic rate for this band */ + if ((mac80211_rix >= sc->curband->n_bitrates) || + (mac80211_rix <= 0 )) + mac80211_rix = 1; + + return mac80211_rix; +} + @@ -1268,7 +1329,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, ret = ah->ah_setup_tx_desc(ah, ds, pktlen, ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, - (ctl->power_level * 2), ctl->tx_rate, ctl->retry_limit, keyidx, 0, flags, 0, 0); + (sc->power_level * 2), ctl->tx_rate->hw_value, + ctl->retry_limit, keyidx, 0, flags, 0, 0); if (ret) goto err_unmap; @@ -1503,8 +1565,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) */ spin_lock_bh(&txq->lock); list_for_each_entry_safe(bf, bf0, &txq->q, list) { - ath5k_debug_printtxbuf(sc, bf, !sc->ah->ah_proc_tx_desc(sc->ah, - bf->desc)); + ath5k_debug_printtxbuf(sc, bf); ath5k_txbuf_free(sc, bf); @@ -1629,20 +1690,20 @@ ath5k_rx_stop(struct ath5k_softc *sc) static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, - struct sk_buff *skb) + struct sk_buff *skb, struct ath5k_rx_status *rs) { struct ieee80211_hdr *hdr = (void *)skb->data; unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb); - if (!(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) && - ds->ds_rxstat.rs_keyix != AR5K_RXKEYIX_INVALID) + if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && + rs->rs_keyix != AR5K_RXKEYIX_INVALID) return RX_FLAG_DECRYPTED; /* Apparently when a default key is used to decrypt the packet the hw does not set the index used to decrypt. In such cases get the index from the packet. */ if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) && - !(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) && + !(rs->rs_status & AR5K_RXERR_DECRYPT) && skb->len >= hlen + 4) { keyix = skb->data[hlen + 3] >> 6; @@ -1655,28 +1716,62 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, static void -ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb) +ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, + struct ieee80211_rx_status *rxs) { + u64 tsf, bc_tstamp; u32 hw_tu; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - if ((mgmt->frame_control & IEEE80211_FCTL_FTYPE) == + if ((le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && - (mgmt->frame_control & IEEE80211_FCTL_STYPE) == + (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON && - mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS && + le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { /* - * Received an IBSS beacon with the same BSSID. Hardware might - * have updated the TSF, check if we need to update timers. + * Received an IBSS beacon with the same BSSID. Hardware *must* + * have updated the local TSF. We have to work around various + * hardware bugs, though... */ - hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah)); - if (hw_tu >= sc->nexttbtt) { - ath5k_beacon_update_timers(sc, - mgmt->u.beacon.timestamp); + tsf = ath5k_hw_get_tsf64(sc->ah); + bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp); + hw_tu = TSF_TO_TU(tsf); + + ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, + "beacon %llx mactime %llx (diff %lld) tsf now %llx\n", + (unsigned long long)bc_tstamp, + (unsigned long long)rxs->mactime, + (unsigned long long)(rxs->mactime - bc_tstamp), + (unsigned long long)tsf); + + /* + * Sometimes the HW will give us a wrong tstamp in the rx + * status, causing the timestamp extension to go wrong. + * (This seems to happen especially with beacon frames bigger + * than 78 byte (incl. FCS)) + * But we know that the receive timestamp must be later than the + * timestamp of the beacon since HW must have synced to that. + * + * NOTE: here we assume mactime to be after the frame was + * received, not like mac80211 which defines it at the start. + */ + if (bc_tstamp > rxs->mactime) { ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, - "detected HW merge from received beacon\n"); + "fixing mactime from %llx to %llx\n", + (unsigned long long)rxs->mactime, + (unsigned long long)tsf); + rxs->mactime = tsf; } + + /* + * Local TSF might have moved higher than our beacon timers, + * in that case we have to update them to continue sending + * beacons. This also takes care of synchronizing beacon sending + * times with other stations. + */ + if (hw_tu >= sc->nexttbtt) + ath5k_beacon_update_timers(sc, bc_tstamp); } } @@ -1685,12 +1780,11 @@ static void ath5k_tasklet_rx(unsigned long data) { struct ieee80211_rx_status rxs = {}; + struct ath5k_rx_status rs = {}; struct sk_buff *skb; struct ath5k_softc *sc = (void *)data; struct ath5k_buf *bf; struct ath5k_desc *ds; - u16 len; - u8 stat; int ret; int hdrlen; int pad; @@ -1713,7 +1807,7 @@ ath5k_tasklet_rx(unsigned long data) if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */ break; - ret = sc->ah->ah_proc_rx_desc(sc->ah, ds); + ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); if (unlikely(ret == -EINPROGRESS)) break; else if (unlikely(ret)) { @@ -1722,16 +1816,15 @@ ath5k_tasklet_rx(unsigned long data) return; } - if (unlikely(ds->ds_rxstat.rs_more)) { + if (unlikely(rs.rs_more)) { ATH5K_WARN(sc, "unsupported jumbo\n"); goto next; } - stat = ds->ds_rxstat.rs_status; - if (unlikely(stat)) { - if (stat & AR5K_RXERR_PHY) + if (unlikely(rs.rs_status)) { + if (rs.rs_status & AR5K_RXERR_PHY) goto next; - if (stat & AR5K_RXERR_DECRYPT) { + if (rs.rs_status & AR5K_RXERR_DECRYPT) { /* * Decrypt error. If the error occurred * because there was no hardware key, then @@ -1742,30 +1835,29 @@ ath5k_tasklet_rx(unsigned long data) * * XXX do key cache faulting */ - if (ds->ds_rxstat.rs_keyix == - AR5K_RXKEYIX_INVALID && - !(stat & AR5K_RXERR_CRC)) + if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && + !(rs.rs_status & AR5K_RXERR_CRC)) goto accept; } - if (stat & AR5K_RXERR_MIC) { + if (rs.rs_status & AR5K_RXERR_MIC) { rxs.flag |= RX_FLAG_MMIC_ERROR; goto accept; } /* let crypto-error packets fall through in MNTR */ - if ((stat & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || + if ((rs.rs_status & + ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || sc->opmode != IEEE80211_IF_TYPE_MNTR) goto next; } accept: - len = ds->ds_rxstat.rs_datalen; - pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, len, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, + rs.rs_datalen, PCI_DMA_FROMDEVICE); pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, PCI_DMA_FROMDEVICE); bf->skb = NULL; - skb_put(skb, len); + skb_put(skb, rs.rs_datalen); /* * the hardware adds a padding to 4 byte boundaries between @@ -1787,13 +1879,23 @@ accept: * 15bit only. that means TSF extension has to be done within * 32768usec (about 32ms). it might be necessary to move this to * the interrupt handler, like it is done in madwifi. + * + * Unfortunately we don't know when the hardware takes the rx + * timestamp (beginning of phy frame, data frame, end of rx?). + * The only thing we know is that it is hardware specific... + * On AR5213 it seems the rx timestamp is at the end of the + * frame, but i'm not sure. + * + * NOTE: mac80211 defines mactime at the beginning of the first + * data symbol. Since we don't have any time references it's + * impossible to comply to that. This affects IBSS merge only + * right now, so it's not too bad... */ - rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp); + rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp); rxs.flag |= RX_FLAG_TSFT; - rxs.freq = sc->curchan->freq; - rxs.channel = sc->curchan->chan; - rxs.phymode = sc->curmode; + rxs.freq = sc->curchan->center_freq; + rxs.band = sc->curband->band; /* * signal quality: @@ -1803,25 +1905,25 @@ accept: /* noise floor in dBm, from the last noise calibration */ rxs.noise = sc->ah->ah_noise_floor; /* signal level in dBm */ - rxs.ssi = rxs.noise + ds->ds_rxstat.rs_rssi; + rxs.ssi = rxs.noise + rs.rs_rssi; /* * "signal" is actually displayed as Link Quality by iwconfig * we provide a percentage based on rssi (assuming max rssi 64) */ - rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64; + rxs.signal = rs.rs_rssi * 100 / 64; - rxs.antenna = ds->ds_rxstat.rs_antenna; - rxs.rate = ds->ds_rxstat.rs_rate; - rxs.flag |= ath5k_rx_decrypted(sc, ds, skb); + rxs.antenna = rs.rs_antenna; + rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); + rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); ath5k_debug_dump_skb(sc, skb, "RX ", 0); /* check beacons in IBSS mode */ if (sc->opmode == IEEE80211_IF_TYPE_IBSS) - ath5k_check_ibss_hw_merge(sc, skb); + ath5k_check_ibss_tsf(sc, skb, &rxs); __ieee80211_rx(sc->hw, skb, &rxs); - sc->led_rxrate = ds->ds_rxstat.rs_rate; + sc->led_rxrate = rs.rs_rate; ath5k_led_event(sc, ATH_LED_RX); next: list_move_tail(&bf->list, &sc->rxbuf); @@ -1840,6 +1942,7 @@ static void ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) { struct ieee80211_tx_status txs = {}; + struct ath5k_tx_status ts = {}; struct ath5k_buf *bf, *bf0; struct ath5k_desc *ds; struct sk_buff *skb; @@ -1852,7 +1955,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) /* TODO only one segment */ pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr, sc->desc_len, PCI_DMA_FROMDEVICE); - ret = sc->ah->ah_proc_tx_desc(sc->ah, ds); + ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); if (unlikely(ret == -EINPROGRESS)) break; else if (unlikely(ret)) { @@ -1867,17 +1970,16 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) PCI_DMA_TODEVICE); txs.control = bf->ctl; - txs.retry_count = ds->ds_txstat.ts_shortretry + - ds->ds_txstat.ts_longretry / 6; - if (unlikely(ds->ds_txstat.ts_status)) { + txs.retry_count = ts.ts_shortretry + ts.ts_longretry / 6; + if (unlikely(ts.ts_status)) { sc->ll_stats.dot11ACKFailureCount++; - if (ds->ds_txstat.ts_status & AR5K_TXERR_XRETRY) + if (ts.ts_status & AR5K_TXERR_XRETRY) txs.excessive_retries = 1; - else if (ds->ds_txstat.ts_status & AR5K_TXERR_FILT) + else if (ts.ts_status & AR5K_TXERR_FILT) txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED; } else { txs.flags |= IEEE80211_TX_STATUS_ACK; - txs.ack_signal = ds->ds_txstat.ts_rssi; + txs.ack_signal = ts.ts_rssi; } ieee80211_tx_status(sc->hw, skb, &txs); @@ -1958,8 +2060,9 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, ds->ds_data = bf->skbaddr; ret = ah->ah_setup_tx_desc(ah, ds, skb->len, ieee80211_get_hdrlen_from_skb(skb), - AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1, - AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0); + AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), + ctl->tx_rate->hw_value, 1, AR5K_TXKEYIX_INVALID, + antenna, flags, 0, 0); if (ret) goto err_unmap; @@ -2050,7 +2153,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) * beacon timer registers. * * This is called in a variety of situations, e.g. when a beacon is received, - * when a HW merge has been detected, but also when an new IBSS is created or + * when a TSF update has been detected, but also when an new IBSS is created or * when we otherwise know we have to update the timers, but we keep it in this * function to have it all together in one place. */ @@ -2150,7 +2253,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) * another AP to associate with. * * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA - * interrupts to detect HW merges only. + * interrupts to detect TSF updates only. * * AP mode is missing. */ @@ -2170,7 +2273,7 @@ ath5k_beacon_config(struct ath5k_softc *sc) * hardware send the beacons automatically. We have to load it * only once here. * We use the SWBA interrupt only to keep track of the beacon - * timers in order to detect HW merges (automatic TSF updates). + * timers in order to detect automatic TSF updates. */ ath5k_beaconq_config(sc); @@ -2211,7 +2314,8 @@ ath5k_init(struct ath5k_softc *sc) * be followed by initialization of the appropriate bits * and then setup of the interrupt mask. */ - sc->curchan = sc->hw->conf.chan; + sc->curchan = sc->hw->conf.channel; + sc->curband = &sc->sbands[sc->curchan->band]; ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false); if (ret) { ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret); @@ -2238,7 +2342,8 @@ ath5k_init(struct ath5k_softc *sc) * Enable interrupts. */ sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL | - AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL; + AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL | + AR5K_INT_MIB; ath5k_hw_set_intr(sc->ah, sc->imask); /* Set ack to be sent at low bit-rates */ @@ -2382,8 +2487,8 @@ ath5k_intr(int irq, void *dev_id) * * In IBSS mode we use this interrupt just to * keep track of the next TBTT (target beacon - * transmission time) in order to detect hardware - * merges (TSF updates). + * transmission time) in order to detect wether + * automatic TSF updates happened. */ if (sc->opmode == IEEE80211_IF_TYPE_IBSS) { /* XXX: only if VEOL suppported */ @@ -2418,7 +2523,11 @@ ath5k_intr(int irq, void *dev_id) if (status & AR5K_INT_BMISS) { } if (status & AR5K_INT_MIB) { - /* TODO */ + /* + * These stats are also used for ANI i think + * so how about updating them more often ? + */ + ath5k_hw_update_mib_counters(ah, &sc->ll_stats); } } } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0); @@ -2448,7 +2557,8 @@ ath5k_calibrate(unsigned long data) struct ath5k_hw *ah = sc->ah; ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", - sc->curchan->chan, sc->curchan->val); + ieee80211_frequency_to_channel(sc->curchan->center_freq), + sc->curchan->hw_value); if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) { /* @@ -2460,7 +2570,8 @@ ath5k_calibrate(unsigned long data) } if (ath5k_hw_phy_calibrate(ah, sc->curchan)) ATH5K_ERR(sc, "calibration of channel %u failed\n", - sc->curchan->chan); + ieee80211_frequency_to_channel( + sc->curchan->center_freq)); mod_timer(&sc->calib_tim, round_jiffies(jiffies + msecs_to_jiffies(ath5k_calinterval * 1000))); @@ -2558,7 +2669,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb, memmove(skb->data, skb->data+pad, hdrlen); } - sc->led_txrate = ctl->tx_rate; + sc->led_txrate = ctl->tx_rate->hw_value; spin_lock_irqsave(&sc->txbuflock, flags); if (list_empty(&sc->txbuf)) { @@ -2597,11 +2708,6 @@ ath5k_reset(struct ieee80211_hw *hw) int ret; ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); - /* - * Convert to a hw channel description with the flags - * constrained to reflect the current operating mode. - */ - sc->curchan = hw->conf.chan; ath5k_hw_set_intr(ah, 0); ath5k_txq_cleanup(sc); @@ -2692,6 +2798,9 @@ end: mutex_unlock(&sc->lock); } +/* + * TODO: Phy disable/diversity etc + */ static int ath5k_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) @@ -2699,9 +2808,9 @@ ath5k_config(struct ieee80211_hw *hw, struct ath5k_softc *sc = hw->priv; sc->bintval = conf->beacon_int; - ath5k_setcurmode(sc, conf->phymode); + sc->power_level = conf->power_level; - return ath5k_chan_set(sc, conf->chan); + return ath5k_chan_set(sc, conf->channel); } static int @@ -2869,7 +2978,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch(key->alg) { case ALG_WEP: - break; + /* XXX: fix hardware encryption, its not working. For now + * allow software encryption */ + /* break; */ case ALG_TKIP: case ALG_CCMP: return -EOPNOTSUPP; @@ -2909,6 +3020,10 @@ ath5k_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + + /* Force update */ + ath5k_hw_update_mib_counters(ah, &sc->ll_stats); memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats)); diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index 8287ae787f12..3a9755893018 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h @@ -83,7 +83,7 @@ struct ath5k_txq { #if CHAN_DEBUG #define ATH_CHAN_MAX (26+26+26+200+200) #else -#define ATH_CHAN_MAX (14+14+14+252+20) /* XXX what's the max? */ +#define ATH_CHAN_MAX (14+14+14+252+20) #endif /* Software Carrier, keeps track of the driver state @@ -95,15 +95,22 @@ struct ath5k_softc { struct ieee80211_tx_queue_stats tx_stats; struct ieee80211_low_level_stats ll_stats; struct ieee80211_hw *hw; /* IEEE 802.11 common */ - struct ieee80211_hw_mode modes[NUM_DRIVER_MODES]; + struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; struct ieee80211_channel channels[ATH_CHAN_MAX]; - struct ieee80211_rate rates[AR5K_MAX_RATES * NUM_DRIVER_MODES]; + struct ieee80211_rate rates[AR5K_MAX_RATES * IEEE80211_NUM_BANDS]; enum ieee80211_if_types opmode; struct ath5k_hw *ah; /* Atheros HW */ -#if ATH5K_DEBUG + struct ieee80211_supported_band *curband; + + u8 a_rates; + u8 b_rates; + u8 g_rates; + u8 xr_rates; + +#ifdef CONFIG_ATH5K_DEBUG struct ath5k_dbg_info debug; /* debug info */ -#endif +#endif /* CONFIG_ATH5K_DEBUG */ struct ath5k_buf *bufptr; /* allocated buffer ptr */ struct ath5k_desc *desc; /* TX/RX descriptors */ @@ -169,6 +176,7 @@ struct ath5k_softc { unsigned int nexttbtt; /* next beacon time in TU */ struct timer_list calib_tim; /* calibration timer */ + int power_level; /* Requested tx power in dbm */ }; #define ath5k_hw_hasbssidmask(_ah) \ diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c index bb581ef6d1ef..41d5fa34b544 100644 --- a/drivers/net/wireless/ath5k/debug.c +++ b/drivers/net/wireless/ath5k/debug.c @@ -65,7 +65,7 @@ static unsigned int ath5k_debug; module_param_named(debug, ath5k_debug, uint, 0); -#if ATH5K_DEBUG +#ifdef CONFIG_ATH5K_DEBUG #include <linux/seq_file.h> #include "reg.h" @@ -200,7 +200,8 @@ static ssize_t read_file_tsf(struct file *file, char __user *user_buf, { struct ath5k_softc *sc = file->private_data; char buf[100]; - snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah)); + snprintf(buf, sizeof(buf), "0x%016llx\n", + (unsigned long long)ath5k_hw_get_tsf64(sc->ah)); return simple_read_from_buffer(user_buf, count, ppos, buf, 19); } @@ -271,7 +272,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf, tsf = ath5k_hw_get_tsf64(sc->ah); len += snprintf(buf+len, sizeof(buf)-len, - "TSF\t\t0x%016llx\tTU: %08x\n", tsf, TSF_TO_TU(tsf)); + "TSF\t\t0x%016llx\tTU: %08x\n", + (unsigned long long)tsf, TSF_TO_TU(tsf)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -340,7 +342,7 @@ static struct { { ATH5K_DEBUG_LED, "led", "LED mamagement" }, { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, - { ATH5K_DEBUG_DUMPMODES, "dumpmodes", "dump modes" }, + { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, }; @@ -452,43 +454,63 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) /* functions used in other places */ void -ath5k_debug_dump_modes(struct ath5k_softc *sc, struct ieee80211_hw_mode *modes) +ath5k_debug_dump_bands(struct ath5k_softc *sc) { - unsigned int m, i; + unsigned int b, i; - if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPMODES))) + if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS))) return; - for (m = 0; m < NUM_DRIVER_MODES; m++) { - printk(KERN_DEBUG "Mode %u: channels %d, rates %d\n", m, - modes[m].num_channels, modes[m].num_rates); + BUG_ON(!sc->sbands); + + for (b = 0; b < IEEE80211_NUM_BANDS; b++) { + struct ieee80211_supported_band *band = &sc->sbands[b]; + char bname[5]; + switch (band->band) { + case IEEE80211_BAND_2GHZ: + strcpy(bname, "2 GHz"); + break; + case IEEE80211_BAND_5GHZ: + strcpy(bname, "5 GHz"); + break; + default: + printk(KERN_DEBUG "Band not supported: %d\n", + band->band); + return; + } + printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname, + band->n_channels, band->n_bitrates); printk(KERN_DEBUG " channels:\n"); - for (i = 0; i < modes[m].num_channels; i++) + for (i = 0; i < band->n_channels; i++) printk(KERN_DEBUG " %3d %d %.4x %.4x\n", - modes[m].channels[i].chan, - modes[m].channels[i].freq, - modes[m].channels[i].val, - modes[m].channels[i].flag); + ieee80211_frequency_to_channel( + band->channels[i].center_freq), + band->channels[i].center_freq, + band->channels[i].hw_value, + band->channels[i].flags); printk(KERN_DEBUG " rates:\n"); - for (i = 0; i < modes[m].num_rates; i++) + for (i = 0; i < band->n_bitrates; i++) printk(KERN_DEBUG " %4d %.4x %.4x %.4x\n", - modes[m].rates[i].rate, - modes[m].rates[i].val, - modes[m].rates[i].flags, - modes[m].rates[i].val2); + band->bitrates[i].bitrate, + band->bitrates[i].hw_value, + band->bitrates[i].flags, + band->bitrates[i].hw_value_short); } } static inline void -ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done) +ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done, + struct ath5k_rx_status *rs) { struct ath5k_desc *ds = bf->desc; + struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx; printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n", ds, (unsigned long long)bf->daddr, - ds->ds_link, ds->ds_data, ds->ds_ctl0, ds->ds_ctl1, - ds->ds_hw[0], ds->ds_hw[1], - !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!'); + ds->ds_link, ds->ds_data, + rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1, + rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0, + !done ? ' ' : (rs->rs_status == 0) ? '*' : '!'); } void @@ -496,6 +518,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) { struct ath5k_desc *ds; struct ath5k_buf *bf; + struct ath5k_rx_status rs = {}; int status; if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) @@ -507,9 +530,9 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) spin_lock_bh(&sc->rxbuflock); list_for_each_entry(bf, &sc->rxbuf, list) { ds = bf->desc; - status = ah->ah_proc_rx_desc(ah, ds); + status = ah->ah_proc_rx_desc(ah, ds, &rs); if (!status) - ath5k_debug_printrxbuf(bf, status == 0); + ath5k_debug_printrxbuf(bf, status == 0, &rs); } spin_unlock_bh(&sc->rxbuflock); } @@ -533,19 +556,24 @@ ath5k_debug_dump_skb(struct ath5k_softc *sc, } void -ath5k_debug_printtxbuf(struct ath5k_softc *sc, - struct ath5k_buf *bf, int done) +ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) { struct ath5k_desc *ds = bf->desc; + struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212; + struct ath5k_tx_status ts = {}; + int done; if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) return; + done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts); + printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x " "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link, - ds->ds_data, ds->ds_ctl0, ds->ds_ctl1, - ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3], - !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!'); + ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1, + td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3, + td->tx_stat.tx_status_0, td->tx_stat.tx_status_1, + done ? ' ' : (ts.ts_status == 0) ? '*' : '!'); } -#endif /* if ATH5K_DEBUG */ +#endif /* ifdef CONFIG_ATH5K_DEBUG */ diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h index c4fd8c43df0c..2cf8d18b10e3 100644 --- a/drivers/net/wireless/ath5k/debug.h +++ b/drivers/net/wireless/ath5k/debug.h @@ -61,11 +61,6 @@ #ifndef _ATH5K_DEBUG_H #define _ATH5K_DEBUG_H -/* set this to 1 for debugging output */ -#ifndef ATH5K_DEBUG -#define ATH5K_DEBUG 0 -#endif - struct ath5k_softc; struct ath5k_hw; struct ieee80211_hw_mode; @@ -96,7 +91,7 @@ struct ath5k_dbg_info { * @ATH5K_DEBUG_LED: led management * @ATH5K_DEBUG_DUMP_RX: print received skb content * @ATH5K_DEBUG_DUMP_TX: print transmit skb content - * @ATH5K_DEBUG_DUMPMODES: dump modes + * @ATH5K_DEBUG_DUMPBANDS: dump bands * @ATH5K_DEBUG_TRACE: trace function calls * @ATH5K_DEBUG_ANY: show at any debug level * @@ -118,12 +113,12 @@ enum ath5k_debug_level { ATH5K_DEBUG_LED = 0x00000080, ATH5K_DEBUG_DUMP_RX = 0x00000100, ATH5K_DEBUG_DUMP_TX = 0x00000200, - ATH5K_DEBUG_DUMPMODES = 0x00000400, + ATH5K_DEBUG_DUMPBANDS = 0x00000400, ATH5K_DEBUG_TRACE = 0x00001000, ATH5K_DEBUG_ANY = 0xffffffff }; -#if ATH5K_DEBUG +#ifdef CONFIG_ATH5K_DEBUG #define ATH5K_TRACE(_sc) do { \ if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \ @@ -158,20 +153,20 @@ void ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); void -ath5k_debug_dump_modes(struct ath5k_softc *sc, - struct ieee80211_hw_mode *modes); +ath5k_debug_dump_bands(struct ath5k_softc *sc); void ath5k_debug_dump_skb(struct ath5k_softc *sc, struct sk_buff *skb, const char *prefix, int tx); void -ath5k_debug_printtxbuf(struct ath5k_softc *sc, - struct ath5k_buf *bf, int done); +ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf); #else /* no debugging */ -#define ATH5K_TRACE(_sc) /* empty */ +#include <linux/compiler.h> + +#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc)) static inline void __attribute__ ((format (printf, 3, 4))) ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} @@ -196,17 +191,15 @@ static inline void ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} static inline void -ath5k_debug_dump_modes(struct ath5k_softc *sc, - struct ieee80211_hw_mode *modes) {} +ath5k_debug_dump_bands(struct ath5k_softc *sc) {} static inline void ath5k_debug_dump_skb(struct ath5k_softc *sc, struct sk_buff *skb, const char *prefix, int tx) {} static inline void -ath5k_debug_printtxbuf(struct ath5k_softc *sc, - struct ath5k_buf *bf, int done) {} +ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {} -#endif /* if ATH5K_DEBUG */ +#endif /* ifdef CONFIG_ATH5K_DEBUG */ #endif /* ifndef _ATH5K_DEBUG_H */ diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 01757436353d..5fb1ae6ad3e2 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c @@ -1,4 +1,4 @@ - /* +/* * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org> @@ -48,14 +48,18 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *); +static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *, + struct ath5k_tx_status *); static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *); -static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *, struct ath5k_desc *); -static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *, struct ath5k_desc *); +static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *, + struct ath5k_tx_status *); +static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *, struct ath5k_desc *, + struct ath5k_rx_status *); +static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *, struct ath5k_desc *, + struct ath5k_rx_status *); static int ath5k_hw_get_capabilities(struct ath5k_hw *); static int ath5k_eeprom_init(struct ath5k_hw *); @@ -81,12 +85,12 @@ static int ath5k_hw_disable_pspoll(struct ath5k_hw *); static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) { - return turbo == true ? (usec * 80) : (usec * 40); + return turbo ? (usec * 80) : (usec * 40); } static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo) { - return turbo == true ? (clock / 80) : (clock / 40); + return turbo ? (clock / 80) : (clock / 40); } /* @@ -100,7 +104,7 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { data = ath5k_hw_reg_read(ah, reg); - if ((is_set == true) && (data & flag)) + if (is_set && (data & flag)) break; else if ((data & flag) == val) break; @@ -116,11 +120,69 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, \***************************************/ /* + * Power On Self Test helper function + */ +static int ath5k_hw_post(struct ath5k_hw *ah) +{ + + int i, c; + u16 cur_reg; + u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)}; + u32 var_pattern; + u32 static_pattern[4] = { + 0x55555555, 0xaaaaaaaa, + 0x66666666, 0x99999999 + }; + u32 init_val; + u32 cur_val; + + for (c = 0; c < 2; c++) { + + cur_reg = regs[c]; + init_val = ath5k_hw_reg_read(ah, cur_reg); + + for (i = 0; i < 256; i++) { + var_pattern = i << 16 | i; + ath5k_hw_reg_write(ah, var_pattern, cur_reg); + cur_val = ath5k_hw_reg_read(ah, cur_reg); + + if (cur_val != var_pattern) { + ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n"); + return -EAGAIN; + } + + /* Found on ndiswrapper dumps */ + var_pattern = 0x0039080f; + ath5k_hw_reg_write(ah, var_pattern, cur_reg); + } + + for (i = 0; i < 4; i++) { + var_pattern = static_pattern[i]; + ath5k_hw_reg_write(ah, var_pattern, cur_reg); + cur_val = ath5k_hw_reg_read(ah, cur_reg); + + if (cur_val != var_pattern) { + ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n"); + return -EAGAIN; + } + + /* Found on ndiswrapper dumps */ + var_pattern = 0x003b080f; + ath5k_hw_reg_write(ah, var_pattern, cur_reg); + } + } + + return 0; + +} + +/* * Check if the device is supported and initialize the needed structs */ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) { struct ath5k_hw *ah; + struct pci_dev *pdev = sc->pdev; u8 mac[ETH_ALEN]; int ret; u32 srev; @@ -140,9 +202,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) * HW information */ - /* Get reg domain from eeprom */ - ath5k_get_regdomain(ah); - ah->ah_op_mode = IEEE80211_IF_TYPE_STA; ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; ah->ah_turbo = false; @@ -177,9 +236,9 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) } if (ah->ah_version == AR5K_AR5212) - ah->ah_proc_rx_desc = ath5k_hw_proc_new_rx_status; + ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; else if (ah->ah_version <= AR5K_AR5211) - ah->ah_proc_rx_desc = ath5k_hw_proc_old_rx_status; + ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; /* Bring device out of sleep and reset it's units */ ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true); @@ -203,15 +262,19 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) CHANNEL_2GHZ); /* Return on unsuported chips (unsupported eeprom etc) */ - if(srev >= AR5K_SREV_VER_AR5416){ + if ((srev >= AR5K_SREV_VER_AR5416) && + (srev < AR5K_SREV_VER_AR2425)) { ATH5K_ERR(sc, "Device not yet supported.\n"); ret = -ENODEV; goto err_free; + } else if (srev == AR5K_SREV_VER_AR2425) { + ATH5K_WARN(sc, "Support for RF2425 is under development.\n"); } /* Identify single chip solutions */ - if((srev <= AR5K_SREV_VER_AR5414) && - (srev >= AR5K_SREV_VER_AR2424)) { + if (((srev <= AR5K_SREV_VER_AR5414) && + (srev >= AR5K_SREV_VER_AR2413)) || + (srev == AR5K_SREV_VER_AR2425)) { ah->ah_single_chip = true; } else { ah->ah_single_chip = false; @@ -226,15 +289,87 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) ah->ah_radio = AR5K_RF5110; } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) { ah->ah_radio = AR5K_RF5111; - } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) { + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; + } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) { + ah->ah_radio = AR5K_RF5112; - } else { + + if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) { + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; + } else { + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; + } + + } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) { + ah->ah_radio = AR5K_RF2413; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; + } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) { ah->ah_radio = AR5K_RF5413; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; + } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) { + + /* AR5424 */ + if (srev >= AR5K_SREV_VER_AR5424) { + ah->ah_radio = AR5K_RF5413; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424; + /* AR2424 */ + } else { + ah->ah_radio = AR5K_RF2413; /* For testing */ + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; + } + + /* + * Register returns 0x4 for radio revision + * so ath5k_hw_radio_revision doesn't parse the value + * correctly. For now we are based on mac's srev to + * identify RF2425 radio. + */ + } else if (srev == AR5K_SREV_VER_AR2425) { + ah->ah_radio = AR5K_RF2425; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; } ah->ah_phy = AR5K_PHY(0); /* + * Identify AR5212-based PCI-E cards + * And write some initial settings. + * + * (doing a "strings" on ndis driver + * -ar5211.sys- reveals the following + * pci-e related functions: + * + * pcieClockReq + * pcieRxErrNotify + * pcieL1SKPEnable + * pcieAspm + * pcieDisableAspmOnRfWake + * pciePowerSaveEnable + * + * I guess these point to ClockReq but + * i'm not sure.) + */ + if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { + ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080); + ath5k_hw_reg_write(ah, 0x24924924, 0x4080); + ath5k_hw_reg_write(ah, 0x28000039, 0x4080); + ath5k_hw_reg_write(ah, 0x53160824, 0x4080); + ath5k_hw_reg_write(ah, 0xe5980579, 0x4080); + ath5k_hw_reg_write(ah, 0x001defff, 0x4080); + ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080); + ath5k_hw_reg_write(ah, 0xbe105554, 0x4080); + ath5k_hw_reg_write(ah, 0x000e3007, 0x4080); + ath5k_hw_reg_write(ah, 0x00000000, 0x4084); + } + + /* + * POST + */ + ret = ath5k_hw_post(ah); + if (ret) + goto err_free; + + /* * Get card capabilities, values, ... */ @@ -280,7 +415,8 @@ err: */ static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) { - u32 turbo, mode, clock; + struct pci_dev *pdev = ah->ah_sc->pdev; + u32 turbo, mode, clock, bus_flags; int ret; turbo = 0; @@ -357,10 +493,16 @@ static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) AR5K_PHY_TURBO); } - /* ...reset chipset and PCI device */ - if (ah->ah_single_chip == false && ath5k_hw_nic_reset(ah, - AR5K_RESET_CTL_CHIP | AR5K_RESET_CTL_PCI)) { - ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip + PCI\n"); + /* reseting PCI on PCI-E cards results card to hang + * and always return 0xffff... so we ingore that flag + * for PCI-E cards */ + bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; + + /* Reset chipset */ + ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | + AR5K_RESET_CTL_BASEBAND | bus_flags); + if (ret) { + ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n"); return -EIO; } @@ -405,15 +547,15 @@ const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, /* Get rate tables */ switch (mode) { - case MODE_IEEE80211A: + case AR5K_MODE_11A: return &ath5k_rt_11a; - case MODE_ATHEROS_TURBO: + case AR5K_MODE_11A_TURBO: return &ath5k_rt_turbo; - case MODE_IEEE80211B: + case AR5K_MODE_11B: return &ath5k_rt_11b; - case MODE_IEEE80211G: + case AR5K_MODE_11G: return &ath5k_rt_11g; - case MODE_ATHEROS_TURBOG: + case AR5K_MODE_11G_TURBO: return &ath5k_rt_xr; } @@ -459,15 +601,15 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, ds_coef_exp, ds_coef_man, clock; if (!(ah->ah_version == AR5K_AR5212) || - !(channel->val & CHANNEL_OFDM)) + !(channel->hw_value & CHANNEL_OFDM)) BUG(); /* Seems there are two PLLs, one for baseband sampling and one * for tuning. Tuning basebands are 40 MHz or 80MHz when in * turbo. */ - clock = channel->val & CHANNEL_TURBO ? 80 : 40; + clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40; coef_scaled = ((5 * (clock << 24)) / 2) / - channel->freq; + channel->center_freq; for (coef_exp = 31; coef_exp > 0; coef_exp--) if ((coef_scaled >> coef_exp) & 0x1) @@ -494,8 +636,7 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, * ath5k_hw_write_rate_duration - set rate duration during hw resets * * @ah: the &struct ath5k_hw - * @driver_mode: one of enum ieee80211_phymode or our one of our own - * vendor modes + * @mode: one of enum ath5k_driver_mode * * Write the rate duration table for the current mode upon hw reset. This * is a helper for ath5k_hw_reset(). It seems all this is doing is setting @@ -506,19 +647,20 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, * */ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, - unsigned int driver_mode) + unsigned int mode) { struct ath5k_softc *sc = ah->ah_sc; const struct ath5k_rate_table *rt; + struct ieee80211_rate srate = {}; unsigned int i; /* Get rate table for the current operating mode */ - rt = ath5k_hw_get_rate_table(ah, - driver_mode); + rt = ath5k_hw_get_rate_table(ah, mode); /* Write rate duration table */ for (i = 0; i < rt->rate_count; i++) { const struct ath5k_rate *rate, *control_rate; + u32 reg; u16 tx_time; @@ -528,14 +670,16 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, /* Set ACK timeout */ reg = AR5K_RATE_DUR(rate->rate_code); + srate.bitrate = control_rate->rate_kbps/100; + /* An ACK frame consists of 10 bytes. If you add the FCS, * which ieee80211_generic_frame_duration() adds, * its 14 bytes. Note we use the control rate and not the * actual rate for this rate. See mac80211 tx.c * ieee80211_duration() for a brief description of * what rate we should choose to TX ACKs. */ - tx_time = ieee80211_generic_frame_duration(sc->hw, - sc->vif, 10, control_rate->rate_kbps/100); + tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, + sc->vif, 10, &srate)); ath5k_hw_reg_write(ah, tx_time, reg); @@ -568,8 +712,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, struct ieee80211_channel *channel, bool change_channel) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 data, s_seq, s_ant, s_led[3]; - unsigned int i, mode, freq, ee_mode, ant[2], driver_mode = -1; + struct pci_dev *pdev = ah->ah_sc->pdev; + u32 data, s_seq, s_ant, s_led[3], dma_size; + unsigned int i, mode, freq, ee_mode, ant[2]; int ret; ATH5K_TRACE(ah->ah_sc); @@ -585,7 +730,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, */ /*DCU/Antenna selection not available on 5210*/ if (ah->ah_version != AR5K_AR5210) { - if (change_channel == true) { + if (change_channel) { /* Seq number for queue 0 -do this for all queues ? */ s_seq = ath5k_hw_reg_read(ah, AR5K_QUEUE_DFS_SEQNUM(0)); @@ -599,12 +744,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); - if (change_channel == true && ah->ah_rf_banks != NULL) + if (change_channel && ah->ah_rf_banks != NULL) ath5k_hw_get_rf_gain(ah); /*Wakeup the device*/ - ret = ath5k_hw_nic_wakeup(ah, channel->val, false); + ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); if (ret) return ret; @@ -620,43 +765,40 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, if (ah->ah_version != AR5K_AR5210) { if (ah->ah_radio != AR5K_RF5111 && ah->ah_radio != AR5K_RF5112 && - ah->ah_radio != AR5K_RF5413) { + ah->ah_radio != AR5K_RF5413 && + ah->ah_radio != AR5K_RF2413 && + ah->ah_radio != AR5K_RF2425) { ATH5K_ERR(ah->ah_sc, "invalid phy radio: %u\n", ah->ah_radio); return -EINVAL; } - switch (channel->val & CHANNEL_MODES) { + switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: - mode = AR5K_INI_VAL_11A; + mode = AR5K_MODE_11A; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; - driver_mode = MODE_IEEE80211A; break; case CHANNEL_G: - mode = AR5K_INI_VAL_11G; + mode = AR5K_MODE_11G; freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11G; - driver_mode = MODE_IEEE80211G; break; case CHANNEL_B: - mode = AR5K_INI_VAL_11B; + mode = AR5K_MODE_11B; freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11B; - driver_mode = MODE_IEEE80211B; break; case CHANNEL_T: - mode = AR5K_INI_VAL_11A_TURBO; + mode = AR5K_MODE_11A_TURBO; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; - driver_mode = MODE_ATHEROS_TURBO; break; /*Is this ok on 5211 too ?*/ case CHANNEL_TG: - mode = AR5K_INI_VAL_11G_TURBO; + mode = AR5K_MODE_11G_TURBO; freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11G; - driver_mode = MODE_ATHEROS_TURBOG; break; case CHANNEL_XR: if (ah->ah_version == AR5K_AR5211) { @@ -664,14 +806,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, "XR mode not available on 5211"); return -EINVAL; } - mode = AR5K_INI_VAL_XR; + mode = AR5K_MODE_XR; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; - driver_mode = MODE_IEEE80211A; break; default: ATH5K_ERR(ah->ah_sc, - "invalid channel: %d\n", channel->freq); + "invalid channel: %d\n", channel->center_freq); return -EINVAL; } @@ -701,15 +842,26 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, /* * Write some more initial register settings */ - if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */ + if (ah->ah_version == AR5K_AR5212) { ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); - if (channel->val == CHANNEL_G) - ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */ + if (channel->hw_value == CHANNEL_G) + if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413) + ath5k_hw_reg_write(ah, 0x00f80d80, + AR5K_PHY(83)); + else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424) + ath5k_hw_reg_write(ah, 0x00380140, + AR5K_PHY(83)); + else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425) + ath5k_hw_reg_write(ah, 0x00fc0ec0, + AR5K_PHY(83)); + else /* 2425 */ + ath5k_hw_reg_write(ah, 0x00fc0fc0, + AR5K_PHY(83)); else - ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83)); + ath5k_hw_reg_write(ah, 0x00000000, + AR5K_PHY(83)); - ath5k_hw_reg_write(ah, 0x000001b5, 0xa228); /* 0x000009b5 */ ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); ath5k_hw_reg_write(ah, 0x0000000f, 0x8060); ath5k_hw_reg_write(ah, 0x00000000, 0xa254); @@ -722,7 +874,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, AR5K_SREV_RAD_5112A) { ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, AR5K_PHY_CCKTXCTL); - if (channel->val & CHANNEL_5GHZ) + if (channel->hw_value & CHANNEL_5GHZ) data = 0xffb81020; else data = 0xffb80d20; @@ -742,7 +894,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, * mac80211 are integrated */ if (ah->ah_version == AR5K_AR5212 && ah->ah_sc->vif != NULL) - ath5k_hw_write_rate_duration(ah, driver_mode); + ath5k_hw_write_rate_duration(ah, mode); /* * Write RF registers @@ -758,7 +910,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, /* Write OFDM timings on 5212*/ if (ah->ah_version == AR5K_AR5212 && - channel->val & CHANNEL_OFDM) { + channel->hw_value & CHANNEL_OFDM) { ret = ath5k_hw_write_ofdm_timings(ah, channel); if (ret) return ret; @@ -767,7 +919,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, /*Enable/disable 802.11b mode on 5111 (enable 2111 frequency converter + CCK)*/ if (ah->ah_radio == AR5K_RF5111) { - if (driver_mode == MODE_IEEE80211B) + if (mode == AR5K_MODE_11B) AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_B_MODE); else @@ -885,13 +1037,24 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, /* * Set Rx/Tx DMA Configuration - *(passing dma size not available on 5210) + * + * Set maximum DMA size (512) except for PCI-E cards since + * it causes rx overruns and tx errors (tested on 5424 but since + * rx overruns also occur on 5416/5418 with madwifi we set 128 + * for all PCI-E cards to be safe). + * + * In dumps this is 128 for allchips. + * + * XXX: need to check 5210 for this + * TODO: Check out tx triger level, it's always 64 on dumps but I + * guess we can tweak it and see how it goes ;-) */ + dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B; if (ah->ah_version != AR5K_AR5210) { - AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR, - AR5K_DMASIZE_512B | AR5K_TXCFG_DMASIZE); - AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_SDMAMW, - AR5K_DMASIZE_512B); + AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, + AR5K_TXCFG_SDMAMR, dma_size); + AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, + AR5K_RXCFG_SDMAMW, dma_size); } /* @@ -905,7 +1068,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, if (ah->ah_version != AR5K_AR5210) { data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & AR5K_PHY_RX_DELAY_M; - data = (channel->val & CHANNEL_CCK) ? + data = (channel->hw_value & CHANNEL_CCK) ? ((data << 2) / 22) : (data / 10); udelay(100 + data); @@ -922,11 +1085,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL, 0, false)) { ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", - channel->freq); + channel->center_freq); return -EAGAIN; } - ret = ath5k_hw_noise_floor_calibration(ah, channel->freq); + ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); if (ret) return ret; @@ -934,7 +1097,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, /* A and G modes can use QAM modulation which requires enabling * I and Q calibration. Don't bother in B mode. */ - if (!(driver_mode == MODE_IEEE80211B)) { + if (!(mode == AR5K_MODE_11B)) { ah->ah_calibration = true; AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); @@ -981,6 +1144,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, /* * Set the 32MHz reference clock on 5212 phy clock sleep register + * + * TODO: Find out how to switch to external 32Khz clock to save power */ if (ah->ah_version == AR5K_AR5212) { ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR); @@ -988,9 +1153,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL); ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); - ath5k_hw_reg_write(ah, ah->ah_radio == AR5K_RF5111 ? - AR5K_PHY_SPENDING_RF5111 : AR5K_PHY_SPENDING_RF5112, - AR5K_PHY_SPENDING); + ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING); + } + + if (ah->ah_version == AR5K_AR5212) { + ath5k_hw_reg_write(ah, 0x000100aa, 0x8118); + ath5k_hw_reg_write(ah, 0x00003210, 0x811c); + ath5k_hw_reg_write(ah, 0x00000052, 0x8108); + if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413) + ath5k_hw_reg_write(ah, 0x00000004, 0x8120); } /* @@ -1065,7 +1236,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA; /* fallthrough */ case AR5K_PM_NETWORK_SLEEP: - if (set_chip == true) + if (set_chip) ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE | sleep_duration, AR5K_SLEEP_CTL); @@ -1074,7 +1245,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, break; case AR5K_PM_FULL_SLEEP: - if (set_chip == true) + if (set_chip) ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP, AR5K_SLEEP_CTL); @@ -1082,7 +1253,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, break; case AR5K_PM_AWAKE: - if (set_chip == false) + if (!set_chip) goto commit; ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE, @@ -1389,7 +1560,7 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase) trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG), AR5K_TXCFG_TXFULL); - if (increase == false) { + if (!increase) { if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES) goto done; } else @@ -1592,9 +1763,10 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) /* * Write to eeprom - currently disabled, use at your own risk */ +#if 0 static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) { -#if 0 + u32 status, timeout; ATH5K_TRACE(ah->ah_sc); @@ -1636,10 +1808,11 @@ static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) } udelay(15); } -#endif + ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!"); return -EIO; } +#endif /* * Translate binary channel representation in EEPROM to frequency @@ -2045,50 +2218,6 @@ static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) } /* - * Read/Write regulatory domain - */ -static bool ath5k_eeprom_regulation_domain(struct ath5k_hw *ah, bool write, - enum ath5k_regdom *regdomain) -{ - u16 ee_regdomain; - - /* Read current value */ - if (write != true) { - ee_regdomain = ah->ah_capabilities.cap_eeprom.ee_regdomain; - *regdomain = ath5k_regdom_to_ieee(ee_regdomain); - return true; - } - - ee_regdomain = ath5k_regdom_from_ieee(*regdomain); - - /* Try to write a new value */ - if (ah->ah_capabilities.cap_eeprom.ee_protect & - AR5K_EEPROM_PROTECT_WR_128_191) - return false; - if (ath5k_hw_eeprom_write(ah, AR5K_EEPROM_REG_DOMAIN, ee_regdomain)!=0) - return false; - - ah->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain; - - return true; -} - -/* - * Use the above to write a new regulatory domain - */ -int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain) -{ - enum ath5k_regdom ieee_regdomain; - - ieee_regdomain = ath5k_regdom_to_ieee(regdomain); - - if (ath5k_eeprom_regulation_domain(ah, true, &ieee_regdomain) == true) - return 0; - - return -EIO; -} - -/* * Fill the capabilities struct */ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) @@ -2110,8 +2239,8 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) ah->ah_capabilities.cap_range.range_2ghz_max = 0; /* Set supported modes */ - __set_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode); - __set_bit(MODE_ATHEROS_TURBO, ah->ah_capabilities.cap_mode); + __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); + __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); } else { /* * XXX The tranceiver supports frequencies from 4920 to 6100GHz @@ -2133,12 +2262,12 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) ah->ah_capabilities.cap_range.range_5ghz_max = 6100; /* Set supported modes */ - __set_bit(MODE_IEEE80211A, + __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); - __set_bit(MODE_ATHEROS_TURBO, + __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); if (ah->ah_version == AR5K_AR5212) - __set_bit(MODE_ATHEROS_TURBOG, + __set_bit(AR5K_MODE_11G_TURBO, ah->ah_capabilities.cap_mode); } @@ -2150,11 +2279,11 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) ah->ah_capabilities.cap_range.range_2ghz_max = 2732; if (AR5K_EEPROM_HDR_11B(ee_header)) - __set_bit(MODE_IEEE80211B, + __set_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode); if (AR5K_EEPROM_HDR_11G(ee_header)) - __set_bit(MODE_IEEE80211G, + __set_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode); } } @@ -2279,8 +2408,8 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id) * Set simple BSSID mask on 5212 */ if (ah->ah_version == AR5K_AR5212) { - ath5k_hw_reg_write(ah, 0xfffffff, AR5K_BSS_IDM0); - ath5k_hw_reg_write(ah, 0xfffffff, AR5K_BSS_IDM1); + ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0); + ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1); } /* @@ -2425,6 +2554,8 @@ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) { ATH5K_TRACE(ah->ah_sc); AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); + + /* TODO: ANI Support */ } /* @@ -2434,6 +2565,8 @@ void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah) { ATH5K_TRACE(ah->ah_sc); AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); + + /* TODO: ANI Support */ } /* @@ -2828,15 +2961,19 @@ int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr) * Update mib counters (statistics) */ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, - struct ath5k_mib_stats *statistics) + struct ieee80211_low_level_stats *stats) { ATH5K_TRACE(ah->ah_sc); + /* Read-And-Clear */ - statistics->ackrcv_bad += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); - statistics->rts_bad += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); - statistics->rts_good += ath5k_hw_reg_read(ah, AR5K_RTS_OK); - statistics->fcs_bad += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); - statistics->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); + stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); + stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); + stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK); + stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); + + /* XXX: Should we use this to track beacon count ? + * -we read it anyway to clear the register */ + ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); /* Reset profile count registers on 5212*/ if (ah->ah_version == AR5K_AR5212) { @@ -2937,8 +3074,16 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); - /* Set NULL encryption on non-5210*/ - if (ah->ah_version != AR5K_AR5210) + /* + * Set NULL encryption on AR5212+ + * + * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5) + * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007 + * + * Note2: Windows driver (ndiswrapper) sets this to + * 0x00000714 instead of 0x00000007 + */ + if (ah->ah_version > AR5K_AR5211) ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, AR5K_KEYTABLE_TYPE(entry)); @@ -3186,19 +3331,19 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) return 0; /* Set Slot time */ - ath5k_hw_reg_write(ah, ah->ah_turbo == true ? + ath5k_hw_reg_write(ah, ah->ah_turbo ? AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME, AR5K_SLOT_TIME); /* Set ACK_CTS timeout */ - ath5k_hw_reg_write(ah, ah->ah_turbo == true ? + ath5k_hw_reg_write(ah, ah->ah_turbo ? AR5K_INIT_ACK_CTS_TIMEOUT_TURBO : AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME); /* Set Transmit Latency */ - ath5k_hw_reg_write(ah, ah->ah_turbo == true ? + ath5k_hw_reg_write(ah, ah->ah_turbo ? AR5K_INIT_TRANSMIT_LATENCY_TURBO : AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210); /* Set IFS0 */ - if (ah->ah_turbo == true) + if (ah->ah_turbo) ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + (ah->ah_aifs + tq->tqi_aifs) * AR5K_INIT_SLOT_TIME_TURBO) << @@ -3211,16 +3356,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) AR5K_INIT_SIFS, AR5K_IFS0); /* Set IFS1 */ - ath5k_hw_reg_write(ah, ah->ah_turbo == true ? + ath5k_hw_reg_write(ah, ah->ah_turbo ? AR5K_INIT_PROTO_TIME_CNTRL_TURBO : AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); /* Set PHY register 0x9844 (??) */ - ath5k_hw_reg_write(ah, ah->ah_turbo == true ? + ath5k_hw_reg_write(ah, ah->ah_turbo ? (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 : (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C, AR5K_PHY(17)); /* Set Frame Control Register */ - ath5k_hw_reg_write(ah, ah->ah_turbo == true ? + ath5k_hw_reg_write(ah, ah->ah_turbo ? (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT | 0x2020) : (AR5K_PHY_FRAME_CTL_INI | 0x1020), @@ -3259,7 +3404,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /* * Calculate and set retry limits */ - if (ah->ah_software_retry == true) { + if (ah->ah_software_retry) { /* XXX Need to test this */ retry_lg = ah->ah_limit_tx_retries; retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ? @@ -3507,10 +3652,10 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, unsigned int rtscts_rate, unsigned int rtscts_duration) { u32 frame_type; - struct ath5k_hw_2w_tx_desc *tx_desc; + struct ath5k_hw_2w_tx_ctl *tx_ctl; unsigned int frame_len; - tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0; + tx_ctl = &desc->ud.ds_tx5210.tx_ctl; /* * Validate input @@ -3529,12 +3674,8 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, return -EINVAL; } - /* Clear status descriptor */ - memset(desc->ds_hw, 0, sizeof(struct ath5k_hw_tx_status)); - - /* Initialize control descriptor */ - tx_desc->tx_control_0 = 0; - tx_desc->tx_control_1 = 0; + /* Clear descriptor */ + memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc)); /* Setup control descriptor */ @@ -3546,7 +3687,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; - tx_desc->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; + tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ @@ -3557,7 +3698,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; - tx_desc->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; + tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; /* * Verify and set header length @@ -3566,7 +3707,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, if (ah->ah_version == AR5K_AR5210) { if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN) return -EINVAL; - tx_desc->tx_control_0 |= + tx_ctl->tx_control_0 |= AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); } @@ -3582,19 +3723,19 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, frame_type = type /*<< 2 ?*/; } - tx_desc->tx_control_0 |= + tx_ctl->tx_control_0 |= AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) | AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); } else { - tx_desc->tx_control_0 |= + tx_ctl->tx_control_0 |= AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) | AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); - tx_desc->tx_control_1 |= + tx_ctl->tx_control_1 |= AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE); } #define _TX_FLAGS(_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) \ - tx_desc->tx_control_##_c |= \ + tx_ctl->tx_control_##_c |= \ AR5K_2W_TX_DESC_CTL##_c##_##_flag _TX_FLAGS(0, CLRDMASK); @@ -3609,9 +3750,9 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, * WEP crap */ if (key_index != AR5K_TXKEYIX_INVALID) { - tx_desc->tx_control_0 |= + tx_ctl->tx_control_0 |= AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; - tx_desc->tx_control_1 |= + tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); } @@ -3621,7 +3762,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, */ if ((ah->ah_version == AR5K_AR5210) && (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) - tx_desc->tx_control_1 |= rtscts_duration & + tx_ctl->tx_control_1 |= rtscts_duration & AR5K_2W_TX_DESC_CTL1_RTS_DURATION; return 0; @@ -3637,13 +3778,11 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate, unsigned int rtscts_duration) { - struct ath5k_hw_4w_tx_desc *tx_desc; - struct ath5k_hw_tx_status *tx_status; + struct ath5k_hw_4w_tx_ctl *tx_ctl; unsigned int frame_len; ATH5K_TRACE(ah->ah_sc); - tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0; - tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2]; + tx_ctl = &desc->ud.ds_tx5212.tx_ctl; /* * Validate input @@ -3662,14 +3801,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, return -EINVAL; } - /* Clear status descriptor */ - memset(tx_status, 0, sizeof(struct ath5k_hw_tx_status)); - - /* Initialize control descriptor */ - tx_desc->tx_control_0 = 0; - tx_desc->tx_control_1 = 0; - tx_desc->tx_control_2 = 0; - tx_desc->tx_control_3 = 0; + /* Clear descriptor */ + memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); /* Setup control descriptor */ @@ -3681,7 +3814,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; - tx_desc->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; + tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ @@ -3692,20 +3825,20 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; - tx_desc->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; + tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; - tx_desc->tx_control_0 |= + tx_ctl->tx_control_0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); - tx_desc->tx_control_1 |= AR5K_REG_SM(type, + tx_ctl->tx_control_1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); - tx_desc->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, + tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); - tx_desc->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; + tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; #define _TX_FLAGS(_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) \ - tx_desc->tx_control_##_c |= \ + tx_ctl->tx_control_##_c |= \ AR5K_4W_TX_DESC_CTL##_c##_##_flag _TX_FLAGS(0, CLRDMASK); @@ -3721,8 +3854,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, * WEP crap */ if (key_index != AR5K_TXKEYIX_INVALID) { - tx_desc->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; - tx_desc->tx_control_1 |= AR5K_REG_SM(key_index, + tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; + tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); } @@ -3733,9 +3866,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if ((flags & AR5K_TXDESC_RTSENA) && (flags & AR5K_TXDESC_CTSENA)) return -EINVAL; - tx_desc->tx_control_2 |= rtscts_duration & + tx_ctl->tx_control_2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; - tx_desc->tx_control_3 |= AR5K_REG_SM(rtscts_rate, + tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); } @@ -3750,7 +3883,7 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) { - struct ath5k_hw_4w_tx_desc *tx_desc; + struct ath5k_hw_4w_tx_ctl *tx_ctl; /* * Rates can be 0 as long as the retry count is 0 too. @@ -3767,14 +3900,14 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, } if (ah->ah_version == AR5K_AR5212) { - tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0; + tx_ctl = &desc->ud.ds_tx5212.tx_ctl; #define _XTX_TRIES(_n) \ if (tx_tries##_n) { \ - tx_desc->tx_control_2 |= \ + tx_ctl->tx_control_2 |= \ AR5K_REG_SM(tx_tries##_n, \ AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \ - tx_desc->tx_control_3 |= \ + tx_ctl->tx_control_3 |= \ AR5K_REG_SM(tx_rate##_n, \ AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \ } @@ -3795,13 +3928,15 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, * Proccess the tx status descriptor on 5210/5211 */ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc) + struct ath5k_desc *desc, struct ath5k_tx_status *ts) { + struct ath5k_hw_2w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; - struct ath5k_hw_2w_tx_desc *tx_desc; - tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0; - tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[0]; + ATH5K_TRACE(ah->ah_sc); + + tx_ctl = &desc->ud.ds_tx5210.tx_ctl; + tx_status = &desc->ud.ds_tx5210.tx_stat; /* No frame has been send or error */ if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) @@ -3810,32 +3945,32 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, /* * Get descriptor status */ - desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); - desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); - /*TODO: desc->ds_us.tx.ts_virtcol + test*/ - desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, + /*TODO: ts->ts_virtcol + test*/ + ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_SEQ_NUM); - desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); - desc->ds_us.tx.ts_antenna = 1; - desc->ds_us.tx.ts_status = 0; - desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_0, + ts->ts_antenna = 1; + ts->ts_status = 0; + ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){ if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) - desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY; + ts->ts_status |= AR5K_TXERR_XRETRY; if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) - desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO; + ts->ts_status |= AR5K_TXERR_FIFO; if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) - desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT; + ts->ts_status |= AR5K_TXERR_FILT; } return 0; @@ -3845,14 +3980,15 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, * Proccess a tx descriptor on 5212 */ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc) + struct ath5k_desc *desc, struct ath5k_tx_status *ts) { + struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; - struct ath5k_hw_4w_tx_desc *tx_desc; ATH5K_TRACE(ah->ah_sc); - tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0; - tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2]; + + tx_ctl = &desc->ud.ds_tx5212.tx_ctl; + tx_status = &desc->ud.ds_tx5212.tx_stat; /* No frame has been send or error */ if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) @@ -3861,42 +3997,42 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, /* * Get descriptor status */ - desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); - desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); - desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_SEQ_NUM); - desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); - desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 & + ts->ts_antenna = (tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; - desc->ds_us.tx.ts_status = 0; + ts->ts_status = 0; switch (AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) { case 0: - desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 & + ts->ts_rate = tx_ctl->tx_control_3 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; break; case 1: - desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, + ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); - desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, + ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); break; case 2: - desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, + ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); - desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, + ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); break; case 3: - desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, + ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); - desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, + ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3); break; } @@ -3904,13 +4040,13 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){ if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) - desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY; + ts->ts_status |= AR5K_TXERR_XRETRY; if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) - desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO; + ts->ts_status |= AR5K_TXERR_FIFO; if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) - desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT; + ts->ts_status |= AR5K_TXERR_FILT; } return 0; @@ -3926,31 +4062,27 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, u32 size, unsigned int flags) { - struct ath5k_rx_desc *rx_desc; + struct ath5k_hw_rx_ctl *rx_ctl; ATH5K_TRACE(ah->ah_sc); - rx_desc = (struct ath5k_rx_desc *)&desc->ds_ctl0; + rx_ctl = &desc->ud.ds_rx.rx_ctl; /* - *Clear ds_hw + * Clear the descriptor * If we don't clean the status descriptor, * while scanning we get too many results, * most of them virtual, after some secs * of scanning system hangs. M.F. */ - memset(desc->ds_hw, 0, sizeof(desc->ds_hw)); - - /*Initialize rx descriptor*/ - rx_desc->rx_control_0 = 0; - rx_desc->rx_control_1 = 0; + memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); /* Setup descriptor */ - rx_desc->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; - if (unlikely(rx_desc->rx_control_1 != size)) + rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; + if (unlikely(rx_ctl->rx_control_1 != size)) return -EINVAL; if (flags & AR5K_RXDESC_INTREQ) - rx_desc->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; + rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; return 0; } @@ -3958,67 +4090,68 @@ int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, /* * Proccess the rx status descriptor on 5210/5211 */ -static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc) +static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, + struct ath5k_desc *desc, struct ath5k_rx_status *rs) { - struct ath5k_hw_old_rx_status *rx_status; + struct ath5k_hw_rx_status *rx_status; - rx_status = (struct ath5k_hw_old_rx_status *)&desc->ds_hw[0]; + rx_status = &desc->ud.ds_rx.u.rx_stat; /* No frame received / not ready */ - if (unlikely((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_DONE) + if (unlikely((rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE) == 0)) return -EINPROGRESS; /* * Frame receive status */ - desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 & - AR5K_OLD_RX_DESC_STATUS0_DATA_LEN; - desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, - AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL); - desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0, - AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE); - desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 & - AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA; - desc->ds_us.rx.rs_more = rx_status->rx_status_0 & - AR5K_OLD_RX_DESC_STATUS0_MORE; - desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, - AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); - desc->ds_us.rx.rs_status = 0; + rs->rs_datalen = rx_status->rx_status_0 & + AR5K_5210_RX_DESC_STATUS0_DATA_LEN; + rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, + AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); + rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, + AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); + rs->rs_antenna = rx_status->rx_status_0 & + AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA; + rs->rs_more = rx_status->rx_status_0 & + AR5K_5210_RX_DESC_STATUS0_MORE; + /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ + rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, + AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); + rs->rs_status = 0; /* * Key table status */ - if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID) - desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, - AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX); + if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID) + rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, + AR5K_5210_RX_DESC_STATUS1_KEY_INDEX); else - desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID; + rs->rs_keyix = AR5K_RXKEYIX_INVALID; /* * Receive/descriptor errors */ - if ((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK) - == 0) { - if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR) - desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC; + if ((rx_status->rx_status_1 & + AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) { + if (rx_status->rx_status_1 & + AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) + rs->rs_status |= AR5K_RXERR_CRC; if (rx_status->rx_status_1 & - AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN) - desc->ds_us.rx.rs_status |= AR5K_RXERR_FIFO; + AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN) + rs->rs_status |= AR5K_RXERR_FIFO; if (rx_status->rx_status_1 & - AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR) { - desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY; - desc->ds_us.rx.rs_phyerr = - AR5K_REG_MS(rx_status->rx_status_1, - AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR); + AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { + rs->rs_status |= AR5K_RXERR_PHY; + rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, + AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); } if (rx_status->rx_status_1 & - AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) - desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT; + AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) + rs->rs_status |= AR5K_RXERR_DECRYPT; } return 0; @@ -4027,71 +4160,72 @@ static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *ah, /* * Proccess the rx status descriptor on 5212 */ -static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc) +static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, + struct ath5k_desc *desc, struct ath5k_rx_status *rs) { - struct ath5k_hw_new_rx_status *rx_status; + struct ath5k_hw_rx_status *rx_status; struct ath5k_hw_rx_error *rx_err; ATH5K_TRACE(ah->ah_sc); - rx_status = (struct ath5k_hw_new_rx_status *)&desc->ds_hw[0]; + rx_status = &desc->ud.ds_rx.u.rx_stat; /* Overlay on error */ - rx_err = (struct ath5k_hw_rx_error *)&desc->ds_hw[0]; + rx_err = &desc->ud.ds_rx.u.rx_err; /* No frame received / not ready */ - if (unlikely((rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_DONE) + if (unlikely((rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE) == 0)) return -EINPROGRESS; /* * Frame receive status */ - desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 & - AR5K_NEW_RX_DESC_STATUS0_DATA_LEN; - desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, - AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL); - desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0, - AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE); - desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 & - AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA; - desc->ds_us.rx.rs_more = rx_status->rx_status_0 & - AR5K_NEW_RX_DESC_STATUS0_MORE; - desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, - AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); - desc->ds_us.rx.rs_status = 0; + rs->rs_datalen = rx_status->rx_status_0 & + AR5K_5212_RX_DESC_STATUS0_DATA_LEN; + rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, + AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); + rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, + AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); + rs->rs_antenna = rx_status->rx_status_0 & + AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA; + rs->rs_more = rx_status->rx_status_0 & + AR5K_5212_RX_DESC_STATUS0_MORE; + rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, + AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); + rs->rs_status = 0; /* * Key table status */ - if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID) - desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, - AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX); + if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) + rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, + AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); else - desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID; + rs->rs_keyix = AR5K_RXKEYIX_INVALID; /* * Receive/descriptor errors */ if ((rx_status->rx_status_1 & - AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) { - if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR) - desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC; + AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) { + if (rx_status->rx_status_1 & + AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) + rs->rs_status |= AR5K_RXERR_CRC; if (rx_status->rx_status_1 & - AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR) { - desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY; - desc->ds_us.rx.rs_phyerr = - AR5K_REG_MS(rx_err->rx_error_1, - AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); + AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { + rs->rs_status |= AR5K_RXERR_PHY; + rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1, + AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); } if (rx_status->rx_status_1 & - AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) - desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT; + AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) + rs->rs_status |= AR5K_RXERR_DECRYPT; - if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR) - desc->ds_us.rx.rs_status |= AR5K_RXERR_MIC; + if (rx_status->rx_status_1 & + AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) + rs->rs_status |= AR5K_RXERR_MIC; } return 0; @@ -4250,35 +4384,6 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, } -/*********************************\ - Regulatory Domain/Channels Setup -\*********************************/ - -u16 ath5k_get_regdomain(struct ath5k_hw *ah) -{ - u16 regdomain; - enum ath5k_regdom ieee_regdomain; -#ifdef COUNTRYCODE - u16 code; -#endif - - ath5k_eeprom_regulation_domain(ah, false, &ieee_regdomain); - ah->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain; - -#ifdef COUNTRYCODE - /* - * Get the regulation domain by country code. This will ignore - * the settings found in the EEPROM. - */ - code = ieee80211_name2countrycode(COUNTRYCODE); - ieee_regdomain = ieee80211_countrycode2regdomain(code); -#endif - - regdomain = ath5k_regdom_from_ieee(ieee_regdomain); - ah->ah_capabilities.cap_regdomain.reg_current = regdomain; - - return regdomain; -} /****************\ diff --git a/drivers/net/wireless/ath5k/hw.h b/drivers/net/wireless/ath5k/hw.h index d9a7c0973f53..64fca8dcb386 100644 --- a/drivers/net/wireless/ath5k/hw.h +++ b/drivers/net/wireless/ath5k/hw.h @@ -173,7 +173,10 @@ struct ath5k_eeprom_info { * (rX: reserved fields possibily used by future versions of the ar5k chipset) */ -struct ath5k_rx_desc { +/* + * common hardware RX control descriptor + */ +struct ath5k_hw_rx_ctl { u32 rx_control_0; /* RX control word 0 */ #define AR5K_DESC_RX_CTL0 0x00000000 @@ -185,69 +188,63 @@ struct ath5k_rx_desc { } __packed; /* - * 5210/5211 rx status descriptor + * common hardware RX status descriptor + * 5210/11 and 5212 differ only in the flags defined below */ -struct ath5k_hw_old_rx_status { +struct ath5k_hw_rx_status { u32 rx_status_0; /* RX status word 0 */ - -#define AR5K_OLD_RX_DESC_STATUS0_DATA_LEN 0x00000fff -#define AR5K_OLD_RX_DESC_STATUS0_MORE 0x00001000 -#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 -#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE_S 15 -#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000 -#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 -#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000 -#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27 - u32 rx_status_1; /* RX status word 1 */ - -#define AR5K_OLD_RX_DESC_STATUS1_DONE 0x00000001 -#define AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 -#define AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR 0x00000004 -#define AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008 -#define AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 -#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 -#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR_S 5 -#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 -#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 -#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_S 9 -#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 -#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15 -#define AR5K_OLD_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 } __packed; +/* 5210/5211 */ +#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff +#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15 +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000 +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000 +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27 +#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 +#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 +#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 +#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008 +#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 +#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 +#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5 +#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 +#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 +#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9 +#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 +#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15 +#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 + +/* 5212 */ +#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff +#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 +#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000 +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S 15 +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000 +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 +#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 +#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 +#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 +#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008 +#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010 +#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020 +#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 +#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00 +#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S 9 +#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000 +#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16 +#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 + /* - * 5212 rx status descriptor + * common hardware RX error descriptor */ -struct ath5k_hw_new_rx_status { - u32 rx_status_0; /* RX status word 0 */ - -#define AR5K_NEW_RX_DESC_STATUS0_DATA_LEN 0x00000fff -#define AR5K_NEW_RX_DESC_STATUS0_MORE 0x00001000 -#define AR5K_NEW_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 -#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000 -#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE_S 15 -#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000 -#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 -#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 -#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 - - u32 rx_status_1; /* RX status word 1 */ - -#define AR5K_NEW_RX_DESC_STATUS1_DONE 0x00000001 -#define AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 -#define AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR 0x00000004 -#define AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008 -#define AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR 0x00000010 -#define AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR 0x00000020 -#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 -#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00 -#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_S 9 -#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000 -#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16 -#define AR5K_NEW_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 -} __packed; - struct ath5k_hw_rx_error { u32 rx_error_0; /* RX error word 0 */ @@ -268,7 +265,10 @@ struct ath5k_hw_rx_error { #define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0 #define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0 -struct ath5k_hw_2w_tx_desc { +/* + * 5210/5211 hardware 2-word TX control descriptor + */ +struct ath5k_hw_2w_tx_ctl { u32 tx_control_0; /* TX control word 0 */ #define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff @@ -314,9 +314,9 @@ struct ath5k_hw_2w_tx_desc { #define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10 /* - * 5212 4-word tx control descriptor + * 5212 hardware 4-word TX control descriptor */ -struct ath5k_hw_4w_tx_desc { +struct ath5k_hw_4w_tx_ctl { u32 tx_control_0; /* TX control word 0 */ #define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff @@ -374,7 +374,7 @@ struct ath5k_hw_4w_tx_desc { } __packed; /* - * Common tx status descriptor + * Common TX status descriptor */ struct ath5k_hw_tx_status { u32 tx_status_0; /* TX status word 0 */ @@ -415,6 +415,34 @@ struct ath5k_hw_tx_status { /* + * 5210/5211 hardware TX descriptor + */ +struct ath5k_hw_5210_tx_desc { + struct ath5k_hw_2w_tx_ctl tx_ctl; + struct ath5k_hw_tx_status tx_stat; +} __packed; + +/* + * 5212 hardware TX descriptor + */ +struct ath5k_hw_5212_tx_desc { + struct ath5k_hw_4w_tx_ctl tx_ctl; + struct ath5k_hw_tx_status tx_stat; +} __packed; + +/* + * common hardware RX descriptor + */ +struct ath5k_hw_all_rx_desc { + struct ath5k_hw_rx_ctl rx_ctl; + union { + struct ath5k_hw_rx_status rx_stat; + struct ath5k_hw_rx_error rx_err; + } u; +} __packed; + + +/* * AR5K REGISTER ACCESS */ diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c index 2c22f1d4ee64..04c84e9da89d 100644 --- a/drivers/net/wireless/ath5k/initvals.c +++ b/drivers/net/wireless/ath5k/initvals.c @@ -678,8 +678,8 @@ static const struct ath5k_ini ar5212_ini[] = { { AR5K_PHY(644), 0x00806333 }, { AR5K_PHY(645), 0x00106c10 }, { AR5K_PHY(646), 0x009c4060 }, - /*{ AR5K_PHY(647), 0x1483800a },*/ /* Old value */ { AR5K_PHY(647), 0x1483800a }, + /* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413 */ { AR5K_PHY(648), 0x01831061 }, { AR5K_PHY(649), 0x00000400 }, /*{ AR5K_PHY(650), 0x000001b5 },*/ @@ -1081,6 +1081,414 @@ static const struct ath5k_ini_mode rf5413_ini_mode_end[] = { { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } }, }; +/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */ +/* XXX: No dumps for turbog yet, so turbog is the same with g here with some + * minor tweaking based on dumps from other chips */ +static const struct ath5k_ini_mode rf2413_ini_mode_end[] = { + { AR5K_TXCFG, + /* b g gTurbo */ + { 0x00000015, 0x00000015, 0x00000015 } }, + { AR5K_USEC_5211, + { 0x04e01395, 0x12e013ab, 0x098813cf } }, + { AR5K_PHY(10), + { 0x05020000, 0x0a020001, 0x0a020001 } }, + { AR5K_PHY(13), + { 0x00000e00, 0x00000e00, 0x00000e00 } }, + { AR5K_PHY(14), + { 0x0000000a, 0x0000000a, 0x0000000a } }, + { AR5K_PHY(18), + { 0x001a6a64, 0x001a6a64, 0x001a6a64 } }, + { AR5K_PHY(20), + { 0x0de8b0da, 0x0c98b0da, 0x0c98b0da } }, + { AR5K_PHY_SIG, + { 0x7ee80d2e, 0x7ec80d2e, 0x7ec80d2e } }, + { AR5K_PHY_AGCCOARSE, + { 0x3137665e, 0x3139605e, 0x3139605e } }, + { AR5K_PHY(27), + { 0x050cb081, 0x050cb081, 0x050cb081 } }, + { AR5K_PHY_RX_DELAY, + { 0x0000044c, 0x00000898, 0x000007d0 } }, + { AR5K_PHY_FRAME_CTL_5211, + { 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, + { AR5K_PHY_CCKTXCTL, + { 0x00000000, 0x00000000, 0x00000000 } }, + { AR5K_PHY(642), + { 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, + { AR5K_PHY_GAIN_2GHZ, + { 0x0042c140, 0x0042c140, 0x0042c140 } }, + { 0xa21c, + { 0x1863800a, 0x1883800a, 0x1883800a } }, + { AR5K_DCU_FP, + { 0x000003e0, 0x000003e0, 0x000003e0 } }, + { 0x8060, + { 0x0000000f, 0x0000000f, 0x0000000f } }, + { 0x8118, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x811c, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x8120, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x8124, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x8128, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x812c, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x8130, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x8134, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x8138, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x813c, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0x8140, + { 0x800000a8, 0x800000a8, 0x800000a8 } }, + { 0x8144, + { 0x00000000, 0x00000000, 0x00000000 } }, + { AR5K_PHY_AGC, + { 0x00000000, 0x00000000, 0x00000000 } }, + { AR5K_PHY(11), + { 0x0000a000, 0x0000a000, 0x0000a000 } }, + { AR5K_PHY(15), + { 0x00200400, 0x00200400, 0x00200400 } }, + { AR5K_PHY(19), + { 0x1284233c, 0x1284233c, 0x1284233c } }, + { AR5K_PHY_SCR, + { 0x0000001f, 0x0000001f, 0x0000001f } }, + { AR5K_PHY_SLMT, + { 0x00000080, 0x00000080, 0x00000080 } }, + { AR5K_PHY_SCAL, + { 0x0000000e, 0x0000000e, 0x0000000e } }, + { AR5K_PHY(86), + { 0x000000ff, 0x000000ff, 0x000000ff } }, + { AR5K_PHY(96), + { 0x00000000, 0x00000000, 0x00000000 } }, + { AR5K_PHY(97), + { 0x02800000, 0x02800000, 0x02800000 } }, + { AR5K_PHY(104), + { 0x00000000, 0x00000000, 0x00000000 } }, + { AR5K_PHY(120), + { 0x00000000, 0x00000000, 0x00000000 } }, + { AR5K_PHY(121), + { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } }, + { AR5K_PHY(122), + { 0x3c466478, 0x3c466478, 0x3c466478 } }, + { AR5K_PHY(123), + { 0x000000aa, 0x000000aa, 0x000000aa } }, + { AR5K_PHY_SCLOCK, + { 0x0000000c, 0x0000000c, 0x0000000c } }, + { AR5K_PHY_SDELAY, + { 0x000000ff, 0x000000ff, 0x000000ff } }, + { AR5K_PHY_SPENDING, + { 0x00000014, 0x00000014, 0x00000014 } }, + { 0xa228, + { 0x000009b5, 0x000009b5, 0x000009b5 } }, + { 0xa23c, + { 0x93c889af, 0x93c889af, 0x93c889af } }, + { 0xa24c, + { 0x00000001, 0x00000001, 0x00000001 } }, + { 0xa250, + { 0x0000a000, 0x0000a000, 0x0000a000 } }, + { 0xa254, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0xa258, + { 0x0cc75380, 0x0cc75380, 0x0cc75380 } }, + { 0xa25c, + { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } }, + { 0xa260, + { 0x5f690f01, 0x5f690f01, 0x5f690f01 } }, + { 0xa264, + { 0x00418a11, 0x00418a11, 0x00418a11 } }, + { 0xa268, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0xa26c, + { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } }, + { 0xa270, + { 0x00820820, 0x00820820, 0x00820820 } }, + { 0xa274, + { 0x001b7caa, 0x001b7caa, 0x001b7caa } }, + { 0xa278, + { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } }, + { 0xa27c, + { 0x051701ce, 0x051701ce, 0x051701ce } }, + { 0xa300, + { 0x18010000, 0x18010000, 0x18010000 } }, + { 0xa304, + { 0x30032602, 0x30032602, 0x30032602 } }, + { 0xa308, + { 0x48073e06, 0x48073e06, 0x48073e06 } }, + { 0xa30c, + { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } }, + { 0xa310, + { 0x641a600f, 0x641a600f, 0x641a600f } }, + { 0xa314, + { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } }, + { 0xa318, + { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } }, + { 0xa31c, + { 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } }, + { 0xa320, + { 0x9d4f970f, 0x9d4f970f, 0x9d4f970f } }, + { 0xa324, + { 0xa5cfa18f, 0xa5cfa18f, 0xa5cfa18f } }, + { 0xa328, + { 0xb55faf1f, 0xb55faf1f, 0xb55faf1f } }, + { 0xa32c, + { 0xbddfb99f, 0xbddfb99f, 0xbddfb99f } }, + { 0xa330, + { 0xcd7fc73f, 0xcd7fc73f, 0xcd7fc73f } }, + { 0xa334, + { 0xd5ffd1bf, 0xd5ffd1bf, 0xd5ffd1bf } }, + { 0xa338, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0xa33c, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0xa340, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0xa344, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 0xa348, + { 0x3fffffff, 0x3fffffff, 0x3fffffff } }, + { 0xa34c, + { 0x3fffffff, 0x3fffffff, 0x3fffffff } }, + { 0xa350, + { 0x3fffffff, 0x3fffffff, 0x3fffffff } }, + { 0xa354, + { 0x0003ffff, 0x0003ffff, 0x0003ffff } }, + { 0xa358, + { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } }, + { 0xa35c, + { 0x066c420f, 0x066c420f, 0x066c420f } }, + { 0xa360, + { 0x0f282207, 0x0f282207, 0x0f282207 } }, + { 0xa364, + { 0x17601685, 0x17601685, 0x17601685 } }, + { 0xa368, + { 0x1f801104, 0x1f801104, 0x1f801104 } }, + { 0xa36c, + { 0x37a00c03, 0x37a00c03, 0x37a00c03 } }, + { 0xa370, + { 0x3fc40883, 0x3fc40883, 0x3fc40883 } }, + { 0xa374, + { 0x57c00803, 0x57c00803, 0x57c00803 } }, + { 0xa378, + { 0x5fd80682, 0x5fd80682, 0x5fd80682 } }, + { 0xa37c, + { 0x7fe00482, 0x7fe00482, 0x7fe00482 } }, + { 0xa380, + { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } }, + { 0xa384, + { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } }, +}; + +/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */ +/* XXX: No dumps for turbog yet, so turbog is the same with g here with some + * minor tweaking based on dumps from other chips */ +static const struct ath5k_ini_mode rf2425_ini_mode_end[] = { + { AR5K_TXCFG, + /* g gTurbo */ + { 0x00000015, 0x00000015 } }, + { AR5K_USEC_5211, + { 0x12e013ab, 0x098813cf } }, + { AR5K_PHY_TURBO, + { 0x00000000, 0x00000003 } }, + { AR5K_PHY(10), + { 0x0a020001, 0x0a020001 } }, + { AR5K_PHY(13), + { 0x00000e0e, 0x00000e0e } }, + { AR5K_PHY(14), + { 0x0000000b, 0x0000000b } }, + { AR5K_PHY(17), + { 0x13721422, 0x13721422 } }, + { AR5K_PHY(18), + { 0x00199a65, 0x00199a65 } }, + { AR5K_PHY(20), + { 0x0c98b0da, 0x0c98b0da } }, + { AR5K_PHY_SIG, + { 0x7ec80d2e, 0x7ec80d2e } }, + { AR5K_PHY_AGCCOARSE, + { 0x3139605e, 0x3139605e } }, + { AR5K_PHY(27), + { 0x050cb081, 0x050cb081 } }, + { AR5K_PHY_RX_DELAY, + { 0x00000898, 0x000007d0 } }, + { AR5K_PHY_FRAME_CTL_5211, + { 0xf7b81000, 0xf7b81000 } }, + { AR5K_PHY_CCKTXCTL, + { 0x00000000, 0x00000000 } }, + { AR5K_PHY(642), + { 0xd03e6788, 0xd03e6788 } }, + { AR5K_PHY_GAIN_2GHZ, + { 0x0052c140, 0x0052c140 } }, + { 0xa21c, + { 0x1883800a, 0x1883800a } }, + { 0xa324, + { 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa328, + { 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa32c, + { 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa330, + { 0xa7cfa7cf, 0xa7cfa7cf } }, + { 0xa334, + { 0xa7cfa7cf, 0xa7cfa7cf } }, + { AR5K_DCU_FP, + { 0x000003e0, 0x000003e0 } }, + { 0x8060, + { 0x0000000f, 0x0000000f } }, + { 0x809c, + { 0x00000000, 0x00000000 } }, + { 0x80a0, + { 0x00000000, 0x00000000 } }, + { 0x8118, + { 0x00000000, 0x00000000 } }, + { 0x811c, + { 0x00000000, 0x00000000 } }, + { 0x8120, + { 0x00000000, 0x00000000 } }, + { 0x8124, + { 0x00000000, 0x00000000 } }, + { 0x8128, + { 0x00000000, 0x00000000 } }, + { 0x812c, + { 0x00000000, 0x00000000 } }, + { 0x8130, + { 0x00000000, 0x00000000 } }, + { 0x8134, + { 0x00000000, 0x00000000 } }, + { 0x8138, + { 0x00000000, 0x00000000 } }, + { 0x813c, + { 0x00000000, 0x00000000 } }, + { 0x8140, + { 0x800003f9, 0x800003f9 } }, + { 0x8144, + { 0x00000000, 0x00000000 } }, + { AR5K_PHY_AGC, + { 0x00000000, 0x00000000 } }, + { AR5K_PHY(11), + { 0x0000a000, 0x0000a000 } }, + { AR5K_PHY(15), + { 0x00200400, 0x00200400 } }, + { AR5K_PHY(19), + { 0x1284233c, 0x1284233c } }, + { AR5K_PHY_SCR, + { 0x0000001f, 0x0000001f } }, + { AR5K_PHY_SLMT, + { 0x00000080, 0x00000080 } }, + { AR5K_PHY_SCAL, + { 0x0000000e, 0x0000000e } }, + { AR5K_PHY(86), + { 0x00081fff, 0x00081fff } }, + { AR5K_PHY(96), + { 0x00000000, 0x00000000 } }, + { AR5K_PHY(97), + { 0x02800000, 0x02800000 } }, + { AR5K_PHY(104), + { 0x00000000, 0x00000000 } }, + { AR5K_PHY(119), + { 0xfebadbe8, 0xfebadbe8 } }, + { AR5K_PHY(120), + { 0x00000000, 0x00000000 } }, + { AR5K_PHY(121), + { 0xaaaaaaaa, 0xaaaaaaaa } }, + { AR5K_PHY(122), + { 0x3c466478, 0x3c466478 } }, + { AR5K_PHY(123), + { 0x000000aa, 0x000000aa } }, + { AR5K_PHY_SCLOCK, + { 0x0000000c, 0x0000000c } }, + { AR5K_PHY_SDELAY, + { 0x000000ff, 0x000000ff } }, + { AR5K_PHY_SPENDING, + { 0x00000014, 0x00000014 } }, + { 0xa228, + { 0x000009b5, 0x000009b5 } }, + { AR5K_PHY_TXPOWER_RATE3, + { 0x20202020, 0x20202020 } }, + { AR5K_PHY_TXPOWER_RATE4, + { 0x20202020, 0x20202020 } }, + { 0xa23c, + { 0x93c889af, 0x93c889af } }, + { 0xa24c, + { 0x00000001, 0x00000001 } }, + { 0xa250, + { 0x0000a000, 0x0000a000 } }, + { 0xa254, + { 0x00000000, 0x00000000 } }, + { 0xa258, + { 0x0cc75380, 0x0cc75380 } }, + { 0xa25c, + { 0x0f0f0f01, 0x0f0f0f01 } }, + { 0xa260, + { 0x5f690f01, 0x5f690f01 } }, + { 0xa264, + { 0x00418a11, 0x00418a11 } }, + { 0xa268, + { 0x00000000, 0x00000000 } }, + { 0xa26c, + { 0x0c30c166, 0x0c30c166 } }, + { 0xa270, + { 0x00820820, 0x00820820 } }, + { 0xa274, + { 0x081a3caa, 0x081a3caa } }, + { 0xa278, + { 0x1ce739ce, 0x1ce739ce } }, + { 0xa27c, + { 0x051701ce, 0x051701ce } }, + { 0xa300, + { 0x16010000, 0x16010000 } }, + { 0xa304, + { 0x2c032402, 0x2c032402 } }, + { 0xa308, + { 0x48433e42, 0x48433e42 } }, + { 0xa30c, + { 0x5a0f500b, 0x5a0f500b } }, + { 0xa310, + { 0x6c4b624a, 0x6c4b624a } }, + { 0xa314, + { 0x7e8b748a, 0x7e8b748a } }, + { 0xa318, + { 0x96cf8ccb, 0x96cf8ccb } }, + { 0xa31c, + { 0xa34f9d0f, 0xa34f9d0f } }, + { 0xa320, + { 0xa7cfa58f, 0xa7cfa58f } }, + { 0xa348, + { 0x3fffffff, 0x3fffffff } }, + { 0xa34c, + { 0x3fffffff, 0x3fffffff } }, + { 0xa350, + { 0x3fffffff, 0x3fffffff } }, + { 0xa354, + { 0x0003ffff, 0x0003ffff } }, + { 0xa358, + { 0x79a8aa1f, 0x79a8aa1f } }, + { 0xa35c, + { 0x066c420f, 0x066c420f } }, + { 0xa360, + { 0x0f282207, 0x0f282207 } }, + { 0xa364, + { 0x17601685, 0x17601685 } }, + { 0xa368, + { 0x1f801104, 0x1f801104 } }, + { 0xa36c, + { 0x37a00c03, 0x37a00c03 } }, + { 0xa370, + { 0x3fc40883, 0x3fc40883 } }, + { 0xa374, + { 0x57c00803, 0x57c00803 } }, + { 0xa378, + { 0x5fd80682, 0x5fd80682 } }, + { 0xa37c, + { 0x7fe00482, 0x7fe00482 } }, + { 0xa380, + { 0x7f3c7bba, 0x7f3c7bba } }, + { 0xa384, + { 0xf3307ff0, 0xf3307ff0 } }, +}; + /* * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI) @@ -1290,35 +1698,92 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) /* Second set of mode-specific settings */ if (ah->ah_radio == AR5K_RF5111){ + ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5212_rf5111_ini_mode_end), ar5212_rf5111_ini_mode_end, mode); + /* Baseband gain table */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain), rf5111_ini_bbgain, change_channel); + } else if (ah->ah_radio == AR5K_RF5112){ + ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5212_rf5112_ini_mode_end), ar5212_rf5112_ini_mode_end, mode); - /* Baseband gain table */ + ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), rf5112_ini_bbgain, change_channel); + } else if (ah->ah_radio == AR5K_RF5413){ + ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(rf5413_ini_mode_end), rf5413_ini_mode_end, mode); + + ath5k_hw_ini_registers(ah, + ARRAY_SIZE(rf5112_ini_bbgain), + rf5112_ini_bbgain, change_channel); + + } else if (ah->ah_radio == AR5K_RF2413) { + + if (mode < 2) { + ATH5K_ERR(ah->ah_sc, + "unsupported channel mode: %d\n", mode); + return -EINVAL; + } + mode = mode - 2; + + /* Override a setting from ar5212_ini */ + ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648)); + + ath5k_hw_ini_mode_registers(ah, + ARRAY_SIZE(rf2413_ini_mode_end), + rf2413_ini_mode_end, mode); + + /* Baseband gain table */ + ath5k_hw_ini_registers(ah, + ARRAY_SIZE(rf5112_ini_bbgain), + rf5112_ini_bbgain, change_channel); + + } else if (ah->ah_radio == AR5K_RF2425) { + + if (mode < 2) { + ATH5K_ERR(ah->ah_sc, + "unsupported channel mode: %d\n", mode); + return -EINVAL; + } + + /* Map b to g */ + if (mode == 2) + mode = 0; + else + mode = mode - 3; + + /* Override a setting from ar5212_ini */ + ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648)); + + ath5k_hw_ini_mode_registers(ah, + ARRAY_SIZE(rf2425_ini_mode_end), + rf2425_ini_mode_end, mode); + /* Baseband gain table */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), rf5112_ini_bbgain, change_channel); + } + /* For AR5211 */ } else if (ah->ah_version == AR5K_AR5211) { - if(mode > 2){ /* AR5K_INI_VAL_11B */ - ATH5K_ERR(ah->ah_sc,"unsupported channel mode: %d\n", mode); + /* AR5K_MODE_11B */ + if (mode > 2) { + ATH5K_ERR(ah->ah_sc, + "unsupported channel mode: %d\n", mode); return -EINVAL; } diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c index b95941797141..afd8689e5c03 100644 --- a/drivers/net/wireless/ath5k/phy.c +++ b/drivers/net/wireless/ath5k/phy.c @@ -666,6 +666,153 @@ static const struct ath5k_ini_rf rfregs_5413[] = { { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, }; +/* RF2413/2414 mode-specific init registers */ +static const struct ath5k_ini_rf rfregs_2413[] = { + { 1, AR5K_RF_BUFFER_CONTROL_4, + /* mode b mode g mode gTurbo */ + { 0x00000020, 0x00000020, 0x00000020 } }, + { 2, AR5K_RF_BUFFER_CONTROL_3, + { 0x02001408, 0x02001408, 0x02001408 } }, + { 3, AR5K_RF_BUFFER_CONTROL_6, + { 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, + { 6, AR5K_RF_BUFFER, + { 0xf0000000, 0xf0000000, 0xf0000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x03000000, 0x03000000, 0x03000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x40400000, 0x40400000, 0x40400000 } }, + { 6, AR5K_RF_BUFFER, + { 0x65050000, 0x65050000, 0x65050000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00420000, 0x00420000, 0x00420000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00b50000, 0x00b50000, 0x00b50000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00030000, 0x00030000, 0x00030000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00f70000, 0x00f70000, 0x00f70000 } }, + { 6, AR5K_RF_BUFFER, + { 0x009d0000, 0x009d0000, 0x009d0000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00220000, 0x00220000, 0x00220000 } }, + { 6, AR5K_RF_BUFFER, + { 0x04220000, 0x04220000, 0x04220000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00230018, 0x00230018, 0x00230018 } }, + { 6, AR5K_RF_BUFFER, + { 0x00280050, 0x00280050, 0x00280050 } }, + { 6, AR5K_RF_BUFFER, + { 0x005000c3, 0x005000c3, 0x005000c3 } }, + { 6, AR5K_RF_BUFFER, + { 0x0004007f, 0x0004007f, 0x0004007f } }, + { 6, AR5K_RF_BUFFER, + { 0x00000458, 0x00000458, 0x00000458 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x0000c000, 0x0000c000, 0x0000c000 } }, + { 6, AR5K_RF_BUFFER_CONTROL_5, + { 0x00400230, 0x00400230, 0x00400230 } }, + { 7, AR5K_RF_BUFFER, + { 0x00006400, 0x00006400, 0x00006400 } }, + { 7, AR5K_RF_BUFFER, + { 0x00000800, 0x00000800, 0x00000800 } }, + { 7, AR5K_RF_BUFFER_CONTROL_2, + { 0x0000000e, 0x0000000e, 0x0000000e } }, +}; + +/* RF2425 mode-specific init registers */ +static const struct ath5k_ini_rf rfregs_2425[] = { + { 1, AR5K_RF_BUFFER_CONTROL_4, + /* mode g mode gTurbo */ + { 0x00000020, 0x00000020 } }, + { 2, AR5K_RF_BUFFER_CONTROL_3, + { 0x02001408, 0x02001408 } }, + { 3, AR5K_RF_BUFFER_CONTROL_6, + { 0x00e020c0, 0x00e020c0 } }, + { 6, AR5K_RF_BUFFER, + { 0x10000000, 0x10000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x002a0000, 0x002a0000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00100000, 0x00100000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00020000, 0x00020000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00730000, 0x00730000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00f80000, 0x00f80000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00e70000, 0x00e70000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00140000, 0x00140000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00910040, 0x00910040 } }, + { 6, AR5K_RF_BUFFER, + { 0x0007001a, 0x0007001a } }, + { 6, AR5K_RF_BUFFER, + { 0x00410000, 0x00410000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00810060, 0x00810060 } }, + { 6, AR5K_RF_BUFFER, + { 0x00020803, 0x00020803 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00000000, 0x00000000 } }, + { 6, AR5K_RF_BUFFER, + { 0x00001660, 0x00001660 } }, + { 6, AR5K_RF_BUFFER, + { 0x00001688, 0x00001688 } }, + { 6, AR5K_RF_BUFFER_CONTROL_1, + { 0x00000001, 0x00000001 } }, + { 7, AR5K_RF_BUFFER, + { 0x00006400, 0x00006400 } }, + { 7, AR5K_RF_BUFFER, + { 0x00000800, 0x00000800 } }, + { 7, AR5K_RF_BUFFER_CONTROL_2, + { 0x0000000e, 0x0000000e } }, +}; /* Initial RF Gain settings for RF5112 */ static const struct ath5k_ini_rfgain rfgain_5112[] = { @@ -805,6 +952,74 @@ static const struct ath5k_ini_rfgain rfgain_5413[] = { { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } }, }; +/* Initial RF Gain settings for RF2413 */ +static const struct ath5k_ini_rfgain rfgain_2413[] = { + { AR5K_RF_GAIN(0), { 0x00000000 } }, + { AR5K_RF_GAIN(1), { 0x00000040 } }, + { AR5K_RF_GAIN(2), { 0x00000080 } }, + { AR5K_RF_GAIN(3), { 0x00000181 } }, + { AR5K_RF_GAIN(4), { 0x000001c1 } }, + { AR5K_RF_GAIN(5), { 0x00000001 } }, + { AR5K_RF_GAIN(6), { 0x00000041 } }, + { AR5K_RF_GAIN(7), { 0x00000081 } }, + { AR5K_RF_GAIN(8), { 0x00000168 } }, + { AR5K_RF_GAIN(9), { 0x000001a8 } }, + { AR5K_RF_GAIN(10), { 0x000001e8 } }, + { AR5K_RF_GAIN(11), { 0x00000028 } }, + { AR5K_RF_GAIN(12), { 0x00000068 } }, + { AR5K_RF_GAIN(13), { 0x00000189 } }, + { AR5K_RF_GAIN(14), { 0x000001c9 } }, + { AR5K_RF_GAIN(15), { 0x00000009 } }, + { AR5K_RF_GAIN(16), { 0x00000049 } }, + { AR5K_RF_GAIN(17), { 0x00000089 } }, + { AR5K_RF_GAIN(18), { 0x00000190 } }, + { AR5K_RF_GAIN(19), { 0x000001d0 } }, + { AR5K_RF_GAIN(20), { 0x00000010 } }, + { AR5K_RF_GAIN(21), { 0x00000050 } }, + { AR5K_RF_GAIN(22), { 0x00000090 } }, + { AR5K_RF_GAIN(23), { 0x00000191 } }, + { AR5K_RF_GAIN(24), { 0x000001d1 } }, + { AR5K_RF_GAIN(25), { 0x00000011 } }, + { AR5K_RF_GAIN(26), { 0x00000051 } }, + { AR5K_RF_GAIN(27), { 0x00000091 } }, + { AR5K_RF_GAIN(28), { 0x00000178 } }, + { AR5K_RF_GAIN(29), { 0x000001b8 } }, + { AR5K_RF_GAIN(30), { 0x000001f8 } }, + { AR5K_RF_GAIN(31), { 0x00000038 } }, + { AR5K_RF_GAIN(32), { 0x00000078 } }, + { AR5K_RF_GAIN(33), { 0x00000199 } }, + { AR5K_RF_GAIN(34), { 0x000001d9 } }, + { AR5K_RF_GAIN(35), { 0x00000019 } }, + { AR5K_RF_GAIN(36), { 0x00000059 } }, + { AR5K_RF_GAIN(37), { 0x00000099 } }, + { AR5K_RF_GAIN(38), { 0x000000d9 } }, + { AR5K_RF_GAIN(39), { 0x000000f9 } }, + { AR5K_RF_GAIN(40), { 0x000000f9 } }, + { AR5K_RF_GAIN(41), { 0x000000f9 } }, + { AR5K_RF_GAIN(42), { 0x000000f9 } }, + { AR5K_RF_GAIN(43), { 0x000000f9 } }, + { AR5K_RF_GAIN(44), { 0x000000f9 } }, + { AR5K_RF_GAIN(45), { 0x000000f9 } }, + { AR5K_RF_GAIN(46), { 0x000000f9 } }, + { AR5K_RF_GAIN(47), { 0x000000f9 } }, + { AR5K_RF_GAIN(48), { 0x000000f9 } }, + { AR5K_RF_GAIN(49), { 0x000000f9 } }, + { AR5K_RF_GAIN(50), { 0x000000f9 } }, + { AR5K_RF_GAIN(51), { 0x000000f9 } }, + { AR5K_RF_GAIN(52), { 0x000000f9 } }, + { AR5K_RF_GAIN(53), { 0x000000f9 } }, + { AR5K_RF_GAIN(54), { 0x000000f9 } }, + { AR5K_RF_GAIN(55), { 0x000000f9 } }, + { AR5K_RF_GAIN(56), { 0x000000f9 } }, + { AR5K_RF_GAIN(57), { 0x000000f9 } }, + { AR5K_RF_GAIN(58), { 0x000000f9 } }, + { AR5K_RF_GAIN(59), { 0x000000f9 } }, + { AR5K_RF_GAIN(60), { 0x000000f9 } }, + { AR5K_RF_GAIN(61), { 0x000000f9 } }, + { AR5K_RF_GAIN(62), { 0x000000f9 } }, + { AR5K_RF_GAIN(63), { 0x000000f9 } }, +}; + static const struct ath5k_gain_opt rfgain_opt_5112 = { 1, 8, @@ -844,14 +1059,14 @@ static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits, entry = ((first - 1) / 8) + offset; position = (first - 1) % 8; - if (set == true) + if (set) data = ath5k_hw_bitswap(reg, bits); for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) { last = (position + left > 8) ? 8 : position + left; mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8); - if (set == true) { + if (set) { rf[entry] &= ~mask; rf[entry] |= ((data << position) << (col * 8)) & mask; data >>= (8 - position); @@ -864,7 +1079,7 @@ static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits, left -= 8 - position; } - data = set == true ? 1 : ath5k_hw_bitswap(data, bits); + data = set ? 1 : ath5k_hw_bitswap(data, bits); return data; } @@ -955,7 +1170,6 @@ static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah) go = &rfgain_opt_5111; break; case AR5K_RF5112: - case AR5K_RF5413: /* ??? */ go = &rfgain_opt_5112; break; default: @@ -1018,7 +1232,7 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, int obdb = -1, bank = -1; u32 ee_mode; - AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); + AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); rf = ah->ah_rf_banks; @@ -1038,8 +1252,8 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, } /* Modify bank 0 */ - if (channel->val & CHANNEL_2GHZ) { - if (channel->val & CHANNEL_CCK) + if (channel->hw_value & CHANNEL_2GHZ) { + if (channel->hw_value & CHANNEL_CCK) ee_mode = AR5K_EEPROM_MODE_11B; else ee_mode = AR5K_EEPROM_MODE_11G; @@ -1058,10 +1272,10 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, } else { /* For 11a, Turbo and XR */ ee_mode = AR5K_EEPROM_MODE_11A; - obdb = channel->freq >= 5725 ? 3 : - (channel->freq >= 5500 ? 2 : - (channel->freq >= 5260 ? 1 : - (channel->freq > 4000 ? 0 : -1))); + obdb = channel->center_freq >= 5725 ? 3 : + (channel->center_freq >= 5500 ? 2 : + (channel->center_freq >= 5260 ? 1 : + (channel->center_freq > 4000 ? 0 : -1))); if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], ee->ee_pwd_84, 1, 51, 3, true)) @@ -1119,12 +1333,12 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, int obdb = -1, bank = -1; u32 ee_mode; - AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); + AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); rf = ah->ah_rf_banks; if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A - && !test_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode)){ + && !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) { rf_ini = rfregs_2112a; rf_size = ARRAY_SIZE(rfregs_5112a); if (mode < 2) { @@ -1156,8 +1370,8 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, } /* Modify bank 6 */ - if (channel->val & CHANNEL_2GHZ) { - if (channel->val & CHANNEL_OFDM) + if (channel->hw_value & CHANNEL_2GHZ) { + if (channel->hw_value & CHANNEL_OFDM) ee_mode = AR5K_EEPROM_MODE_11G; else ee_mode = AR5K_EEPROM_MODE_11B; @@ -1173,10 +1387,13 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, } else { /* For 11a, Turbo and XR */ ee_mode = AR5K_EEPROM_MODE_11A; - obdb = channel->freq >= 5725 ? 3 : - (channel->freq >= 5500 ? 2 : - (channel->freq >= 5260 ? 1 : - (channel->freq > 4000 ? 0 : -1))); + obdb = channel->center_freq >= 5725 ? 3 : + (channel->center_freq >= 5500 ? 2 : + (channel->center_freq >= 5260 ? 1 : + (channel->center_freq > 4000 ? 0 : -1))); + + if (obdb == -1) + return -EINVAL; if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) @@ -1209,7 +1426,8 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, } /* - * Initialize RF5413/5414 + * Initialize RF5413/5414 and future chips + * (until we come up with a better solution) */ static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode) @@ -1219,12 +1437,47 @@ static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah, unsigned int rf_size, i; int bank = -1; - AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); + AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); rf = ah->ah_rf_banks; - rf_ini = rfregs_5413; - rf_size = ARRAY_SIZE(rfregs_5413); + switch (ah->ah_radio) { + case AR5K_RF5413: + rf_ini = rfregs_5413; + rf_size = ARRAY_SIZE(rfregs_5413); + break; + case AR5K_RF2413: + rf_ini = rfregs_2413; + rf_size = ARRAY_SIZE(rfregs_2413); + + if (mode < 2) { + ATH5K_ERR(ah->ah_sc, + "invalid channel mode: %i\n", mode); + return -EINVAL; + } + + mode = mode - 2; + break; + case AR5K_RF2425: + rf_ini = rfregs_2425; + rf_size = ARRAY_SIZE(rfregs_2425); + + if (mode < 2) { + ATH5K_ERR(ah->ah_sc, + "invalid channel mode: %i\n", mode); + return -EINVAL; + } + + /* Map b to g */ + if (mode == 2) + mode = 0; + else + mode = mode - 3; + + break; + default: + return -EINVAL; + } /* Copy values to modify them */ for (i = 0; i < rf_size; i++) { @@ -1283,6 +1536,14 @@ int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, ah->ah_rf_banks_size = sizeof(rfregs_5413); func = ath5k_hw_rf5413_rfregs; break; + case AR5K_RF2413: + ah->ah_rf_banks_size = sizeof(rfregs_2413); + func = ath5k_hw_rf5413_rfregs; + break; + case AR5K_RF2425: + ah->ah_rf_banks_size = sizeof(rfregs_2425); + func = ath5k_hw_rf5413_rfregs; + break; default: return -EINVAL; } @@ -1321,6 +1582,16 @@ int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq) ath5k_rfg = rfgain_5413; size = ARRAY_SIZE(rfgain_5413); break; + case AR5K_RF2413: + ath5k_rfg = rfgain_2413; + size = ARRAY_SIZE(rfgain_2413); + freq = 0; /* only 2Ghz */ + break; + case AR5K_RF2425: + ath5k_rfg = rfgain_2413; + size = ARRAY_SIZE(rfgain_2413); + freq = 0; /* only 2Ghz */ + break; default: return -EINVAL; } @@ -1395,7 +1666,6 @@ int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah) ah->ah_gain.g_active = 1; break; case AR5K_RF5112: - case AR5K_RF5413: /* ??? */ ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default; ah->ah_gain.g_step = &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx]; @@ -1445,9 +1715,10 @@ static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) * newer chipsets like the AR5212A who have a completely * different RF/PHY part. */ - athchan = (ath5k_hw_bitswap((channel->chan - 24) / 2, 5) << 1) | - (1 << 6) | 0x1; - + athchan = (ath5k_hw_bitswap( + (ieee80211_frequency_to_channel( + channel->center_freq) - 24) / 2, 5) + << 1) | (1 << 6) | 0x1; return athchan; } @@ -1506,7 +1777,8 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) { struct ath5k_athchan_2ghz ath5k_channel_2ghz; - unsigned int ath5k_channel = channel->chan; + unsigned int ath5k_channel = + ieee80211_frequency_to_channel(channel->center_freq); u32 data0, data1, clock; int ret; @@ -1515,10 +1787,11 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah, */ data0 = data1 = 0; - if (channel->val & CHANNEL_2GHZ) { + if (channel->hw_value & CHANNEL_2GHZ) { /* Map 2GHz channel to 5GHz Atheros channel ID */ - ret = ath5k_hw_rf5111_chan2athchan(channel->chan, - &ath5k_channel_2ghz); + ret = ath5k_hw_rf5111_chan2athchan( + ieee80211_frequency_to_channel(channel->center_freq), + &ath5k_channel_2ghz); if (ret) return ret; @@ -1555,7 +1828,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, u16 c; data = data0 = data1 = data2 = 0; - c = channel->freq; + c = channel->center_freq; /* * Set the channel on the RF5112 or newer @@ -1599,19 +1872,17 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) { int ret; - /* - * Check bounds supported by the PHY - * (don't care about regulation restrictions at this point) - */ - if ((channel->freq < ah->ah_capabilities.cap_range.range_2ghz_min || - channel->freq > ah->ah_capabilities.cap_range.range_2ghz_max) && - (channel->freq < ah->ah_capabilities.cap_range.range_5ghz_min || - channel->freq > ah->ah_capabilities.cap_range.range_5ghz_max)) { + * Check bounds supported by the PHY (we don't care about regultory + * restrictions at this point). Note: hw_value already has the band + * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok() + * of the band by that */ + if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) { ATH5K_ERR(ah->ah_sc, - "channel out of supported range (%u MHz)\n", - channel->freq); - return -EINVAL; + "channel frequency (%u MHz) out of supported " + "band range\n", + channel->center_freq); + return -EINVAL; } /* @@ -1632,9 +1903,9 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) if (ret) return ret; - ah->ah_current_channel.freq = channel->freq; - ah->ah_current_channel.val = channel->val; - ah->ah_turbo = channel->val == CHANNEL_T ? true : false; + ah->ah_current_channel.center_freq = channel->center_freq; + ah->ah_current_channel.hw_value = channel->hw_value; + ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; return 0; } @@ -1797,11 +2068,11 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, if (ret) { ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", - channel->freq); + channel->center_freq); return ret; } - ret = ath5k_hw_noise_floor_calibration(ah, channel->freq); + ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); if (ret) return ret; @@ -1825,7 +2096,7 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd; ATH5K_TRACE(ah->ah_sc); - if (ah->ah_calibration == false || + if (!ah->ah_calibration || ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) goto done; @@ -1848,10 +2119,10 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); done: - ath5k_hw_noise_floor_calibration(ah, channel->freq); + ath5k_hw_noise_floor_calibration(ah, channel->center_freq); /* Request RF gain */ - if (channel->val & CHANNEL_5GHZ) { + if (channel->hw_value & CHANNEL_5GHZ) { ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max, AR5K_PHY_PAPD_PROBE_TXPOWER) | AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); @@ -2015,6 +2286,18 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EINVAL; } + /* + * RF2413 for some reason can't + * transmit anything if we call + * this funtion, so we skip it + * until we fix txpower. + * + * XXX: Assume same for RF2425 + * to be safe. + */ + if ((ah->ah_radio == AR5K_RF2413) || (ah->ah_radio == AR5K_RF2425)) + return 0; + /* Reset TX power values */ memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); ah->ah_txpower.txp_tpc = tpc; @@ -2048,7 +2331,7 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) | AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4); - if (ah->ah_txpower.txp_tpc == true) + if (ah->ah_txpower.txp_tpc) ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE | AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); else diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h index 2f41c8398602..30629b3e37c2 100644 --- a/drivers/net/wireless/ath5k/reg.h +++ b/drivers/net/wireless/ath5k/reg.h @@ -1923,7 +1923,9 @@ after DFS is enabled */ #define AR5K_PHY_SDELAY_32MHZ 0x000000ff #define AR5K_PHY_SPENDING 0x99f8 #define AR5K_PHY_SPENDING_RF5111 0x00000018 -#define AR5K_PHY_SPENDING_RF5112 0x00000014 +#define AR5K_PHY_SPENDING_RF5112 0x00000014 /* <- i 've only seen this on 2425 dumps ! */ +#define AR5K_PHY_SPENDING_RF5112A 0x0000000e /* but since i only have 5112A-based chips */ +#define AR5K_PHY_SPENDING_RF5424 0x00000012 /* to test it might be also for old 5112. */ /* * Misc PHY/radio registers [5110 - 5111] diff --git a/drivers/net/wireless/ath5k/regdom.c b/drivers/net/wireless/ath5k/regdom.c deleted file mode 100644 index e851957dacfd..000000000000 --- a/drivers/net/wireless/ath5k/regdom.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Basic regulation domain extensions for the IEEE 802.11 stack - */ - -#include <linux/kernel.h> -#include <linux/string.h> - -#include "regdom.h" - -static const struct ath5k_regdommap { - enum ath5k_regdom dmn; - enum ath5k_regdom dmn5; - enum ath5k_regdom dmn2; -} r_map[] = { - { DMN_DEFAULT, DMN_DEBUG, DMN_DEBUG }, - { DMN_NULL_WORLD, DMN_NULL, DMN_WORLD }, - { DMN_NULL_ETSIB, DMN_NULL, DMN_ETSIB }, - { DMN_NULL_ETSIC, DMN_NULL, DMN_ETSIC }, - { DMN_FCC1_FCCA, DMN_FCC1, DMN_FCCA }, - { DMN_FCC1_WORLD, DMN_FCC1, DMN_WORLD }, - { DMN_FCC2_FCCA, DMN_FCC2, DMN_FCCA }, - { DMN_FCC2_WORLD, DMN_FCC2, DMN_WORLD }, - { DMN_FCC2_ETSIC, DMN_FCC2, DMN_ETSIC }, - { DMN_FRANCE_NULL, DMN_ETSI3, DMN_ETSI3 }, - { DMN_FCC3_FCCA, DMN_FCC3, DMN_WORLD }, - { DMN_ETSI1_WORLD, DMN_ETSI1, DMN_WORLD }, - { DMN_ETSI3_ETSIA, DMN_ETSI3, DMN_WORLD }, - { DMN_ETSI2_WORLD, DMN_ETSI2, DMN_WORLD }, - { DMN_ETSI3_WORLD, DMN_ETSI3, DMN_WORLD }, - { DMN_ETSI4_WORLD, DMN_ETSI4, DMN_WORLD }, - { DMN_ETSI4_ETSIC, DMN_ETSI4, DMN_ETSIC }, - { DMN_ETSI5_WORLD, DMN_ETSI5, DMN_WORLD }, - { DMN_ETSI6_WORLD, DMN_ETSI6, DMN_WORLD }, - { DMN_ETSI_NULL, DMN_ETSI1, DMN_ETSI1 }, - { DMN_MKK1_MKKA, DMN_MKK1, DMN_MKKA }, - { DMN_MKK1_MKKB, DMN_MKK1, DMN_MKKA }, - { DMN_APL4_WORLD, DMN_APL4, DMN_WORLD }, - { DMN_MKK2_MKKA, DMN_MKK2, DMN_MKKA }, - { DMN_APL_NULL, DMN_APL1, DMN_NULL }, - { DMN_APL2_WORLD, DMN_APL2, DMN_WORLD }, - { DMN_APL2_APLC, DMN_APL2, DMN_WORLD }, - { DMN_APL3_WORLD, DMN_APL3, DMN_WORLD }, - { DMN_MKK1_FCCA, DMN_MKK1, DMN_FCCA }, - { DMN_APL2_APLD, DMN_APL2, DMN_APLD }, - { DMN_MKK1_MKKA1, DMN_MKK1, DMN_MKKA }, - { DMN_MKK1_MKKA2, DMN_MKK1, DMN_MKKA }, - { DMN_APL1_WORLD, DMN_APL1, DMN_WORLD }, - { DMN_APL1_FCCA, DMN_APL1, DMN_FCCA }, - { DMN_APL1_APLA, DMN_APL1, DMN_WORLD }, - { DMN_APL1_ETSIC, DMN_APL1, DMN_ETSIC }, - { DMN_APL2_ETSIC, DMN_APL2, DMN_ETSIC }, - { DMN_APL5_WORLD, DMN_APL5, DMN_WORLD }, - { DMN_WOR0_WORLD, DMN_WORLD, DMN_WORLD }, - { DMN_WOR1_WORLD, DMN_WORLD, DMN_WORLD }, - { DMN_WOR2_WORLD, DMN_WORLD, DMN_WORLD }, - { DMN_WOR3_WORLD, DMN_WORLD, DMN_WORLD }, - { DMN_WOR4_WORLD, DMN_WORLD, DMN_WORLD }, - { DMN_WOR5_ETSIC, DMN_WORLD, DMN_WORLD }, - { DMN_WOR01_WORLD, DMN_WORLD, DMN_WORLD }, - { DMN_WOR02_WORLD, DMN_WORLD, DMN_WORLD }, - { DMN_EU1_WORLD, DMN_ETSI1, DMN_WORLD }, - { DMN_WOR9_WORLD, DMN_WORLD, DMN_WORLD }, - { DMN_WORA_WORLD, DMN_WORLD, DMN_WORLD }, -}; - -enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom dmn, u16 mhz) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(r_map); i++) { - if (r_map[i].dmn == dmn) { - if (mhz >= 2000 && mhz <= 3000) - return r_map[i].dmn2; - if (mhz >= IEEE80211_CHANNELS_5GHZ_MIN && - mhz <= IEEE80211_CHANNELS_5GHZ_MAX) - return r_map[i].dmn5; - } - } - - return DMN_DEBUG; -} - -u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee) -{ - u32 regdomain = (u32)ieee; - - /* - * Use the default regulation domain if the value is empty - * or not supported by the net80211 regulation code. - */ - if (ath5k_regdom2flag(regdomain, IEEE80211_CHANNELS_5GHZ_MIN) == - DMN_DEBUG) - return (u16)AR5K_TUNE_REGDOMAIN; - - /* It is supported, just return the value */ - return regdomain; -} - -enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain) -{ - enum ath5k_regdom ieee = (enum ath5k_regdom)regdomain; - - return ieee; -} - diff --git a/drivers/net/wireless/ath5k/regdom.h b/drivers/net/wireless/ath5k/regdom.h deleted file mode 100644 index f7d3c66e594e..000000000000 --- a/drivers/net/wireless/ath5k/regdom.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _IEEE80211_REGDOMAIN_H_ -#define _IEEE80211_REGDOMAIN_H_ - -#include <linux/types.h> - -/* Default regulation domain if stored value EEPROM value is invalid */ -#define AR5K_TUNE_REGDOMAIN DMN_FCC2_FCCA /* Canada */ -#define AR5K_TUNE_CTRY CTRY_DEFAULT - - -enum ath5k_regdom { - DMN_DEFAULT = 0x00, - DMN_NULL_WORLD = 0x03, - DMN_NULL_ETSIB = 0x07, - DMN_NULL_ETSIC = 0x08, - DMN_FCC1_FCCA = 0x10, - DMN_FCC1_WORLD = 0x11, - DMN_FCC2_FCCA = 0x20, - DMN_FCC2_WORLD = 0x21, - DMN_FCC2_ETSIC = 0x22, - DMN_FRANCE_NULL = 0x31, - DMN_FCC3_FCCA = 0x3A, - DMN_ETSI1_WORLD = 0x37, - DMN_ETSI3_ETSIA = 0x32, - DMN_ETSI2_WORLD = 0x35, - DMN_ETSI3_WORLD = 0x36, - DMN_ETSI4_WORLD = 0x30, - DMN_ETSI4_ETSIC = 0x38, - DMN_ETSI5_WORLD = 0x39, - DMN_ETSI6_WORLD = 0x34, - DMN_ETSI_NULL = 0x33, - DMN_MKK1_MKKA = 0x40, - DMN_MKK1_MKKB = 0x41, - DMN_APL4_WORLD = 0x42, - DMN_MKK2_MKKA = 0x43, - DMN_APL_NULL = 0x44, - DMN_APL2_WORLD = 0x45, - DMN_APL2_APLC = 0x46, - DMN_APL3_WORLD = 0x47, - DMN_MKK1_FCCA = 0x48, - DMN_APL2_APLD = 0x49, - DMN_MKK1_MKKA1 = 0x4A, - DMN_MKK1_MKKA2 = 0x4B, - DMN_APL1_WORLD = 0x52, - DMN_APL1_FCCA = 0x53, - DMN_APL1_APLA = 0x54, - DMN_APL1_ETSIC = 0x55, - DMN_APL2_ETSIC = 0x56, - DMN_APL5_WORLD = 0x58, - DMN_WOR0_WORLD = 0x60, - DMN_WOR1_WORLD = 0x61, - DMN_WOR2_WORLD = 0x62, - DMN_WOR3_WORLD = 0x63, - DMN_WOR4_WORLD = 0x64, - DMN_WOR5_ETSIC = 0x65, - DMN_WOR01_WORLD = 0x66, - DMN_WOR02_WORLD = 0x67, - DMN_EU1_WORLD = 0x68, - DMN_WOR9_WORLD = 0x69, - DMN_WORA_WORLD = 0x6A, - - DMN_APL1 = 0xf0000001, - DMN_APL2 = 0xf0000002, - DMN_APL3 = 0xf0000004, - DMN_APL4 = 0xf0000008, - DMN_APL5 = 0xf0000010, - DMN_ETSI1 = 0xf0000020, - DMN_ETSI2 = 0xf0000040, - DMN_ETSI3 = 0xf0000080, - DMN_ETSI4 = 0xf0000100, - DMN_ETSI5 = 0xf0000200, - DMN_ETSI6 = 0xf0000400, - DMN_ETSIA = 0xf0000800, - DMN_ETSIB = 0xf0001000, - DMN_ETSIC = 0xf0002000, - DMN_FCC1 = 0xf0004000, - DMN_FCC2 = 0xf0008000, - DMN_FCC3 = 0xf0010000, - DMN_FCCA = 0xf0020000, - DMN_APLD = 0xf0040000, - DMN_MKK1 = 0xf0080000, - DMN_MKK2 = 0xf0100000, - DMN_MKKA = 0xf0200000, - DMN_NULL = 0xf0400000, - DMN_WORLD = 0xf0800000, - DMN_DEBUG = 0xf1000000 /* used for debugging */ -}; - -#define IEEE80211_DMN(_d) ((_d) & ~0xf0000000) - -enum ath5k_countrycode { - CTRY_DEFAULT = 0, /* Default domain (NA) */ - CTRY_ALBANIA = 8, /* Albania */ - CTRY_ALGERIA = 12, /* Algeria */ - CTRY_ARGENTINA = 32, /* Argentina */ - CTRY_ARMENIA = 51, /* Armenia */ - CTRY_AUSTRALIA = 36, /* Australia */ - CTRY_AUSTRIA = 40, /* Austria */ - CTRY_AZERBAIJAN = 31, /* Azerbaijan */ - CTRY_BAHRAIN = 48, /* Bahrain */ - CTRY_BELARUS = 112, /* Belarus */ - CTRY_BELGIUM = 56, /* Belgium */ - CTRY_BELIZE = 84, /* Belize */ - CTRY_BOLIVIA = 68, /* Bolivia */ - CTRY_BRAZIL = 76, /* Brazil */ - CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */ - CTRY_BULGARIA = 100, /* Bulgaria */ - CTRY_CANADA = 124, /* Canada */ - CTRY_CHILE = 152, /* Chile */ - CTRY_CHINA = 156, /* People's Republic of China */ - CTRY_COLOMBIA = 170, /* Colombia */ - CTRY_COSTA_RICA = 188, /* Costa Rica */ - CTRY_CROATIA = 191, /* Croatia */ - CTRY_CYPRUS = 196, /* Cyprus */ - CTRY_CZECH = 203, /* Czech Republic */ - CTRY_DENMARK = 208, /* Denmark */ - CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */ - CTRY_ECUADOR = 218, /* Ecuador */ - CTRY_EGYPT = 818, /* Egypt */ - CTRY_EL_SALVADOR = 222, /* El Salvador */ - CTRY_ESTONIA = 233, /* Estonia */ - CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */ - CTRY_FINLAND = 246, /* Finland */ - CTRY_FRANCE = 250, /* France */ - CTRY_FRANCE2 = 255, /* France2 */ - CTRY_GEORGIA = 268, /* Georgia */ - CTRY_GERMANY = 276, /* Germany */ - CTRY_GREECE = 300, /* Greece */ - CTRY_GUATEMALA = 320, /* Guatemala */ - CTRY_HONDURAS = 340, /* Honduras */ - CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */ - CTRY_HUNGARY = 348, /* Hungary */ - CTRY_ICELAND = 352, /* Iceland */ - CTRY_INDIA = 356, /* India */ - CTRY_INDONESIA = 360, /* Indonesia */ - CTRY_IRAN = 364, /* Iran */ - CTRY_IRAQ = 368, /* Iraq */ - CTRY_IRELAND = 372, /* Ireland */ - CTRY_ISRAEL = 376, /* Israel */ - CTRY_ITALY = 380, /* Italy */ - CTRY_JAMAICA = 388, /* Jamaica */ - CTRY_JAPAN = 392, /* Japan */ - CTRY_JAPAN1 = 393, /* Japan (JP1) */ - CTRY_JAPAN2 = 394, /* Japan (JP0) */ - CTRY_JAPAN3 = 395, /* Japan (JP1-1) */ - CTRY_JAPAN4 = 396, /* Japan (JE1) */ - CTRY_JAPAN5 = 397, /* Japan (JE2) */ - CTRY_JORDAN = 400, /* Jordan */ - CTRY_KAZAKHSTAN = 398, /* Kazakhstan */ - CTRY_KENYA = 404, /* Kenya */ - CTRY_KOREA_NORTH = 408, /* North Korea */ - CTRY_KOREA_ROC = 410, /* South Korea */ - CTRY_KOREA_ROC2 = 411, /* South Korea */ - CTRY_KUWAIT = 414, /* Kuwait */ - CTRY_LATVIA = 428, /* Latvia */ - CTRY_LEBANON = 422, /* Lebanon */ - CTRY_LIBYA = 434, /* Libya */ - CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */ - CTRY_LITHUANIA = 440, /* Lithuania */ - CTRY_LUXEMBOURG = 442, /* Luxembourg */ - CTRY_MACAU = 446, /* Macau */ - CTRY_MACEDONIA = 807, /* Republic of Macedonia */ - CTRY_MALAYSIA = 458, /* Malaysia */ - CTRY_MEXICO = 484, /* Mexico */ - CTRY_MONACO = 492, /* Principality of Monaco */ - CTRY_MOROCCO = 504, /* Morocco */ - CTRY_NETHERLANDS = 528, /* Netherlands */ - CTRY_NEW_ZEALAND = 554, /* New Zealand */ - CTRY_NICARAGUA = 558, /* Nicaragua */ - CTRY_NORWAY = 578, /* Norway */ - CTRY_OMAN = 512, /* Oman */ - CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */ - CTRY_PANAMA = 591, /* Panama */ - CTRY_PARAGUAY = 600, /* Paraguay */ - CTRY_PERU = 604, /* Peru */ - CTRY_PHILIPPINES = 608, /* Republic of the Philippines */ - CTRY_POLAND = 616, /* Poland */ - CTRY_PORTUGAL = 620, /* Portugal */ - CTRY_PUERTO_RICO = 630, /* Puerto Rico */ - CTRY_QATAR = 634, /* Qatar */ - CTRY_ROMANIA = 642, /* Romania */ - CTRY_RUSSIA = 643, /* Russia */ - CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */ - CTRY_SINGAPORE = 702, /* Singapore */ - CTRY_SLOVAKIA = 703, /* Slovak Republic */ - CTRY_SLOVENIA = 705, /* Slovenia */ - CTRY_SOUTH_AFRICA = 710, /* South Africa */ - CTRY_SPAIN = 724, /* Spain */ - CTRY_SRI_LANKA = 728, /* Sri Lanka */ - CTRY_SWEDEN = 752, /* Sweden */ - CTRY_SWITZERLAND = 756, /* Switzerland */ - CTRY_SYRIA = 760, /* Syria */ - CTRY_TAIWAN = 158, /* Taiwan */ - CTRY_THAILAND = 764, /* Thailand */ - CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */ - CTRY_TUNISIA = 788, /* Tunisia */ - CTRY_TURKEY = 792, /* Turkey */ - CTRY_UAE = 784, /* U.A.E. */ - CTRY_UKRAINE = 804, /* Ukraine */ - CTRY_UNITED_KINGDOM = 826, /* United Kingdom */ - CTRY_UNITED_STATES = 840, /* United States */ - CTRY_URUGUAY = 858, /* Uruguay */ - CTRY_UZBEKISTAN = 860, /* Uzbekistan */ - CTRY_VENEZUELA = 862, /* Venezuela */ - CTRY_VIET_NAM = 704, /* Viet Nam */ - CTRY_YEMEN = 887, /* Yemen */ - CTRY_ZIMBABWE = 716, /* Zimbabwe */ -}; - -#define IEEE80211_CHANNELS_2GHZ_MIN 2412 /* 2GHz channel 1 */ -#define IEEE80211_CHANNELS_2GHZ_MAX 2732 /* 2GHz channel 26 */ -#define IEEE80211_CHANNELS_5GHZ_MIN 5005 /* 5GHz channel 1 */ -#define IEEE80211_CHANNELS_5GHZ_MAX 6100 /* 5GHz channel 220 */ - -struct ath5k_regchannel { - u16 chan; - enum ath5k_regdom domain; - u32 mode; -}; - -#define IEEE80211_CHANNELS_2GHZ { \ -/*2412*/ { 1, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2417*/ { 2, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2422*/ { 3, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2427*/ { 4, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2432*/ { 5, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2437*/ { 6, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2442*/ { 7, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2447*/ { 8, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2452*/ { 9, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2457*/ { 10, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2462*/ { 11, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2467*/ { 12, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2472*/ { 13, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \ - \ -/*2432*/ { 5, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2437*/ { 6, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*2442*/ { 7, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM }, \ - \ -/*2412*/ { 1, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2417*/ { 2, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2422*/ { 3, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2427*/ { 4, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2432*/ { 5, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2437*/ { 6, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*2442*/ { 7, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2447*/ { 8, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2452*/ { 9, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2457*/ { 10, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2462*/ { 11, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2467*/ { 12, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2472*/ { 13, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \ - \ -/*2412*/ { 1, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2417*/ { 2, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2422*/ { 3, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2427*/ { 4, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2432*/ { 5, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2437*/ { 6, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*2442*/ { 7, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2447*/ { 8, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2452*/ { 9, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2457*/ { 10, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2462*/ { 11, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \ - \ -/*2412*/ { 1, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2417*/ { 2, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2422*/ { 3, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2427*/ { 4, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2432*/ { 5, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2437*/ { 6, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2442*/ { 7, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2447*/ { 8, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2452*/ { 9, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2457*/ { 10, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2462*/ { 11, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2467*/ { 12, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2472*/ { 13, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2484*/ { 14, DMN_MKKA, CHANNEL_CCK }, \ - \ -/*2412*/ { 1, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2417*/ { 2, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2422*/ { 3, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2427*/ { 4, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2432*/ { 5, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2437*/ { 6, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*2442*/ { 7, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2447*/ { 8, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2452*/ { 9, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2457*/ { 10, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2462*/ { 11, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2467*/ { 12, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -/*2472*/ { 13, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \ -} - -#define IEEE80211_CHANNELS_5GHZ { \ -/*5745*/ { 149, DMN_APL1, CHANNEL_OFDM }, \ -/*5765*/ { 153, DMN_APL1, CHANNEL_OFDM }, \ -/*5785*/ { 157, DMN_APL1, CHANNEL_OFDM }, \ -/*5805*/ { 161, DMN_APL1, CHANNEL_OFDM }, \ -/*5825*/ { 165, DMN_APL1, CHANNEL_OFDM }, \ - \ -/*5745*/ { 149, DMN_APL2, CHANNEL_OFDM }, \ -/*5765*/ { 153, DMN_APL2, CHANNEL_OFDM }, \ -/*5785*/ { 157, DMN_APL2, CHANNEL_OFDM }, \ -/*5805*/ { 161, DMN_APL2, CHANNEL_OFDM }, \ - \ -/*5280*/ { 56, DMN_APL3, CHANNEL_OFDM }, \ -/*5300*/ { 60, DMN_APL3, CHANNEL_OFDM }, \ -/*5320*/ { 64, DMN_APL3, CHANNEL_OFDM }, \ -/*5745*/ { 149, DMN_APL3, CHANNEL_OFDM }, \ -/*5765*/ { 153, DMN_APL3, CHANNEL_OFDM }, \ -/*5785*/ { 157, DMN_APL3, CHANNEL_OFDM }, \ -/*5805*/ { 161, DMN_APL3, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_APL4, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_APL4, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_APL4, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_APL4, CHANNEL_OFDM }, \ -/*5745*/ { 149, DMN_APL4, CHANNEL_OFDM }, \ -/*5765*/ { 153, DMN_APL4, CHANNEL_OFDM }, \ -/*5785*/ { 157, DMN_APL4, CHANNEL_OFDM }, \ -/*5805*/ { 161, DMN_APL4, CHANNEL_OFDM }, \ -/*5825*/ { 165, DMN_APL4, CHANNEL_OFDM }, \ - \ -/*5745*/ { 149, DMN_APL5, CHANNEL_OFDM }, \ -/*5765*/ { 153, DMN_APL5, CHANNEL_OFDM }, \ -/*5785*/ { 157, DMN_APL5, CHANNEL_OFDM }, \ -/*5805*/ { 161, DMN_APL5, CHANNEL_OFDM }, \ -/*5825*/ { 165, DMN_APL5, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5260*/ { 52, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5280*/ { 56, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5300*/ { 60, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5320*/ { 64, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5500*/ { 100, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5520*/ { 104, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5540*/ { 108, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5560*/ { 112, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5580*/ { 116, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5600*/ { 120, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5620*/ { 124, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5640*/ { 128, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5660*/ { 132, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5680*/ { 136, DMN_ETSI1, CHANNEL_OFDM }, \ -/*5700*/ { 140, DMN_ETSI1, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_ETSI2, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_ETSI2, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_ETSI2, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_ETSI2, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_ETSI3, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_ETSI3, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_ETSI3, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_ETSI3, CHANNEL_OFDM }, \ -/*5260*/ { 52, DMN_ETSI3, CHANNEL_OFDM }, \ -/*5280*/ { 56, DMN_ETSI3, CHANNEL_OFDM }, \ -/*5300*/ { 60, DMN_ETSI3, CHANNEL_OFDM }, \ -/*5320*/ { 64, DMN_ETSI3, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_ETSI4, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_ETSI4, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_ETSI4, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_ETSI4, CHANNEL_OFDM }, \ -/*5260*/ { 52, DMN_ETSI4, CHANNEL_OFDM }, \ -/*5280*/ { 56, DMN_ETSI4, CHANNEL_OFDM }, \ -/*5300*/ { 60, DMN_ETSI4, CHANNEL_OFDM }, \ -/*5320*/ { 64, DMN_ETSI4, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_ETSI5, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_ETSI5, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_ETSI5, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_ETSI5, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5260*/ { 52, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5280*/ { 56, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5500*/ { 100, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5520*/ { 104, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5540*/ { 108, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5560*/ { 112, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5580*/ { 116, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5600*/ { 120, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5620*/ { 124, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5640*/ { 128, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5660*/ { 132, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5680*/ { 136, DMN_ETSI6, CHANNEL_OFDM }, \ -/*5700*/ { 140, DMN_ETSI6, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_FCC1, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_FCC1, CHANNEL_OFDM }, \ -/*5210*/ { 42, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5220*/ { 44, DMN_FCC1, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_FCC1, CHANNEL_OFDM }, \ -/*5250*/ { 50, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5260*/ { 52, DMN_FCC1, CHANNEL_OFDM }, \ -/*5280*/ { 56, DMN_FCC1, CHANNEL_OFDM }, \ -/*5290*/ { 58, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5300*/ { 60, DMN_FCC1, CHANNEL_OFDM }, \ -/*5320*/ { 64, DMN_FCC1, CHANNEL_OFDM }, \ -/*5745*/ { 149, DMN_FCC1, CHANNEL_OFDM }, \ -/*5760*/ { 152, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5765*/ { 153, DMN_FCC1, CHANNEL_OFDM }, \ -/*5785*/ { 157, DMN_FCC1, CHANNEL_OFDM }, \ -/*5800*/ { 160, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5805*/ { 161, DMN_FCC1, CHANNEL_OFDM }, \ -/*5825*/ { 165, DMN_FCC1, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_FCC2, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_FCC2, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_FCC2, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_FCC2, CHANNEL_OFDM }, \ -/*5260*/ { 52, DMN_FCC2, CHANNEL_OFDM }, \ -/*5280*/ { 56, DMN_FCC2, CHANNEL_OFDM }, \ -/*5300*/ { 60, DMN_FCC2, CHANNEL_OFDM }, \ -/*5320*/ { 64, DMN_FCC2, CHANNEL_OFDM }, \ -/*5745*/ { 149, DMN_FCC2, CHANNEL_OFDM }, \ -/*5765*/ { 153, DMN_FCC2, CHANNEL_OFDM }, \ -/*5785*/ { 157, DMN_FCC2, CHANNEL_OFDM }, \ -/*5805*/ { 161, DMN_FCC2, CHANNEL_OFDM }, \ -/*5825*/ { 165, DMN_FCC2, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_FCC3, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_FCC3, CHANNEL_OFDM }, \ -/*5210*/ { 42, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5220*/ { 44, DMN_FCC3, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_FCC3, CHANNEL_OFDM }, \ -/*5250*/ { 50, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5260*/ { 52, DMN_FCC3, CHANNEL_OFDM }, \ -/*5280*/ { 56, DMN_FCC3, CHANNEL_OFDM }, \ -/*5290*/ { 58, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5300*/ { 60, DMN_FCC3, CHANNEL_OFDM }, \ -/*5320*/ { 64, DMN_FCC3, CHANNEL_OFDM }, \ -/*5500*/ { 100, DMN_FCC3, CHANNEL_OFDM }, \ -/*5520*/ { 104, DMN_FCC3, CHANNEL_OFDM }, \ -/*5540*/ { 108, DMN_FCC3, CHANNEL_OFDM }, \ -/*5560*/ { 112, DMN_FCC3, CHANNEL_OFDM }, \ -/*5580*/ { 116, DMN_FCC3, CHANNEL_OFDM }, \ -/*5600*/ { 120, DMN_FCC3, CHANNEL_OFDM }, \ -/*5620*/ { 124, DMN_FCC3, CHANNEL_OFDM }, \ -/*5640*/ { 128, DMN_FCC3, CHANNEL_OFDM }, \ -/*5660*/ { 132, DMN_FCC3, CHANNEL_OFDM }, \ -/*5680*/ { 136, DMN_FCC3, CHANNEL_OFDM }, \ -/*5700*/ { 140, DMN_FCC3, CHANNEL_OFDM }, \ -/*5745*/ { 149, DMN_FCC3, CHANNEL_OFDM }, \ -/*5760*/ { 152, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5765*/ { 153, DMN_FCC3, CHANNEL_OFDM }, \ -/*5785*/ { 157, DMN_FCC3, CHANNEL_OFDM }, \ -/*5800*/ { 160, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \ -/*5805*/ { 161, DMN_FCC3, CHANNEL_OFDM }, \ -/*5825*/ { 165, DMN_FCC3, CHANNEL_OFDM }, \ - \ -/*5170*/ { 34, DMN_MKK1, CHANNEL_OFDM }, \ -/*5190*/ { 38, DMN_MKK1, CHANNEL_OFDM }, \ -/*5210*/ { 42, DMN_MKK1, CHANNEL_OFDM }, \ -/*5230*/ { 46, DMN_MKK1, CHANNEL_OFDM }, \ - \ -/*5040*/ { 8, DMN_MKK2, CHANNEL_OFDM }, \ -/*5060*/ { 12, DMN_MKK2, CHANNEL_OFDM }, \ -/*5080*/ { 16, DMN_MKK2, CHANNEL_OFDM }, \ -/*5170*/ { 34, DMN_MKK2, CHANNEL_OFDM }, \ -/*5190*/ { 38, DMN_MKK2, CHANNEL_OFDM }, \ -/*5210*/ { 42, DMN_MKK2, CHANNEL_OFDM }, \ -/*5230*/ { 46, DMN_MKK2, CHANNEL_OFDM }, \ - \ -/*5180*/ { 36, DMN_WORLD, CHANNEL_OFDM }, \ -/*5200*/ { 40, DMN_WORLD, CHANNEL_OFDM }, \ -/*5220*/ { 44, DMN_WORLD, CHANNEL_OFDM }, \ -/*5240*/ { 48, DMN_WORLD, CHANNEL_OFDM }, \ -} - -enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom, u16); -u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee); -enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain); - -#endif |