/** * @brief handle TX Queue * @param priv pointer to wlan_private * @return N/A */ void wlan_process_txqueue(wlan_private * priv) { wlan_adapter *Adapter = priv->adapter; ulong flags; struct sk_buff *Q; OS_INTERRUPT_SAVE_AREA; ENTER(); //spin_lock_irqsave(&Adapter->CurrentTxLock, flags); OS_INT_DISABLE(flags); if (Adapter->TxSkbNum > 0) { Q = &priv->adapter->TxSkbQ; Adapter->CurrentTxSkb = Q->next; list_del((struct list_head *) Adapter->CurrentTxSkb); Adapter->TxSkbNum--; } //spin_unlock_irqrestore(&Adapter->CurrentTxLock, flags); OS_INT_RESTORE(flags); if (Adapter->CurrentTxSkb) { wlan_process_tx(priv); } LEAVE(); }
/** * @brief This function handles the major job in WLAN driver. * it handles the event generated by firmware, rx data received * from firmware and tx data sent from kernel. * * @param data A pointer to wlan_thread structure * @return WLAN_STATUS_SUCCESS */ static int wlan_service_main_thread(void *data) { wlan_thread *thread = data; wlan_private *priv = thread->priv; wlan_adapter *Adapter = priv->adapter; wait_queue_t wait; u8 ireg = 0; unsigned long driver_flags; OS_INTERRUPT_SAVE_AREA; ENTER(); wlan_activate_thread(thread); init_waitqueue_entry(&wait, current); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) current->flags |= PF_NOFREEZE; #endif wlan_meas_init(priv); PRINTM(INFO, "11H: init 11H\n"); wlan_11h_init(priv); wmm_init(priv); for (;;) { #define MAX_MAIN_THREAD_LOOPS (10000) if (++Adapter->main_thread_loops > MAX_MAIN_THREAD_LOOPS) { panic("main-thread dead loop detected: %u\n" "IntCnt=%d\n" "Adapter->HisRegCpy=%#x\n" "CurCmd=%p CmdPending=%s\n" "Connect=%s\n" "cmd_sent=%s\n" "data_sent=%s\n" "IsDeepSleep=%d\n" "PSMode=%d PSState=%d\n" "WakeupDevReq=%d\n" "HS_Activated=%d\n" "WakeupTries=%d\n", Adapter->main_thread_loops, Adapter->IntCounter, Adapter->HisRegCpy, Adapter->CurCmd, list_empty(&Adapter->CmdPendingQ) ? "N" : "Y", (Adapter->MediaConnectStatus == WlanMediaStateConnected) ? "Y" : "N", (priv->wlan_dev.cmd_sent) ? "TRUE" : "FALSE", (priv->wlan_dev.data_sent) ? "TRUE" : "FALSE", Adapter->IsDeepSleep, Adapter->PSMode, Adapter->PSState, Adapter->bWakeupDevRequired, Adapter->HS_Activated, Adapter->WakeupTries); } add_wait_queue(&thread->waitQ, &wait); OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE); TX_DISABLE; if ((Adapter->WakeupTries) || (Adapter->PSState == PS_STATE_SLEEP && !Adapter->bWakeupDevRequired) || (!Adapter->IntCounter && Adapter->PSState == PS_STATE_PRE_SLEEP) || (!Adapter->IntCounter && (priv->wlan_dev.data_sent || Adapter->TxLockFlag || wmm_lists_empty(priv) || wmm_is_queue_stopped(priv)) && (priv->wlan_dev.cmd_sent || Adapter->CurCmd || list_empty(&Adapter->CmdPendingQ)) ) ) { PRINTM(INFO, "main-thread sleeping... " "HS_Act=%s WakeupReq=%s Conn=%s PS_Mode=%d PS_State=%d\n", (Adapter->HS_Activated) ? "Y" : "N", (Adapter->bWakeupDevRequired) ? "Y" : "N", (Adapter->MediaConnectStatus) ? "Y" : "N", Adapter->PSMode, Adapter->PSState); TX_RESTORE; Adapter->main_thread_loops = 0; schedule(); PRINTM(INFO, "main-thread waking up: IntCnt=%d " "CurCmd=%s CmdPending=%s\n" " Connect=%s " "cmd_sent=%s data_sent=%s\n", Adapter->IntCounter, (Adapter->CurCmd) ? "Y" : "N", list_empty(&Adapter->CmdPendingQ) ? "N" : "Y", (Adapter->MediaConnectStatus) ? "Y" : "N", (priv->wlan_dev.cmd_sent) ? "TRUE" : "FALSE", (priv->wlan_dev.data_sent) ? "TRUE" : "FALSE"); } else { TX_RESTORE; } OS_SET_THREAD_STATE(TASK_RUNNING); remove_wait_queue(&thread->waitQ, &wait); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) if ((thread->state == WLAN_THREAD_STOPPED) || Adapter->SurpriseRemoved) #else if (kthread_should_stop() || Adapter->SurpriseRemoved) #endif { PRINTM(INFO, "main-thread: break from main thread: " "SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved); break; } if (Adapter->IntCounter) { OS_INT_DISABLE(priv, driver_flags); Adapter->IntCounter = 0; OS_INT_RESTORE(priv, driver_flags); if (sbi_get_int_status(priv, &ireg)) { PRINTM(ERROR, "main-thread: reading HOST_INT_STATUS_REG failed\n"); continue; } /* If we have a valid interrupt then we have something to do, so we are not running in a dead loop */ if (ireg) Adapter->main_thread_loops = 0; OS_INT_DISABLE(priv, driver_flags); Adapter->HisRegCpy |= ireg; OS_INT_RESTORE(priv, driver_flags); PRINTM(INTR, "INT: status = 0x%x\n", Adapter->HisRegCpy); } else if (Adapter->bWakeupDevRequired) { Adapter->WakeupTries++; PRINTM(CMND, "Wakeup device... WakeupReq=%s Conn=%s PS_Mode=%d PS_State=%d @ %lu\n", (Adapter->bWakeupDevRequired) ? "Y" : "N", (priv->adapter->MediaConnectStatus) ? "Y" : "N", priv->adapter->PSMode, priv->adapter->PSState, os_time_get()); /* Wake up device */ if (sbi_exit_deep_sleep(priv)) PRINTM(MSG, "main-thread: wakeup device failed\n"); continue; } /* Command response? */ if (Adapter->HisRegCpy & HIS_CmdUpLdRdy) { OS_INT_DISABLE(priv, driver_flags); Adapter->HisRegCpy &= ~HIS_CmdUpLdRdy; OS_INT_RESTORE(priv, driver_flags); wlan_process_cmdresp(priv); } /* Any Card Event */ if (Adapter->HisRegCpy & HIS_CardEvent) { OS_INT_DISABLE(priv, driver_flags); Adapter->HisRegCpy &= ~HIS_CardEvent; OS_INT_RESTORE(priv, driver_flags); wlan_process_event(priv); } /* Check if we need to confirm Sleep Request received previously */ if (Adapter->PSState == PS_STATE_PRE_SLEEP) { if (!priv->wlan_dev.cmd_sent && !Adapter->CurCmd) { ASSERT(Adapter->MediaConnectStatus == WlanMediaStateConnected); wlan_ps_cond_check(priv, (u16) Adapter->PSMode); } } /* The PS state is changed during processing of Sleep Request event above */ if ((Adapter->PSState == PS_STATE_SLEEP) || (Adapter->PSState == PS_STATE_PRE_SLEEP)) continue; if (Adapter->IsDeepSleep) continue; /* The HS_Activated flag is changed during processing of HS_Activate command resp */ /* We cannot send command or data if HS_Activated and WakeupDevRequired are TRUE */ if (Adapter->HS_Activated && Adapter->bWakeupDevRequired) { PRINTM(INFO, "main-thread: cannot send command or data, " "HS_Activated=%d\n", Adapter->HS_Activated); continue; } /* Execute the next command */ if (!priv->wlan_dev.cmd_sent && !Adapter->CurCmd) wlan_exec_next_cmd(priv); if (!priv->wlan_dev.data_sent && !wmm_lists_empty(priv) && !wmm_is_queue_stopped(priv)) { if ((Adapter->PSState == PS_STATE_FULL_POWER) || (Adapter->sleep_period.period == 0) || (Adapter->TxLockFlag == FALSE)) wmm_process_tx(priv); } } wlan_deactivate_thread(thread); LEAVE(); return WLAN_STATUS_SUCCESS; }
/** * @brief This function hanldes the major job in WLAN driver. * it handles the event generated by firmware, rx data received * from firmware and tx data sent from kernel. * * @param data A pointer to wlan_thread structure * @return WLAN_STATUS_SUCCESS */ static void wlan_service_main_thread(cyg_addrword_t data) { struct eth_drv_sc *sc = (struct eth_drv_sc *)data; wlan_private *priv = (wlan_private *)sc->driver_private; w99702_priv_t * priv702 = priv->priv; wlan_thread *thread = &priv->MainThread; wlan_adapter *Adapter = priv->adapter; //wait_queue_t wait; cyg_uint8 ireg = 0; int volatile save_irq; int x; int ret; //OS_INTERRUPT_SAVE_AREA; ENTER(); wlan_activate_thread(thread); thread_stop_ptr[0] = NULL; //init_waitqueue_entry(&wait, current); for (;;) { #if 0 diag_printf("main-thread 111: IntCounter=%d " "CurCmd=%p CmdPending=%s Connect=%d " "dnld_sent=%d\n", Adapter->IntCounter, Adapter->CurCmd, list_empty(&Adapter->CmdPendingQ) ? "N" : "Y", Adapter->MediaConnectStatus, /*Adapter->CurrentTxSkb,*/ priv->wlan_dev.dnld_sent); #endif //add_wait_queue(&thread->waitQ, &wait); //OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE); TX_DISABLE; if ((Adapter->WakeupTries) || (Adapter->PSState == PS_STATE_SLEEP && !Adapter->bWakeupDevRequired) || (!Adapter->IntCounter && (priv->wlan_dev.dnld_sent || !Adapter->wmm.enabled || Adapter->TxLockFlag /*|| !os_queue_is_active(priv)*/ || wmm_lists_empty(priv)) && (priv->wlan_dev.dnld_sent || Adapter->TxLockFlag || !Adapter->TxSkbNum) && (priv->wlan_dev.dnld_sent || Adapter->CurCmd || list_empty(&Adapter->CmdPendingQ)) ) ) { #if 0 diag_printf( "main-thread sleeping... Conn=%d IntC=%d PS_Mode=%d PS_State=%d\n", Adapter->MediaConnectStatus, Adapter->IntCounter, Adapter->PSMode, Adapter->PSState); #endif #ifdef _MAINSTONE MST_LEDDAT1 = get_utimeofday(); #endif TX_RESTORE; //schedule(); /* Lock control thread to avoid re-entry when waiting event. ??? */ //cyg_mutex_lock(&thread->waitQ_mutex); //diag_printf("main_thread wait\n"); /* Waitint until any event input */ x = cyg_flag_wait( &thread->waitQ_flag_q, -1, CYG_FLAG_WAITMODE_OR | CYG_FLAG_WAITMODE_CLR ); //diag_printf("main_thread wakeup %d\n", Adapter->IntCounter); /* ----------if keypad pressed then print message----------------- */ //if ( 2 & x ) } else { TX_RESTORE; } #if 0 diag_printf( "main-thread 222 (waking up): IntCounter=%d " "dnld_sent=%d\n", Adapter->IntCounter, /*Adapter->CurrentTxSkb,*/ priv->wlan_dev.dnld_sent); //OS_SET_THREAD_STATE(TASK_RUNNING); //remove_wait_queue(&thread->waitQ, &wait); diag_printf("main-thread 333: IntCounter=%d "//CurrentTxSkb=%p "dnld_sent=%d g_NeedWakeupMainThread = %d\n", Adapter->IntCounter, /*Adapter->CurrentTxSkb,*/ priv->wlan_dev.dnld_sent, g_WakeupMainThreadStatus); #endif if (thread_should_stop() || Adapter->SurpriseRemoved) { diag_printf( "main-thread: break from main thread: SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved); break; } //OS_INT_DISABLE(save_irq); if(Adapter->IntCounter) { Adapter->IntCounter = 0; if ((ret = sbi_get_int_status(sc, &ireg)) < 0) { diag_printf("main-thread: reading HOST_INT_STATUS_REG failed\n"); //OS_INT_RESTORE(save_irq); continue; } OS_INT_DISABLE(save_irq); Adapter->HisRegCpy |= ireg; OS_INT_RESTORE(save_irq); } //else if (Adapter->bWakeupDevRequired && ((Adapter->PSState == PS_STATE_SLEEP))) else if (Adapter->bWakeupDevRequired && Adapter->HS_Activated) //JONO { //OS_INT_RESTORE(save_irq); Adapter->WakeupTries++; /* we borrow deep_sleep wakeup code for time being */ if (sbi_exit_deep_sleep(priv)) diag_printf("main-thread: wakeup dev failed\n"); continue; } //else OS_INT_RESTORE(save_irq); #if 0 diag_printf("main-thread 444: IntCounter=%d "// CurrentTxSkb=%p "dnld_sent=%d TxSkbNum=%d\n", Adapter->IntCounter, /*Adapter->CurrentTxSkb,*/ priv->wlan_dev.dnld_sent, Adapter->TxSkbNum); diag_printf("Adapter->HisRegCpy = %x, %d, %d, %d\n", Adapter->HisRegCpy, priv->wlan_dev.dnld_sent, Adapter->TxLockFlag, priv->open); #endif /* Command response? */ if (Adapter->HisRegCpy & HIS_CmdUpLdRdy) { //diag_printf("main-thread: Cmd response ready.\n"); OS_INT_DISABLE(save_irq); Adapter->HisRegCpy &= ~HIS_CmdUpLdRdy; OS_INT_RESTORE(save_irq); wlan_process_rx_command(priv); } /* Any received data? */ #if 1 if (Adapter->HisRegCpy & HIS_RxUpLdRdy) { //diag_printf("main-thread: Rx Packet ready.\n"); OS_INT_DISABLE(save_irq); Adapter->HisRegCpy &= ~HIS_RxUpLdRdy; OS_INT_RESTORE(save_irq); //wlan_send_rxskbQ(priv); if((priv702->rx_head != priv702->rx_tail) || !priv702->rx_head->mode) eth_drv_dsr(0, 0, (cyg_addrword_t)sc); } else OS_INT_RESTORE(save_irq); #endif /* Any Card Event */ if (Adapter->HisRegCpy & HIS_CardEvent) { //diag_printf("main-thread: Card Event Activity.\n"); OS_INT_DISABLE(save_irq); Adapter->HisRegCpy &= ~HIS_CardEvent; OS_INT_RESTORE(save_irq); if (sbi_read_event_cause(priv)) { diag_printf("main-thread: sbi_read_event_cause failed.\n"); continue; } wlan_process_event(priv); } /* Check if we need to confirm Sleep Request received previously */ if (Adapter->PSState == PS_STATE_PRE_SLEEP) { if (!priv->wlan_dev.dnld_sent && !Adapter->CurCmd) { if (Adapter->MediaConnectStatus == WlanMediaStateConnected) { diag_printf( "main_thread: PRE_SLEEP--IntCounter=%d "// CurrentTxSkb=%p "dnld_sent=%d CurCmd=%p, confirm now\n", Adapter->IntCounter, /*Adapter->CurrentTxSkb,*/ priv->wlan_dev.dnld_sent, Adapter->CurCmd); PSConfirmSleep(priv, (cyg_uint16) Adapter->PSMode); } else { /* workaround for firmware sending deauth/linkloss event immediately after sleep request, remove this after firmware fixes it */ Adapter->PSState = PS_STATE_AWAKE; diag_printf( "main-thread: ignore PS_SleepConfirm in non-connected state\n"); } } } /* The PS state is changed during processing of Sleep Request event above */ if ((priv->adapter->PSState == PS_STATE_SLEEP) || (priv->adapter->PSState == PS_STATE_PRE_SLEEP) ) { diag_printf("999 The PS state is changed during processing ... %d\n", priv->adapter->PSState); continue; //JONO } if (Adapter->HS_Activated && Adapter->bWakeupDevRequired) { //JONO diag_printf( "main-thread: cannot send command or date, HS_Activated=%d\n", Adapter->HS_Activated); //JONO continue; } /* Execute the next command */ if (!priv->wlan_dev.dnld_sent && !Adapter->CurCmd) { ExecuteNextCommand(priv); } if (Adapter->wmm.enabled) { if (!wmm_lists_empty(priv) && (priv->open == TRUE)/* && os_queue_is_active(priv)*/) { if ((Adapter->PSState == PS_STATE_FULL_POWER) || (Adapter->sleep_period.period == 0) || (Adapter->TxLockFlag == FALSE)) //wmm_process_tx(priv); handle_send(sc); } } else { if (!priv->wlan_dev.dnld_sent && (Adapter->TxLockFlag == false) &&(priv->open == TRUE) /*&& !list_empty((struct list_head *) &priv->adapter->TxSkbQ)*/) { //wlan_process_txqueue(priv); //diag_printf("send01\n"); handle_send(sc); //diag_printf("send02\n"); } } } wlan_deactivate_thread(thread); LEAVE(); return ;//WLAN_STATUS_SUCCESS; }