diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-03-09 17:42:59 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-13 16:02:35 -0400 |
commit | 8af244ccb14a4367568db11c5e78b45a4c2cf77e (patch) | |
tree | 350727822602b851dcc2d31ad7a64fe7c4528a88 /drivers/net/wireless/rt2x00 | |
parent | 3976ae6c2b09608cd6a13663737a6b219245b651 (diff) |
rt2x00: Only disable beaconing just before beacon update
We should not write 0 to the beacon sync register during
config_intf() since that will clear out the beacon interval
and forces the beacon to be send out at the lowest interval.
(reported by Mattias Nissler).
The side effect of the same bug was that while working with
multiple virtual AP interfaces a change for any of those
interfaces would disable beaconing untill an beacon update
was provided.
This is resolved by only updating the TSF_SYNC value during
config_intf(). In update_beacon() we disable beaconing
temporarily to prevent fake beacons to be transmitted.
Finally kick_tx_queue() will enable beaconing again.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 18 |
5 files changed, 65 insertions, 29 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 460ef2fb5104..a1c38a144149 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -279,8 +279,6 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
279 | u32 reg; | 279 | u32 reg; |
280 | 280 | ||
281 | if (flags & CONFIG_UPDATE_TYPE) { | 281 | if (flags & CONFIG_UPDATE_TYPE) { |
282 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
283 | |||
284 | /* | 282 | /* |
285 | * Enable beacon config | 283 | * Enable beacon config |
286 | */ | 284 | */ |
@@ -293,10 +291,6 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
293 | * Enable synchronisation. | 291 | * Enable synchronisation. |
294 | */ | 292 | */ |
295 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 293 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
296 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
297 | rt2x00_set_field32(®, CSR14_TBCN, | ||
298 | (conf->sync == TSF_SYNC_BEACON)); | ||
299 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
300 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | 294 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
301 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 295 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
302 | } | 296 | } |
@@ -1040,6 +1034,8 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1040 | if (queue == RT2X00_BCN_QUEUE_BEACON) { | 1034 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1041 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1035 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1042 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1036 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1037 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1038 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1043 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1039 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
1044 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1040 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1045 | } | 1041 | } |
@@ -1517,10 +1513,10 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1517 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | 1513 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1518 | struct queue_entry_priv_pci_tx *priv_tx; | 1514 | struct queue_entry_priv_pci_tx *priv_tx; |
1519 | struct skb_frame_desc *skbdesc; | 1515 | struct skb_frame_desc *skbdesc; |
1516 | u32 reg; | ||
1520 | 1517 | ||
1521 | if (unlikely(!intf->beacon)) | 1518 | if (unlikely(!intf->beacon)) |
1522 | return -ENOBUFS; | 1519 | return -ENOBUFS; |
1523 | |||
1524 | priv_tx = intf->beacon->priv_data; | 1520 | priv_tx = intf->beacon->priv_data; |
1525 | 1521 | ||
1526 | /* | 1522 | /* |
@@ -1536,6 +1532,16 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1536 | skbdesc->entry = intf->beacon; | 1532 | skbdesc->entry = intf->beacon; |
1537 | 1533 | ||
1538 | /* | 1534 | /* |
1535 | * Disable beaconing while we are reloading the beacon data, | ||
1536 | * otherwise we might be sending out invalid data. | ||
1537 | */ | ||
1538 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1539 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1540 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1541 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1542 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1543 | |||
1544 | /* | ||
1539 | * mac80211 doesn't provide the control->queue variable | 1545 | * mac80211 doesn't provide the control->queue variable |
1540 | * for beacons. Set our own queue identification so | 1546 | * for beacons. Set our own queue identification so |
1541 | * it can be used during descriptor initialization. | 1547 | * it can be used during descriptor initialization. |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index ffcd996df064..096232763055 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -281,8 +281,6 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
281 | u32 reg; | 281 | u32 reg; |
282 | 282 | ||
283 | if (flags & CONFIG_UPDATE_TYPE) { | 283 | if (flags & CONFIG_UPDATE_TYPE) { |
284 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
285 | |||
286 | /* | 284 | /* |
287 | * Enable beacon config | 285 | * Enable beacon config |
288 | */ | 286 | */ |
@@ -296,10 +294,6 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
296 | * Enable synchronisation. | 294 | * Enable synchronisation. |
297 | */ | 295 | */ |
298 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 296 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
299 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
300 | rt2x00_set_field32(®, CSR14_TBCN, | ||
301 | (conf->sync == TSF_SYNC_BEACON)); | ||
302 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
303 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | 297 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
304 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 298 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
305 | } | 299 | } |
@@ -1193,6 +1187,8 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1193 | if (queue == RT2X00_BCN_QUEUE_BEACON) { | 1187 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1194 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1188 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1195 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1189 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1190 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1191 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1196 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1192 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
1197 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1193 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1198 | } | 1194 | } |
@@ -1828,6 +1824,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1828 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | 1824 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1829 | struct queue_entry_priv_pci_tx *priv_tx; | 1825 | struct queue_entry_priv_pci_tx *priv_tx; |
1830 | struct skb_frame_desc *skbdesc; | 1826 | struct skb_frame_desc *skbdesc; |
1827 | u32 reg; | ||
1831 | 1828 | ||
1832 | if (unlikely(!intf->beacon)) | 1829 | if (unlikely(!intf->beacon)) |
1833 | return -ENOBUFS; | 1830 | return -ENOBUFS; |
@@ -1847,6 +1844,16 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1847 | skbdesc->entry = intf->beacon; | 1844 | skbdesc->entry = intf->beacon; |
1848 | 1845 | ||
1849 | /* | 1846 | /* |
1847 | * Disable beaconing while we are reloading the beacon data, | ||
1848 | * otherwise we might be sending out invalid data. | ||
1849 | */ | ||
1850 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1851 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1852 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1853 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1854 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1855 | |||
1856 | /* | ||
1850 | * mac80211 doesn't provide the control->queue variable | 1857 | * mac80211 doesn't provide the control->queue variable |
1851 | * for beacons. Set our own queue identification so | 1858 | * for beacons. Set our own queue identification so |
1852 | * it can be used during descriptor initialization. | 1859 | * it can be used during descriptor initialization. |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 559131fc6d53..b6c6f7dd9eda 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -324,8 +324,6 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, | |||
324 | u16 reg; | 324 | u16 reg; |
325 | 325 | ||
326 | if (flags & CONFIG_UPDATE_TYPE) { | 326 | if (flags & CONFIG_UPDATE_TYPE) { |
327 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | ||
328 | |||
329 | /* | 327 | /* |
330 | * Enable beacon config | 328 | * Enable beacon config |
331 | */ | 329 | */ |
@@ -344,10 +342,6 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, | |||
344 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | 342 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); |
345 | 343 | ||
346 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 344 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
347 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
348 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | ||
349 | (conf->sync == TSF_SYNC_BEACON)); | ||
350 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
351 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); | 345 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); |
352 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | 346 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); |
353 | } | 347 | } |
@@ -1092,6 +1086,8 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1092 | 1086 | ||
1093 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 1087 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
1094 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { | 1088 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { |
1089 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
1090 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); | ||
1095 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); | 1091 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); |
1096 | /* | 1092 | /* |
1097 | * Beacon generation will fail initially. | 1093 | * Beacon generation will fail initially. |
@@ -1740,6 +1736,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1740 | struct skb_frame_desc *skbdesc; | 1736 | struct skb_frame_desc *skbdesc; |
1741 | int pipe = usb_sndbulkpipe(usb_dev, 1); | 1737 | int pipe = usb_sndbulkpipe(usb_dev, 1); |
1742 | int length; | 1738 | int length; |
1739 | u16 reg; | ||
1743 | 1740 | ||
1744 | if (unlikely(!intf->beacon)) | 1741 | if (unlikely(!intf->beacon)) |
1745 | return -ENOBUFS; | 1742 | return -ENOBUFS; |
@@ -1765,6 +1762,16 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1765 | skbdesc->entry = intf->beacon; | 1762 | skbdesc->entry = intf->beacon; |
1766 | 1763 | ||
1767 | /* | 1764 | /* |
1765 | * Disable beaconing while we are reloading the beacon data, | ||
1766 | * otherwise we might be sending out invalid data. | ||
1767 | */ | ||
1768 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
1769 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); | ||
1770 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
1771 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
1772 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
1773 | |||
1774 | /* | ||
1768 | * mac80211 doesn't provide the control->queue variable | 1775 | * mac80211 doesn't provide the control->queue variable |
1769 | * for beacons. Set our own queue identification so | 1776 | * for beacons. Set our own queue identification so |
1770 | * it can be used during descriptor initialization. | 1777 | * it can be used during descriptor initialization. |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 091fe398676d..13b918db1850 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -336,17 +336,12 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
336 | * bits which (when set to 0) will invalidate the entire beacon. | 336 | * bits which (when set to 0) will invalidate the entire beacon. |
337 | */ | 337 | */ |
338 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | 338 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
339 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
340 | rt2x00pci_register_write(rt2x00dev, beacon_base, 0); | 339 | rt2x00pci_register_write(rt2x00dev, beacon_base, 0); |
341 | 340 | ||
342 | /* | 341 | /* |
343 | * Enable synchronisation. | 342 | * Enable synchronisation. |
344 | */ | 343 | */ |
345 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 344 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); |
346 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
347 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
348 | (conf->sync == TSF_SYNC_BEACON)); | ||
349 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
350 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | 345 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); |
351 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 346 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); |
352 | } | 347 | } |
@@ -1562,6 +1557,8 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1562 | 1557 | ||
1563 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 1558 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); |
1564 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | 1559 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { |
1560 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1561 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1565 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1562 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
1566 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1563 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); |
1567 | } | 1564 | } |
@@ -2373,6 +2370,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2373 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | 2370 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
2374 | struct skb_frame_desc *skbdesc; | 2371 | struct skb_frame_desc *skbdesc; |
2375 | unsigned int beacon_base; | 2372 | unsigned int beacon_base; |
2373 | u32 reg; | ||
2376 | 2374 | ||
2377 | if (unlikely(!intf->beacon)) | 2375 | if (unlikely(!intf->beacon)) |
2378 | return -ENOBUFS; | 2376 | return -ENOBUFS; |
@@ -2408,6 +2406,16 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2408 | skbdesc->entry = intf->beacon; | 2406 | skbdesc->entry = intf->beacon; |
2409 | 2407 | ||
2410 | /* | 2408 | /* |
2409 | * Disable beaconing while we are reloading the beacon data, | ||
2410 | * otherwise we might be sending out invalid data. | ||
2411 | */ | ||
2412 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2413 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2414 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2415 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2416 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2417 | |||
2418 | /* | ||
2411 | * mac80211 doesn't provide the control->queue variable | 2419 | * mac80211 doesn't provide the control->queue variable |
2412 | * for beacons. Set our own queue identification so | 2420 | * for beacons. Set our own queue identification so |
2413 | * it can be used during descriptor initialization. | 2421 | * it can be used during descriptor initialization. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 468039f1bff9..a28c1d84ba95 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -347,17 +347,12 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, | |||
347 | * bits which (when set to 0) will invalidate the entire beacon. | 347 | * bits which (when set to 0) will invalidate the entire beacon. |
348 | */ | 348 | */ |
349 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | 349 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
350 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
351 | rt73usb_register_write(rt2x00dev, beacon_base, 0); | 350 | rt73usb_register_write(rt2x00dev, beacon_base, 0); |
352 | 351 | ||
353 | /* | 352 | /* |
354 | * Enable synchronisation. | 353 | * Enable synchronisation. |
355 | */ | 354 | */ |
356 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 355 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
357 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
358 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
359 | (conf->sync == TSF_SYNC_BEACON)); | ||
360 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
361 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | 356 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); |
362 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 357 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
363 | } | 358 | } |
@@ -1312,6 +1307,8 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1312 | 1307 | ||
1313 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 1308 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
1314 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | 1309 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { |
1310 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1311 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1315 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1312 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
1316 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 1313 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
1317 | } | 1314 | } |
@@ -1987,6 +1984,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1987 | struct skb_frame_desc *skbdesc; | 1984 | struct skb_frame_desc *skbdesc; |
1988 | unsigned int beacon_base; | 1985 | unsigned int beacon_base; |
1989 | unsigned int timeout; | 1986 | unsigned int timeout; |
1987 | u32 reg; | ||
1990 | 1988 | ||
1991 | if (unlikely(!intf->beacon)) | 1989 | if (unlikely(!intf->beacon)) |
1992 | return -ENOBUFS; | 1990 | return -ENOBUFS; |
@@ -2010,6 +2008,16 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2010 | skbdesc->entry = intf->beacon; | 2008 | skbdesc->entry = intf->beacon; |
2011 | 2009 | ||
2012 | /* | 2010 | /* |
2011 | * Disable beaconing while we are reloading the beacon data, | ||
2012 | * otherwise we might be sending out invalid data. | ||
2013 | */ | ||
2014 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2015 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2016 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2017 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2018 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2019 | |||
2020 | /* | ||
2013 | * mac80211 doesn't provide the control->queue variable | 2021 | * mac80211 doesn't provide the control->queue variable |
2014 | * for beacons. Set our own queue identification so | 2022 | * for beacons. Set our own queue identification so |
2015 | * it can be used during descriptor initialization. | 2023 | * it can be used during descriptor initialization. |