aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt73usb.c
diff options
context:
space:
mode:
authorHelmut Schaa <helmut.schaa@googlemail.com>2011-01-30 07:16:03 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-01-31 15:06:22 -0500
commit69cf36a4523be026bc16743c5c989c5e82edb7d9 (patch)
tree0c6572b724d840d879ff12861d8ac57da1bad635 /drivers/net/wireless/rt2x00/rt73usb.c
parentd828cd5a95e532636dbc495e4b94b625ab9abdad (diff)
rt2x00: Refactor beacon code to make use of start- and stop_queue
This patch allows to dynamically remove beaconing interfaces without shutting beaconing down on all interfaces. The only place to start and stop beaconing are now the start- and stop_queue callbacks. Hence, we can remove some register writes during interface bring up (config_intf) and only write the correct sync mode to the register there. When multiple beaconing interfaces are present we should enable beaconing as soon as mac80211 enables beaconing on at least one of them. The beacon queue gets stopped when the last beaconing interface was stopped by mac80211. Therefore, introduce another interface counter to keep track ot the number of enabled beaconing interfaces and start or stop the beacon queue accordingly. To allow single interfaces to stop beaconing, add a new driver callback clear_beacon to clear a single interface's beacon without affecting the other interfaces. Don't overload the clear_entry callback for clearing beacons as that would introduce additional overhead (check for each TX queue) into the clear_entry callback which is used on the drivers TX/RX hotpaths. Furthermore, the write beacon callback doesn't need to enable beaconing anymore but since beaconing should be disabled while a new beacon is written or cleared we still disable beacon generation and enable it afterwards again in the driver specific callbacks. However, beacon related interrupts should not be disabled/enabled here, that's solely done from the start- and stop queue callbacks. It would be nice to stop the beacon queue just before the beacon update and enable it afterwards in rt2x00queue itself instead of the current implementation that relies on the driver doing the right thing. However, since start- and stop_queue are mutex protected we cannot use them for atomic beacon updates. 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>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 029be3c6c030..330353ec5c96 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -502,26 +502,14 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
502 struct rt2x00intf_conf *conf, 502 struct rt2x00intf_conf *conf,
503 const unsigned int flags) 503 const unsigned int flags)
504{ 504{
505 unsigned int beacon_base;
506 u32 reg; 505 u32 reg;
507 506
508 if (flags & CONFIG_UPDATE_TYPE) { 507 if (flags & CONFIG_UPDATE_TYPE) {
509 /* 508 /*
510 * Clear current synchronisation setup.
511 * For the Beacon base registers we only need to clear
512 * the first byte since that byte contains the VALID and OWNER
513 * bits which (when set to 0) will invalidate the entire beacon.
514 */
515 beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
516 rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
517
518 /*
519 * Enable synchronisation. 509 * Enable synchronisation.
520 */ 510 */
521 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg); 511 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
522 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
523 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync); 512 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync);
524 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
525 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); 513 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
526 } 514 }
527 515
@@ -1590,8 +1578,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1590 */ 1578 */
1591 rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); 1579 rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
1592 1580
1593 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1594 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
1595 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1); 1581 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1596 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); 1582 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1597 1583
@@ -1602,6 +1588,33 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1602 entry->skb = NULL; 1588 entry->skb = NULL;
1603} 1589}
1604 1590
1591static void rt73usb_clear_beacon(struct queue_entry *entry)
1592{
1593 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1594 unsigned int beacon_base;
1595 u32 reg;
1596
1597 /*
1598 * Disable beaconing while we are reloading the beacon data,
1599 * otherwise we might be sending out invalid data.
1600 */
1601 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
1602 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
1603 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1604
1605 /*
1606 * Clear beacon.
1607 */
1608 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1609 rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
1610
1611 /*
1612 * Enable beaconing again.
1613 */
1614 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1615 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1616}
1617
1605static int rt73usb_get_tx_data_len(struct queue_entry *entry) 1618static int rt73usb_get_tx_data_len(struct queue_entry *entry)
1606{ 1619{
1607 int length; 1620 int length;
@@ -2313,6 +2326,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2313 .flush_queue = rt2x00usb_flush_queue, 2326 .flush_queue = rt2x00usb_flush_queue,
2314 .write_tx_desc = rt73usb_write_tx_desc, 2327 .write_tx_desc = rt73usb_write_tx_desc,
2315 .write_beacon = rt73usb_write_beacon, 2328 .write_beacon = rt73usb_write_beacon,
2329 .clear_beacon = rt73usb_clear_beacon,
2316 .get_tx_data_len = rt73usb_get_tx_data_len, 2330 .get_tx_data_len = rt73usb_get_tx_data_len,
2317 .fill_rxdone = rt73usb_fill_rxdone, 2331 .fill_rxdone = rt73usb_fill_rxdone,
2318 .config_shared_key = rt73usb_config_shared_key, 2332 .config_shared_key = rt73usb_config_shared_key,