diff options
author | Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> | 2011-05-15 14:19:19 +0200 |
---|---|---|
committer | Philippe LANGLAIS <philippe.langlais@stericsson.com> | 2011-10-13 09:48:10 +0200 |
commit | cfb080ee289b8ac17d24f7a9e1f12ea63de7daac (patch) | |
tree | 566ef9ea74391aa27f8127830edb7daa3f2d6f25 /drivers/staging/cw1200/txrx.c | |
parent | 5af0c9e8c945fa28d570d232ddebb8bca5db427f (diff) |
cw1200: Fix for buffered multicasts in AP-PS mode.
Refactoring of multicast handling:
* When multicast is coming, driver sets aid0 bit in TIM IE and puts
multicas in the queue with "AFTER_DTIM" link id.
* When WSM indicates DTIM beacon, driver verifies if aid0 indicating
beacon was sent and sends buffered multicasts.
* Driver clears aid0 bit in the TIM IE when no more multicasts are
available.
+ A stilistic change: 1 << shift is replaced by BIT(shift)
Change-Id: I15b134bf847913a907f00293ae99d7a71bbc7343
Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/27306
Reviewed-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
Tested-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33488
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Diffstat (limited to 'drivers/staging/cw1200/txrx.c')
-rw-r--r-- | drivers/staging/cw1200/txrx.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/staging/cw1200/txrx.c b/drivers/staging/cw1200/txrx.c index 7616c237a88..5439947d742 100644 --- a/drivers/staging/cw1200/txrx.c +++ b/drivers/staging/cw1200/txrx.c @@ -350,8 +350,8 @@ u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv, u32 rates) u32 ret = 0; int i; for (i = 0; i < 32; ++i) { - if (rates & (1 << i)) - ret |= 1 << priv->rates[i].hw_value; + if (rates & BIT(i)) + ret |= BIT(priv->rates[i].hw_value); } return ret; } @@ -422,10 +422,12 @@ void cw1200_tx(struct ieee80211_hw *dev, struct sk_buff *skb) (struct ieee80211_hdr *)skb->data; struct cw1200_sta_priv *sta_priv = (struct cw1200_sta_priv *)&tx_info->control.sta->drv_priv; + bool obtain_lock; int link_id = 0; int ret; - if (tx_info->flags | IEEE80211_TX_CTL_SEND_AFTER_DTIM) + if ((tx_info->flags | IEEE80211_TX_CTL_SEND_AFTER_DTIM) && + (priv->mode == NL80211_IFTYPE_AP)) link_id = CW1200_LINK_ID_AFTER_DTIM; else if (tx_info->control.sta) link_id = sta_priv->link_id; @@ -510,8 +512,22 @@ void cw1200_tx(struct ieee80211_hw *dev, struct sk_buff *skb) if (cw1200_handle_action_tx(priv, skb)) goto drop; + obtain_lock = (link_id == CW1200_LINK_ID_AFTER_DTIM); + + if (obtain_lock) + spin_lock_bh(&priv->buffered_multicasts_lock); + + if (link_id == CW1200_LINK_ID_AFTER_DTIM && + !priv->buffered_multicasts) { + priv->buffered_multicasts = true; + queue_work(priv->workqueue, + &priv->multicast_start_work); + } ret = cw1200_queue_put(&priv->tx_queue[queue], priv, skb, link_id); + if (obtain_lock) + spin_unlock_bh(&priv->buffered_multicasts_lock); + if (!WARN_ON(ret)) cw1200_bh_wakeup(priv); else @@ -773,16 +789,16 @@ int cw1200_alloc_key(struct cw1200_common *priv) if (idx < 0 || idx > WSM_KEY_MAX_INDEX) return -1; - priv->key_map |= 1 << idx; + priv->key_map |= BIT(idx); priv->keys[idx].entryIndex = idx; return idx; } void cw1200_free_key(struct cw1200_common *priv, int idx) { - BUG_ON(!(priv->key_map & (1 << idx))); + BUG_ON(!(priv->key_map & BIT(idx))); memset(&priv->keys[idx], 0, sizeof(priv->keys[idx])); - priv->key_map &= ~(1 << idx); + priv->key_map &= ~BIT(idx); } void cw1200_free_keys(struct cw1200_common *priv) @@ -795,7 +811,7 @@ int cw1200_upload_keys(struct cw1200_common *priv) { int idx, ret = 0; for (idx = 0; idx <= WSM_KEY_MAX_INDEX; ++idx) - if (priv->key_map & (1 << idx)) { + if (priv->key_map & BIT(idx)) { ret = wsm_add_key(priv, &priv->keys[idx]); if (ret < 0) break; |