summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h26
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h18
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h26
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h52
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c330
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h22
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c73
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c65
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h27
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h31
17 files changed, 516 insertions, 220 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 8b9dbd76a252..6458ab87717b 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -205,7 +205,7 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
u32 reg;
rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
- return rt2x00_get_field32(reg, GPIOCSR_BIT0);
+ return rt2x00_get_field32(reg, GPIOCSR_VAL0);
}
#ifdef CONFIG_RT2X00_LIB_LEDS
@@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
+ u32 reg;
/*
* Allocate eeprom data.
@@ -1624,6 +1625,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
return retval;
/*
+ * Enable rfkill polling by setting GPIO direction of the
+ * rfkill switch GPIO pin correctly.
+ */
+ rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
+ rt2x00_set_field32(&reg, GPIOCSR_DIR0, 1);
+ rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg);
+
+ /*
* Initialize hw specifications.
*/
retval = rt2400pci_probe_hw_mode(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index d3a4a68cc439..e4b07f0aa3cc 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -660,16 +660,26 @@
/*
* GPIOCSR: GPIO control register.
+ * GPIOCSR_VALx: Actual GPIO pin x value
+ * GPIOCSR_DIRx: GPIO direction: 0 = output; 1 = input
*/
#define GPIOCSR 0x0120
-#define GPIOCSR_BIT0 FIELD32(0x00000001)
-#define GPIOCSR_BIT1 FIELD32(0x00000002)
-#define GPIOCSR_BIT2 FIELD32(0x00000004)
-#define GPIOCSR_BIT3 FIELD32(0x00000008)
-#define GPIOCSR_BIT4 FIELD32(0x00000010)
-#define GPIOCSR_BIT5 FIELD32(0x00000020)
-#define GPIOCSR_BIT6 FIELD32(0x00000040)
-#define GPIOCSR_BIT7 FIELD32(0x00000080)
+#define GPIOCSR_VAL0 FIELD32(0x00000001)
+#define GPIOCSR_VAL1 FIELD32(0x00000002)
+#define GPIOCSR_VAL2 FIELD32(0x00000004)
+#define GPIOCSR_VAL3 FIELD32(0x00000008)
+#define GPIOCSR_VAL4 FIELD32(0x00000010)
+#define GPIOCSR_VAL5 FIELD32(0x00000020)
+#define GPIOCSR_VAL6 FIELD32(0x00000040)
+#define GPIOCSR_VAL7 FIELD32(0x00000080)
+#define GPIOCSR_DIR0 FIELD32(0x00000100)
+#define GPIOCSR_DIR1 FIELD32(0x00000200)
+#define GPIOCSR_DIR2 FIELD32(0x00000400)
+#define GPIOCSR_DIR3 FIELD32(0x00000800)
+#define GPIOCSR_DIR4 FIELD32(0x00001000)
+#define GPIOCSR_DIR5 FIELD32(0x00002000)
+#define GPIOCSR_DIR6 FIELD32(0x00004000)
+#define GPIOCSR_DIR7 FIELD32(0x00008000)
/*
* BBPPCSR: BBP Pin control register.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index d2cf8a4bc8b5..68bca1456cda 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -205,7 +205,7 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
u32 reg;
rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
- return rt2x00_get_field32(reg, GPIOCSR_BIT0);
+ return rt2x00_get_field32(reg, GPIOCSR_VAL0);
}
#ifdef CONFIG_RT2X00_LIB_LEDS
@@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
+ u32 reg;
/*
* Allocate eeprom data.
@@ -1942,6 +1943,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
return retval;
/*
+ * Enable rfkill polling by setting GPIO direction of the
+ * rfkill switch GPIO pin correctly.
+ */
+ rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
+ rt2x00_set_field32(&reg, GPIOCSR_DIR0, 1);
+ rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg);
+
+ /*
* Initialize hw specifications.
*/
retval = rt2500pci_probe_hw_mode(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index 2aad7ba8a100..9c10068e4987 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -789,16 +789,18 @@
/*
* GPIOCSR: GPIO control register.
+ * GPIOCSR_VALx: GPIO value
+ * GPIOCSR_DIRx: GPIO direction: 0 = output; 1 = input
*/
#define GPIOCSR 0x0120
-#define GPIOCSR_BIT0 FIELD32(0x00000001)
-#define GPIOCSR_BIT1 FIELD32(0x00000002)
-#define GPIOCSR_BIT2 FIELD32(0x00000004)
-#define GPIOCSR_BIT3 FIELD32(0x00000008)
-#define GPIOCSR_BIT4 FIELD32(0x00000010)
-#define GPIOCSR_BIT5 FIELD32(0x00000020)
-#define GPIOCSR_BIT6 FIELD32(0x00000040)
-#define GPIOCSR_BIT7 FIELD32(0x00000080)
+#define GPIOCSR_VAL0 FIELD32(0x00000001)
+#define GPIOCSR_VAL1 FIELD32(0x00000002)
+#define GPIOCSR_VAL2 FIELD32(0x00000004)
+#define GPIOCSR_VAL3 FIELD32(0x00000008)
+#define GPIOCSR_VAL4 FIELD32(0x00000010)
+#define GPIOCSR_VAL5 FIELD32(0x00000020)
+#define GPIOCSR_VAL6 FIELD32(0x00000040)
+#define GPIOCSR_VAL7 FIELD32(0x00000080)
#define GPIOCSR_DIR0 FIELD32(0x00000100)
#define GPIOCSR_DIR1 FIELD32(0x00000200)
#define GPIOCSR_DIR2 FIELD32(0x00000400)
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 3aae36bb0a9e..f95b5516c50a 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
u16 reg;
rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
- return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
+ return rt2x00_get_field16(reg, MAC_CSR19_VAL7);
}
#ifdef CONFIG_RT2X00_LIB_LEDS
@@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
+ u16 reg;
/*
* Allocate eeprom data.
@@ -1781,6 +1782,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
return retval;
/*
+ * Enable rfkill polling by setting GPIO direction of the
+ * rfkill switch GPIO pin correctly.
+ */
+ rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
+ rt2x00_set_field16(&reg, MAC_CSR19_DIR0, 0);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg);
+
+ /*
* Initialize hw specifications.
*/
retval = rt2500usb_probe_hw_mode(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index b493306a7eed..1b91a4cef965 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -187,16 +187,26 @@
/*
* MAC_CSR19: GPIO control register.
+ * MAC_CSR19_VALx: GPIO value
+ * MAC_CSR19_DIRx: GPIO direction: 0 = input; 1 = output
*/
#define MAC_CSR19 0x0426
-#define MAC_CSR19_BIT0 FIELD32(0x0001)
-#define MAC_CSR19_BIT1 FIELD32(0x0002)
-#define MAC_CSR19_BIT2 FIELD32(0x0004)
-#define MAC_CSR19_BIT3 FIELD32(0x0008)
-#define MAC_CSR19_BIT4 FIELD32(0x0010)
-#define MAC_CSR19_BIT5 FIELD32(0x0020)
-#define MAC_CSR19_BIT6 FIELD32(0x0040)
-#define MAC_CSR19_BIT7 FIELD32(0x0080)
+#define MAC_CSR19_VAL0 FIELD16(0x0001)
+#define MAC_CSR19_VAL1 FIELD16(0x0002)
+#define MAC_CSR19_VAL2 FIELD16(0x0004)
+#define MAC_CSR19_VAL3 FIELD16(0x0008)
+#define MAC_CSR19_VAL4 FIELD16(0x0010)
+#define MAC_CSR19_VAL5 FIELD16(0x0020)
+#define MAC_CSR19_VAL6 FIELD16(0x0040)
+#define MAC_CSR19_VAL7 FIELD16(0x0080)
+#define MAC_CSR19_DIR0 FIELD16(0x0100)
+#define MAC_CSR19_DIR1 FIELD16(0x0200)
+#define MAC_CSR19_DIR2 FIELD16(0x0400)
+#define MAC_CSR19_DIR3 FIELD16(0x0800)
+#define MAC_CSR19_DIR4 FIELD16(0x1000)
+#define MAC_CSR19_DIR5 FIELD16(0x2000)
+#define MAC_CSR19_DIR6 FIELD16(0x4000)
+#define MAC_CSR19_DIR7 FIELD16(0x8000)
/*
* MAC_CSR20: LED control register.
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index e252e9bafd0e..6d67c3ede651 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -439,26 +439,33 @@
#define WMM_TXOP1_CFG_AC3TXOP FIELD32(0xffff0000)
/*
- * GPIO_CTRL_CFG:
- * GPIOD: GPIO direction, 0: Output, 1: Input
- */
-#define GPIO_CTRL_CFG 0x0228
-#define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001)
-#define GPIO_CTRL_CFG_BIT1 FIELD32(0x00000002)
-#define GPIO_CTRL_CFG_BIT2 FIELD32(0x00000004)
-#define GPIO_CTRL_CFG_BIT3 FIELD32(0x00000008)
-#define GPIO_CTRL_CFG_BIT4 FIELD32(0x00000010)
-#define GPIO_CTRL_CFG_BIT5 FIELD32(0x00000020)
-#define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040)
-#define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080)
-#define GPIO_CTRL_CFG_GPIOD_BIT0 FIELD32(0x00000100)
-#define GPIO_CTRL_CFG_GPIOD_BIT1 FIELD32(0x00000200)
-#define GPIO_CTRL_CFG_GPIOD_BIT2 FIELD32(0x00000400)
-#define GPIO_CTRL_CFG_GPIOD_BIT3 FIELD32(0x00000800)
-#define GPIO_CTRL_CFG_GPIOD_BIT4 FIELD32(0x00001000)
-#define GPIO_CTRL_CFG_GPIOD_BIT5 FIELD32(0x00002000)
-#define GPIO_CTRL_CFG_GPIOD_BIT6 FIELD32(0x00004000)
-#define GPIO_CTRL_CFG_GPIOD_BIT7 FIELD32(0x00008000)
+ * GPIO_CTRL:
+ * GPIO_CTRL_VALx: GPIO value
+ * GPIO_CTRL_DIRx: GPIO direction: 0 = output; 1 = input
+ */
+#define GPIO_CTRL 0x0228
+#define GPIO_CTRL_VAL0 FIELD32(0x00000001)
+#define GPIO_CTRL_VAL1 FIELD32(0x00000002)
+#define GPIO_CTRL_VAL2 FIELD32(0x00000004)
+#define GPIO_CTRL_VAL3 FIELD32(0x00000008)
+#define GPIO_CTRL_VAL4 FIELD32(0x00000010)
+#define GPIO_CTRL_VAL5 FIELD32(0x00000020)
+#define GPIO_CTRL_VAL6 FIELD32(0x00000040)
+#define GPIO_CTRL_VAL7 FIELD32(0x00000080)
+#define GPIO_CTRL_DIR0 FIELD32(0x00000100)
+#define GPIO_CTRL_DIR1 FIELD32(0x00000200)
+#define GPIO_CTRL_DIR2 FIELD32(0x00000400)
+#define GPIO_CTRL_DIR3 FIELD32(0x00000800)
+#define GPIO_CTRL_DIR4 FIELD32(0x00001000)
+#define GPIO_CTRL_DIR5 FIELD32(0x00002000)
+#define GPIO_CTRL_DIR6 FIELD32(0x00004000)
+#define GPIO_CTRL_DIR7 FIELD32(0x00008000)
+#define GPIO_CTRL_VAL8 FIELD32(0x00010000)
+#define GPIO_CTRL_VAL9 FIELD32(0x00020000)
+#define GPIO_CTRL_VAL10 FIELD32(0x00040000)
+#define GPIO_CTRL_DIR8 FIELD32(0x01000000)
+#define GPIO_CTRL_DIR9 FIELD32(0x02000000)
+#define GPIO_CTRL_DIR10 FIELD32(0x04000000)
/*
* MCU_CMD_CFG
@@ -1936,6 +1943,11 @@ struct mac_iveiv_entry {
#define BBP47_TSSI_ADC6 FIELD8(0x80)
/*
+ * BBP 49
+ */
+#define BBP49_UPDATE_FLAG FIELD8(0x01)
+
+/*
* BBP 109
*/
#define BBP109_TX0_POWER FIELD8(0x0f)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index cb8c2aca54e4..9e09367c9739 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -923,8 +923,8 @@ int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev)
rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
return rt2x00_get_field32(reg, WLAN_GPIO_IN_BIT0);
} else {
- rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
- return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
+ rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
+ return rt2x00_get_field32(reg, GPIO_CTRL_VAL2);
}
}
EXPORT_SYMBOL_GPL(rt2800_rfkill_poll);
@@ -1570,10 +1570,10 @@ static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev,
rt2800_mcu_request(rt2x00dev, MCU_ANT_SELECT, 0xff,
eesk_pin, 0);
- rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT3, 0);
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT3, gpio_bit3);
- rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+ rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
+ rt2x00_set_field32(&reg, GPIO_CTRL_DIR3, 0);
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, gpio_bit3);
+ rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
}
void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
@@ -1615,6 +1615,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
case 1:
if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT3390)) {
rt2x00_eeprom_read(rt2x00dev,
EEPROM_NIC_CONF1, &eeprom);
@@ -1995,13 +1996,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 29, 0x9f);
}
- rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT7, 0);
+ rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
+ rt2x00_set_field32(&reg, GPIO_CTRL_DIR7, 0);
if (rf->channel <= 14)
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT7, 1);
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL7, 1);
else
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT7, 0);
- rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL7, 0);
+ rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
@@ -2053,6 +2054,60 @@ static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
}
}
+static void rt2800_config_channel_rf3322(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_write(rt2x00dev, 11, 0x42);
+ rt2800_rfcsr_write(rt2x00dev, 12, 0x1c);
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
+
+ if (info->default_power1 > POWER_BOUND)
+ rt2800_rfcsr_write(rt2x00dev, 47, POWER_BOUND);
+ else
+ rt2800_rfcsr_write(rt2x00dev, 47, info->default_power1);
+
+ if (info->default_power2 > POWER_BOUND)
+ rt2800_rfcsr_write(rt2x00dev, 48, POWER_BOUND);
+ else
+ rt2800_rfcsr_write(rt2x00dev, 48, info->default_power2);
+
+ 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);
+
+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
+
+ if ( rt2x00dev->default_ant.tx_chain_num == 2 )
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+
+ if ( rt2x00dev->default_ant.rx_chain_num == 2 )
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
+
+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+ rt2800_rfcsr_write(rt2x00dev, 31, 80);
+}
+
static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
struct rf_channel *rf,
@@ -2182,6 +2237,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
case RF3290:
rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
break;
+ case RF3322:
+ rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
+ break;
case RF5360:
case RF5370:
case RF5372:
@@ -2194,6 +2252,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
}
if (rt2x00_rf(rt2x00dev, RF3290) ||
+ rt2x00_rf(rt2x00dev, RF3322) ||
rt2x00_rf(rt2x00dev, RF5360) ||
rt2x00_rf(rt2x00dev, RF5370) ||
rt2x00_rf(rt2x00dev, RF5372) ||
@@ -2212,10 +2271,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
/*
* Change BBP settings
*/
- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 86, 0);
+ if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_bbp_write(rt2x00dev, 27, 0x0);
+ rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 27, 0x20);
+ rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
+ } else {
+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 86, 0);
+ }
if (rf->channel <= 14) {
if (!rt2x00_rt(rt2x00dev, RT5390) &&
@@ -2310,6 +2376,15 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2800_register_read(rt2x00dev, CH_IDLE_STA, &reg);
rt2800_register_read(rt2x00dev, CH_BUSY_STA, &reg);
rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
+
+ /*
+ * Clear update flag
+ */
+ if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_bbp_read(rt2x00dev, 49, &bbp);
+ rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
+ rt2800_bbp_write(rt2x00dev, 49, bbp);
+ }
}
static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
@@ -2998,6 +3073,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030);
+ } else if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
} else if (rt2x00_rt(rt2x00dev, RT3572)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -3378,6 +3457,11 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_wait_bbp_ready(rt2x00dev)))
return -EACCES;
+ if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_bbp_write(rt2x00dev, 3, 0x00);
+ rt2800_bbp_write(rt2x00dev, 4, 0x50);
+ }
+
if (rt2x00_rt(rt2x00dev, RT3290) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392)) {
@@ -3388,15 +3472,20 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
if (rt2800_is_305x_soc(rt2x00dev) ||
rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT3572) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 31, 0x08);
+ if (rt2x00_rt(rt2x00dev, RT3352))
+ rt2800_bbp_write(rt2x00dev, 47, 0x48);
+
rt2800_bbp_write(rt2x00dev, 65, 0x2c);
rt2800_bbp_write(rt2x00dev, 66, 0x38);
if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 68, 0x0b);
@@ -3405,6 +3494,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 69, 0x16);
rt2800_bbp_write(rt2x00dev, 73, 0x12);
} else if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392)) {
rt2800_bbp_write(rt2x00dev, 69, 0x12);
@@ -3436,6 +3526,10 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
} else if (rt2800_is_305x_soc(rt2x00dev)) {
rt2800_bbp_write(rt2x00dev, 78, 0x0e);
rt2800_bbp_write(rt2x00dev, 80, 0x08);
+ } else if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_bbp_write(rt2x00dev, 78, 0x0e);
+ rt2800_bbp_write(rt2x00dev, 80, 0x08);
+ rt2800_bbp_write(rt2x00dev, 81, 0x37);
} else {
rt2800_bbp_write(rt2x00dev, 81, 0x37);
}
@@ -3465,18 +3559,21 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 84, 0x99);
if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 86, 0x38);
else
rt2800_bbp_write(rt2x00dev, 86, 0x00);
- if (rt2x00_rt(rt2x00dev, RT5392))
+ if (rt2x00_rt(rt2x00dev, RT3352) ||
+ rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 88, 0x90);
rt2800_bbp_write(rt2x00dev, 91, 0x04);
if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 92, 0x02);
@@ -3493,6 +3590,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT3572) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392) ||
@@ -3502,6 +3600,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 103, 0x00);
if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 104, 0x92);
@@ -3510,6 +3609,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 105, 0x01);
else if (rt2x00_rt(rt2x00dev, RT3290))
rt2800_bbp_write(rt2x00dev, 105, 0x1c);
+ else if (rt2x00_rt(rt2x00dev, RT3352))
+ rt2800_bbp_write(rt2x00dev, 105, 0x34);
else if (rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 105, 0x3c);
@@ -3519,11 +3620,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt(rt2x00dev, RT3290) ||
rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 106, 0x03);
+ else if (rt2x00_rt(rt2x00dev, RT3352))
+ rt2800_bbp_write(rt2x00dev, 106, 0x05);
else if (rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 106, 0x12);
else
rt2800_bbp_write(rt2x00dev, 106, 0x35);
+ if (rt2x00_rt(rt2x00dev, RT3352))
+ rt2800_bbp_write(rt2x00dev, 120, 0x50);
+
if (rt2x00_rt(rt2x00dev, RT3290) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
@@ -3534,6 +3640,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 135, 0xf6);
}
+ if (rt2x00_rt(rt2x00dev, RT3352))
+ rt2800_bbp_write(rt2x00dev, 137, 0x0f);
+
if (rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3090) ||
rt2x00_rt(rt2x00dev, RT3390) ||
@@ -3574,6 +3683,28 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 3, value);
}
+ if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_bbp_write(rt2x00dev, 163, 0xbd);
+ /* Set ITxBF timeout to 0x9c40=1000msec */
+ rt2800_bbp_write(rt2x00dev, 179, 0x02);
+ rt2800_bbp_write(rt2x00dev, 180, 0x00);
+ rt2800_bbp_write(rt2x00dev, 182, 0x40);
+ rt2800_bbp_write(rt2x00dev, 180, 0x01);
+ rt2800_bbp_write(rt2x00dev, 182, 0x9c);
+ rt2800_bbp_write(rt2x00dev, 179, 0x00);
+ /* Reprogram the inband interface to put right values in RXWI */
+ rt2800_bbp_write(rt2x00dev, 142, 0x04);
+ rt2800_bbp_write(rt2x00dev, 143, 0x3b);
+ rt2800_bbp_write(rt2x00dev, 142, 0x06);
+ rt2800_bbp_write(rt2x00dev, 143, 0xa0);
+ rt2800_bbp_write(rt2x00dev, 142, 0x07);
+ rt2800_bbp_write(rt2x00dev, 143, 0xa1);
+ rt2800_bbp_write(rt2x00dev, 142, 0x08);
+ rt2800_bbp_write(rt2x00dev, 143, 0xa2);
+
+ rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+ }
+
if (rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392)) {
int ant, div_mode;
@@ -3587,16 +3718,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
u32 reg;
- rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT3, 0);
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT6, 0);
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT3, 0);
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT6, 0);
+ rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
+ rt2x00_set_field32(&reg, GPIO_CTRL_DIR3, 0);
+ rt2x00_set_field32(&reg, GPIO_CTRL_DIR6, 0);
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 0);
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 0);
if (ant == 0)
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT3, 1);
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 1);
else if (ant == 1)
- rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT6, 1);
- rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 1);
+ rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
}
/* This chip has hardware antenna diversity*/
@@ -3707,6 +3838,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
!rt2x00_rt(rt2x00dev, RT3071) &&
!rt2x00_rt(rt2x00dev, RT3090) &&
!rt2x00_rt(rt2x00dev, RT3290) &&
+ !rt2x00_rt(rt2x00dev, RT3352) &&
!rt2x00_rt(rt2x00dev, RT3390) &&
!rt2x00_rt(rt2x00dev, RT3572) &&
!rt2x00_rt(rt2x00dev, RT5390) &&
@@ -3903,6 +4035,70 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
return 0;
+ } else if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
+ rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
+ rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
+ rt2800_rfcsr_write(rt2x00dev, 3, 0x18);
+ rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 6, 0x33);
+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
+ rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
+ rt2800_rfcsr_write(rt2x00dev, 10, 0xd2);
+ rt2800_rfcsr_write(rt2x00dev, 11, 0x42);
+ rt2800_rfcsr_write(rt2x00dev, 12, 0x1c);
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 14, 0x5a);
+ rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 16, 0x01);
+ rt2800_rfcsr_write(rt2x00dev, 18, 0x45);
+ rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
+ rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
+ rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
+ rt2800_rfcsr_write(rt2x00dev, 28, 0x03);
+ rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
+ 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, 0x01);
+ rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
+ rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
+ rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
+ rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
+ rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
+ rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
+ rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
+ rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
+ rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
+ rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
+ rt2800_rfcsr_write(rt2x00dev, 46, 0xdd);
+ rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
+ rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
+ rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
+ rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
+ rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
+ rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
+ rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
+ rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
+ rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
+ rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
} else if (rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
@@ -4089,6 +4285,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
msleep(1);
rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+ rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
}
@@ -4103,6 +4300,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
} else if (rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT3390) ||
rt2x00_rt(rt2x00dev, RT3572)) {
drv_data->calibration_bw20 =
@@ -4391,7 +4589,7 @@ void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
}
EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
-int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
{
struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
u16 word;
@@ -4399,6 +4597,11 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
u8 default_lna_gain;
/*
+ * Read the EEPROM.
+ */
+ rt2800_read_eeprom(rt2x00dev);
+
+ /*
* Start validation of the data that has been read.
*/
mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
@@ -4520,9 +4723,8 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_validate_eeprom);
-int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
+static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
u16 value;
@@ -4561,6 +4763,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
case RT3071:
case RT3090:
case RT3290:
+ case RT3352:
case RT3390:
case RT3572:
case RT5390:
@@ -4583,6 +4786,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
case RF3052:
case RF3290:
case RF3320:
+ case RF3322:
case RF5360:
case RF5370:
case RF5372:
@@ -4607,6 +4811,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT3390)) {
value = rt2x00_get_field16(eeprom,
EEPROM_NIC_CONF1_ANT_DIVERSITY);
@@ -4680,7 +4885,6 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_init_eeprom);
/*
* RF value list for rt28xx
@@ -4823,7 +5027,7 @@ static const struct rf_channel rf_vals_3x[] = {
{173, 0x61, 0, 9},
};
-int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
{
struct hw_mode_spec *spec = &rt2x00dev->spec;
struct channel_info *info;
@@ -4900,6 +5104,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00_rf(rt2x00dev, RF3022) ||
rt2x00_rf(rt2x00dev, RF3290) ||
rt2x00_rf(rt2x00dev, RF3320) ||
+ rt2x00_rf(rt2x00dev, RF3322) ||
rt2x00_rf(rt2x00dev, RF5360) ||
rt2x00_rf(rt2x00dev, RF5370) ||
rt2x00_rf(rt2x00dev, RF5372) ||
@@ -4999,7 +5204,72 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_probe_hw_mode);
+
+int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
+{
+ int retval;
+ u32 reg;
+
+ /*
+ * Allocate eeprom data.
+ */
+ retval = rt2800_validate_eeprom(rt2x00dev);
+ if (retval)
+ return retval;
+
+ retval = rt2800_init_eeprom(rt2x00dev);
+ if (retval)
+ return retval;
+
+ /*
+ * Enable rfkill polling by setting GPIO direction of the
+ * rfkill switch GPIO pin correctly.
+ */
+ rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
+ rt2x00_set_field32(&reg, GPIO_CTRL_DIR2, 1);
+ rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
+
+ /*
+ * Initialize hw specifications.
+ */
+ retval = rt2800_probe_hw_mode(rt2x00dev);
+ if (retval)
+ return retval;
+
+ /*
+ * Set device capabilities.
+ */
+ __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
+ if (!rt2x00_is_usb(rt2x00dev))
+ __set_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags);
+
+ /*
+ * Set device requirements.
+ */
+ if (!rt2x00_is_soc(rt2x00dev))
+ __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
+ if (!rt2800_hwcrypt_disabled(rt2x00dev))
+ __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+ __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
+ if (rt2x00_is_usb(rt2x00dev))
+ __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
+ else {
+ __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
+ }
+
+ /*
+ * Set the rssi offset.
+ */
+ rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_probe_hw);
/*
* IEEE80211 stack callback functions.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 18a0b67b4c68..a128ceadcb3e 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -43,6 +43,9 @@ struct rt2800_ops {
const unsigned int offset,
const struct rt2x00_field32 field, u32 *reg);
+ void (*read_eeprom)(struct rt2x00_dev *rt2x00dev);
+ bool (*hwcrypt_disabled)(struct rt2x00_dev *rt2x00dev);
+
int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
@@ -114,6 +117,20 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev,
return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg);
}
+static inline void rt2800_read_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+
+ rt2800ops->read_eeprom(rt2x00dev);
+}
+
+static inline bool rt2800_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
+{
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+
+ return rt2800ops->hwcrypt_disabled(rt2x00dev);
+}
+
static inline int rt2800_drv_write_firmware(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len)
{
@@ -191,9 +208,8 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
-int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev);
-int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev);
-int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev);
+
+int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev);
void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32,
u16 *iv16);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 98aa426a3564..391e08fa054b 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -54,6 +54,11 @@ static bool modparam_nohwcrypt = false;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+static bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
+{
+ return modparam_nohwcrypt;
+}
+
static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
{
unsigned int i;
@@ -965,76 +970,14 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
/*
* Device probe functions.
*/
-static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+static void rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
{
- /*
- * Read EEPROM into buffer
- */
if (rt2x00_is_soc(rt2x00dev))
rt2800pci_read_eeprom_soc(rt2x00dev);
else if (rt2800pci_efuse_detect(rt2x00dev))
rt2800pci_read_eeprom_efuse(rt2x00dev);
else
rt2800pci_read_eeprom_pci(rt2x00dev);
-
- return rt2800_validate_eeprom(rt2x00dev);
-}
-
-static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
-{
- int retval;
-
- /*
- * Allocate eeprom data.
- */
- retval = rt2800pci_validate_eeprom(rt2x00dev);
- if (retval)
- return retval;
-
- retval = rt2800_init_eeprom(rt2x00dev);
- if (retval)
- return retval;
-
- /*
- * Initialize hw specifications.
- */
- retval = rt2800_probe_hw_mode(rt2x00dev);
- if (retval)
- return retval;
-
- /*
- * This device has multiple filters for control frames
- * and has a separate filter for PS Poll frames.
- */
- __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
- __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
-
- /*
- * This device has a pre tbtt interrupt and thus fetches
- * a new beacon directly prior to transmission.
- */
- __set_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags);
-
- /*
- * This device requires firmware.
- */
- if (!rt2x00_is_soc(rt2x00dev))
- __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
- if (!modparam_nohwcrypt)
- __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
- __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
-
- /*
- * Set the rssi offset.
- */
- rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
-
- return 0;
}
static const struct ieee80211_ops rt2800pci_mac80211_ops = {
@@ -1072,6 +1015,8 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
.register_multiread = rt2x00pci_register_multiread,
.register_multiwrite = rt2x00pci_register_multiwrite,
.regbusy_read = rt2x00pci_regbusy_read,
+ .read_eeprom = rt2800pci_read_eeprom,
+ .hwcrypt_disabled = rt2800pci_hwcrypt_disabled,
.drv_write_firmware = rt2800pci_write_firmware,
.drv_init_registers = rt2800pci_init_registers,
.drv_get_txwi = rt2800pci_get_txwi,
@@ -1084,7 +1029,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
.tbtt_tasklet = rt2800pci_tbtt_tasklet,
.rxdone_tasklet = rt2800pci_rxdone_tasklet,
.autowake_tasklet = rt2800pci_autowake_tasklet,
- .probe_hw = rt2800pci_probe_hw,
+ .probe_hw = rt2800_probe_hw,
.get_firmware_name = rt2800pci_get_firmware_name,
.check_firmware = rt2800_check_firmware,
.load_firmware = rt2800_load_firmware,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 6cf336595e25..603b65d6f28b 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -49,6 +49,11 @@ static bool modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+static bool rt2800usb_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
+{
+ return modparam_nohwcrypt;
+}
+
/*
* Queue handlers.
*/
@@ -667,8 +672,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
skb_pull(entry->skb, RXINFO_DESC_SIZE);
/*
- * FIXME: we need to check for rx_pkt_len validity
+ * Check for rx_pkt_len validity. Return if invalid, leaving
+ * rxdesc->size zeroed out by the upper level.
*/
+ if (unlikely(rx_pkt_len == 0 ||
+ rx_pkt_len > entry->queue->data_size)) {
+ ERROR(entry->queue->rt2x00dev,
+ "Bad frame size %d, forcing to 0\n", rx_pkt_len);
+ return;
+ }
+
rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
/*
@@ -722,64 +735,27 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
/*
* Device probe functions.
*/
-static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+static void rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
{
if (rt2800_efuse_detect(rt2x00dev))
rt2800_read_eeprom_efuse(rt2x00dev);
else
rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
EEPROM_SIZE);
-
- return rt2800_validate_eeprom(rt2x00dev);
}
static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
- /*
- * Allocate eeprom data.
- */
- retval = rt2800usb_validate_eeprom(rt2x00dev);
- if (retval)
- return retval;
-
- retval = rt2800_init_eeprom(rt2x00dev);
+ retval = rt2800_probe_hw(rt2x00dev);
if (retval)
return retval;
/*
- * Initialize hw specifications.
+ * Set txstatus timer function.
*/
- retval = rt2800_probe_hw_mode(rt2x00dev);
- if (retval)
- return retval;
-
- /*
- * This device has multiple filters for control frames
- * and has a separate filter for PS Poll frames.
- */
- __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
- __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
-
- /*
- * This device requires firmware.
- */
- __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
- if (!modparam_nohwcrypt)
- __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
- __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
- __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
-
- rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout,
-
- /*
- * Set the rssi offset.
- */
- rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
+ rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout;
/*
* Overwrite TX done handler
@@ -825,6 +801,8 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = {
.register_multiread = rt2x00usb_register_multiread,
.register_multiwrite = rt2x00usb_register_multiwrite,
.regbusy_read = rt2x00usb_regbusy_read,
+ .read_eeprom = rt2800usb_read_eeprom,
+ .hwcrypt_disabled = rt2800usb_hwcrypt_disabled,
.drv_write_firmware = rt2800usb_write_firmware,
.drv_init_registers = rt2800usb_init_registers,
.drv_get_txwi = rt2800usb_get_txwi,
@@ -1157,6 +1135,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x1690, 0x0744) },
{ USB_DEVICE(0x1690, 0x0761) },
{ USB_DEVICE(0x1690, 0x0764) },
+ /* ASUS */
+ { USB_DEVICE(0x0b05, 0x179d) },
/* Cisco */
{ USB_DEVICE(0x167b, 0x4001) },
/* EnGenius */
@@ -1222,7 +1202,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0b05, 0x1760) },
{ USB_DEVICE(0x0b05, 0x1761) },
{ USB_DEVICE(0x0b05, 0x1790) },
- { USB_DEVICE(0x0b05, 0x179d) },
/* AzureWave */
{ USB_DEVICE(0x13d3, 0x3262) },
{ USB_DEVICE(0x13d3, 0x3284) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index f991e8bedc70..49375c86c334 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -188,6 +188,7 @@ struct rt2x00_chip {
#define RT3071 0x3071
#define RT3090 0x3090 /* 2.4GHz PCIe */
#define RT3290 0x3290
+#define RT3352 0x3352 /* WSOC */
#define RT3390 0x3390
#define RT3572 0x3572
#define RT3593 0x3593
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index a59048ffa092..10cf67267775 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
*/
if (unlikely(rxdesc.size == 0 ||
rxdesc.size > entry->queue->data_size)) {
- WARNING(rt2x00dev, "Wrong frame size %d max %d.\n",
+ ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",
rxdesc.size, entry->queue->data_size);
dev_kfree_skb(entry->skb);
goto renew_skb;
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 3f7bc5cadf9a..2673e058caaf 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -243,7 +243,7 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
u32 reg;
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
- return rt2x00_get_field32(reg, MAC_CSR13_BIT5);
+ return rt2x00_get_field32(reg, MAC_CSR13_VAL5);
}
#ifdef CONFIG_RT2X00_LIB_LEDS
@@ -715,11 +715,11 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
- rt2x00_set_field32(&reg, MAC_CSR13_BIT4, p1);
- rt2x00_set_field32(&reg, MAC_CSR13_BIT12, 0);
+ rt2x00_set_field32(&reg, MAC_CSR13_DIR4, 0);
+ rt2x00_set_field32(&reg, MAC_CSR13_VAL4, p1);
- rt2x00_set_field32(&reg, MAC_CSR13_BIT3, !p2);
- rt2x00_set_field32(&reg, MAC_CSR13_BIT11, 0);
+ rt2x00_set_field32(&reg, MAC_CSR13_DIR3, 0);
+ rt2x00_set_field32(&reg, MAC_CSR13_VAL3, !p2);
rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
}
@@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
+ u32 reg;
/*
* Disable power saving.
@@ -2850,6 +2851,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
return retval;
/*
+ * Enable rfkill polling by setting GPIO direction of the
+ * rfkill switch GPIO pin correctly.
+ */
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR13_DIR5, 1);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
+
+ /*
* Initialize hw specifications.
*/
retval = rt61pci_probe_hw_mode(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index e3cd6db76b0e..9bc6b6044e34 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -357,21 +357,22 @@ struct hw_pairwise_ta_entry {
/*
* MAC_CSR13: GPIO.
+ * MAC_CSR13_VALx: GPIO value
+ * MAC_CSR13_DIRx: GPIO direction: 0 = output; 1 = input
*/
#define MAC_CSR13 0x3034
-#define MAC_CSR13_BIT0 FIELD32(0x00000001)
-#define MAC_CSR13_BIT1 FIELD32(0x00000002)
-#define MAC_CSR13_BIT2 FIELD32(0x00000004)
-#define MAC_CSR13_BIT3 FIELD32(0x00000008)
-#define MAC_CSR13_BIT4 FIELD32(0x00000010)
-#define MAC_CSR13_BIT5 FIELD32(0x00000020)
-#define MAC_CSR13_BIT6 FIELD32(0x00000040)
-#define MAC_CSR13_BIT7 FIELD32(0x00000080)
-#define MAC_CSR13_BIT8 FIELD32(0x00000100)
-#define MAC_CSR13_BIT9 FIELD32(0x00000200)
-#define MAC_CSR13_BIT10 FIELD32(0x00000400)
-#define MAC_CSR13_BIT11 FIELD32(0x00000800)
-#define MAC_CSR13_BIT12 FIELD32(0x00001000)
+#define MAC_CSR13_VAL0 FIELD32(0x00000001)
+#define MAC_CSR13_VAL1 FIELD32(0x00000002)
+#define MAC_CSR13_VAL2 FIELD32(0x00000004)
+#define MAC_CSR13_VAL3 FIELD32(0x00000008)
+#define MAC_CSR13_VAL4 FIELD32(0x00000010)
+#define MAC_CSR13_VAL5 FIELD32(0x00000020)
+#define MAC_CSR13_DIR0 FIELD32(0x00000100)
+#define MAC_CSR13_DIR1 FIELD32(0x00000200)
+#define MAC_CSR13_DIR2 FIELD32(0x00000400)
+#define MAC_CSR13_DIR3 FIELD32(0x00000800)
+#define MAC_CSR13_DIR4 FIELD32(0x00001000)
+#define MAC_CSR13_DIR5 FIELD32(0x00002000)
/*
* MAC_CSR14: LED control register.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ba6e434b859d..cfa9f37cccc2 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -189,7 +189,7 @@ static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
u32 reg;
rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
- return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
+ return rt2x00_get_field32(reg, MAC_CSR13_VAL7);
}
#ifdef CONFIG_RT2X00_LIB_LEDS
@@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
+ u32 reg;
/*
* Allocate eeprom data.
@@ -2190,6 +2191,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
return retval;
/*
+ * Enable rfkill polling by setting GPIO direction of the
+ * rfkill switch GPIO pin correctly.
+ */
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR13_DIR7, 0);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg);
+
+ /*
* Initialize hw specifications.
*/
retval = rt73usb_probe_hw_mode(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 9f6b470414d3..7577e0ba3877 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -267,21 +267,26 @@ struct hw_pairwise_ta_entry {
/*
* MAC_CSR13: GPIO.
+ * MAC_CSR13_VALx: GPIO value
+ * MAC_CSR13_DIRx: GPIO direction: 0 = input; 1 = output
*/
#define MAC_CSR13 0x3034
-#define MAC_CSR13_BIT0 FIELD32(0x00000001)
-#define MAC_CSR13_BIT1 FIELD32(0x00000002)
-#define MAC_CSR13_BIT2 FIELD32(0x00000004)
-#define MAC_CSR13_BIT3 FIELD32(0x00000008)
-#define MAC_CSR13_BIT4 FIELD32(0x00000010)
-#define MAC_CSR13_BIT5 FIELD32(0x00000020)
-#define MAC_CSR13_BIT6 FIELD32(0x00000040)
-#define MAC_CSR13_BIT7 FIELD32(0x00000080)
-#define MAC_CSR13_BIT8 FIELD32(0x00000100)
-#define MAC_CSR13_BIT9 FIELD32(0x00000200)
-#define MAC_CSR13_BIT10 FIELD32(0x00000400)
-#define MAC_CSR13_BIT11 FIELD32(0x00000800)
-#define MAC_CSR13_BIT12 FIELD32(0x00001000)
+#define MAC_CSR13_VAL0 FIELD32(0x00000001)
+#define MAC_CSR13_VAL1 FIELD32(0x00000002)
+#define MAC_CSR13_VAL2 FIELD32(0x00000004)
+#define MAC_CSR13_VAL3 FIELD32(0x00000008)
+#define MAC_CSR13_VAL4 FIELD32(0x00000010)
+#define MAC_CSR13_VAL5 FIELD32(0x00000020)
+#define MAC_CSR13_VAL6 FIELD32(0x00000040)
+#define MAC_CSR13_VAL7 FIELD32(0x00000080)
+#define MAC_CSR13_DIR0 FIELD32(0x00000100)
+#define MAC_CSR13_DIR1 FIELD32(0x00000200)
+#define MAC_CSR13_DIR2 FIELD32(0x00000400)
+#define MAC_CSR13_DIR3 FIELD32(0x00000800)
+#define MAC_CSR13_DIR4 FIELD32(0x00001000)
+#define MAC_CSR13_DIR5 FIELD32(0x00002000)
+#define MAC_CSR13_DIR6 FIELD32(0x00004000)
+#define MAC_CSR13_DIR7 FIELD32(0x00008000)
/*
* MAC_CSR14: LED control register.