* [PATCH 2/7] rt2x00: Don't disable G0 PA_PE bit in case of BT coexistence.
[not found] <201105182022.20341.IvDoorn@gmail.com>
@ 2011-05-18 18:25 ` Ivo van Doorn
[not found] ` <201105182022.40563.IvDoorn@gmail.com>
1 sibling, 0 replies; 9+ messages in thread
From: Ivo van Doorn @ 2011-05-18 18:25 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, users
From: Gertjan van Wingerde <gwingerde@gmail.com>
(split off from the earlier RT35xx patch submitted by Shiang)
Signed-off-by: Shiang Tu <shiang_tu@ralinktech.com>
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 1cad89e..ce736e9 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1811,7 +1811,11 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14);
+ if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
+ else
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
+ rf->channel <= 14);
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/7] rt2x00: Add support for RT3572/RT3592/RT3592+Bluetooth combo card
[not found] ` <201105182022.40563.IvDoorn@gmail.com>
@ 2011-05-18 18:25 ` Ivo van Doorn
[not found] ` <201105182023.04837.IvDoorn@gmail.com>
1 sibling, 0 replies; 9+ messages in thread
From: Ivo van Doorn @ 2011-05-18 18:25 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, users
From: Gertjan van Wingerde <gwingerde@gmail.com>
(based on an earlier patch submitted by Shiang)
Add support for RT3572/RT3592/RT3592+Bluetooth combo card
Signed-off-by: Shiang Tu <shiang_tu@ralinktech.com>
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800.h | 16 ++
drivers/net/wireless/rt2x00/rt2800lib.c | 282 ++++++++++++++++++++++++++++++-
drivers/net/wireless/rt2x00/rt2800pci.c | 4 +-
3 files changed, 295 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 47a04d2..7edd008 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1740,6 +1740,7 @@ struct mac_iveiv_entry {
/*
* BBP 3: RX Antenna
*/
+#define BBP3_RX_ADC FIELD8(0x03)
#define BBP3_RX_ANTENNA FIELD8(0x18)
#define BBP3_HT40_MINUS FIELD8(0x20)
@@ -1783,6 +1784,8 @@ struct mac_iveiv_entry {
#define RFCSR1_TX0_PD FIELD8(0x08)
#define RFCSR1_RX1_PD FIELD8(0x10)
#define RFCSR1_TX1_PD FIELD8(0x20)
+#define RFCSR1_RX2_PD FIELD8(0x40)
+#define RFCSR1_TX2_PD FIELD8(0x80)
/*
* RFCSR 2:
@@ -1790,15 +1793,25 @@ struct mac_iveiv_entry {
#define RFCSR2_RESCAL_EN FIELD8(0x80)
/*
+ * FRCSR 5:
+ */
+#define RFCSR5_R1 FIELD8(0x0c)
+
+/*
* RFCSR 6:
*/
#define RFCSR6_R1 FIELD8(0x03)
#define RFCSR6_R2 FIELD8(0x40)
+#define RFCSR6_TXDIV FIELD8(0x0c)
/*
* RFCSR 7:
*/
#define RFCSR7_RF_TUNING FIELD8(0x01)
+#define RFCSR7_R02 FIELD8(0x07)
+#define RFCSR7_R3 FIELD8(0x08)
+#define RFCSR7_R45 FIELD8(0x30)
+#define RFCSR7_R67 FIELD8(0xc0)
/*
* RFCSR 11:
@@ -1809,11 +1822,13 @@ struct mac_iveiv_entry {
* RFCSR 12:
*/
#define RFCSR12_TX_POWER FIELD8(0x1f)
+#define RFCSR12_DR0 FIELD8(0xe0)
/*
* RFCSR 13:
*/
#define RFCSR13_TX_POWER FIELD8(0x1f)
+#define RFCSR13_DR0 FIELD8(0xe0)
/*
* RFCSR 15:
@@ -2256,6 +2271,7 @@ struct mac_iveiv_entry {
#define MCU_ANT_SELECT 0X73
#define MCU_BBP_SIGNAL 0x80
#define MCU_POWER_SAVE 0x83
+#define MCU_BAND_SELECT 0x91
/*
* MCU mailbox tokens
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index ce736e9..445d681 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -401,7 +401,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
return -EBUSY;
if (rt2x00_is_pci(rt2x00dev)) {
- if (rt2x00_rt(rt2x00dev, RT5390)) {
+ if (rt2x00_rt(rt2x00dev, RT3572) ||
+ rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_register_read(rt2x00dev, AUX_CTRL, ®);
rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1);
rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1);
@@ -1433,6 +1434,40 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
}
EXPORT_SYMBOL_GPL(rt2800_config_erp);
+static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ u16 eeprom;
+ u8 led_ctrl, led_g_mode, led_r_mode;
+
+ rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®);
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
+ rt2x00_set_field32(®, GPIO_SWITCH_0, 1);
+ rt2x00_set_field32(®, GPIO_SWITCH_1, 1);
+ } else {
+ rt2x00_set_field32(®, GPIO_SWITCH_0, 0);
+ rt2x00_set_field32(®, GPIO_SWITCH_1, 0);
+ }
+ rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
+
+ rt2800_register_read(rt2x00dev, LED_CFG, ®);
+ led_g_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 3 : 0;
+ led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3;
+ if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) ||
+ led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE);
+ if (led_ctrl == 0 || led_ctrl > 0x40) {
+ rt2x00_set_field32(®, LED_CFG_G_LED_MODE, led_g_mode);
+ rt2x00_set_field32(®, LED_CFG_R_LED_MODE, led_r_mode);
+ rt2800_register_write(rt2x00dev, LED_CFG, reg);
+ } else {
+ rt2800_mcu_request(rt2x00dev, MCU_BAND_SELECT, 0xff,
+ (led_g_mode << 2) | led_r_mode, 1);
+ }
+ }
+}
+
static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev,
enum antenna ant)
{
@@ -1463,6 +1498,10 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
rt2800_bbp_read(rt2x00dev, 1, &r1);
rt2800_bbp_read(rt2x00dev, 3, &r3);
+ if (rt2x00_rt(rt2x00dev, RT3572) &&
+ test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
+ rt2800_config_3572bt_ant(rt2x00dev);
+
/*
* Configure the TX antenna.
*/
@@ -1471,7 +1510,11 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
break;
case 2:
- rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+ if (rt2x00_rt(rt2x00dev, RT3572) &&
+ test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
+ rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 1);
+ else
+ rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
break;
case 3:
rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
@@ -1496,7 +1539,15 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
break;
case 2:
- rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+ if (rt2x00_rt(rt2x00dev, RT3572) &&
+ test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
+ rt2x00_set_field8(&r3, BBP3_RX_ADC, 1);
+ rt2x00_set_field8(&r3, BBP3_RX_ANTENNA,
+ rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
+ rt2800_set_ant_diversity(rt2x00dev, ANTENNA_B);
+ } else {
+ rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+ }
break;
case 3:
rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
@@ -1630,6 +1681,161 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
}
+static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ u8 rfcsr;
+ u32 reg;
+
+ if (rf->channel <= 14) {
+ rt2800_bbp_write(rt2x00dev, 25, 0x15);
+ rt2800_bbp_write(rt2x00dev, 26, 0x85);
+ } else {
+ rt2800_bbp_write(rt2x00dev, 25, 0x09);
+ rt2800_bbp_write(rt2x00dev, 26, 0xff);
+ }
+
+ rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
+ rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
+
+ rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
+ if (rf->channel <= 14)
+ rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 2);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 1);
+ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 5, &rfcsr);
+ if (rf->channel <= 14)
+ rt2x00_set_field8(&rfcsr, RFCSR5_R1, 1);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR5_R1, 2);
+ rt2800_rfcsr_write(rt2x00dev, 5, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
+ if (rf->channel <= 14) {
+ rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3);
+ rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+ (info->default_power1 & 0x3) |
+ ((info->default_power1 & 0xC) << 1));
+ } else {
+ rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7);
+ rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+ (info->default_power1 & 0x3) |
+ ((info->default_power1 & 0xC) << 1));
+ }
+ rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
+ if (rf->channel <= 14) {
+ rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3);
+ rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
+ (info->default_power2 & 0x3) |
+ ((info->default_power2 & 0xC) << 1));
+ } else {
+ rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7);
+ rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
+ (info->default_power2 & 0x3) |
+ ((info->default_power2 & 0xC) << 1));
+ }
+ rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+ if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
+ if (rf->channel <= 14) {
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
+ }
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+ } else {
+ switch (rt2x00dev->default_ant.tx_chain_num) {
+ case 1:
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+ case 2:
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+ break;
+ }
+
+ switch (rt2x00dev->default_ant.rx_chain_num) {
+ case 1:
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+ case 2:
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+ break;
+ }
+ }
+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
+ rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+
+ rt2800_rfcsr_write(rt2x00dev, 24,
+ rt2x00dev->calibration[conf_is_ht40(conf)]);
+ rt2800_rfcsr_write(rt2x00dev, 31,
+ rt2x00dev->calibration[conf_is_ht40(conf)]);
+
+ if (rf->channel <= 14) {
+ rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
+ rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
+ rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
+ rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
+ rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
+ rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
+ rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
+ rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
+ rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
+ rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
+ } else {
+ rt2800_rfcsr_write(rt2x00dev, 7, 0x14);
+ rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
+ rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
+ rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 15, 0x43);
+ rt2800_rfcsr_write(rt2x00dev, 16, 0x7a);
+ rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
+ if (rf->channel <= 64) {
+ rt2800_rfcsr_write(rt2x00dev, 19, 0xb7);
+ rt2800_rfcsr_write(rt2x00dev, 20, 0xf6);
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x3d);
+ } else if (rf->channel <= 128) {
+ rt2800_rfcsr_write(rt2x00dev, 19, 0x74);
+ rt2800_rfcsr_write(rt2x00dev, 20, 0xf4);
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
+ } else {
+ rt2800_rfcsr_write(rt2x00dev, 19, 0x72);
+ rt2800_rfcsr_write(rt2x00dev, 20, 0xf3);
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
+ }
+ rt2800_rfcsr_write(rt2x00dev, 26, 0x87);
+ rt2800_rfcsr_write(rt2x00dev, 27, 0x01);
+ rt2800_rfcsr_write(rt2x00dev, 29, 0x9f);
+ }
+
+ rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
+ rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT7, 0);
+ if (rf->channel <= 14)
+ rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 1);
+ else
+ rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 0);
+ rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+
+ rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+ rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+}
#define RT5390_POWER_BOUND 0x27
#define RT5390_FREQ_OFFSET_BOUND 0x5f
@@ -1748,9 +1954,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_rf(rt2x00dev, RF3020) ||
rt2x00_rf(rt2x00dev, RF3021) ||
rt2x00_rf(rt2x00dev, RF3022) ||
- rt2x00_rf(rt2x00dev, RF3052) ||
rt2x00_rf(rt2x00dev, RF3320))
rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
+ else if (rt2x00_rf(rt2x00dev, RF3052))
+ rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
else if (rt2x00_rf(rt2x00dev, RF5370) ||
rt2x00_rf(rt2x00dev, RF5390))
rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
@@ -1777,7 +1984,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
}
}
} else {
- rt2800_bbp_write(rt2x00dev, 82, 0xf2);
+ if (rt2x00_rt(rt2x00dev, RT3572))
+ rt2800_bbp_write(rt2x00dev, 82, 0x94);
+ else
+ rt2800_bbp_write(rt2x00dev, 82, 0xf2);
if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
rt2800_bbp_write(rt2x00dev, 75, 0x46);
@@ -1791,6 +2001,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14);
rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg);
+ if (rt2x00_rt(rt2x00dev, RT3572))
+ rt2800_rfcsr_write(rt2x00dev, 8, 0);
+
tx_pin = 0;
/* Turn on unused PA or LNA when not using 1T or 1R */
@@ -1820,6 +2033,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+ if (rt2x00_rt(rt2x00dev, RT3572))
+ rt2800_rfcsr_write(rt2x00dev, 8, 0x80);
+
rt2800_bbp_read(rt2x00dev, 4, &bbp);
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
rt2800_bbp_write(rt2x00dev, 4, bbp);
@@ -2419,6 +2635,9 @@ 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, RT3572)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
} else if (rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -2805,6 +3024,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
}
if (rt2800_is_305x_soc(rt2x00dev) ||
+ rt2x00_rt(rt2x00dev, RT3572) ||
rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 31, 0x08);
@@ -2834,6 +3054,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3090) ||
rt2x00_rt(rt2x00dev, RT3390) ||
+ rt2x00_rt(rt2x00dev, RT3572) ||
rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_bbp_write(rt2x00dev, 79, 0x13);
rt2800_bbp_write(rt2x00dev, 80, 0x05);
@@ -2874,6 +3095,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, RT3572) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2800_is_305x_soc(rt2x00dev))
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
@@ -2901,6 +3123,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3090) ||
rt2x00_rt(rt2x00dev, RT3390) ||
+ rt2x00_rt(rt2x00dev, RT3572) ||
rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_bbp_read(rt2x00dev, 138, &value);
@@ -3037,6 +3260,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
!rt2x00_rt(rt2x00dev, RT3071) &&
!rt2x00_rt(rt2x00dev, RT3090) &&
!rt2x00_rt(rt2x00dev, RT3390) &&
+ !rt2x00_rt(rt2x00dev, RT3572) &&
!rt2x00_rt(rt2x00dev, RT5390) &&
!rt2800_is_305x_soc(rt2x00dev))
return 0;
@@ -3115,6 +3339,38 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_rfcsr_write(rt2x00dev, 29, 0x8f);
rt2800_rfcsr_write(rt2x00dev, 30, 0x20);
rt2800_rfcsr_write(rt2x00dev, 31, 0x0f);
+ } else if (rt2x00_rt(rt2x00dev, RT3572)) {
+ rt2800_rfcsr_write(rt2x00dev, 0, 0x70);
+ rt2800_rfcsr_write(rt2x00dev, 1, 0x81);
+ rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
+ rt2800_rfcsr_write(rt2x00dev, 3, 0x02);
+ rt2800_rfcsr_write(rt2x00dev, 4, 0x4c);
+ rt2800_rfcsr_write(rt2x00dev, 5, 0x05);
+ rt2800_rfcsr_write(rt2x00dev, 6, 0x4a);
+ rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
+ rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
+ rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
+ rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
+ rt2800_rfcsr_write(rt2x00dev, 12, 0x70);
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x65);
+ rt2800_rfcsr_write(rt2x00dev, 14, 0xa0);
+ rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
+ rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
+ rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
+ rt2800_rfcsr_write(rt2x00dev, 18, 0xac);
+ rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
+ rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
+ rt2800_rfcsr_write(rt2x00dev, 21, 0xd0);
+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 23, 0x3c);
+ rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
+ rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
+ rt2800_rfcsr_write(rt2x00dev, 30, 0x09);
+ rt2800_rfcsr_write(rt2x00dev, 31, 0x10);
} else if (rt2800_is_305x_soc(rt2x00dev)) {
rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
@@ -3264,6 +3520,19 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®);
rt2x00_set_field32(®, GPIO_SWITCH_5, 0);
rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
+ } else if (rt2x00_rt(rt2x00dev, RT3572)) {
+ rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1);
+ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+ rt2800_register_read(rt2x00dev, LDO_CFG0, ®);
+ rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3);
+ rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);
+ rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
+ msleep(1);
+ rt2800_register_read(rt2x00dev, LDO_CFG0, ®);
+ rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);
+ rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
}
/*
@@ -3276,7 +3545,8 @@ 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, RT3390)) {
+ rt2x00_rt(rt2x00dev, RT3390) ||
+ rt2x00_rt(rt2x00dev, RT3572)) {
rt2x00dev->calibration[0] =
rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
rt2x00dev->calibration[1] =
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index cc4a54f..5513edf 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -501,7 +501,9 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
- if (rt2x00_rt(rt2x00dev, RT5390)) {
+ if (rt2x00_is_pcie(rt2x00dev) &&
+ (rt2x00_rt(rt2x00dev, RT3572) ||
+ rt2x00_rt(rt2x00dev, RT5390))) {
rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®);
rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1);
rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/7] rt2x00: Interface sequence lock doesn't have to disable interrupts.
[not found] ` <201105182023.04837.IvDoorn@gmail.com>
@ 2011-05-18 18:25 ` Ivo van Doorn
[not found] ` <201105182023.25912.IvDoorn@gmail.com>
1 sibling, 0 replies; 9+ messages in thread
From: Ivo van Doorn @ 2011-05-18 18:25 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, users
From: Gertjan van Wingerde <gwingerde@gmail.com>
This lock is only used in the TX path and thus in process context. Therefore
we can use a much lighter spinlock variant.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00queue.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 56f9d0d..f1e1381 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -206,7 +206,6 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
- unsigned long irqflags;
if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
return;
@@ -227,14 +226,14 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
* sequence counting per-frame, since those will override the
* sequence counter given by mac80211.
*/
- spin_lock_irqsave(&intf->seqlock, irqflags);
+ spin_lock(&intf->seqlock);
if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
intf->seqno += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
- spin_unlock_irqrestore(&intf->seqlock, irqflags);
+ spin_unlock(&intf->seqlock);
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/7] rt2x00: Move rt2800_txdone and rt2800_txdone_entry_check to rt2800usb.
[not found] ` <201105182023.25912.IvDoorn@gmail.com>
@ 2011-05-18 18:25 ` Ivo van Doorn
2011-05-18 20:38 ` [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check " Marc Dietrich
[not found] ` <201105182023.47984.IvDoorn@gmail.com>
1 sibling, 1 reply; 9+ messages in thread
From: Ivo van Doorn @ 2011-05-18 18:25 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, users
From: Gertjan van Wingerde <gwingerde@gmail.com>
These two functions are only used by rt2800usb so they don't have to be
in rt2800lib.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 82 ------------------------------
drivers/net/wireless/rt2x00/rt2800lib.h | 1 -
drivers/net/wireless/rt2x00/rt2800usb.c | 83 ++++++++++++++++++++++++++++++-
3 files changed, 82 insertions(+), 84 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 445d681..562dc1d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -601,49 +601,6 @@ void rt2800_process_rxwi(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
-static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
-{
- __le32 *txwi;
- u32 word;
- int wcid, ack, pid;
- int tx_wcid, tx_ack, tx_pid;
-
- wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
- ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
- pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
-
- /*
- * This frames has returned with an IO error,
- * so the status report is not intended for this
- * frame.
- */
- if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
- rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
- return false;
- }
-
- /*
- * Validate if this TX status report is intended for
- * this entry by comparing the WCID/ACK/PID fields.
- */
- txwi = rt2800_drv_get_txwi(entry);
-
- rt2x00_desc_read(txwi, 1, &word);
- tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
- tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
- tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
-
- if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
- WARNING(entry->queue->rt2x00dev,
- "TX status report missed for queue %d entry %d\n",
- entry->queue->qid, entry->entry_idx);
- rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
- return false;
- }
-
- return true;
-}
-
void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -726,45 +683,6 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
}
EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
-void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
-{
- struct data_queue *queue;
- struct queue_entry *entry;
- u32 reg;
- u8 qid;
-
- while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
-
- /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
- * qid is guaranteed to be one of the TX QIDs
- */
- qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
- queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
- if (unlikely(!queue)) {
- WARNING(rt2x00dev, "Got TX status for an unavailable "
- "queue %u, dropping\n", qid);
- continue;
- }
-
- /*
- * Inside each queue, we process each entry in a chronological
- * order. We first check that the queue is not empty.
- */
- entry = NULL;
- while (!rt2x00queue_empty(queue)) {
- entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
- if (rt2800_txdone_entry_check(entry, reg))
- break;
- }
-
- if (!entry || rt2x00queue_empty(queue))
- break;
-
- rt2800_txdone_entry(entry, reg);
- }
-}
-EXPORT_SYMBOL_GPL(rt2800_txdone);
-
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index f2d1594..69deb31 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -152,7 +152,6 @@ void rt2800_write_tx_data(struct queue_entry *entry,
struct txentry_desc *txdesc);
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
-void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index ba82c97..6e92298 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
/*
* TX control handlers
*/
+static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
+{
+ __le32 *txwi;
+ u32 word;
+ int wcid, ack, pid;
+ int tx_wcid, tx_ack, tx_pid;
+
+ wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
+ ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
+ pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
+
+ /*
+ * This frames has returned with an IO error,
+ * so the status report is not intended for this
+ * frame.
+ */
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+ return false;
+ }
+
+ /*
+ * Validate if this TX status report is intended for
+ * this entry by comparing the WCID/ACK/PID fields.
+ */
+ txwi = rt2800usb_get_txwi(entry);
+
+ rt2x00_desc_read(txwi, 1, &word);
+ tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
+ tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
+ tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
+
+ if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
+ WARNING(entry->queue->rt2x00dev,
+ "TX status report missed for queue %d entry %d\n",
+ entry->queue->qid, entry->entry_idx);
+ rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
+ return false;
+ }
+
+ return true;
+}
+
+static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+ struct queue_entry *entry;
+ u32 reg;
+ u8 qid;
+
+ while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
+
+ /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
+ * qid is guaranteed to be one of the TX QIDs
+ */
+ qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
+ queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
+ if (unlikely(!queue)) {
+ WARNING(rt2x00dev, "Got TX status for an unavailable "
+ "queue %u, dropping\n", qid);
+ continue;
+ }
+
+ /*
+ * Inside each queue, we process each entry in a chronological
+ * order. We first check that the queue is not empty.
+ */
+ entry = NULL;
+ while (!rt2x00queue_empty(queue)) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+ if (rt2800usb_txdone_entry_check(entry, reg))
+ break;
+ }
+
+ if (!entry || rt2x00queue_empty(queue))
+ break;
+
+ rt2800_txdone_entry(entry, reg);
+ }
+}
+
static void rt2800usb_work_txdone(struct work_struct *work)
{
struct rt2x00_dev *rt2x00dev =
@@ -464,7 +545,7 @@ static void rt2800usb_work_txdone(struct work_struct *work)
struct data_queue *queue;
struct queue_entry *entry;
- rt2800_txdone(rt2x00dev);
+ rt2800usb_txdone(rt2x00dev);
/*
* Process any trailing TX status reports for IO failures,
--
1.7.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/7] rt2x00: Queue index locks don't have to disable IRQs.
[not found] ` <201105182023.47984.IvDoorn@gmail.com>
@ 2011-05-18 18:25 ` Ivo van Doorn
2011-05-18 20:54 ` [rt2x00-users] " Gertjan van Wingerde
[not found] ` <201105182024.21295.IvDoorn@gmail.com>
1 sibling, 1 reply; 9+ messages in thread
From: Ivo van Doorn @ 2011-05-18 18:25 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, users
From: Gertjan van Wingerde <gwingerde@gmail.com>
The queue index locks are no longer used in interrupt context due to the
introduction of tasklets and workqueues. Therefore we can use a lighter
variant of the spinlocks.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00debug.c | 5 ++---
drivers/net/wireless/rt2x00/rt2x00queue.c | 20 ++++++++------------
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 78787fc..8e417de 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -327,7 +327,6 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
{
struct rt2x00debug_intf *intf = file->private_data;
struct data_queue *queue;
- unsigned long irqflags;
unsigned int lines = 1 + intf->rt2x00dev->data_queues;
size_t size;
char *data;
@@ -344,7 +343,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
queue_for_each(intf->rt2x00dev, queue) {
- spin_lock_irqsave(&queue->index_lock, irqflags);
+ spin_lock_bh(&queue->index_lock);
temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
queue->qid, (unsigned int)queue->flags,
@@ -353,7 +352,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
queue->index[Q_INDEX_DMA_DONE],
queue->index[Q_INDEX_DONE]);
- spin_unlock_irqrestore(&queue->index_lock, irqflags);
+ spin_unlock_bh(&queue->index_lock);
}
size = strlen(data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index f1e1381..e2e1bf6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -735,7 +735,6 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue,
bool (*fn)(struct queue_entry *entry,
void *data))
{
- unsigned long irqflags;
unsigned int index_start;
unsigned int index_end;
unsigned int i;
@@ -753,10 +752,10 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue,
* it should not be kicked during this run, since it
* is part of another TX operation.
*/
- spin_lock_irqsave(&queue->index_lock, irqflags);
+ spin_lock_bh(&queue->index_lock);
index_start = queue->index[start];
index_end = queue->index[end];
- spin_unlock_irqrestore(&queue->index_lock, irqflags);
+ spin_unlock_bh(&queue->index_lock);
/*
* Start from the TX done pointer, this guarentees that we will
@@ -787,7 +786,6 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
enum queue_index index)
{
struct queue_entry *entry;
- unsigned long irqflags;
if (unlikely(index >= Q_INDEX_MAX)) {
ERROR(queue->rt2x00dev,
@@ -795,11 +793,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
return NULL;
}
- spin_lock_irqsave(&queue->index_lock, irqflags);
+ spin_lock_bh(&queue->index_lock);
entry = &queue->entries[queue->index[index]];
- spin_unlock_irqrestore(&queue->index_lock, irqflags);
+ spin_unlock_bh(&queue->index_lock);
return entry;
}
@@ -808,7 +806,6 @@ EXPORT_SYMBOL_GPL(rt2x00queue_get_entry);
void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
{
struct data_queue *queue = entry->queue;
- unsigned long irqflags;
if (unlikely(index >= Q_INDEX_MAX)) {
ERROR(queue->rt2x00dev,
@@ -816,7 +813,7 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
return;
}
- spin_lock_irqsave(&queue->index_lock, irqflags);
+ spin_lock_bh(&queue->index_lock);
queue->index[index]++;
if (queue->index[index] >= queue->limit)
@@ -831,7 +828,7 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
queue->count++;
}
- spin_unlock_irqrestore(&queue->index_lock, irqflags);
+ spin_unlock_bh(&queue->index_lock);
}
void rt2x00queue_pause_queue(struct data_queue *queue)
@@ -1031,10 +1028,9 @@ EXPORT_SYMBOL_GPL(rt2x00queue_flush_queues);
static void rt2x00queue_reset(struct data_queue *queue)
{
- unsigned long irqflags;
unsigned int i;
- spin_lock_irqsave(&queue->index_lock, irqflags);
+ spin_lock_bh(&queue->index_lock);
queue->count = 0;
queue->length = 0;
@@ -1042,7 +1038,7 @@ static void rt2x00queue_reset(struct data_queue *queue)
for (i = 0; i < Q_INDEX_MAX; i++)
queue->index[i] = 0;
- spin_unlock_irqrestore(&queue->index_lock, irqflags);
+ spin_unlock_bh(&queue->index_lock);
}
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
--
1.7.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/7] rt2x00: Enabled rt35xx device support by default.
[not found] ` <201105182024.21295.IvDoorn@gmail.com>
@ 2011-05-18 18:26 ` Ivo van Doorn
0 siblings, 0 replies; 9+ messages in thread
From: Ivo van Doorn @ 2011-05-18 18:26 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, users
From: Gertjan van Wingerde <gwingerde@gmail.com>
Now that support for these devices has been added we can enable them
by default and remove the Kconfig not on support for these devices to
be non-functional.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/Kconfig | 9 ++-------
1 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 9def1e5..3a91033 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -83,14 +83,12 @@ config RT2800PCI_RT33XX
config RT2800PCI_RT35XX
bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
- default n
+ default y
---help---
This adds support for rt35xx wireless chipset family to the
rt2800pci driver.
Supported chips: RT3060, RT3062, RT3562, RT3592
- Support for these devices is non-functional at the moment and is
- intended for testers and developers.
config RT2800PCI_RT53XX
bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)"
@@ -154,15 +152,12 @@ config RT2800USB_RT33XX
config RT2800USB_RT35XX
bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
- default n
+ default y
---help---
This adds support for rt35xx wireless chipset family to the
rt2800usb driver.
Supported chips: RT3572
- Support for these devices is non-functional at the moment and is
- intended for testers and developers.
-
config RT2800USB_RT53XX
bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
--
1.7.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check to rt2800usb.
2011-05-18 18:25 ` [PATCH 5/7] rt2x00: Move rt2800_txdone and rt2800_txdone_entry_check to rt2800usb Ivo van Doorn
@ 2011-05-18 20:38 ` Marc Dietrich
2011-05-18 20:53 ` Gertjan van Wingerde
0 siblings, 1 reply; 9+ messages in thread
From: Marc Dietrich @ 2011-05-18 20:38 UTC (permalink / raw)
To: users; +Cc: Ivo van Doorn, John W. Linville, linux-wireless
Hi,
I tested the patches and got this during boot on a rt3070 chip:
[ 14.173458] ------------[ cut here ]------------
[ 14.173482] WARNING: at /home/marc/ac100/marvin24s-kernel/kernel/softirq.c:159 local_bh_enable_ip+0x4c/0xcc()
[ 14.173490] Modules linked in: binfmt_misc snd_soc_tegra_paz00 snd_soc_alc5632 snd_soc_tegra_i2s snd_soc_tegra_pcm
snd_soc_tegra_das rt2800usb snd_soc_core snd_pcm_oss rt2800lib rt2x00usb snd_mixer_oss rt2x00lib snd_pcm mac80211
snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq cfg80211 snd_timer snd_seq_device uvcvideo rfkill cdc_acm snd
cdc_wdm videodev snd_soc_tegra_utils soundcore snd_page_alloc g_cdc btrfs
[ 14.173567] Backtrace:
[ 14.173607] [<c0043708>] (unwind_backtrace+0x0/0xe0) from [<c00753f8>] (warn_slowpath_common+0x4c/0x64)
[ 14.173628] [<c00753f8>] (warn_slowpath_common+0x4c/0x64) from [<c0075428>] (warn_slowpath_null+0x18/0x1c)
[ 14.173646] [<c0075428>] (warn_slowpath_null+0x18/0x1c) from [<c007bc80>] (local_bh_enable_ip+0x4c/0xcc)
[ 14.173676] [<c007bc80>] (local_bh_enable_ip+0x4c/0xcc) from [<bf40b9b4>] (rt2x00usb_interrupt_rxdone+0x30/0x70
[rt2x00usb])
[ 14.173723] [<bf40b9b4>] (rt2x00usb_interrupt_rxdone+0x30/0x70 [rt2x00usb]) from [<c02d9150>]
(usb_hcd_giveback_urb+0x74/0xbc)
[ 14.173752] [<c02d9150>] (usb_hcd_giveback_urb+0x74/0xbc) from [<c02e75f8>] (ehci_urb_done+0x90/0x9c)
[ 14.173775] [<c02e75f8>] (ehci_urb_done+0x90/0x9c) from [<c02eb284>] (qh_completions+0xb4/0x3ec)
[ 14.173795] [<c02eb284>] (qh_completions+0xb4/0x3ec) from [<c02ec4b8>] (ehci_work+0xb4/0x97c)
[ 14.173814] [<c02ec4b8>] (ehci_work+0xb4/0x97c) from [<c02ed3d0>] (ehci_irq+0x21c/0x24c)
[ 14.173830] [<c02ed3d0>] (ehci_irq+0x21c/0x24c) from [<c02d8b34>] (usb_hcd_irq+0x34/0x6c)
[ 14.173865] [<c02d8b34>] (usb_hcd_irq+0x34/0x6c) from [<c00bb840>] (handle_IRQ_event+0x9c/0x1b4)
[ 14.173884] [<c00bb840>] (handle_IRQ_event+0x9c/0x1b4) from [<c00bd4fc>] (handle_level_irq+0xd0/0x154)
[ 14.173910] [<c00bd4fc>] (handle_level_irq+0xd0/0x154) from [<c0037080>] (asm_do_IRQ+0x80/0xb4)
[ 14.173943] [<c0037080>] (asm_do_IRQ+0x80/0xb4) from [<c040d84c>] (__irq_svc+0x4c/0xe0)
[ 14.173954] Exception stack(0xdb84be10 to 0xdb84be58)
[ 14.173964] be00: db929800 db28dc60 00000000 dcc00000
[ 14.173979] be20: db28dc60 dcd20000 00000000 00000010 db929800 00000008 00000010 db28dc98
[ 14.173991] be40: 00000000 db84be58 c026c86c c026ef58 60000013 ffffffff
[ 14.174027] [<c040d84c>] (__irq_svc+0x4c/0xe0) from [<c026ef58>] (cfb_imageblit+0x54/0x43c)
[ 14.174047] [<c026ef58>] (cfb_imageblit+0x54/0x43c) from [<c026c86c>] (soft_cursor+0x1a0/0x1a8)
[ 14.174065] [<c026c86c>] (soft_cursor+0x1a0/0x1a8) from [<c026c254>] (bit_cursor+0x41c/0x42c)
[ 14.174083] [<c026c254>] (bit_cursor+0x41c/0x42c) from [<c0266d08>] (fb_flashcursor+0xfc/0x118)
[ 14.174114] [<c0266d08>] (fb_flashcursor+0xfc/0x118) from [<c008c9a0>] (process_one_work+0x274/0x43c)
[ 14.174136] [<c008c9a0>] (process_one_work+0x274/0x43c) from [<c008e698>] (worker_thread+0x1b8/0x2b4)
[ 14.174159] [<c008e698>] (worker_thread+0x1b8/0x2b4) from [<c0091d5c>] (kthread+0x7c/0x84)
[ 14.174190] [<c0091d5c>] (kthread+0x7c/0x84) from [<c003d470>] (kernel_thread_exit+0x0/0x8)
[ 14.174202] ---[ end trace 7b2804cb6c2b13fe ]---
Of course, this didn't happen before.
Thanks
Marc
Am Mittwoch 18 Mai 2011, 20:25:49 schrieb Ivo van Doorn:
> From: Gertjan van Wingerde <gwingerde@gmail.com>
>
> These two functions are only used by rt2800usb so they don't have to be
> in rt2800lib.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
> ---
> drivers/net/wireless/rt2x00/rt2800lib.c | 82
> ------------------------------ drivers/net/wireless/rt2x00/rt2800lib.h |
> 1 -
> drivers/net/wireless/rt2x00/rt2800usb.c | 83
> ++++++++++++++++++++++++++++++- 3 files changed, 82 insertions(+), 84
> deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c
> b/drivers/net/wireless/rt2x00/rt2800lib.c index 445d681..562dc1d 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -601,49 +601,6 @@ void rt2800_process_rxwi(struct queue_entry *entry,
> }
> EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
>
> -static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
> -{
> - __le32 *txwi;
> - u32 word;
> - int wcid, ack, pid;
> - int tx_wcid, tx_ack, tx_pid;
> -
> - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
> - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
> - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
> -
> - /*
> - * This frames has returned with an IO error,
> - * so the status report is not intended for this
> - * frame.
> - */
> - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
> - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
> - return false;
> - }
> -
> - /*
> - * Validate if this TX status report is intended for
> - * this entry by comparing the WCID/ACK/PID fields.
> - */
> - txwi = rt2800_drv_get_txwi(entry);
> -
> - rt2x00_desc_read(txwi, 1, &word);
> - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
> - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
> - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
> -
> - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
> - WARNING(entry->queue->rt2x00dev,
> - "TX status report missed for queue %d entry %d\n",
> - entry->queue->qid, entry->entry_idx);
> - rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
> - return false;
> - }
> -
> - return true;
> -}
> -
> void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
> {
> struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
> @@ -726,45 +683,6 @@ void rt2800_txdone_entry(struct queue_entry *entry,
> u32 status) }
> EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
>
> -void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
> -{
> - struct data_queue *queue;
> - struct queue_entry *entry;
> - u32 reg;
> - u8 qid;
> -
> - while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
> -
> - /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
> - * qid is guaranteed to be one of the TX QIDs
> - */
> - qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
> - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
> - if (unlikely(!queue)) {
> - WARNING(rt2x00dev, "Got TX status for an unavailable "
> - "queue %u, dropping\n", qid);
> - continue;
> - }
> -
> - /*
> - * Inside each queue, we process each entry in a chronological
> - * order. We first check that the queue is not empty.
> - */
> - entry = NULL;
> - while (!rt2x00queue_empty(queue)) {
> - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
> - if (rt2800_txdone_entry_check(entry, reg))
> - break;
> - }
> -
> - if (!entry || rt2x00queue_empty(queue))
> - break;
> -
> - rt2800_txdone_entry(entry, reg);
> - }
> -}
> -EXPORT_SYMBOL_GPL(rt2800_txdone);
> -
> void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc
> *txdesc) {
> struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h
> b/drivers/net/wireless/rt2x00/rt2800lib.h index f2d1594..69deb31 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.h
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.h
> @@ -152,7 +152,6 @@ void rt2800_write_tx_data(struct queue_entry *entry,
> struct txentry_desc *txdesc);
> void rt2800_process_rxwi(struct queue_entry *entry, struct
> rxdone_entry_desc *txdesc);
>
> -void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
> void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
>
> void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc
> *txdesc); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c
> b/drivers/net/wireless/rt2x00/rt2800usb.c index ba82c97..6e92298 100644
> --- a/drivers/net/wireless/rt2x00/rt2800usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2800usb.c
> @@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct
> queue_entry *entry) /*
> * TX control handlers
> */
> +static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32
> reg) +{
> + __le32 *txwi;
> + u32 word;
> + int wcid, ack, pid;
> + int tx_wcid, tx_ack, tx_pid;
> +
> + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
> + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
> + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
> +
> + /*
> + * This frames has returned with an IO error,
> + * so the status report is not intended for this
> + * frame.
> + */
> + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
> + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
> + return false;
> + }
> +
> + /*
> + * Validate if this TX status report is intended for
> + * this entry by comparing the WCID/ACK/PID fields.
> + */
> + txwi = rt2800usb_get_txwi(entry);
> +
> + rt2x00_desc_read(txwi, 1, &word);
> + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
> + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
> + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
> +
> + if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
> + WARNING(entry->queue->rt2x00dev,
> + "TX status report missed for queue %d entry %d\n",
> + entry->queue->qid, entry->entry_idx);
> + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
> +{
> + struct data_queue *queue;
> + struct queue_entry *entry;
> + u32 reg;
> + u8 qid;
> +
> + while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
> +
> + /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
> + * qid is guaranteed to be one of the TX QIDs
> + */
> + qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
> + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
> + if (unlikely(!queue)) {
> + WARNING(rt2x00dev, "Got TX status for an unavailable "
> + "queue %u, dropping\n", qid);
> + continue;
> + }
> +
> + /*
> + * Inside each queue, we process each entry in a chronological
> + * order. We first check that the queue is not empty.
> + */
> + entry = NULL;
> + while (!rt2x00queue_empty(queue)) {
> + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
> + if (rt2800usb_txdone_entry_check(entry, reg))
> + break;
> + }
> +
> + if (!entry || rt2x00queue_empty(queue))
> + break;
> +
> + rt2800_txdone_entry(entry, reg);
> + }
> +}
> +
> static void rt2800usb_work_txdone(struct work_struct *work)
> {
> struct rt2x00_dev *rt2x00dev =
> @@ -464,7 +545,7 @@ static void rt2800usb_work_txdone(struct work_struct
> *work) struct data_queue *queue;
> struct queue_entry *entry;
>
> - rt2800_txdone(rt2x00dev);
> + rt2800usb_txdone(rt2x00dev);
>
> /*
> * Process any trailing TX status reports for IO failures,
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check to rt2800usb.
2011-05-18 20:38 ` [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check " Marc Dietrich
@ 2011-05-18 20:53 ` Gertjan van Wingerde
0 siblings, 0 replies; 9+ messages in thread
From: Gertjan van Wingerde @ 2011-05-18 20:53 UTC (permalink / raw)
To: Marc Dietrich; +Cc: users, Ivo van Doorn, John W. Linville, linux-wireless
On 05/18/11 22:38, Marc Dietrich wrote:
>
> Hi,
>
> I tested the patches and got this during boot on a rt3070 chip:
>
> [ 14.173458] ------------[ cut here ]------------
> [ 14.173482] WARNING: at /home/marc/ac100/marvin24s-kernel/kernel/softirq.c:159 local_bh_enable_ip+0x4c/0xcc()
> [ 14.173490] Modules linked in: binfmt_misc snd_soc_tegra_paz00 snd_soc_alc5632 snd_soc_tegra_i2s snd_soc_tegra_pcm
> snd_soc_tegra_das rt2800usb snd_soc_core snd_pcm_oss rt2800lib rt2x00usb snd_mixer_oss rt2x00lib snd_pcm mac80211
> snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq cfg80211 snd_timer snd_seq_device uvcvideo rfkill cdc_acm snd
> cdc_wdm videodev snd_soc_tegra_utils soundcore snd_page_alloc g_cdc btrfs
> [ 14.173567] Backtrace:
> [ 14.173607] [<c0043708>] (unwind_backtrace+0x0/0xe0) from [<c00753f8>] (warn_slowpath_common+0x4c/0x64)
> [ 14.173628] [<c00753f8>] (warn_slowpath_common+0x4c/0x64) from [<c0075428>] (warn_slowpath_null+0x18/0x1c)
> [ 14.173646] [<c0075428>] (warn_slowpath_null+0x18/0x1c) from [<c007bc80>] (local_bh_enable_ip+0x4c/0xcc)
> [ 14.173676] [<c007bc80>] (local_bh_enable_ip+0x4c/0xcc) from [<bf40b9b4>] (rt2x00usb_interrupt_rxdone+0x30/0x70
> [rt2x00usb])
> [ 14.173723] [<bf40b9b4>] (rt2x00usb_interrupt_rxdone+0x30/0x70 [rt2x00usb]) from [<c02d9150>]
> (usb_hcd_giveback_urb+0x74/0xbc)
> [ 14.173752] [<c02d9150>] (usb_hcd_giveback_urb+0x74/0xbc) from [<c02e75f8>] (ehci_urb_done+0x90/0x9c)
> [ 14.173775] [<c02e75f8>] (ehci_urb_done+0x90/0x9c) from [<c02eb284>] (qh_completions+0xb4/0x3ec)
> [ 14.173795] [<c02eb284>] (qh_completions+0xb4/0x3ec) from [<c02ec4b8>] (ehci_work+0xb4/0x97c)
> [ 14.173814] [<c02ec4b8>] (ehci_work+0xb4/0x97c) from [<c02ed3d0>] (ehci_irq+0x21c/0x24c)
> [ 14.173830] [<c02ed3d0>] (ehci_irq+0x21c/0x24c) from [<c02d8b34>] (usb_hcd_irq+0x34/0x6c)
> [ 14.173865] [<c02d8b34>] (usb_hcd_irq+0x34/0x6c) from [<c00bb840>] (handle_IRQ_event+0x9c/0x1b4)
> [ 14.173884] [<c00bb840>] (handle_IRQ_event+0x9c/0x1b4) from [<c00bd4fc>] (handle_level_irq+0xd0/0x154)
> [ 14.173910] [<c00bd4fc>] (handle_level_irq+0xd0/0x154) from [<c0037080>] (asm_do_IRQ+0x80/0xb4)
> [ 14.173943] [<c0037080>] (asm_do_IRQ+0x80/0xb4) from [<c040d84c>] (__irq_svc+0x4c/0xe0)
> [ 14.173954] Exception stack(0xdb84be10 to 0xdb84be58)
> [ 14.173964] be00: db929800 db28dc60 00000000 dcc00000
> [ 14.173979] be20: db28dc60 dcd20000 00000000 00000010 db929800 00000008 00000010 db28dc98
> [ 14.173991] be40: 00000000 db84be58 c026c86c c026ef58 60000013 ffffffff
> [ 14.174027] [<c040d84c>] (__irq_svc+0x4c/0xe0) from [<c026ef58>] (cfb_imageblit+0x54/0x43c)
> [ 14.174047] [<c026ef58>] (cfb_imageblit+0x54/0x43c) from [<c026c86c>] (soft_cursor+0x1a0/0x1a8)
> [ 14.174065] [<c026c86c>] (soft_cursor+0x1a0/0x1a8) from [<c026c254>] (bit_cursor+0x41c/0x42c)
> [ 14.174083] [<c026c254>] (bit_cursor+0x41c/0x42c) from [<c0266d08>] (fb_flashcursor+0xfc/0x118)
> [ 14.174114] [<c0266d08>] (fb_flashcursor+0xfc/0x118) from [<c008c9a0>] (process_one_work+0x274/0x43c)
> [ 14.174136] [<c008c9a0>] (process_one_work+0x274/0x43c) from [<c008e698>] (worker_thread+0x1b8/0x2b4)
> [ 14.174159] [<c008e698>] (worker_thread+0x1b8/0x2b4) from [<c0091d5c>] (kthread+0x7c/0x84)
> [ 14.174190] [<c0091d5c>] (kthread+0x7c/0x84) from [<c003d470>] (kernel_thread_exit+0x0/0x8)
> [ 14.174202] ---[ end trace 7b2804cb6c2b13fe ]---
>
> Of course, this didn't happen before.
>
Hmm, OK. This is not caused by the patch you responded to, but it is indeed introduced by an other patch.
I have no idea how this has escaped my testing, as I did test the patches on USB devices as well, but there
seems to be exactly 1 instance in which the queue index spin lock is still used in IRQ context, which escaped
my attention.
So, patch 6 of the series should not be applied right now.
---
Gertjan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rt2x00-users] [PATCH 6/7] rt2x00: Queue index locks don't have to disable IRQs.
2011-05-18 18:25 ` [PATCH 6/7] rt2x00: Queue index locks don't have to disable IRQs Ivo van Doorn
@ 2011-05-18 20:54 ` Gertjan van Wingerde
0 siblings, 0 replies; 9+ messages in thread
From: Gertjan van Wingerde @ 2011-05-18 20:54 UTC (permalink / raw)
To: John W. Linville; +Cc: Ivo van Doorn, linux-wireless, users
On 05/18/11 20:25, Ivo van Doorn wrote:
> From: Gertjan van Wingerde <gwingerde@gmail.com>
>
> The queue index locks are no longer used in interrupt context due to the
> introduction of tasklets and workqueues. Therefore we can use a lighter
> variant of the spinlocks.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
John, as noted in another email on the mailing list, this patch seems to introduce
a problem on USB devices, which escaped my testing for some reason.
Hence, please do not apply this patch to wireless-next.
Patch 7 of the series does not depend on this patch, so that one can still be applied.
> ---
> drivers/net/wireless/rt2x00/rt2x00debug.c | 5 ++---
> drivers/net/wireless/rt2x00/rt2x00queue.c | 20 ++++++++------------
> 2 files changed, 10 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
> index 78787fc..8e417de 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00debug.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
> @@ -327,7 +327,6 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
> {
> struct rt2x00debug_intf *intf = file->private_data;
> struct data_queue *queue;
> - unsigned long irqflags;
> unsigned int lines = 1 + intf->rt2x00dev->data_queues;
> size_t size;
> char *data;
> @@ -344,7 +343,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
> sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
>
> queue_for_each(intf->rt2x00dev, queue) {
> - spin_lock_irqsave(&queue->index_lock, irqflags);
> + spin_lock_bh(&queue->index_lock);
>
> temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
> queue->qid, (unsigned int)queue->flags,
> @@ -353,7 +352,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
> queue->index[Q_INDEX_DMA_DONE],
> queue->index[Q_INDEX_DONE]);
>
> - spin_unlock_irqrestore(&queue->index_lock, irqflags);
> + spin_unlock_bh(&queue->index_lock);
> }
>
> size = strlen(data);
> diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
> index f1e1381..e2e1bf6 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
> @@ -735,7 +735,6 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue,
> bool (*fn)(struct queue_entry *entry,
> void *data))
> {
> - unsigned long irqflags;
> unsigned int index_start;
> unsigned int index_end;
> unsigned int i;
> @@ -753,10 +752,10 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue,
> * it should not be kicked during this run, since it
> * is part of another TX operation.
> */
> - spin_lock_irqsave(&queue->index_lock, irqflags);
> + spin_lock_bh(&queue->index_lock);
> index_start = queue->index[start];
> index_end = queue->index[end];
> - spin_unlock_irqrestore(&queue->index_lock, irqflags);
> + spin_unlock_bh(&queue->index_lock);
>
> /*
> * Start from the TX done pointer, this guarentees that we will
> @@ -787,7 +786,6 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
> enum queue_index index)
> {
> struct queue_entry *entry;
> - unsigned long irqflags;
>
> if (unlikely(index >= Q_INDEX_MAX)) {
> ERROR(queue->rt2x00dev,
> @@ -795,11 +793,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
> return NULL;
> }
>
> - spin_lock_irqsave(&queue->index_lock, irqflags);
> + spin_lock_bh(&queue->index_lock);
>
> entry = &queue->entries[queue->index[index]];
>
> - spin_unlock_irqrestore(&queue->index_lock, irqflags);
> + spin_unlock_bh(&queue->index_lock);
>
> return entry;
> }
> @@ -808,7 +806,6 @@ EXPORT_SYMBOL_GPL(rt2x00queue_get_entry);
> void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
> {
> struct data_queue *queue = entry->queue;
> - unsigned long irqflags;
>
> if (unlikely(index >= Q_INDEX_MAX)) {
> ERROR(queue->rt2x00dev,
> @@ -816,7 +813,7 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
> return;
> }
>
> - spin_lock_irqsave(&queue->index_lock, irqflags);
> + spin_lock_bh(&queue->index_lock);
>
> queue->index[index]++;
> if (queue->index[index] >= queue->limit)
> @@ -831,7 +828,7 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
> queue->count++;
> }
>
> - spin_unlock_irqrestore(&queue->index_lock, irqflags);
> + spin_unlock_bh(&queue->index_lock);
> }
>
> void rt2x00queue_pause_queue(struct data_queue *queue)
> @@ -1031,10 +1028,9 @@ EXPORT_SYMBOL_GPL(rt2x00queue_flush_queues);
>
> static void rt2x00queue_reset(struct data_queue *queue)
> {
> - unsigned long irqflags;
> unsigned int i;
>
> - spin_lock_irqsave(&queue->index_lock, irqflags);
> + spin_lock_bh(&queue->index_lock);
>
> queue->count = 0;
> queue->length = 0;
> @@ -1042,7 +1038,7 @@ static void rt2x00queue_reset(struct data_queue *queue)
> for (i = 0; i < Q_INDEX_MAX; i++)
> queue->index[i] = 0;
>
> - spin_unlock_irqrestore(&queue->index_lock, irqflags);
> + spin_unlock_bh(&queue->index_lock);
> }
>
> void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
--
---
Gertjan
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-05-18 20:54 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <201105182022.20341.IvDoorn@gmail.com>
2011-05-18 18:25 ` [PATCH 2/7] rt2x00: Don't disable G0 PA_PE bit in case of BT coexistence Ivo van Doorn
[not found] ` <201105182022.40563.IvDoorn@gmail.com>
2011-05-18 18:25 ` [PATCH 3/7] rt2x00: Add support for RT3572/RT3592/RT3592+Bluetooth combo card Ivo van Doorn
[not found] ` <201105182023.04837.IvDoorn@gmail.com>
2011-05-18 18:25 ` [PATCH 4/7] rt2x00: Interface sequence lock doesn't have to disable interrupts Ivo van Doorn
[not found] ` <201105182023.25912.IvDoorn@gmail.com>
2011-05-18 18:25 ` [PATCH 5/7] rt2x00: Move rt2800_txdone and rt2800_txdone_entry_check to rt2800usb Ivo van Doorn
2011-05-18 20:38 ` [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check " Marc Dietrich
2011-05-18 20:53 ` Gertjan van Wingerde
[not found] ` <201105182023.47984.IvDoorn@gmail.com>
2011-05-18 18:25 ` [PATCH 6/7] rt2x00: Queue index locks don't have to disable IRQs Ivo van Doorn
2011-05-18 20:54 ` [rt2x00-users] " Gertjan van Wingerde
[not found] ` <201105182024.21295.IvDoorn@gmail.com>
2011-05-18 18:26 ` [PATCH 7/7] rt2x00: Enabled rt35xx device support by default Ivo van Doorn
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.