Skip to content

Commit

Permalink
rt2x00: rework RT chipset and revision determination for PCI an SOC d…
Browse files Browse the repository at this point in the history
…evices.

The recent rt2800 devices are no longer really identified by their PCI
ID's, but rather by the contents of their CSR0 register. Also for the
other chipsets is the contents of this CSR0 register important.
Change the chipset determination logic to be more aligned with the rt2800
model.
Preparation for the support of rt3070 / rt3090 based devices.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Gertjan van Wingerde authored and John W. Linville committed Feb 15, 2010
1 parent 714fa66 commit 49e721e
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 118 deletions.
9 changes: 2 additions & 7 deletions drivers/net/wireless/rt2x00/rt2400pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1327,7 +1327,6 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
u16 chip;
u16 value;
u16 eeprom;

Expand All @@ -1336,17 +1335,13 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);

/*
* Identify RT chipset.
*/
pci_read_config_word(to_pci_dev(rt2x00dev->dev), PCI_DEVICE_ID, &chip);

/*
* Identify RF chipset.
*/
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
rt2x00_set_chip(rt2x00dev, chip, value, reg);
rt2x00_set_chip(rt2x00dev, RT2460, value,
rt2x00_get_field32(reg, CSR0_REVISION));

if (!rt2x00_rf(rt2x00dev, RF2420) && !rt2x00_rf(rt2x00dev, RF2421)) {
ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/rt2x00/rt2400pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
* CSR0: ASIC revision number.
*/
#define CSR0 0x0000
#define CSR0_REVISION FIELD32(0x0000ffff)

/*
* CSR1: System control register.
Expand Down
9 changes: 2 additions & 7 deletions drivers/net/wireless/rt2x00/rt2500pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,6 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
u16 chip;
u16 value;
u16 eeprom;

Expand All @@ -1499,17 +1498,13 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);

/*
* Identify RT chipset.
*/
pci_read_config_word(to_pci_dev(rt2x00dev->dev), PCI_DEVICE_ID, &chip);

/*
* Identify RF chipset.
*/
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
rt2x00_set_chip(rt2x00dev, chip, value, reg);
rt2x00_set_chip(rt2x00dev, RT2560, value,
rt2x00_get_field32(reg, CSR0_REVISION));

if (!rt2x00_rf(rt2x00dev, RF2522) &&
!rt2x00_rf(rt2x00dev, RF2523) &&
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/rt2x00/rt2500pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
* CSR0: ASIC revision number.
*/
#define CSR0 0x0000
#define CSR0_REVISION FIELD32(0x0000ffff)

/*
* CSR1: System control register.
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/rt2x00/rt2500usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1409,8 +1409,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, RT2570, value, reg);

if (!rt2x00_check_rev(rt2x00dev, 0x000ffff0, 0) ||
rt2x00_check_rev(rt2x00dev, 0x0000000f, 0)) {
if (((reg & 0xfff0) != 0) || ((reg & 0x0000000f) == 0)) {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV;
}
Expand Down
14 changes: 7 additions & 7 deletions drivers/net/wireless/rt2x00/rt2800.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@
/*
* Chipset version.
*/
#define RT2860C_VERSION 0x28600100
#define RT2860D_VERSION 0x28600101
#define RT2880E_VERSION 0x28720200
#define RT2883_VERSION 0x28830300
#define RT3070_VERSION 0x30700200
#define RT2860C_VERSION 0x0100
#define RT2860D_VERSION 0x0101
#define RT2880E_VERSION 0x0200
#define RT2883_VERSION 0x0300
#define RT3070_VERSION 0x0200

/*
* Signal information.
Expand Down Expand Up @@ -408,8 +408,8 @@
* ASIC_VER: 2860 or 2870
*/
#define MAC_CSR0 0x1000
#define MAC_CSR0_ASIC_REV FIELD32(0x0000ffff)
#define MAC_CSR0_ASIC_VER FIELD32(0xffff0000)
#define MAC_CSR0_REVISION FIELD32(0x0000ffff)
#define MAC_CSR0_CHIPSET FIELD32(0xffff0000)

/*
* MAC_SYS_CTRL:
Expand Down
92 changes: 47 additions & 45 deletions drivers/net/wireless/rt2x00/rt2800lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
rt2800_bbp_write(rt2x00dev, 3, bbp);

if (rt2x00_rev(rt2x00dev) == RT2860C_VERSION) {
if (rt2x00_rt(rt2x00dev, RT2860) &&
(rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
if (conf_is_ht40(conf)) {
rt2800_bbp_write(rt2x00dev, 69, 0x1a);
rt2800_bbp_write(rt2x00dev, 70, 0x0a);
Expand Down Expand Up @@ -1061,7 +1062,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
{
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
if (rt2x00_is_usb(rt2x00dev) &&
rt2x00_rev(rt2x00dev) == RT3070_VERSION)
rt2x00_rt(rt2x00dev, RT3070) &&
(rt2x00_rev(rt2x00dev) == RT3070_VERSION))
return 0x1c + (2 * rt2x00dev->lna_gain);
else
return 0x2e + rt2x00dev->lna_gain;
Expand Down Expand Up @@ -1092,7 +1094,8 @@ EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
const u32 count)
{
if (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)
if (rt2x00_rt(rt2x00dev, RT2860) &&
(rt2x00_rev(rt2x00dev) == RT2860C_VERSION))
return;

/*
Expand Down Expand Up @@ -1178,7 +1181,8 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);

if (rt2x00_is_usb(rt2x00dev) &&
rt2x00_rev(rt2x00dev) == RT3070_VERSION) {
rt2x00_rt(rt2x00dev, RT3070) &&
(rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
Expand All @@ -1205,8 +1209,14 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)

rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
if (rt2x00_rev(rt2x00dev) >= RT2880E_VERSION &&
rt2x00_rev(rt2x00dev) < RT3070_VERSION)
if ((rt2x00_rt(rt2x00dev, RT2872) &&
(rt2x00_rev(rt2x00dev) >= RT2880E_VERSION)) ||
rt2x00_rt(rt2x00dev, RT2880) ||
rt2x00_rt(rt2x00dev, RT2883) ||
rt2x00_rt(rt2x00dev, RT2890) ||
rt2x00_rt(rt2x00dev, RT3052) ||
(rt2x00_rt(rt2x00dev, RT3070) &&
(rt2x00_rev(rt2x00dev) < RT3070_VERSION)))
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
else
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
Expand Down Expand Up @@ -1485,16 +1495,19 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 103, 0x00);
rt2800_bbp_write(rt2x00dev, 105, 0x05);

if (rt2x00_rev(rt2x00dev) == RT2860C_VERSION) {
if (rt2x00_rt(rt2x00dev, RT2860) &&
(rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
rt2800_bbp_write(rt2x00dev, 69, 0x16);
rt2800_bbp_write(rt2x00dev, 73, 0x12);
}

if (rt2x00_rev(rt2x00dev) > RT2860D_VERSION)
if (rt2x00_rt(rt2x00dev, RT2860) &&
(rt2x00_rev(rt2x00dev) > RT2860D_VERSION))
rt2800_bbp_write(rt2x00dev, 84, 0x19);

if (rt2x00_is_usb(rt2x00dev) &&
rt2x00_rev(rt2x00dev) == RT3070_VERSION) {
rt2x00_rt(rt2x00dev, RT3070) &&
(rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
rt2800_bbp_write(rt2x00dev, 70, 0x0a);
rt2800_bbp_write(rt2x00dev, 84, 0x99);
rt2800_bbp_write(rt2x00dev, 105, 0x05);
Expand Down Expand Up @@ -1586,7 +1599,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
u8 bbp;

if (rt2x00_is_usb(rt2x00dev) &&
rt2x00_rev(rt2x00dev) != RT3070_VERSION)
rt2x00_rt(rt2x00dev, RT3070) &&
(rt2x00_rev(rt2x00dev) != RT3070_VERSION))
return 0;

if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
Expand Down Expand Up @@ -1757,7 +1771,12 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
} else if (rt2x00_rev(rt2x00dev) < RT2883_VERSION) {
} else if (rt2x00_rt(rt2x00dev, RT2860) ||
rt2x00_rt(rt2x00dev, RT2870) ||
rt2x00_rt(rt2x00dev, RT2872) ||
rt2x00_rt(rt2x00dev, RT2880) ||
(rt2x00_rt(rt2x00dev, RT2883) &&
(rt2x00_rev(rt2x00dev) < RT2883_VERSION))) {
/*
* There is a max of 2 RX streams for RT28x0 series
*/
Expand Down Expand Up @@ -1842,7 +1861,6 @@ EXPORT_SYMBOL_GPL(rt2800_validate_eeprom);
int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
u16 chip;
u16 value;
u16 eeprom;

Expand All @@ -1857,41 +1875,25 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);

if (rt2x00_is_pci(rt2x00dev)) {
#if defined(CONFIG_RT2X00_LIB_PCI) || defined(CONFIG_RT2X00_LIB_PCI_MODULE)
pci_read_config_word(to_pci_dev(rt2x00dev->dev),
PCI_DEVICE_ID,
&chip);
#else
BUG();
#endif
} else if (rt2x00_is_usb(rt2x00dev)) {
/*
* The check for rt2860 is not a typo, some rt2870 hardware
* identifies itself as rt2860 in the CSR register.
*/
if (((reg & 0xfff00000) == 0x28600000) ||
((reg & 0xfff00000) == 0x28700000) ||
((reg & 0xfff00000) == 0x28800000)) {
chip = RT2870;
} else if ((reg & 0xffff0000) == 0x30700000) {
chip = RT3070;
} else {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV;
}
} else if (rt2x00_is_soc(rt2x00dev)) {
#if defined(CONFIG_RALINK_RT288X)
chip = RT2880;
#elif defined(CONFIG_RALINK_RT305X)
chip = RT3052;
#else
BUG();
#endif
rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));

