/* ======================================================================== Routine Description: MLME kernel thread. Arguments: *Context the pAd, driver control block pointer Return Value: 0 close the thread Note: ======================================================================== */ INT MlmeThread( IN ULONG Context) { RTMP_ADAPTER *pAd; RTMP_OS_TASK *pTask; int status; status = 0; pTask = (RTMP_OS_TASK *)Context; pAd = (PRTMP_ADAPTER)pTask->priv; RtmpOSTaskCustomize(pTask); while(!pTask->task_killed) { #ifdef KTHREAD_SUPPORT RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); #else RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); /* unlock the device pointers */ if (status != 0) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } #endif /* lock the device pointers , need to check if required*/ //down(&(pAd->usbdev_semaphore)); if (!pAd->PM_FlgSuspend) MlmeHandler(pAd); } /* notify the exit routine that we're actually exiting now * * complete()/wait_for_completion() is similar to up()/down(), * except that complete() is safe in the case where the structure * is getting deleted in a parallel mode of execution (i.e. just * after the down() -- that's necessary for the thread-shutdown * case. * * complete_and_exit() goes even further than this -- it is safe in * the case that the thread of the caller is going away (not just * the structure) -- this is necessary for the module-remove case. * This is important in preemption kernels, which transfer the flow * of execution immediately upon a complete(). */ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__)); #ifndef KTHREAD_SUPPORT pTask->taskPID = THREAD_PID_INIT_VALUE; complete_and_exit (&pTask->taskComplete, 0); #endif return 0; }
/* ======================================================================== Routine Description: Read 8-bit BBP register via firmware Arguments: Return Value: IRQL = Note: ======================================================================== */ NTSTATUS RTUSBReadBBPRegister( IN PRTMP_ADAPTER pAd, IN UCHAR Id, IN PUCHAR pValue) { BBP_CSR_CFG_STRUC BbpCsr; int i, k, ret; RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret); if (ret != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret)); return STATUS_UNSUCCESSFUL; } for (i=0; i<MAX_BUSY_COUNT; i++) { RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word); if (BbpCsr.field.Busy == BUSY) continue; BbpCsr.word = 0; BbpCsr.field.fRead = 1; BbpCsr.field.BBP_RW_MODE = 1; BbpCsr.field.Busy = 1; BbpCsr.field.RegNum = Id; RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word, FALSE); AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0, TRUE); for (k=0; k<MAX_BUSY_COUNT; k++) { RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word); if (BbpCsr.field.Busy == IDLE) break; } if ((BbpCsr.field.Busy == IDLE) && (BbpCsr.field.RegNum == Id)) { *pValue = (UCHAR)BbpCsr.field.Value; break; } } RTMP_SEM_EVENT_UP(&pAd->reg_atomic); if (BbpCsr.field.Busy == BUSY) { DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word)); *pValue = pAd->BbpWriteLatch[Id]; return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; }
/* ======================================================================== Routine Description: Write 8-bit BBP register Arguments: Return Value: IRQL = Note: ======================================================================== */ NTSTATUS RTUSBWriteBBPRegister( IN PRTMP_ADAPTER pAd, IN UCHAR Id, IN UCHAR Value) { BBP_CSR_CFG_STRUC BbpCsr; UINT i = 0; NTSTATUS status; int RET = 0; RTMP_SEM_EVENT_WAIT(&(pAd->UsbVendorReq_semaphore2), RET); /* Verify the busy condition*/ do { status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); if (status >= 0) { if (!(BbpCsr.field.Busy == BUSY)) break; } DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i)); i++; } while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2)); return STATUS_UNSUCCESSFUL; } /* Prepare for write material*/ BbpCsr.word = 0; BbpCsr.field.fRead = 0; BbpCsr.field.Value = Value; BbpCsr.field.Busy = 1; BbpCsr.field.RegNum = Id; RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word); pAd->BbpWriteLatch[Id] = Value; RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2)); return STATUS_SUCCESS; }
/* ======================================================================== Routine Description: Write RF register through MAC Arguments: Return Value: IRQL = Note: ======================================================================== */ NTSTATUS RTUSBWriteRFRegister( IN PRTMP_ADAPTER pAd, IN UINT32 Value) { PHY_CSR4_STRUC PhyCsr4; UINT i = 0; NTSTATUS status; NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC)); RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, status); if (status != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", status)); return STATUS_UNSUCCESSFUL; } status = STATUS_UNSUCCESSFUL; do { status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word); if (status >= 0) { if (!(PhyCsr4.field.Busy)) break; } DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i)); i++; } while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); goto done; } RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value, FALSE); status = STATUS_SUCCESS; done: RTMP_SEM_EVENT_UP(&pAd->reg_atomic); return status; }
NTSTATUS RTUSBWriteBBPRegister( IN PRTMP_ADAPTER pAd, IN UCHAR Id, IN UCHAR Value) { BBP_CSR_CFG_STRUC BbpCsr; int BusyCnt; int ret; RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret); if (ret != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret)); return STATUS_UNSUCCESSFUL; } for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) { RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word); if (BbpCsr.field.Busy == BUSY) continue; BbpCsr.word = 0; BbpCsr.field.fRead = 0; BbpCsr.field.BBP_RW_MODE = 1; BbpCsr.field.Busy = 1; BbpCsr.field.Value = Value; BbpCsr.field.RegNum = Id; RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word); AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0, TRUE); pAd->BbpWriteLatch[Id] = Value; break; } RTMP_SEM_EVENT_UP(&pAd->reg_atomic); if (BusyCnt == MAX_BUSY_COUNT) { DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word)); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; }
static void RtmpTimerQHandle(RTMP_ADAPTER *pAd) { #ifndef KTHREAD_SUPPORT int status; #endif RALINK_TIMER_STRUCT *pTimer; RTMP_TIMER_TASK_ENTRY *pEntry; unsigned long irqFlag; RTMP_OS_TASK *pTask; pTask = &pAd->timerTask; while(!pTask->task_killed) { pTimer = NULL; #ifdef KTHREAD_SUPPORT RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); #else RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); #endif if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED) break; // event happened. while(pAd->TimerQ.pQHead) { RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag); pEntry = pAd->TimerQ.pQHead; if (pEntry) { pTimer = pEntry->pRaTimer; // update pQHead pAd->TimerQ.pQHead = pEntry->pNext; if (pEntry == pAd->TimerQ.pQTail) pAd->TimerQ.pQTail = NULL; // return this queue entry to timerQFreeList. pEntry->pNext = pAd->TimerQ.pQPollFreeList; pAd->TimerQ.pQPollFreeList = pEntry; } RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag); if (pTimer) { if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend)) pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer); if ((pTimer->Repeat) && (pTimer->State == FALSE)) RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); } } #ifndef KTHREAD_SUPPORT if (status != 0) { pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } #endif } }
/* ======================================================================== Routine Description: USB command kernel thread. Arguments: *Context the pAd, driver control block pointer Return Value: 0 close the thread Note: ======================================================================== */ INT RTUSBCmdThread( IN ULONG Context) { RTMP_ADAPTER *pAd; RTMP_OS_TASK *pTask; int status; status = 0; pTask = (RTMP_OS_TASK *)Context; pAd = (PRTMP_ADAPTER)pTask->priv; RtmpOSTaskCustomize(pTask); NdisAcquireSpinLock(&pAd->CmdQLock); pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING; NdisReleaseSpinLock(&pAd->CmdQLock); while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) { #ifdef KTHREAD_SUPPORT RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); #else /* lock the device pointers */ RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); if (status != 0) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } #endif if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED) break; if (!pAd->PM_FlgSuspend) CMDHandler(pAd); } if (pAd && !pAd->PM_FlgSuspend) { // Clear the CmdQElements. CmdQElmt *pCmdQElmt = NULL; NdisAcquireSpinLock(&pAd->CmdQLock); pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; while(pAd->CmdQ.size) { RTThreadDequeueCmd(&pAd->CmdQ, &pCmdQElmt); if (pCmdQElmt) { if (pCmdQElmt->CmdFromNdis == TRUE) { if (pCmdQElmt->buffer != NULL) os_free_mem(pAd, pCmdQElmt->buffer); os_free_mem(pAd, (PUCHAR)pCmdQElmt); } else { if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0)) os_free_mem(pAd, pCmdQElmt->buffer); os_free_mem(pAd, (PUCHAR)pCmdQElmt); } } } NdisReleaseSpinLock(&pAd->CmdQLock); } /* notify the exit routine that we're actually exiting now * * complete()/wait_for_completion() is similar to up()/down(), * except that complete() is safe in the case where the structure * is getting deleted in a parallel mode of execution (i.e. just * after the down() -- that's necessary for the thread-shutdown * case. * * complete_and_exit() goes even further than this -- it is safe in * the case that the thread of the caller is going away (not just * the structure) -- this is necessary for the module-remove case. * This is important in preemption kernels, which transfer the flow * of execution immediately upon a complete(). */ DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n")); #ifndef KTHREAD_SUPPORT pTask->taskPID = THREAD_PID_INIT_VALUE; complete_and_exit (&pTask->taskComplete, 0); #endif return 0; }
NDIS_STATUS rlt_rf_write( IN PRTMP_ADAPTER pAd, IN UCHAR bank, IN UCHAR regID, IN UCHAR value) { RF_CSR_CFG_STRUC rfcsr = { { 0 } }; NDIS_STATUS ret; #ifdef RTMP_MAC_PCI if ((pAd->bPCIclkOff == TRUE) || (pAd->LastMCUCmd == SLEEP_MCU_CMD)) { DBGPRINT_ERR(("rlt_rf_write. Not allow to write RF 0x%x : fail\n", regID)); return STATUS_UNSUCCESSFUL; } #endif /* RTMP_MAC_PCI */ #ifdef RLT_MAC // TODO: shiang-usw, why we need to check this for MT7601?? Get these code from MT7601! if (pAd->chipCap.hif_type == HIF_RLT) { if (pAd->WlanFunCtrl.field.WLAN_EN == 0) { DBGPRINT_ERR(("rlt_rf_write. Not allow to write RF 0x%x : fail\n", regID)); return STATUS_UNSUCCESSFUL; } } #endif /* RLT_MAC */ #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret); if (ret != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret)); return STATUS_UNSUCCESSFUL; } } #endif /* RTMP_MAC_USB */ ASSERT((regID <= pAd->chipCap.MaxNumOfRfId)); ret = STATUS_UNSUCCESSFUL; if (rf_csr_poll_idle(pAd, &rfcsr.word) != IDLE) goto done; #ifdef RT6352 if (IS_RT6352(pAd)) { rfcsr.bank_6352.RF_CSR_WR = 1; rfcsr.bank_6352.RF_CSR_KICK = 1; rfcsr.bank_6352.TESTCSR_RFACC_REGNUM = (regID | (bank << 6)); rfcsr.bank_6352.RF_CSR_DATA = value; } else #endif /* RT6352 */ #ifdef RT65xx if (IS_RT65XX(pAd)) { rfcsr.bank_65xx.RF_CSR_WR = 1; rfcsr.bank_65xx.RF_CSR_KICK = 1; rfcsr.bank_65xx.RF_CSR_REG_BANK = bank; rfcsr.bank_65xx.RF_CSR_REG_ID = regID; rfcsr.bank_65xx.RF_CSR_DATA = value; } else #endif /* RT65xx */ { DBGPRINT_ERR(("%s():RF write with wrong handler!\n", __FUNCTION__)); goto done; } RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); ret = NDIS_STATUS_SUCCESS; done: #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_UP(&pAd->reg_atomic); } #endif /* RTMP_MAC_USB */ return ret; }
/* ======================================================================== Routine Description: Read RF register through MAC Arguments: Return Value: IRQL = Note: ======================================================================== */ NDIS_STATUS rlt_rf_read( IN RTMP_ADAPTER *pAd, IN UCHAR bank, IN UCHAR regID, IN UCHAR *pValue) { RF_CSR_CFG_STRUC rfcsr = { { 0 } }; UINT i=0, k=0; BOOLEAN rf_status; NDIS_STATUS ret = STATUS_UNSUCCESSFUL; #ifdef MT76x0 if (IS_MT7610U(pAd)) { BANK_RF_REG_PAIR reg; reg.Bank = bank; reg.Register = regID; RF_RANDOM_READ(pAd, ®, 1); *pValue = reg.Value; return NDIS_STATUS_SUCCESS; } #endif /* MT76x0 */ #ifdef RTMP_MAC_PCI if ((pAd->bPCIclkOff == TRUE) || (pAd->LastMCUCmd == SLEEP_MCU_CMD)) { DBGPRINT_ERR(("RT30xxReadRFRegister. Not allow to read RF 0x%x : fail\n", regID)); return STATUS_UNSUCCESSFUL; } #endif /* RTMP_MAC_PCI */ #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, i); if (i != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", i)); return STATUS_UNSUCCESSFUL; } } #endif /* RTMP_MAC_USB */ ASSERT((regID <= pAd->chipCap.MaxNumOfRfId)); rfcsr.word = 0; for (i=0; i<MAX_BUSY_COUNT; i++) { if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto done; rf_status = rf_csr_poll_idle(pAd, &rfcsr.word); if ( rf_status == BUSY) break; rfcsr.word = 0; #ifdef RT6352 if (IS_RT6352(pAd)) { rfcsr.bank_6352.RF_CSR_WR = 0; rfcsr.bank_6352.RF_CSR_KICK = 1; rfcsr.bank_6352.TESTCSR_RFACC_REGNUM = (regID | (bank << 6)); } else #endif /* RT6352 */ #ifdef RT65xx if (IS_RT65XX(pAd)) { rfcsr.bank_65xx.RF_CSR_WR = 0; rfcsr.bank_65xx.RF_CSR_KICK = 1; rfcsr.bank_65xx.RF_CSR_REG_ID = regID; rfcsr.bank_65xx.RF_CSR_REG_BANK = bank; } else #endif /* RT65xx */ { DBGPRINT_ERR(("RF[%d] read function for non-supported chip[0x%x]\n", regID, pAd->MACVersion)); break; } RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); rf_status = rf_csr_poll_idle(pAd, &rfcsr.word); if (rf_status == IDLE) { #ifdef RT6352 if (IS_RT6352(pAd) && ((rfcsr.bank_6352.TESTCSR_RFACC_REGNUM & 0x3F) == regID)) { *pValue = (UCHAR)(rfcsr.bank_6352.RF_CSR_DATA); break; } #endif /* RT6352 */ #ifdef RT65xx if (IS_RT65XX(pAd) && (rfcsr.bank_65xx.RF_CSR_REG_ID == regID) && (rfcsr.bank_65xx.RF_CSR_REG_BANK == bank)) { *pValue = (UCHAR)(rfcsr.bank_65xx.RF_CSR_DATA); break; } #endif /* RT65xx */ } } if (rf_status == BUSY) { DBGPRINT_ERR(("RF read R%d=0x%X fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k)); goto done; } ret = STATUS_SUCCESS; #if 0 if (bank >= RF_BANK4) { printk("TESTCSR_RFACC_REGNUM = %x, RF_CSR_DATA = %x !!!\n", rfcsr.field.TESTCSR_RFACC_REGNUM, rfcsr.field.RF_CSR_DATA); } #endif done: #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_UP(&pAd->reg_atomic); } #endif /* RTMP_MAC_USB */ return ret; }
/* ======================================================================== Routine Description: RTUSB_VendorRequest - Builds a ralink specific request, sends it off to USB endpoint zero and waits for completion Arguments: @pAd: @TransferFlags: @RequestType: USB message request type value @Request: USB message request value @Value: USB message value @Index: USB message index value @TransferBuffer: USB data to be sent @TransferBufferLength: Lengths in bytes of the data to be sent Context: ! in atomic context Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_FAILURE Note: This function sends a simple control message to endpoint zero and waits for the message to complete, or CONTROL_TIMEOUT_JIFFIES timeout. Because it is synchronous transfer, so don't use this function within an atomic context, otherwise system will hang, do be careful. TransferBuffer may located in stack region which may not in DMA'able region in some embedded platforms, so need to copy TransferBuffer to UsbVendorReqBuf allocated by kmalloc to do DMA transfer. Use UsbVendorReq_semaphore to protect this region which may be accessed by multi task. Normally, coherent issue is resloved by low-level HC driver, so do not flush this zone by RTUSB_VendorRequest. ======================================================================== */ NTSTATUS RTUSB_VendorRequest( IN PRTMP_ADAPTER pAd, IN UINT32 TransferFlags, IN UCHAR RequestType, IN UCHAR Request, IN USHORT Value, IN USHORT Index, IN PVOID TransferBuffer, IN UINT32 TransferBufferLength) { int RET = 0; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; if(in_interrupt()) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("BUG: RTUSB_VendorRequest is called from invalid context\n")); return NDIS_STATUS_FAILURE; } if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { /*MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("WIFI device has been disconnected\n"));*/ return NDIS_STATUS_FAILURE; } else if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_MCU_SLEEP)) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("MCU has entered sleep mode\n")); return NDIS_STATUS_FAILURE; } else { int RetryCount = 0; /* RTUSB_CONTROL_MSG retry counts*/ ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE); RTMP_SEM_EVENT_WAIT(&(pAd->UsbVendorReq_semaphore), RET); if (RET != 0) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("UsbVendorReq_semaphore get failed! (%d)\n",RET)); return NDIS_STATUS_FAILURE; } if ((TransferBufferLength > 0) && ((RequestType == DEVICE_VENDOR_REQUEST_OUT) || (RequestType == DEVICE_CLASS_REQUEST_OUT))) NdisMoveMemory(pAd->UsbVendorReqBuf, TransferBuffer, TransferBufferLength); do { RTUSB_CONTROL_MSG(pObj->pUsb_Dev, 0, Request, RequestType, Value, Index, pAd->UsbVendorReqBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES, RET); if (RET < 0) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("#\n")); if (RET == RTMP_USB_CONTROL_MSG_ENODEV) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); break; } RetryCount++; RtmpusecDelay(5000); /* wait for 5ms*/ } } while((RET < 0) && (RetryCount < MAX_VENDOR_REQ_RETRY_COUNT)); if ( (!(RET < 0)) && (TransferBufferLength > 0) && (RequestType == DEVICE_VENDOR_REQUEST_IN)) NdisMoveMemory(TransferBuffer, pAd->UsbVendorReqBuf, TransferBufferLength); RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore)); if (RET < 0) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Idx=0x%x,pAd->Flags=0x%lx\n", RET, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index, pAd->Flags)); if (Request == 0x2) MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\tRequest Value=0x%04x!\n", Value)); if ((!TransferBuffer) && (TransferBufferLength > 0)) hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength); if (RET == RTMP_USB_CONTROL_MSG_ENODEV) RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); } } if (RET < 0) return NDIS_STATUS_FAILURE; else return NDIS_STATUS_SUCCESS; }
/* ======================================================================== RTUSB_CONTROL_MSG - Builds a control urb, sends it off and waits for completion @dev: pointer to the usb device to send the message to @pipe: endpoint "pipe" to send the message to @request: USB message request value @requesttype: USB message request type value @value: USB message value @index: USB message index value @data: pointer to the data to send @size: length in bytes of the data to send @timeout: time in jiffies to wait for the message to complete before timing out (if 0 the wait is forever) Context: !in_interrupt () This function sends a simple control message to a specified endpoint and waits for the message to complete, or timeout. If successful, it returns the number of bytes transferred, otherwise a negative error number. Don't use this function from within an interrupt context, like a bottom half handler. If you need an asynchronous message, or need to send a message from within interrupt context, use usb_submit_urb() If a thread in your driver uses this call, make sure your disconnect() method can wait for it to complete. Since you don't have a handle on the URB used, you can't cancel the request. Routine Description: Arguments: Return Value: Note: ======================================================================== */ NTSTATUS RTUSB_VendorRequest( IN PRTMP_ADAPTER pAd, IN UINT32 TransferFlags, IN UCHAR RequestType, IN UCHAR Request, IN USHORT Value, IN USHORT Index, IN PVOID TransferBuffer, IN UINT32 TransferBufferLength) { int ret = 0; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { /*DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));*/ return -1; } else if (in_interrupt()) { DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index)); return -1; } else { #define MAX_RETRY_COUNT 10 int retryCount = 0; void *tmpBuf = TransferBuffer; RTMP_SEM_EVENT_WAIT(&(pAd->UsbVendorReq_semaphore), ret); if (pAd->UsbVendorReqBuf) { ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE); tmpBuf = (void *)pAd->UsbVendorReqBuf; NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength); if (RequestType == DEVICE_VENDOR_REQUEST_OUT) NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength); } do { RTUSB_CONTROL_MSG(pObj->pUsb_Dev, 0, Request, RequestType, Value, Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES, ret); retryCount++; if (ret < 0) { DBGPRINT(RT_DEBUG_OFF, ("#\n")); if (ret == -ENODEV) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); break; } RTMPusecDelay(5000); } } while((ret < 0) && (retryCount < MAX_RETRY_COUNT)); if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN)) NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength); RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore)); if (ret < 0) { DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Idx=0x%x, pAd->Flags=0x%lx\n", ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index, pAd->Flags)); if (Request == 0x2) DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value)); if ((TransferBuffer!= NULL) && (TransferBufferLength > 0)) hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength); } } if (ret != -1) return STATUS_SUCCESS; else return STATUS_UNSUCCESSFUL; }
NDIS_STATUS MT7601_BBP_read( IN RTMP_ADAPTER *pAd, IN UCHAR regID, IN UCHAR *pValue) { BBP_CSR_CFG_STRUC BbpCsr = { { 0 } }; UINT i=0, k=0; NDIS_STATUS ret = STATUS_UNSUCCESSFUL; if (pAd->WlanFunCtrl.field.WLAN_EN == 0) { DBGPRINT_ERR(("MT7601_BBP_read. Not allow to read BBP 0x%x : fail\n", regID)); return STATUS_UNSUCCESSFUL; } #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, i); if (i != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", i)); return STATUS_UNSUCCESSFUL; } } #endif /* RTMP_MAC_USB */ ASSERT((regID <= pAd->chipCap.MaxNumOfBbpId)); for (i=0; i<MAX_BUSY_COUNT; i++) { if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto done; RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word); if (BbpCsr.field.Busy == BUSY) continue; BbpCsr.word = 0; BbpCsr.field.fRead = 1; BbpCsr.field.BBP_RW_MODE = 1; BbpCsr.field.Busy = 1; BbpCsr.field.RegNum = regID; RTMP_IO_WRITE32(pAd, BBP_CSR_CFG, BbpCsr.word); for (k=0; k<MAX_BUSY_COUNT; k++) { if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto done; RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word); if (BbpCsr.field.Busy == IDLE) break; } if ((BbpCsr.field.Busy == IDLE) && (BbpCsr.field.RegNum == regID) ) { *pValue = (UCHAR)(BbpCsr.field.Value); break; } } if (BbpCsr.field.Busy == BUSY) { DBGPRINT_ERR(("BBP read R%d=0x%X fail, i[%d], k[%d]\n", regID, BbpCsr.word,i,k)); goto done; } ret = STATUS_SUCCESS; done: #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_UP(&pAd->reg_atomic); } #endif /* RTMP_MAC_USB */ return ret; }
NDIS_STATUS MT7601_BBP_write( IN PRTMP_ADAPTER pAd, IN UCHAR regID, IN UCHAR value) { BBP_CSR_CFG_STRUC BbpCsr = { { 0 } }; UINT i = 0; NDIS_STATUS ret; #ifdef MT7601FPGA return; #endif /*MT7601FPGA */ if (pAd->WlanFunCtrl.field.WLAN_EN == 0) { DBGPRINT_ERR(("rlt_rf_write. Not allow to write BBP 0x%x : fail\n", regID)); return STATUS_UNSUCCESSFUL; } #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret); if (ret != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret)); return STATUS_UNSUCCESSFUL; } } #endif /* RTMP_MAC_USB */ ASSERT((regID <= pAd->chipCap.MaxNumOfBbpId)); ret = STATUS_UNSUCCESSFUL; do { RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word); if (!BbpCsr.field.Busy) break; i++; } while ((i < MAX_BUSY_COUNT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); if ((i == MAX_BUSY_COUNT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); goto done; } BbpCsr.word = 0; BbpCsr.field.fRead = 0; BbpCsr.field.BBP_RW_MODE = 1; BbpCsr.field.Busy = 1; BbpCsr.field.Value = value; BbpCsr.field.RegNum = regID; RTMP_IO_WRITE32(pAd, BBP_CSR_CFG, BbpCsr.word); ret = NDIS_STATUS_SUCCESS; done: #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_UP(&pAd->reg_atomic); } #endif /* RTMP_MAC_USB */ return ret; }
/* ======================================================================== Routine Description: Read RT30xx RF register through MAC Arguments: Return Value: IRQL = Note: ======================================================================== */ NDIS_STATUS RT30xxReadRFRegister( IN PRTMP_ADAPTER pAd, IN UCHAR regID, IN PUCHAR pValue) { RF_CSR_CFG_STRUC rfcsr = { { 0 } }; UINT i=0, k=0; NDIS_STATUS ret = STATUS_UNSUCCESSFUL; ASSERT((regID <= pAd->chipCap.MaxNumOfRfId)); #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, i); if (i != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", i)); return STATUS_UNSUCCESSFUL; } } #endif /* RTMP_MAC_USB */ for (i=0; i<MAX_BUSY_COUNT; i++) { if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto done; RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); if (rfcsr.field.RF_CSR_KICK == BUSY) continue; rfcsr.word = 0; rfcsr.field.RF_CSR_WR = 0; rfcsr.field.RF_CSR_KICK = 1; rfcsr.field.TESTCSR_RFACC_REGNUM = regID; RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); for (k=0; k<MAX_BUSY_COUNT; k++) { if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto done; RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); if (rfcsr.field.RF_CSR_KICK == IDLE) break; } if ((rfcsr.field.RF_CSR_KICK == IDLE) && (rfcsr.field.TESTCSR_RFACC_REGNUM == regID)) { *pValue = (UCHAR)(rfcsr.field.RF_CSR_DATA); break; } } if (rfcsr.field.RF_CSR_KICK == BUSY) { DBGPRINT_ERR(("RF read R%d=0x%X fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k)); goto done; } ret = STATUS_SUCCESS; done: #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_UP(&pAd->reg_atomic); } #endif /* RTMP_MAC_USB */ return ret; }
/* ======================================================================== Routine Description: Write RT30xx RF register through MAC Arguments: Return Value: IRQL = Note: ======================================================================== */ NDIS_STATUS RT30xxWriteRFRegister( IN PRTMP_ADAPTER pAd, IN UCHAR regID, IN UCHAR value) { RF_CSR_CFG_STRUC rfcsr = { { 0 } }; UINT i = 0; NDIS_STATUS ret; ASSERT((regID <= pAd->chipCap.MaxNumOfRfId)); #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret); if (ret != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret)); return STATUS_UNSUCCESSFUL; } } #endif /* RTMP_MAC_USB */ ret = STATUS_UNSUCCESSFUL; do { RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); if (!rfcsr.field.RF_CSR_KICK) break; i++; } while ((i < MAX_BUSY_COUNT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); if ((i == MAX_BUSY_COUNT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); goto done; } rfcsr.field.RF_CSR_WR = 1; rfcsr.field.RF_CSR_KICK = 1; rfcsr.field.TESTCSR_RFACC_REGNUM = regID; if ((pAd->chipCap.RfReg17WtMethod == RF_REG_WT_METHOD_STEP_ON) && (regID == RF_R17)) { UCHAR IdRf; UCHAR RfValue; BOOLEAN beAdd; RT30xxReadRFRegister(pAd, RF_R17, &RfValue); beAdd = (RfValue < value) ? TRUE : FALSE; IdRf = RfValue; while(IdRf != value) { if (beAdd) IdRf++; else IdRf--; rfcsr.field.RF_CSR_DATA = IdRf; RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); RtmpOsMsDelay(1); } } rfcsr.field.RF_CSR_DATA = value; RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); ret = NDIS_STATUS_SUCCESS; done: #ifdef RTMP_MAC_USB if (IS_USB_INF(pAd)) { RTMP_SEM_EVENT_UP(&pAd->reg_atomic); } #endif /* RTMP_MAC_USB */ return ret; }