diff -urN a/ar6000/ar6000/ar6000_drv.c b/ar6000/ar6000/ar6000_drv.c
--- a/ar6000/ar6000/ar6000_drv.c	2009-03-25 00:23:38.000000000 +0300
+++ b/ar6000/ar6000/ar6000_drv.c	2009-03-27 13:45:54.000000000 +0300
@@ -238,6 +238,8 @@
 
 static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint);
 
+static void ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint);
+
 /*
  * Static variables
  */
@@ -1149,7 +1151,7 @@
 ar6000_open(struct net_device *dev)
 {
     /* Wake up the queues */
-    netif_wake_queue(dev);
+    netif_start_queue(dev);
 
     return 0;
 }
@@ -1278,6 +1280,7 @@
         connect.EpCallbacks.EpRecv = ar6000_rx;
         connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
         connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
+        connect.EpCallbacks.EpSendAvail = ar6000_tx_queue_avail;
             /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
              * Linux has the peculiarity of not providing flow control between the
              * NIC and the network stack. There is no API to indicate that a TX packet
@@ -1755,8 +1758,7 @@
 
 static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint)
 {
-    AR_SOFTC_T     *ar = (AR_SOFTC_T *)Context;
-
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
 
     if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) {
         if (!bypasswmi) {
@@ -1771,19 +1773,27 @@
             AR_DEBUG_PRINTF("WMI Control Endpoint is FULL!!! \n");
         }
     } else {
-
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-        ar->arNetQueueStopped = TRUE;
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
         /* one of the data endpoints queues is getting full..need to stop network stack
-         * the queue will resume in ar6000_tx_complete() */
-        netif_stop_queue(ar->arNetDev);
+         * the queue will resume after credits received */
+        netif_stop_queue (ar->arNetDev);
     }
+}
 
+static void ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
 
+    if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) {
+        /* FIXME: what do for it?  */
+    } else {
+            /* Wake up interface, rescheduling prevented.  */
+        if (((ar->arConnected == TRUE) || (bypasswmi))
+         && netif_queue_stopped (ar->arNetDev)) {
+            netif_wake_queue (ar->arNetDev);
+        }
+    }
 }
 
-
 static void
 ar6000_tx_complete(void *Context, HTC_PACKET *pPacket)
 {
@@ -1877,10 +1887,6 @@
         ar6000_free_cookie(ar, cookie);
     }
 
-    if (ar->arNetQueueStopped) {
-        ar->arNetQueueStopped = FALSE;
-    }
-
     AR6000_SPIN_UNLOCK(&ar->arLock, 0);
 
     /* lock is released, we can freely call other kernel APIs */
@@ -1888,18 +1894,9 @@
         /* this indirectly frees the HTC_PACKET */
     A_NETBUF_FREE(skb);
 
-    if ((ar->arConnected == TRUE) || (bypasswmi)) {
-        if (status != A_ECANCELED) {
-                /* don't wake the queue if we are flushing, other wise it will just
-                 * keep queueing packets, which will keep failing */
-            netif_wake_queue(ar->arNetDev);
-        }
-    }
-
     if (wakeEvent) {
         wake_up(&arEvent);
     }
-
 }
 
 /*
@@ -2317,7 +2314,7 @@
         /* flush data queues */
     ar6000_TxDataCleanup(ar);
 
