aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/txrx.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2009-07-16 14:03:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 15:05:21 -0400
commit46df10ae44b4488176bae16da0b31541eb0f8f48 (patch)
tree0f562347c429808ee8ba0ec151ea77189d5be744 /drivers/net/wireless/p54/txrx.c
parent12f49a79cd32d97a11f864a7b67660438ee3e6c8 (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.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 416400c4ad03..0d589d68e547 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 }