Skip to contentSkip to conversation

rt2x00: Add rt2800 EEPROM definition

PATCH In review Ivo van Doorn 5 participants 32 messages Dec 13, 2010 – Dec 17, 2010 Networking drivers (wireless)

lore
Share & tools
lore
#0 lore raw

PATCH 1/17 rt2x00: Add rt2800 EEPROM definition

From: RA-Jay Hung <[email protected]>

Add and modify NIC Configuration and LED definition of EEPROM

---
 drivers/net/wireless/rt2x00/rt2800.h    |   94 +++++++++++++++++---------
 drivers/net/wireless/rt2x00/rt2800lib.c |  111 ++++++++++++++++---------------
 2 files changed, 119 insertions(+), 86 deletions(-)
drivers/net/wireless/rt2x00/rt2800.h +62 -32
index a81c437..9dcbf87 100644
@@ -1841,32 +1841,51 @@ struct mac_iveiv_entry {
 #define EEPROM_MAC_ADDR_BYTE5		FIELD16(0xff00)
 
 /*
- * EEPROM ANTENNA config
+ * EEPROM NIC Configuration 0
  * RXPATH: 1: 1R, 2: 2R, 3: 3R
- * TXPATH: 1: 1T, 2: 2T
- */
-#define	EEPROM_ANTENNA			0x001a
-#define EEPROM_ANTENNA_RXPATH		FIELD16(0x000f)
-#define EEPROM_ANTENNA_TXPATH		FIELD16(0x00f0)
-#define EEPROM_ANTENNA_RF_TYPE		FIELD16(0x0f00)
-
-/*
- * EEPROM NIC config
- * CARDBUS_ACCEL: 0 - enable, 1 - disable
- */
-#define	EEPROM_NIC			0x001b
-#define EEPROM_NIC_HW_RADIO		FIELD16(0x0001)
-#define EEPROM_NIC_DYNAMIC_TX_AGC	FIELD16(0x0002)
-#define EEPROM_NIC_EXTERNAL_LNA_BG	FIELD16(0x0004)
-#define EEPROM_NIC_EXTERNAL_LNA_A	FIELD16(0x0008)
-#define EEPROM_NIC_CARDBUS_ACCEL	FIELD16(0x0010)
-#define EEPROM_NIC_BW40M_SB_BG		FIELD16(0x0020)
-#define EEPROM_NIC_BW40M_SB_A		FIELD16(0x0040)
-#define EEPROM_NIC_WPS_PBC		FIELD16(0x0080)
-#define EEPROM_NIC_BW40M_BG		FIELD16(0x0100)
-#define EEPROM_NIC_BW40M_A		FIELD16(0x0200)
-#define EEPROM_NIC_ANT_DIVERSITY	FIELD16(0x0800)
-#define EEPROM_NIC_DAC_TEST		FIELD16(0x8000)
+ * TXPATH: 1: 1T, 2: 2T, 3: 3T
+ * RF_TYPE: RFIC type
+ */
+#define	EEPROM_NIC_CONF0		0x001a
+#define EEPROM_NIC_CONF0_RXPATH		FIELD16(0x000f)
+#define EEPROM_NIC_CONF0_TXPATH		FIELD16(0x00f0)
+#define EEPROM_NIC_CONF0_RF_TYPE		FIELD16(0x0f00)
+
+/*
+ * EEPROM NIC Configuration 1
+ * HW_RADIO: 0: disable, 1: enable
+ * EXTERNAL_TX_ALC: 0: disable, 1: enable
+ * EXTERNAL_LNA_2G: 0: disable, 1: enable
+ * EXTERNAL_LNA_5G: 0: disable, 1: enable
+ * CARDBUS_ACCEL: 0: enable, 1: disable
+ * BW40M_SB_2G: 0: disable, 1: enable
+ * BW40M_SB_5G: 0: disable, 1: enable
+ * WPS_PBC: 0: disable, 1: enable
+ * BW40M_2G: 0: enable, 1: disable
+ * BW40M_5G: 0: enable, 1: disable
+ * BROADBAND_EXT_LNA: 0: disable, 1: enable
+ * ANT_DIVERSITY: 00: Disable, 01: Diversity,
+ * 				  10: Main antenna, 11: Aux antenna
+ * INTERNAL_TX_ALC: 0: disable, 1: enable
+ * BT_COEXIST: 0: disable, 1: enable
+ * DAC_TEST: 0: disable, 1: enable
+ */
+#define	EEPROM_NIC_CONF1		0x001b
+#define EEPROM_NIC_CONF1_HW_RADIO		FIELD16(0x0001)
+#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC		FIELD16(0x0002)
+#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G		FIELD16(0x0004)
+#define EEPROM_NIC_CONF1_EXTERNAL_LNA_5G		FIELD16(0x0008)
+#define EEPROM_NIC_CONF1_CARDBUS_ACCEL		FIELD16(0x0010)
+#define EEPROM_NIC_CONF1_BW40M_SB_2G		FIELD16(0x0020)
+#define EEPROM_NIC_CONF1_BW40M_SB_5G		FIELD16(0x0040)
+#define EEPROM_NIC_CONF1_WPS_PBC		FIELD16(0x0080)
+#define EEPROM_NIC_CONF1_BW40M_2G		FIELD16(0x0100)
+#define EEPROM_NIC_CONF1_BW40M_5G		FIELD16(0x0200)
+#define EEPROM_NIC_CONF1_BROADBAND_EXT_LNA		FIELD16(0x400)
+#define EEPROM_NIC_CONF1_ANT_DIVERSITY		FIELD16(0x1800)
+#define EEPROM_NIC_CONF1_INTERNAL_TX_ALC		FIELD16(0x2000)
+#define EEPROM_NIC_CONF1_BT_COEXIST		FIELD16(0x4000)
+#define EEPROM_NIC_CONF1_DAC_TEST		FIELD16(0x8000)
 
 /*
  * EEPROM frequency
@@ -1888,9 +1907,9 @@ struct mac_iveiv_entry {
  * POLARITY_GPIO_4: Polarity GPIO4 setting.
  * LED_MODE: Led mode.
  */
-#define EEPROM_LED1			0x001e
-#define EEPROM_LED2			0x001f
-#define EEPROM_LED3			0x0020
+#define EEPROM_LED_AG_CONF		0x001e
+#define EEPROM_LED_ACT_CONF		0x001f
+#define EEPROM_LED_POLARITY		0x0020
 #define EEPROM_LED_POLARITY_RDY_BG	FIELD16(0x0001)
 #define EEPROM_LED_POLARITY_RDY_A	FIELD16(0x0002)
 #define EEPROM_LED_POLARITY_ACT		FIELD16(0x0004)
@@ -1902,6 +1921,17 @@ struct mac_iveiv_entry {
 #define EEPROM_LED_LED_MODE		FIELD16(0x1f00)
 
 /*
+ * EEPROM NIC Configuration 2
+ * RX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
+ * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
+ * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved
+ */
+#define EEPROM_NIC_CONF2		0x0021
+#define EEPROM_NIC_CONF2_RX_STREAM		FIELD16(0x000f)
+#define EEPROM_NIC_CONF2_TX_STREAM		FIELD16(0x00f0)
+#define EEPROM_NIC_CONF2_CRYSTAL		FIELD16(0x0600)
+
+/*
  * EEPROM LNA
  */
 #define EEPROM_LNA			0x0022
@@ -1951,7 +1981,7 @@ struct mac_iveiv_entry {
 
 /*
  * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
- *	This is delta in 40MHZ.
+ * This is delta in 40MHZ.
  * VALUE: Tx Power dalta value (MAX=4)
  * TYPE: 1: Plus the delta value, 0: minus the delta value
  * TXPOWER: Enable:
@@ -2007,9 +2037,9 @@ struct mac_iveiv_entry {
 #define MCU_CURRENT			0x36
 #define MCU_LED				0x50
 #define MCU_LED_STRENGTH		0x51
-#define MCU_LED_1			0x52
-#define MCU_LED_2			0x53
-#define MCU_LED_3			0x54
+#define MCU_LED_AG_CONF		0x52
+#define MCU_LED_ACT_CONF		0x53
+#define MCU_LED_LED_POLARITY		0x54
 #define MCU_RADAR			0x60
 #define MCU_BOOT_SIGNAL			0x72
 #define MCU_BBP_SIGNAL			0x80
drivers/net/wireless/rt2x00/rt2800lib.c +57 -54

222 lines not on this page · raw message

Signature · 1 line
1.7.2.3
#1 lore raw

PATCH 2/17 rt2x00: Implement get_survey callback for rt2800

From: Helmut Schaa <[email protected]>

Implement the get_survey callback to allow user space to read statistics about the current channel condition.

---
 drivers/net/wireless/rt2x00/rt2800.h    |   10 ++++++
 drivers/net/wireless/rt2x00/rt2800lib.c |   49 +++++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800lib.h |    2 +
 drivers/net/wireless/rt2x00/rt2800pci.c |    1 +
 drivers/net/wireless/rt2x00/rt2800usb.c |    1 +
 5 files changed, 63 insertions(+), 0 deletions(-)
drivers/net/wireless/rt2x00/rt2800.h +10 -0
index 9dcbf87..03f9fa1 100644
@@ -699,8 +699,18 @@
 
 /*
  * CH_TIME_CFG: count as channel busy
+ * EIFS_BUSY: Count EIFS as channel busy
+ * NAV_BUSY: Count NAS as channel busy
+ * RX_BUSY: Count RX as channel busy
+ * TX_BUSY: Count TX as channel busy
+ * TMR_EN: Enable channel statistics timer
  */
 #define CH_TIME_CFG     	        0x110c
+#define CH_TIME_CFG_EIFS_BUSY		FIELD32(0x00000010)
+#define CH_TIME_CFG_NAV_BUSY		FIELD32(0x00000008)
+#define CH_TIME_CFG_RX_BUSY		FIELD32(0x00000004)
+#define CH_TIME_CFG_TX_BUSY		FIELD32(0x00000002)
+#define CH_TIME_CFG_TMR_EN		FIELD32(0x00000001)
 
 /*
  * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
drivers/net/wireless/rt2x00/rt2800lib.c +49 -0

67 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2800lib.h +2 -0
index 81cbc92..e3c995a 100644
@@ -199,5 +199,7 @@ u64 rt2800_get_tsf(struct ieee80211_hw *hw);
 int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			enum ieee80211_ampdu_mlme_action action,
 			struct ieee80211_sta *sta, u16 tid, u16 *ssn);
+int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
+		      struct survey_info *survey);
 
 #endif /* RT2800LIB_H */
drivers/net/wireless/rt2x00/rt2800pci.c +1 -0
index 433c7f3..3a1468a 100644
@@ -943,6 +943,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 	.ampdu_action		= rt2800_ampdu_action,
 	.flush			= rt2x00mac_flush,
+	.get_survey		= rt2800_get_survey,
 };
 
 static const struct rt2800_ops rt2800pci_rt2800_ops = {
drivers/net/wireless/rt2x00/rt2800usb.c +1 -0
index 935b76d..042e47d 100644
@@ -562,6 +562,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 	.ampdu_action		= rt2800_ampdu_action,
 	.flush			= rt2x00mac_flush,
+	.get_survey		= rt2800_get_survey,
 };
 
 static const struct rt2800_ops rt2800usb_rt2800_ops = {
Signature · 1 line
1.7.2.3
#2 lore raw

PATCH 3/17 rt2x00: Add RF chip definition

From: RA-Jay Hung <[email protected]>

Add RF chip definition

---
 drivers/net/wireless/rt2x00/rt2800.h |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)
drivers/net/wireless/rt2x00/rt2800.h +8 -2
index 03f9fa1..9ea0961 100644
@@ -46,8 +46,11 @@
  * RF2020 2.4G B/G
  * RF3021 2.4G 1T2R
  * RF3022 2.4G 2T2R
- * RF3052 2.4G 2T2R
- * RF3320 2.4G 1T1R
+ * RF3052 2.4G/5G 2T2R
+ * RF2853 2.4G/5G 3T3R
+ * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
+ * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
+ * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
  */
 #define RF2820				0x0001
 #define RF2850				0x0002
@@ -58,7 +61,10 @@
 #define RF3021				0x0007
 #define RF3022				0x0008
 #define RF3052				0x0009
+#define RF2853				0x000a
 #define RF3320				0x000b
+#define RF3322				0x000c
+#define RF3853				0x000d
 
 /*
  * Chipset revisions.
Signature · 1 line
1.7.2.3
#3 lore raw

PATCH 4/17 rt2x00: fix hang when unplugging USB device in use

From: Johannes Stezenbach <[email protected]>

When an rt2x00 USB device is unplugged while in use, it reliably hangs the whole system. After some time the watchdog prints:

BUG: soft lockup - CPU#0 stuck for 64s! [kworker/u:0:5]

...
[<c01a88d8>] (usb_submit_urb+0x0/0x2ac) from [<bf0e752c>] (rt2x00usb_kick_rx_entry+0xb4/0xe8 [rt2x00usb]) [<bf0e7478>] (rt2x00usb_kick_rx_entry+0x0/0xe8 [rt2x00usb]) from [<bf0e7588>] (rt2x00usb_clear_entry+x28/0x2c [rt2x00usb]) [<bf0e7560>] (rt2x00usb_clear_entry+0x0/0x2c [rt2x00usb]) from [<bf0d5bc4>] (rt2x00lib_rxdone+0x2e0/0x2f8 [rt2x00lib]) [<bf0d58e4>] (rt2x00lib_rxdone+0x0/0x2f8 [rt2x00lib]) from [<bf0e7e00>] (rt2x00usb_work_rxdone+0x54/0x74 [rt2x00usb]) [<bf0e7dac>] (rt2x00usb_work_rxdone+0x0/0x74 [rt2x00usb]) from [<c00542b4>] (process_one_work+0x20c/0x35c)

Clear the DEVICE_STATE_PRESENT flag when usb_submit_urb() returns -ENODEV to fix this.

---
 drivers/net/wireless/rt2x00/rt2x00usb.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)
drivers/net/wireless/rt2x00/rt2x00usb.c +12 -2
index 9ac1459..3a6c83e 100644
@@ -235,6 +235,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
 	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
 	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
 	u32 length;
+	int status;
 
 	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
 		return;
@@ -251,7 +252,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
 			  entry->skb->data, length,
 			  rt2x00usb_interrupt_txdone, entry);
 
-	if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+	status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+	if (status) {
+		if (status == -ENODEV)
+			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 		rt2x00lib_dmadone(entry);
 	}
@@ -435,6 +439,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
 	    to_usb_device_intf(entry->queue->rt2x00dev->dev);
 	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
 	int pipe;
+	int status;
 
 	entry->flags = 0;
 
@@ -445,7 +450,12 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
 				rt2x00usb_interrupt_rxdone, entry);
 
 		set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
-		if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+
+		status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+		if (status) {
+			if (status == -ENODEV)
+				clear_bit(DEVICE_STATE_PRESENT,
+					  &entry->queue->rt2x00dev->flags);
 			set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 			rt2x00lib_dmadone(entry);
 		}
Signature · 1 line
1.7.2.3
#4 lore raw

PATCH 5/17 rt2x00: Ensure TX-ed frames are returned in the original state.

From: Gertjan van Wingerde <[email protected]>

Recent changes to the TX-done code of rt2x00 resulted in TX-ed frames not being returned to mac80211 in the original state, and therefore with insufficient headroom for re-transmissions.

Fix this by reverting the changes done and by ensuring we remove the inserted L2pad by moving the header backwards instead of the data forwards.

At the same time also make sure that the rt2x00queue_remove_l2pad will not move any memory when a frame has no data at all.

---
 drivers/net/wireless/rt2x00/rt2x00queue.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)
drivers/net/wireless/rt2x00/rt2x00queue.c +8 -5
index a3d79c7..35133d8 100644
@@ -199,15 +199,18 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
 
 void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
 {
-	unsigned int l2pad = L2PAD_SIZE(header_length);
+	/*
+	 * L2 padding is only present if the skb contains more than just the
+	 * IEEE 802.11 header.
+	 */
+	unsigned int l2pad = (skb->len > header_length) ?
+				L2PAD_SIZE(header_length) : 0;
 
 	if (!l2pad)
 		return;
 
-	memmove(skb->data + header_length, skb->data + header_length + l2pad,
-				skb->len - header_length - l2pad);
-
-	skb_trim(skb, skb->len - l2pad);
+	memmove(skb->data + l2pad, skb->data, header_length);
+	skb_pull(skb, l2pad);
 }
 
 static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
Signature · 1 line
1.7.2.3
#5 lore raw

PATCH 6/17 rt2x00: Don't frequently reset beacon interval in AdHoc mode

From: Helmut Schaa <[email protected]>

Commit 0204464329c17ba6d293e1899f71223599a0e582 "Check for specific changed flags when updating the erp config" changed the way in which a new beacon interval gets handled. However, due to a bug in rt2800usb and rt2800pci the beacon interval was reset during each scan, thus causing problems in AdHoc mode.

Fix this by not cleaning up the beacon interval when killing the beacon queue but just prevent the device from sending out beacons.

---
 drivers/net/wireless/rt2x00/rt2400pci.c |    6 +++++-
 drivers/net/wireless/rt2x00/rt2500pci.c |    6 +++++-
 drivers/net/wireless/rt2x00/rt2500usb.c |   12 ++++++++++--
 drivers/net/wireless/rt2x00/rt2800pci.c |    6 +++++-
 drivers/net/wireless/rt2x00/rt2800usb.c |   12 ++++++++++--
 drivers/net/wireless/rt2x00/rt61pci.c   |    6 +++++-
 drivers/net/wireless/rt2x00/rt73usb.c   |   12 ++++++++++--
 7 files changed, 50 insertions(+), 10 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +5 -1
index 9ec6691..6278660 100644
@@ -1140,7 +1140,11 @@ static void rt2400pci_kill_tx_queue(struct data_queue *queue)
 	u32 reg;
 
 	if (queue->qid == QID_BEACON) {
-		rt2x00pci_register_write(rt2x00dev, CSR14, 0);
+		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+		rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+		rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 	} else {
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
drivers/net/wireless/rt2x00/rt2500pci.c +5 -1
index 3e7f203..ce9212f 100644
@@ -1294,7 +1294,11 @@ static void rt2500pci_kill_tx_queue(struct data_queue *queue)
 	u32 reg;
 
 	if (queue->qid == QID_BEACON) {
-		rt2x00pci_register_write(rt2x00dev, CSR14, 0);
+		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+		rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+		rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 	} else {
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
drivers/net/wireless/rt2x00/rt2500usb.c +10 -2
index 8152fec..bbfa671 100644
@@ -1205,8 +1205,16 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
 
 static void rt2500usb_kill_tx_queue(struct data_queue *queue)
 {
-	if (queue->qid == QID_BEACON)
-		rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0);
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	u16 reg;
+
+	if (queue->qid == QID_BEACON) {
+		rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
+		rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
+		rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
+		rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
+		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+	}
 
 	rt2x00usb_kill_tx_queue(queue);
 }
drivers/net/wireless/rt2x00/rt2800pci.c +5 -1
index 3a1468a..bea8352 100644
@@ -588,7 +588,11 @@ static void rt2800pci_kill_tx_queue(struct data_queue *queue)
 	u32 reg;
 
 	if (queue->qid == QID_BEACON) {
-		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
+		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 		return;
 	}
 
drivers/net/wireless/rt2x00/rt2800usb.c +10 -2
index 042e47d..a150fcc 100644
@@ -391,8 +391,16 @@ static void rt2800usb_work_txdone(struct work_struct *work)
 
 static void rt2800usb_kill_tx_queue(struct data_queue *queue)
 {
-	if (queue->qid == QID_BEACON)
-		rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0);
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	u32 reg;
+
+	if (queue->qid == QID_BEACON) {
+		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+	}
 
 	rt2x00usb_kill_tx_queue(queue);
 }
drivers/net/wireless/rt2x00/rt61pci.c +5 -1
index 6b09b01..6ad0c1c 100644
@@ -1944,7 +1944,11 @@ static void rt61pci_kill_tx_queue(struct data_queue *queue)
 	u32 reg;
 
 	if (queue->qid == QID_BEACON) {
-		rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
+		rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+		rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+		rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+		rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+		rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
 		return;
 	}
 
drivers/net/wireless/rt2x00/rt73usb.c +10 -2
index 6f04552..3934dad 100644
@@ -1581,8 +1581,16 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)
 
 static void rt73usb_kill_tx_queue(struct data_queue *queue)
 {
-	if (queue->qid == QID_BEACON)
-		rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0);
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	u32 reg;
+
+	if (queue->qid == QID_BEACON) {
+		rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+		rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+		rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+		rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+		rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+	}
 
 	rt2x00usb_kill_tx_queue(queue);
 }
Signature · 1 line
1.7.2.3
#6 lore raw

PATCH 7/17 rt2x00: trivial: add missing \n on warnings

From: Johannes Stezenbach <[email protected]>

---
 drivers/net/wireless/rt2x00/rt2800pci.c |    6 +++---
 drivers/net/wireless/rt2x00/rt2800usb.c |    4 ++--
 drivers/net/wireless/rt2x00/rt2x00mac.c |    2 +-
 drivers/net/wireless/rt2x00/rt2x00usb.c |    4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)
drivers/net/wireless/rt2x00/rt2800pci.c +3 -3
index bea8352..2b68009 100644
@@ -686,7 +686,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
 			 * this tx status.
 			 */
 			WARNING(rt2x00dev, "Got TX status report with "
-					   "unexpected pid %u, dropping", qid);
+					   "unexpected pid %u, dropping\n", qid);
 			break;
 		}
 
@@ -697,7 +697,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
 			 * processing here and drop the tx status
 			 */
 			WARNING(rt2x00dev, "Got TX status for an unavailable "
-					   "queue %u, dropping", qid);
+					   "queue %u, dropping\n", qid);
 			break;
 		}
 
@@ -707,7 +707,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
 			 * and drop the tx status.
 			 */
 			WARNING(rt2x00dev, "Got TX status for an empty "
-					   "queue %u, dropping", qid);
+					   "queue %u, dropping\n", qid);
 			break;
 		}
 
drivers/net/wireless/rt2x00/rt2800usb.c +2 -2
index a150fcc..1dfa59d 100644
@@ -253,7 +253,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
 	rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
 	if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
 		WARNING(rt2x00dev, "TX HW queue 0 timed out,"
-			" invoke forced kick");
+			" invoke forced kick\n");
 
 		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);
 
@@ -269,7 +269,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
 	rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
 	if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
 		WARNING(rt2x00dev, "TX HW queue 1 timed out,"
-			" invoke forced kick");
+			" invoke forced kick\n");
 
 		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
 
drivers/net/wireless/rt2x00/rt2x00mac.c +1 -1
index 829bf4b..7ad4b27 100644
@@ -745,7 +745,7 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
 		}
 
 		if (!rt2x00queue_empty(queue))
-			WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid);
+			WARNING(rt2x00dev, "Failed to flush queue %d\n", queue->qid);
 	}
 
 	ieee80211_wake_queues(hw);
drivers/net/wireless/rt2x00/rt2x00usb.c +2 -2
index 3a6c83e..608200e 100644
@@ -300,7 +300,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
 	unsigned short threshold = queue->threshold;
 
 	WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
-		" invoke forced forced reset", queue->qid);
+		" invoke forced forced reset\n", queue->qid);
 
 	/*
 	 * Temporarily disable the TX queue, this will force mac80211
@@ -335,7 +335,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
 static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
 {
 	WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
-		" invoke forced tx handler", queue->qid);
+		" invoke forced tx handler\n", queue->qid);
 
 	ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
 }
Signature · 1 line
1.7.2.3
#7 lore raw

PATCH 8/17 rt2x00: Introduce 3 queue commands in drivers (start, kick, stop).

As part of the queue refactoring, we now introduce 3 queue commands: start, kick, stop.

- Start: will enable a queue, for TX this will not mean anything, while for beacons and RX this will update the registers to enable the queue.
- Kick: This will kick all pending frames to the hardware. This is needed for the TX queue to push all frames to the HW after the queue has been started
- Stop: This will stop the queue in the hardware, and cancel any pending work (So this doesn't mean the queue is empty after a stop!).

Move all code from the drivers into the appropriate functions, and link those calls to the old rt2x00lib callback functions (we will fix this later when we refactor the queue control inside rt2x00lib).

---
 drivers/net/wireless/rt2x00/rt2400pci.c |  131 +++++++++++++++++---------
 drivers/net/wireless/rt2x00/rt2500pci.c |  131 +++++++++++++++++---------
 drivers/net/wireless/rt2x00/rt2500usb.c |   84 +++++++++++------
 drivers/net/wireless/rt2x00/rt2800pci.c |  129 +++++++++++++++-----------
 drivers/net/wireless/rt2x00/rt2800usb.c |   84 +++++++++++------
 drivers/net/wireless/rt2x00/rt2x00usb.c |   12 +-
 drivers/net/wireless/rt2x00/rt2x00usb.h |    8 +-
 drivers/net/wireless/rt2x00/rt61pci.c   |  154 +++++++++++++++++++++----------
 drivers/net/wireless/rt2x00/rt73usb.c   |   84 +++++++++++------
 9 files changed, 530 insertions(+), 287 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +87 -44
index 6278660..35d9a06 100644
@@ -633,6 +633,88 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev,
 }
 
 /*
+ * Queue handlers.
+ */
+static void rt2400pci_start_queue(struct data_queue *queue)
+{
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	u32 reg;
+
+	switch (queue->qid) {
+	case QID_RX:
+		rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
+		rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 0);
+		rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
+		break;
+	case QID_BEACON:
+		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
+		rt2x00_set_field32(&reg, CSR14_TBCN, 1);
+		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
+		rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+		break;
+	default:
+		break;
+	}
+}
+
+static void rt2400pci_kick_queue(struct data_queue *queue)
+{
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	u32 reg;
+
+	switch (queue->qid) {
+	case QID_AC_BE:
+		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
+		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+		break;
+	case QID_AC_BK:
+		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+		rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
+		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+		break;
+	case QID_ATIM:
+		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+		rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
+		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+		break;
+	default:
+		break;
+	}
+}
+
+static void rt2400pci_stop_queue(struct data_queue *queue)
+{
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	u32 reg;
+
+	switch (queue->qid) {
+	case QID_AC_BE:
+	case QID_AC_BK:
+	case QID_ATIM:
+		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+		break;
+	case QID_RX:
+		rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
+		rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1);
+		rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
+		break;
+	case QID_BEACON:
+		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+		rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+		rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+		break;
+	default:
+		break;
+	}
+}
+
+/*
  * Initialization functions.
  */
 static bool rt2400pci_get_entry_state(struct queue_entry *entry)
@@ -878,17 +960,6 @@ static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
 /*
  * Device state switch handlers.
  */
-static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
-				enum dev_state state)
-{
-	u32 reg;
-
-	rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
-	rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
-			   (state == STATE_RADIO_RX_OFF));
-	rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
-}
-
 static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
 				 enum dev_state state)
 {
@@ -988,8 +1059,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 		rt2400pci_disable_radio(rt2x00dev);
 		break;
 	case STATE_RADIO_RX_ON:
+		rt2400pci_start_queue(rt2x00dev->rx);
+		break;
 	case STATE_RADIO_RX_OFF:
-		rt2400pci_toggle_rx(rt2x00dev, state);
+		rt2400pci_stop_queue(rt2x00dev->rx);
 		break;
 	case STATE_RADIO_IRQ_ON:
 	case STATE_RADIO_IRQ_ON_ISR:
@@ -1122,36 +1195,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
 	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 }
 
-static void rt2400pci_kick_tx_queue(struct data_queue *queue)
-{
-	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
-	u32 reg;
-
-	rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
-	rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
-	rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
-	rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
-	rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
-}
-
-static void rt2400pci_kill_tx_queue(struct data_queue *queue)
-{
-	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
-	u32 reg;
-
-	if (queue->qid == QID_BEACON) {
-		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
-		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
-		rt2x00_set_field32(&reg, CSR14_TBCN, 0);
-		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
-		rt2x00pci_register_write(rt2x00dev, CSR14, reg);
-	} else {
-		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
-		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
-		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
-	}
-}
-
 /*
  * RX control handlers
  */
@@ -1631,8 +1674,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
 	.link_tuner		= rt2400pci_link_tuner,
 	.write_tx_desc		= rt2400pci_write_tx_desc,
 	.write_beacon		= rt2400pci_write_beacon,
-	.kick_tx_queue		= rt2400pci_kick_tx_queue,
-	.kill_tx_queue		= rt2400pci_kill_tx_queue,
+	.kick_tx_queue		= rt2400pci_kick_queue,
+	.kill_tx_queue		= rt2400pci_stop_queue,
 	.fill_rxdone		= rt2400pci_fill_rxdone,
 	.config_filter		= rt2400pci_config_filter,
 	.config_intf		= rt2400pci_config_intf,
drivers/net/wireless/rt2x00/rt2500pci.c +87 -44

162 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2500usb.c +55 -29

115 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2800pci.c +76 -53

160 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2800usb.c +55 -29

115 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2x00usb.c +6 -6
index 608200e..12958a4 100644
@@ -268,7 +268,7 @@ void rt2x00usb_kick_tx_queue(struct data_queue *queue)
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
 
-static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
+static void rt2x00usb_kill_entry(struct queue_entry *entry)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
@@ -287,12 +287,12 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
 		usb_kill_urb(bcn_priv->guardian_urb);
 }
 
-void rt2x00usb_kill_tx_queue(struct data_queue *queue)
+void rt2x00usb_stop_queue(struct data_queue *queue)
 {
 	rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
-				   rt2x00usb_kill_tx_entry);
+				   rt2x00usb_kill_entry);
 }
-EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
+EXPORT_SYMBOL_GPL(rt2x00usb_stop_queue);
 
 static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
 {
@@ -316,7 +316,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
 	 * Kill all entries in the queue, afterwards we need to
 	 * wait a bit for all URBs to be cancelled.
 	 */
-	rt2x00usb_kill_tx_queue(queue);
+	rt2x00usb_stop_queue(queue);
 
 	/*
 	 * In case that a driver has overriden the txdone_work
@@ -423,7 +423,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
 				    REGISTER_TIMEOUT);
 
 	/*
-	 * The USB version of kill_tx_queue also works
+	 * The USB version of also works
 	 * on the RX queue.
 	 */
 	rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx);
