[WCNCR00169319] misc: Refine USB state to control USB WiFi path TX
[Description]
Change USB state to control USB WiFi path transmission
- Add spinlock_t rStateLock and related functions glUsbSetState() and
glUsbSubmitUrb().
- Forbid any TX urb to be submitted when USB WiFi path not allowed.
- Refine spin locks used by USB.
Change-Id: Id7f36f0904d4a344d4c95140ca4ff86cb6171a52
CR-Id: WCNCR00169319
Feature: misc
Signed-off-by: Desmond Lin <desmond.lin@mediatek.com>
Reviewed-on: http://gerrit.mediatek.inc:8080/1241091
CheckPatch: Check Patch <srv_checkpatch@mediatek.com>
Reviewed-by: George Kuo <george.kuo@mediatek.com>
Reviewed-by: ZD Hu <zd.hu@mediatek.com>
Build: srv_neptune_adm <srv_neptune_adm@mediatek.com>
diff --git a/common/wlan_lib.c b/common/wlan_lib.c
index 81cd8a2..661a122 100644
--- a/common/wlan_lib.c
+++ b/common/wlan_lib.c
@@ -824,7 +824,7 @@
fgTimeout = FALSE;
#if defined(_HIF_USB)
- if (prAdapter->prGlueInfo->rHifInfo.state != USB_STATE_LINK_UP)
+ if (prAdapter->prGlueInfo->rHifInfo.state == USB_STATE_LINK_DOWN)
return WLAN_STATUS_FAILURE;
#endif
diff --git a/os/linux/hif/usb/hal_api.c b/os/linux/hif/usb/hal_api.c
index a06b909..f5d31cc 100644
--- a/os/linux/hif/usb/hal_api.c
+++ b/os/linux/hif/usb/hal_api.c
@@ -250,10 +250,6 @@
P_HW_MAC_TX_DESC_T prTxDesc;
UINT_8 ucQueIdx;
- if (prHifInfo->state != USB_STATE_LINK_UP &&
- !(prHifInfo->state == USB_STATE_PRE_RESUME && prCmdInfo->ucCID == 0))
- return WLAN_STATUS_FAILURE;
-
prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxCmdFreeQ, &prHifInfo->rTxCmdQLock);
if (prUsbReq == NULL)
return WLAN_STATUS_RESOURCES;
@@ -301,16 +297,13 @@
prUsbReq->prUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
#endif
spin_lock_irqsave(&prHifInfo->rTxCmdQLock, flags);
- u4Status = usb_submit_urb(prUsbReq->prUrb, GFP_ATOMIC);
+ u4Status = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, SUBMIT_TYPE_TX_CMD);
if (u4Status) {
- DBGLOG(HAL, ERROR, "usb_submit_urb() reports error (%d)\n", u4Status);
- /* glUsbEnqueueReq(prHifInfo, &prHifInfo->rTxCmdFreeQ, &prHifInfo->rTxCmdQLock, prUsbReq); */
+ DBGLOG(HAL, ERROR, "glUsbSubmitUrb() reports error (%d)\n", u4Status);
list_add_tail(&prUsbReq->list, &prHifInfo->rTxCmdFreeQ);
spin_unlock_irqrestore(&prHifInfo->rTxCmdQLock, flags);
return WLAN_STATUS_FAILURE;
}
-
- /* glUsbEnqueueReq(prHifInfo, &prHifInfo->rTxCmdSendingQ, &prHifInfo->rTxCmdQLock, prUsbReq); */
list_add_tail(&prUsbReq->list, &prHifInfo->rTxCmdSendingQ);
spin_unlock_irqrestore(&prHifInfo->rTxCmdQLock, flags);
@@ -427,19 +420,6 @@
memset(prBufCtrl->pucBuf + prBufCtrl->u4WrIdx, 0, LEN_USB_UDMA_TX_TERMINATOR);
prBufCtrl->u4WrIdx += LEN_USB_UDMA_TX_TERMINATOR;
- if (prHifInfo->state != USB_STATE_LINK_UP) {
- list_del_init(&prUsbReq->list);
- list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataCompleteQ);
-
-#if CFG_USB_TX_HANDLE_IN_HIF_THREAD
- kalSetIntEvent(prGlueInfo);
-#else
- /*tasklet_hi_schedule(&prGlueInfo->rTxCompleteTask);*/
- tasklet_schedule(&prGlueInfo->rTxCompleteTask);
-#endif
- return WLAN_STATUS_FAILURE;
- }
-
list_del_init(&prUsbReq->list);
usb_fill_bulk_urb(prUsbReq->prUrb,
@@ -451,13 +431,19 @@
#endif
usb_anchor_urb(prUsbReq->prUrb, &prHifInfo->rTxDataAnchor[ucTc]);
- u4Status = usb_submit_urb(prUsbReq->prUrb, GFP_ATOMIC);
+ u4Status = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, SUBMIT_TYPE_TX_DATA);
if (u4Status) {
- DBGLOG(HAL, ERROR, "usb_submit_urb() reports error (%d) [%s]\n", u4Status, __func__);
+ DBGLOG(HAL, ERROR, "glUsbSubmitUrb() reports error (%d)\n", u4Status);
halTxUSBProcessMsduDone(prHifInfo->prGlueInfo, prUsbReq);
prBufCtrl->u4WrIdx = 0;
usb_unanchor_urb(prUsbReq->prUrb);
- list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataFreeQ[ucTc]);
+ list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataCompleteQ);
+#if CFG_USB_TX_HANDLE_IN_HIF_THREAD
+ kalSetIntEvent(prGlueInfo);
+#else
+ /*tasklet_hi_schedule(&prGlueInfo->rTxCompleteTask);*/
+ tasklet_schedule(&prGlueInfo->rTxCompleteTask);
+#endif
return WLAN_STATUS_FAILURE;
}
@@ -485,11 +471,11 @@
u4Length = skb->len;
ucTc = USB_TRANS_MSDU_TC(prMsduInfo);
#if CFG_USB_TX_AGG
- spin_lock_irqsave(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_lock_irqsave(&prHifInfo->rTxDataQLock, flags);
if (list_empty(&prHifInfo->rTxDataFreeQ[ucTc])) {
if (glUsbBorrowFfaReq(prHifInfo, ucTc) == FALSE) {
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
DBGLOG(HAL, ERROR, "run out of rTxDataFreeQ #1!!\n");
wlanProcessQueuedMsduInfo(prGlueInfo->prAdapter, prMsduInfo);
return WLAN_STATUS_RESOURCES;
@@ -508,7 +494,7 @@
if (list_empty(&prHifInfo->rTxDataFreeQ[ucTc])) {
if (glUsbBorrowFfaReq(prHifInfo, ucTc) == FALSE) {
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
DBGLOG(HAL, ERROR, "run out of rTxDataFreeQ #2!!\n");
wlanProcessQueuedMsduInfo(prGlueInfo->prAdapter, prMsduInfo);
return WLAN_STATUS_FAILURE;
@@ -534,9 +520,9 @@
if (usb_anchor_empty(&prHifInfo->rTxDataAnchor[ucTc]))
halTxUSBSendAggData(prHifInfo, ucTc, prUsbReq);
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
#else
- prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataFreeQ, &prHifInfo->rTxDataFreeQLock);
+ prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataFreeQ, &prHifInfo->rTxDataQLock);
if (prUsbReq == NULL) {
DBGLOG(HAL, ERROR, "run out of rTxDataFreeQ!!\n");
wlanProcessQueuedMsduInfo(prGlueInfo->prAdapter, prMsduInfo);
@@ -572,13 +558,13 @@
#endif
usb_anchor_urb(prUsbReq->prUrb, &prHifInfo->rTxDataAnchor);
- u4Status = usb_submit_urb(prUsbReq->prUrb, GFP_ATOMIC);
+ u4Status = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, SUBMIT_TYPE_TX_DATA);
if (u4Status) {
- DBGLOG(HAL, ERROR, "usb_submit_urb() reports error (%d) [%s]\n", u4Status, __func__);
+ DBGLOG(HAL, ERROR, "glUsbSubmitUrb() reports error (%d)\n", u4Status);
halTxUSBProcessMsduDone(prHifInfo->prGlueInfo, prUsbReq);
prBufCtrl->u4WrIdx = 0;
usb_unanchor_urb(prUsbReq->prUrb);
- glUsbEnqueueReq(prHifInfo, &prHifInfo->rTxDataFreeQ, prUsbReq, &prHifInfo->rTxDataFreeQLock, FALSE);
+ glUsbEnqueueReq(prHifInfo, &prHifInfo->rTxDataFreeQ, prUsbReq, &prHifInfo->rTxDataQLock, FALSE);
return WLAN_STATUS_FAILURE;
}
#endif
@@ -605,7 +591,7 @@
UINT_8 ucTc;
unsigned long flags;
- spin_lock_irqsave(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_lock_irqsave(&prHifInfo->rTxDataQLock, flags);
for (ucTc = TC0_INDEX; ucTc < USB_TC_NUM; ucTc++) {
if (list_empty(&prHifInfo->rTxDataFreeQ[ucTc]))
@@ -618,7 +604,7 @@
halTxUSBSendAggData(prHifInfo, ucTc, prUsbReq);
}
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
#endif
return WLAN_STATUS_SUCCESS;
@@ -681,7 +667,7 @@
halTxUSBProcessMsduDone(prAdapter->prGlueInfo, prUsbReq);
- spin_lock_irqsave(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_lock_irqsave(&prHifInfo->rTxDataQLock, flags);
#if CFG_USB_TX_AGG
prBufCtrl->u4WrIdx = 0;
@@ -700,7 +686,7 @@
#else
list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataFreeQ);
#endif
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
if (!HAL_IS_TX_DIRECT(prAdapter)) {
if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0)
@@ -805,9 +791,6 @@
P_USB_REQ_T prUsbReq;
WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
- if (/*prGlueInfo->ulFlag & GLUE_FLAG_HALT || */prHifInfo->state != USB_STATE_LINK_UP)
- return WLAN_STATUS_FAILURE;
-
while (1) {
prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, &prHifInfo->rRxEventQLock);
if (prUsbReq == NULL)
@@ -829,10 +812,9 @@
(void *)prUsbReq->prBufCtrl->pucBuf, prUsbReq->prBufCtrl->u4BufSize,
halRxUSBReceiveEventComplete, (void *)prUsbReq);
}
- u4Status = usb_submit_urb(prUsbReq->prUrb, GFP_ATOMIC);
-
+ u4Status = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, SUBMIT_TYPE_RX_EVENT);
if (u4Status) {
- DBGLOG(HAL, ERROR, "usb_submit_urb() reports error (%d) [%s]\n", u4Status, __func__);
+ DBGLOG(HAL, ERROR, "glUsbSubmitUrb() reports error (%d)\n", u4Status);
usb_unanchor_urb(prUsbReq->prUrb);
glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, prUsbReq,
&prHifInfo->rRxEventQLock, FALSE);
@@ -849,7 +831,7 @@
P_GL_HIF_INFO_T prHifInfo = prUsbReq->prHifInfo;
P_GLUE_INFO_T prGlueInfo = prHifInfo->prGlueInfo;
- if (/*prGlueInfo->ulFlag & GLUE_FLAG_HALT || */prHifInfo->state != USB_STATE_LINK_UP) {
+ if (prHifInfo->state != USB_STATE_LINK_UP) {
glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, prUsbReq, &prHifInfo->rRxEventQLock, FALSE);
return;
}
@@ -895,9 +877,6 @@
P_USB_REQ_T prUsbReq;
WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
- if (/*prGlueInfo->ulFlag & GLUE_FLAG_HALT || */prHifInfo->state != USB_STATE_LINK_UP)
- return WLAN_STATUS_FAILURE;
-
while (1) {
prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, &prHifInfo->rRxDataQLock);
if (prUsbReq == NULL)
@@ -911,9 +890,9 @@
usb_rcvbulkpipe(prHifInfo->udev, USB_DATA_EP_IN),
(void *)prUsbReq->prBufCtrl->pucBuf,
prUsbReq->prBufCtrl->u4BufSize, halRxUSBReceiveDataComplete, (void *)prUsbReq);
- u4Status = usb_submit_urb(prUsbReq->prUrb, GFP_ATOMIC);
+ u4Status = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, SUBMIT_TYPE_RX_DATA);
if (u4Status) {
- DBGLOG(HAL, ERROR, "usb_submit_urb() reports error (%d) [%s]\n", u4Status, __func__);
+ DBGLOG(HAL, ERROR, "glUsbSubmitUrb() reports error (%d)\n", u4Status);
usb_unanchor_urb(prUsbReq->prUrb);
glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE);
break;
@@ -929,7 +908,7 @@
P_GL_HIF_INFO_T prHifInfo = prUsbReq->prHifInfo;
P_GLUE_INFO_T prGlueInfo = prHifInfo->prGlueInfo;
- if (/*prGlueInfo->ulFlag & GLUE_FLAG_HALT || */prHifInfo->state != USB_STATE_LINK_UP) {
+ if (prHifInfo->state != USB_STATE_LINK_UP) {
glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE);
return;
}
@@ -1206,12 +1185,12 @@
u4Length = skb->len;
ucTc = USB_TRANS_MSDU_TC(prMsduInfo);
- spin_lock_irqsave(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_lock_irqsave(&prHifInfo->rTxDataQLock, flags);
#if CFG_USB_TX_AGG
if (list_empty(&prHifInfo->rTxDataFreeQ[ucTc])) {
if (glUsbBorrowFfaReq(prHifInfo, ucTc) == FALSE) {
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
return FALSE;
}
}
@@ -1225,7 +1204,7 @@
prBufCtrl->u4BufSize - prHifInfo->u4AggRsvSize[ucTc] - LEN_USB_UDMA_TX_TERMINATOR) {
/* Buffer is not enough */
if (glUsbBorrowFfaReq(prHifInfo, ucTc) == FALSE) {
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
return FALSE;
}
}
@@ -1233,13 +1212,13 @@
prHifInfo->u4AggRsvSize[ucTc] += ALIGN_4(u4Length);
#else
if (list_empty(&prHifInfo->rTxDataFreeQ)) {
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
return FALSE;
}
#endif
- spin_unlock_irqrestore(&prHifInfo->rTxDataFreeQLock, flags);
+ spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags);
return TRUE;
}
@@ -1257,10 +1236,10 @@
}
/* Process complete Tx data */
- prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataCompleteQ, &prHifInfo->rTxCmdQLock);
+ prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataCompleteQ, &prHifInfo->rTxDataQLock);
while (prUsbReq) {
halTxUSBProcessDataComplete(prAdapter, prUsbReq);
- prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataCompleteQ, &prHifInfo->rTxCmdQLock);
+ prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataCompleteQ, &prHifInfo->rTxDataQLock);
}
#endif
}
@@ -1414,20 +1393,7 @@
rCmdHifCtrl.ucHifType = ENUM_HIF_TYPE_USB;
rCmdHifCtrl.ucHifDirection = ENUM_HIF_TX;
rCmdHifCtrl.ucHifStop = 1;
-#if 0
- rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */
- CMD_ID_HIF_CTRL, /* ucCID */
- FALSE, /* fgSetQuery */
- TRUE, /* fgNeedResp */
- FALSE, /* fgIsOid */
- usbPreSuspendDone, /* pfCmdDoneHandler */
- usbPreSuspendTimeout, /* pfCmdTimeoutHandler */
- sizeof(CMD_HIF_CTRL_T), /* u4SetQueryInfoLen */
- (PUINT_8)&rCmdHifCtrl, /* pucInfoBuffer */
- NULL, /* pvSetQueryBuffer */
- 0 /* u4SetQueryBufferLen */
- );
-#else
+
rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */
CMD_ID_HIF_CTRL, /* ucCID */
TRUE, /* fgSetQuery */
@@ -1439,24 +1405,45 @@
(PUINT_8)&rCmdHifCtrl, /* pucInfoBuffer */
NULL, /* pvSetQueryBuffer */
0 /* u4SetQueryBufferLen */
- );
-#endif
+ );
ASSERT(rStatus == WLAN_STATUS_PENDING);
}
VOID halUSBPreSuspendDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
{
- ASSERT(prAdapter);
+ unsigned long flags;
+ P_GL_HIF_INFO_T prHifInfo;
- prAdapter->prGlueInfo->rHifInfo.state = USB_STATE_PRE_SUSPEND_DONE;
+ ASSERT(prAdapter);
+ prHifInfo = &prAdapter->prGlueInfo->rHifInfo;
+
+ spin_lock_irqsave(&prHifInfo->rStateLock, flags);
+
+ if (prHifInfo->state == USB_STATE_LINK_UP)
+ prHifInfo->state = USB_STATE_PRE_SUSPEND_DONE;
+ else
+ DBGLOG(HAL, ERROR, "Previous USB state (%d)!\n", prHifInfo->state);
+
+ spin_unlock_irqrestore(&prHifInfo->rStateLock, flags);
}
VOID halUSBPreSuspendTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
{
- ASSERT(prAdapter);
+ unsigned long flags;
+ P_GL_HIF_INFO_T prHifInfo;
- prAdapter->prGlueInfo->rHifInfo.state = USB_STATE_PRE_SUSPEND_FAIL;
+ ASSERT(prAdapter);
+ prHifInfo = &prAdapter->prGlueInfo->rHifInfo;
+
+ spin_lock_irqsave(&prHifInfo->rStateLock, flags);
+
+ if (prHifInfo->state == USB_STATE_LINK_UP)
+ prHifInfo->state = USB_STATE_PRE_SUSPEND_FAIL;
+ else
+ DBGLOG(HAL, ERROR, "Previous USB state (%d)!\n", prHifInfo->state);
+
+ spin_unlock_irqrestore(&prHifInfo->rStateLock, flags);
}
UINT_32 halGetValidCoalescingBufSize(IN P_ADAPTER_T prAdapter)
@@ -1527,7 +1514,7 @@
rStatus = wlanCheckWifiFunc(prAdapter, FALSE);
- prAdapter->prGlueInfo->rHifInfo.state = USB_STATE_WIFI_OFF;
+ glUsbSetState(&prAdapter->prGlueInfo->rHifInfo, USB_STATE_WIFI_OFF);
nicDisableInterrupt(prAdapter);
diff --git a/os/linux/hif/usb/include/hif.h b/os/linux/hif/usb/include/hif.h
index b415885..3e78ad6 100644
--- a/os/linux/hif/usb/include/hif.h
+++ b/os/linux/hif/usb/include/hif.h
@@ -217,6 +217,13 @@
USB_STATE_WIFI_OFF /* Hif power off wifi */
};
+enum usb_submit_type {
+ SUBMIT_TYPE_TX_CMD,
+ SUBMIT_TYPE_TX_DATA,
+ SUBMIT_TYPE_RX_EVENT,
+ SUBMIT_TYPE_RX_DATA
+};
+
typedef enum _EVENT_EP_TYPE {
EVENT_EP_TYPE_UNKONW,
EVENT_EP_TYPE_BULK,
@@ -242,6 +249,7 @@
spinlock_t rTxCmdQLock;
spinlock_t rRxEventQLock;
spinlock_t rRxDataQLock;
+ spinlock_t rStateLock;
PVOID prTxCmdReqHead;
PVOID arTxDataFfaReqHead;
@@ -261,17 +269,17 @@
struct list_head rTxDataFreeQ;
struct usb_anchor rTxDataAnchor;
#endif
- spinlock_t rTxDataFreeQLock;
+ /*spinlock_t rTxDataFreeQLock;*/
struct list_head rRxEventFreeQ;
- spinlock_t rRxEventFreeQLock;
+ /*spinlock_t rRxEventFreeQLock;*/
struct usb_anchor rRxEventAnchor;
struct list_head rRxDataFreeQ;
- spinlock_t rRxDataFreeQLock;
+ /*spinlock_t rRxDataFreeQLock;*/
struct usb_anchor rRxDataAnchor;
struct list_head rRxEventCompleteQ;
- spinlock_t rRxEventCompleteQLock;
+ /*spinlock_t rRxEventCompleteQLock;*/
struct list_head rRxDataCompleteQ;
- spinlock_t rRxDataCompleteQLock;
+ /*spinlock_t rRxDataCompleteQLock;*/
struct list_head rTxCmdCompleteQ;
struct list_head rTxDataCompleteQ;
@@ -362,6 +370,10 @@
P_USB_REQ_T glUsbDequeueReq(P_GL_HIF_INFO_T prHifInfo, struct list_head *prHead, spinlock_t *prLock);
BOOLEAN glUsbBorrowFfaReq(P_GL_HIF_INFO_T prHifInfo, UINT_8 ucTc);
+VOID glUsbSetState(P_GL_HIF_INFO_T prHifInfo, enum usb_state state);
+
+INT_32 glUsbSubmitUrb(P_GL_HIF_INFO_T prHifInfo, struct urb *urb, enum usb_submit_type type);
+
WLAN_STATUS halTxUSBSendCmd(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucTc, IN P_CMD_INFO_T prCmdInfo);
VOID halTxUSBSendCmdComplete(struct urb *urb);
VOID halTxUSBProcessCmdComplete(IN P_ADAPTER_T prAdapter, P_USB_REQ_T prUsbReq);
diff --git a/os/linux/hif/usb/usb.c b/os/linux/hif/usb/usb.c
index fdfa851..9fae786 100644
--- a/os/linux/hif/usb/usb.c
+++ b/os/linux/hif/usb/usb.c
@@ -167,6 +167,14 @@
* F U N C T I O N D E C L A R A T I O N S
********************************************************************************
*/
+static int mtk_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);
+static void mtk_usb_disconnect(struct usb_interface *intf);
+static int mtk_usb_suspend(struct usb_interface *intf, pm_message_t message);
+static int mtk_usb_resume(struct usb_interface *intf);
+static int mtk_usb_reset_resume(struct usb_interface *intf);
+static int mtk_usb_bulk_in_msg(IN P_GL_HIF_INFO_T prHifInfo, IN UINT_32 len, OUT UCHAR * buffer, int InEp);
+static int mtk_usb_intr_in_msg(IN P_GL_HIF_INFO_T prHifInfo, IN UINT_32 len, OUT UCHAR * buffer, int InEp);
+static int mtk_usb_bulk_out_msg(IN P_GL_HIF_INFO_T prHifInfo, IN UINT_32 len, IN UCHAR * buffer, int OutEp);
/*******************************************************************************
* F U N C T I O N S
@@ -227,7 +235,7 @@
ASSERT(intf);
prGlueInfo = (P_GLUE_INFO_T)usb_get_intfdata(intf);
- prGlueInfo->rHifInfo.state = USB_STATE_LINK_DOWN;
+ glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_LINK_DOWN);
if (g_fgDriverProbed)
pfWlanRemove();
@@ -240,7 +248,7 @@
DBGLOG(HAL, STATE, "mtk_usb_disconnect() done\n");
}
-int mtk_usb_suspend(struct usb_interface *intf, pm_message_t message)
+static int mtk_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)usb_get_intfdata(intf);
UINT_8 count = 0;
@@ -262,17 +270,19 @@
count++;
}
- prGlueInfo->rHifInfo.state = USB_STATE_SUSPEND;
+ glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_SUSPEND);
halDisableInterrupt(prGlueInfo->prAdapter);
halTxCancelAllSending(prGlueInfo->prAdapter);
DBGLOG(HAL, STATE, "mtk_usb_suspend() done!\n");
- /* TODO */
+ if (ret && PMSG_IS_AUTO(message))
+ mtk_usb_resume(intf);
+
return ret;
}
-int mtk_usb_resume(struct usb_interface *intf)
+static int mtk_usb_resume(struct usb_interface *intf)
{
int ret = 0;
P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)usb_get_intfdata(intf);
@@ -287,11 +297,11 @@
if (ret)
DBGLOG(HAL, ERROR, "VendorRequest FeatureSetResume ERROR: %x\n", (unsigned int)ret);
- prGlueInfo->rHifInfo.state = USB_STATE_PRE_RESUME;
+ glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_PRE_RESUME);
/* To trigger CR4 path */
wlanSendDummyCmd(prGlueInfo->prAdapter, FALSE);
- prGlueInfo->rHifInfo.state = USB_STATE_LINK_UP;
+ glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_LINK_UP);
halEnableInterrupt(prGlueInfo->prAdapter);
wlanResumePmHandle(prGlueInfo);
@@ -302,7 +312,7 @@
return 0;
}
-int mtk_usb_reset_resume(struct usb_interface *intf)
+static int mtk_usb_reset_resume(struct usb_interface *intf)
{
DBGLOG(HAL, STATE, "mtk_usb_reset_resume()\n");
@@ -347,16 +357,6 @@
return -EFAULT;
}
- /*
- * if (prHifInfo->state != USB_STATE_LINK_UP)
- * return -EFAULT;
- */
-
-#if 0
- if (prGlueInfo->ulFlag & GLUE_FLAG_HALT)
- return FALSE;
-#endif
-
if (unlikely(TransferBufferLength > prHifInfo->vendor_req_buf_sz)) {
DBGLOG(REQ, ERROR, "len %u exceeds limit %zu\n", TransferBufferLength,
prHifInfo->vendor_req_buf_sz);
@@ -399,7 +399,7 @@
/*!
* \brief USB Bulk IN msg
*
-* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
+* \param[in] prHifInfo Pointer to the GL_HIF_INFO_T structure
* \param[in] len
* \param[in] buffer
* \param[in] InEp
@@ -475,7 +475,7 @@
/*!
* \brief USB Bulk OUT msg
*
-* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
+* \param[in] prHifInfo Pointer to the GL_HIF_INFO_T structure
* \param[in] len
* \param[in] buffer
* \param[in] OutEp
@@ -678,7 +678,7 @@
/*!
* \brief This function borrow UsbReq from Tx data FFA queue to the spcified TC Tx data free queue
*
-* \param[in] prGlueInfo Pointer to HIF info structure
+* \param[in] prHifInfo Pointer to the GL_HIF_INFO_T structure
* \param[in] ucTc Specify TC index
*
* \retval TRUE operation success
@@ -702,6 +702,66 @@
/*----------------------------------------------------------------------------*/
/*!
+* \brief This function set USB state
+*
+* \param[in] prHifInfo Pointer to the GL_HIF_INFO_T structure
+* \param[in] state Specify TC index
+*
+* \retval TRUE operation success
+* \retval FALSE operation fail
+*/
+/*----------------------------------------------------------------------------*/
+VOID glUsbSetState(P_GL_HIF_INFO_T prHifInfo, enum usb_state state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&prHifInfo->rStateLock, flags);
+ prHifInfo->state = state;
+ spin_unlock_irqrestore(&prHifInfo->rStateLock, flags);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is a wrapper of submit urb to ensure driver can transmit
+* WiFi packet when WiFi path of device is allowed.
+*
+* \param[in] prHifInfo Pointer to the GL_HIF_INFO_T structure
+* \param[in] type Specify submit type
+*
+* \retval 0 Successful submissions.
+* \retval negative Error number.
+*/
+/*----------------------------------------------------------------------------*/
+INT_32 glUsbSubmitUrb(P_GL_HIF_INFO_T prHifInfo, struct urb *urb, enum usb_submit_type type)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (type == SUBMIT_TYPE_RX_EVENT || type == SUBMIT_TYPE_RX_DATA)
+ return usb_submit_urb(urb, GFP_ATOMIC);
+
+ spin_lock_irqsave(&prHifInfo->rStateLock, flags);
+ if (type == SUBMIT_TYPE_TX_CMD) {
+ if (!(prHifInfo->state == USB_STATE_LINK_UP || prHifInfo->state == USB_STATE_PRE_RESUME)) {
+ spin_unlock_irqrestore(&prHifInfo->rStateLock, flags);
+ DBGLOG(HAL, INFO, "WiFi path is not allowed to transmit CMD packet. (%d)\n", prHifInfo->state);
+ return -ESHUTDOWN;
+ }
+ } else if (type == SUBMIT_TYPE_TX_DATA) {
+ if (prHifInfo->state != USB_STATE_LINK_UP) {
+ spin_unlock_irqrestore(&prHifInfo->rStateLock, flags);
+ DBGLOG(HAL, INFO, "WiFi path is not allowed to transmit DATA packet. (%d)\n", prHifInfo->state);
+ return -ESHUTDOWN;
+ }
+ }
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ spin_unlock_irqrestore(&prHifInfo->rStateLock, flags);
+
+ return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
* \brief This function stores hif related info, which is initialized before.
*
* \param[in] prGlueInfo Pointer to glue info structure
@@ -759,9 +819,9 @@
spin_lock_init(&prHifInfo->rTxCmdQLock);
spin_lock_init(&prHifInfo->rTxDataQLock);
- spin_lock_init(&prHifInfo->rTxDataFreeQLock);
spin_lock_init(&prHifInfo->rRxEventQLock);
spin_lock_init(&prHifInfo->rRxDataQLock);
+ spin_lock_init(&prHifInfo->rStateLock);
mutex_init(&prHifInfo->vendor_req_sem);
prHifInfo->vendor_req_buf = kzalloc(VND_REQ_BUF_SIZE, GFP_KERNEL);
@@ -945,7 +1005,7 @@
glUsbInitQ(prHifInfo, &prHifInfo->rRxEventCompleteQ, 0);
glUsbInitQ(prHifInfo, &prHifInfo->rRxDataCompleteQ, 0);
- prHifInfo->state = USB_STATE_LINK_UP;
+ glUsbSetState(prHifInfo, USB_STATE_LINK_UP);
return;