diff options
Diffstat (limited to 'drivers/net/wireless/rda/rda_wlan/wlan_event.c')
-rwxr-xr-x | drivers/net/wireless/rda/rda_wlan/wlan_event.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/drivers/net/wireless/rda/rda_wlan/wlan_event.c b/drivers/net/wireless/rda/rda_wlan/wlan_event.c new file mode 100755 index 00000000..2bda586b --- /dev/null +++ b/drivers/net/wireless/rda/rda_wlan/wlan_event.c @@ -0,0 +1,227 @@ +#include "wlan_includes.h" + +void wlan_push_event(wlan_private * priv, wlan_event_type type, void* para, u8 front) +{ + wlan_event *event = NULL; + ENTER(); + + event = kzalloc(sizeof(wlan_event), GFP_KERNEL); + if (event) + event->EventType = type; + else { + WLAN_ERRP("kzalloc wlan_event memory failed\n"); + return; + } + + event->Para = para; + + spin_lock(&priv->EventLock); + if(front) + list_add(&event->list, &priv->EventQueue); + else + list_add_tail(&event->list, &priv->EventQueue); + priv->EventQuNum ++; + spin_unlock(&priv->EventLock); + + complete(&priv->EventThread.comp); + + LEAVE(); +} + +wlan_event* wlan_pull_event(wlan_private * priv) +{ + wlan_event* event; + + ENTER(); + spin_lock(&priv->EventLock); + if (list_empty(&priv->EventQueue)) { + spin_unlock(&priv->EventLock); + return NULL; + } + event = (wlan_event*)priv->EventQueue.next; + list_del(&event->list); + priv->EventQuNum --; + spin_unlock(&priv->EventLock); + LEAVE(); + return event; +} + +void wlan_timer_handler(unsigned long fcontext) +{ + PWLAN_DRV_TIMER timer = (PWLAN_DRV_TIMER) fcontext; + + if(timer->timer_function) + timer->timer_function(timer->function_context); + else { + wlan_push_event((wlan_private *) timer->function_context, timer->EventType, timer->function_context, TRUE); + } + + if (timer->timer_is_periodic == TRUE) { + mod_timer(&timer->tl, jiffies + ((timer->time_period * HZ) / 1000)); + } else + timer->timer_is_canceled = TRUE; +} + + +void wlan_mac_status(wlan_private *priv, + char *wid_status, unsigned short wid_status_len) +{ + char mac_status; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_DEBUG, "%s >>>\n", __func__); + +#ifdef WLAN_FORCE_SUSPEND_SUPPORT + if (priv->CardInSuspend == TRUE) { + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "%s ingnored in ap deep sleep mode.\n", __func__); + return; + } +#endif + mac_status = wid_status[7]; + + if (mac_status == MAC_CONNECTED) { + + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_CRIT, "MAC CONNECTED\n"); + + priv->connect_status = MAC_CONNECTED; + netif_carrier_on(priv->netDev); + netif_wake_queue(priv->netDev); + + wlan_cancel_timer(&priv->ReAssociationTimeOut); + //report connect to supper layer + wlan_indicate_connected(priv); + { + wlan_push_event(priv, WLAN_EVENT_SET_PHY_ERR_INT, priv, FALSE); + } + wake_lock_timeout(&priv->MacStatusLock, 6 * HZ); + } else if (mac_status == MAC_DISCONNECTED) { + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_CRIT, "MAC_DISCONNECTED\n"); + + wlan_cancel_timer(&priv->ReAssociationTimeOut); + //for wep we should toggler from open to shared if auth failed + if(priv->ToggalAssociation){ + wlan_re_assocication(priv); + }else{ + wlan_cancel_timer(&priv->AssociationTimeOut); + + priv->connect_status = MAC_DISCONNECTED; + priv->assoc_ongoing = FALSE; + netif_stop_queue(priv->netDev); + netif_carrier_off(priv->netDev); + + //report disconnect to supper layer + if(!priv->IgnoreFisrtDisconnect){ + wlan_indicate_disconnected(priv); + + wake_lock_timeout(&priv->MacStatusLock, 6*HZ); + }else{ + priv->IgnoreFisrtDisconnect = FALSE; + } + } + } else { + WLAN_ERRP("Invalid MAC Status 0x%02x\n", mac_status); + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_DEBUG, "%s <<<\n", __func__); +} + +void wlan_start_netif(wlan_private* priv) +{ + netif_wake_queue(priv->netDev); +} +void wlan_process_event(wlan_private * priv) +{ + int ret=0; + wlan_event *event = NULL; + + event = wlan_pull_event(priv); + if (!event) + return; + + WLAN_DBGLAP(WLAN_DA_MAIN, WLAN_DL_TRACE, "type :%d \n", event->EventType); + + switch(event->EventType){ + case WLAN_EVENT_SCAN_RESULT_TIMEOUT: + wlan_report_scan_result(priv); + break; + + case WLAN_EVENT_START_ASSOC: + wlan_assocication(priv); + break; + + case WLAN_EVENT_ASSOC_TIMEOUT: + wlan_assocication_timeout(priv); + break; + + case WLAN_EVENT_REASSOC_TIMEOUT: + wlan_re_assocication(priv); + break; + + case WLAN_EVENT_CARD_TO_SLEEP: + handle_card_to_sleep_cmd(priv); + break; + + case WLAN_EVENT_CARD_CONTROL_INIT: + ret=wlan_card_control_init(priv); + if (ret) { + WLAN_ERRP("Wlan Card Control Init Failed! \n"); + } else { + WLAN_DBGLAP(WLAN_DA_MAIN, WLAN_DL_CRIT, "Wlan Card Control Init Success, Chip Version:%d \n", priv->version); + } + + break; + case WLAN_EVENT_CHECK_SDIO: + wlan_card_check_sdio(priv); + break; + + case WLAN_EVENT_START_NETIF: + wlan_start_netif(priv); + break; + + case WLAN_EVENT_SET_PHY_ERR_INT: + wlan_set_phy_timeout(priv); + break; + + case WLAN_EVENT_START_SCAN: + wlan_set_scan_by_driver(priv); + break; + default: + break; + } + + kfree(event); +} + + +int wlan_event_thread(void *data) +{ + wlan_thread *thread = (wlan_thread *)data; + wlan_private *priv = thread->priv; + + ENTER(); + + wlan_activate_thread(thread); + + current->flags |= PF_NOFREEZE; + + while(1){ + + wait_for_completion_interruptible(&thread->comp); + + if (kthread_should_stop()){ + WLAN_DBGLAP(WLAN_DA_MAIN, WLAN_DL_CRIT,"wlan_event_thread: break from main thread \n"); + break; + } + + if(priv->CardRemoved){ + break; + } + + wlan_process_event(priv); + } + wlan_deactivate_thread(thread); + + LEAVE(); + return 0; +} + |