-    netif_wake_queue(ar->arNetDev);
+    netif_start_queue(ar->arNetDev);
 
     if ((OPEN_AUTH == ar->arDot11AuthMode) &&
         (NONE_AUTH == ar->arAuthMode)      &&
diff -urN a/ar6000/ar6000/ar6000_drv.h b/ar6000/ar6000/ar6000_drv.h
--- a/ar6000/ar6000/ar6000_drv.h	2009-03-25 00:23:38.000000000 +0300
+++ b/ar6000/ar6000/ar6000_drv.h	2009-03-27 02:27:25.000000000 +0300
@@ -273,7 +273,6 @@
     A_BOOL                  write_buffer_available[HTC_RAW_STREAM_NUM_MAX];
     A_BOOL                  read_buffer_available[HTC_RAW_STREAM_NUM_MAX];
 #endif
-    A_BOOL                  arNetQueueStopped;
     A_BOOL                  arRawIfInit;
     int                     arDeviceIndex;
     COMMON_CREDIT_STATE_INFO arCreditStateInfo;
diff -urN a/ar6000/ar6000/ar6000_raw_if.c b/ar6000/ar6000/ar6000_raw_if.c
--- a/ar6000/ar6000/ar6000_raw_if.c	2009-03-25 00:23:38.000000000 +0300
+++ b/ar6000/ar6000/ar6000_raw_if.c	2009-03-26 21:44:24.000000000 +0300
@@ -127,6 +127,7 @@
             /* simple interface, we don't need these optional callbacks */
         connect.EpCallbacks.EpRecvRefill = NULL;
         connect.EpCallbacks.EpSendFull = NULL;
+        connect.EpCallbacks.EpSendAvail = NULL;
         connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;
 
             /* connect to the raw streams service, we may be able to get 1 or more
diff -urN a/ar6000/htc/htc.c b/ar6000/htc/htc.c
--- a/ar6000/htc/htc.c	2009-03-25 00:23:38.000000000 +0300
+++ b/ar6000/htc/htc.c	2009-03-26 21:45:48.000000000 +0300
@@ -284,6 +284,7 @@
         connect.EpCallbacks.EpRecv = HTCControlRecv;
         connect.EpCallbacks.EpRecvRefill = NULL;  /* not needed */
         connect.EpCallbacks.EpSendFull = NULL;    /* not nedded */
+        connect.EpCallbacks.EpSendAvail = NULL;    /* not nedded */
         connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS;
         connect.ServiceID = HTC_CTRL_RSVD_SVC;
 
diff -urN a/ar6000/htc/htc_send.c b/ar6000/htc/htc_send.c
--- a/ar6000/htc/htc_send.c	2009-03-25 00:23:38.000000000 +0300
+++ b/ar6000/htc/htc_send.c	2009-03-27 02:19:55.000000000 +0300
@@ -101,23 +101,22 @@
 }
 
 /* try to send the current packet or a packet at the head of the TX queue,
- * if there are no credits, the packet remains in the queue.
- * this function always succeeds and returns a flag if the TX queue for
- * the endpoint has hit the set limit */
-static A_BOOL HTCTrySend(HTC_TARGET   *target,
-                         HTC_ENDPOINT *pEndpoint,
-                         HTC_PACKET   *pPacketToSend)
+ * if there are no credits, the packet remains in the queue. */
+static void HTCTrySend(HTC_TARGET      *target,
+                       HTC_PACKET      *pPacketToSend,
+                       HTC_ENDPOINT_ID ep)
 {
-    HTC_PACKET  *pPacket;
-    int         creditsRequired;
-    int         remainder;
-    A_UINT8     sendFlags;
-    A_BOOL      epFull = FALSE;
-
-    LOCK_HTC_TX(target);
+    HTC_PACKET   *pPacket;
+    HTC_ENDPOINT *pEndpoint;
+    int          creditsRequired;
+    A_UINT8      sendFlags;
 
     AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (pPkt:0x%X)\n",(A_UINT32)pPacketToSend));
 
+    pEndpoint = &target->EndPoint[ep];
+
+    LOCK_HTC_TX(target);
+
     if (pPacketToSend != NULL) {
         /* caller supplied us a packet to queue to the tail of the HTC TX queue before
          * we check the tx queue */
@@ -143,12 +142,9 @@
                 (A_UINT32)pPacket, pEndpoint->CurrentTxQueueDepth));
 
             /* figure out how many credits this message requires */
-        creditsRequired = (pPacket->ActualLength + HTC_HDR_LENGTH) / target->TargetCreditSize;
-        remainder = (pPacket->ActualLength + HTC_HDR_LENGTH) % target->TargetCreditSize;
-
-        if (remainder) {
-            creditsRequired++;
-        }
+        creditsRequired  = pPacket->ActualLength + HTC_HDR_LENGTH;
+        creditsRequired += target->TargetCreditSize - 1;
+        creditsRequired /= target->TargetCreditSize;
 
         AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d   Got:%d\n",
                             creditsRequired, pEndpoint->CreditDist.TxCredits));
