rt2x00: Fix rt2400pci signal
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>
This commit is contained in:
parent
dac37d7208
commit
89993890ae
8 changed files with 45 additions and 17 deletions
|
@ -1058,9 +1058,11 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
|
||||||
struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
|
struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
|
||||||
u32 word0;
|
u32 word0;
|
||||||
u32 word2;
|
u32 word2;
|
||||||
|
u32 word3;
|
||||||
|
|
||||||
rt2x00_desc_read(priv_rx->desc, 0, &word0);
|
rt2x00_desc_read(priv_rx->desc, 0, &word0);
|
||||||
rt2x00_desc_read(priv_rx->desc, 2, &word2);
|
rt2x00_desc_read(priv_rx->desc, 2, &word2);
|
||||||
|
rt2x00_desc_read(priv_rx->desc, 3, &word3);
|
||||||
|
|
||||||
rxdesc->flags = 0;
|
rxdesc->flags = 0;
|
||||||
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
|
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.
|
* Obtain the status about this packet.
|
||||||
|
* The signal is the PLCP value.
|
||||||
*/
|
*/
|
||||||
rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
|
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;
|
entry->queue->rt2x00dev->rssi_offset;
|
||||||
rxdesc->ofdm = 0;
|
rxdesc->ofdm = 0;
|
||||||
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
||||||
|
|
|
@ -899,13 +899,13 @@
|
||||||
* Word2
|
* Word2
|
||||||
*/
|
*/
|
||||||
#define RXD_W2_BUFFER_LENGTH FIELD32(0x0000ffff)
|
#define RXD_W2_BUFFER_LENGTH FIELD32(0x0000ffff)
|
||||||
#define RXD_W2_SIGNAL FIELD32(0x00ff0000)
|
#define RXD_W2_BBR0 FIELD32(0x00ff0000)
|
||||||
#define RXD_W2_RSSI FIELD32(0xff000000)
|
#define RXD_W2_SIGNAL FIELD32(0xff000000)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Word3
|
* Word3
|
||||||
*/
|
*/
|
||||||
#define RXD_W3_BBR2 FIELD32(0x000000ff)
|
#define RXD_W3_RSSI FIELD32(0x000000ff)
|
||||||
#define RXD_W3_BBR3 FIELD32(0x0000ff00)
|
#define RXD_W3_BBR3 FIELD32(0x0000ff00)
|
||||||
#define RXD_W3_BBR4 FIELD32(0x00ff0000)
|
#define RXD_W3_BBR4 FIELD32(0x00ff0000)
|
||||||
#define RXD_W3_BBR5 FIELD32(0xff000000)
|
#define RXD_W3_BBR5 FIELD32(0xff000000)
|
||||||
|
|
|
@ -1219,10 +1219,17 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry,
|
||||||
if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
|
if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
|
||||||
rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
|
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 = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
|
||||||
|
rxdesc->signal_plcp = rxdesc->ofdm;
|
||||||
rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
|
rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
|
||||||
entry->queue->rt2x00dev->rssi_offset;
|
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->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
||||||
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1135,11 +1135,15 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain the status about this packet.
|
* 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 = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
|
||||||
|
rxdesc->signal_plcp = rxdesc->ofdm;
|
||||||
rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) -
|
rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) -
|
||||||
entry->queue->rt2x00dev->rssi_offset;
|
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->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
||||||
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
||||||
|
|
||||||
|
|
|
@ -573,6 +573,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
u16 fc;
|
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.
|
* Update RX statistics.
|
||||||
*/
|
*/
|
||||||
|
@ -580,13 +587,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
|
||||||
for (i = 0; i < sband->n_bitrates; i++) {
|
for (i = 0; i < sband->n_bitrates; i++) {
|
||||||
rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
|
rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
|
||||||
|
|
||||||
/*
|
if ((rxdesc->signal_plcp && rate->plcp == rxdesc->signal) ||
|
||||||
* When frame was received with an OFDM bitrate,
|
(!rxdesc->signal_plcp && rate->bitrate == rxdesc->signal)) {
|
||||||
* 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)) {
|
|
||||||
idx = i;
|
idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
* Summary of information that has been read from the RX frame descriptor.
|
||||||
*
|
*
|
||||||
* @signal: Signal of the received frame.
|
* @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.
|
* @rssi: RSSI of the received frame.
|
||||||
* @ofdm: Was frame send with an OFDM rate.
|
* @ofdm: Was frame send with an OFDM rate.
|
||||||
* @size: Data size of the received frame.
|
* @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 {
|
struct rxdone_entry_desc {
|
||||||
int signal;
|
int signal;
|
||||||
|
int signal_plcp;
|
||||||
int rssi;
|
int rssi;
|
||||||
int ofdm;
|
int ofdm;
|
||||||
int size;
|
int size;
|
||||||
|
|
|
@ -1645,10 +1645,14 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain the status about this packet.
|
* 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->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
|
|
||||||
rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1);
|
|
||||||
rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
|
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->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
||||||
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1405,10 +1405,14 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain the status about this packet.
|
* 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->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
|
|
||||||
rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1);
|
|
||||||
rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
|
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->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
||||||
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue