diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2011-02-16 13:43:06 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-18 16:54:54 -0500 |
commit | 0d4171e2153b70957fe67867420a1a24d5e4cd82 (patch) | |
tree | 3040d892010187dee5434fb4fb031cc52dc5c54b | |
parent | 8b2988c13da00ac9d03f1764fdb26180c188f9e0 (diff) |
p54: implement flush callback
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/p54/main.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 338e8dcac1f3..e14a05bbc485 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -524,6 +524,48 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx, | |||
524 | return 0; | 524 | return 0; |
525 | } | 525 | } |
526 | 526 | ||
527 | static unsigned int p54_flush_count(struct p54_common *priv) | ||
528 | { | ||
529 | unsigned int total = 0, i; | ||
530 | |||
531 | BUILD_BUG_ON(P54_QUEUE_NUM > ARRAY_SIZE(priv->tx_stats)); | ||
532 | |||
533 | /* | ||
534 | * Because the firmware has the sole control over any frames | ||
535 | * in the P54_QUEUE_BEACON or P54_QUEUE_SCAN queues, they | ||
536 | * don't really count as pending or active. | ||
537 | */ | ||
538 | for (i = P54_QUEUE_MGMT; i < P54_QUEUE_NUM; i++) | ||
539 | total += priv->tx_stats[i].len; | ||
540 | return total; | ||
541 | } | ||
542 | |||
543 | static void p54_flush(struct ieee80211_hw *dev, bool drop) | ||
544 | { | ||
545 | struct p54_common *priv = dev->priv; | ||
546 | unsigned int total, i; | ||
547 | |||
548 | /* | ||
549 | * Currently, it wouldn't really matter if we wait for one second | ||
550 | * or 15 minutes. But once someone gets around and completes the | ||
551 | * TODOs [ancel stuck frames / reset device] in p54_work, it will | ||
552 | * suddenly make sense to wait that long. | ||
553 | */ | ||
554 | i = P54_STATISTICS_UPDATE * 2 / 20; | ||
555 | |||
556 | /* | ||
557 | * In this case no locking is required because as we speak the | ||
558 | * queues have already been stopped and no new frames can sneak | ||
559 | * up from behind. | ||
560 | */ | ||
561 | while ((total = p54_flush_count(priv) && i--)) { | ||
562 | /* waste time */ | ||
563 | msleep(20); | ||
564 | } | ||
565 | |||
566 | WARN(total, "tx flush timeout, unresponsive firmware"); | ||
567 | } | ||
568 | |||
527 | static const struct ieee80211_ops p54_ops = { | 569 | static const struct ieee80211_ops p54_ops = { |
528 | .tx = p54_tx_80211, | 570 | .tx = p54_tx_80211, |
529 | .start = p54_start, | 571 | .start = p54_start, |
@@ -536,6 +578,7 @@ static const struct ieee80211_ops p54_ops = { | |||
536 | .sta_remove = p54_sta_add_remove, | 578 | .sta_remove = p54_sta_add_remove, |
537 | .set_key = p54_set_key, | 579 | .set_key = p54_set_key, |
538 | .config = p54_config, | 580 | .config = p54_config, |
581 | .flush = p54_flush, | ||
539 | .bss_info_changed = p54_bss_info_changed, | 582 | .bss_info_changed = p54_bss_info_changed, |
540 | .configure_filter = p54_configure_filter, | 583 | .configure_filter = p54_configure_filter, |
541 | .conf_tx = p54_conf_tx, | 584 | .conf_tx = p54_conf_tx, |