summaryrefslogtreecommitdiff
path: root/drivers/staging/cw1200/wsm.c
diff options
context:
space:
mode:
authorDmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>2011-10-10 23:20:13 +0200
committerPhilippe LANGLAIS <philippe.langlais@stericsson.com>2011-10-13 10:25:09 +0200
commit7a2de54ab4a67e97bc1a4fac9b84eb6c307f9488 (patch)
tree1001141bce26ea659b625841c687823b9d53a1a7 /drivers/staging/cw1200/wsm.c
parent98a9d7c86ef2ff6df10008dbb93a8139a79a9f33 (diff)
cw1200: Requeue special frames.
Some frames require special handling in wsm, for example offchannel, wep, join... Requeue for offchannel and wep frames was missing, leading to queue entry leakage and unexpected drop of frames. Fix implements requeue for special frames. Change-Id: Iba5c41496f898e30b4261db3888bba384504df50 Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33596 Reviewed-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com> Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Diffstat (limited to 'drivers/staging/cw1200/wsm.c')
-rw-r--r--drivers/staging/cw1200/wsm.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/staging/cw1200/wsm.c b/drivers/staging/cw1200/wsm.c
index 19f87bed526..10303fae3c8 100644
--- a/drivers/staging/cw1200/wsm.c
+++ b/drivers/staging/cw1200/wsm.c
@@ -1313,6 +1313,7 @@ out:
static bool wsm_handle_tx_data(struct cw1200_common *priv,
const struct wsm_tx *wsm,
const struct ieee80211_tx_info *tx_info,
+ struct cw1200_queue *queue,
int link_id)
{
bool handled = false;
@@ -1395,24 +1396,24 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
switch (action) {
case doProbe:
{
+ const struct cw1200_txpriv *txpriv;
/* An interesting FW "feature". Device filters
* probe responses.
* The easiest way to get it back is to convert
* probe request into WSM start_scan command. */
- struct cw1200_queue *queue =
- &priv->tx_queue[cw1200_queue_get_queue_id(
- wsm->packetID)];
wsm_printk(KERN_DEBUG \
"[WSM] Convert probe request to scan.\n");
wsm_lock_tx_async(priv);
BUG_ON(priv->scan.probe_skb);
BUG_ON(cw1200_queue_get_skb(queue,
wsm->packetID,
- &priv->scan.probe_skb));
+ &priv->scan.probe_skb,
+ &txpriv));
skb_get(priv->scan.probe_skb);
IEEE80211_SKB_CB(priv->scan.probe_skb)->flags |=
IEEE80211_TX_STAT_ACK;
- BUG_ON(cw1200_queue_remove(queue, wsm->packetID));
+ BUG_ON(cw1200_queue_remove(queue,
+ __le32_to_cpu(wsm->packetID)));
/* Release used TX rate policy */
queue_delayed_work(priv->workqueue,
&priv->scan.probe_work, 0);
@@ -1423,11 +1424,9 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
{
/* See detailed description of "join" below.
* We are dropping everything except AUTH in non-joined mode. */
- struct cw1200_queue *queue =
- &priv->tx_queue[cw1200_queue_get_queue_id(
- wsm->packetID)];
wsm_printk(KERN_DEBUG "[WSM] Drop frame (0x%.4X).\n", fctl);
- BUG_ON(cw1200_queue_remove(queue, wsm->packetID));
+ BUG_ON(cw1200_queue_remove(queue,
+ __le32_to_cpu(wsm->packetID)));
handled = true;
}
break;
@@ -1441,8 +1440,7 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
* not require protection */
wsm_printk(KERN_DEBUG "[WSM] Issue join command.\n");
wsm_lock_tx_async(priv);
- BUG_ON(priv->join_pending_frame);
- priv->join_pending_frame = wsm;
+ priv->pending_frame_id = __le32_to_cpu(wsm->packetID);
if (queue_work(priv->workqueue, &priv->join_work) <= 0)
wsm_unlock_tx(priv);
handled = true;
@@ -1452,6 +1450,7 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
{
wsm_printk(KERN_DEBUG "[WSM] Offchannel TX request.\n");
wsm_lock_tx_async(priv);
+ priv->pending_frame_id = __le32_to_cpu(wsm->packetID);
if (queue_work(priv->workqueue, &priv->offchannel_work) <= 0)
wsm_unlock_tx(priv);
handled = true;
@@ -1462,6 +1461,7 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
wsm_printk(KERN_DEBUG "[WSM] Issue set_default_wep_key.\n");
wsm_lock_tx_async(priv);
priv->wep_default_key_id = tx_info->control.hw_key->keyidx;
+ priv->pending_frame_id = __le32_to_cpu(wsm->packetID);
if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0)
wsm_unlock_tx(priv);
handled = true;
@@ -1619,7 +1619,8 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data,
continue;
if (wsm_handle_tx_data(priv, wsm,
- tx_info, txpriv->raw_link_id))
+ tx_info, queue,
+ txpriv->raw_link_id))
continue; /* Handled by WSM */
wsm->hdr.id &= __cpu_to_le16(