mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-04 06:54:27 -05:00 
			
		
		
		
	This updates mac80211 to backports based on kernel 4.19-rc4. I plan to integrate all the patches which are in this tar into upstream backports soon. I used the backports generated from this code: https://github.com/hauke/backports/commits/wip2 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
		
			
				
	
	
		
			357 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			357 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 0381bfbc400ce4c3000b0b31c577ad9e8071e4f6 Mon Sep 17 00:00:00 2001
 | 
						|
From: Stanislaw Gruszka <sgruszka@redhat.com>
 | 
						|
Date: Fri, 18 May 2018 12:25:08 +0200
 | 
						|
Subject: [PATCH 1/5] rt2800: move usb specific txdone/txstatus routines to
 | 
						|
 rt2800lib
 | 
						|
 | 
						|
In order to reuse usb txdone/txstatus routines for mmio, move them
 | 
						|
to common rt2800lib.c file.
 | 
						|
 | 
						|
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
 | 
						|
---
 | 
						|
 .../net/wireless/ralink/rt2x00/rt2800lib.c    | 138 +++++++++++++++++
 | 
						|
 .../net/wireless/ralink/rt2x00/rt2800lib.h    |   3 +
 | 
						|
 .../net/wireless/ralink/rt2x00/rt2800usb.c    | 143 +-----------------
 | 
						|
 3 files changed, 145 insertions(+), 139 deletions(-)
 | 
						|
 | 
						|
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 | 
						|
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 | 
						|
@@ -960,6 +960,47 @@ static void rt2800_rate_from_status(stru
 | 
						|
 	skbdesc->tx_rate_flags = flags;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
 | 
						|
+{
 | 
						|
+	__le32 *txwi;
 | 
						|
+	u32 word;
 | 
						|
+	int wcid, ack, pid;
 | 
						|
+	int tx_wcid, tx_ack, tx_pid, is_agg;
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * This frames has returned with an IO error,
 | 
						|
+	 * so the status report is not intended for this
 | 
						|
+	 * frame.
 | 
						|
+	 */
 | 
						|
+	if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
 | 
						|
+		return false;
 | 
						|
+
 | 
						|
+	wcid	= rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
 | 
						|
+	ack	= rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
 | 
						|
+	pid	= rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
 | 
						|
+	is_agg	= rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE);
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Validate if this TX status report is intended for
 | 
						|
+	 * this entry by comparing the WCID/ACK/PID fields.
 | 
						|
+	 */
 | 
						|
+	txwi = rt2800_drv_get_txwi(entry);
 | 
						|
+
 | 
						|
+	word = rt2x00_desc_read(txwi, 1);
 | 
						|
+	tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
 | 
						|
+	tx_ack  = rt2x00_get_field32(word, TXWI_W1_ACK);
 | 
						|
+	tx_pid  = rt2x00_get_field32(word, TXWI_W1_PACKETID);
 | 
						|
+
 | 
						|
+	if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) {
 | 
						|
+		rt2x00_dbg(entry->queue->rt2x00dev,
 | 
						|
+			   "TX status report missed for queue %d entry %d\n",
 | 
						|
+			   entry->queue->qid, entry->entry_idx);
 | 
						|
+		return false;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return true;
 | 
						|
+}
 | 
						|
+
 | 
						|
 void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
 | 
						|
 			 bool match)
 | 
						|
 {
 | 
						|
@@ -1062,6 +1103,103 @@ void rt2800_txdone_entry(struct queue_en
 | 
						|
 }
 | 
						|
 EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
 | 
						|
 
 | 
						|
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
 | 
						|
+{
 | 
						|
+	struct data_queue *queue;
 | 
						|
+	struct queue_entry *entry;
 | 
						|
+	u32 reg;
 | 
						|
+	u8 qid;
 | 
						|
+	bool match;
 | 
						|
+
 | 
						|
+	while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
 | 
						|
+		/*
 | 
						|
+		 * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is
 | 
						|
+		 * guaranteed to be one of the TX QIDs .
 | 
						|
+		 */
 | 
						|
+		qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
 | 
						|
+		queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
 | 
						|
+
 | 
						|
+		if (unlikely(rt2x00queue_empty(queue))) {
 | 
						|
+			rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n",
 | 
						|
+				   qid);
 | 
						|
+			break;
 | 
						|
+		}
 | 
						|
+
 | 
						|
+		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 | 
						|
+
 | 
						|
+		if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
 | 
						|
+			     !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) {
 | 
						|
+			rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n",
 | 
						|
+				    entry->entry_idx, qid);
 | 
						|
+			break;
 | 
						|
+		}
 | 
						|
+
 | 
						|
+		match = rt2800_txdone_entry_check(entry, reg);
 | 
						|
+		rt2800_txdone_entry(entry, reg, rt2800_drv_get_txwi(entry), match);
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+EXPORT_SYMBOL_GPL(rt2800_txdone);
 | 
						|
+
 | 
						|
+static inline bool rt2800_entry_txstatus_timeout(struct queue_entry *entry)
 | 
						|