if (!rt2x00_rt(rt2x00dev, RT2860) &&
!rt2x00_rt(rt2x00dev, RT2870) &&
!rt2x00_rt(rt2x00dev, RT2872) &&
!rt2x00_rt(rt2x00dev, RT2880) &&
!rt2x00_rt(rt2x00dev, RT2883) &&
!rt2x00_rt(rt2x00dev, RT2890) &&
!rt2x00_rt(rt2x00dev, RT3052) &&
!rt2x00_rt(rt2x00dev, RT3070) &&
!rt2x00_rt(rt2x00dev, RT3071) &&
!rt2x00_rt(rt2x00dev, RT3090) &&
!rt2x00_rt(rt2x00dev, RT3390) &&
!rt2x00_rt(rt2x00dev, RT3572)) {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV;
}

rt2x00_set_chip(rt2x00dev, chip, value, reg);

if (!rt2x00_rf(rt2x00dev, RF2820) &&
!rt2x00_rf(rt2x00dev, RF2850) &&
!rt2x00_rf(rt2x00dev, RF2720) &&
Expand Down
20 changes: 9 additions & 11 deletions drivers/net/wireless/rt2x00/rt2800usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ static bool rt2800usb_check_crc(const u8 *data, const size_t len)
static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len)
{
u16 chipset = (rt2x00_rev(rt2x00dev) >> 16) & 0xffff;
size_t offset = 0;

/*
Expand All @@ -111,9 +110,9 @@ static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
* Check if we need the upper 4kb firmware data or not.
*/
if ((len == 4096) &&
(chipset != 0x2860) &&
(chipset != 0x2872) &&
(chipset != 0x3070))
!rt2x00_rt(rt2x00dev, RT2860) &&
!rt2x00_rt(rt2x00dev, RT2872) &&
!rt2x00_rt(rt2x00dev, RT3070))
return FW_BAD_VERSION;

/*
Expand All @@ -138,14 +137,13 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
u32 reg;
u32 offset;
u32 length;
u16 chipset = (rt2x00_rev(rt2x00dev) >> 16) & 0xffff;

/*
* Check which section of the firmware we need.
*/
if ((chipset == 0x2860) ||
(chipset == 0x2872) ||
(chipset == 0x3070)) {
if (rt2x00_rt(rt2x00dev, RT2860) ||
rt2x00_rt(rt2x00dev, RT2872) ||
rt2x00_rt(rt2x00dev, RT3070)) {
offset = 0;
length = 4096;
} else {
Expand Down Expand Up @@ -200,9 +198,9 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
*/
rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);

if ((chipset == 0x3070) ||
(chipset == 0x3071) ||
(chipset == 0x3572)) {
if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3572)) {
udelay(200);
rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
udelay(10);
Expand Down
Loading

0 comments on commit 49e721e

Please sign in to comment.