]> err.no Git - linux-2.6/commitdiff
rt2x00: Fix rt2400pci signal
authorIvo van Doorn <ivdoorn@gmail.com>
Sun, 9 Mar 2008 21:49:04 +0000 (22:49 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 13 Mar 2008 23:32:31 +0000 (19:32 -0400)
After sampling hundreds of RX frame descriptors,
the results were conclusive:
- The Ralink documentation regarding the SIGNAL and RSSI are wrong.

It turns out that of the 5 BBR registers, we should not use BBR0 and BBR1
for SIGNAL and RSSI respectively, but actually BBR1 and BBR2.
BBR0 does show values, but the exact meaning remains unclear,
but they cannot be translated into a SIGNAL or RSSI field.
BBR3, BBR4 and BBR5 are always 0, so their meaning is unknown.

As it turns out, the reported SIGNAL is the PLCP value, this
in contradiction to what was expected looking at rt2500pci which
only reported the PLCP values for OFDM rates and bitrate values
for CCK rates.

This means we should let the driver raise the flag about the contents
of the SIGNAL field so rt2x00lib can always do the right thing based
on what the driver reports.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2400pci.h
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c

index a92626bc536a808847a2bb7a712ff73cd71424a9..4cd284209d160cca682ce7c18b76249e8d637d86 100644 (file)
@@ -1058,9 +1058,11 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
        struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
        u32 word0;
        u32 word2;
+       u32 word3;
 
        rt2x00_desc_read(priv_rx->desc, 0, &word0);
        rt2x00_desc_read(priv_rx->desc, 2, &word2);
+       rt2x00_desc_read(priv_rx->desc, 3, &word3);
 
        rxdesc->flags = 0;
        if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
@@ -1070,9 +1072,11 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
 
        /*
         * Obtain the status about this packet.
+        * The signal is the PLCP value.
         */
        rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
-       rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
+       rxdesc->signal_plcp = 1;
+       rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) -
            entry->queue->rt2x00dev->rssi_offset;
        rxdesc->ofdm = 0;
        rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
index da178d44660ea0f07c8614180a428e595047a715..a5210f9a3360ba521f7ca6dc786351156f32dc18 100644 (file)
  * Word2
  */
 #define RXD_W2_BUFFER_LENGTH           FIELD32(0x0000ffff)
-#define RXD_W2_SIGNAL                  FIELD32(0x00ff0000)
-#define RXD_W2_RSSI                    FIELD32(0xff000000)
+#define RXD_W2_BBR0                    FIELD32(0x00ff0000)
+#define RXD_W2_SIGNAL                  FIELD32(0xff000000)
 
 /*
  * Word3
  */
-#define RXD_W3_BBR2                    FIELD32(0x000000ff)
+#define RXD_W3_RSSI                    FIELD32(0x000000ff)
 #define RXD_W3_BBR3                    FIELD32(0x0000ff00)
 #define RXD_W3_BBR4                    FIELD32(0x00ff0000)
 #define RXD_W3_BBR5                    FIELD32(0xff000000)
index 4ae09b4187045b481cfe11634bbc0c7505603bdb..0f5139a2f238e36afb1e9400a291ad18174d9237 100644 (file)
@@ -1219,10 +1219,17 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry,
        if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
                rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
 
+       /*
+        * Obtain the status about this packet.
+        * When frame was received with an OFDM bitrate,
+        * the signal is the PLCP value. If it was received with
+        * a CCK bitrate the signal is the rate in 100kbit/s.
+        */
+       rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
+       rxdesc->signal_plcp = rxdesc->ofdm;
        rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
            entry->queue->rt2x00dev->rssi_offset;
-       rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
        rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 }
index 8dfebfd695de3012975fe93245edc4fc843c01fc..c8216d755835daf1e8fbcdbf1db050095b30d1e5 100644 (file)
@@ -1135,11 +1135,15 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
 
        /*
         * Obtain the status about this packet.
+        * When frame was received with an OFDM bitrate,
+        * the signal is the PLCP value. If it was received with
+        * a CCK bitrate the signal is the rate in 100kbit/s.
         */
+       rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+       rxdesc->signal_plcp = rxdesc->ofdm;
        rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) -
            entry->queue->rt2x00dev->rssi_offset;
-       rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
        rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 
index eb2d21c4e8e9a7afca0ba41ab0af5ae1bc458487..a885254d2e85cf1133fbe8ed3ea7784881385cd1 100644 (file)
@@ -573,6 +573,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
        int idx = -1;
        u16 fc;
 
+       /*
+        * If the signal is the plcp value,
+        * we need to strip the preamble bit (0x08).
+        */
+       if (rxdesc->signal_plcp)
+               rxdesc->signal &= ~0x08;
+
        /*
         * Update RX statistics.
         */
@@ -580,13 +587,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
        for (i = 0; i < sband->n_bitrates; i++) {
                rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
 
-               /*
-                * When frame was received with an OFDM bitrate,
-                * the signal is the PLCP value. If it was received with
-                * a CCK bitrate the signal is the rate in 100kbit/s.
-                */
-               if ((rxdesc->ofdm && rate->plcp == rxdesc->signal) ||
-                   (!rxdesc->ofdm && rate->bitrate == rxdesc->signal)) {
+               if ((rxdesc->signal_plcp && rate->plcp == rxdesc->signal) ||
+                   (!rxdesc->signal_plcp && rate->bitrate == rxdesc->signal)) {
                        idx = i;
                        break;
                }
index fbabf389b62269cdc01c7d153015354caedb09de..c5f46f234083b678fd211e519d3afb792c85c621 100644 (file)
@@ -134,6 +134,8 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
  * Summary of information that has been read from the RX frame descriptor.
  *
  * @signal: Signal of the received frame.
+ * @signal_plcp: Does the signal field contain the plcp value,
+ *     or does it contain the bitrate itself.
  * @rssi: RSSI of the received frame.
  * @ofdm: Was frame send with an OFDM rate.
  * @size: Data size of the received frame.
@@ -142,6 +144,7 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
  */
 struct rxdone_entry_desc {
        int signal;
+       int signal_plcp;
        int rssi;
        int ofdm;
        int size;
index 914aee0ce8cee7d42e71655e12030a61399eb115..4baa916b80cf215f68aa9166b7a49d166a92e5a9 100644 (file)
@@ -1645,10 +1645,14 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry,
 
        /*
         * Obtain the status about this packet.
+        * When frame was received with an OFDM bitrate,
+        * the signal is the PLCP value. If it was received with
+        * a CCK bitrate the signal is the rate in 100kbit/s.
         */
+       rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+       rxdesc->signal_plcp = rxdesc->ofdm;
        rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1);
-       rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
        rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 }
index fc38c0c5cc3accff7a28dbcb7c82c7525045e977..48938819ee2f41777dd14240df87b037f0988d83 100644 (file)
@@ -1405,10 +1405,14 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
 
        /*
         * Obtain the status about this packet.
+        * When frame was received with an OFDM bitrate,
+        * the signal is the PLCP value. If it was received with
+        * a CCK bitrate the signal is the rate in 100kbit/s.
         */
+       rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+       rxdesc->signal_plcp = rxdesc->ofdm;
        rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1);
-       rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
        rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);