* [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
[parent not found: <201105182022.40563.IvDoorn@gmail.com>]
* [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
[parent not found: <201105182023.04837.IvDoorn@gmail.com>]
* [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
[parent not found: <201105182023.25912.IvDoorn@gmail.com>]
* [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
* 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
[parent not found: <201105182023.47984.IvDoorn@gmail.com>]
* [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
* 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
[parent not found: <201105182024.21295.IvDoorn@gmail.com>]
* [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
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).