提交 d6756d0d 编写于 作者: I Igor Perminov 提交者: John W. Linville

rt2x00: Fix beacon de-synchronization while update beacon

When beacon is being updated to refresh TIM (AP mode), beacon frames are
de-synchronizing (i.e. two neighbor beacon frames - before and after
update - are being transmitted with a wrong time interval).
That is because xxx_write_beacon should disable beacon generation only
while beacon data are being uploaded to the device, but it should not
disable the beacon clock.
Signed-off-by: NIgor Perminov <igor.perminov@inbox.ru>
Signed-off-by: NIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 3281d95d
...@@ -1069,8 +1069,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry) ...@@ -1069,8 +1069,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry)
* otherwise we might be sending out invalid data. * otherwise we might be sending out invalid data.
*/ */
rt2x00pci_register_read(rt2x00dev, CSR14, &reg); rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
rt2x00_set_field32(&reg, CSR14_TBCN, 0);
rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0); rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, CSR14, reg); rt2x00pci_register_write(rt2x00dev, CSR14, reg);
......
...@@ -1227,8 +1227,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry) ...@@ -1227,8 +1227,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry)
* otherwise we might be sending out invalid data. * otherwise we might be sending out invalid data.
*/ */
rt2x00pci_register_read(rt2x00dev, CSR14, &reg); rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
rt2x00_set_field32(&reg, CSR14_TBCN, 0);
rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0); rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, CSR14, reg); rt2x00pci_register_write(rt2x00dev, CSR14, reg);
......
...@@ -1238,8 +1238,6 @@ static void rt2500usb_write_beacon(struct queue_entry *entry) ...@@ -1238,8 +1238,6 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
* otherwise we might be sending out invalid data. * otherwise we might be sending out invalid data.
*/ */
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg); rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0); rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
...@@ -1287,7 +1285,7 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry) ...@@ -1287,7 +1285,7 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid queue) const enum data_queue_qid queue)
{ {
u16 reg; u16 reg, reg0;
if (queue != QID_BEACON) { if (queue != QID_BEACON) {
rt2x00usb_kick_tx_queue(rt2x00dev, queue); rt2x00usb_kick_tx_queue(rt2x00dev, queue);
...@@ -1298,16 +1296,19 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, ...@@ -1298,16 +1296,19 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {
rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1); rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1); rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
reg0 = reg;
rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1); rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
/* /*
* Beacon generation will fail initially. * Beacon generation will fail initially.
* To prevent this we need to register the TXRX_CSR19 * To prevent this we need to change the TXRX_CSR19
* register several times. * register several times (reg0 is the same as reg
* except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0
* and 1 in reg).
*/ */
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
} }
} }
......
...@@ -2050,8 +2050,6 @@ static void rt2800usb_write_beacon(struct queue_entry *entry) ...@@ -2050,8 +2050,6 @@ static void rt2800usb_write_beacon(struct queue_entry *entry)
* otherwise we might be sending out invalid data. * otherwise we might be sending out invalid data.
*/ */
rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg); rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0); rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg); rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
......
...@@ -1855,8 +1855,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry) ...@@ -1855,8 +1855,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry)
* otherwise we might be sending out invalid data. * otherwise we might be sending out invalid data.
*/ */
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg); rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0); rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
......
...@@ -1527,8 +1527,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry) ...@@ -1527,8 +1527,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
* otherwise we might be sending out invalid data. * otherwise we might be sending out invalid data.
*/ */
rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg); rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0); rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册