diff options
author | Christian Lamparter <chunkeey@web.de> | 2009-07-16 14:03:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-24 15:05:21 -0400 |
commit | 46df10ae44b4488176bae16da0b31541eb0f8f48 (patch) | |
tree | 0f562347c429808ee8ba0ec151ea77189d5be744 /drivers/net/wireless/p54/txrx.c | |
parent | 12f49a79cd32d97a11f864a7b67660438ee3e6c8 (diff) |
p54: fix beaconing related firmware crash
This patch fixes a firmware crash which can be provoked by changing
operation mode.
Acked-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Christian Lamparter <chunkeey@web.de>
Tested-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54/txrx.c')
-rw-r--r-- | drivers/net/wireless/p54/txrx.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 416400c4ad0..0d589d68e54 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -134,9 +134,13 @@ static int p54_assign_address(struct p54_common *priv, struct sk_buff *skb) | |||
134 | range = (void *) info->rate_driver_data; | 134 | range = (void *) info->rate_driver_data; |
135 | range->start_addr = target_addr; | 135 | range->start_addr = target_addr; |
136 | range->end_addr = target_addr + len; | 136 | range->end_addr = target_addr + len; |
137 | data->req_id = cpu_to_le32(target_addr + priv->headroom); | ||
138 | if (IS_DATA_FRAME(skb) && | ||
139 | unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON)) | ||
140 | priv->beacon_req_id = data->req_id; | ||
141 | |||
137 | __skb_queue_after(&priv->tx_queue, target_skb, skb); | 142 | __skb_queue_after(&priv->tx_queue, target_skb, skb); |
138 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | 143 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
139 | data->req_id = cpu_to_le32(target_addr + priv->headroom); | ||
140 | return 0; | 144 | return 0; |
141 | } | 145 | } |
142 | 146 | ||
@@ -209,13 +213,19 @@ static void p54_tx_qos_accounting_free(struct p54_common *priv, | |||
209 | struct sk_buff *skb) | 213 | struct sk_buff *skb) |
210 | { | 214 | { |
211 | if (IS_DATA_FRAME(skb)) { | 215 | if (IS_DATA_FRAME(skb)) { |
212 | struct p54_hdr *hdr = (void *) skb->data; | ||
213 | struct p54_tx_data *data = (void *) hdr->data; | ||
214 | unsigned long flags; | 216 | unsigned long flags; |
215 | 217 | ||
216 | spin_lock_irqsave(&priv->tx_stats_lock, flags); | 218 | spin_lock_irqsave(&priv->tx_stats_lock, flags); |
217 | priv->tx_stats[data->hw_queue].len--; | 219 | priv->tx_stats[GET_HW_QUEUE(skb)].len--; |
218 | spin_unlock_irqrestore(&priv->tx_stats_lock, flags); | 220 | spin_unlock_irqrestore(&priv->tx_stats_lock, flags); |
221 | |||
222 | if (unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON)) { | ||
223 | if (priv->beacon_req_id == GET_REQ_ID(skb)) { | ||
224 | /* this is the active beacon set anymore */ | ||
225 | priv->beacon_req_id = 0; | ||
226 | } | ||
227 | complete(&priv->beacon_comp); | ||
228 | } | ||
219 | } | 229 | } |
220 | p54_wake_queues(priv); | 230 | p54_wake_queues(priv); |
221 | } | 231 | } |
@@ -403,10 +413,6 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb) | |||
403 | * and we don't want to confuse the mac80211 stack. | 413 | * and we don't want to confuse the mac80211 stack. |
404 | */ | 414 | */ |
405 | if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) { | 415 | if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) { |
406 | if (entry_data->hw_queue == P54_QUEUE_BEACON && | ||
407 | hdr->req_id == priv->beacon_req_id) | ||
408 | priv->beacon_req_id = cpu_to_le32(0); | ||
409 | |||
410 | dev_kfree_skb_any(entry); | 416 | dev_kfree_skb_any(entry); |
411 | return ; | 417 | return ; |
412 | } | 418 | } |