summaryrefslogtreecommitdiff
path: root/drivers/staging/cw1200/sta.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/cw1200/sta.c')
-rw-r--r--drivers/staging/cw1200/sta.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/staging/cw1200/sta.c b/drivers/staging/cw1200/sta.c
index 2ddbc1aa2b0..908294c8a93 100644
--- a/drivers/staging/cw1200/sta.c
+++ b/drivers/staging/cw1200/sta.c
@@ -725,14 +725,19 @@ void cw1200_wep_key_work(struct work_struct *work)
{
struct cw1200_common *priv =
container_of(work, struct cw1200_common, wep_key_work);
+ u8 queueId = cw1200_queue_get_queue_id(priv->pending_frame_id);
+ struct cw1200_queue *queue = &priv->tx_queue[queueId];
__le32 wep_default_key_id = __cpu_to_le32(
priv->wep_default_key_id);
+ BUG_ON(queueId >= 4);
+
sta_printk(KERN_DEBUG "[STA] Setting default WEP key: %d\n",
priv->wep_default_key_id);
wsm_flush_tx(priv);
WARN_ON(wsm_write_mib(priv, WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
&wep_default_key_id, sizeof(wep_default_key_id)));
+ cw1200_queue_requeue(queue, priv->pending_frame_id);
wsm_unlock_tx(priv);
}
@@ -1096,15 +1101,22 @@ void cw1200_offchannel_work(struct work_struct *work)
{
struct cw1200_common *priv =
container_of(work, struct cw1200_common, offchannel_work);
+ u8 queueId = cw1200_queue_get_queue_id(priv->pending_frame_id);
+ struct cw1200_queue *queue = &priv->tx_queue[queueId];
+ BUG_ON(queueId >= 4);
BUG_ON(!priv->channel);
mutex_lock(&priv->conf_mutex);
- if (!priv->join_status) {
+ if (likely(!priv->join_status)) {
wsm_flush_tx(priv);
cw1200_update_listening(priv, true);
cw1200_update_filtering(priv);
}
+ if (unlikely(!priv->join_status))
+ cw1200_queue_remove(queue, priv->pending_frame_id);
+ else
+ cw1200_queue_requeue(queue, priv->pending_frame_id);
mutex_unlock(&priv->conf_mutex);
wsm_unlock_tx(priv);
}
@@ -1113,20 +1125,31 @@ void cw1200_join_work(struct work_struct *work)
{
struct cw1200_common *priv =
container_of(work, struct cw1200_common, join_work);
- const struct wsm_tx *wsm = priv->join_pending_frame;
- const struct ieee80211_hdr *frame = (struct ieee80211_hdr *)&wsm[1];
- const u8 *bssid = &frame->addr1[0]; /* AP SSID in a 802.11 frame */
+ u8 queueId = cw1200_queue_get_queue_id(priv->pending_frame_id);
+ struct cw1200_queue *queue = &priv->tx_queue[queueId];
+ const struct cw1200_txpriv *txpriv = NULL;
+ struct sk_buff *skb = NULL;
+ const struct wsm_tx *wsm;
+ const struct ieee80211_hdr *frame;
+ const u8 *bssid;
struct cfg80211_bss *bss;
const u8 *ssidie;
const u8 *dtimie;
const struct ieee80211_tim_ie *tim = NULL;
- u8 queueId;
+
+ BUG_ON(queueId >= 4);
+ if (cw1200_queue_get_skb(queue, priv->pending_frame_id,
+ &skb, &txpriv)) {
+ wsm_unlock_tx(priv);
+ return;
+ }
+ wsm = (struct wsm_tx *)&skb->data[0];
+ frame = (struct ieee80211_hdr *)&skb->data[txpriv->offset];
+ bssid = &frame->addr1[0]; /* AP SSID in a 802.11 frame */
BUG_ON(!wsm);
BUG_ON(!priv->channel);
- queueId = wsm_queue_id_to_linux(wsm->queueId);
-
if (unlikely(priv->join_status)) {
wsm_lock_tx(priv);
cw1200_unjoin_work(&priv->unjoin_work);
@@ -1134,12 +1157,10 @@ void cw1200_join_work(struct work_struct *work)
cancel_delayed_work_sync(&priv->join_timeout);
- priv->join_pending_frame = NULL;
bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel,
bssid, NULL, 0, 0, 0);
if (!bss) {
- cw1200_queue_remove(&priv->tx_queue[queueId],
- __le32_to_cpu(wsm->packetID));
+ cw1200_queue_remove(queue, priv->pending_frame_id);
wsm_unlock_tx(priv);
return;
}
@@ -1213,16 +1234,14 @@ void cw1200_join_work(struct work_struct *work)
if (wsm_join(priv, &join)) {
memset(&priv->join_bssid[0],
0, sizeof(priv->join_bssid));
- cw1200_queue_remove(&priv->tx_queue[queueId],
- __le32_to_cpu(wsm->packetID));
+ cw1200_queue_remove(queue, priv->pending_frame_id);
cancel_delayed_work_sync(&priv->join_timeout);
cw1200_update_listening(priv, priv->listening);
} else {
/* Upload keys */
WARN_ON(cw1200_upload_keys(priv));
WARN_ON(wsm_keep_alive_period(priv, 30 /* sec */));
- cw1200_queue_requeue(&priv->tx_queue[queueId],
- __le32_to_cpu(wsm->packetID));
+ cw1200_queue_requeue(queue, priv->pending_frame_id);
priv->join_status = CW1200_JOIN_STATUS_STA;
}
WARN_ON(wsm_set_block_ack_policy(priv,