summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rda/rda_wlan/wlan_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rda/rda_wlan/wlan_event.c')
-rwxr-xr-xdrivers/net/wireless/rda/rda_wlan/wlan_event.c227
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;
+}
+