mirror of https://gitee.com/openkylin/linux.git
rt2x00: Fix TX_STA_FIFO handling
Currently rt2800pci will read TX_STA_FIFO until the previously read value matches the current value. However, it is obvious that TX_STA_FIFO only contains values that can easily be the same for multiple consecutive frames (especially when communicating with only one other STA). Hence, we often ended up with reading only the first entry and ignoring the rest. One result was that when the TX_STA_FIFO contained multiple entires, only the first one was read and properly handled while the others remained in the tx queue. Thus, drop this check but introduce a maximum number of reads. All legacy drivers use the size of the tx ring as limit but state that the TX_STA_FIFO has only 16 entries. So, let's just stick with the tx ring size for now. Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com> Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
52b58facff
commit
3afa626a05
|
@ -813,29 +813,24 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
|
||||||
struct txdone_entry_desc txdesc;
|
struct txdone_entry_desc txdesc;
|
||||||
u32 word;
|
u32 word;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
u32 old_reg;
|
|
||||||
int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
|
int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
|
||||||
u16 mcs, real_mcs;
|
u16 mcs, real_mcs;
|
||||||
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* During each loop we will compare the freshly read
|
* TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
|
||||||
* TX_STA_FIFO register value with the value read from
|
* at most X times and also stop processing once the TX_STA_FIFO_VALID
|
||||||
* the previous loop. If the 2 values are equal then
|
* flag is not set anymore.
|
||||||
* we should stop processing because the chance it
|
*
|
||||||
* quite big that the device has been unplugged and
|
* The legacy drivers use X=TX_RING_SIZE but state in a comment
|
||||||
* we risk going into an endless loop.
|
* that the TX_STA_FIFO stack has a size of 16. We stick to our
|
||||||
|
* tx ring size for now.
|
||||||
*/
|
*/
|
||||||
old_reg = 0;
|
for (i = 0; i < TX_ENTRIES; i++) {
|
||||||
|
|
||||||
while (1) {
|
|
||||||
rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®);
|
rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®);
|
||||||
if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
|
if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (old_reg == reg)
|
|
||||||
break;
|
|
||||||
old_reg = reg;
|
|
||||||
|
|
||||||
wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
|
wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
|
||||||
ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
|
ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
|
||||||
pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
|
pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
|
||||||
|
|
Loading…
Reference in New Issue