diff options
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r-- | drivers/net/wireless/libertas/dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/tx.c | 9 |
3 files changed, 25 insertions, 10 deletions
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 5cb29235fee3..eaa45d4bb9d2 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -285,7 +285,6 @@ struct lbs_adapter { | |||
285 | 285 | ||
286 | /** Tx-related variables (for single packet tx) */ | 286 | /** Tx-related variables (for single packet tx) */ |
287 | struct sk_buff *currenttxskb; | 287 | struct sk_buff *currenttxskb; |
288 | u16 TxLockFlag; | ||
289 | 288 | ||
290 | /** NIC Operation characteristics */ | 289 | /** NIC Operation characteristics */ |
291 | u16 currentpacketfilter; | 290 | u16 currentpacketfilter; |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index d03a2f8710fb..7155f4818167 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -290,8 +290,14 @@ static ssize_t lbs_rtap_set(struct device *dev, | |||
290 | return strlen(buf); | 290 | return strlen(buf); |
291 | adapter->monitormode = LBS_MONITOR_OFF; | 291 | adapter->monitormode = LBS_MONITOR_OFF; |
292 | lbs_remove_rtap(priv); | 292 | lbs_remove_rtap(priv); |
293 | netif_wake_queue(priv->dev); | 293 | |
294 | netif_wake_queue(priv->mesh_dev); | 294 | if (adapter->currenttxskb) { |
295 | dev_kfree_skb_any(adapter->currenttxskb); | ||
296 | adapter->currenttxskb = NULL; | ||
297 | } | ||
298 | |||
299 | /* Wake queues, command thread, etc. */ | ||
300 | lbs_host_to_card_done(priv); | ||
295 | } | 301 | } |
296 | 302 | ||
297 | lbs_prepare_and_send_command(priv, | 303 | lbs_prepare_and_send_command(priv, |
@@ -521,7 +527,15 @@ static int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
521 | 527 | ||
522 | lbs_deb_enter(LBS_DEB_TX); | 528 | lbs_deb_enter(LBS_DEB_TX); |
523 | 529 | ||
524 | if (priv->dnld_sent || priv->adapter->TxLockFlag) { | 530 | /* We could return NETDEV_TX_BUSY here, but I'd actually |
531 | like to get the point where we can BUG() */ | ||
532 | if (priv->dnld_sent) { | ||
533 | lbs_pr_err("%s while dnld_sent\n", __func__); | ||
534 | priv->stats.tx_dropped++; | ||
535 | goto done; | ||
536 | } | ||
537 | if (priv->adapter->currenttxskb) { | ||
538 | lbs_pr_err("%s while TX skb pending\n", __func__); | ||
525 | priv->stats.tx_dropped++; | 539 | priv->stats.tx_dropped++; |
526 | goto done; | 540 | goto done; |
527 | } | 541 | } |
@@ -624,6 +638,11 @@ void lbs_host_to_card_done(struct lbs_private *priv) | |||
624 | if (!adapter->cur_cmd) | 638 | if (!adapter->cur_cmd) |
625 | wake_up_interruptible(&priv->waitq); | 639 | wake_up_interruptible(&priv->waitq); |
626 | 640 | ||
641 | /* Don't wake netif queues if we're in monitor mode and | ||
642 | a TX packet is already pending. */ | ||
643 | if (priv->adapter->currenttxskb) | ||
644 | return; | ||
645 | |||
627 | if (priv->dev && adapter->connect_status == LBS_CONNECTED) | 646 | if (priv->dev && adapter->connect_status == LBS_CONNECTED) |
628 | netif_wake_queue(priv->dev); | 647 | netif_wake_queue(priv->dev); |
629 | 648 | ||
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index b423ce1ff42b..131ef3fe0337 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c | |||
@@ -152,11 +152,11 @@ done: | |||
152 | netif_stop_queue(priv->dev); | 152 | netif_stop_queue(priv->dev); |
153 | if (priv->mesh_dev) | 153 | if (priv->mesh_dev) |
154 | netif_stop_queue(priv->mesh_dev); | 154 | netif_stop_queue(priv->mesh_dev); |
155 | /* freeze any packets already in our queues */ | 155 | |
156 | priv->adapter->TxLockFlag = 1; | 156 | /* Keep the skb around for when we get feedback */ |
157 | priv->adapter->currenttxskb = skb; | ||
157 | } else { | 158 | } else { |
158 | dev_kfree_skb_any(skb); | 159 | dev_kfree_skb_any(skb); |
159 | priv->adapter->currenttxskb = NULL; | ||
160 | } | 160 | } |
161 | 161 | ||
162 | lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); | 162 | lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); |
@@ -227,8 +227,6 @@ int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb) | |||
227 | return ret; | 227 | return ret; |
228 | } | 228 | } |
229 | 229 | ||
230 | priv->adapter->currenttxskb = skb; | ||
231 | |||
232 | ret = SendSinglePacket(priv, skb); | 230 | ret = SendSinglePacket(priv, skb); |
233 | done: | 231 | done: |
234 | lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); | 232 | lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); |
@@ -272,7 +270,6 @@ void lbs_send_tx_feedback(struct lbs_private *priv) | |||
272 | (1 + adapter->txretrycount - try_count) : 0; | 270 | (1 + adapter->txretrycount - try_count) : 0; |
273 | lbs_upload_rx_packet(priv, adapter->currenttxskb); | 271 | lbs_upload_rx_packet(priv, adapter->currenttxskb); |
274 | adapter->currenttxskb = NULL; | 272 | adapter->currenttxskb = NULL; |
275 | priv->adapter->TxLockFlag = 0; | ||
276 | 273 | ||
277 | if (adapter->connect_status == LBS_CONNECTED) | 274 | if (adapter->connect_status == LBS_CONNECTED) |
278 | netif_wake_queue(priv->dev); | 275 | netif_wake_queue(priv->dev); |