rt2x00: Don't disable G0 PA_PE bit in case of BT coexistence.
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 2/7 rt2x00: Don't disable G0 PA_PE bit in case of BT coexistence.
From: Gertjan van Wingerde <[email protected]>
(split off from the earlier RT35xx patch submitted by Shiang)
--- drivers/net/wireless/rt2x00/rt2800lib.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/net/wireless/rt2x00/rt2800lib.c +5 -1
@@ -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);
Signature · 1 line
1.7.2.3
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 3/7 rt2x00: Add support for RT3572/RT3592/RT3592+Bluetooth combo card
From: Gertjan van Wingerde <[email protected]>
(based on an earlier patch submitted by Shiang)
Add support for RT3572/RT3592/RT3592+Bluetooth combo card
--- 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(-)
drivers/net/wireless/rt2x00/rt2800.h +16 -0
@@ -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
drivers/net/wireless/rt2x00/rt2800lib.c +276 -6
398 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2800pci.c +3 -1
@@ -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 );
Signature · 1 line
1.7.2.3
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 4/7 rt2x00: Interface sequence lock doesn't have to disable interrupts.
From: Gertjan van Wingerde <[email protected]>
This lock is only used in the TX path and thus in process context. Therefore we can use a much lighter spinlock variant.
--- drivers/net/wireless/rt2x00/rt2x00queue.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
drivers/net/wireless/rt2x00/rt2x00queue.c +2 -3
@@ -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); }
Signature · 1 line
1.7.2.3
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 5/7 rt2x00: Move rt2800_txdone and rt2800_txdone_entry_check to rt2800usb.
From: Gertjan van Wingerde <[email protected]>
These two functions are only used by rt2800usb so they don't have to be in rt2800lib.
--- 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(-)
drivers/net/wireless/rt2x00/rt2800lib.c +0 -82
@@ -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;
drivers/net/wireless/rt2x00/rt2800lib.h +0 -1
@@ -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);
drivers/net/wireless/rt2x00/rt2800usb.c +82 -1
95 lines not on this page · raw message
Signature · 1 line
1.7.2.3
Re: [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check to rt2800usb.
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:
Quoted 229 lines
From: Gertjan van Wingerde <[email protected]>
These two functions are only used by rt2800usb so they don't have to be in rt2800lib.
Signed-off-by Gertjan van Wingerde <[email protected]>Signed-off-by Ivo van Doorn <[email protected]>--- 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(-)
(quoted diff) +0
-0
b/drivers/net/wireless/rt2x00/rt2800lib.cindex 445d681..562dc1d 100644drivers/net/wireless/rt2x00/rt2800lib.c +0
-82@@ -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;(quoted diff) +0
-0
b/drivers/net/wireless/rt2x00/rt2800lib.hindex f2d1594..69deb31 100644drivers/net/wireless/rt2x00/rt2800lib.h +0
-1@@ -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, structtxentry_desc
*txdesc); diff --gita/drivers/net/wireless/rt2x00/rt2800usb.cb/drivers/net/wireless/rt2x00/rt2800usb.cindex ba82c97..6e92298 100644drivers/net/wireless/rt2x00/rt2800usb.c +0
-0@@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct
queue_entry*entry) /*
* TX control handlers
*/
+static boolrt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)+{drivers/net/wireless/rt2x00/rt2800usb.c +80
-1+__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,
Re: [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check to rt2800usb.
Quoted 42 lines · Marc Dietrich
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 ]---
Quoted 2 lines
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
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 6/7 rt2x00: Queue index locks don't have to disable IRQs.
From: Gertjan van Wingerde <[email protected]>
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.
--- drivers/net/wireless/rt2x00/rt2x00debug.c | 5 ++--- drivers/net/wireless/rt2x00/rt2x00queue.c | 20 ++++++++------------ 2 files changed, 10 insertions(+), 15 deletions(-)
drivers/net/wireless/rt2x00/rt2x00debug.c +2 -3
@@ -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);
drivers/net/wireless/rt2x00/rt2x00queue.c +8 -12
@@ -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)
Signature · 1 line
1.7.2.3
Re: [rt2x00-users] [PATCH 6/7] rt2x00: Queue index locks don't have to disable IRQs.
Quoted 8 lines · Ivo van Doorn
From: Gertjan van Wingerde <[email protected]>
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 <[email protected]>Signed-off-by Ivo van Doorn <[email protected]>
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.
Quoted 129 lines
--- drivers/net/wireless/rt2x00/rt2x00debug.c | 5 ++--- drivers/net/wireless/rt2x00/rt2x00queue.c | 20 ++++++++------------ 2 files changed, 10 insertions(+), 15 deletions(-)drivers/net/wireless/rt2x00/rt2x00debug.c +2
-3@@ -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);drivers/net/wireless/rt2x00/rt2x00queue.c +8
-12@@ -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)
Signature · 2 lines
--- Gertjan
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 7/7 rt2x00: Enabled rt35xx device support by default.
From: Gertjan van Wingerde <[email protected]>
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.
--- drivers/net/wireless/rt2x00/Kconfig | 9 ++------- 1 files changed, 2 insertions(+), 7 deletions(-)
drivers/net/wireless/rt2x00/Kconfig +2 -7
@@ -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
Signature · 1 line
1.7.2.3