@@ -207,19 +203,27 @@
         HTCIssueSend(target, pPacket, sendFlags);
 
         LOCK_HTC_TX(target);
-
         /* go back and check for more messages */
     }
 
     if (pEndpoint->CurrentTxQueueDepth >= pEndpoint->MaxTxQueueDepth) {
-            /* let caller know that this endpoint has reached the maximum depth */
-        epFull = TRUE;
+        AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d, TX queue is full, Depth:%d, Max:%d \n",
+                        ep, pEndpoint->CurrentTxQueueDepth, pEndpoint->MaxTxQueueDepth));
+        UNLOCK_HTC_TX(target);
+            /* queue is now full, let caller know */
+        if (pEndpoint->EpCallBacks.EpSendFull != NULL) {
+            AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Calling driver's send full callback.... \n"));
+            pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext, ep);
+        }
+    } else {
+        UNLOCK_HTC_TX(target);
+            /* queue is now available for new packet, let caller know */
+        if (pEndpoint->EpCallBacks.EpSendAvail) {
+            pEndpoint->EpCallBacks.EpSendAvail(pEndpoint->EpCallBacks.pContext, ep);
+        }
     }
 
-    UNLOCK_HTC_TX(target);
-
     AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend:  \n"));
-    return epFull;
 }
 
 /* HTC API - HTCSendPkt */
@@ -251,20 +255,12 @@
         pPacket->Completion = HTCSendPktCompletionHandler;
         pPacket->pContext = target;
 
-        if (HTCTrySend(target, pEndpoint, pPacket)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d, TX queue is full, Depth:%d, Max:%d \n",
-                    ep, pEndpoint->CurrentTxQueueDepth, pEndpoint->MaxTxQueueDepth));
-                /* queue is now full, let caller know */
-            if (pEndpoint->EpCallBacks.EpSendFull != NULL) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Calling driver's send full callback.... \n"));
-                pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext,
-                                                  ep);
-            }
-        }
+        HTCTrySend(target, pPacket, ep);
 
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPkt \n"));
     } while (FALSE);
 
+    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPkt \n"));
+
     return status;
 }
 
@@ -292,7 +288,7 @@
                  * Highest priority queue get's processed first, if there are credits available the
                  * highest priority queue will get a chance to reclaim credits from lower priority
                  * ones */
-            HTCTrySend(target, pEndpoint, NULL);
+            HTCTrySend(target, NULL, pDistItem->Endpoint);
         }
 
         pDistItem = pDistItem->pNext;
@@ -480,7 +476,6 @@
         HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL);
     }
 
-
 }
 
 /* HTC API to flush an endpoint's TX queue*/
diff -urN a/ar6000/include/htc_api.h b/ar6000/include/htc_api.h
--- a/ar6000/include/htc_api.h	2009-03-25 00:23:38.000000000 +0300
+++ b/ar6000/include/htc_api.h	2009-03-27 02:11:15.000000000 +0300
@@ -86,6 +86,8 @@
  * Other OSes require a "per-packet" indication_RAW_STREAM_NUM_MAX for each completed TX packet, this
  * closed loop mechanism will prevent the network stack from overunning the NIC */
 typedef void (*HTC_EP_SEND_QUEUE_FULL)(void *, HTC_ENDPOINT_ID Endpoint);
+/* Optional per service connection callback when a send queue is available for receive new packet. */
+typedef void (*HTC_EP_SEND_QUEUE_AVAIL)(void *, HTC_ENDPOINT_ID Endpoint);
 
 typedef struct _HTC_EP_CALLBACKS {
     void                     *pContext;     /* context for each callback */
@@ -93,6 +95,7 @@
     HTC_EP_RECV_PKT          EpRecv;        /* receive callback for connected endpoint */
     HTC_EP_RECV_REFILL       EpRecvRefill;  /* OPTIONAL receive re-fill callback for connected endpoint */
     HTC_EP_SEND_QUEUE_FULL   EpSendFull;    /* OPTIONAL send full callback */
+    HTC_EP_SEND_QUEUE_AVAIL  EpSendAvail;    /* OPTIONAL send available callback */
 } HTC_EP_CALLBACKS;
 
 /* service connection information */
