Skip to contentSkip to conversation

rt2x00: txdone implementation supporting hw encryption.

PATCH In review Alban Browaeys 3 participants 4 messages Feb 26, 2010 – Mar 15, 2010 Networking drivers (wireless)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 rt2x00: txdone implementation supporting hw encryption.

This is an implementation that support WCID being the encryption key. Wireless Cli Id was set to be the encryption key in rt2800pci_write_tx_desc and read (TX_STA_FIFO_WCID) as the current queue entry index.

---
 drivers/net/wireless/rt2x00/rt2800pci.c |   57 +++++++++++++-----------------
 1 files changed, 25 insertions(+), 32 deletions(-)
drivers/net/wireless/rt2x00/rt2800pci.c +25 -32
index 0e4c417..841f973 100644
@@ -907,14 +907,12 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
 {
 	struct data_queue *queue;
 	struct queue_entry *entry;
-	struct queue_entry *entry_done;
-	struct queue_entry_priv_pci *entry_priv;
+	__le32 *txwi;
 	struct txdone_entry_desc txdesc;
 	u32 word;
 	u32 reg;
 	u32 old_reg;
-	unsigned int type;
-	unsigned int index;
+	int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
 	u16 mcs, real_mcs;
 
 	/*
@@ -936,47 +934,41 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
 			break;
 		old_reg = reg;
 
+		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);
+
 		/*
 		 * Skip this entry when it contains an invalid
 		 * queue identication number.
 		 */
-		type = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1;
-		if (type >= QID_RX)
+		if (pid - 1 < 0 || pid - 1 >= QID_RX)
 			continue;
 
-		queue = rt2x00queue_get_queue(rt2x00dev, type);
+		queue = rt2x00queue_get_queue(rt2x00dev, pid - 1);
 		if (unlikely(!queue))
 			continue;
 
 		/*
-		 * Skip this entry when it contains an invalid
-		 * index number.
+		 * Inside each queue, we process each entry in a chronological
+		 * order. We first check that the queue is not empty.
 		 */
-		index = rt2x00_get_field32(reg, TX_STA_FIFO_WCID) - 1;
-		if (unlikely(index >= queue->limit))
+		if (queue->length == 0)
 			continue;
+		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 
-		entry = &queue->entries[index];
-		entry_priv = entry->priv_data;
-		rt2x00_desc_read((__le32 *)entry->skb->data, 0, &word);
-
-		entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-		while (entry != entry_done) {
-			/*
-			 * Catch up.
-			 * Just report any entries we missed as failed.
-			 */
-			WARNING(rt2x00dev,
-				"TX status report missed for entry %d\n",
-				entry_done->entry_idx);
-
-			txdesc.flags = 0;
-			__set_bit(TXDONE_UNKNOWN, &txdesc.flags);
-			txdesc.retry = 0;
-
-			rt2x00lib_txdone(entry_done, &txdesc);
-			entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-		}
+		/* Check if we got a match by looking at WCID/ACK/PID
+		 * fields */
+		txwi = (__le32 *)(entry->skb->data -
+				  rt2x00dev->ops->extra_tx_headroom);
+
+		rt2x00_desc_read(txwi, 1, &word);
+		tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
+		tx_ack  = rt2x00_get_field32(word, TXWI_W1_ACK);
+		tx_pid  = rt2x00_get_field32(word, TXWI_W1_PACKETID);
+
+		if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid))
+			WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n");
 
 		/*
 		 * Obtain the status about this packet.
@@ -997,6 +989,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
 		 * we have mcs = tx_mcs - 1. So the number of
 		 * retry is (tx_mcs - mcs).
 		 */
+		rt2x00_desc_read(txwi, 0, &word);
 		mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
 		real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
 		__set_bit(TXDONE_FALLBACK, &txdesc.flags);
Signature · 1 line
1.7.0
#1 lore raw
Quoted 7 lines · Alban Browaeys

This is an implementation that support WCID being the encryption key. Wireless Cli Id was set to be the encryption key in rt2800pci_write_tx_desc and read (TX_STA_FIFO_WCID) as the current queue entry index.

---

Thanks for bearing with us. I just have a few style issues that need to be resolved.

Quoted 35 lines
 drivers/net/wireless/rt2x00/rt2800pci.c |   57
+++++++++++++-----------------
 1 files changed, 25 insertions(+), 32 deletions(-)
drivers/net/wireless/rt2x00/rt2800pci.c +2 -4
index 0e4c417..841f973 100644
@@ -907,14 +907,12 @@ static void rt2800pci_txdone(struct rt2x00_dev
 *rt2x00dev)
 {
     struct data_queue *queue;
     struct queue_entry *entry;
-    struct queue_entry *entry_done;
-    struct queue_entry_priv_pci *entry_priv;
+    __le32 *txwi;
     struct txdone_entry_desc txdesc;
     u32 word;
     u32 reg;
     u32 old_reg;
-    unsigned int type;
-    unsigned int index;
+    int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
     u16 mcs, real_mcs;
 
     /*
drivers/net/wireless/rt2x00/rt2800pci.c +3 -0
@@ -936,47 +934,41 @@ static void rt2800pci_txdone(struct rt2x00_dev
 *rt2x00dev)
             break;
         old_reg = reg;
 
+        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);

drivers/net/wireless/rt2x00/rt2800pci.c static void rt2800pci_txdone(struct rt2x00_dev · line 948

Quoted 10 lines
drivers/net/wireless/rt2x00/rt2800pci.c +2 -2
+
         /*
          * Skip this entry when it contains an invalid
          * queue identication number.
          */
-        type = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1;
-        if (type >= QID_RX)
+        if (pid - 1 < 0 || pid - 1 >= QID_RX)
             continue;
 

How about using:

	if (pid <= 0 || pid > QID_RX)

That's a lot more readable than the current expression.

Quoted 5 lines
drivers/net/wireless/rt2x00/rt2800pci.c +1 -1
-        queue = rt2x00queue_get_queue(rt2x00dev, type);
+        queue = rt2x00queue_get_queue(rt2x00dev, pid - 1);
         if (unlikely(!queue))
             continue;
 

drivers/net/wireless/rt2x00/rt2800pci.c static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) · line 957

Quoted 10 lines
drivers/net/wireless/rt2x00/rt2800pci.c +3 -4
         /*
-         * Skip this entry when it contains an invalid
-         * index number.
+         * Inside each queue, we process each entry in a chronological
+         * order. We first check that the queue is not empty.
          */
-        index = rt2x00_get_field32(reg, TX_STA_FIFO_WCID) - 1;
-        if (unlikely(index >= queue->limit))
+        if (queue->length == 0)
             continue;

Please use the rt2x00queue_empty utility function here. It's there exactly for this purpose.

Quoted 47 lines
drivers/net/wireless/rt2x00/rt2800pci.c +13 -21
+        entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 
-        entry = &queue->entries[index];
-        entry_priv = entry->priv_data;
-        rt2x00_desc_read((__le32 *)entry->skb->data, 0, &word);
-
-        entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-        while (entry != entry_done) {
-            /*
-             * Catch up.
-             * Just report any entries we missed as failed.
-             */
-            WARNING(rt2x00dev,
-                "TX status report missed for entry %d\n",
-                entry_done->entry_idx);
-
-            txdesc.flags = 0;
-            __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
-            txdesc.retry = 0;
-
-            rt2x00lib_txdone(entry_done, &txdesc);
-            entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-        }
+        /* Check if we got a match by looking at WCID/ACK/PID
+         * fields */
+        txwi = (__le32 *)(entry->skb->data -
+                  rt2x00dev->ops->extra_tx_headroom);
+
+        rt2x00_desc_read(txwi, 1, &word);
+        tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
+        tx_ack  = rt2x00_get_field32(word, TXWI_W1_ACK);
+        tx_pid  = rt2x00_get_field32(word, TXWI_W1_PACKETID);
+
+        if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid))
+            WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n");
 
         /*

* Obtain the status about this packet.

drivers/net/wireless/rt2x00/rt2800pci.c +1 -0
@@ -997,6 +989,7 @@ static void rt2800pci_txdone(struct rt2x00_dev
 *rt2x00dev)
          * we have mcs = tx_mcs - 1. So the number of
          * retry is (tx_mcs - mcs).
          */
+        rt2x00_desc_read(txwi, 0, &word);
         mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
         real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
         __set_bit(TXDONE_FALLBACK, &txdesc.flags);
#2 lore raw
In reply to Alban Browaeys
Quoted 6 lines · Alban Browaeys

This is an implementation that support WCID being the encryption key. Wireless Cli Id was set to be the encryption key in rt2800pci_write_tx_desc and read (TX_STA_FIFO_WCID) as the current queue entry index.

/home/linville/git/wireless-testing
[linville-t400.local]:> patch -p1 < rt2x00.patch
patching file drivers/net/wireless/rt2x00/rt2800pci.c
Hunk #1 FAILED at 907.
Hunk #2 FAILED at 936.
Hunk #3 FAILED at 997.
3 out of 3 hunks FAILED -- saving rejects to file drivers/net/wireless/rt2x00/rt2800pci.c.rej

Would you care to post a version that applies against the current wireless-testing?

Thanks!

John

Signature · 2 lines
John W. Linville		Someday the world will need a hero, and you
[email protected]			might be all we have.  Be ready.
#3 lore raw
Quoted 16 lines · John W. Linville
Quoted 6 lines · Alban Browaeys

This is an implementation that support WCID being the encryption key. Wireless Cli Id was set to be the encryption key in rt2800pci_write_tx_desc and read (TX_STA_FIFO_WCID) as the current queue entry index.

/home/linville/git/wireless-testing
[linville-t400.local]:> patch -p1 < rt2x00.patch
patching file drivers/net/wireless/rt2x00/rt2800pci.c
Hunk #1 FAILED at 907.
Hunk #2 FAILED at 936.
Hunk #3 FAILED at 997.
3 out of 3 hunks FAILED -- saving rejects to file drivers/net/wireless/rt2x00/rt2800pci.c.rej

Quoted 3 lines

Would you care to post a version that applies against the current wireless-testing?

John,

If you want, you can also pull from:

git://git.gwingerde.nl/rt2x00-next-2.6.git

This contains all rt2x00 patches sent to the list (and you) that were acked by either Ivo or myself, or both. This tree is against wireless-next-2.6, but should do the trick, I guess.

---
Gertjan.