diff options
-rwxr-xr-x | drivers/staging/cw1200/ap.c | 9 | ||||
-rw-r--r-- | drivers/staging/cw1200/txrx.c | 9 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.c | 4 |
3 files changed, 20 insertions, 2 deletions
diff --git a/drivers/staging/cw1200/ap.c b/drivers/staging/cw1200/ap.c index f58ccb13205..ff8d36cbedb 100755 --- a/drivers/staging/cw1200/ap.c +++ b/drivers/staging/cw1200/ap.c @@ -59,6 +59,8 @@ int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, entry = &priv->link_id_db[sta_priv->link_id - 1]; spin_lock_bh(&priv->ps_state_lock); + if (sta->uapsd_queues) + priv->sta_asleep_mask |= BIT(sta_priv->link_id); entry->status = CW1200_LINK_HARD; while ((skb = skb_dequeue(&entry->rx_queue))) ieee80211_rx_irqsafe(priv->hw, skb); @@ -617,11 +619,13 @@ void cw1200_multicast_start_work(struct work_struct *work) long tmo = priv->join_dtim_period * (priv->beacon_int + 20) * HZ / 1024; + cancel_work_sync(&priv->multicast_stop_work); + if (!priv->aid0_bit_set) { wsm_lock_tx(priv); cw1200_set_tim_impl(priv, true); priv->aid0_bit_set = true; - mod_timer(&priv->mcast_timeout, tmo); + mod_timer(&priv->mcast_timeout, jiffies + tmo); wsm_unlock_tx(priv); } } @@ -632,6 +636,7 @@ void cw1200_multicast_stop_work(struct work_struct *work) container_of(work, struct cw1200_common, multicast_stop_work); if (priv->aid0_bit_set) { + del_timer_sync(&priv->mcast_timeout); wsm_lock_tx(priv); priv->aid0_bit_set = false; cw1200_set_tim_impl(priv, false); @@ -644,6 +649,8 @@ void cw1200_mcast_timeout(unsigned long arg) struct cw1200_common *priv = (struct cw1200_common *)arg; + wiphy_warn(priv->hw->wiphy, + "Multicast delivery timeout.\n"); spin_lock_bh(&priv->ps_state_lock); priv->tx_multicast = priv->aid0_bit_set && priv->buffered_multicasts; diff --git a/drivers/staging/cw1200/txrx.c b/drivers/staging/cw1200/txrx.c index 0d535f797a8..9569fd5849f 100644 --- a/drivers/staging/cw1200/txrx.c +++ b/drivers/staging/cw1200/txrx.c @@ -892,6 +892,15 @@ void cw1200_tx_confirm_cb(struct cw1200_common *priv, priv->sta_asleep_mask); WARN_ON(cw1200_queue_requeue(queue, arg->packetID)); + spin_lock_bh(&priv->ps_state_lock); + if (!arg->link_id) { + priv->buffered_multicasts = true; + if (priv->sta_asleep_mask) { + queue_work(priv->workqueue, + &priv->multicast_start_work); + } + } + spin_unlock_bh(&priv->ps_state_lock); } else if (!WARN_ON(cw1200_queue_get_skb( queue, arg->packetID, &skb, &txpriv))) { struct ieee80211_tx_info *tx = IEEE80211_SKB_CB(skb); diff --git a/drivers/staging/cw1200/wsm.c b/drivers/staging/cw1200/wsm.c index b1a2a9ecc6a..d3a23b44462 100644 --- a/drivers/staging/cw1200/wsm.c +++ b/drivers/staging/cw1200/wsm.c @@ -1638,9 +1638,11 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data, (priv->tx_multicast || !priv->sta_asleep_mask)) { priv->buffered_multicasts = false; - if (priv->tx_multicast) + if (priv->tx_multicast) { + priv->tx_multicast = false; queue_work(priv->workqueue, &priv->multicast_stop_work); + } } spin_unlock_bh(&priv->ps_state_lock); |