static int rt2860_suspend( struct pci_dev *pci_dev, pm_message_t state) { struct net_device *net_dev = pci_get_drvdata(pci_dev); PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; INT32 retval = 0; DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n")); if (net_dev == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); } else { GET_PAD_FROM_NET_DEV(pAd, net_dev); /* we can not use IFF_UP because ra0 down but ra1 up */ /* and 1 suspend/resume function for 1 module, not for each interface */ /* so Linux will call suspend/resume function once */ if (VIRTUAL_IF_NUM(pAd) > 0) { // avoid users do suspend after interface is down // stop interface netif_carrier_off(net_dev); netif_stop_queue(net_dev); // mark device as removed from system and therefore no longer available netif_device_detach(net_dev); // mark halt flag RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); // take down the device rt28xx_close((PNET_DEV)net_dev); RT_MOD_DEC_USE_COUNT(); } } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10) // reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html // enable device to generate PME# when suspended // pci_choose_state(): Choose the power state of a PCI device to be suspended retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1); // save the PCI configuration space of a device before suspending pci_save_state(pci_dev); // disable PCI device after use pci_disable_device(pci_dev); retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); #endif DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n")); return retval; }
static int rt2860_suspend( struct pci_dev *pci_dev, pm_message_t state) { struct net_device *net_dev = pci_get_drvdata(pci_dev); PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; INT32 retval = 0; DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n")); if (net_dev == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); } else { pAd = (PRTMP_ADAPTER)RTMP_OS_NETDEV_GET_PRIV(net_dev); if (VIRTUAL_IF_NUM(pAd) > 0) { netif_carrier_off(net_dev); netif_stop_queue(net_dev); netif_device_detach(net_dev); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); rt28xx_close((PNET_DEV)net_dev); RT_MOD_DEC_USE_COUNT(); } } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1); pci_save_state(pci_dev); pci_disable_device(pci_dev); retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); #endif DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n")); return retval; }
void mt7612u_radio_off(struct rtmp_adapter *pAd, u8 Stage) { uint32_t Value, ret; DBGPRINT(RT_DEBUG_TRACE, ("--> %s\n", __FUNCTION__)); mt7612u_disable_txrx(pAd); ret = down_interruptible(&pAd->hw_atomic); if (ret != 0) { DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret)); return; } RTMP_SET_PSFLAG(pAd, fRTMP_PS_MCU_SLEEP); if (Stage == MLME_RADIO_OFF) mt7612u_mcu_pwr_saving(pAd, RADIO_OFF, 1); mt7612u_mcu_ctrl_exit(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); /* Stop bulkin pipe*/ //if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { RTUSBCancelPendingBulkInIRP(pAd); //pAd->PendingRx = 0; } up(&pAd->hw_atomic); DBGPRINT(RT_DEBUG_TRACE, ("<== %s\n", __FUNCTION__)); }
static void RtmpTimerQHandle(RTMP_ADAPTER *pAd) { int status; RALINK_TIMER_STRUCT *pTimer; RTMP_TIMER_TASK_ENTRY *pEntry; unsigned long irqFlag; RTMP_OS_TASK *pTask; pTask = &pAd->timerTask; while(!RTMP_OS_TASK_IS_KILLED(pTask)) { pTimer = NULL; if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } 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); } } if (status != 0) { pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } } }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_MlmeChannelSwitchRspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PMLME_TDLS_CH_SWITCH_STRUCT pMlmeChSwitchRsp = NULL; NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS; PRT_802_11_TDLS pTdls = NULL; int LinkId = 0xff; DBGPRINT(RT_DEBUG_WARN,("TDLS ===> TDLS_MlmeChannelSwitchRspAction() \n")); pMlmeChSwitchRsp = (PMLME_TDLS_CH_SWITCH_STRUCT)Elem->Msg; if (INFRA_ON(pAd)) { // Drop not within my TDLS Table that created before ! LinkId = TDLS_SearchLinkId(pAd, pMlmeChSwitchRsp->PeerMacAddr); if (LinkId == -1 || LinkId == MAX_NUM_OF_TDLS_ENTRY) { DBGPRINT(RT_DEBUG_OFF,("TDLS - TDLS_MlmeChannelSwitchRspAction() can not find the LinkId!\n")); return; } /* Point to the current Link ID */ pTdls = &pAd->StaCfg.TdlsInfo.TDLSEntry[LinkId]; /* Build TDLS channel switch Request Frame */ NStatus = TDLS_ChannelSwitchRspAction(pAd, pTdls, pTdls->ChSwitchTime, pTdls->ChSwitchTimeout, 0, (RTMP_TDLS_SPECIFIC_CS_RSP_NOACK + RTMP_TDLS_SPECIFIC_HCCA)); if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("TDLS - TDLS_MlmeChannelSwitchRspAction() Build Channel Switch Response Fail !!!\n")); } else { RTMPusecDelay(300); NdisGetSystemUpTime(&pAd->StaCfg.TdlsGoBackStartTime); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH); if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_ABOVE); else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_BELOW); else TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_NONE); TDLS_EnablePktChannel(pAd, TDLS_FIFO_ALL); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH); DBGPRINT(RT_DEBUG_WARN,("TDLS <=== TDLS_MlmeChannelSwitchRspAction() \n")); } } else { DBGPRINT(RT_DEBUG_ERROR,("TDLS - TDLS_MlmeChannelSwitchRspAction() TDLS only support infra mode !!!\n")); } return; }
INT AsicSetRDG(RTMP_ADAPTER *pAd, BOOLEAN bEnable) { INT ret = FALSE; #if defined(RTMP_MAC) || defined(RLT_MAC) if (pAd->chipCap.hif_type == HIF_RTMP ||pAd->chipCap.hif_type == HIF_RLT) ret = RtAsicSetRDG(pAd, bEnable); #endif #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) ret = MtAsicSetRDG(pAd, bEnable); #endif if (ret == TRUE) { if (bEnable) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE); } else { RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE); } } //AsicNotSupportFunc(pAd, __FUNCTION__); return ret; }
static void mt7612u_stop_dma_tx(struct rtmp_adapter *pAd) { uint32_t MacReg = 0, MTxCycle = 0; UINT8 IdleNums = 0; DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__)); for (MTxCycle = 0; MTxCycle < 2000; MTxCycle++) { MacReg = mt76u_sys_read(pAd, U3DMA_WLCFG); if (((MacReg & 0x80000000) == 0) && IdleNums > 10) { break; } else { IdleNums++; udelay(50); } if (MacReg == 0xFFFFFFFF) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); return; } } if (MTxCycle >= 2000) DBGPRINT(RT_DEBUG_ERROR, ("TX DMA busy!! DMA_CFG(%x)\n", MacReg)); }
/* ======================================================================== Routine Description: Release allocated resources. Arguments: *dev Point to the PCI or USB device pAd driver control block pointer Return Value: None Note: ======================================================================== */ static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd) { DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n", dev->bus->bus_name, dev->devpath)); if (!pAd) { usb_put_dev(dev); printk("rtusb_disconnect: pAd == NULL!\n"); return; } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); /* for debug, wait to show some messages to /proc system */ udelay(1); RtmpPhyNetDevExit(pAd, pAd->net_dev); /* FIXME: Shall we need following delay and flush the schedule?? */ udelay(1); flush_scheduled_work(); udelay(1); /* free the root net_device */ RtmpOSNetDevFree(pAd->net_dev); RtmpRaDevCtrlExit(pAd); /* release a use of the usb device structure */ usb_put_dev(dev); udelay(1); DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n")); }
static int rt73_suspend(struct usb_interface *intf, pm_message_t state) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; DBGPRINT(RT_DEBUG_TRACE,"---> rt73_suspend()\n"); pAd = usb_get_intfdata(intf); // need to send it first before USB go susped. // without it system unable to reume back. RTUSB_VendorRequest(pAd, 0, DEVICE_VENDOR_REQUEST_OUT, 0x0C, 0x0, 0x0, NULL, 0); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); MlmeRadioOff(pAd); DBGPRINT(RT_DEBUG_TRACE,"<--- rt73_suspend()\n"); return 0; }
VOID RTMPDrvOpen( IN VOID *pAdSrc) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; #ifdef CONFIG_STA_SUPPORT #endif /* CONFIG_STA_SUPPORT */ /* Enable Interrupt*/ RTMP_IRQ_ENABLE(pAd); /* Now Enable RxTx*/ RTMPEnableRxTx(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); { UINT32 reg = 0; RTMP_IO_READ32(pAd, 0x1300, ®); /* clear garbage interrupts*/ DBGPRINT(RT_DEBUG_TRACE, ("Clear Interrupts: 0x1300 = %08x\n", reg)); } { /* u32 reg;*/ /* UINT8 byte;*/ /* u16 tmp;*/ /* RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®);*/ /* tmp = 0x0805;*/ /* reg = (reg & 0xffff0000) | tmp;*/ /* RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);*/ } #ifdef CONFIG_STA_SUPPORT #ifdef PCIE_PS_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) RTMPInitPCIeLinkCtrlValue(pAd); #endif /* PCIE_PS_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_STA_SUPPORT /* To reduce connection time, do auto reconnect here instead of waiting STAMlmePeriodicExec to do auto reconnect. */ if (pAd->OpMode == OPMODE_STA) MlmeAutoReconnectLastSSID(pAd); #endif /* CONFIG_STA_SUPPORT */ }
/* ======================================================================== 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: Release allocated resources. Arguments: *dev Point to the PCI or USB device pAd driver control block pointer Return Value: None Note: ======================================================================== */ static void rt2870_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd) { DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n", dev->bus->bus_name, dev->devpath)); if (!pAd) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */ while(MOD_IN_USE > 0) { MOD_DEC_USE_COUNT; } #else usb_put_dev(dev); #endif // LINUX_VERSION_CODE // printk("rtusb_disconnect: pAd == NULL!\n"); return; } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); // for debug, wait to show some messages to /proc system udelay(1); RtmpPhyNetDevExit(pAd, pAd->net_dev); // FIXME: Shall we need following delay and flush the schedule?? udelay(1); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */ #else flush_scheduled_work(); #endif // LINUX_VERSION_CODE // udelay(1); // free the root net_device RtmpOSNetDevFree(pAd->net_dev); #ifdef RT_CFG80211_SUPPORT CFG80211_UnRegister(pAd, pAd->net_dev); #endif // RT_CFG80211_SUPPORT // RtmpRaDevCtrlExit(pAd); // release a use of the usb device structure #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */ while(MOD_IN_USE > 0) { MOD_DEC_USE_COUNT; } #else usb_put_dev(dev); #endif // LINUX_VERSION_CODE // udelay(1); DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n")); }
static void rt2870_rts_frame_complete_tasklet(unsigned long data) { PRTMP_ADAPTER pAd; PTX_CONTEXT pRTSContext; purbb_t pUrb; NTSTATUS Status; unsigned long irqFlag; pUrb = (purbb_t)data; pRTSContext = (PTX_CONTEXT)pUrb->context; pAd = pRTSContext->pAd; Status = pUrb->status; // Reset RTS frame context flags RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); pRTSContext->IRPPending = FALSE; pRTSContext->InUse = FALSE; if (Status == USB_ST_NOERROR) { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); } else // STATUS_OTHER { if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n")); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); } else { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); } } RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE; RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); // Always call Bulk routine, even reset bulk. // The protectioon of rest bulk should be in BulkOut routine RTUSBKickBulkOut(pAd); }
static void rtusb_null_frame_done_tasklet(unsigned long data) { PRTMP_ADAPTER pAd; PTX_CONTEXT pNullContext; purbb_t pUrb; NTSTATUS Status; unsigned long irqFlag; pUrb = (purbb_t)data; /* pNullContext = (PTX_CONTEXT)pUrb->context; */ pNullContext = (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); Status = RTMP_USB_URB_STATUS_GET(pUrb); pAd = pNullContext->pAd; /* Status = pUrb->status; */ /* Reset Null frame context flags */ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); pNullContext->IRPPending = FALSE; pNullContext->InUse = FALSE; pAd->BulkOutPending[0] = FALSE; pAd->watchDogTxPendingCnt[0] = 0; if (Status == USB_ST_NOERROR) { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); } else /* STATUS_OTHER */ { if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status)); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); } else { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); } } /* Always call Bulk routine, even reset bulk. */ /* The protectioon of rest bulk should be in BulkOut routine */ RTUSBKickBulkOut(pAd); }
/* ======================================================================== 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)RTMP_OS_TASK_DATA_GET(pTask); if (pAd == NULL) goto LabelExit; /* avoid compile warning */ RtmpOSTaskCustomize(pTask); while(!RTMP_OS_TASK_IS_KILLED(pTask)) { if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE) { DBGPRINT_ERR(("RtmpOSTaskWait returned false in MlmeThread, setting halt in progress flag!\n")); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } /* 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(). */ LabelExit: DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__)); RtmpOSTaskNotifyToExit(pTask); return 0; }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_ChannelSwitchTimeOutAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PRT_802_11_TDLS pTDLS = (PRT_802_11_TDLS)FunctionContext; PRTMP_ADAPTER pAd = pTDLS->pAd; BOOLEAN TimerCancelled; DBGPRINT(RT_DEBUG_WARN, ("TDLS - Failed to wait for channel switch, terminate the channel switch procedure (%02x:%02x:%02x:%02x:%02x:%02x)\n", pTDLS->MacAddr[0], pTDLS->MacAddr[1], pTDLS->MacAddr[2], pTDLS->MacAddr[3], pTDLS->MacAddr[4], pTDLS->MacAddr[5])); { ULONG Now, temp1; NdisGetSystemUpTime(&Now); temp1 = (((Now - pTDLS->ChannelSwitchTimerStartTime) * 1000) / OS_HZ); if (temp1 < (pTDLS->ChSwitchTimeout / 1000)) { RTMPSetTimer(&pTDLS->ChannelSwitchTimeoutTimer, ((pTDLS->ChSwitchTimeout / 1000) - temp1)); return; } if (temp1 < (pTDLS->ChSwitchTimeout / 1000)) { DBGPRINT(RT_DEBUG_OFF, ("Timer = %ld < 11 !!!\n", temp1)); } } RTMPCancelTimer(&pAd->StaCfg.TdlsResponderGoBackBaseChTimer, &TimerCancelled); pAd->StaCfg.bTdlsCurrentDoingChannelSwitchWaitSuccess = FALSE; pAd->StaCfg.bDoingPeriodChannelSwitch = FALSE; RTMPusecDelay(300); NdisGetSystemUpTime(&pAd->StaCfg.TdlsGoBackStartTime); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH); if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_ABOVE); else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_BELOW); else TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_NONE); TDLS_EnablePktChannel(pAd, TDLS_FIFO_ALL); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH); }
// RTS frame use BulkOutPipeId = PipeID VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs) { PRTMP_ADAPTER pAd; PTX_CONTEXT pRTSContext; NTSTATUS status; unsigned long IrqFlags; pRTSContext= (PTX_CONTEXT)pUrb->context; pAd = pRTSContext->pAd; DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutRTSFrameComplete\n"); // Reset RTS frame context flags pRTSContext->IRPPending = FALSE; pRTSContext->InUse = FALSE; status = pUrb->status; if (status == USB_ST_NOERROR) { // Don't worry about the queue is empty or not, this function will check itself RTMPDeQueuePacket(pAd, pRTSContext->BulkOutPipeId); } #if 1 // STATUS_OTHER else { if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out RTS Frame Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); } } #endif NdisAcquireSpinLock(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags); pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags); // Always call Bulk routine, even reset bulk. // The protectioon of rest bulk should be in BulkOut routine RTUSBKickBulkOut(pAd); DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutRTSFrameComplete\n"); }
static void mt7612u_stop_dma_rx(struct rtmp_adapter *pAd) { struct sk_buff *pRxPacket; RX_BLK RxBlk, *pRxBlk; uint32_t RxPending = 0, MacReg = 0, MTxCycle = 0; bool bReschedule = false; bool bCmdRspPacket = false; UINT8 IdleNums = 0; /* process whole rx ring */ while (1) { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) return; pRxBlk = &RxBlk; pRxPacket = GetPacketFromRxRing(pAd, pRxBlk, &bReschedule, &RxPending, 0); bCmdRspPacket = false; if ((RxPending == 0) && (bReschedule == false)) break; else dev_kfree_skb_any(pRxPacket); } /* Check DMA Rx idle */ for (MTxCycle = 0; MTxCycle < 2000; MTxCycle++) { MacReg = mt76u_sys_read(pAd, U3DMA_WLCFG); if ((MacReg & 0x40000000) && (IdleNums < 10)) { IdleNums++; udelay(50); } else { break; } if (MacReg == 0xFFFFFFFF) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); return; } } if (MTxCycle >= 2000) DBGPRINT(RT_DEBUG_ERROR, ("%s:RX DMA busy!! DMA_CFG = 0x%08x\n", __FUNCTION__, MacReg)); DBGPRINT(RT_DEBUG_TRACE, ("<==== %s\n", __FUNCTION__)); }
static inline void rt2860_int_enable(struct rt_rtmp_adapter *pAd, unsigned int mode) { u32 regValue; pAd->int_disable_mask &= ~(mode); regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask); /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */ { RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); /* 1:enable */ } /*else */ /* DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); */ if (regValue != 0) RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); }
static void usb_rtusb_disconnect(struct usb_interface *intf) { struct net_device *net_dev = NULL; struct usb_device *dev = interface_to_usbdev(intf); PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; pAd = usb_get_intfdata(intf); DBGPRINT(RT_DEBUG_TRACE, "%s-->\n", __FUNCTION__); usb_set_intfdata(intf, NULL); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); DBGPRINT(RT_DEBUG_ERROR, "unregister usbnet usb-%s-%s\n", dev->bus->bus_name, dev->devpath); if (!pAd) return; if (pAd) usb_rtusb_close_device(pAd); // for debug, wait to show some messages to /proc system udelay(1); //After Add Thread implementation, Upon exec there, pAd->net_dev seems becomes NULL, //need to check why??? //assert(pAd->net_dev != NULL) net_dev = pAd->net_dev; if(pAd->net_dev!= NULL) { printk("unregister_netdev()\n"); unregister_netdev (pAd->net_dev); } udelay(1); flush_scheduled_work (); udelay(1); // free adapter vfree(pAd); if (net_dev != NULL) free_netdev(net_dev); usb_put_dev(dev); udelay(1); DBGPRINT(RT_DEBUG_TRACE, "%s<--\n", __FUNCTION__); }
//Disconnect function is called within exit routine static void usb_rtusb_disconnect(struct usb_device *dev, void *ptr) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) ptr; struct net_device *net_dev = NULL; DBGPRINT(RT_DEBUG_TRACE, "%s-->\n", __FUNCTION__); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); if (!pAd) return; if (pAd) usb_rtusb_close_device(pAd); // for debug, wait to show some messages to /proc system udelay(1); //After Add Thread implementation, Upon exec there, pAd->net_dev seems becomes NULL, //need to check why??? //assert(pAd->net_dev != NULL) net_dev = pAd->net_dev; if(pAd->net_dev != NULL) { printk("unregister_netdev()\n"); unregister_netdev (pAd->net_dev); } udelay(1); udelay(1); // free adapter vfree(pAd); if (net_dev != NULL) kfree(net_dev); while (MOD_IN_USE > 0) { MOD_DEC_USE_COUNT; } udelay(1); DBGPRINT(RT_DEBUG_TRACE, "%s<--\n", __FUNCTION__); }
VOID RTUSBHalt( IN PRTMP_ADAPTER pAd, IN BOOLEAN IsFree) { BOOLEAN TimerCancelled; DBGPRINT(RT_DEBUG_TRACE, "====> RTUSBHalt\n"); // // before set flag fRTMP_ADAPTER_HALT_IN_PROGRESS, // we should send a disassoc frame to our AP. // RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); RTUSBCleanUpMLMEWaitQueue(pAd); RTUSBCleanUpMLMEBulkOutQueue(pAd); RTMPCancelTimer(&pAd->PortCfg.QuickResponeForRateUpTimer,&TimerCancelled); RTMPCancelTimer(&pAd->RxAnt.RxAntDiversityTimer,&TimerCancelled); // Free MLME stuff MlmeHalt(pAd); // Sleep 50 milliseconds so pending io might finish normally RTMPusecDelay(50000); // We want to wait until all pending receives and sends to the // device object. We cancel any // irps. Wait until sends and receives have stopped. // RTUSBCancelPendingIRPs(pAd); // Free the entire adapter object ReleaseAdapter(pAd, IsFree, FALSE); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); }
VOID RT28xxUsbMlmeRadioOFF( IN PRTMP_ADAPTER pAd) { WPDMA_GLO_CFG_STRUC GloCfg; UINT32 Value, i; DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n")); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) return; RTMPSetLED(pAd, LED_RADIO_OFF); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); { if (INFRA_ON(pAd) || ADHOC_ON(pAd)) LinkDown(pAd, FALSE); RTMPusecDelay(10000); BssTableInit(&pAd->ScanTab); } if (pAd->CommonCfg.BBPCurrentBW == BW_40) { AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); } else { AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); } RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); GloCfg.field.EnableTxDMA = 0; GloCfg.field.EnableRxDMA = 0; RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); i = 0; do { RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) break; RTMPusecDelay(1000); }while (i++ < 100); RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); Value &= (0xfffffff3); RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); }
// ************************ Completion Func ************************ // VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs) { PTX_CONTEXT pTxContext; PRTMP_ADAPTER pAd; NTSTATUS status; UCHAR BulkOutPipeId; unsigned long IrqFlags; DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutDataPacketComplete\n"); pTxContext= (PTX_CONTEXT)pUrb->context; pAd = pTxContext->pAd; status = pUrb->status; // Store BulkOut PipeId BulkOutPipeId = pTxContext->BulkOutPipeId; pAd->BulkOutDataOneSecCount++; if (status == USB_ST_NOERROR) { DBGPRINT_RAW(RT_DEBUG_INFO, "BulkOutDataPacketComplete %d (STATUS_SUCCESS)\n", BulkOutPipeId); if (pTxContext->LastOne == TRUE) { pAd->Counters.GoodTransmits++; FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--; // sync. to TxCount if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0) { RTMPDeQueuePacket(pAd, BulkOutPipeId); } } else { if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--; // sync. to TxCount // Indicate next one is frag data which has highest priority RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); } else { while (pTxContext->LastOne != TRUE) { FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--; // sync. to TxCount pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]); } FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--; // sync. to TxCount } } } #if 1 // STATUS_OTHER else { DBGPRINT_RAW(RT_DEBUG_ERROR, "BulkOutDataPacketComplete %d (STATUS_OTHER)\n", BulkOutPipeId); while (pTxContext->LastOne != TRUE) { FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--; // sync. to TxCount pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]); } FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--; // sync. to TxCount if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); } } #endif pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]); // // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. // if ((pTxContext->bWaitingBulkOut == TRUE) && !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId))) { // Indicate There is data avaliable RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); } NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); // Always call Bulk routine, even reset bulk. // The protectioon of rest bulk should be in BulkOut routine RTUSBKickBulkOut(pAd); }
/* ======================================================================== Routine Description: This routine process Rx Irp and call rx complete function. Arguments: DeviceObject Pointer to the device object for next lower device. DeviceObject passed in here belongs to the next lower driver in the stack because we were invoked via IoCallDriver in USB_RxPacket AND it is not OUR device object Irp Ptr to completed IRP Context Ptr to our Adapter object (context specified in IoSetCompletionRoutine Return Value: Always returns STATUS_MORE_PROCESSING_REQUIRED Note: Always returns STATUS_MORE_PROCESSING_REQUIRED ======================================================================== */ VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs) { PRX_CONTEXT pRxContext; PRTMP_ADAPTER pAd; NTSTATUS status; pRxContext= (PRX_CONTEXT)pUrb->context; pAd = pRxContext->pAd; // // We have a number of cases: // 1) The USB read timed out and we received no data. // 2) The USB read timed out and we received some data. // 3) The USB read was successful and fully filled our irp buffer. // 4) The irp was cancelled. // 5) Some other failure from the USB device object. // // // Free the IRP and its mdl because they were alloced by us // #if 0 if ( (atomread = (atomic_read(&pRxContext->IrpLock))) == IRPLOCK_CANCE_START) { atomic_dec(&pAd->PendingRx); atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCE_COMPLETE); } #endif status = pUrb->status; atomic_set(&pRxContext->IrpLock, IRPLOCK_COMPLETED); if( atomic_read(&pAd->PendingRx) > 0) atomic_dec(&pAd->PendingRx); switch (status) { case 0: break; case -ECONNRESET: // async unlink case -ESHUTDOWN: // hardware gone = -108 //pUrb = NULL; DBGPRINT(RT_DEBUG_ERROR, "==> RTUSBBulkRxComplete Error code = %d\n", status); break; default: DBGPRINT(RT_DEBUG_ERROR, "==> RTUSBBulkRxComplete UnKnown Error code = %d\n", status); break; } if (atomic_read(&pRxContext->IrpLock) != IRPLOCK_CANCE_START) { pAd->rx_bh.data = (unsigned long)pUrb; if(!RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_HALT_IN_PROGRESS)) //Add by Zero:Jan09.2008 Fix IF down crash tasklet_schedule(&pAd->rx_bh); //iverson patch usb 1.1 or 2.0 2007 1109 if(pAd->BulkOutMaxPacketSize == 512) { DBGPRINT(RT_DEBUG_INFO, "In USB 2.0 Mode \n"); } else{ RTUSBBulkReceive(pAd); } } else DBGPRINT(RT_DEBUG_INFO, "==> RTUSBBulkRxComplete (IrpLock) = %d\n", atomic_read(&pRxContext->IrpLock)); #if 0 if ((status == USB_ST_NOERROR) && (atomic_read(&pRxContext->IrpLock) != IRPLOCK_CANCE_START)) { RTUSBRxPacket(pUrb); //tasklet_schedule(&pAd->rx_bh); }// STATUS_SUCCESS else { DBGPRINT(RT_DEBUG_TEMP,"==> RTUSBBulkRxComplete Error code = %d\n", status); pRxContext->InUse = FALSE; if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk In Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_IN); } } #endif }
// MLME use BulkOutPipeId = 0 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs) { PTX_CONTEXT pMLMEContext; PRTMP_ADAPTER pAd; NTSTATUS status; unsigned long IrqFlags; pMLMEContext= (PTX_CONTEXT)pUrb->context; pAd = pMLMEContext->pAd; status = pUrb->status; pAd->PrioRingTxCnt--; if (pAd->PrioRingTxCnt < 0) pAd->PrioRingTxCnt = 0; pAd->PrioRingFirstIndex++; if (pAd->PrioRingFirstIndex >= PRIO_RING_SIZE) { pAd->PrioRingFirstIndex = 0; } DBGPRINT(RT_DEBUG_INFO, "RTUSBBulkOutMLMEPacketComplete::PrioRingFirstIndex = %d, PrioRingTxCnt = %d, PopMgmtIndex = %d, PushMgmtIndex = %d, NextMLMEIndex = %d\n", pAd->PrioRingFirstIndex, pAd->PrioRingTxCnt, pAd->PopMgmtIndex, pAd->PushMgmtIndex, pAd->NextMLMEIndex); DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutMLMEPacketComplete\n"); // Reset MLME context flags pMLMEContext->IRPPending = FALSE; pMLMEContext->InUse = FALSE; pMLMEContext->bWaitingBulkOut =FALSE; if (status == USB_ST_NOERROR) { // Don't worry about the queue is empty or not, this function will check itself RTUSBDequeueMLMEPacket(pAd); } #if 1 // STATUS_OTHER else { if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out MLME Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); } } #endif pMLMEContext = &pAd->MLMEContext[pAd->PrioRingFirstIndex]; if ( (pAd->PrioRingTxCnt >= 1) && (pMLMEContext->bWaitingBulkOut == TRUE)) RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags); pAd->BulkOutPending[0] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags); // Always call Bulk routine, even reset bulk. // The protectioon of rest bulk should be in BulkOut routine RTUSBKickBulkOut(pAd); DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutMLMEPacketComplete\n"); }
VOID ATE_RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs) { PRTMP_ADAPTER pAd; PTX_CONTEXT pNullContext; NTSTATUS status; unsigned long IrqFlags; ULONG OldValue; pNullContext= (PTX_CONTEXT)pUrb->context; pAd = pNullContext->pAd; DBGPRINT_RAW(RT_DEBUG_INFO, "--->ATE_RTUSBBulkOutDataPacketComplete\n"); // Reset Null frame context flags pNullContext->IRPPending = FALSE; pNullContext->InUse = FALSE; status = pUrb->status; if (status == USB_ST_NOERROR) { // Don't worry about the queue is empty or not, this function will check itself RTMPDeQueuePacket(pAd, 0); } #if 1 // STATUS_OTHER else { if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out Null Frame Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); } } #endif if (atomic_read(&pAd->BulkOutRemained) > 0) { atomic_dec(&pAd->BulkOutRemained); DBGPRINT(RT_DEBUG_INFO, "Bulk Out Remained = %d\n", atomic_read(&pAd->BulkOutRemained)); } // 1st - Transmit Success OldValue = pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart; pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart++; if (pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart < OldValue) { pAd->WlanCounters.TransmittedFragmentCount.vv.HighPart++; } if(((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) && (pAd->ate.Mode != ATE_STASTART)) { DBGPRINT(RT_DEBUG_INFO, "ContinBulkOut = TRUE \n"); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); } else { RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); } NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags); pAd->BulkOutPending[0] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags); // Always call Bulk routine, even reset bulk. // The protectioon of rest bulk should be in BulkOut routine RTUSBKickBulkOut(pAd); DBGPRINT_RAW(RT_DEBUG_INFO, "<---ATE_RTUSBBulkOutDataPacketComplete\n"); }
/* ======================================================================== Routine Description: Open raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: ======================================================================== */ int rt28xx_open(IN PNET_DEV dev) { struct net_device * net_dev = (struct net_device *)dev; PRTMP_ADAPTER pAd = NULL; int retval = 0; //POS_COOKIE pObj; GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) { /* if 1st open fail, pAd will be free; So the net_dev->priv will be NULL in 2rd open */ return -1; } #ifdef CONFIG_APSTA_MIXED_SUPPORT if (pAd->OpMode == OPMODE_AP) { CW_MAX_IN_BITS = 6; } else if (pAd->OpMode == OPMODE_STA) { CW_MAX_IN_BITS = 10; } #endif // CONFIG_APSTA_MIXED_SUPPORT // #if WIRELESS_EXT >= 12 if (RT_DEV_PRIV_FLAGS_GET(net_dev) == INT_MAIN) { #ifdef CONFIG_APSTA_MIXED_SUPPORT if (pAd->OpMode == OPMODE_AP) net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def; #endif // CONFIG_APSTA_MIXED_SUPPORT // } #endif // WIRELESS_EXT >= 12 // // Request interrupt service routine for PCI device // register the interrupt routine with the os /* AP Channel auto-selection will be run in rt28xx_init(), so we must reqister IRQ hander here. */ RtmpOSIRQRequest(net_dev); // Init IRQ parameters stored in pAd RTMP_IRQ_INIT(pAd); // Chip & other init if (rt28xx_init(pAd, mac, hostname) == FALSE) goto err; #ifdef LINUX #ifdef RT_CFG80211_SUPPORT RT_CFG80211_REINIT(pAd); RT_CFG80211_CRDA_REG_RULE_APPLY(pAd); #endif // RT_CFG80211_SUPPORT // #endif // LINUX // // Enable Interrupt RTMP_IRQ_ENABLE(pAd); // Now Enable RxTx RTMPEnableRxTx(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); { UINT32 reg = 0; RTMP_IO_READ32(pAd, 0x1300, ®); // clear garbage interrupts if (reg); DBGPRINT(RT_DEBUG_TRACE, ("0x1300 = %08x\n", reg)); } { // u32 reg; // UINT8 byte; // u16 tmp; // RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®); // tmp = 0x0805; // reg = (reg & 0xffff0000) | tmp; // RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); } #ifdef CONFIG_AP_SUPPORT #ifdef BG_FT_SUPPORT BG_FTPH_Init(); #endif // BG_FT_SUPPORT // #endif // CONFIG_AP_SUPPORT // #ifdef VENDOR_FEATURE2_SUPPORT printk("Number of Packet Allocated in open = %d\n", pAd->NumOfPktAlloc); printk("Number of Packet Freed in open = %d\n", pAd->NumOfPktFree); #endif // VENDOR_FEATURE2_SUPPORT // return (retval); err: //+++Add by shiang, move from rt28xx_init() to here. RtmpOSIRQRelease(net_dev); //---Add by shiang, move from rt28xx_init() to here. return (-1); } /* End of rt28xx_open */
/* ======================================================================== Routine Description: Close raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: 1. if open fail, kernel will not call the close function. 2. Free memory for (1) Mlme Memory Handler: MlmeHalt() (2) TX & RX: RTMPFreeTxRxRingMemory() (3) BA Reordering: ba_reordering_resource_release() ======================================================================== */ int rt28xx_close(IN PNET_DEV dev) { struct net_device * net_dev = (struct net_device *)dev; RTMP_ADAPTER *pAd = NULL; BOOLEAN Cancelled; UINT32 i = 0; GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n")); #ifdef CONFIG_AP_SUPPORT #ifdef BG_FT_SUPPORT BG_FTPH_Remove(); #endif // BG_FT_SUPPORT // #endif // CONFIG_AP_SUPPORT // Cancelled = FALSE; // Sanity check for pAd if (pAd == NULL) return 0; // close ok RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); #ifdef WMM_ACM_SUPPORT /* must call first */ ACMP_Release(pAd); #endif // WMM_ACM_SUPPORT // #ifdef WDS_SUPPORT WdsDown(pAd); #endif // WDS_SUPPORT // mdelay(20); /* wait for disconnect requests transmitted */ for (i = 0 ; i < NUM_OF_TX_RING; i++) { while (pAd->DeQueueRunning[i] == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i)); RTMPusecDelay(1000); } } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef DOT11N_DRAFT3 if (pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_TIMER_FIRED) { RTMPCancelTimer(&pAd->CommonCfg.Bss2040CoexistTimer, &Cancelled); pAd->CommonCfg.Bss2040CoexistFlag = 0; } #endif // DOT11N_DRAFT3 // // PeriodicTimer already been canceled by MlmeHalt() API. //RTMPCancelTimer(&pAd->PeriodicTimer, &Cancelled); } #endif // CONFIG_AP_SUPPORT // // Stop Mlme state machine MlmeHalt(pAd); // Close net tasklets RtmpNetTaskExit(pAd); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MAT_SUPPORT MATEngineExit(pAd); #endif // MAT_SUPPORT // #ifdef CLIENT_WDS CliWds_ProxyTabDestory(pAd); #endif // CLIENT_WDS // // Shutdown Access Point function, release all related resources APShutdown(pAd); #ifdef AUTO_CH_SELECT_ENHANCE // Free BssTab & ChannelInfo tabbles. AutoChBssTableDestroy(pAd); ChannelInfoDestroy(pAd); #endif // AUTO_CH_SELECT_ENHANCE // } #endif // CONFIG_AP_SUPPORT // MeasureReqTabExit(pAd); TpcReqTabExit(pAd); #ifdef WSC_INCLUDED #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { INT ap_idx; for (ap_idx = 0; ap_idx < pAd->ApCfg.BssidNum; ap_idx++) { PWSC_CTRL pWpsCtrl = &pAd->ApCfg.MBSSID[ap_idx].WscControl; WscStop(pAd, FALSE, pWpsCtrl); } #ifdef APCLI_SUPPORT WscStop(pAd, TRUE, &pAd->ApCfg.ApCliTab[BSS0].WscControl); #endif // APCLI_SUPPORT // } #endif // CONFIG_AP_SUPPORT // #ifdef OLD_DH_KEY #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) WSC_VFREE_KEY_MEM(pAd->ApCfg.MBSSID[0].WscControl.pPubKeyMem, pAd->ApCfg.MBSSID[0].WscControl.pSecKeyMem); #endif // CONFIG_AP_SUPPORT // #endif // OLD_DH_KEY // /* WSC hardware push button function 0811 */ WSC_HDR_BTN_Stop(pAd); #endif // WSC_INCLUDED // // Close kernel threads RtmpMgmtTaskExit(pAd); #ifdef RTMP_MAC_PCI { BOOLEAN brc; // ULONG Value; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { RTMP_ASIC_INTERRUPT_DISABLE(pAd); } // Receive packets to clear DMA index after disable interrupt. //RTMPHandleRxDoneInterrupt(pAd); // put to radio off to save power when driver unload. After radiooff, can't write /read register. So need to finish all // register access before Radio off. brc=RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0); //In solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff #ifdef PCIE_PS_SUPPORT pAd->bPCIclkOff = FALSE; #endif // PCIE_PS_SUPPORT // if (brc==FALSE) { DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __FUNCTION__)); } } /* if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { RTMP_ASIC_INTERRUPT_DISABLE(pAd); } // Disable Rx, register value supposed will remain after reset NICIssueReset(pAd); */ #endif // RTMP_MAC_PCI // // Free IRQ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { #ifdef RTMP_MAC_PCI // Deregister interrupt function RtmpOSIRQRelease(net_dev); #endif // RTMP_MAC_PCI // RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } #ifdef RESOURCE_PRE_ALLOC RTMPResetTxRxRingMemory(pAd); #else // Free Ring or USB buffers RTMPFreeTxRxRingMemory(pAd); #endif // RESOURCE_PRE_ALLOC // RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); #ifdef DOT11_N_SUPPORT // Free BA reorder resource ba_reordering_resource_release(pAd); #endif // DOT11_N_SUPPORT // RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP); /*+++Modify by woody to solve the bulk fail+++*/ #ifdef VENDOR_FEATURE2_SUPPORT printk("Number of Packet Allocated = %d\n", pAd->NumOfPktAlloc); printk("Number of Packet Freed = %d\n", pAd->NumOfPktFree); #endif // VENDOR_FEATURE2_SUPPORT // /* clear MAC table */ /* TODO: do not clear spin lock, such as fLastChangeAccordingMfbLock */ NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); /* release all timers */ RTMPusecDelay(2000); RTMP_TimerListRelease(pAd); DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n")); return 0; // close ok } /* End of rt28xx_close */
/* ======================================================================== Routine Description: Open raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: ======================================================================== */ int rt28xx_open(IN PNET_DEV dev) { struct net_device * net_dev = (struct net_device *)dev; PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev); int retval = 0; //POS_COOKIE pObj; // Sanity check for pAd if (pAd == NULL) { /* if 1st open fail, pAd will be free; So the net_dev->priv will be NULL in 2rd open */ return -1; } #ifdef CONFIG_APSTA_MIXED_SUPPORT if (pAd->OpMode == OPMODE_AP) { CW_MAX_IN_BITS = 6; } else if (pAd->OpMode == OPMODE_STA) { CW_MAX_IN_BITS = 10; } #endif // CONFIG_APSTA_MIXED_SUPPORT // #if WIRELESS_EXT >= 12 if (net_dev->priv_flags == INT_MAIN) { #ifdef CONFIG_APSTA_MIXED_SUPPORT if (pAd->OpMode == OPMODE_AP) net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def; #endif // CONFIG_APSTA_MIXED_SUPPORT // #ifdef CONFIG_STA_SUPPORT if (pAd->OpMode == OPMODE_STA) net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def; #endif // CONFIG_STA_SUPPORT // } #endif // WIRELESS_EXT >= 12 // // Request interrupt service routine for PCI device // register the interrupt routine with the os RTMP_IRQ_REQUEST(net_dev); // Init IRQ parameters stored in pAd RTMP_IRQ_INIT(pAd); // Chip & other init if (rt28xx_init(pAd, mac, hostname) == FALSE) goto err; #ifdef CONFIG_STA_SUPPORT #endif // CONFIG_STA_SUPPORT // // Enable Interrupt RTMP_IRQ_ENABLE(pAd); // Now Enable RxTx RTMPEnableRxTx(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); { UINT32 reg = 0; RTMP_IO_READ32(pAd, 0x1300, ®); // clear garbage interrupts printk("0x1300 = %08x\n", reg); } { // u32 reg; // UINT8 byte; // u16 tmp; // RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®); // tmp = 0x0805; // reg = (reg & 0xffff0000) | tmp; // RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); } #ifdef CONFIG_STA_SUPPORT #ifdef RTMP_MAC_PCI IF_DEV_CONFIG_OPMODE_ON_STA(pAd) RTMPInitPCIeLinkCtrlValue(pAd); #endif // RTMP_MAC_PCI // #endif // CONFIG_STA_SUPPORT // return (retval); err: //+++Add by shiang, move from rt28xx_init() to here. RTMP_IRQ_RELEASE(net_dev); //---Add by shiang, move from rt28xx_init() to here. return (-1); } /* End of rt28xx_open */