p54: implement flush callback
authorChristian Lamparter <chunkeey@googlemail.com>
Wed, 16 Feb 2011 18:43:06 +0000 (19:43 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 18 Feb 2011 21:54:54 +0000 (16:54 -0500)
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/p54/main.c

index 338e8dcac1f3f4dfe13d3f06372d54c156b4e1ff..e14a05bbc485720fc8a2509b405c335770c832db 100644 (file)
@@ -524,6 +524,48 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx,
        return 0;
 }
 
+static unsigned int p54_flush_count(struct p54_common *priv)
+{
+       unsigned int total = 0, i;
+
+       BUILD_BUG_ON(P54_QUEUE_NUM > ARRAY_SIZE(priv->tx_stats));
+
+       /*
+        * Because the firmware has the sole control over any frames
+        * in the P54_QUEUE_BEACON or P54_QUEUE_SCAN queues, they
+        * don't really count as pending or active.
+        */
+       for (i = P54_QUEUE_MGMT; i < P54_QUEUE_NUM; i++)
+               total += priv->tx_stats[i].len;
+       return total;
+}
+
+static void p54_flush(struct ieee80211_hw *dev, bool drop)
+{
+       struct p54_common *priv = dev->priv;
+       unsigned int total, i;
+
+       /*
+        * Currently, it wouldn't really matter if we wait for one second
+        * or 15 minutes. But once someone gets around and completes the
+        * TODOs [ancel stuck frames / reset device] in p54_work, it will
+        * suddenly make sense to wait that long.
+        */
+       i = P54_STATISTICS_UPDATE * 2 / 20;
+
+       /*
+        * In this case no locking is required because as we speak the
+        * queues have already been stopped and no new frames can sneak
+        * up from behind.
+        */
+       while ((total = p54_flush_count(priv) && i--)) {
+               /* waste time */
+               msleep(20);
+       }
+
+       WARN(total, "tx flush timeout, unresponsive firmware");
+}
+
 static const struct ieee80211_ops p54_ops = {
        .tx                     = p54_tx_80211,
        .start                  = p54_start,
@@ -536,6 +578,7 @@ static const struct ieee80211_ops p54_ops = {
        .sta_remove             = p54_sta_add_remove,
        .set_key                = p54_set_key,
        .config                 = p54_config,
+       .flush                  = p54_flush,
        .bss_info_changed       = p54_bss_info_changed,
        .configure_filter       = p54_configure_filter,
        .conf_tx                = p54_conf_tx,