+{
 | 
						|
+	bool tout;
 | 
						|
+
 | 
						|
+	if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
 | 
						|
+		return false;
 | 
						|
+
 | 
						|
+	tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500));
 | 
						|
+	if (unlikely(tout))
 | 
						|
+		rt2x00_dbg(entry->queue->rt2x00dev,
 | 
						|
+			   "TX status timeout for entry %d in queue %d\n",
 | 
						|
+			   entry->entry_idx, entry->queue->qid);
 | 
						|
+	return tout;
 | 
						|
+
 | 
						|
+}
 | 
						|
+
 | 
						|
+bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev)
 | 
						|
+{
 | 
						|
+	struct data_queue *queue;
 | 
						|
+	struct queue_entry *entry;
 | 
						|
+
 | 
						|
+	tx_queue_for_each(rt2x00dev, queue) {
 | 
						|
+		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 | 
						|
+		if (rt2800_entry_txstatus_timeout(entry))
 | 
						|
+			return true;
 | 
						|
+	}
 | 
						|
+	return false;
 | 
						|
+}
 | 
						|
+EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout);
 | 
						|
+
 | 
						|
+void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev)
 | 
						|
+{
 | 
						|
+	struct data_queue *queue;
 | 
						|
+	struct queue_entry *entry;
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Process any trailing TX status reports for IO failures,
 | 
						|
+	 * we loop until we find the first non-IO error entry. This
 | 
						|
+	 * can either be a frame which is free, is being uploaded,
 | 
						|
+	 * or has completed the upload but didn't have an entry
 | 
						|
+	 * in the TX_STAT_FIFO register yet.
 | 
						|
+	 */
 | 
						|
+	tx_queue_for_each(rt2x00dev, queue) {
 | 
						|
+		while (!rt2x00queue_empty(queue)) {
 | 
						|
+			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 | 
						|
+
 | 
						|
+			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
 | 
						|
+			    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
 | 
						|
+				break;
 | 
						|
+
 | 
						|
+			if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) ||
 | 
						|
+			    rt2800_entry_txstatus_timeout(entry))
 | 
						|
+				rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
 | 
						|
+			else
 | 
						|
+				break;
 | 
						|
+		}
 | 
						|
+	}
 | 
						|
+}
 | 
						|
+EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus);
 | 
						|
+
 | 
						|
 static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
 | 
						|
 					  unsigned int index)
 | 
						|
 {
 | 
						|
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
 | 
						|
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
 | 
						|
@@ -206,6 +206,9 @@ void rt2800_process_rxwi(struct queue_en
 | 
						|
 
 | 
						|
 void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
 | 
						|
 			 bool match);
 | 
						|
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
 | 
						|
+void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev);
 | 
						|
+bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev);
 | 
						|
 
 | 
						|
 void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
 | 
						|
 void rt2800_clear_beacon(struct queue_entry *entry);
 | 
						|
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
 | 
						|
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
 | 
						|
@@ -116,35 +116,6 @@ static bool rt2800usb_txstatus_pending(s
 | 
						|
 	return false;
 | 
						|
 }
 | 
						|
 
 | 
						|
-static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry)
 | 
						|
-{
 | 
						|
-	bool tout;
 | 
						|
-
 | 
						|
-	if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
 | 
						|
-		return false;
 | 
						|
-
 | 
						|
-	tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500));
 | 
						|
-	if (unlikely(tout))
 | 
						|
-		rt2x00_dbg(entry->queue->rt2x00dev,
 | 
						|
-			   "TX status timeout for entry %d in queue %d\n",
 | 
						|
-			   entry->entry_idx, entry->queue->qid);
 | 
						|
-	return tout;
 | 
						|
-
 | 
						|
-}
 | 
						|
-
 | 
						|
-static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev)
 | 
						|
-{
 | 
						|
-	struct data_queue *queue;
 | 
						|
-	struct queue_entry *entry;
 | 
						|
-
 | 
						|
-	tx_queue_for_each(rt2x00dev, queue) {
 | 
						|
-		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 | 
						|
-		if (rt2800usb_entry_txstatus_timeout(entry))
 | 
						|
-			return true;
 | 
						|
-	}
 | 
						|
-	return false;
 | 
						|
-}
 | 
						|
-
 | 
						|
 #define TXSTATUS_READ_INTERVAL 1000000
 | 
						|
 
 | 
						|
 static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
 | 
						|
@@ -171,7 +142,7 @@ static bool rt2800usb_tx_sta_fifo_read_c
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	/* Check if there is any entry that timedout waiting on TX status */
 | 
						|
-	if (rt2800usb_txstatus_timeout(rt2x00dev))
 | 
						|
