linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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, &reg);
 			rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
 			rt2x00_set_field32(&reg, 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, &reg);
+	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
+		rt2x00_set_field32(&reg, GPIO_SWITCH_0, 1);
+		rt2x00_set_field32(&reg, GPIO_SWITCH_1, 1);
+	} else {
+		rt2x00_set_field32(&reg, GPIO_SWITCH_0, 0);
+		rt2x00_set_field32(&reg, GPIO_SWITCH_1, 0);
+	}
+	rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
+
+	rt2800_register_read(rt2x00dev, LED_CFG, &reg);
+	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(&reg, LED_CFG_G_LED_MODE, led_g_mode);
+			rt2x00_set_field32(&reg, 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, &reg);
+	rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT7, 0);
+	if (rf->channel <= 14)
+		rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT7, 1);
+	else
+		rt2x00_set_field32(&reg, 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(&reg, 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, &reg);
 		rt2x00_set_field32(&reg, 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, &reg);
+		rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
+		rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+		rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
+		msleep(1);
+		rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+		rt2x00_set_field32(&reg, 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, &reg);
 		rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
 		rt2x00_set_field32(&reg, 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, &reg)) {
-
-		/* 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, &reg)) {
+
+		/* 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, &reg)) {
> -
> -		/* 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, &reg)) {
> +
> +		/* 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).