aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/main.c25
-rw-r--r--drivers/net/wireless/libertas/tx.c9
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);
233done: 231done:
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);