+	if (rt2800_txstatus_timeout(rt2x00dev))
 | 
						|
 		queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
 | 
						|
 
 | 
						|
 	if (rt2800usb_txstatus_pending(rt2x00dev)) {
 | 
						|
@@ -501,123 +472,17 @@ static int rt2800usb_get_tx_data_len(str
 | 
						|
 /*
 | 
						|
  * TX control handlers
 | 
						|
  */
 | 
						|
-static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
 | 
						|
-{
 | 
						|
-	__le32 *txwi;
 | 
						|
-	u32 word;
 | 
						|
-	int wcid, ack, pid;
 | 
						|
-	int tx_wcid, tx_ack, tx_pid, is_agg;
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * This frames has returned with an IO error,
 | 
						|
-	 * so the status report is not intended for this
 | 
						|
-	 * frame.
 | 
						|
-	 */
 | 
						|
-	if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
 | 
						|
-		return false;
 | 
						|
-
 | 
						|
-	wcid	= rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
 | 
						|
-	ack	= rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
 | 
						|
-	pid	= rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
 | 
						|
-	is_agg	= rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE);
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * Validate if this TX status report is intended for
 | 
						|
-	 * this entry by comparing the WCID/ACK/PID fields.
 | 
						|
-	 */
 | 
						|
-	txwi = rt2800usb_get_txwi(entry);
 | 
						|
-
 | 
						|
-	word = rt2x00_desc_read(txwi, 1);
 | 
						|
-	tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
 | 
						|
-	tx_ack  = rt2x00_get_field32(word, TXWI_W1_ACK);
 | 
						|
-	tx_pid  = rt2x00_get_field32(word, TXWI_W1_PACKETID);
 | 
						|
-
 | 
						|
-	if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) {
 | 
						|
-		rt2x00_dbg(entry->queue->rt2x00dev,
 | 
						|
-			   "TX status report missed for queue %d entry %d\n",
 | 
						|
-			   entry->queue->qid, entry->entry_idx);
 | 
						|
-		return false;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	return true;
 | 
						|
-}
 | 
						|
-
 | 
						|
-static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
 | 
						|
-{
 | 
						|
-	struct data_queue *queue;
 | 
						|
-	struct queue_entry *entry;
 | 
						|
-	u32 reg;
 | 
						|
-	u8 qid;
 | 
						|
-	bool match;
 | 
						|
-
 | 
						|
-	while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
 | 
						|
-		/*
 | 
						|
-		 * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is
 | 
						|
-		 * guaranteed to be one of the TX QIDs .
 | 
						|
-		 */
 | 
						|
-		qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
 | 
						|
-		queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
 | 
						|
-
 | 
						|
-		if (unlikely(rt2x00queue_empty(queue))) {
 | 
						|
-			rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n",
 | 
						|
-				   qid);
 | 
						|
-			break;
 | 
						|
-		}
 | 
						|
-
 | 
						|
-		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 | 
						|
-
 | 
						|
-		if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
 | 
						|
-			     !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) {
 | 
						|
-			rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n",
 | 
						|
-				    entry->entry_idx, qid);
 | 
						|
-			break;
 | 
						|
-		}
 | 
						|
-
 | 
						|
-		match = rt2800usb_txdone_entry_check(entry, reg);
 | 
						|
-		rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match);
 | 
						|
-	}
 | 
						|
-}
 | 
						|
-
 | 
						|
-static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev)
 | 
						|
-{
 | 
						|
-	struct data_queue *queue;
 | 
						|
-	struct queue_entry *entry;
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * Process any trailing TX status reports for IO failures,
 | 
						|
-	 * we loop until we find the first non-IO error entry. This
 | 
						|
-	 * can either be a frame which is free, is being uploaded,
 | 
						|
-	 * or has completed the upload but didn't have an entry
 | 
						|
-	 * in the TX_STAT_FIFO register yet.
 | 
						|
-	 */
 | 
						|
-	tx_queue_for_each(rt2x00dev, queue) {
 | 
						|
-		while (!rt2x00queue_empty(queue)) {
 | 
						|
-			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 | 
						|
-
 | 
						|
-			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
 | 
						|
-			    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
 | 
						|
-				break;
 | 
						|
-
 | 
						|
-			if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) ||
 | 
						|
-			    rt2800usb_entry_txstatus_timeout(entry))
 | 
						|
-				rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
 | 
						|
-			else
 | 
						|
-				break;
 | 
						|
-		}
 | 
						|
-	}
 | 
						|
-}
 | 
						|
-
 | 
						|
 static void rt2800usb_work_txdone(struct work_struct *work)
 | 
						|
 {
 | 
						|
 	struct rt2x00_dev *rt2x00dev =
 | 
						|
 	    container_of(work, struct rt2x00_dev, txdone_work);
 | 
						|
 
 | 
						|
 	while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
 | 
						|
-	       rt2800usb_txstatus_timeout(rt2x00dev)) {
 | 
						|
+	       rt2800_txstatus_timeout(rt2x00dev)) {
 | 
						|
 
 | 
						|
-		rt2800usb_txdone(rt2x00dev);
 | 
						|
+		rt2800_txdone(rt2x00dev);
 | 
						|
 
 | 
						|
-		rt2800usb_txdone_nostatus(rt2x00dev);
 | 
						|
+		rt2800_txdone_nostatus(rt2x00dev);
 | 
						|
 
 | 
						|
 		/*
 | 
						|
 		 * The hw may delay sending the packet after DMA complete
 |