drivers/net/wireless/rt2x00/rt2x00usb.h +4 -4
index c2d997f..656a35f 100644
@@ -387,13 +387,13 @@ struct queue_entry_priv_usb_bcn {
 void rt2x00usb_kick_tx_queue(struct data_queue *queue);
 
 /**
- * rt2x00usb_kill_tx_queue - Kill data queue
- * @queue: Data queue to kill
+ * rt2x00usb_stop_queue - Stop data queue
+ * @queue: Data queue to stop
  *
  * This will walk through all entries of the queue and kill all
- * previously kicked frames before they can be send.
+ * URB's which were send to the device.
  */
-void rt2x00usb_kill_tx_queue(struct data_queue *queue);
+void rt2x00usb_stop_queue(struct data_queue *queue);
 
 /**
  * rt2x00usb_watchdog - Watchdog for USB communication
drivers/net/wireless/rt2x00/rt61pci.c +105 -49

185 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt73usb.c +55 -29

115 lines not on this page · raw message

Signature · 1 line
1.7.2.3
#8 lore raw

PATCH 9/17 rt2x00: Reorganize queue callback functions

As part of the queue refactoring, change the queue callback function names to have 3 different actions: start, kick & stop.

We can now also remove the STATE_RADIO_RX_ON/STATE_RADIO_RX_OFF device_state flags, and replace the usage with using the start_queue/stop_queue callback functions.
This streamlines the RX queue handling to the
similar approach as all other queues.

---
 drivers/net/wireless/rt2x00/rt2400pci.c    |   11 +++--------
 drivers/net/wireless/rt2x00/rt2500pci.c    |   11 +++--------
 drivers/net/wireless/rt2x00/rt2500usb.c    |   11 +++--------
 drivers/net/wireless/rt2x00/rt2800pci.c    |   11 +++--------
 drivers/net/wireless/rt2x00/rt2800usb.c    |   11 +++--------
 drivers/net/wireless/rt2x00/rt2x00.h       |    9 +++++++--
 drivers/net/wireless/rt2x00/rt2x00config.c |    6 ++----
 drivers/net/wireless/rt2x00/rt2x00dev.c    |    4 ++--
 drivers/net/wireless/rt2x00/rt2x00mac.c    |    6 +++---
 drivers/net/wireless/rt2x00/rt2x00queue.c  |    6 +++---
 drivers/net/wireless/rt2x00/rt2x00reg.h    |    2 --
 drivers/net/wireless/rt2x00/rt2x00usb.c    |   24 +++++++++++++++---------
 drivers/net/wireless/rt2x00/rt2x00usb.h    |    4 ++--
 drivers/net/wireless/rt2x00/rt61pci.c      |   11 +++--------
 drivers/net/wireless/rt2x00/rt73usb.c      |   11 +++--------
 15 files changed, 55 insertions(+), 83 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +3 -8
index 35d9a06..2fc6ca5 100644
@@ -1058,12 +1058,6 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 	case STATE_RADIO_OFF:
 		rt2400pci_disable_radio(rt2x00dev);
 		break;
-	case STATE_RADIO_RX_ON:
-		rt2400pci_start_queue(rt2x00dev->rx);
-		break;
-	case STATE_RADIO_RX_OFF:
-		rt2400pci_stop_queue(rt2x00dev->rx);
-		break;
 	case STATE_RADIO_IRQ_ON:
 	case STATE_RADIO_IRQ_ON_ISR:
 	case STATE_RADIO_IRQ_OFF:
@@ -1672,10 +1666,11 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
 	.link_stats		= rt2400pci_link_stats,
 	.reset_tuner		= rt2400pci_reset_tuner,
 	.link_tuner		= rt2400pci_link_tuner,
+	.start_queue		= rt2400pci_start_queue,
+	.kick_queue		= rt2400pci_kick_queue,
+	.stop_queue		= rt2400pci_stop_queue,
 	.write_tx_desc		= rt2400pci_write_tx_desc,
 	.write_beacon		= rt2400pci_write_beacon,
-	.kick_tx_queue		= rt2400pci_kick_queue,
-	.kill_tx_queue		= rt2400pci_stop_queue,
 	.fill_rxdone		= rt2400pci_fill_rxdone,
 	.config_filter		= rt2400pci_config_filter,
 	.config_intf		= rt2400pci_config_intf,
drivers/net/wireless/rt2x00/rt2500pci.c +3 -8
index bee7ce1..d67f911 100644
@@ -1213,12 +1213,6 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 	case STATE_RADIO_OFF:
 		rt2500pci_disable_radio(rt2x00dev);
 		break;
-	case STATE_RADIO_RX_ON:
-		rt2500pci_start_queue(rt2x00dev->rx);
-		break;
-	case STATE_RADIO_RX_OFF:
-		rt2500pci_stop_queue(rt2x00dev->rx);
-		break;
 	case STATE_RADIO_IRQ_ON:
 	case STATE_RADIO_IRQ_ON_ISR:
 	case STATE_RADIO_IRQ_OFF:
@@ -1969,10 +1963,11 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
 	.link_stats		= rt2500pci_link_stats,
 	.reset_tuner		= rt2500pci_reset_tuner,
 	.link_tuner		= rt2500pci_link_tuner,
+	.start_queue		= rt2500pci_start_queue,
+	.kick_queue		= rt2500pci_kick_queue,
+	.stop_queue		= rt2500pci_stop_queue,
 	.write_tx_desc		= rt2500pci_write_tx_desc,
 	.write_beacon		= rt2500pci_write_beacon,
-	.kick_tx_queue		= rt2500pci_kick_queue,
-	.kill_tx_queue		= rt2500pci_stop_queue,
 	.fill_rxdone		= rt2500pci_fill_rxdone,
 	.config_filter		= rt2500pci_config_filter,
 	.config_intf		= rt2500pci_config_intf,
drivers/net/wireless/rt2x00/rt2500usb.c +3 -8
index 52bd0ed..a56b38f 100644
@@ -1057,12 +1057,6 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
 	case STATE_RADIO_OFF:
 		rt2500usb_disable_radio(rt2x00dev);
 		break;
-	case STATE_RADIO_RX_ON:
-		rt2500usb_start_queue(rt2x00dev->rx);
-		break;
-	case STATE_RADIO_RX_OFF:
-		rt2500usb_stop_queue(rt2x00dev->rx);
-		break;
 	case STATE_RADIO_IRQ_ON:
 	case STATE_RADIO_IRQ_ON_ISR:
 	case STATE_RADIO_IRQ_OFF:
@@ -1845,11 +1839,12 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
 	.link_stats		= rt2500usb_link_stats,
 	.reset_tuner		= rt2500usb_reset_tuner,
 	.watchdog		= rt2x00usb_watchdog,
+	.start_queue		= rt2500usb_start_queue,
+	.kick_queue		= rt2x00usb_kick_queue,
+	.stop_queue		= rt2500usb_stop_queue,
 	.write_tx_desc		= rt2500usb_write_tx_desc,
 	.write_beacon		= rt2500usb_write_beacon,
 	.get_tx_data_len	= rt2500usb_get_tx_data_len,
-	.kick_tx_queue		= rt2x00usb_kick_tx_queue,
-	.kill_tx_queue		= rt2500usb_stop_queue,
 	.fill_rxdone		= rt2500usb_fill_rxdone,
 	.config_shared_key	= rt2500usb_config_key,
 	.config_pairwise_key	= rt2500usb_config_key,
drivers/net/wireless/rt2x00/rt2800pci.c +3 -8
index 08b55b5..195f0be3 100644
@@ -537,12 +537,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 		rt2800pci_disable_radio(rt2x00dev);
 		rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
 		break;
-	case STATE_RADIO_RX_ON:
-		rt2800pci_start_queue(rt2x00dev->rx);
-		break;
-	case STATE_RADIO_RX_OFF:
-		rt2800pci_stop_queue(rt2x00dev->rx);
-		break;
 	case STATE_RADIO_IRQ_ON:
 	case STATE_RADIO_IRQ_ON_ISR:
 	case STATE_RADIO_IRQ_OFF:
@@ -1003,11 +997,12 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
 	.link_stats		= rt2800_link_stats,
 	.reset_tuner		= rt2800_reset_tuner,
 	.link_tuner		= rt2800_link_tuner,
+	.start_queue		= rt2800pci_start_queue,
+	.kick_queue		= rt2800pci_kick_queue,
+	.stop_queue		= rt2800pci_stop_queue,
 	.write_tx_desc		= rt2800pci_write_tx_desc,
 	.write_tx_data		= rt2800_write_tx_data,
 	.write_beacon		= rt2800_write_beacon,
-	.kick_tx_queue		= rt2800pci_kick_queue,
-	.kill_tx_queue		= rt2800pci_stop_queue,
 	.fill_rxdone		= rt2800pci_fill_rxdone,
 	.config_shared_key	= rt2800_config_shared_key,
 	.config_pairwise_key	= rt2800_config_pairwise_key,
drivers/net/wireless/rt2x00/rt2800usb.c +3 -8
index ee51936..60b5503 100644
@@ -254,12 +254,6 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
 		rt2800usb_disable_radio(rt2x00dev);
 		rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
 		break;
-	case STATE_RADIO_RX_ON:
-		rt2800usb_start_queue(rt2x00dev->rx);
-		break;
-	case STATE_RADIO_RX_OFF:
-		rt2800usb_stop_queue(rt2x00dev->rx);
-		break;
 	case STATE_RADIO_IRQ_ON:
 	case STATE_RADIO_IRQ_ON_ISR:
 	case STATE_RADIO_IRQ_OFF:
@@ -626,12 +620,13 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
 	.reset_tuner		= rt2800_reset_tuner,
 	.link_tuner		= rt2800_link_tuner,
 	.watchdog		= rt2800usb_watchdog,
+	.start_queue		= rt2800usb_start_queue,
+	.kick_queue		= rt2x00usb_kick_queue,
+	.stop_queue		= rt2800usb_stop_queue,
 	.write_tx_desc		= rt2800usb_write_tx_desc,
 	.write_tx_data		= rt2800usb_write_tx_data,
 	.write_beacon		= rt2800_write_beacon,
 	.get_tx_data_len	= rt2800usb_get_tx_data_len,
-	.kick_tx_queue		= rt2x00usb_kick_tx_queue,
-	.kill_tx_queue		= rt2800usb_stop_queue,
 	.fill_rxdone		= rt2800usb_fill_rxdone,
 	.config_shared_key	= rt2800_config_shared_key,
 	.config_pairwise_key	= rt2800_config_pairwise_key,
drivers/net/wireless/rt2x00/rt2x00.h +7 -2
index 0a55eef..617d68f 100644
@@ -567,7 +567,14 @@ struct rt2x00lib_ops {
 			     struct link_qual *qual);
 	void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
 			    struct link_qual *qual, const u32 count);
+
+	/*
+	 * Data queue handlers.
+	 */
 	void (*watchdog) (struct rt2x00_dev *rt2x00dev);
+	void (*start_queue) (struct data_queue *queue);
+	void (*kick_queue) (struct data_queue *queue);
+	void (*stop_queue) (struct data_queue *queue);
 
 	/*
 	 * TX control handlers
@@ -579,8 +586,6 @@ struct rt2x00lib_ops {
 	void (*write_beacon) (struct queue_entry *entry,
 			      struct txentry_desc *txdesc);
 	int (*get_tx_data_len) (struct queue_entry *entry);
-	void (*kick_tx_queue) (struct data_queue *queue);
-	void (*kill_tx_queue) (struct data_queue *queue);
 
 	/*
 	 * RX control handlers
drivers/net/wireless/rt2x00/rt2x00config.c +2 -4
index a238e90..d2f1f0a 100644
@@ -146,8 +146,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
 	 * else the changes will be ignored by the device.
 	 */
 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-		rt2x00dev->ops->lib->set_device_state(rt2x00dev,
-						      STATE_RADIO_RX_OFF);
+		rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
 
 	/*
 	 * Write new antenna setup to device and reset the link tuner.
@@ -161,8 +160,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
 	memcpy(active, &config, sizeof(config));
 
 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-		rt2x00dev->ops->lib->set_device_state(rt2x00dev,
-						      STATE_RADIO_RX_ON);
+		rt2x00dev->ops->lib->start_queue(rt2x00dev->rx);
 }
 
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
drivers/net/wireless/rt2x00/rt2x00dev.c +2 -2
index c879f9a..8d864b6 100644
@@ -68,7 +68,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Enable RX.
 	 */
-	rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON);
+	rt2x00dev->ops->lib->start_queue(rt2x00dev->rx);
 	rt2x00link_start_tuner(rt2x00dev);
 
 	/*
@@ -104,7 +104,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
 	 * Disable RX.
 	 */
 	rt2x00link_stop_tuner(rt2x00dev);
-	rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF);
+	rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
 
 	/*
 	 * Disable radio.
drivers/net/wireless/rt2x00/rt2x00mac.c +3 -3
index 7ad4b27..6713f1a 100644
@@ -352,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 	 * if for any reason the link tuner must be reset, this will be
 	 * handled by rt2x00lib_config().
 	 */
-	rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF);
+	rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
 
 	/*
 	 * When we've just turned on the radio, we want to reprogram
@@ -370,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 	rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
 
 	/* Turn RX back on */
-	rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON);
+	rt2x00dev->ops->lib->start_queue(rt2x00dev->rx);
 
 	return 0;
 }
@@ -727,7 +727,7 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
 	 * any pending frames to be transmitted.
 	 */
 	tx_queue_for_each(rt2x00dev, queue) {
-		rt2x00dev->ops->lib->kick_tx_queue(queue);
+		rt2x00dev->ops->lib->kick_queue(queue);
 	}
 
 	/**
drivers/net/wireless/rt2x00/rt2x00queue.c +3 -3
index 35133d8..2af6cea 100644
@@ -471,7 +471,7 @@ static void rt2x00queue_kick_tx_queue(struct data_queue *queue,
 	 */
 	if (rt2x00queue_threshold(queue) ||
 	    !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
-		queue->rt2x00dev->ops->lib->kick_tx_queue(queue);
+		queue->rt2x00dev->ops->lib->kick_queue(queue);
 }
 
 int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
@@ -585,7 +585,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
 	rt2x00queue_free_skb(intf->beacon);
 
 	if (!enable_beacon) {
-		rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
+		rt2x00dev->ops->lib->stop_queue(intf->beacon->queue);
 		mutex_unlock(&intf->beacon_skb_mutex);
 		return 0;
 	}
@@ -761,7 +761,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
 	struct data_queue *queue;
 
 	txall_queue_for_each(rt2x00dev, queue)
-		rt2x00dev->ops->lib->kill_tx_queue(queue);
+		rt2x00dev->ops->lib->stop_queue(queue);
 }
 
 void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
drivers/net/wireless/rt2x00/rt2x00reg.h +0 -2
index ed71be9..e8259ae 100644
@@ -83,8 +83,6 @@ enum dev_state {
  */
 	STATE_RADIO_ON,
 	STATE_RADIO_OFF,
-	STATE_RADIO_RX_ON,
-	STATE_RADIO_RX_OFF,
 	STATE_RADIO_IRQ_ON,
 	STATE_RADIO_IRQ_OFF,
 	STATE_RADIO_IRQ_ON_ISR,
drivers/net/wireless/rt2x00/rt2x00usb.c +15 -9
index 12958a4..d4361dc 100644
@@ -261,12 +261,22 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
 	}
 }
 
-void rt2x00usb_kick_tx_queue(struct data_queue *queue)
+void rt2x00usb_kick_queue(struct data_queue *queue)
 {
-	rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
-				   rt2x00usb_kick_tx_entry);
+	switch (queue->qid) {
+	case QID_AC_BE:
+	case QID_AC_BK:
+	case QID_AC_VI:
+	case QID_AC_VO:
+		if (!rt2x00queue_empty(queue))
+			rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+						   rt2x00usb_kick_tx_entry);
+		break;
+	default:
+		break;
+	}
 }
-EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
+EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
 
 static void rt2x00usb_kill_entry(struct queue_entry *entry)
 {
@@ -422,11 +432,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
 	rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
 				    REGISTER_TIMEOUT);
 
-	/*
-	 * The USB version of also works
-	 * on the RX queue.
-	 */
-	rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx);
+	rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
 
drivers/net/wireless/rt2x00/rt2x00usb.h +2 -2
index 656a35f..05a5424 100644
@@ -378,13 +378,13 @@ struct queue_entry_priv_usb_bcn {
 };
 
 /**
- * rt2x00usb_kick_tx_queue - Kick data queue
+ * rt2x00usb_kick_queue - Kick data queue
  * @queue: Data queue to kick
  *
  * This will walk through all entries of the queue and push all pending
  * frames to the hardware as a single burst.
  */
-void rt2x00usb_kick_tx_queue(struct data_queue *queue);
+void rt2x00usb_kick_queue(struct data_queue *queue);
 
 /**
  * rt2x00usb_stop_queue - Stop data queue
drivers/net/wireless/rt2x00/rt61pci.c +3 -8
index 044f500..7156b78 100644
@@ -1832,12 +1832,6 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 	case STATE_RADIO_OFF:
 		rt61pci_disable_radio(rt2x00dev);
 		break;
-	case STATE_RADIO_RX_ON:
-		rt61pci_start_queue(rt2x00dev->rx);
-		break;
-	case STATE_RADIO_RX_OFF:
-		rt61pci_stop_queue(rt2x00dev->rx);
-		break;
 	case STATE_RADIO_IRQ_ON:
 	case STATE_RADIO_IRQ_ON_ISR:
 	case STATE_RADIO_IRQ_OFF:
@@ -2900,10 +2894,11 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
 	.link_stats		= rt61pci_link_stats,
 	.reset_tuner		= rt61pci_reset_tuner,
 	.link_tuner		= rt61pci_link_tuner,
+	.start_queue		= rt61pci_start_queue,
+	.kick_queue		= rt61pci_kick_queue,
+	.stop_queue		= rt61pci_stop_queue,
 	.write_tx_desc		= rt61pci_write_tx_desc,
 	.write_beacon		= rt61pci_write_beacon,
-	.kick_tx_queue		= rt61pci_kick_queue,
-	.kill_tx_queue		= rt61pci_stop_queue,
 	.fill_rxdone		= rt61pci_fill_rxdone,
 	.config_shared_key	= rt61pci_config_shared_key,
 	.config_pairwise_key	= rt61pci_config_pairwise_key,
drivers/net/wireless/rt2x00/rt73usb.c +3 -8
index e9b1e3d..f55e74e 100644
@@ -1441,12 +1441,6 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
 	case STATE_RADIO_OFF:
 		rt73usb_disable_radio(rt2x00dev);
 		break;
-	case STATE_RADIO_RX_ON:
-		rt73usb_start_queue(rt2x00dev->rx);
-		break;
-	case STATE_RADIO_RX_OFF:
-		rt73usb_stop_queue(rt2x00dev->rx);
-		break;
 	case STATE_RADIO_IRQ_ON:
 	case STATE_RADIO_IRQ_ON_ISR:
 	case STATE_RADIO_IRQ_OFF:
@@ -2312,11 +2306,12 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
 	.reset_tuner		= rt73usb_reset_tuner,
 	.link_tuner		= rt73usb_link_tuner,
 	.watchdog		= rt2x00usb_watchdog,
+	.start_queue		= rt73usb_start_queue,
+	.kick_queue		= rt2x00usb_kick_queue,
+	.stop_queue		= rt73usb_stop_queue,
 	.write_tx_desc		= rt73usb_write_tx_desc,
 	.write_beacon		= rt73usb_write_beacon,
 	.get_tx_data_len	= rt73usb_get_tx_data_len,
-	.kick_tx_queue		= rt2x00usb_kick_tx_queue,
-	.kill_tx_queue		= rt73usb_stop_queue,
 	.fill_rxdone		= rt73usb_fill_rxdone,
 	.config_shared_key	= rt73usb_config_shared_key,
 	.config_pairwise_key	= rt73usb_config_pairwise_key,
Signature · 1 line
1.7.2.3
#9 lore raw

PATCH 10/17 rt2x00: Protect queue control with mutex

Add wrapper functions in rt2x00queue.c to start & stop queues. This control must be protected using a mutex.

Queues can also be paused which will halt the flow of packets between the driver and mac80211. This doesn't require a mutex protection.

---
 drivers/net/wireless/rt2x00/rt2x00.h       |   52 ++++++++
 drivers/net/wireless/rt2x00/rt2x00config.c |    4 +-
 drivers/net/wireless/rt2x00/rt2x00debug.c  |    5 +-
 drivers/net/wireless/rt2x00/rt2x00dev.c    |   22 +---
 drivers/net/wireless/rt2x00/rt2x00lib.h    |    9 --
 drivers/net/wireless/rt2x00/rt2x00mac.c    |    8 +-
 drivers/net/wireless/rt2x00/rt2x00queue.c  |  130 ++++++++++++++++++--
 drivers/net/wireless/rt2x00/rt2x00queue.h  |   23 ++++
 drivers/net/wireless/rt2x00/rt2x00usb.c    |  190 ++++++++++++++--------------
 9 files changed, 302 insertions(+), 141 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +52 -0
index 617d68f..511ca91 100644
@@ -1072,6 +1072,58 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
 struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
 					  enum queue_index index);
 
+/**
+ * rt2x00queue_pause_queue - Pause a data queue
+ * @queue: Pointer to &struct data_queue.
+ *
+ * This function will pause the data queue locally, preventing
+ * new frames to be added to the queue (while the hardware is
+ * still allowed to run).
+ */
+void rt2x00queue_pause_queue(struct data_queue *queue);
+
+/**
+ * rt2x00queue_unpause_queue - unpause a data queue
+ * @queue: Pointer to &struct data_queue.
+ *
+ * This function will unpause the data queue locally, allowing
+ * new frames to be added to the queue again.
+ */
+void rt2x00queue_unpause_queue(struct data_queue *queue);
+
+/**
+ * rt2x00queue_start_queue - Start a data queue
+ * @queue: Pointer to &struct data_queue.
+ *
+ * This function will start handling all pending frames in the queue.
+ */
+void rt2x00queue_start_queue(struct data_queue *queue);
+
+/**
+ * rt2x00queue_stop_queue - Halt a data queue
+ * @queue: Pointer to &struct data_queue.
+ *
+ * This function will stop all pending frames in the queue.
+ */
+void rt2x00queue_stop_queue(struct data_queue *queue);
+
+/**
+ * rt2x00queue_start_queues - Start all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This function will loop through all available queues to start them
+ */
+void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00queue_stop_queues - Halt all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This function will loop through all available queues to stop
+ * any pending frames.
+ */
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
+
 /*
  * Debugfs handlers.
  */
drivers/net/wireless/rt2x00/rt2x00config.c +2 -2
index d2f1f0a..70ca937 100644
@@ -146,7 +146,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
 	 * else the changes will be ignored by the device.
 	 */
 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-		rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
+		rt2x00queue_stop_queue(rt2x00dev->rx);
 
 	/*
 	 * Write new antenna setup to device and reset the link tuner.
@@ -160,7 +160,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
 	memcpy(active, &config, sizeof(config));
 
 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-		rt2x00dev->ops->lib->start_queue(rt2x00dev->rx);
+		rt2x00queue_start_queue(rt2x00dev->rx);
 }
 
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
drivers/net/wireless/rt2x00/rt2x00debug.c +3 -2
index 64dfb1f..c92db32 100644
@@ -339,12 +339,13 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
 		return -ENOMEM;
 
 	temp = data +
-	    sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
+	    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);
 
-		temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
+		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,
 				queue->count, queue->limit, queue->length,
 				queue->index[Q_INDEX],
 				queue->index[Q_INDEX_DMA_DONE],
drivers/net/wireless/rt2x00/rt2x00dev.c +5 -17
index 8d864b6..fbc98dd 100644
@@ -66,9 +66,9 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
 	set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
 
 	/*
-	 * Enable RX.
+	 * Enable queues.
 	 */
-	rt2x00dev->ops->lib->start_queue(rt2x00dev->rx);
+	rt2x00queue_start_queues(rt2x00dev);
 	rt2x00link_start_tuner(rt2x00dev);
 
 	/*
@@ -76,11 +76,6 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
 	 */
 	rt2x00link_start_watchdog(rt2x00dev);
 
-	/*
-	 * Start the TX queues.
-	 */
-	ieee80211_wake_queues(rt2x00dev->hw);
-
 	return 0;
 }
 
@@ -90,21 +85,15 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
 		return;
 
 	/*
-	 * Stop the TX queues in mac80211.
-	 */
-	ieee80211_stop_queues(rt2x00dev->hw);
-	rt2x00queue_stop_queues(rt2x00dev);
-
-	/*
 	 * Stop watchdog monitoring.
 	 */
 	rt2x00link_stop_watchdog(rt2x00dev);
 
 	/*
-	 * Disable RX.
+	 * Stop all queues
 	 */
 	rt2x00link_stop_tuner(rt2x00dev);
-	rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
+	rt2x00queue_stop_queues(rt2x00dev);
 
 	/*
 	 * Disable radio.
@@ -249,7 +238,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
-	enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
 	unsigned int header_length, i;
 	u8 rate_idx, rate_flags, retry_rates;
 	u8 skbdesc_flags = skbdesc->flags;
@@ -400,7 +388,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	 * is reenabled when the txdone handler has finished.
 	 */
 	if (!rt2x00queue_threshold(entry->queue))
-		ieee80211_wake_queue(rt2x00dev->hw, qid);
+		rt2x00queue_unpause_queue(entry->queue);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
 
drivers/net/wireless/rt2x00/rt2x00lib.h +0 -9
index 2cf68f8..a105c50 100644
@@ -178,15 +178,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
 void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
 
 /**
- * rt2x00queue_stop_queues - Halt all data queues
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- *
- * This function will loop through all available queues to stop
- * any pending outgoing frames.
- */
-void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
-
-/**
  * rt2x00queue_init_queues - Initialize all data queues
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
  *
drivers/net/wireless/rt2x00/rt2x00mac.c +4 -4
index 6713f1a..c4abb20 100644
@@ -104,7 +104,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	enum data_queue_qid qid = skb_get_queue_mapping(skb);
-	struct data_queue *queue;
+	struct data_queue *queue = NULL;
 
 	/*
 	 * Mac80211 might be calling this function while we are trying
@@ -153,7 +153,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 		goto exit_fail;
 
 	if (rt2x00queue_threshold(queue))
-		ieee80211_stop_queue(rt2x00dev->hw, qid);
+		rt2x00queue_pause_queue(queue);
 
 	return NETDEV_TX_OK;
 
@@ -352,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 	 * if for any reason the link tuner must be reset, this will be
 	 * handled by rt2x00lib_config().
 	 */
-	rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
+	rt2x00queue_stop_queue(rt2x00dev->rx);
 
 	/*
 	 * When we've just turned on the radio, we want to reprogram
@@ -370,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 	rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
 
 	/* Turn RX back on */
-	rt2x00dev->ops->lib->start_queue(rt2x00dev->rx);
+	rt2x00queue_start_queue(rt2x00dev->rx);
 
 	return 0;
 }
drivers/net/wireless/rt2x00/rt2x00queue.c +121 -9

154 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2x00queue.h +23 -0
index 29b051a..baa39b7 100644
@@ -392,12 +392,32 @@ enum queue_index {
 };
 
 /**
+ * enum data_queue_flags: Status flags for data queues
+ *
+ * @QUEUE_STARTED: The queue has been started. Fox RX queues this means the
+ *	device might be DMA'ing skbuffers. TX queues will accept skbuffers to
+ *	be transmitted and beacon queues will start beaconing the configured
+ *	beacons.
+ * @QUEUE_PAUSED: The queue has been started but is currently paused.
+ *	When this bit is set, the queue has been stopped in mac80211,
+ *	preventing new frames to be enqueued. However, a few frames
+ *	might still appear shortly after the pausing...
+ */
+enum data_queue_flags {
+	QUEUE_STARTED,
+	QUEUE_PAUSED,
+};
+
+/**
  * struct data_queue: Data queue
  *
  * @rt2x00dev: Pointer to main &struct rt2x00dev where this queue belongs to.
  * @entries: Base address of the &struct queue_entry which are
  *	part of this queue.
  * @qid: The queue identification, see &enum data_queue_qid.
+ * @flags: Entry flags, see &enum queue_entry_flags.
+ * @status_lock: The mutex for protecting the start/stop/flush
+ *	handling on this queue.
  * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or
  *	@index_crypt needs to be changed this lock should be grabbed to prevent
  *	index corruption due to concurrency.
@@ -421,8 +441,11 @@ struct data_queue {
 	struct queue_entry *entries;
 
 	enum data_queue_qid qid;
+	unsigned long flags;
 
+	struct mutex status_lock;
 	spinlock_t index_lock;
+
 	unsigned int count;
 	unsigned short limit;
 	unsigned short threshold;
drivers/net/wireless/rt2x00/rt2x00usb.c +92 -98

241 lines not on this page · raw message

Signature · 1 line
1.7.2.3
#10 lore raw

PATCH 11/17 rt2x00: Add "flush" queue command

Add a new command to the queue handlers: "flush", this moves the flush() callback from mac80211 into rt2x00queue and adds support for flushing the RX queue as well.

---
 drivers/net/wireless/rt2x00/rt2500usb.c   |    3 +-
 drivers/net/wireless/rt2x00/rt2800usb.c   |    3 +-
 drivers/net/wireless/rt2x00/rt2x00.h      |   21 +++++++
 drivers/net/wireless/rt2x00/rt2x00dev.c   |    1 +
 drivers/net/wireless/rt2x00/rt2x00mac.c   |   32 +----------
 drivers/net/wireless/rt2x00/rt2x00queue.c |   85 +++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2x00usb.c   |   70 ++++++++++++++++--------
 drivers/net/wireless/rt2x00/rt2x00usb.h   |    4 +-
 drivers/net/wireless/rt2x00/rt73usb.c     |    3 +-
 9 files changed, 161 insertions(+), 61 deletions(-)
drivers/net/wireless/rt2x00/rt2500usb.c +1 -2
index a56b38f..6b3b1de4 100644
@@ -785,8 +785,6 @@ static void rt2500usb_stop_queue(struct data_queue *queue)
 	default:
 		break;
 	}
-
-	rt2x00usb_stop_queue(queue);
 }
 
 /*
@@ -1842,6 +1840,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
 	.start_queue		= rt2500usb_start_queue,
 	.kick_queue		= rt2x00usb_kick_queue,
 	.stop_queue		= rt2500usb_stop_queue,
+	.flush_queue		= rt2x00usb_flush_queue,
 	.write_tx_desc		= rt2500usb_write_tx_desc,
 	.write_beacon		= rt2500usb_write_beacon,
 	.get_tx_data_len	= rt2500usb_get_tx_data_len,
drivers/net/wireless/rt2x00/rt2800usb.c +1 -2
index 60b5503..3e0205d 100644
@@ -96,8 +96,6 @@ static void rt2800usb_stop_queue(struct data_queue *queue)
 	default:
 		break;
 	}
-
-	rt2x00usb_stop_queue(queue);
 }
 
 /*
@@ -623,6 +621,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
 	.start_queue		= rt2800usb_start_queue,
 	.kick_queue		= rt2x00usb_kick_queue,
 	.stop_queue		= rt2800usb_stop_queue,
+	.flush_queue		= rt2x00usb_flush_queue,
 	.write_tx_desc		= rt2800usb_write_tx_desc,
 	.write_tx_data		= rt2800usb_write_tx_data,
 	.write_beacon		= rt2800_write_beacon,
drivers/net/wireless/rt2x00/rt2x00.h +21 -0
index 511ca91..520e736 100644
@@ -575,6 +575,7 @@ struct rt2x00lib_ops {
 	void (*start_queue) (struct data_queue *queue);
 	void (*kick_queue) (struct data_queue *queue);
 	void (*stop_queue) (struct data_queue *queue);
+	void (*flush_queue) (struct data_queue *queue);
 
 	/*
 	 * TX control handlers
@@ -1108,6 +1109,16 @@ void rt2x00queue_start_queue(struct data_queue *queue);
 void rt2x00queue_stop_queue(struct data_queue *queue);
 
 /**
+ * rt2x00queue_flush_queue - Flush a data queue
+ * @queue: Pointer to &struct data_queue.
+ * @drop: True to drop all pending frames.
+ *
+ * This function will flush the queue. After this call
+ * the queue is guarenteed to be empty.
+ */
+void rt2x00queue_flush_queue(struct data_queue *queue, bool drop);
+
+/**
  * rt2x00queue_start_queues - Start all data queues
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
  *
@@ -1124,6 +1135,16 @@ void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev);
  */
 void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
 
+/**
+ * rt2x00queue_flush_queues - Flush all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @drop: True to drop all pending frames.
+ *
+ * This function will loop through all available queues to flush
+ * any pending frames.
+ */
+void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop);
+
 /*
  * Debugfs handlers.
  */
drivers/net/wireless/rt2x00/rt2x00dev.c +1 -0
index fbc98dd..01c8415 100644
@@ -94,6 +94,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
 	 */
 	rt2x00link_stop_tuner(rt2x00dev);
 	rt2x00queue_stop_queues(rt2x00dev);
+	rt2x00queue_flush_queues(rt2x00dev, true);
 
 	/*
 	 * Disable radio.
drivers/net/wireless/rt2x00/rt2x00mac.c +2 -30
index c4abb20..4cac7ad 100644
@@ -718,36 +718,8 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 	struct data_queue *queue;
-	unsigned int i = 0;
 
-	ieee80211_stop_queues(hw);
-
-	/*
-	 * Run over all queues to kick them, this will force
-	 * any pending frames to be transmitted.
-	 */
-	tx_queue_for_each(rt2x00dev, queue) {
-		rt2x00dev->ops->lib->kick_queue(queue);
-	}
-
-	/**
-	 * All queues have been kicked, now wait for each queue
-	 * to become empty. With a bit of luck, we only have to wait
-	 * for the first queue to become empty, because while waiting
-	 * for the that queue, the other queues will have transmitted
-	 * all their frames as well (since they were already kicked).
-	 */
-	tx_queue_for_each(rt2x00dev, queue) {
-		for (i = 0; i < 10; i++) {
-			if (rt2x00queue_empty(queue))
-				break;
-			msleep(100);
-		}
-
-		if (!rt2x00queue_empty(queue))
-			WARNING(rt2x00dev, "Failed to flush queue %d\n", queue->qid);
-	}
-
-	ieee80211_wake_queues(hw);
+	tx_queue_for_each(rt2x00dev, queue)
+		rt2x00queue_flush_queue(queue, drop);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_flush);
drivers/net/wireless/rt2x00/rt2x00queue.c +85 -0

103 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2x00usb.c +47 -23

91 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2x00usb.h +2 -2
index 05a5424..6aaf51f 100644
@@ -387,13 +387,13 @@ struct queue_entry_priv_usb_bcn {
 void rt2x00usb_kick_queue(struct data_queue *queue);
 
 /**
- * rt2x00usb_stop_queue - Stop data queue
+ * rt2x00usb_flush_queue - Flush data queue
  * @queue: Data queue to stop
  *
  * This will walk through all entries of the queue and kill all
  * URB's which were send to the device.
  */
-void rt2x00usb_stop_queue(struct data_queue *queue);
+void rt2x00usb_flush_queue(struct data_queue *queue);
 
 /**
  * rt2x00usb_watchdog - Watchdog for USB communication
drivers/net/wireless/rt2x00/rt73usb.c +1 -2
index f55e74e..0b3959b 100644
@@ -1077,8 +1077,6 @@ static void rt73usb_stop_queue(struct data_queue *queue)
 	default:
 		break;
 	}
-
-	rt2x00usb_stop_queue(queue);
 }
 
 /*
@@ -2309,6 +2307,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
 	.start_queue		= rt73usb_start_queue,
 	.kick_queue		= rt2x00usb_kick_queue,
 	.stop_queue		= rt73usb_stop_queue,
+	.flush_queue		= rt2x00usb_flush_queue,
 	.write_tx_desc		= rt73usb_write_tx_desc,
 	.write_beacon		= rt73usb_write_beacon,
 	.get_tx_data_len	= rt73usb_get_tx_data_len,
Signature · 1 line
1.7.2.3
#11 lore raw

PATCH 12/17 rt2x00: Cleanup RX index counting

Add the rt2x00_dmastart function to rt2x00lib which marks the queue_entry as "owned by device", and increased the Q_INDEX number.

This cleanups up the index handling by rt2x00lib which at until so far used hackish approaches to keep the RX queue index numbering sane.

The rt2x00pci.c changes are from Helmut Schaa

---
 drivers/net/wireless/rt2x00/rt2x00.h      |    1 +
 drivers/net/wireless/rt2x00/rt2x00dev.c   |   11 ++++++++---
 drivers/net/wireless/rt2x00/rt2x00pci.c   |    7 +++++++
 drivers/net/wireless/rt2x00/rt2x00queue.c |    5 +----
 drivers/net/wireless/rt2x00/rt2x00usb.c   |    2 ++
 5 files changed, 19 insertions(+), 7 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +1 -0
index 520e736..556b744 100644
@@ -1170,6 +1170,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
  */
 void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
 void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev);
+void rt2x00lib_dmastart(struct queue_entry *entry);
 void rt2x00lib_dmadone(struct queue_entry *entry);
 void rt2x00lib_txdone(struct queue_entry *entry,
 		      struct txdone_entry_desc *txdesc);
drivers/net/wireless/rt2x00/rt2x00dev.c +8 -3
index 01c8415..f3ae949 100644
@@ -226,6 +226,13 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
 
+void rt2x00lib_dmastart(struct queue_entry *entry)
+{
+	set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+	rt2x00queue_index_inc(entry->queue, Q_INDEX);
+}
+EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
+
 void rt2x00lib_dmadone(struct queue_entry *entry)
 {
 	clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
@@ -552,10 +559,8 @@ submit_entry:
 	entry->flags = 0;
 	rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
 	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
-	    test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
+	    test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
 		rt2x00dev->ops->lib->clear_entry(entry);
-		rt2x00queue_index_inc(entry->queue, Q_INDEX);
-	}
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
 
drivers/net/wireless/rt2x00/rt2x00pci.c +7 -0
index 868ca19..28e6ff1 100644
@@ -82,6 +82,13 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 		skbdesc->desc_len = entry->queue->desc_size;
 
 		/*
+		 * DMA is already done, notify rt2x00lib that
+		 * it finished successfully.
+		 */
+		rt2x00lib_dmastart(entry);
+		rt2x00lib_dmadone(entry);
+
+		/*
 		 * Send the frame to rt2x00lib for further processing.
 		 */
 		rt2x00lib_rxdone(entry);
drivers/net/wireless/rt2x00/rt2x00queue.c +1 -4
index 313a8fa..52cc92d 100644
@@ -968,11 +968,8 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
 	queue_for_each(rt2x00dev, queue) {
 		rt2x00queue_reset(queue);
 
-		for (i = 0; i < queue->limit; i++) {
+		for (i = 0; i < queue->limit; i++)
 			rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
-			if (queue->qid == QID_RX)
-				rt2x00queue_index_inc(queue, Q_INDEX);
-		}
 	}
 }
 
drivers/net/wireless/rt2x00/rt2x00usb.c +2 -0
index cd80eec..cd29ebc 100644
@@ -330,6 +330,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
 	if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
 		return;
 
+	rt2x00lib_dmastart(entry);
+
 	usb_fill_bulk_urb(entry_priv->urb, usb_dev,
 			  usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint),
 			  entry->skb->data, entry->skb->len,
Signature · 1 line
1.7.2.3
#12 lore raw

PATCH 13/17 rt2x00: Introduce extra queue entry sanity flag

Add a queue entry flag ENTRY_DATA_STATUS_PENDING, which can be used to indicate a queue entry has returned from the hardware and is waiting for status processing. Using this flag we can add some extra sanity checks to prevent queue corruption.

---
 drivers/net/wireless/rt2x00/rt2x00dev.c   |    1 +
 drivers/net/wireless/rt2x00/rt2x00queue.h |    6 +++++-
 drivers/net/wireless/rt2x00/rt2x00usb.c   |   12 ++++++++----
 3 files changed, 14 insertions(+), 5 deletions(-)
drivers/net/wireless/rt2x00/rt2x00dev.c +1 -0
index f3ae949..87a421b 100644
@@ -235,6 +235,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
 
 void rt2x00lib_dmadone(struct queue_entry *entry)
 {
+	set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
 	clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
 	rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
 }
drivers/net/wireless/rt2x00/rt2x00queue.h +5 -1
index baa39b7..4765934 100644
@@ -340,12 +340,16 @@ struct txentry_desc {
  * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
  *	while transfering the data to the hardware. No TX status report will
  *	be expected from the hardware.
+ * @ENTRY_DATA_STATUS_PENDING: The entry has been send to the device and
+ *	returned. It is now waiting for the status reporting before the
+ *	entry can be reused again.
  */
 enum queue_entry_flags {
 	ENTRY_BCN_ASSIGNED,
 	ENTRY_OWNER_DEVICE_DATA,
 	ENTRY_DATA_PENDING,
-	ENTRY_DATA_IO_FAILED
+	ENTRY_DATA_IO_FAILED,
+	ENTRY_DATA_STATUS_PENDING,
 };
 
 /**
drivers/net/wireless/rt2x00/rt2x00usb.c +8 -4
index cd29ebc..8a16b51 100644
@@ -195,7 +195,8 @@ static void rt2x00usb_work_txdone(struct work_struct *work)
 		while (!rt2x00queue_empty(queue)) {
 			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 
-			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+			    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
 				break;
 
 			rt2x00usb_work_txdone_entry(entry);
@@ -237,7 +238,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
 	u32 length;
 	int status;
 
-	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
+	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
+	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
 		return;
 
 	/*
@@ -275,7 +277,8 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
 	while (!rt2x00queue_empty(rt2x00dev->rx)) {
 		entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
 
-		if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+		if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+		    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
 			break;
 
 		/*
@@ -327,7 +330,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
 	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
 	int status;
 
-	if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+	if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
 		return;
 
 	rt2x00lib_dmastart(entry);
Signature · 1 line
1.7.2.3
#13 lore raw

PATCH 14/17 rt2x00: Fix WMM Queue naming

The Queue names were incorrectly copied from the legacy drivers, as a result the queue names were inversed to what was expected.

This renames the queues using this mapping:

	QID_AC_BK -> QID_AC_VO (priority 0)
	QID_AC_BE -> QID_AC_VI (priority 1)
	QID_AC_VI -> QID_AC_BE (priority 2)
	QID_AC_VO -> QID_AC_BK (priority 3)

Note that this was a naming problem only, which didn't affect the assignment of frames to their respective queues.

---
 drivers/net/wireless/rt2x00/rt2400pci.c   |   12 +++---
 drivers/net/wireless/rt2x00/rt2500pci.c   |   12 +++---
 drivers/net/wireless/rt2x00/rt2800.h      |   44 ++++++++++----------
 drivers/net/wireless/rt2x00/rt2800pci.c   |    4 +-
 drivers/net/wireless/rt2x00/rt2x00queue.c |   18 ++++----
 drivers/net/wireless/rt2x00/rt2x00queue.h |   12 +++---
 drivers/net/wireless/rt2x00/rt2x00usb.c   |    8 ++--
 drivers/net/wireless/rt2x00/rt61pci.c     |   16 ++++----
 drivers/net/wireless/rt2x00/rt61pci.h     |   62 ++++++++++++++--------------
 drivers/net/wireless/rt2x00/rt73usb.h     |   36 ++++++++--------
 10 files changed, 112 insertions(+), 112 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +6 -6
index 2fc6ca5..54ca49a 100644
@@ -664,12 +664,12 @@ static void rt2400pci_kick_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
+	case QID_AC_VO:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
 		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 		break;
-	case QID_AC_BK:
+	case QID_AC_VI:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
 		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
@@ -690,8 +690,8 @@ static void rt2400pci_stop_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
-	case QID_AC_BK:
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_ATIM:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
@@ -1322,13 +1322,13 @@ static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance)
 	 * 4 - Priority ring transmit done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
-		rt2400pci_txdone(rt2x00dev, QID_AC_BE);
+		rt2400pci_txdone(rt2x00dev, QID_AC_VO);
 
 	/*
 	 * 5 - Tx ring transmit done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
-		rt2400pci_txdone(rt2x00dev, QID_AC_BK);
+		rt2400pci_txdone(rt2x00dev, QID_AC_VI);
 
 	/* Enable interrupts again. */
 	rt2x00dev->ops->lib->set_device_state(rt2x00dev,
drivers/net/wireless/rt2x00/rt2500pci.c +6 -6
index d67f911..a9ff26a 100644
@@ -754,12 +754,12 @@ static void rt2500pci_kick_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
+	case QID_AC_VO:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
 		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 		break;
-	case QID_AC_BK:
+	case QID_AC_VI:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
 		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
@@ -780,8 +780,8 @@ static void rt2500pci_stop_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
-	case QID_AC_BK:
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_ATIM:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
@@ -1455,13 +1455,13 @@ static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance)
 	 * 4 - Priority ring transmit done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
-		rt2500pci_txdone(rt2x00dev, QID_AC_BE);
+		rt2500pci_txdone(rt2x00dev, QID_AC_VO);
 
 	/*
 	 * 5 - Tx ring transmit done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
-		rt2500pci_txdone(rt2x00dev, QID_AC_BK);
+		rt2500pci_txdone(rt2x00dev, QID_AC_VI);
 
 	/* Enable interrupts again. */
 	rt2x00dev->ops->lib->set_device_state(rt2x00dev,
drivers/net/wireless/rt2x00/rt2800.h +22 -22

98 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt2800pci.c +2 -2
index 195f0be3..403013f 100644
@@ -217,10 +217,10 @@ static void rt2800pci_kick_queue(struct data_queue *queue)
 	struct queue_entry *entry;
 
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		entry = rt2x00queue_get_entry(queue, Q_INDEX);
 		rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx);
 		break;
drivers/net/wireless/rt2x00/rt2x00queue.c +9 -9
index 52cc92d..ca82b3a 100644
@@ -746,10 +746,10 @@ void rt2x00queue_pause_queue(struct data_queue *queue)
 		return;
 
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		/*
 		 * For TX queues, we have to disable the queue
 		 * inside mac80211.
@@ -770,10 +770,10 @@ void rt2x00queue_unpause_queue(struct data_queue *queue)
 		return;
 
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		/*
 		 * For TX queues, we have to enable the queue
 		 * inside mac80211.
@@ -834,10 +834,10 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
 	unsigned int i;
 	bool started;
 	bool tx_queue =
-		(queue->qid == QID_AC_BE) ||
-		(queue->qid == QID_AC_BK) ||
+		(queue->qid == QID_AC_VO) ||
 		(queue->qid == QID_AC_VI) ||
-		(queue->qid == QID_AC_VO);
+		(queue->qid == QID_AC_BE) ||
+		(queue->qid == QID_AC_BK);
 
 	mutex_lock(&queue->status_lock);
 
@@ -1141,7 +1141,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Initialize queue parameters.
 	 * RX: qid = QID_RX
-	 * TX: qid = QID_AC_BE + index
+	 * TX: qid = QID_AC_VO + index
 	 * TX: cw_min: 2^5 = 32.
 	 * TX: cw_max: 2^10 = 1024.
 	 * BCN: qid = QID_BEACON
@@ -1149,7 +1149,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
 	 */
 	rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX);
 
-	qid = QID_AC_BE;
+	qid = QID_AC_VO;
 	tx_queue_for_each(rt2x00dev, queue)
 		rt2x00queue_init(rt2x00dev, queue, qid++);
 
drivers/net/wireless/rt2x00/rt2x00queue.h +6 -6
index 4765934..fab8e26 100644
@@ -45,10 +45,10 @@
 /**
  * enum data_queue_qid: Queue identification
  *
+ * @QID_AC_VO: AC VO queue
+ * @QID_AC_VI: AC VI queue
  * @QID_AC_BE: AC BE queue
  * @QID_AC_BK: AC BK queue
- * @QID_AC_VI: AC VI queue
- * @QID_AC_VO: AC VO queue
  * @QID_HCCA: HCCA queue
  * @QID_MGMT: MGMT queue (prio queue)
  * @QID_RX: RX queue
@@ -57,10 +57,10 @@
  * @QID_ATIM: Atim queue (value unspeficied, don't send it to device)
  */
 enum data_queue_qid {
-	QID_AC_BE = 0,
-	QID_AC_BK = 1,
-	QID_AC_VI = 2,
-	QID_AC_VO = 3,
+	QID_AC_VO = 0,
+	QID_AC_VI = 1,
+	QID_AC_BE = 2,
+	QID_AC_BK = 3,
 	QID_HCCA = 4,
 	QID_MGMT = 13,
 	QID_RX = 14,
drivers/net/wireless/rt2x00/rt2x00usb.c +4 -4
index 8a16b51..1a9937d 100644
@@ -353,10 +353,10 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
 void rt2x00usb_kick_queue(struct data_queue *queue)
 {
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		if (!rt2x00queue_empty(queue))
 			rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
 						   rt2x00usb_kick_tx_entry);
@@ -403,10 +403,10 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
 	 * Obtain the queue completion handler
 	 */
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		completion = &queue->rt2x00dev->txdone_work;
 		break;
 	case QID_RX:
drivers/net/wireless/rt2x00/rt61pci.c +8 -8
index 7156b78..9405b10 100644
@@ -1171,22 +1171,22 @@ static void rt61pci_kick_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
+	case QID_AC_VO:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_BK:
+	case QID_AC_VI:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_VI:
+	case QID_AC_BE:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_VO:
+	case QID_AC_BK:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
@@ -1202,22 +1202,22 @@ static void rt61pci_stop_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
+	case QID_AC_VO:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_BK:
+	case QID_AC_VI:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_VI:
+	case QID_AC_BE:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_VO:
+	case QID_AC_BK:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
drivers/net/wireless/rt2x00/rt61pci.h +31 -31

125 lines not on this page · raw message

drivers/net/wireless/rt2x00/rt73usb.h +18 -18
index 1315ce5..9f6b470 100644
@@ -689,10 +689,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * AIFSN_CSR: AIFSN for each EDCA AC.
- * AIFSN0: For AC_BK.
- * AIFSN1: For AC_BE.
- * AIFSN2: For AC_VI.
- * AIFSN3: For AC_VO.
+ * AIFSN0: For AC_VO.
+ * AIFSN1: For AC_VI.
+ * AIFSN2: For AC_BE.
+ * AIFSN3: For AC_BK.
  */
 #define AIFSN_CSR			0x0400
 #define AIFSN_CSR_AIFSN0		FIELD32(0x0000000f)
@@ -702,10 +702,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * CWMIN_CSR: CWmin for each EDCA AC.
- * CWMIN0: For AC_BK.
- * CWMIN1: For AC_BE.
- * CWMIN2: For AC_VI.
- * CWMIN3: For AC_VO.
+ * CWMIN0: For AC_VO.
+ * CWMIN1: For AC_VI.
+ * CWMIN2: For AC_BE.
+ * CWMIN3: For AC_BK.
  */
 #define CWMIN_CSR			0x0404
 #define CWMIN_CSR_CWMIN0		FIELD32(0x0000000f)
@@ -715,10 +715,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * CWMAX_CSR: CWmax for each EDCA AC.
- * CWMAX0: For AC_BK.
- * CWMAX1: For AC_BE.
- * CWMAX2: For AC_VI.
- * CWMAX3: For AC_VO.
+ * CWMAX0: For AC_VO.
+ * CWMAX1: For AC_VI.
+ * CWMAX2: For AC_BE.
+ * CWMAX3: For AC_BK.
  */
 #define CWMAX_CSR			0x0408
 #define CWMAX_CSR_CWMAX0		FIELD32(0x0000000f)
@@ -727,18 +727,18 @@ struct hw_pairwise_ta_entry {
 #define CWMAX_CSR_CWMAX3		FIELD32(0x0000f000)
 
 /*
- * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register.
- * AC0_TX_OP: For AC_BK, in unit of 32us.
- * AC1_TX_OP: For AC_BE, in unit of 32us.
+ * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
+ * AC0_TX_OP: For AC_VO, in unit of 32us.
+ * AC1_TX_OP: For AC_VI, in unit of 32us.
  */
 #define AC_TXOP_CSR0			0x040c
 #define AC_TXOP_CSR0_AC0_TX_OP		FIELD32(0x0000ffff)
 #define AC_TXOP_CSR0_AC1_TX_OP		FIELD32(0xffff0000)
 
 /*
- * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register.
- * AC2_TX_OP: For AC_VI, in unit of 32us.
- * AC3_TX_OP: For AC_VO, in unit of 32us.
+ * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
+ * AC2_TX_OP: For AC_BE, in unit of 32us.
+ * AC3_TX_OP: For AC_BK, in unit of 32us.
  */
 #define AC_TXOP_CSR1			0x0410
 #define AC_TXOP_CSR1_AC2_TX_OP		FIELD32(0x0000ffff)
Signature · 1 line
1.7.2.3
#14 lore raw

PATCH 15/17 rt2x00: remove stray semicolon

From: Johannes Stezenbach <[email protected]>

The stray semicolon after DEBUG_PRINTK_MSG causes things like "if (...) WARNING(...); else {}" to fail with syntax error.

---
 drivers/net/wireless/rt2x00/rt2x00.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +1 -1
index 556b744..5ea62554 100644
@@ -66,7 +66,7 @@
 
 #ifdef CONFIG_RT2X00_DEBUG
 #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...)	\
-	DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args);
+	DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args)
 #else
 #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...)	\
 	do { } while (0)
Signature · 1 line
1.7.2.3
#15 lore raw

PATCH 16/17 rt2x00: Pad beacon to multiple of 32 bits.

From: Wolfgang Kufner <[email protected]>

Pad beacon to a multiple of 32 bits in preparation for the change from memcpy_toio() to __iowrite32_copy() in register_multiwrite().

---
 drivers/net/wireless/rt2x00/rt2800lib.c |    9 ++++++---
 drivers/net/wireless/rt2x00/rt61pci.c   |    8 ++++++--
 drivers/net/wireless/rt2x00/rt73usb.c   |    9 ++++++---
 3 files changed, 18 insertions(+), 8 deletions(-)
drivers/net/wireless/rt2x00/rt2800lib.c +6 -3
index b7de1a5..54917a2 100644
@@ -772,6 +772,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 	unsigned int beacon_base;
+	unsigned int padding_len;
 	u32 reg;
 
 	/*
@@ -806,11 +807,13 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
 
 	/*
-	 * Write entire beacon with TXWI to register.
+	 * Write entire beacon with TXWI and padding to register.
 	 */
+	padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
+	skb_pad(entry->skb, padding_len);
 	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
-	rt2800_register_multiwrite(rt2x00dev, beacon_base,
-				   entry->skb->data, entry->skb->len);
+	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+				   entry->skb->len + padding_len);
 
 	/*
 	 * Enable beaconing again.
drivers/net/wireless/rt2x00/rt61pci.c +6 -2
index 9405b10..8de44dd 100644
@@ -1961,6 +1961,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
 	unsigned int beacon_base;
+	unsigned int padding_len;
 	u32 reg;
 
 	/*
@@ -1982,13 +1983,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
 	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
 
 	/*
-	 * Write entire beacon with descriptor to register.
+	 * Write entire beacon with descriptor and padding to register.
 	 */
+	padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
+	skb_pad(entry->skb, padding_len);
 	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
 	rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
 				      entry_priv->desc, TXINFO_SIZE);
 	rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE,
-				      entry->skb->data, entry->skb->len);
+				      entry->skb->data,
+				      entry->skb->len + padding_len);
 
 	/*
 	 * Enable beaconing again.
drivers/net/wireless/rt2x00/rt73usb.c +6 -3
index 0b3959b..0b4e859 100644
@@ -1546,6 +1546,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	unsigned int beacon_base;
+	unsigned int padding_len;
 	u32 reg;
 
 	/*
@@ -1573,11 +1574,13 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
 	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
 
 	/*
-	 * Write entire beacon with descriptor to register.
+	 * Write entire beacon with descriptor and padding to register.
 	 */
+	padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
+	skb_pad(entry->skb, padding_len);
 	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
-	rt2x00usb_register_multiwrite(rt2x00dev, beacon_base,
-				      entry->skb->data, entry->skb->len);
+	rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+				      entry->skb->len + padding_len);
 
 	/*
 	 * Enable beaconing again.
Signature · 1 line
1.7.2.3
#16 lore raw

PATCH 17/17 rt2x00: Fix firmware loading regression on x86_64.

From: Wolfgang Kufner <[email protected]>

Commit 6175ddf06b6172046a329e3abfd9c901a43efd2e changes the way memcpy_toio() works for x86_64, causing firmware loading to fail for some Ralink WLAN devices with the rt2800pci driver since linux 2.6.34. This causes the log message: "phy0 -> rt2800pci_load_firmware: Error - PBF system register not ready.".

Fix this by using __iowrite32_copy instead of memcpy_toio().

---
 drivers/net/wireless/rt2x00/rt2x00pci.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/rt2x00/rt2x00pci.h +1 -1
index b854d62..746ce8f 100644
@@ -64,7 +64,7 @@ static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
 						 const void *value,
 						 const u32 length)
 {
-	memcpy_toio(rt2x00dev->csr.base + offset, value, length);
+	__iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
 }
 
 /**
Signature · 1 line
1.7.2.3
#22 lore raw

Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use

In reply to Ivo van Doorn
Quoted 3 lines

---

Hi.

I have two issues to report regarding system hangs. The system would either freeze entirely, prompting me to hard-reset it, or it would freeze certain parts of the system like, no shell commands execution. These occurrences manifest themselves sporadically, when I'm switching between modes (ad-hoc, monitor etc.), also when I try to rmmod the rt2xxx stuff or when unplugging the USB chip. I have to "ifconcfig wlanx down" the device first in order to not hang my box. My question is, will this patch fix all of that, or only parts of it? Here's log I managed to dig out.

[   67.784831] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x07 failed for offset 0x1718 with error -19.
[   67.789440] BUG: unable to handle kernel NULL pointer dereference at 00000004
[   67.789455] IP: [<f833e536>] rt2x00usb_kick_tx_entry+0x16/0xc0 [rt2x00usb]
[   67.789470] *pde = 7e56c067
[   67.789564] 
[   67.789571] Pid: 21, comm: khubd Not tainted 2.6.35-23-generic #41-Ubuntu Latitude C840            /Latitude C840                   
[   67.789577] EIP: 0060:[<f833e536>] EFLAGS: 00010282 CPU: 0
[   67.789583] EIP is at rt2x00usb_kick_tx_entry+0x16/0xc0 [rt2x00usb]
[   67.789588] EAX: 00000000 EBX: 00000000 ECX: 00000001 EDX: 00000000
[   67.789592] ESI: f833e520 EDI: 00000001 EBP: f712bc7c ESP: f712bc68
[   67.789597]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[   67.789602] Process khubd (pid: 21, ti=f712a000 task=f7130000 task.ti=f712a000)
[   67.789606] Stack:
[   67.789609]  f712bc7c c05c94ef f20b603c f833e520 00000001 f712bcb4 f90c1825 c012ced8
[   67.789620] <0> f712bc9c c05c94ef f712bc9c 00000286 00000004 00000000 f20b6048 00000001
[   67.789631] <0> f20b6078 f20b603c f20cb040 f712bcc0 f833e7fe f833e520 f712bcdc f90c0198
[   67.789644] Call Trace:
[   67.789656]  [<c05c94ef>] ? _raw_spin_lock_irqsave+0x2f/0x50
[   67.789663]  [<f833e520>] ? rt2x00usb_kick_tx_entry+0x0/0xc0 [rt2x00usb]
[   67.789675]  [<f90c1825>] ? rt2x00queue_for_each_entry+0xc5/0x120 [rt2x00lib]
[   67.789685]  [<c012ced8>] ? default_spin_lock_flags+0x8/0x10
[   67.789691]  [<c05c94ef>] ? _raw_spin_lock_irqsave+0x2f/0x50
[   67.789699]  [<f833e7fe>] ? rt2x00usb_kick_tx_queue+0x1e/0x20 [rt2x00usb]
[   67.789706]  [<f833e520>] ? rt2x00usb_kick_tx_entry+0x0/0xc0 [rt2x00usb]
[   67.789714]  [<f90c0198>] ? rt2x00mac_flush+0x48/0xd0 [rt2x00lib]
[   67.789738]  [<f9090272>] ? __ieee80211_recalc_idle+0x192/0x1a0 [mac80211]
[   67.789753]  [<f90902ac>] ? ieee80211_recalc_idle+0x2c/0x60 [mac80211]
[   67.789766]  [<f9086642>] ? __ieee80211_scan_completed_finish+0x32/0x90 [mac80211]
[   67.789779]  [<f9086721>] ? ieee80211_scan_cancel+0x81/0x90 [mac80211]
[   67.789794]  [<f9090e77>] ? ieee80211_do_stop+0x4a7/0x4d0 [mac80211]
[   67.789804]  [<c050e5a4>] ? dev_deactivate_queue+0x44/0x60
[   67.789811]  [<c05c9736>] ? _raw_spin_unlock_bh+0x16/0x20
[   67.789817]  [<c050e93e>] ? dev_deactivate+0x17e/0x190
[   67.789832]  [<f9090eb7>] ? ieee80211_stop+0x17/0x20 [mac80211]
[   67.789841]  [<c04f75e6>] ? __dev_close+0x46/0x80
[   67.789849]  [<c0352206>] ? kset_unregister+0x16/0x20
[   67.789856]  [<c04f7639>] ? dev_close+0x19/0x40
[   67.789862]  [<c04f76b5>] ? rollback_registered_many+0x55/0x1d0
[   67.789868]  [<c04f789a>] ? unregister_netdevice_queue+0x1a/0xc0
[   67.789878]  [<f90d7b4f>] ? rt2800_mcu_request+0x6f/0xd0 [rt2800lib]
[   67.789885]  [<c04f7844>] ? unregister_netdevice_many+0x14/0x50
[   67.789900]  [<f9090543>] ? ieee80211_remove_interfaces+0x83/0xc0 [mac80211]
[   67.789906]  [<c05c88b0>] ? down_write+0x10/0x30
[   67.789917]  [<f90820cb>] ? ieee80211_unregister_hw+0x4b/0x120 [mac80211]
[   67.789925]  [<f90bfa60>] ? rt2x00lib_remove_dev+0xd0/0xe0 [rt2x00lib]
[   67.789932]  [<f833e10f>] ? rt2x00usb_disconnect+0x2f/0x70 [rt2x00usb]
[   67.789941]  [<c0475e00>] ? usb_unbind_interface+0x40/0x150
[   67.789949]  [<c0400821>] ? __device_release_driver+0x51/0xb0
[   67.789955]  [<c0400945>] ? device_release_driver+0x25/0x40
[   67.789961]  [<c03ffbcb>] ? bus_remove_device+0x7b/0xa0
[   67.789970]  [<c03fdd17>] ? device_del+0xf7/0x180
[   67.789977]  [<c0472b25>] ? usb_disable_device+0x85/0x100
[   67.789983]  [<c046cf4e>] ? usb_disconnect+0xae/0x140
[   67.789989]  [<c046d4fa>] ? hub_port_connect_change+0x8a/0x8f0
[   67.789995]  [<c04736f3>] ? usb_control_msg+0xd3/0x130
[   67.790003]  [<c0460101>] ? ppp_unattached_ioctl+0x1a1/0x270
[   67.790009]  [<c046ecd0>] ? hub_events+0x2b0/0x4f0
[   67.790019]  [<c016601f>] ? finish_wait+0x4f/0x70
[   67.790024]  [<c046ef4a>] ? hub_thread+0x3a/0x140
[   67.790030]  [<c0165eb0>] ? autoremove_wake_function+0x0/0x50
[   67.790036]  [<c046ef10>] ? hub_thread+0x0/0x140
[   67.790042]  [<c0165a84>] ? kthread+0x74/0x80
[   67.790047]  [<c0165a10>] ? kthread+0x0/0x80
[   67.790055]  [<c010363e>] ? kernel_thread_helper+0x6/0x10
[   67.790058] Code: d8 e8 6f 0d d8 00 eb 8b 8d b6 00 00 00 00 8d bc 27 00 00 00 00 55 89 e5 83 ec 14 89 5d f4 89 75 f8 89 7d fc 0f 1f 44 00 00 89 c3 <8b> 40 04 8b 73 10 8b 00 8b 10 8b 3a 3e 0f ba 33 02 19 d2 85 d2 
[   67.790119] EIP: [<f833e536>] rt2x00usb_kick_tx_entry+0x16/0xc0 [rt2x00usb] SS:ESP 0068:f712bc68
[   67.790128] CR2: 0000000000000004
[   67.790133] ---[ end trace 81dd02b06472de40 ]---

My second question pertains to the STA drivers - rt3070sta. It is not possible to switch between the rt2800usb and rt3070sta without having to unplug the device and plugging it back again followed by loading manually the desired driver. I'm not sure but I think this might have something to do withe voltage settings or the firmware. But it really is annoying to physically unplug the USB chip every time I switch between the two modules. Is it possible to enable switching between rt3070sta/rt2800usb without unplugging/plugging the USB chip?

Walter

#23 lore raw

Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use

Hi,

Quoted 1 line

I have two issues to report regarding system hangs. The system would either freeze entirely, prompting me to hard-reset it, or it would freeze certain parts of the system like, no shell commands execution. These occurrences manifest themselves sporadically, when I'm switching between modes (ad-hoc, monitor etc.), also when I try to rmmod the rt2xxx stuff or when unplugging the USB chip. I have to "ifconcfig wlanx down" the device first in order to not hang my box. My question is, will this patch fix all of that, or only parts of it? Here's log I managed to dig out.

This patch, but also the queue refactoring patches in this series should resolve all unplug and rmmod bugs.

Quoted 3 lines

My second question pertains to the STA drivers - rt3070sta. It is not possible to switch between the rt2800usb and rt3070sta without having to unplug the device and plugging it back again followed by loading manually the desired driver. I'm not sure but I think this might have  something to do withe voltage settings or the firmware. But it really is annoying to physically unplug the USB chip every time I switch between the two modules. Is it possible to enable switching between rt3070sta/rt2800usb without unplugging/plugging the USB chip?

It should be possible, but what are the exact problems that you encounter? Is there a difference between going from rt3070sta to rt2800usb and vice versa? (Please note that the rt2x00 project doesn't maintain the rt3070sta driver in the staging directory).

Ivo

#24 lore raw

Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use

Quoted 8 lines

It should be possible, but what are the exact problems that you encounter?
Is there a difference between going from rt3070sta to rt2800usb and vice versa?
(Please note that the rt2x00 project doesn't maintain the rt3070sta
driver in the staging directory).

Thanks for replying.

I hope these sets of patches ameliorate all of the unplugging and rmmod'ing for the rt2800usb/rt3070.

And yes, I know the rt2x00 project does not cover staging drivers, actually the staging driver adopted by Ubuntu (and others) is in fact rt2870sta and not the rt3070sta (from Ralink), but they both do not allow switching between them and rt2800usb. On my system, when rt3070sta is loaded first and then subsequently rmmod'ed to modprobe the rt2800usb the following error occurs:

[14775.401131] cfg80211: 2474000 KHz - 2494000 KHz @  KHz), (300 mBi, 2000 mBm)
[14775.413682] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
[14775.418857] Registered led device: rt2800usb-phy0::radio
[14775.421376] Registered led device: rt2800usb-phy0::assoc
[14775.423420] Registered led device: rt2800usb-phy0::quality
[14775.426517] usbcore: registered new interface driver rt2800usb
[14775.449012] udev[4470]: renamed network interface wlan0 to wlan2
[14776.031493] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x3240 with error -71.
[14776.605073] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x7014 with error -71.
[14777.173373] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x701c with error -71.
[14777.748941] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x01 failed for offset 0x0000 with error -71.
[14777.748956] phy0 -> rt2800usb_write_firmware: Error - Failed to write Firmware to device.
[14778.307770] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x07 failed for offset 0x0400 with error -71.
[14778.876970] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x07 failed for offset 0x0400 with error -71.

then the system freezes, partially, meaning for example I cannot issue simple "ifconfig" - this command as well as other commands are inactive. To unlock the system, thus command prompt and so on I have to unplug the device, then dmesg basically is flooding with errors.

LOG:

[15254.800224] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x6640 with error -71.
[15255.365301] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x1e48 with error -71.
[15255.939468] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x6b24 with error -71.
[15256.507077] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x6648 with error -71.
[15257.078835] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x1e50 with error -71.
[15257.650201] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x6b28 with error -71.
[15258.216303] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x6650 with error -71.
[15258.782110] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x1e58 with error -71.
[15259.131561] usb 5-2.6: USB disconnect, address 6
[15259.131791] phy0 -> rt2x00usb_vendor_request: Error - Vendor Request 0x06 failed for offset 0x6b2c with error -19.
[15259.151361] phy0 -> rt2800_wait_bbp_ready: Error - BBP register access failed, aborting.
[15259.151379] phy0 -> rt2800usb_set_device_state: Error - Device failed to enter state 4 (-5).

Now trying vice versa rt2800usb --> rt3070sta:
Interestingly, when rt2800usb is first loaded and then rmmod'ed without unplugging followed by loading of the rt3070sta takes about a minute or so, but the rt3070sta becomes operational. But not always. A repeat of the procedure partially froze the system again.

Tried with both staging rt2870sta and manually compiled rt3070sta - the result is the same, total or partial system failure, forcing me to plug/unplug the USB chip.

Walter

#17 lore raw

Re: [PATCH 14/17] rt2x00: Fix WMM Queue naming

In reply to Ivo van Doorn

Am Montag, 13. Dezember 2010 schrieb Ivo van Doorn:

Quoted 9 lines

The Queue names were incorrectly copied from the legacy drivers, as a result the queue names were inversed to what was expected.

This renames the queues using this mapping:

	QID_AC_BK -> QID_AC_VO (priority 0)
	QID_AC_BE -> QID_AC_VI (priority 1)
	QID_AC_VI -> QID_AC_BE (priority 2)
	QID_AC_VO -> QID_AC_BK (priority 3)
Quoted 4 lines

Note that this was a naming problem only, which didn't affect the assignment of frames to their respective queues.

Ivo, due to the latest info from Ralink I'd say we should drop this patch and instead introduce a mac80211_to_rt2x00_qid mapper that maps from ieee80211_ac_numbers to data_queue_qid.

This patch doesn't cause any harm, but we would have to revert it partly if we introduce the queue mapping as needed by the rt2x00 devices.

Thanks,
Helmut

Quoted 625 lines
---
 drivers/net/wireless/rt2x00/rt2400pci.c   |   12 +++---
 drivers/net/wireless/rt2x00/rt2500pci.c   |   12 +++---
 drivers/net/wireless/rt2x00/rt2800.h      |   44 ++++++++++----------
 drivers/net/wireless/rt2x00/rt2800pci.c   |    4 +-
 drivers/net/wireless/rt2x00/rt2x00queue.c |   18 ++++----
 drivers/net/wireless/rt2x00/rt2x00queue.h |   12 +++---
 drivers/net/wireless/rt2x00/rt2x00usb.c   |    8 ++--
 drivers/net/wireless/rt2x00/rt61pci.c     |   16 ++++----
 drivers/net/wireless/rt2x00/rt61pci.h     |   62 ++++++++++++++--------------
 drivers/net/wireless/rt2x00/rt73usb.h     |   36 ++++++++--------
 10 files changed, 112 insertions(+), 112 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +6 -6
index 2fc6ca5..54ca49a 100644
@@ -664,12 +664,12 @@ static void rt2400pci_kick_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
+	case QID_AC_VO:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
 		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 		break;
-	case QID_AC_BK:
+	case QID_AC_VI:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
 		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
@@ -690,8 +690,8 @@ static void rt2400pci_stop_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
-	case QID_AC_BK:
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_ATIM:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
@@ -1322,13 +1322,13 @@ static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance)
 	 * 4 - Priority ring transmit done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
-		rt2400pci_txdone(rt2x00dev, QID_AC_BE);
+		rt2400pci_txdone(rt2x00dev, QID_AC_VO);
 
 	/*
 	 * 5 - Tx ring transmit done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
-		rt2400pci_txdone(rt2x00dev, QID_AC_BK);
+		rt2400pci_txdone(rt2x00dev, QID_AC_VI);
 
 	/* Enable interrupts again. */
 	rt2x00dev->ops->lib->set_device_state(rt2x00dev,
drivers/net/wireless/rt2x00/rt2500pci.c +6 -6
index d67f911..a9ff26a 100644
@@ -754,12 +754,12 @@ static void rt2500pci_kick_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
+	case QID_AC_VO:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
 		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 		break;
-	case QID_AC_BK:
+	case QID_AC_VI:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
 		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
@@ -780,8 +780,8 @@ static void rt2500pci_stop_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
-	case QID_AC_BK:
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_ATIM:
 		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
@@ -1455,13 +1455,13 @@ static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance)
 	 * 4 - Priority ring transmit done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
-		rt2500pci_txdone(rt2x00dev, QID_AC_BE);
+		rt2500pci_txdone(rt2x00dev, QID_AC_VO);
 
 	/*
 	 * 5 - Tx ring transmit done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
-		rt2500pci_txdone(rt2x00dev, QID_AC_BK);
+		rt2500pci_txdone(rt2x00dev, QID_AC_VI);
 
 	/* Enable interrupts again. */
 	rt2x00dev->ops->lib->set_device_state(rt2x00dev,
drivers/net/wireless/rt2x00/rt2800.h +22 -22
index 9ea0961..4c55e85 100644
@@ -213,10 +213,10 @@
 
 /*
  * WMM_AIFSN_CFG: Aifsn for each EDCA AC
- * AIFSN0: AC_BE
- * AIFSN1: AC_BK
- * AIFSN2: AC_VI
- * AIFSN3: AC_VO
+ * AIFSN0: AC_VO
+ * AIFSN1: AC_VI
+ * AIFSN2: AC_BE
+ * AIFSN3: AC_BK
  */
 #define WMM_AIFSN_CFG			0x0214
 #define WMM_AIFSN_CFG_AIFSN0		FIELD32(0x0000000f)
@@ -226,10 +226,10 @@
 
 /*
  * WMM_CWMIN_CSR: CWmin for each EDCA AC
- * CWMIN0: AC_BE
- * CWMIN1: AC_BK
- * CWMIN2: AC_VI
- * CWMIN3: AC_VO
+ * CWMIN0: AC_VO
+ * CWMIN1: AC_VI
+ * CWMIN2: AC_BE
+ * CWMIN3: AC_BK
  */
 #define WMM_CWMIN_CFG			0x0218
 #define WMM_CWMIN_CFG_CWMIN0		FIELD32(0x0000000f)
@@ -239,10 +239,10 @@
 
 /*
  * WMM_CWMAX_CSR: CWmax for each EDCA AC
- * CWMAX0: AC_BE
- * CWMAX1: AC_BK
- * CWMAX2: AC_VI
- * CWMAX3: AC_VO
+ * CWMAX0: AC_VO
+ * CWMAX1: AC_VI
+ * CWMAX2: AC_BE
+ * CWMAX3: AC_BK
  */
 #define WMM_CWMAX_CFG			0x021c
 #define WMM_CWMAX_CFG_CWMAX0		FIELD32(0x0000000f)
@@ -251,18 +251,18 @@
 #define WMM_CWMAX_CFG_CWMAX3		FIELD32(0x0000f000)
 
 /*
- * AC_TXOP0: AC_BK/AC_BE TXOP register
- * AC0TXOP: AC_BK in unit of 32us
- * AC1TXOP: AC_BE in unit of 32us
+ * AC_TXOP0: AC_VO/AC_VI TXOP register
+ * AC0TXOP: AC_VO in unit of 32us
+ * AC1TXOP: AC_VI in unit of 32us
  */
 #define WMM_TXOP0_CFG			0x0220
 #define WMM_TXOP0_CFG_AC0TXOP		FIELD32(0x0000ffff)
 #define WMM_TXOP0_CFG_AC1TXOP		FIELD32(0xffff0000)
 
 /*
- * AC_TXOP1: AC_VO/AC_VI TXOP register
- * AC2TXOP: AC_VI in unit of 32us
- * AC3TXOP: AC_VO in unit of 32us
+ * AC_TXOP1: AC_BE/AC_BK TXOP register
+ * AC2TXOP: AC_BE in unit of 32us
+ * AC3TXOP: AC_BK in unit of 32us
  */
 #define WMM_TXOP1_CFG			0x0224
 #define WMM_TXOP1_CFG_AC2TXOP		FIELD32(0x0000ffff)
@@ -288,7 +288,7 @@
 #define MCU_CMD_CFG			0x022c
 
 /*
- * AC_BK register offsets
+ * AC_VO register offsets
  */
 #define TX_BASE_PTR0			0x0230
 #define TX_MAX_CNT0			0x0234
@@ -296,7 +296,7 @@
 #define TX_DTX_IDX0			0x023c
 
 /*
- * AC_BE register offsets
+ * AC_VI register offsets
  */
 #define TX_BASE_PTR1			0x0240
 #define TX_MAX_CNT1			0x0244
@@ -304,7 +304,7 @@
 #define TX_DTX_IDX1			0x024c
 
 /*
- * AC_VI register offsets
+ * AC_BE register offsets
  */
 #define TX_BASE_PTR2			0x0250
 #define TX_MAX_CNT2			0x0254
@@ -312,7 +312,7 @@
 #define TX_DTX_IDX2			0x025c
 
 /*
- * AC_VO register offsets
+ * AC_BK register offsets
  */
 #define TX_BASE_PTR3			0x0260
 #define TX_MAX_CNT3			0x0264
drivers/net/wireless/rt2x00/rt2800pci.c +2 -2
index 195f0be3..403013f 100644
@@ -217,10 +217,10 @@ static void rt2800pci_kick_queue(struct data_queue *queue)
 	struct queue_entry *entry;
 
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		entry = rt2x00queue_get_entry(queue, Q_INDEX);
 		rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx);
 		break;
drivers/net/wireless/rt2x00/rt2x00queue.c +9 -9
index 52cc92d..ca82b3a 100644
@@ -746,10 +746,10 @@ void rt2x00queue_pause_queue(struct data_queue *queue)
 		return;
 
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		/*
 		 * For TX queues, we have to disable the queue
 		 * inside mac80211.
@@ -770,10 +770,10 @@ void rt2x00queue_unpause_queue(struct data_queue *queue)
 		return;
 
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		/*
 		 * For TX queues, we have to enable the queue
 		 * inside mac80211.
@@ -834,10 +834,10 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
 	unsigned int i;
 	bool started;
 	bool tx_queue =
-		(queue->qid == QID_AC_BE) ||
-		(queue->qid == QID_AC_BK) ||
+		(queue->qid == QID_AC_VO) ||
 		(queue->qid == QID_AC_VI) ||
-		(queue->qid == QID_AC_VO);
+		(queue->qid == QID_AC_BE) ||
+		(queue->qid == QID_AC_BK);
 
 	mutex_lock(&queue->status_lock);
 
@@ -1141,7 +1141,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Initialize queue parameters.
 	 * RX: qid = QID_RX
-	 * TX: qid = QID_AC_BE + index
+	 * TX: qid = QID_AC_VO + index
 	 * TX: cw_min: 2^5 = 32.
 	 * TX: cw_max: 2^10 = 1024.
 	 * BCN: qid = QID_BEACON
@@ -1149,7 +1149,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
 	 */
 	rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX);
 
-	qid = QID_AC_BE;
+	qid = QID_AC_VO;
 	tx_queue_for_each(rt2x00dev, queue)
 		rt2x00queue_init(rt2x00dev, queue, qid++);
 
drivers/net/wireless/rt2x00/rt2x00queue.h +6 -6
index 4765934..fab8e26 100644
@@ -45,10 +45,10 @@
 /**
  * enum data_queue_qid: Queue identification
  *
+ * @QID_AC_VO: AC VO queue
+ * @QID_AC_VI: AC VI queue
  * @QID_AC_BE: AC BE queue
  * @QID_AC_BK: AC BK queue
- * @QID_AC_VI: AC VI queue
- * @QID_AC_VO: AC VO queue
  * @QID_HCCA: HCCA queue
  * @QID_MGMT: MGMT queue (prio queue)
  * @QID_RX: RX queue
@@ -57,10 +57,10 @@
  * @QID_ATIM: Atim queue (value unspeficied, don't send it to device)
  */
 enum data_queue_qid {
-	QID_AC_BE = 0,
-	QID_AC_BK = 1,
-	QID_AC_VI = 2,
-	QID_AC_VO = 3,
+	QID_AC_VO = 0,
+	QID_AC_VI = 1,
+	QID_AC_BE = 2,
+	QID_AC_BK = 3,
 	QID_HCCA = 4,
 	QID_MGMT = 13,
 	QID_RX = 14,
drivers/net/wireless/rt2x00/rt2x00usb.c +4 -4
index 8a16b51..1a9937d 100644
@@ -353,10 +353,10 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
 void rt2x00usb_kick_queue(struct data_queue *queue)
 {
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		if (!rt2x00queue_empty(queue))
 			rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
 						   rt2x00usb_kick_tx_entry);
@@ -403,10 +403,10 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
 	 * Obtain the queue completion handler
 	 */
 	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
 	case QID_AC_BE:
 	case QID_AC_BK:
-	case QID_AC_VI:
-	case QID_AC_VO:
 		completion = &queue->rt2x00dev->txdone_work;
 		break;
 	case QID_RX:
drivers/net/wireless/rt2x00/rt61pci.c +8 -8
index 7156b78..9405b10 100644
@@ -1171,22 +1171,22 @@ static void rt61pci_kick_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
+	case QID_AC_VO:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_BK:
+	case QID_AC_VI:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_VI:
+	case QID_AC_BE:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_VO:
+	case QID_AC_BK:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
@@ -1202,22 +1202,22 @@ static void rt61pci_stop_queue(struct data_queue *queue)
 	u32 reg;
 
 	switch (queue->qid) {
-	case QID_AC_BE:
+	case QID_AC_VO:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_BK:
+	case QID_AC_VI:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_VI:
+	case QID_AC_BE:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 		break;
-	case QID_AC_VO:
+	case QID_AC_BK:
 		rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
 		rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
drivers/net/wireless/rt2x00/rt61pci.h +31 -31
index afc803b..e3cd6db 100644
@@ -784,25 +784,25 @@ struct hw_pairwise_ta_entry {
  */
 
 /*
- * AC0_BASE_CSR: AC_BK base address.
+ * AC0_BASE_CSR: AC_VO base address.
  */
 #define AC0_BASE_CSR			0x3400
 #define AC0_BASE_CSR_RING_REGISTER	FIELD32(0xffffffff)
 
 /*
- * AC1_BASE_CSR: AC_BE base address.
+ * AC1_BASE_CSR: AC_VI base address.
  */
 #define AC1_BASE_CSR			0x3404
 #define AC1_BASE_CSR_RING_REGISTER	FIELD32(0xffffffff)
 
 /*
- * AC2_BASE_CSR: AC_VI base address.
+ * AC2_BASE_CSR: AC_BE base address.
  */
 #define AC2_BASE_CSR			0x3408
 #define AC2_BASE_CSR_RING_REGISTER	FIELD32(0xffffffff)
 
 /*
- * AC3_BASE_CSR: AC_VO base address.
+ * AC3_BASE_CSR: AC_BK base address.
  */
 #define AC3_BASE_CSR			0x340c
 #define AC3_BASE_CSR_RING_REGISTER	FIELD32(0xffffffff)
@@ -814,7 +814,7 @@ struct hw_pairwise_ta_entry {
 #define MGMT_BASE_CSR_RING_REGISTER	FIELD32(0xffffffff)
 
 /*
- * TX_RING_CSR0: TX Ring size for AC_BK, AC_BE, AC_VI, AC_VO.
+ * TX_RING_CSR0: TX Ring size for AC_VO, AC_VI, AC_BE, AC_BK.
  */
 #define TX_RING_CSR0			0x3418
 #define TX_RING_CSR0_AC0_RING_SIZE	FIELD32(0x000000ff)
@@ -833,10 +833,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * AIFSN_CSR: AIFSN for each EDCA AC.
- * AIFSN0: For AC_BK.
- * AIFSN1: For AC_BE.
- * AIFSN2: For AC_VI.
- * AIFSN3: For AC_VO.
+ * AIFSN0: For AC_VO.
+ * AIFSN1: For AC_VI.
+ * AIFSN2: For AC_BE.
+ * AIFSN3: For AC_BK.
  */
 #define AIFSN_CSR			0x3420
 #define AIFSN_CSR_AIFSN0		FIELD32(0x0000000f)
@@ -846,10 +846,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * CWMIN_CSR: CWmin for each EDCA AC.
- * CWMIN0: For AC_BK.
- * CWMIN1: For AC_BE.
- * CWMIN2: For AC_VI.
- * CWMIN3: For AC_VO.
+ * CWMIN0: For AC_VO.
+ * CWMIN1: For AC_VI.
+ * CWMIN2: For AC_BE.
+ * CWMIN3: For AC_BK.
  */
 #define CWMIN_CSR			0x3424
 #define CWMIN_CSR_CWMIN0		FIELD32(0x0000000f)
@@ -859,10 +859,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * CWMAX_CSR: CWmax for each EDCA AC.
- * CWMAX0: For AC_BK.
- * CWMAX1: For AC_BE.
- * CWMAX2: For AC_VI.
- * CWMAX3: For AC_VO.
+ * CWMAX0: For AC_VO.
+ * CWMAX1: For AC_VI.
+ * CWMAX2: For AC_BE.
+ * CWMAX3: For AC_BK.
  */
 #define CWMAX_CSR			0x3428
 #define CWMAX_CSR_CWMAX0		FIELD32(0x0000000f)
@@ -883,14 +883,14 @@ struct hw_pairwise_ta_entry {
 
 /*
  * TX_CNTL_CSR: KICK/Abort TX.
- * KICK_TX_AC0: For AC_BK.
- * KICK_TX_AC1: For AC_BE.
- * KICK_TX_AC2: For AC_VI.
- * KICK_TX_AC3: For AC_VO.
- * ABORT_TX_AC0: For AC_BK.
- * ABORT_TX_AC1: For AC_BE.
- * ABORT_TX_AC2: For AC_VI.
- * ABORT_TX_AC3: For AC_VO.
+ * KICK_TX_AC0: For AC_VO.
+ * KICK_TX_AC1: For AC_VI.
+ * KICK_TX_AC2: For AC_BE.
+ * KICK_TX_AC3: For AC_BK.
+ * ABORT_TX_AC0: For AC_VO.
+ * ABORT_TX_AC1: For AC_VI.
+ * ABORT_TX_AC2: For AC_BE.
+ * ABORT_TX_AC3: For AC_BK.
  */
 #define TX_CNTL_CSR			0x3430
 #define TX_CNTL_CSR_KICK_TX_AC0		FIELD32(0x00000001)
@@ -1010,18 +1010,18 @@ struct hw_pairwise_ta_entry {
 #define E2PROM_CSR_LOAD_STATUS		FIELD32(0x00000040)
 
 /*
- * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register.
- * AC0_TX_OP: For AC_BK, in unit of 32us.
- * AC1_TX_OP: For AC_BE, in unit of 32us.
+ * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
+ * AC0_TX_OP: For AC_VO, in unit of 32us.
+ * AC1_TX_OP: For AC_VI, in unit of 32us.
  */
 #define AC_TXOP_CSR0			0x3474
 #define AC_TXOP_CSR0_AC0_TX_OP		FIELD32(0x0000ffff)
 #define AC_TXOP_CSR0_AC1_TX_OP		FIELD32(0xffff0000)
 
 /*
- * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register.
- * AC2_TX_OP: For AC_VI, in unit of 32us.
- * AC3_TX_OP: For AC_VO, in unit of 32us.
+ * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
+ * AC2_TX_OP: For AC_BE, in unit of 32us.
+ * AC3_TX_OP: For AC_BK, in unit of 32us.
  */
 #define AC_TXOP_CSR1			0x3478
 #define AC_TXOP_CSR1_AC2_TX_OP		FIELD32(0x0000ffff)
drivers/net/wireless/rt2x00/rt73usb.h +18 -18
index 1315ce5..9f6b470 100644
@@ -689,10 +689,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * AIFSN_CSR: AIFSN for each EDCA AC.
- * AIFSN0: For AC_BK.
- * AIFSN1: For AC_BE.
- * AIFSN2: For AC_VI.
- * AIFSN3: For AC_VO.
+ * AIFSN0: For AC_VO.
+ * AIFSN1: For AC_VI.
+ * AIFSN2: For AC_BE.
+ * AIFSN3: For AC_BK.
  */
 #define AIFSN_CSR			0x0400
 #define AIFSN_CSR_AIFSN0		FIELD32(0x0000000f)
@@ -702,10 +702,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * CWMIN_CSR: CWmin for each EDCA AC.
- * CWMIN0: For AC_BK.
- * CWMIN1: For AC_BE.
- * CWMIN2: For AC_VI.
- * CWMIN3: For AC_VO.
+ * CWMIN0: For AC_VO.
+ * CWMIN1: For AC_VI.
+ * CWMIN2: For AC_BE.
+ * CWMIN3: For AC_BK.
  */
 #define CWMIN_CSR			0x0404
 #define CWMIN_CSR_CWMIN0		FIELD32(0x0000000f)
@@ -715,10 +715,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * CWMAX_CSR: CWmax for each EDCA AC.
- * CWMAX0: For AC_BK.
- * CWMAX1: For AC_BE.
- * CWMAX2: For AC_VI.
- * CWMAX3: For AC_VO.
+ * CWMAX0: For AC_VO.
+ * CWMAX1: For AC_VI.
+ * CWMAX2: For AC_BE.
+ * CWMAX3: For AC_BK.
  */
 #define CWMAX_CSR			0x0408
 #define CWMAX_CSR_CWMAX0		FIELD32(0x0000000f)
@@ -727,18 +727,18 @@ struct hw_pairwise_ta_entry {
 #define CWMAX_CSR_CWMAX3		FIELD32(0x0000f000)
 
 /*
- * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register.
- * AC0_TX_OP: For AC_BK, in unit of 32us.
- * AC1_TX_OP: For AC_BE, in unit of 32us.
+ * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
+ * AC0_TX_OP: For AC_VO, in unit of 32us.
+ * AC1_TX_OP: For AC_VI, in unit of 32us.
  */
 #define AC_TXOP_CSR0			0x040c
 #define AC_TXOP_CSR0_AC0_TX_OP		FIELD32(0x0000ffff)
 #define AC_TXOP_CSR0_AC1_TX_OP		FIELD32(0xffff0000)
 
 /*
- * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register.
- * AC2_TX_OP: For AC_VI, in unit of 32us.
- * AC3_TX_OP: For AC_VO, in unit of 32us.
+ * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
+ * AC2_TX_OP: For AC_BE, in unit of 32us.
+ * AC3_TX_OP: For AC_BK, in unit of 32us.
  */
 #define AC_TXOP_CSR1			0x0410
 #define AC_TXOP_CSR1_AC2_TX_OP		FIELD32(0x0000ffff)
#18 lore raw

Re: [PATCH 14/17] rt2x00: Fix WMM Queue naming

Hi,

Quoted 12 lines
Quoted 12 lines

The Queue names were incorrectly copied from the legacy drivers, as a result the queue names were inversed to what was expected.

This renames the queues using this mapping:
      QID_AC_BK -> QID_AC_VO (priority 0)
      QID_AC_BE -> QID_AC_VI (priority 1)
      QID_AC_VI -> QID_AC_BE (priority 2)
      QID_AC_VO -> QID_AC_BK (priority 3)

Note that this was a naming problem only, which didn't affect the assignment of frames to their respective queues.

Quoted 8 lines
Quoted 1 line

Ivo, due to the latest info from Ralink I'd say we should drop this patch and instead introduce a mac80211_to_rt2x00_qid mapper that maps from ieee80211_ac_numbers to data_queue_qid.

This patch doesn't cause any harm, but we would have to revert it partly if we introduce the queue mapping as needed by the rt2x00 devices.

I don't agree, this patch can safely be applied, since the mapping is in the endpoint assignment, rather the register value usage, I think the more optimal solution is fixing rt2x00usb_assign_endpoints. In there it currently assigns endpoints assuming the first endpoint is the highest priority, while we should be able to simply swap that to invert the logic.

Ivo

#19 lore raw

Re: [PATCH 14/17] rt2x00: Fix WMM Queue naming

Am Dienstag, 14. Dezember 2010 schrieb Ivo Van Doorn:

Quoted 23 lines

Hi,

Quoted 12 lines
Quoted 12 lines

The Queue names were incorrectly copied from the legacy drivers, as a result the queue names were inversed to what was expected.

This renames the queues using this mapping:

      QID_AC_BK -> QID_AC_VO (priority 0)
      QID_AC_BE -> QID_AC_VI (priority 1)
      QID_AC_VI -> QID_AC_BE (priority 2)
      QID_AC_VO -> QID_AC_BK (priority 3)

Note that this was a naming problem only, which didn't affect the assignment of frames to their respective queues.

Quoted 8 lines
Quoted 1 line

Ivo, due to the latest info from Ralink I'd say we should drop this patch and instead introduce a mac80211_to_rt2x00_qid mapper that maps from ieee80211_ac_numbers to data_queue_qid.

This patch doesn't cause any harm, but we would have to revert it partly if we introduce the queue mapping as needed by the rt2x00 devices.

Quoted 6 lines

I don't agree, this patch can safely be applied, since the mapping is in the endpoint assignment, rather the register value usage, I think the more optimal solution is fixing rt2x00usb_assign_endpoints. In there it currently assigns endpoints assuming the first endpoint is the highest priority, while we should be able to simply swap that to invert the logic.

Ah, ok, sounds good to me, at least for USB. Do we need the same for PCI devices?

Helmut

#20 lore raw

Re: [PATCH 14/17] rt2x00: Fix WMM Queue naming

In reply to Ivo Van Doorn

Hi,

Quoted 21 lines · Ivo Van Doorn
Quoted 12 lines
Quoted 12 lines

The Queue names were incorrectly copied from the legacy drivers, as a result the queue names were inversed to what was expected.

This renames the queues using this mapping:
      QID_AC_BK -> QID_AC_VO (priority 0)
      QID_AC_BE -> QID_AC_VI (priority 1)
      QID_AC_VI -> QID_AC_BE (priority 2)
      QID_AC_VO -> QID_AC_BK (priority 3)

Note that this was a naming problem only, which didn't affect the assignment of frames to their respective queues.

Quoted 8 lines
Quoted 1 line

Ivo, due to the latest info from Ralink I'd say we should drop this patch and instead introduce a mac80211_to_rt2x00_qid mapper that maps from ieee80211_ac_numbers to data_queue_qid.

This patch doesn't cause any harm, but we would have to revert it partly if we introduce the queue mapping as needed by the rt2x00 devices.

Quoted 6 lines

I don't agree, this patch can safely be applied, since the mapping is in the endpoint assignment, rather the register value usage, I think the more optimal solution is fixing rt2x00usb_assign_endpoints. In there it currently assigns endpoints assuming the first endpoint is the highest priority, while we should be able to simply swap that to invert the logic.

Inverting is not enough since the first OUT EP (EP1) is AC_BE, while AC_BK (lowest priority) is EP2. This corresponds to the to the AC -> ACI mapping from 802.11 Table 7-36 in section "7.3.2.29 EDCA Parameter Set element". Probably the rationale is that ACI value 0 should be the "default" AC.

Johannes

#21 lore raw

Re: [PATCH 14/17] rt2x00: Fix WMM Queue naming

Hi,

Quoted 28 lines
Quoted 21 lines
Quoted 12 lines
Quoted 12 lines

The Queue names were incorrectly copied from the legacy drivers, as a result the queue names were inversed to what was expected.

This renames the queues using this mapping:
      QID_AC_BK -> QID_AC_VO (priority 0)
      QID_AC_BE -> QID_AC_VI (priority 1)
      QID_AC_VI -> QID_AC_BE (priority 2)
      QID_AC_VO -> QID_AC_BK (priority 3)

Note that this was a naming problem only, which didn't affect the assignment of frames to their respective queues.

Quoted 8 lines
Quoted 1 line

Ivo, due to the latest info from Ralink I'd say we should drop this patch and instead introduce a mac80211_to_rt2x00_qid mapper that maps from ieee80211_ac_numbers to data_queue_qid.

This patch doesn't cause any harm, but we would have to revert it partly if we introduce the queue mapping as needed by the rt2x00 devices.

Quoted 6 lines

I don't agree, this patch can safely be applied, since the mapping is in the endpoint assignment, rather the register value usage, I think the more optimal solution is fixing rt2x00usb_assign_endpoints. In there it currently assigns endpoints assuming the first endpoint is the highest priority, while we should be able to simply swap that to invert the logic.

Quoted 5 lines

Inverting is not enough since the first OUT EP (EP1) is AC_BE, while AC_BK (lowest priority) is EP2.  This corresponds to the to the AC -> ACI mapping from 802.11 Table 7-36 in section "7.3.2.29 EDCA Parameter Set element".  Probably the rationale is that ACI value 0 should be the "default" AC.

Ok, but that still means that we can apply this logic in the assign_endpoints function.

Jay, can you confirm the endpoint assignment is the same for rt73usb?

Thanks,

Ivo

#25 lore raw

Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use

In reply to Walter Goldens

Even with the latest patches, rmmod'ing the rt2xXXX stuff causes a complete system freeze. Unless I bring down the interface first via 'ifconfig wlanX down', unloading the driver while operational equates OS hang and hard reset.

Walter.

#26 lore raw

wimaxd daemon bug

Good day.
I have
1.MeeGo 1.1
2.Intel Corporation WiMAX/WiFi Link 6050 Series (rev 2c) 3.Wimax network that named 'Yota'

wimaxcu scan wide
WARNING: Wide scan may take upto 2 minutes...
NSP : Yota

    ID          : 21
    Signal      : Excellent
    RSSI        : -62 dBm
    CINR        : 29 dB

Network Type: Home Network
Activated.

Then i try to connect with Yota-network

wimaxcu connect network 21
Connecting to Yota Network...
Connection successful

[root@meego-desktop ~]# /usr/bin/wimaxd -d -i wmx0 Enter Command:
q - Quit AppSrv
t - Trace ReInit (ReLoads Registry Values)
u - uplink(Apdo uplink event
h - Help
d - Toggle driver messages to display - debug & internal only

AppSrv is ready !
Act_FullRestart!
Act_DriverDeviceStatus - DRIVER_UP CTRL-EVENT-EAP-STARTED EAP authentication started Sending EapResponse. Data size: 25 CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=13 CTRL-EVENT-EAP-METHOD EAP vendor 0 method 13 (TLS) selected Sending EapResponse. Data size: 60
Sending EapResponse. Data size: 60
Sending EapResponse. Data size: 6
Sending EapResponse. Data size: 6
Sending EapResponse. Data size: 1310
Sending EapResponse. Data size: 1144
Sending EapResponse. Data size: 6 CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully CTRL-EVENT-EAP-STARTED EAP authentication started Sending EapResponse. Data size: 17 CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=13 CTRL-EVENT-EAP-METHOD EAP vendor 0 method 13 (TLS) selected Sending EapResponse. Data size: 60
Sending EapResponse. Data size: 6
Sending EapResponse. Data size: 6
Sending EapResponse. Data size: 1310
Sending EapResponse. Data size: 1144
Sending EapResponse. Data size: 6

Then i try to reconnect

[root@meego-desktop ~]# wimaxcu connect network 21 Current Preferred Profile is:

    ID  : 21
    Name: Yota

Connecting to Yota Network...
Connection failure

Next i try to

wimaxll -i wmx0 reset
and start daemon again

/usr/bin/wimaxd -d -i wmx0

Connect to network

imaxcu connect network 21
Current Preferred Profile is:

    ID  : 21
    Name: Yota

Connecting to Yota Network...
Connection successful

Wimaxd version wimax-1.5.1-35.13.i586.rpm
from Inaky Perez-Gonzalez repo.
http://download.meego.com/live/home:/inaky:/pegatron-idf-2010/Trunk/i586/

uname -a
Linux meego-desktop 2.6.36-1.9_mezon.12.1-netbook #1 SMP PREEMPT Wed Dec 15 20:01:48 MSK 2010 i686 i686 i386 GNU/Linux

steps to reproduce:
1.Plug on Intel Corporation WiMAX/WiFi Link 6050 Series (rev 2c) 2.Install any version on wimaxd
3.wimaxcu connect any_network_id
4.wait about 2 minutes
5.connection dropped.
6.try connect again, and see "connection failure" 7.wimaxll -i wmx0 rese
8.connect to network again (it will be succeeded) 9.Proceed to step 4

#28 lore raw

Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use

In reply to Walter Goldens

Hi,

Quoted 1 line

Even with the latest patches, rmmod'ing the rt2xXXX stuff causes a complete system freeze. Unless I bring down the interface first via 'ifconfig wlanX down', unloading the driver while operational equates OS hang and hard reset.

Odd I have been testing this while stresstesting the card, and either unplugging, rmmod or ifdown, and I couldn't
reproduce any crashes. Has the stacktrace changed after these patches?

Ivo

#29 lore raw

Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use

Quoted 6 lines

Odd I have been testing this while stresstesting the card, and either
unplugging, rmmod or ifdown, and I couldn't reproduce any crashes. Has the stacktrace changed after these patches?

Hi.

I can confirm when the rt2800usb is loaded and an rt3070 chip is connected to a network, running 'rmmod rt2800usb rt2x00lib rt2x00usb rt2800lib' causes immediate system hang (and hard-reset).

I was not able to retrieve any relevant error logs.

Walter

#27 lore raw

Re: wimaxd daemon bug

In reply to Alexander Khryukin

16.12.2010 17:10, Alexander Khryukin пишет:

Quoted 110 lines

Good day.
I have
1.MeeGo 1.1
2.Intel Corporation WiMAX/WiFi Link 6050 Series (rev 2c) 3.Wimax network that named 'Yota'

wimaxcu scan wide
WARNING: Wide scan may take upto 2 minutes...
NSP : Yota

    ID          : 21
    Signal      : Excellent
    RSSI        : -62 dBm
    CINR        : 29 dB

Network Type: Home Network
Activated.

Then i try to connect with Yota-network

wimaxcu connect network 21
Connecting to Yota Network...
Connection successful

[root@meego-desktop ~]# /usr/bin/wimaxd -d -i wmx0 Enter Command:
q - Quit AppSrv
t - Trace ReInit (ReLoads Registry Values)
u - uplink(Apdo uplink event
h - Help
d - Toggle driver messages to display - debug & internal only

AppSrv is ready !
Act_FullRestart!
Act_DriverDeviceStatus - DRIVER_UP CTRL-EVENT-EAP-STARTED EAP authentication started Sending EapResponse. Data size: 25 CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=13 CTRL-EVENT-EAP-METHOD EAP vendor 0 method 13 (TLS) selected Sending EapResponse. Data size: 60
Sending EapResponse. Data size: 60
Sending EapResponse. Data size: 6
Sending EapResponse. Data size: 6
Sending EapResponse. Data size: 1310
Sending EapResponse. Data size: 1144
Sending EapResponse. Data size: 6 CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully CTRL-EVENT-EAP-STARTED EAP authentication started Sending EapResponse. Data size: 17 CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=13 CTRL-EVENT-EAP-METHOD EAP vendor 0 method 13 (TLS) selected Sending EapResponse. Data size: 60
Sending EapResponse. Data size: 6
Sending EapResponse. Data size: 6
Sending EapResponse. Data size: 1310
Sending EapResponse. Data size: 1144
Sending EapResponse. Data size: 6

Then i try to reconnect

[root@meego-desktop ~]# wimaxcu connect network 21 Current Preferred Profile is:

    ID  : 21
    Name: Yota

Connecting to Yota Network...
Connection failure

Next i try to

wimaxll -i wmx0 reset
and start daemon again

/usr/bin/wimaxd -d -i wmx0

Connect to network

imaxcu connect network 21
Current Preferred Profile is:

    ID  : 21
    Name: Yota

Connecting to Yota Network...
Connection successful

Wimaxd version wimax-1.5.1-35.13.i586.rpm
from Inaky Perez-Gonzalez repo.
http://download.meego.com/live/home:/inaky:/pegatron-idf-2010/Trunk/i586/

uname -a
Linux meego-desktop 2.6.36-1.9_mezon.12.1-netbook #1 SMP PREEMPT Wed Dec 15 20:01:48 MSK 2010 i686 i686 i386 GNU/Linux

steps to reproduce:
1.Plug on Intel Corporation WiMAX/WiFi Link 6050 Series (rev 2c) 2.Install any version on wimaxd
3.wimaxcu connect any_network_id
4.wait about 2 minutes
5.connection dropped.
6.try connect again, and see "connection failure" 7.wimaxll -i wmx0 rese
8.connect to network again (it will be succeeded) 9.Proceed to step 4

Quoted 5 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Additional report.

[root@meego-desktop ~]# /usr/bin/wimaxd -d -i wmx0 Enter Command:
q - Quit AppSrv
t - Trace ReInit (ReLoads Registry Values)
u - uplink(Apdo uplink event
h - Help
d - Toggle driver messages to display - debug & internal only

AppSrv is ready !
Act_FullRestart!
Act_DriverDeviceStatus - DRIVER_UP

/var/log/wimax/wimaxd.log

http://pastebin.ca/2022059

And wait for 2 minutes

Now connection dropped in log nothing interesting not dropped

[root@meego-desktop ~]# wimaxcu connect network 21 Current Preferred Profile is:
ID : 21
Name: Yota
Connecting to Yota Network...
Connection failure

In log

http://pastebin.ca/2022057

#30 lore raw

Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use

In reply to Walter Goldens
Quoted 10 lines · Walter Goldens
Quoted 6 lines

Odd I have been testing this while stresstesting the card, and either
unplugging, rmmod or ifdown, and I couldn't reproduce any crashes. Has the stacktrace changed after these patches?

I can confirm when the rt2800usb is loaded and an rt3070 chip is connected to a network, running 'rmmod rt2800usb rt2x00lib rt2x00usb rt2800lib' causes immediate system hang (and hard-reset).

FWIW, I did not test this case. I only tested hot-unplug of the USB device. However, I think usually when the network interface is up the module use count should be incremented so that you cannot unload the module.

Johannes

#31 lore raw

Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use

Quoted 15 lines
Quoted 2 lines
Quoted 2 lines

Odd I have been testing this while stresstesting

the card,

Quoted 3 lines
Quoted 3 lines

and either
unplugging, rmmod or ifdown, and I couldn't
reproduce any crashes. Has the stacktrace changed

after

Quoted 3 lines
Quoted 1 line

these patches?

I can confirm when the rt2800usb is loaded and an

rt3070 chip is connected to

Quoted 1 line

a network, running 'rmmod rt2800usb rt2x00lib

rt2x00usb rt2800lib' causes

Quoted 1 line

immediate system hang (and hard-reset).

Quoted 8 lines

FWIW, I did not test this case.  I only tested hot-unplug of the
USB device.  However, I think usually when the network interface
is up the module use count should be incremented so that you
cannot unload the module.

Hi, Johannes

I can rmmod the zd1211rw for example, even the interface is up and connected to a network, whereas the rt2800usb forces the system to freeze. Why the difference?

Walter