diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/Kconfig | 8 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800.h | 181 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 388 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 83 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00config.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 2 |
19 files changed, 640 insertions, 98 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 299c3879582..c7548da6573 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -99,6 +99,14 @@ config RT2800PCI_RT53XX rt2800pci driver. Supported chips: RT5390 +config RT2800PCI_RT3290 + bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)" + depends on EXPERIMENTAL + default y + ---help--- + This adds support for rt3290 wireless chipset family to the + rt2800pci driver. + Supported chips: RT3290 endif config RT2500USB diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 5e6b5014316..8b9dbd76a25 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1455,7 +1455,7 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - random_ether_addr(mac); + eth_random_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 136b849f11b..d2cf8a4bc8b 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1585,7 +1585,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - random_ether_addr(mac); + eth_random_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 669aecdb411..3aae36bb0a9 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1352,7 +1352,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - random_ether_addr(mac); + eth_random_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 9348521e083..e252e9bafd0 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -51,6 +51,7 @@ * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) + * RF5360 2.4G 1T1R * RF5370 2.4G 1T1R * RF5390 2.4G 1T1R */ @@ -67,9 +68,12 @@ #define RF3320 0x000b #define RF3322 0x000c #define RF3053 0x000d +#define RF3290 0x3290 +#define RF5360 0x5360 #define RF5370 0x5370 #define RF5372 0x5372 #define RF5390 0x5390 +#define RF5392 0x5392 /* * Chipset revisions. @@ -114,6 +118,12 @@ * Registers. */ + +/* + * MAC_CSR0_3290: MAC_CSR0 for RT3290 to identity MAC version number. + */ +#define MAC_CSR0_3290 0x0000 + /* * E2PROM_CSR: PCI EEPROM control register. * RELOAD: Write 1 to reload eeprom content. @@ -130,6 +140,150 @@ #define E2PROM_CSR_RELOAD FIELD32(0x00000080) /* + * CMB_CTRL_CFG + */ +#define CMB_CTRL 0x0020 +#define AUX_OPT_BIT0 FIELD32(0x00000001) +#define AUX_OPT_BIT1 FIELD32(0x00000002) +#define AUX_OPT_BIT2 FIELD32(0x00000004) +#define AUX_OPT_BIT3 FIELD32(0x00000008) +#define AUX_OPT_BIT4 FIELD32(0x00000010) +#define AUX_OPT_BIT5 FIELD32(0x00000020) +#define AUX_OPT_BIT6 FIELD32(0x00000040) +#define AUX_OPT_BIT7 FIELD32(0x00000080) +#define AUX_OPT_BIT8 FIELD32(0x00000100) +#define AUX_OPT_BIT9 FIELD32(0x00000200) +#define AUX_OPT_BIT10 FIELD32(0x00000400) +#define AUX_OPT_BIT11 FIELD32(0x00000800) +#define AUX_OPT_BIT12 FIELD32(0x00001000) +#define AUX_OPT_BIT13 FIELD32(0x00002000) +#define AUX_OPT_BIT14 FIELD32(0x00004000) +#define AUX_OPT_BIT15 FIELD32(0x00008000) +#define LDO25_LEVEL FIELD32(0x00030000) +#define LDO25_LARGEA FIELD32(0x00040000) +#define LDO25_FRC_ON FIELD32(0x00080000) +#define CMB_RSV FIELD32(0x00300000) +#define XTAL_RDY FIELD32(0x00400000) +#define PLL_LD FIELD32(0x00800000) +#define LDO_CORE_LEVEL FIELD32(0x0F000000) +#define LDO_BGSEL FIELD32(0x30000000) +#define LDO3_EN FIELD32(0x40000000) +#define LDO0_EN FIELD32(0x80000000) + +/* + * EFUSE_CSR_3290: RT3290 EEPROM + */ +#define EFUSE_CTRL_3290 0x0024 + +/* + * EFUSE_DATA3 of 3290 + */ +#define EFUSE_DATA3_3290 0x0028 + +/* + * EFUSE_DATA2 of 3290 + */ +#define EFUSE_DATA2_3290 0x002c + +/* + * EFUSE_DATA1 of 3290 + */ +#define EFUSE_DATA1_3290 0x0030 + +/* + * EFUSE_DATA0 of 3290 + */ +#define EFUSE_DATA0_3290 0x0034 + +/* + * OSC_CTRL_CFG + * Ring oscillator configuration + */ +#define OSC_CTRL 0x0038 +#define OSC_REF_CYCLE FIELD32(0x00001fff) +#define OSC_RSV FIELD32(0x0000e000) +#define OSC_CAL_CNT FIELD32(0x0fff0000) +#define OSC_CAL_ACK FIELD32(0x10000000) +#define OSC_CLK_32K_VLD FIELD32(0x20000000) +#define OSC_CAL_REQ FIELD32(0x40000000) +#define OSC_ROSC_EN FIELD32(0x80000000) + +/* + * COEX_CFG_0 + */ +#define COEX_CFG0 0x0040 +#define COEX_CFG_ANT FIELD32(0xff000000) +/* + * COEX_CFG_1 + */ +#define COEX_CFG1 0x0044 + +/* + * COEX_CFG_2 + */ +#define COEX_CFG2 0x0048 +#define BT_COEX_CFG1 FIELD32(0xff000000) +#define BT_COEX_CFG0 FIELD32(0x00ff0000) +#define WL_COEX_CFG1 FIELD32(0x0000ff00) +#define WL_COEX_CFG0 FIELD32(0x000000ff) +/* + * PLL_CTRL_CFG + * PLL configuration register + */ +#define PLL_CTRL 0x0050 +#define PLL_RESERVED_INPUT1 FIELD32(0x000000ff) +#define PLL_RESERVED_INPUT2 FIELD32(0x0000ff00) +#define PLL_CONTROL FIELD32(0x00070000) +#define PLL_LPF_R1 FIELD32(0x00080000) +#define PLL_LPF_C1_CTRL FIELD32(0x00300000) +#define PLL_LPF_C2_CTRL FIELD32(0x00c00000) +#define PLL_CP_CURRENT_CTRL FIELD32(0x03000000) +#define PLL_PFD_DELAY_CTRL FIELD32(0x0c000000) +#define PLL_LOCK_CTRL FIELD32(0x70000000) +#define PLL_VBGBK_EN FIELD32(0x80000000) + + +/* + * WLAN_CTRL_CFG + * RT3290 wlan configuration + */ +#define WLAN_FUN_CTRL 0x0080 +#define WLAN_EN FIELD32(0x00000001) +#define WLAN_CLK_EN FIELD32(0x00000002) +#define WLAN_RSV1 FIELD32(0x00000004) +#define WLAN_RESET FIELD32(0x00000008) +#define PCIE_APP0_CLK_REQ FIELD32(0x00000010) +#define FRC_WL_ANT_SET FIELD32(0x00000020) +#define INV_TR_SW0 FIELD32(0x00000040) +#define WLAN_GPIO_IN_BIT0 FIELD32(0x00000100) +#define WLAN_GPIO_IN_BIT1 FIELD32(0x00000200) +#define WLAN_GPIO_IN_BIT2 FIELD32(0x00000400) +#define WLAN_GPIO_IN_BIT3 FIELD32(0x00000800) +#define WLAN_GPIO_IN_BIT4 FIELD32(0x00001000) +#define WLAN_GPIO_IN_BIT5 FIELD32(0x00002000) +#define WLAN_GPIO_IN_BIT6 FIELD32(0x00004000) +#define WLAN_GPIO_IN_BIT7 FIELD32(0x00008000) +#define WLAN_GPIO_IN_BIT_ALL FIELD32(0x0000ff00) +#define WLAN_GPIO_OUT_BIT0 FIELD32(0x00010000) +#define WLAN_GPIO_OUT_BIT1 FIELD32(0x00020000) +#define WLAN_GPIO_OUT_BIT2 FIELD32(0x00040000) +#define WLAN_GPIO_OUT_BIT3 FIELD32(0x00050000) +#define WLAN_GPIO_OUT_BIT4 FIELD32(0x00100000) +#define WLAN_GPIO_OUT_BIT5 FIELD32(0x00200000) +#define WLAN_GPIO_OUT_BIT6 FIELD32(0x00400000) +#define WLAN_GPIO_OUT_BIT7 FIELD32(0x00800000) +#define WLAN_GPIO_OUT_BIT_ALL FIELD32(0x00ff0000) +#define WLAN_GPIO_OUT_OE_BIT0 FIELD32(0x01000000) +#define WLAN_GPIO_OUT_OE_BIT1 FIELD32(0x02000000) +#define WLAN_GPIO_OUT_OE_BIT2 FIELD32(0x04000000) +#define WLAN_GPIO_OUT_OE_BIT3 FIELD32(0x08000000) +#define WLAN_GPIO_OUT_OE_BIT4 FIELD32(0x10000000) +#define WLAN_GPIO_OUT_OE_BIT5 FIELD32(0x20000000) +#define WLAN_GPIO_OUT_OE_BIT6 FIELD32(0x40000000) +#define WLAN_GPIO_OUT_OE_BIT7 FIELD32(0x80000000) +#define WLAN_GPIO_OUT_OE_BIT_ALL FIELD32(0xff000000) + +/* * AUX_CTRL: Aux/PCI-E related configuration */ #define AUX_CTRL 0x10c @@ -1760,9 +1914,11 @@ struct mac_iveiv_entry { /* * BBP 3: RX Antenna */ -#define BBP3_RX_ADC FIELD8(0x03) +#define BBP3_RX_ADC FIELD8(0x03) #define BBP3_RX_ANTENNA FIELD8(0x18) #define BBP3_HT40_MINUS FIELD8(0x20) +#define BBP3_ADC_MODE_SWITCH FIELD8(0x40) +#define BBP3_ADC_INIT_MODE FIELD8(0x80) /* * BBP 4: Bandwidth @@ -1772,6 +1928,14 @@ struct mac_iveiv_entry { #define BBP4_MAC_IF_CTRL FIELD8(0x40) /* + * BBP 47: Bandwidth + */ +#define BBP47_TSSI_REPORT_SEL FIELD8(0x03) +#define BBP47_TSSI_UPDATE_REQ FIELD8(0x04) +#define BBP47_TSSI_TSSI_MODE FIELD8(0x18) +#define BBP47_TSSI_ADC6 FIELD8(0x80) + +/* * BBP 109 */ #define BBP109_TX0_POWER FIELD8(0x0f) @@ -1914,6 +2078,16 @@ struct mac_iveiv_entry { #define RFCSR27_R4 FIELD8(0x40) /* + * RFCSR 29: + */ +#define RFCSR29_ADC6_TEST FIELD8(0x01) +#define RFCSR29_ADC6_INT_TEST FIELD8(0x02) +#define RFCSR29_RSSI_RESET FIELD8(0x04) +#define RFCSR29_RSSI_ON FIELD8(0x08) +#define RFCSR29_RSSI_RIP_CTRL FIELD8(0x30) +#define RFCSR29_RSSI_GAIN FIELD8(0xc0) + +/* * RFCSR 30: */ #define RFCSR30_TX_H20M FIELD8(0x02) @@ -1944,6 +2118,11 @@ struct mac_iveiv_entry { #define RFCSR49_TX FIELD8(0x3f) /* + * RFCSR 50: + */ +#define RFCSR50_TX FIELD8(0x3f) + +/* * RF registers */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index dfc90d34be6..88455b1b9fe 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -354,16 +354,15 @@ int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, * of 4kb. Certain USB chipsets however require different firmware, * which Ralink only provides attached to the original firmware * file. Thus for USB devices, firmware files have a length - * which is a multiple of 4kb. + * which is a multiple of 4kb. The firmware for rt3290 chip also + * have a length which is a multiple of 4kb. */ - if (rt2x00_is_usb(rt2x00dev)) { + if (rt2x00_is_usb(rt2x00dev) || rt2x00_rt(rt2x00dev, RT3290)) fw_len = 4096; - multiple = true; - } else { + else fw_len = 8192; - multiple = true; - } + multiple = true; /* * Validate the firmware length */ @@ -415,7 +414,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, return -EBUSY; if (rt2x00_is_pci(rt2x00dev)) { - if (rt2x00_rt(rt2x00dev, RT3572) || + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { rt2800_register_read(rt2x00dev, AUX_CTRL, ®); @@ -851,8 +851,13 @@ int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); - return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2); + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); + return rt2x00_get_field32(reg, WLAN_GPIO_IN_BIT0); + } else { + rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); + return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2); + } } EXPORT_SYMBOL_GPL(rt2800_rfkill_poll); @@ -1935,8 +1940,50 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); } -#define RT5390_POWER_BOUND 0x27 -#define RT5390_FREQ_OFFSET_BOUND 0x5f +#define POWER_BOUND 0x27 +#define FREQ_OFFSET_BOUND 0x5f + +static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, + struct channel_info *info) +{ + u8 rfcsr; + + rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); + rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); + rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); + rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); + if (info->default_power1 > POWER_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR49_TX, POWER_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); + rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + + if (rf->channel <= 14) { + if (rf->channel == 6) + rt2800_bbp_write(rt2x00dev, 68, 0x0c); + else + rt2800_bbp_write(rt2x00dev, 68, 0x0b); + + if (rf->channel >= 1 && rf->channel <= 6) + rt2800_bbp_write(rt2x00dev, 59, 0x0f); + else if (rf->channel >= 7 && rf->channel <= 11) + rt2800_bbp_write(rt2x00dev, 59, 0x0e); + else if (rf->channel >= 12 && rf->channel <= 14) + rt2800_bbp_write(rt2x00dev, 59, 0x0d); + } +} static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, @@ -1952,13 +1999,27 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); - if (info->default_power1 > RT5390_POWER_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND); + if (info->default_power1 > POWER_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR49_TX, POWER_BOUND); else rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); + if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); + if (info->default_power1 > POWER_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR50_TX, POWER_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR50_TX, + info->default_power2); + rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); + } + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); + } rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); @@ -1966,9 +2027,8 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, - RT5390_FREQ_OFFSET_BOUND); + if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); else rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); @@ -2021,15 +2081,6 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, } } } - - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); - rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); - rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); } static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, @@ -2039,7 +2090,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, { u32 reg; unsigned int tx_pin; - u8 bbp; + u8 bbp, rfcsr; if (rf->channel <= 14) { info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); @@ -2060,15 +2111,36 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, case RF3052: rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); break; + case RF3290: + rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info); + break; + case RF5360: case RF5370: case RF5372: case RF5390: + case RF5392: rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); break; default: rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); } + if (rt2x00_rf(rt2x00dev, RF3290) || + rt2x00_rf(rt2x00dev, RF5360) || + rt2x00_rf(rt2x00dev, RF5370) || + rt2x00_rf(rt2x00dev, RF5372) || + rt2x00_rf(rt2x00dev, RF5390) || + rt2x00_rf(rt2x00dev, RF5392)) { + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); + rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); + } + /* * Change BBP settings */ @@ -2549,9 +2621,12 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); break; + case RF3290: + case RF5360: case RF5370: case RF5372: case RF5390: + case RF5392: rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); @@ -2682,6 +2757,7 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) @@ -2778,10 +2854,54 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2); rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); + if (rt2x00_get_field32(reg, WLAN_EN) == 1) { + rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 1); + rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); + } + + rt2800_register_read(rt2x00dev, CMB_CTRL, ®); + if (!(rt2x00_get_field32(reg, LDO0_EN) == 1)) { + rt2x00_set_field32(®, LDO0_EN, 1); + rt2x00_set_field32(®, LDO_BGSEL, 3); + rt2800_register_write(rt2x00dev, CMB_CTRL, reg); + } + + rt2800_register_read(rt2x00dev, OSC_CTRL, ®); + rt2x00_set_field32(®, OSC_ROSC_EN, 1); + rt2x00_set_field32(®, OSC_CAL_REQ, 1); + rt2x00_set_field32(®, OSC_REF_CYCLE, 0x27); + rt2800_register_write(rt2x00dev, OSC_CTRL, reg); + + rt2800_register_read(rt2x00dev, COEX_CFG0, ®); + rt2x00_set_field32(®, COEX_CFG_ANT, 0x5e); + rt2800_register_write(rt2x00dev, COEX_CFG0, reg); + + rt2800_register_read(rt2x00dev, COEX_CFG2, ®); + rt2x00_set_field32(®, BT_COEX_CFG1, 0x00); + rt2x00_set_field32(®, BT_COEX_CFG0, 0x17); + rt2x00_set_field32(®, WL_COEX_CFG1, 0x93); + rt2x00_set_field32(®, WL_COEX_CFG0, 0x7f); + rt2800_register_write(rt2x00dev, COEX_CFG2, reg); + + rt2800_register_read(rt2x00dev, PLL_CTRL, ®); + rt2x00_set_field32(®, PLL_CONTROL, 1); + rt2800_register_write(rt2x00dev, PLL_CTRL, reg); + } + if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3390)) { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); + + if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_register_write(rt2x00dev, TX_SW_CFG0, + 0x00000404); + else + rt2800_register_write(rt2x00dev, TX_SW_CFG0, + 0x00000400); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || @@ -3190,14 +3310,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_wait_bbp_ready(rt2x00dev))) return -EACCES; - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_read(rt2x00dev, 4, &value); rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); rt2800_bbp_write(rt2x00dev, 4, value); } if (rt2800_is_305x_soc(rt2x00dev) || + rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) @@ -3206,20 +3328,26 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 65, 0x2c); rt2800_bbp_write(rt2x00dev, 66, 0x38); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 68, 0x0b); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { rt2800_bbp_write(rt2x00dev, 69, 0x16); rt2800_bbp_write(rt2x00dev, 73, 0x12); - } else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + } else if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x13); rt2800_bbp_write(rt2x00dev, 75, 0x46); rt2800_bbp_write(rt2x00dev, 76, 0x28); - rt2800_bbp_write(rt2x00dev, 77, 0x59); + + if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_bbp_write(rt2x00dev, 77, 0x58); + else + rt2800_bbp_write(rt2x00dev, 77, 0x59); } else { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x10); @@ -3244,23 +3372,33 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 81, 0x37); } + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_bbp_write(rt2x00dev, 74, 0x0b); + rt2800_bbp_write(rt2x00dev, 79, 0x18); + rt2800_bbp_write(rt2x00dev, 80, 0x09); + rt2800_bbp_write(rt2x00dev, 81, 0x33); + } + rt2800_bbp_write(rt2x00dev, 82, 0x62); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 83, 0x7a); else rt2800_bbp_write(rt2x00dev, 83, 0x6a); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) rt2800_bbp_write(rt2x00dev, 84, 0x19); - else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + else if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 84, 0x9a); else rt2800_bbp_write(rt2x00dev, 84, 0x99); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 86, 0x38); else rt2800_bbp_write(rt2x00dev, 86, 0x00); @@ -3270,8 +3408,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 91, 0x04); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 92, 0x02); else rt2800_bbp_write(rt2x00dev, 92, 0x00); @@ -3285,6 +3424,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || + rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392) || @@ -3293,27 +3433,32 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) else rt2800_bbp_write(rt2x00dev, 103, 0x00); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 104, 0x92); if (rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 105, 0x01); + else if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_bbp_write(rt2x00dev, 105, 0x1c); else if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 105, 0x3c); else rt2800_bbp_write(rt2x00dev, 105, 0x05); - if (rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390)) rt2800_bbp_write(rt2x00dev, 106, 0x03); else if (rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 106, 0x12); else rt2800_bbp_write(rt2x00dev, 106, 0x35); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 128, 0x12); if (rt2x00_rt(rt2x00dev, RT5392)) { @@ -3338,6 +3483,29 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 138, value); } + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_bbp_write(rt2x00dev, 67, 0x24); + rt2800_bbp_write(rt2x00dev, 143, 0x04); + rt2800_bbp_write(rt2x00dev, 142, 0x99); + rt2800_bbp_write(rt2x00dev, 150, 0x30); + rt2800_bbp_write(rt2x00dev, 151, 0x2e); + rt2800_bbp_write(rt2x00dev, 152, 0x20); + rt2800_bbp_write(rt2x00dev, 153, 0x34); + rt2800_bbp_write(rt2x00dev, 154, 0x40); + rt2800_bbp_write(rt2x00dev, 155, 0x3b); + rt2800_bbp_write(rt2x00dev, 253, 0x04); + + rt2800_bbp_read(rt2x00dev, 47, &value); + rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1); + rt2800_bbp_write(rt2x00dev, 47, value); + + /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */ + rt2800_bbp_read(rt2x00dev, 3, &value); + rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1); + rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1); + rt2800_bbp_write(rt2x00dev, 3, value); + } + if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { int ant, div_mode; @@ -3470,6 +3638,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) if (!rt2x00_rt(rt2x00dev, RT3070) && !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && + !rt2x00_rt(rt2x00dev, RT3290) && !rt2x00_rt(rt2x00dev, RT3390) && !rt2x00_rt(rt2x00dev, RT3572) && !rt2x00_rt(rt2x00dev, RT5390) && @@ -3480,8 +3649,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) /* * Init RF calibration. */ - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); @@ -3519,6 +3689,53 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 24, 0x16); rt2800_rfcsr_write(rt2x00dev, 25, 0x01); rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); + } else if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x08); + rt2800_rfcsr_write(rt2x00dev, 4, 0x00); + rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 8, 0xf3); + rt2800_rfcsr_write(rt2x00dev, 9, 0x02); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0x46); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 18, 0x02); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 25, 0x83); + rt2800_rfcsr_write(rt2x00dev, 26, 0x82); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); + rt2800_rfcsr_write(rt2x00dev, 34, 0x05); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); + rt2800_rfcsr_write(rt2x00dev, 43, 0x7b); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + rt2800_rfcsr_write(rt2x00dev, 47, 0x00); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x98); + rt2800_rfcsr_write(rt2x00dev, 52, 0x38); + rt2800_rfcsr_write(rt2x00dev, 53, 0x00); + rt2800_rfcsr_write(rt2x00dev, 54, 0x78); + rt2800_rfcsr_write(rt2x00dev, 55, 0x43); + rt2800_rfcsr_write(rt2x00dev, 56, 0x02); + rt2800_rfcsr_write(rt2x00dev, 57, 0x80); + rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); + rt2800_rfcsr_write(rt2x00dev, 59, 0x09); + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); } else if (rt2x00_rt(rt2x00dev, RT3390)) { rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); @@ -3927,6 +4144,12 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); } + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3); + rt2800_rfcsr_write(rt2x00dev, 29, rfcsr); + } + if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); @@ -4033,9 +4256,14 @@ EXPORT_SYMBOL_GPL(rt2800_disable_radio); int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) { u32 reg; + u16 efuse_ctrl_reg; - rt2800_register_read(rt2x00dev, EFUSE_CTRL, ®); + if (rt2x00_rt(rt2x00dev, RT3290)) + efuse_ctrl_reg = EFUSE_CTRL_3290; + else + efuse_ctrl_reg = EFUSE_CTRL; + rt2800_register_read(rt2x00dev, efuse_ctrl_reg, ®); return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT); } EXPORT_SYMBOL_GPL(rt2800_efuse_detect); @@ -4043,27 +4271,44 @@ EXPORT_SYMBOL_GPL(rt2800_efuse_detect); static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) { u32 reg; - + u16 efuse_ctrl_reg; + u16 efuse_data0_reg; + u16 efuse_data1_reg; + u16 efuse_data2_reg; + u16 efuse_data3_reg; + + if (rt2x00_rt(rt2x00dev, RT3290)) { + efuse_ctrl_reg = EFUSE_CTRL_3290; + efuse_data0_reg = EFUSE_DATA0_3290; + efuse_data1_reg = EFUSE_DATA1_3290; + efuse_data2_reg = EFUSE_DATA2_3290; + efuse_data3_reg = EFUSE_DATA3_3290; + } else { + efuse_ctrl_reg = EFUSE_CTRL; + efuse_data0_reg = EFUSE_DATA0; + efuse_data1_reg = EFUSE_DATA1; + efuse_data2_reg = EFUSE_DATA2; + efuse_data3_reg = EFUSE_DATA3; + } mutex_lock(&rt2x00dev->csr_mutex); - rt2800_register_read_lock(rt2x00dev, EFUSE_CTRL, ®); + rt2800_register_read_lock(rt2x00dev, efuse_ctrl_reg, ®); rt2x00_set_field32(®, EFUSE_CTRL_ADDRESS_IN, i); rt2x00_set_field32(®, EFUSE_CTRL_MODE, 0); rt2x00_set_field32(®, EFUSE_CTRL_KICK, 1); - rt2800_register_write_lock(rt2x00dev, EFUSE_CTRL, reg); + rt2800_register_write_lock(rt2x00dev, efuse_ctrl_reg, reg); /* Wait until the EEPROM has been loaded */ - rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, ®); - + rt2800_regbusy_read(rt2x00dev, efuse_ctrl_reg, EFUSE_CTRL_KICK, ®); /* Apparently the data is read from end to start */ - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); + rt2800_register_read_lock(rt2x00dev, efuse_data3_reg, ®); /* The returned value is in CPU order, but eeprom is le */ *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); + rt2800_register_read_lock(rt2x00dev, efuse_data2_reg, ®); *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); + rt2800_register_read_lock(rt2x00dev, efuse_data1_reg, ®); *(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, ®); + rt2800_register_read_lock(rt2x00dev, efuse_data0_reg, ®); *(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg); mutex_unlock(&rt2x00dev->csr_mutex); @@ -4090,7 +4335,7 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - random_ether_addr(mac); + eth_random_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } @@ -4225,9 +4470,14 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field * RT53xx: defined in "EEPROM_CHIP_ID" field */ - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 || - rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392) + if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_register_read(rt2x00dev, MAC_CSR0_3290, ®); + else + rt2800_register_read(rt2x00dev, MAC_CSR0, ®); + + if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT3290 || + rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 || + rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392) rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); else value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); @@ -4242,6 +4492,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RT3070: case RT3071: case RT3090: + case RT3290: case RT3390: case RT3572: case RT5390: @@ -4262,10 +4513,13 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF3021: case RF3022: case RF3052: + case RF3290: case RF3320: + case RF5360: case RF5370: case RF5372: case RF5390: + case RF5392: break; default: ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", @@ -4576,10 +4830,13 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3290) || rt2x00_rf(rt2x00dev, RF3320) || + rt2x00_rf(rt2x00dev, RF5360) || rt2x00_rf(rt2x00dev, RF5370) || rt2x00_rf(rt2x00dev, RF5372) || - rt2x00_rf(rt2x00dev, RF5390)) { + rt2x00_rf(rt2x00dev, RF5390) || + rt2x00_rf(rt2x00dev, RF5392)) { spec->num_channels = 14; spec->channels = rf_vals_3x; } else if (rt2x00_rf(rt2x00dev, RF3052)) { @@ -4662,9 +4919,12 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF3022: case RF3320: case RF3052: + case RF3290: + case RF5360: case RF5370: case RF5372: case RF5390: + case RF5392: __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); break; } diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index cad25bfebd7..235376e9cb0 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -280,7 +280,13 @@ static void rt2800pci_stop_queue(struct data_queue *queue) */ static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) { - return FIRMWARE_RT2860; + /* + * Chip rt3290 use specific 4KB firmware named rt3290.bin. + */ + if (rt2x00_rt(rt2x00dev, RT3290)) + return FIRMWARE_RT3290; + else + return FIRMWARE_RT2860; } static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, @@ -974,6 +980,66 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) return rt2800_validate_eeprom(rt2x00dev); } +static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + int i, count; + + rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); + if (rt2x00_get_field32(reg, WLAN_EN)) + return 0; + + rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff); + rt2x00_set_field32(®, FRC_WL_ANT_SET, 1); + rt2x00_set_field32(®, WLAN_CLK_EN, 0); + rt2x00_set_field32(®, WLAN_EN, 1); + rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); + + udelay(REGISTER_BUSY_DELAY); + + count = 0; + do { + /* + * Check PLL_LD & XTAL_RDY. + */ + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2800_register_read(rt2x00dev, CMB_CTRL, ®); + if (rt2x00_get_field32(reg, PLL_LD) && + rt2x00_get_field32(reg, XTAL_RDY)) + break; + udelay(REGISTER_BUSY_DELAY); + } + + if (i >= REGISTER_BUSY_COUNT) { + + if (count >= 10) + return -EIO; + + rt2800_register_write(rt2x00dev, 0x58, 0x018); + udelay(REGISTER_BUSY_DELAY); + rt2800_register_write(rt2x00dev, 0x58, 0x418); + udelay(REGISTER_BUSY_DELAY); + rt2800_register_write(rt2x00dev, 0x58, 0x618); + udelay(REGISTER_BUSY_DELAY); + count++; + } else { + count = 0; + } + + rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); + rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0); + rt2x00_set_field32(®, WLAN_CLK_EN, 1); + rt2x00_set_field32(®, WLAN_RESET, 1); + rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); + udelay(10); + rt2x00_set_field32(®, WLAN_RESET, 0); + rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); + udelay(10); + rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff); + } while (count != 0); + + return 0; +} static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; @@ -997,6 +1063,17 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) return retval; /* + * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan + * clk for rt3290. That avoid the MCU fail in start phase. + */ + if (rt2x00_rt(rt2x00dev, RT3290)) { + retval = rt2800_enable_wlan_rt3290(rt2x00dev); + + if (retval) + return retval; + } + + /* * This device has multiple filters for control frames * and has a separate filter for PS Poll frames. */ @@ -1175,6 +1252,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1432, 0x7768) }, { PCI_DEVICE(0x1462, 0x891a) }, { PCI_DEVICE(0x1a3b, 0x1059) }, +#ifdef CONFIG_RT2800PCI_RT3290 + { PCI_DEVICE(0x1814, 0x3290) }, +#endif #ifdef CONFIG_RT2800PCI_RT33XX { PCI_DEVICE(0x1814, 0x3390) }, #endif @@ -1188,6 +1268,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x3593) }, #endif #ifdef CONFIG_RT2800PCI_RT53XX + { PCI_DEVICE(0x1814, 0x5360) }, { PCI_DEVICE(0x1814, 0x5362) }, { PCI_DEVICE(0x1814, 0x5390) }, { PCI_DEVICE(0x1814, 0x5392) }, diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h index 70e050d904c..ab22a087c50 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/drivers/net/wireless/rt2x00/rt2800pci.h @@ -47,6 +47,7 @@ * 8051 firmware image. */ #define FIRMWARE_RT2860 "rt2860.bin" +#define FIRMWARE_RT3290 "rt3290.bin" #define FIRMWARE_IMAGE_BASE 0x2000 /* diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index bf78317a6ad..6cf336595e2 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -971,6 +971,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0411, 0x015d) }, { USB_DEVICE(0x0411, 0x016f) }, { USB_DEVICE(0x0411, 0x01a2) }, + { USB_DEVICE(0x0411, 0x01ee) }, /* Corega */ { USB_DEVICE(0x07aa, 0x002f) }, { USB_DEVICE(0x07aa, 0x003c) }, @@ -1137,6 +1138,8 @@ static struct usb_device_id rt2800usb_device_table[] = { #ifdef CONFIG_RT2800USB_RT33XX /* Belkin */ { USB_DEVICE(0x050d, 0x945b) }, + /* D-Link */ + { USB_DEVICE(0x2001, 0x3c17) }, /* Panasonic */ { USB_DEVICE(0x083a, 0xb511) }, /* Philips */ @@ -1237,7 +1240,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* D-Link */ { USB_DEVICE(0x07d1, 0x3c0b) }, { USB_DEVICE(0x07d1, 0x3c17) }, - { USB_DEVICE(0x2001, 0x3c17) }, /* Encore */ { USB_DEVICE(0x203d, 0x14a1) }, /* Gemtek */ diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8f754025b06..8afb546c2b2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -187,6 +187,7 @@ struct rt2x00_chip { #define RT3070 0x3070 #define RT3071 0x3071 #define RT3090 0x3090 /* 2.4GHz PCIe */ +#define RT3290 0x3290 #define RT3390 0x3390 #define RT3572 0x3572 #define RT3593 0x3593 diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index e7361d913e8..49a63e97393 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -102,7 +102,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, /* Update the AID, this is needed for dynamic PS support */ rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; - rt2x00dev->last_beacon = bss_conf->last_tsf; + rt2x00dev->last_beacon = bss_conf->sync_tsf; /* Update global beacon interval time, this is needed for PS support */ rt2x00dev->beacon_int = bss_conf->beacon_int; diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e5404e57625..a6b88bd4a1a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1161,6 +1161,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_WDS); + rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + /* * Initialize work. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index dd24b2663b5..4ff26c2159b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -506,9 +506,19 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; - else if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) + + if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) + return -EOPNOTSUPP; + + /* + * To support IBSS RSN, don't program group keys in IBSS, the + * hardware will then not attempt to decrypt the frames. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return -EOPNOTSUPP; - else if (key->keylen > 32) + + if (key->keylen > 32) return -ENOSPC; memset(&crypto, 0, sizeof(crypto)); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 0a4653a92ca..a0c8caef3b0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -256,6 +256,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) struct ieee80211_hw *hw; struct rt2x00_dev *rt2x00dev; int retval; + u16 chip; retval = pci_enable_device(pci_dev); if (retval) { @@ -305,6 +306,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) if (retval) goto exit_free_device; + /* + * Because rt3290 chip use different efuse offset to read efuse data. + * So before read efuse it need to indicate it is the + * rt3290 or not. + */ + pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip); + rt2x00dev->chip.rt = chip; + retval = rt2x00lib_probe_dev(rt2x00dev); if (retval) goto exit_free_reg; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 2fd83010341..f7e74a0a775 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -774,9 +774,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, bool rt2x00queue_for_each_entry(struct data_queue *queue, enum queue_index start, enum queue_index end, - void *data, - bool (*fn)(struct queue_entry *entry, - void *data)) + bool (*fn)(struct queue_entry *entry)) { unsigned long irqflags; unsigned int index_start; @@ -807,17 +805,17 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue, */ if (index_start < index_end) { for (i = index_start; i < index_end; i++) { - if (fn(&queue->entries[i], data)) + if (fn(&queue->entries[i])) return true; } } else { for (i = index_start; i < queue->limit; i++) { - if (fn(&queue->entries[i], data)) + if (fn(&queue->entries[i])) return true; } for (i = 0; i < index_end; i++) { - if (fn(&queue->entries[i], data)) + if (fn(&queue->entries[i])) return true; } } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 5f1392c7267..9b8c10a86de 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -584,7 +584,6 @@ struct data_queue_desc { * @queue: Pointer to @data_queue * @start: &enum queue_index Pointer to start index * @end: &enum queue_index Pointer to end index - * @data: Data to pass to the callback function * @fn: The function to call for each &struct queue_entry * * This will walk through all entries in the queue, in chronological @@ -597,9 +596,7 @@ struct data_queue_desc { bool rt2x00queue_for_each_entry(struct data_queue *queue, enum queue_index start, enum queue_index end, - void *data, - bool (*fn)(struct queue_entry *entry, - void *data)); + bool (*fn)(struct queue_entry *entry)); /** * rt2x00queue_empty - Check if the queue is empty. diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index d357d1ed92f..40ea80725a9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -285,7 +285,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); } -static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data) +static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); @@ -390,7 +390,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); } -static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data) +static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); @@ -427,18 +427,12 @@ void rt2x00usb_kick_queue(struct data_queue *queue) case QID_AC_BE: case QID_AC_BK: if (!rt2x00queue_empty(queue)) - rt2x00queue_for_each_entry(queue, - Q_INDEX_DONE, - Q_INDEX, - NULL, + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, rt2x00usb_kick_tx_entry); break; case QID_RX: if (!rt2x00queue_full(queue)) - rt2x00queue_for_each_entry(queue, - Q_INDEX_DONE, - Q_INDEX, - NULL, + rt2x00queue_for_each_entry(queue, Q_INDEX, Q_INDEX_DONE, rt2x00usb_kick_rx_entry); break; default: @@ -447,7 +441,7 @@ void rt2x00usb_kick_queue(struct data_queue *queue) } EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); -static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data) +static bool rt2x00usb_flush_entry(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv = entry->priv_data; @@ -474,7 +468,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue, bool drop) unsigned int i; if (drop) - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, rt2x00usb_flush_entry); /* @@ -565,7 +559,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) entry->flags = 0; if (entry->queue->qid == QID_RX) - rt2x00usb_kick_rx_entry(entry, NULL); + rt2x00usb_kick_rx_entry(entry); } EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index ee22bd74579..f32259686b4 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2415,7 +2415,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - random_ether_addr(mac); + eth_random_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 77ccbbc7da4..ba6e434b859 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1770,7 +1770,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - random_ether_addr(mac); + eth_random_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } |