/** * @brief This function frees the structure of priv * * @param pmpriv A pointer to mlan_private structure * * @return N/A */ t_void wlan_free_priv(mlan_private * pmpriv) { wlan_clean_txrx(pmpriv); wlan_delete_bsspriotbl(pmpriv); #ifdef STA_SUPPORT wlan_free_curr_bcn(pmpriv); #endif /* STA_SUPPORT */ wlan_delete_station_list(pmpriv); }
/** * @brief This function closes the network device * * @param dev A pointer to net_device structure * @return WLAN_STATUS_SUCCESS */ static int wlan_close(struct net_device *dev) { wlan_private *priv = (wlan_private *) netdev_priv(dev); ENTER(); if (priv->adapter) wlan_clean_txrx(priv); MODULE_PUT; priv->open = FALSE; LEAVE(); return WLAN_STATUS_SUCCESS; }
/** * @brief This function handles disconnect event, reports disconnect * to upper layer, cleans tx/rx packets, * resets link state etc. * * @param priv A pointer to mlan_private structure * * @return N/A */ t_void wlan_reset_connect_state(pmlan_private priv) { mlan_adapter *pmadapter = priv->adapter; mlan_status ret = MLAN_STATUS_SUCCESS; state_11d_t enable; ENTER(); if (priv->media_connected != MTRUE) { LEAVE(); return; } PRINTM(MINFO, "Handles disconnect event.\n"); priv->media_connected = MFALSE; if (priv->port_ctrl_mode == MTRUE) { /* Close the port on Disconnect */ PRINTM(MINFO, "DISC: port_status = CLOSED\n"); priv->port_open = MFALSE; } priv->scan_block = MFALSE; /* Free Tx and Rx packets, report disconnect to upper layer */ wlan_clean_txrx(priv); /* Reset SNR/NF/RSSI values */ priv->data_rssi_last = 0; priv->data_nf_last = 0; priv->data_rssi_avg = 0; priv->data_nf_avg = 0; priv->bcn_rssi_last = 0; priv->bcn_nf_last = 0; priv->bcn_rssi_avg = 0; priv->bcn_nf_avg = 0; priv->rxpd_rate = 0; priv->rxpd_htinfo = 0; priv->sec_info.ewpa_enabled = MFALSE; priv->sec_info.wpa_enabled = MFALSE; priv->sec_info.wpa2_enabled = MFALSE; priv->wpa_ie_len = 0; priv->sec_info.wapi_enabled = MFALSE; priv->wapi_ie_len = 0; priv->sec_info.wapi_key_on = MFALSE; priv->sec_info.encryption_mode = MLAN_ENCRYPTION_MODE_NONE; /* Enable auto data rate */ priv->is_data_rate_auto = MTRUE; priv->data_rate = 0; if (priv->bss_mode == MLAN_BSS_MODE_IBSS) { priv->adhoc_state = ADHOC_IDLE; priv->adhoc_is_link_sensed = MFALSE; priv->adhoc_auto_sel = MTRUE; } /* * Memorize the previous SSID and BSSID so * it could be used for re-assoc */ PRINTM(MINFO, "Previous SSID=%s, SSID Length=%u\n", priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); PRINTM(MINFO, "Current SSID=%s, SSID Length=%u\n", priv->curr_bss_params.bss_descriptor.ssid.ssid, priv->curr_bss_params.bss_descriptor.ssid.ssid_len); memcpy(pmadapter, &priv->prev_ssid, &priv->curr_bss_params.bss_descriptor.ssid, sizeof(mlan_802_11_ssid)); memcpy(pmadapter, priv->prev_bssid, priv->curr_bss_params.bss_descriptor.mac_address, MLAN_MAC_ADDR_LENGTH); /* Need to erase the current SSID and BSSID info */ memset(pmadapter, &priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params)); pmadapter->tx_lock_flag = MFALSE; pmadapter->pps_uapsd_mode = MFALSE; if ((wlan_11d_get_state(priv) == ENABLE_11D) && (pmadapter->state_11d.user_enable_11d == DISABLE_11D)) { pmadapter->state_11d.enable_11d = DISABLE_11D; enable = DISABLE_11D; /* Send cmd to FW to enable/disable 11D function */ ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, HostCmd_ACT_GEN_SET, Dot11D_i, MNULL, &enable); if (ret) PRINTM(MERROR, "11D: Failed to enable 11D\n"); } if (pmadapter->num_cmd_timeout && pmadapter->curr_cmd && (pmadapter->cmd_timer_is_set == MFALSE)) { LEAVE(); return; } wlan_recv_event(priv, MLAN_EVENT_ID_FW_DISCONNECTED, MNULL); LEAVE(); }
/** * @brief This function handles events generated by firmware * * @param priv A pointer to mlan_private structure * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status mlan_process_sta_event(IN t_void * priv) { pmlan_private pmpriv = (pmlan_private) priv; pmlan_adapter pmadapter = pmpriv->adapter; mlan_status ret = MLAN_STATUS_SUCCESS; t_u32 eventcause = pmadapter->event_cause; t_u8 event_buf[100]; t_u8 *evt_buf = MNULL; pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event; mlan_event *pevent = (mlan_event *) event_buf; ENTER(); if (pmbuf) memcpy(pmadapter, pmbuf->pbuf + pmbuf->data_offset, (t_u8 *) & eventcause, sizeof(eventcause)); switch (eventcause) { case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: PRINTM(MERROR, "Invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignoring it\n"); break; case EVENT_LINK_SENSED: PRINTM(MEVENT, "EVENT: LINK_SENSED\n"); pmpriv->adhoc_is_link_sensed = MTRUE; wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED, MNULL); break; case EVENT_DEAUTHENTICATED: PRINTM(MEVENT, "EVENT: Deauthenticated\n"); pmadapter->dbg.num_event_deauth++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_DISASSOCIATED: PRINTM(MEVENT, "EVENT: Disassociated\n"); pmadapter->dbg.num_event_disassoc++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_LINK_LOST: PRINTM(MEVENT, "EVENT: Link lost\n"); pmadapter->dbg.num_event_link_lost++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_PS_SLEEP: PRINTM(MINFO, "EVENT: SLEEP\n"); PRINTM(MEVENT, "_"); /* Handle unexpected PS SLEEP event */ if (pmadapter->ps_state == PS_STATE_SLEEP_CFM) break; pmadapter->ps_state = PS_STATE_PRE_SLEEP; wlan_check_ps_cond(pmadapter); break; case EVENT_PS_AWAKE: PRINTM(MINFO, "EVENT: AWAKE \n"); PRINTM(MEVENT, "|"); if (!pmadapter->pps_uapsd_mode && pmpriv->media_connected && pmadapter->sleep_period.period) { pmadapter->pps_uapsd_mode = MTRUE; PRINTM(MEVENT, "PPS/UAPSD mode activated\n"); } /* Handle unexpected PS AWAKE event */ if (pmadapter->ps_state == PS_STATE_SLEEP_CFM) break; pmadapter->tx_lock_flag = MFALSE; if (pmadapter->pps_uapsd_mode && pmadapter->gen_null_pkt) { if (MTRUE == wlan_check_last_packet_indication(pmpriv)) { if (!pmadapter->data_sent) { if (wlan_send_null_packet(pmpriv, MRVDRV_TxPD_POWER_MGMT_NULL_PACKET | MRVDRV_TxPD_POWER_MGMT_LAST_PACKET) == MLAN_STATUS_SUCCESS) { return MLAN_STATUS_SUCCESS; } } } } pmadapter->ps_state = PS_STATE_AWAKE; pmadapter->pm_wakeup_card_req = MFALSE; pmadapter->pm_wakeup_fw_try = MFALSE; break; case EVENT_HS_ACT_REQ: PRINTM(MEVENT, "EVENT: HS_ACT_REQ\n"); ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, 0, 0, MNULL, MNULL); break; case EVENT_MIC_ERR_UNICAST: PRINTM(MEVENT, "EVENT: UNICAST MIC ERROR\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_UNI, MNULL); break; case EVENT_MIC_ERR_MULTICAST: PRINTM(MEVENT, "EVENT: MULTICAST MIC ERROR\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_MUL, MNULL); break; case EVENT_MIB_CHANGED: case EVENT_INIT_DONE: break; case EVENT_ADHOC_BCN_LOST: PRINTM(MEVENT, "EVENT: ADHOC_BCN_LOST\n"); pmpriv->adhoc_is_link_sensed = MFALSE; wlan_clean_txrx(pmpriv); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_LOST, MNULL); break; case EVENT_BG_SCAN_REPORT: PRINTM(MEVENT, "EVENT: BGS_REPORT\n"); /* Clear the previous scan result */ memset(pmadapter, pmadapter->pscan_table, 0x00, sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST); pmadapter->num_in_scan_table = 0; pmadapter->pbcn_buf_end = pmadapter->bcn_buf; ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_BG_SCAN_QUERY, HostCmd_ACT_GEN_GET, 0, MNULL, MNULL); break; case EVENT_PORT_RELEASE: PRINTM(MEVENT, "EVENT: PORT RELEASE\n"); /* Open the port for e-supp mode */ if (pmpriv->port_ctrl_mode == MTRUE) { PRINTM(MINFO, "PORT_REL: port_status = OPEN\n"); pmpriv->port_open = MTRUE; } pmpriv->scan_block = MFALSE; wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PORT_RELEASE, MNULL); break; case EVENT_STOP_TX: PRINTM(MEVENT, "EVENT: Stop Tx (%#x)\n", eventcause); wlan_11h_tx_disable(pmpriv); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_STOP_TX, MNULL); break; case EVENT_START_TX: PRINTM(MEVENT, "EVENT: Start Tx (%#x)\n", eventcause); wlan_11h_tx_enable(pmpriv); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_START_TX, MNULL); break; case EVENT_CHANNEL_SWITCH: PRINTM(MEVENT, "EVENT: Channel Switch (%#x)\n", eventcause); /* To be handled for 'chanswann' private command */ break; case EVENT_CHANNEL_SWITCH_ANN: PRINTM(MEVENT, "EVENT: Channel Switch Announcement\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN, MNULL); wlan_11h_handle_event_chanswann(pmpriv); break; case EVENT_MEAS_REPORT_RDY: PRINTM(MEVENT, "EVENT: Measurement Report Ready (%#x)\n", eventcause); wlan_prepare_cmd(priv, HostCmd_CMD_MEASUREMENT_REPORT, HostCmd_ACT_GEN_SET, 0, 0, MNULL); break; case EVENT_WMM_STATUS_CHANGE: if (pmbuf && pmbuf->data_len > sizeof(eventcause) + sizeof(MrvlIEtypesHeader_t)) { PRINTM(MEVENT, "EVENT: WMM status changed: %d\n", pmbuf->data_len); evt_buf = (pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause)); wlan_ret_wmm_get_status(pmpriv, evt_buf, pmbuf->data_len - sizeof(eventcause)); } else { PRINTM(MEVENT, "EVENT: WMM status changed\n"); ret = wlan_cmd_wmm_status_change(pmpriv); } break; case EVENT_RSSI_LOW: PRINTM(MEVENT, "EVENT: Beacon RSSI_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_RSSI_LOW, MNULL); break; case EVENT_SNR_LOW: PRINTM(MEVENT, "EVENT: Beacon SNR_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_LOW, MNULL); break; case EVENT_MAX_FAIL: PRINTM(MEVENT, "EVENT: MAX_FAIL\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MAX_FAIL, MNULL); break; case EVENT_RSSI_HIGH: PRINTM(MEVENT, "EVENT: Beacon RSSI_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_RSSI_HIGH, MNULL); break; case EVENT_SNR_HIGH: PRINTM(MEVENT, "EVENT: Beacon SNR_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_HIGH, MNULL); break; case EVENT_DATA_RSSI_LOW: PRINTM(MEVENT, "EVENT: Data RSSI_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_LOW, MNULL); break; case EVENT_DATA_SNR_LOW: PRINTM(MEVENT, "EVENT: Data SNR_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_LOW, MNULL); break; case EVENT_DATA_RSSI_HIGH: PRINTM(MEVENT, "EVENT: Data RSSI_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_HIGH, MNULL); break; case EVENT_DATA_SNR_HIGH: PRINTM(MEVENT, "EVENT: Data SNR_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_HIGH, MNULL); break; case EVENT_LINK_QUALITY: PRINTM(MEVENT, "EVENT: Link Quality\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_LINK_QUALITY, MNULL); break; case EVENT_PRE_BEACON_LOST: PRINTM(MEVENT, "EVENT: Pre-Beacon Lost\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PRE_BCN_LOST, MNULL); break; case EVENT_IBSS_COALESCED: PRINTM(MEVENT, "EVENT: IBSS_COALESCED\n"); ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, HostCmd_ACT_GEN_GET, 0, MNULL, MNULL); break; case EVENT_ADDBA: PRINTM(MEVENT, "EVENT: ADDBA Request\n"); wlan_prepare_cmd(pmpriv, HostCmd_CMD_11N_ADDBA_RSP, HostCmd_ACT_GEN_SET, 0, MNULL, pmadapter->event_body); break; case EVENT_DELBA: PRINTM(MEVENT, "EVENT: DELBA Request\n"); wlan_11n_delete_bastream(pmpriv, pmadapter->event_body); break; case EVENT_BA_STREAM_TIMEOUT: PRINTM(MEVENT, "EVENT: BA Stream timeout\n"); wlan_11n_ba_stream_timeout(pmpriv, (HostCmd_DS_11N_BATIMEOUT *) pmadapter-> event_body); break; case EVENT_AMSDU_AGGR_CTRL: PRINTM(MEVENT, "EVENT: AMSDU_AGGR_CTRL %d\n", *(t_u16 *) pmadapter->event_body); pmadapter->tx_buf_size = MIN(pmadapter->curr_tx_buf_size, wlan_le16_to_cpu(*(t_u16 *) pmadapter->event_body)); PRINTM(MEVENT, "tx_buf_size %d\n", pmadapter->tx_buf_size); break; case EVENT_WEP_ICV_ERR: PRINTM(MEVENT, "EVENT: WEP ICV error\n"); pevent->bss_num = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_FW_WEP_ICV_ERR; pevent->event_len = sizeof(Event_WEP_ICV_ERR); memcpy(pmadapter, (t_u8 *) pevent->event_buf, pmadapter->event_body, pevent->event_len); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_WEP_ICV_ERR, pevent); break; case EVENT_BW_CHANGE: PRINTM(MEVENT, "EVENT: BW Change\n"); pevent->bss_num = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_FW_BW_CHANGED; pevent->event_len = sizeof(t_u8); /* Copy event body from the event buffer */ memcpy(pmadapter, (t_u8 *) pevent->event_buf, pmadapter->event_body, pevent->event_len); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BW_CHANGED, pevent); break; default: PRINTM(MEVENT, "EVENT: unknown event id: %#x\n", eventcause); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_UNKNOWN, MNULL); break; } LEAVE(); return ret; }
/** * @brief This function adds the card. it will probe the * card, allocate the wlan_priv and initialize the device. * * @param card A pointer to card * @return A pointer to wlan_private structure */ wlan_private * wlan_add_card(void *card) { struct net_device *dev = NULL; wlan_private *priv = NULL; ENTER(); if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) goto exit_sem_err; /* Allocate an Ethernet device and register it */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) if (!(dev = init_etherdev(dev, sizeof(wlan_private)))) { #else if (!(dev = alloc_etherdev(sizeof(wlan_private)))) { #endif PRINTM(MSG, "Init ethernet device failed!\n"); goto exit_add_err; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) /* Allocate device name */ if (dev_alloc_name(dev, "mlan%d") < 0) { PRINTM(ERROR, "Could not allocate device name!\n"); goto err_kmalloc; } #endif priv = (wlan_private *) netdev_priv(dev); /* allocate buffer for wlan_adapter */ if (!(priv->adapter = kmalloc(sizeof(wlan_adapter), GFP_KERNEL))) { PRINTM(MSG, "Allocate buffer for wlan_adapter failed!\n"); goto err_kmalloc; } /* init wlan_adapter */ memset(priv->adapter, 0, sizeof(wlan_adapter)); priv->wlan_dev.netdev = dev; priv->wlan_dev.card = card; ((struct sdio_mmc_card *) card)->priv = priv; wlanpriv = priv; //XXX FB global var a virer ? #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) SET_MODULE_OWNER(dev); #endif /* Setup the OS Interface to our functions */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) dev->open = wlan_open; dev->hard_start_xmit = wlan_hard_start_xmit; dev->stop = wlan_close; dev->do_ioctl = wlan_do_ioctl; dev->set_mac_address = wlan_set_mac_address; dev->set_multicast_list = wlan_set_multicast_list; dev->tx_timeout = wlan_tx_timeout; dev->get_stats = wlan_get_stats; #else dev->netdev_ops = &wlan_netdev_ops; #endif dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT; dev->hard_header_len += sizeof(TxPD); dev->hard_header_len += SDIO_HEADER_LEN; dev->hard_header_len += HEADER_ALIGNMENT; #ifdef WIRELESS_EXT #if WIRELESS_EXT < 21 dev->get_wireless_stats = wlan_get_wireless_stats; #endif dev->wireless_handlers = (struct iw_handler_def *) &wlan_handler_def; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) dev->features |= NETIF_F_DYNALLOC; #endif dev->flags |= IFF_BROADCAST | IFF_MULTICAST; /* init SW */ if (wlan_init_sw(priv)) { PRINTM(FATAL, "Software Init Failed\n"); goto err_kmalloc; } PRINTM(INFO, "Starting kthread...\n"); priv->MainThread.priv = priv; wlan_create_thread(wlan_service_main_thread, &priv->MainThread, "wlan_main_service"); ConfigureThreadPriority(); #ifdef REASSOCIATION priv->ReassocThread.priv = priv; wlan_create_thread(wlan_reassociation_thread, &priv->ReassocThread, "wlan_reassoc_service"); #endif /* REASSOCIATION */ while ((priv->MainThread.pid == 0) #ifdef REASSOCIATION || (priv->ReassocThread.pid == 0) #endif ) { os_sched_timeout(2); } /* * Register the device. Fill up the private data structure with * relevant information from the card and request for the required * IRQ. */ if (sbi_register_dev(priv) < 0) { PRINTM(FATAL, "Failed to register wlan device!\n"); goto err_registerdev; } SET_NETDEV_DEV(dev, priv->hotplug_device); /* init FW and HW */ if (wlan_init_fw(priv)) { PRINTM(FATAL, "Firmware Init Failed\n"); goto err_init_fw; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) SET_NETDEV_DEVTYPE(dev, &wlan_type); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) if (register_netdev(dev)) { printk(KERN_ERR "Cannot register network device!\n"); goto err_init_fw; } #endif os_carrier_off(priv); os_stop_queue(priv); PRINTM(INFO, "%s: WLAN 802.11 Adapter revision 0x%02X\n", dev->name, priv->adapter->chip_rev); #ifdef CONFIG_PROC_FS wlan_proc_entry(priv, dev); #ifdef PROC_DEBUG wlan_debug_entry(priv, dev); #endif #endif /* CONFIG_PROC_FS */ OS_REL_SEMAPHORE(&AddRemoveCardSem); LEAVE(); return priv; err_init_fw: sbi_unregister_dev(priv); err_registerdev: priv->adapter->SurpriseRemoved = TRUE; if (priv->MainThread.pid) { /* Stop the thread servicing the interrupts */ wake_up_interruptible(&priv->MainThread.waitQ); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) wlan_terminate_thread(&priv->MainThread); #endif } #ifdef REASSOCIATION if (priv->ReassocThread.pid) { wake_up_interruptible(&priv->ReassocThread.waitQ); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) wlan_terminate_thread(&priv->ReassocThread); #endif } #endif /* REASSOCIATION */ /* waiting for main thread quit */ while (priv->MainThread.pid #ifdef REASSOCIATION || priv->ReassocThread.pid #endif ) { os_sched_timeout(2); } err_kmalloc: if (dev->reg_state == NETREG_REGISTERED) unregister_netdev(dev); wlan_free_adapter(priv); priv->wlan_dev.netdev = NULL; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) free_netdev(dev); #endif ((struct sdio_mmc_card *) card)->priv = NULL; wlanpriv = NULL; exit_add_err: OS_REL_SEMAPHORE(&AddRemoveCardSem); exit_sem_err: LEAVE(); return NULL; } /** * @brief This function removes the card. * * @param card A pointer to card * @return WLAN_STATUS_SUCCESS */ int wlan_remove_card(void *card) { wlan_private *priv = ((struct sdio_mmc_card *) card)->priv; wlan_adapter *Adapter = NULL; struct net_device *dev; union iwreq_data wrqu; ENTER(); if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) goto exit_sem_err; if (!priv || !(Adapter = priv->adapter)) goto exit_remove; Adapter->SurpriseRemoved = TRUE; #ifdef REASSOCIATION if (Adapter->ReassocTimerIsSet == TRUE) { wlan_cancel_timer(&Adapter->MrvDrvTimer); Adapter->ReassocTimerIsSet = FALSE; } #endif if (Adapter->MediaConnectStatus == WlanMediaStateConnected) { Adapter->MediaConnectStatus = WlanMediaStateDisconnected; memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); wlan_clean_txrx(priv); } /* Release all pending commands */ wlan_clear_pending_cmd(priv); dev = priv->wlan_dev.netdev; /* Last reference is our one */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) PRINTM(INFO, "refcnt = %d\n", atomic_read(&dev->refcnt)); #else PRINTM(INFO, "refcnt = %d\n", netdev_refcnt_read(dev)); #endif PRINTM(INFO, "netdev_finish_unregister: %s\n", dev->name); if (dev->reg_state == NETREG_REGISTERED) unregister_netdev(dev); PRINTM(INFO, "Unregister finish\n"); if (priv->MainThread.pid) { /* Stop the thread servicing the interrupts */ wake_up_interruptible(&priv->MainThread.waitQ); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) wlan_terminate_thread(&priv->MainThread); #endif } #ifdef REASSOCIATION if (priv->ReassocThread.pid) { wake_up_interruptible(&priv->ReassocThread.waitQ); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) wlan_terminate_thread(&priv->ReassocThread); #endif } #endif /* REASSOCIATION */ /* waiting for thread quit */ while (priv->MainThread.pid #ifdef REASSOCIATION || priv->ReassocThread.pid #endif ) { os_sched_timeout(1); } wake_up_interruptible(&Adapter->HS_wait_q); if (Adapter->IsDeepSleep == TRUE) { Adapter->IsDeepSleep = FALSE; wake_up_interruptible(&Adapter->ds_awake_q); } #ifdef CONFIG_PROC_FS #ifdef PROC_DEBUG wlan_debug_remove(priv); #endif wlan_proc_remove(priv); #endif PRINTM(INFO, "unregister device\n"); sbi_unregister_dev(priv); PRINTM(INFO, "Free Adapter\n"); wlan_free_adapter(priv); priv->wlan_dev.netdev = NULL; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) free_netdev(dev); #endif wlanpriv = NULL; exit_remove: OS_REL_SEMAPHORE(&AddRemoveCardSem); exit_sem_err: LEAVE(); return WLAN_STATUS_SUCCESS; }
/** * @brief Shutdown firmware * * @param pmlan_adapter A pointer to mlan_adapter structure * * @return MLAN_STATUS_SUCCESS * The firmware shutdown call succeeded. * MLAN_STATUS_PENDING * The firmware shutdown call is pending. * MLAN_STATUS_FAILURE * The firmware shutdown call failed. */ mlan_status mlan_shutdown_fw(IN t_void * pmlan_adapter) { mlan_status ret = MLAN_STATUS_PENDING; mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter; mlan_private *priv = MNULL; pmlan_callbacks pcb; t_s32 i = 0; ENTER(); MASSERT(pmlan_adapter); /* mlan already shutdown */ if (pmadapter->hw_status == WlanHardwareStatusNotReady) return MLAN_STATUS_SUCCESS; pmadapter->hw_status = WlanHardwareStatusClosing; /* wait for mlan_process to complete */ if (pmadapter->mlan_processing) { PRINTM(MWARN, "mlan main processing is still running\n"); return ret; } /* shut down mlan */ PRINTM(MINFO, "Shutdown mlan...\n"); pcb = &pmadapter->callbacks; /* Clean up Tx/Rx queues and delete BSS priority table */ for (i = 0; i < MLAN_MAX_BSS_NUM; i++) { if (pmadapter->priv[i]) { priv = pmadapter->priv[i]; wlan_clean_txrx(priv); wlan_wmm_cleanup_node(priv); pcb->moal_free_lock(pmadapter->pmoal_handle, priv->rx_pkt_lock); wlan_delete_bsspriotbl(priv); pcb->moal_free_lock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock); #ifdef UAP_SUPPORT if (priv->bss_type == MLAN_BSS_TYPE_UAP) { wlan_delete_station_list(priv); util_free_list_head((t_void *) pmadapter->pmoal_handle, &priv->sta_list, priv->adapter->callbacks.moal_free_lock); } #endif /* UAP_SUPPORT */ } } for (i = 0; i < MLAN_MAX_BSS_NUM; i++) util_free_list_head((t_void *) pmadapter->pmoal_handle, &pmadapter->bssprio_tbl[i].bssprio_head, pcb->moal_free_lock); if (pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->pmlan_lock) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto exit_shutdown_fw; } /* Free adapter structure */ wlan_free_adapter(pmadapter); if (pcb->moal_spin_unlock(pmadapter->pmoal_handle, pmadapter->pmlan_lock) != MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; goto exit_shutdown_fw; } /* Notify completion */ ret = wlan_shutdown_fw_complete(pmadapter); exit_shutdown_fw: LEAVE(); return ret; }
/** * @brief This function handles events generated by firmware * * @param priv A pointer to mlan_private structure * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status wlan_ops_sta_process_event(IN t_void *priv) { pmlan_private pmpriv = (pmlan_private)priv; pmlan_adapter pmadapter = pmpriv->adapter; mlan_status ret = MLAN_STATUS_SUCCESS; t_u32 eventcause = pmadapter->event_cause; t_u8 event_buf[100]; t_u8 *evt_buf = MNULL; pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event; t_u16 reason_code; pmlan_callbacks pcb = &pmadapter->callbacks; mlan_event *pevent = (mlan_event *)event_buf; ENTER(); /* Event length check */ if ((pmbuf->data_len - sizeof(eventcause)) > MAX_EVENT_SIZE) { pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID; LEAVE(); return MLAN_STATUS_FAILURE; } if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE && pmbuf->data_len > sizeof(eventcause)) DBG_HEXDUMP(MEVT_D, "EVENT", pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len); switch (eventcause) { case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: PRINTM(MERROR, "Invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignoring it\n"); break; case EVENT_LINK_SENSED: PRINTM(MEVENT, "EVENT: LINK_SENSED\n"); pmpriv->adhoc_is_link_sensed = MTRUE; wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED, MNULL); break; case EVENT_DEAUTHENTICATED: if (pmpriv->wps.session_enable) { PRINTM(MMSG, "wlan: Recevie deauth event in wps session\n"); break; } reason_code = *(t_u16 *)(pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause)); PRINTM(MMSG, "wlan: EVENT: Deauthenticated (reason 0x%x)\n", reason_code); pmadapter->dbg.num_event_deauth++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_DISASSOCIATED: if (pmpriv->wps.session_enable) { PRINTM(MMSG, "wlan: Recevie disassociate event in wps session\n"); break; } reason_code = *(t_u16 *)(pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause)); PRINTM(MMSG, "wlan: EVENT: Disassociated (reason 0x%x)\n", reason_code); pmadapter->dbg.num_event_disassoc++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_LINK_LOST: reason_code = *(t_u16 *)(pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause)); PRINTM(MMSG, "wlan: EVENT: Link lost (reason 0x%x)\n", reason_code); pmadapter->dbg.num_event_link_lost++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_PS_SLEEP: PRINTM(MINFO, "EVENT: SLEEP\n"); PRINTM(MEVENT, "_"); /* Handle unexpected PS SLEEP event */ if (pmadapter->ps_state == PS_STATE_SLEEP_CFM) break; pmadapter->ps_state = PS_STATE_PRE_SLEEP; wlan_check_ps_cond(pmadapter); break; case EVENT_PS_AWAKE: PRINTM(MINFO, "EVENT: AWAKE\n"); PRINTM(MEVENT, "|"); if (!pmadapter->pps_uapsd_mode && pmpriv->media_connected && (pmpriv->port_open || !pmpriv->port_ctrl_mode) && pmadapter->sleep_period.period) { pmadapter->pps_uapsd_mode = MTRUE; PRINTM(MEVENT, "PPS/UAPSD mode activated\n"); } /* Handle unexpected PS AWAKE event */ if (pmadapter->ps_state == PS_STATE_SLEEP_CFM) break; pmadapter->tx_lock_flag = MFALSE; if (pmadapter->pps_uapsd_mode && pmadapter->gen_null_pkt) { if (MTRUE == wlan_check_last_packet_indication(pmpriv)) { if (!pmadapter->data_sent) { if (wlan_send_null_packet(pmpriv, MRVDRV_TxPD_POWER_MGMT_NULL_PACKET | MRVDRV_TxPD_POWER_MGMT_LAST_PACKET) == MLAN_STATUS_SUCCESS) { LEAVE(); return MLAN_STATUS_SUCCESS; } } } } pmadapter->ps_state = PS_STATE_AWAKE; pmadapter->pm_wakeup_card_req = MFALSE; pmadapter->pm_wakeup_fw_try = MFALSE; break; case EVENT_HS_ACT_REQ: PRINTM(MEVENT, "EVENT: HS_ACT_REQ\n"); ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, 0, 0, MNULL, MNULL); break; case EVENT_MIC_ERR_UNICAST: PRINTM(MEVENT, "EVENT: UNICAST MIC ERROR\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_UNI, MNULL); break; case EVENT_MIC_ERR_MULTICAST: PRINTM(MEVENT, "EVENT: MULTICAST MIC ERROR\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_MUL, MNULL); break; case EVENT_MIB_CHANGED: case EVENT_INIT_DONE: break; case EVENT_ADHOC_BCN_LOST: PRINTM(MEVENT, "EVENT: ADHOC_BCN_LOST\n"); pmpriv->adhoc_is_link_sensed = MFALSE; wlan_clean_txrx(pmpriv); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_LOST, MNULL); break; case EVENT_FW_DEBUG_INFO: /* Allocate memory for event buffer */ ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, MLAN_MEM_DEF, &evt_buf); if ((ret == MLAN_STATUS_SUCCESS) && evt_buf) { pevent = (pmlan_event)evt_buf; pevent->bss_index = pmpriv->bss_index; PRINTM(MEVENT, "EVENT: FW Debug Info\n"); pevent->event_id = MLAN_EVENT_ID_FW_DEBUG_INFO; pevent->event_len = pmbuf->data_len - sizeof(eventcause); memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause), pevent->event_len); wlan_recv_event(pmpriv, pevent->event_id, pevent); pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf); } break; case EVENT_BG_SCAN_REPORT: PRINTM(MEVENT, "EVENT: BGS_REPORT\n"); pmadapter->bgscan_reported = MTRUE; wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN, MNULL); break; case EVENT_BG_SCAN_STOPPED: PRINTM(MEVENT, "EVENT: BGS_STOPPED\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN_STOPPED, MNULL); break; case EVENT_PORT_RELEASE: PRINTM(MEVENT, "EVENT: PORT RELEASE\n"); /* Open the port for e-supp mode */ if (pmpriv->port_ctrl_mode == MTRUE) { PRINTM(MINFO, "PORT_REL: port_status = OPEN\n"); pmpriv->port_open = MTRUE; } pmadapter->scan_block = MFALSE; wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PORT_RELEASE, MNULL); break; case EVENT_STOP_TX: PRINTM(MEVENT, "EVENT: Stop Tx (%#x)\n", eventcause); wlan_11h_tx_disable(pmpriv); /* this fn will send event up to MOAL */ break; case EVENT_START_TX: PRINTM(MEVENT, "EVENT: Start Tx (%#x)\n", eventcause); wlan_11h_tx_enable(pmpriv); /* this fn will send event up to MOAL */ break; case EVENT_CHANNEL_SWITCH: PRINTM(MEVENT, "EVENT: Channel Switch (%#x)\n", eventcause); /* To be handled for 'chanswann' private command */ break; case EVENT_CHANNEL_SWITCH_ANN: PRINTM(MEVENT, "EVENT: Channel Switch Announcement\n"); /* Here, pass up event first, as handling will send deauth */ wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN, MNULL); wlan_11h_handle_event_chanswann(pmpriv); break; case EVENT_RADAR_DETECTED: PRINTM(MEVENT, "EVENT: Radar Detected\n"); /* Send as passthru first, this event can cause other events */ memset(pmadapter, pevent, 0x00, sizeof(event_buf)); pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU; pevent->event_len = pmbuf->data_len; memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset, pevent->event_len); wlan_recv_event(pmpriv, pevent->event_id, pevent); if (pmadapter->state_rdh.stage == RDH_OFF) { pmadapter->state_rdh.stage = RDH_CHK_INTFS; wlan_11h_radar_detected_handling(pmadapter); } else { PRINTM(MEVENT, "Ignore Event Radar Detected - handling" " already in progress.\n"); } break; case EVENT_CHANNEL_REPORT_RDY: PRINTM(MEVENT, "EVENT: Channel Report Ready\n"); /* Allocate memory for event buffer */ ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, MLAN_MEM_DEF, &evt_buf); if ((ret == MLAN_STATUS_SUCCESS) && evt_buf) { memset(pmadapter, evt_buf, 0x00, MAX_EVENT_SIZE); /* Setup event buffer */ pevent = (pmlan_event)evt_buf; pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY; pevent->event_len = pmbuf->data_len - sizeof(eventcause); /* Copy event data */ memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause), pevent->event_len); /* Handle / pass event data */ ret = wlan_11h_handle_event_chanrpt_ready(pmpriv, pevent); /* Also send this event as passthru */ pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU; pevent->event_len = pmbuf->data_len; memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset, pevent->event_len); wlan_recv_event(pmpriv, pevent->event_id, pevent); /* Now done with buffer */ pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf); } /* Send up this Event to unblock MOAL waitqueue */ wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_MEAS_REPORT, MNULL); break; case EVENT_EXT_SCAN_REPORT: PRINTM(MEVENT, "EVENT: EXT_SCAN Report (%d)\n", pmbuf->data_len); if (pmadapter->pscan_ioctl_req && pmadapter->ext_scan) ret = wlan_handle_event_ext_scan_report(priv, pmbuf); break; case EVENT_MEAS_REPORT_RDY: PRINTM(MEVENT, "EVENT: Measurement Report Ready (%#x)\n", eventcause); ret = wlan_prepare_cmd(priv, HostCmd_CMD_MEASUREMENT_REPORT, HostCmd_ACT_GEN_SET, 0, 0, MNULL); break; case EVENT_WMM_STATUS_CHANGE: if (pmbuf && pmbuf->data_len > sizeof(eventcause) + sizeof(MrvlIEtypesHeader_t)) { PRINTM(MEVENT, "EVENT: WMM status changed: %d\n", pmbuf->data_len); evt_buf = (pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause)); wlan_ret_wmm_get_status(pmpriv, evt_buf, pmbuf->data_len - sizeof(eventcause)); } else { PRINTM(MEVENT, "EVENT: WMM status changed\n"); ret = wlan_cmd_wmm_status_change(pmpriv); } break; case EVENT_RSSI_LOW: PRINTM(MEVENT, "EVENT: Beacon RSSI_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_RSSI_LOW, MNULL); break; case EVENT_SNR_LOW: PRINTM(MEVENT, "EVENT: Beacon SNR_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_LOW, MNULL); break; case EVENT_MAX_FAIL: PRINTM(MEVENT, "EVENT: MAX_FAIL\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MAX_FAIL, MNULL); break; case EVENT_RSSI_HIGH: PRINTM(MEVENT, "EVENT: Beacon RSSI_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_RSSI_HIGH, MNULL); break; case EVENT_SNR_HIGH: PRINTM(MEVENT, "EVENT: Beacon SNR_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_HIGH, MNULL); break; case EVENT_DATA_RSSI_LOW: PRINTM(MEVENT, "EVENT: Data RSSI_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_LOW, MNULL); break; case EVENT_DATA_SNR_LOW: PRINTM(MEVENT, "EVENT: Data SNR_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_LOW, MNULL); break; case EVENT_DATA_RSSI_HIGH: PRINTM(MEVENT, "EVENT: Data RSSI_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_HIGH, MNULL); break; case EVENT_DATA_SNR_HIGH: PRINTM(MEVENT, "EVENT: Data SNR_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_HIGH, MNULL); break; case EVENT_LINK_QUALITY: PRINTM(MEVENT, "EVENT: Link Quality\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_LINK_QUALITY, MNULL); break; case EVENT_PRE_BEACON_LOST: PRINTM(MEVENT, "EVENT: Pre-Beacon Lost\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PRE_BCN_LOST, MNULL); break; case EVENT_IBSS_COALESCED: PRINTM(MEVENT, "EVENT: IBSS_COALESCED\n"); ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, HostCmd_ACT_GEN_GET, 0, MNULL, MNULL); break; case EVENT_ADDBA: PRINTM(MEVENT, "EVENT: ADDBA Request\n"); if (pmpriv->media_connected == MTRUE) ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_11N_ADDBA_RSP, HostCmd_ACT_GEN_SET, 0, MNULL, pmadapter->event_body); else PRINTM(MERROR, "Ignore ADDBA Request event in disconnected state\n"); break; case EVENT_DELBA: PRINTM(MEVENT, "EVENT: DELBA Request\n"); if (pmpriv->media_connected == MTRUE) wlan_11n_delete_bastream(pmpriv, pmadapter->event_body); else PRINTM(MERROR, "Ignore DELBA Request event in disconnected state\n"); break; case EVENT_BA_STREAM_TIMEOUT: PRINTM(MEVENT, "EVENT: BA Stream timeout\n"); if (pmpriv->media_connected == MTRUE) wlan_11n_ba_stream_timeout(pmpriv, (HostCmd_DS_11N_BATIMEOUT *) pmadapter->event_body); else PRINTM(MERROR, "Ignore BA Stream timeout event in disconnected state\n"); break; case EVENT_RXBA_SYNC: PRINTM(MEVENT, "EVENT: RXBA_SYNC\n"); wlan_11n_rxba_sync_event(pmpriv, pmadapter->event_body, pmbuf->data_len - sizeof(eventcause)); break; case EVENT_AMSDU_AGGR_CTRL: PRINTM(MEVENT, "EVENT: AMSDU_AGGR_CTRL %d\n", *(t_u16 *)pmadapter->event_body); pmadapter->tx_buf_size = MIN(pmadapter->curr_tx_buf_size, wlan_le16_to_cpu(*(t_u16 *)pmadapter->event_body)); PRINTM(MEVENT, "tx_buf_size %d\n", pmadapter->tx_buf_size); break; case EVENT_WEP_ICV_ERR: PRINTM(MEVENT, "EVENT: WEP ICV error\n"); pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_FW_WEP_ICV_ERR; pevent->event_len = sizeof(Event_WEP_ICV_ERR); memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmadapter->event_body, pevent->event_len); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_WEP_ICV_ERR, pevent); break; case EVENT_BW_CHANGE: PRINTM(MEVENT, "EVENT: BW Change\n"); pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_FW_BW_CHANGED; pevent->event_len = sizeof(t_u8); /* Copy event body from the event buffer */ memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmadapter->event_body, pevent->event_len); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BW_CHANGED, pevent); break; #ifdef WIFI_DIRECT_SUPPORT case EVENT_WIFIDIRECT_GENERIC_EVENT: PRINTM(MEVENT, "EVENT: WIFIDIRECT event %d\n", eventcause); /* Allocate memory for event buffer */ ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, MLAN_MEM_DEF, &evt_buf); if ((ret == MLAN_STATUS_SUCCESS) && evt_buf) { pevent = (pmlan_event)evt_buf; pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU; pevent->event_len = pmbuf->data_len; memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset, pevent->event_len); wlan_recv_event(pmpriv, pevent->event_id, pevent); pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf); } break; case EVENT_WIFIDIRECT_SERVICE_DISCOVERY: PRINTM(MEVENT, "EVENT: WIFIDIRECT service discovery event %d\n", eventcause); /* Allocate large memory for service discovery */ if (pmbuf->data_len < MAX_EVENT_SIZE) ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, MLAN_MEM_DEF, &evt_buf); else ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE * 2, MLAN_MEM_DEF, &evt_buf); if ((ret == MLAN_STATUS_SUCCESS) && evt_buf) { pevent = (pmlan_event)evt_buf; pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU; pevent->event_len = pmbuf->data_len; memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset, pevent->event_len); wlan_recv_event(pmpriv, pevent->event_id, pevent); pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf); } break; case EVENT_REMAIN_ON_CHANNEL_EXPIRED: PRINTM(MEVENT, "EVENT: REMAIN_ON_CHANNEL_EXPIRED reason=%d\n", *(t_u16 *)pmadapter->event_body); wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_FLUSH_RX_WORK, MNULL); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED, MNULL); break; #endif /* WIFI_DIRECT_SUPPORT */ case EVENT_TDLS_GENERIC_EVENT: PRINTM(MEVENT, "EVENT: TDLS event %d\n", eventcause); wlan_parse_tdls_event(pmpriv, pmbuf); /* Allocate memory for event buffer */ ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, MLAN_MEM_DEF, &evt_buf); if ((ret == MLAN_STATUS_SUCCESS) && evt_buf) { pevent = (pmlan_event)evt_buf; pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU; pevent->event_len = pmbuf->data_len; memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset, pevent->event_len); wlan_recv_event(pmpriv, pevent->event_id, pevent); pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf); } break; case EVENT_TX_DATA_PAUSE: PRINTM(MEVENT, "EVENT: TX_DATA_PAUSE\n"); wlan_process_sta_tx_pause_event(priv, pmbuf); break; case EVENT_SAD_REPORT: pevent->event_len = pmbuf->data_len - sizeof(eventcause); if (pevent->event_len > sizeof(t_u32)) { PRINTM(MEVENT, "EVENT: SAD_REPORT %d\n", eventcause); /* Allocate memory for event buffer */ ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, MLAN_MEM_DEF, &evt_buf); if ((ret == MLAN_STATUS_SUCCESS) && evt_buf) { pevent = (pmlan_event)evt_buf; pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU; pevent->event_len = pmbuf->data_len; memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset, pevent->event_len); wlan_recv_event(pmpriv, pevent->event_id, pevent); pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf); } } else { t_u8 *pevt_dat = pmbuf->pbuf + pmbuf->data_offset + sizeof(t_u32); PRINTM(MEVENT, "EVENT: Antenna Diversity %d (%d, %d, %d, %d)\n", eventcause, pevt_dat[0] + 1, pevt_dat[1] + 1, pevt_dat[2], pevt_dat[3]); } break; case EVENT_MULTI_CHAN_INFO: PRINTM(MEVENT, "EVENT: MULTI_CHAN_INFO\n"); wlan_handle_event_multi_chan_info(pmpriv, pmbuf); break; case EVENT_FW_DUMP_INFO: PRINTM(MEVENT, "EVENT: Dump FW info\n"); /* Allocate memory for event buffer */ ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, MLAN_MEM_DEF, &evt_buf); if ((ret == MLAN_STATUS_SUCCESS) && evt_buf) { pevent = (pmlan_event)evt_buf; pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_FW_DUMP_INFO; pevent->event_len = pmbuf->data_len; memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset, pevent->event_len); wlan_recv_event(pmpriv, pevent->event_id, pevent); pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf); } break; case EVENT_TX_STATUS_REPORT: PRINTM(MINFO, "EVENT: TX_STATUS\n"); pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_FW_TX_STATUS; pevent->event_len = pmbuf->data_len; memcpy(pmadapter, (t_u8 *)pevent->event_buf, pmbuf->pbuf + pmbuf->data_offset, MIN(pevent->event_len, sizeof (event_buf))); wlan_recv_event(pmpriv, pevent->event_id, pevent); break; case EVENT_BT_COEX_WLAN_PARA_CHANGE: PRINTM(MEVENT, "EVENT: BT coex wlan param update\n"); wlan_bt_coex_wlan_param_update_event(pmpriv, pmbuf); break; default: PRINTM(MEVENT, "EVENT: unknown event id: %#x\n", eventcause); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_UNKNOWN, MNULL); break; } LEAVE(); return ret; }
/** * @brief This function handles disconnect event, reports disconnect * to upper layer, cleans tx/rx packets, * resets link state etc. * * @param priv A pointer to mlan_private structure * @param drv_disconnect Flag indicating the driver should disconnect * and flush pending packets. * * @return N/A */ t_void wlan_reset_connect_state(pmlan_private priv, t_u8 drv_disconnect) { mlan_adapter *pmadapter = priv->adapter; mlan_status ret = MLAN_STATUS_SUCCESS; state_11d_t enable; ENTER(); PRINTM(MINFO, "Handles disconnect event.\n"); if (drv_disconnect) { priv->media_connected = MFALSE; wlan_11h_check_update_radar_det_state(priv); } if (priv->port_ctrl_mode == MTRUE) { /* Close the port on Disconnect */ PRINTM(MINFO, "DISC: port_status = CLOSED\n"); priv->port_open = MFALSE; } pmadapter->scan_block = MFALSE; /* Reset SNR/NF/RSSI values */ priv->data_rssi_last = 0; priv->data_nf_last = 0; priv->data_rssi_avg = 0; priv->data_nf_avg = 0; priv->bcn_rssi_last = 0; priv->bcn_nf_last = 0; priv->bcn_rssi_avg = 0; priv->bcn_nf_avg = 0; priv->rxpd_rate = 0; priv->rxpd_rate_info = 0; priv->max_amsdu = 0; wlan_coex_ampdu_rxwinsize(pmadapter); priv->sec_info.ewpa_enabled = MFALSE; priv->sec_info.wpa_enabled = MFALSE; priv->sec_info.wpa2_enabled = MFALSE; priv->wpa_ie_len = 0; priv->sec_info.wapi_enabled = MFALSE; priv->wapi_ie_len = 0; priv->sec_info.wapi_key_on = MFALSE; priv->wps.session_enable = MFALSE; memset(priv->adapter, (t_u8 *)&priv->wps.wps_ie, 0x00, sizeof(priv->wps.wps_ie)); priv->sec_info.osen_enabled = MFALSE; priv->osen_ie_len = 0; priv->sec_info.encryption_mode = MLAN_ENCRYPTION_MODE_NONE; /* Enable auto data rate */ priv->is_data_rate_auto = MTRUE; priv->data_rate = 0; if (priv->bss_mode == MLAN_BSS_MODE_IBSS) { priv->adhoc_state = ADHOC_IDLE; priv->adhoc_is_link_sensed = MFALSE; priv->intf_state_11h.adhoc_auto_sel_chan = MTRUE; } if (drv_disconnect) { /* Free Tx and Rx packets, report disconnect to upper layer */ wlan_clean_txrx(priv); /* Need to erase the current SSID and BSSID info */ memset(pmadapter, &priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params)); } wlan_send_tdls_tear_down_request(priv); wlan_delete_station_list(priv); pmadapter->tdls_status = TDLS_NOT_SETUP; priv->wmm_qosinfo = priv->saved_wmm_qosinfo; pmadapter->sleep_period.period = pmadapter->saved_sleep_period.period; pmadapter->tx_lock_flag = MFALSE; pmadapter->pps_uapsd_mode = MFALSE; pmadapter->delay_null_pkt = MFALSE; if ((wlan_11d_is_enabled(priv)) && (priv->state_11d.user_enable_11d == DISABLE_11D)) { priv->state_11d.enable_11d = DISABLE_11D; enable = DISABLE_11D; /* Send cmd to FW to enable/disable 11D function */ ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, HostCmd_ACT_GEN_SET, Dot11D_i, MNULL, &enable); if (ret) PRINTM(MERROR, "11D: Failed to enable 11D\n"); } if (pmadapter->num_cmd_timeout && pmadapter->curr_cmd && (pmadapter->cmd_timer_is_set == MFALSE)) { LEAVE(); return; } wlan_recv_event(priv, MLAN_EVENT_ID_FW_DISCONNECTED, MNULL); LEAVE(); }
/** * @brief This function handles events generated by firmware * * @param priv A pointer to mlan_private structure * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status mlan_process_sta_event(IN t_void * priv) { pmlan_private pmpriv = (pmlan_private) priv; pmlan_adapter pmadapter = pmpriv->adapter; mlan_status ret = MLAN_STATUS_SUCCESS; t_u32 eventcause = pmadapter->event_cause; t_u8 event_buf[100]; mlan_event *pevent = (mlan_event *) event_buf; ENTER(); /* Clear BSS_NO_BITS from event */ eventcause &= EVENT_ID_MASK; switch (eventcause) { case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: PRINTM(MERROR, "Invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignoring it\n"); break; case EVENT_LINK_SENSED: PRINTM(MEVENT, "EVENT: LINK_SENSED\n"); pmpriv->adhoc_is_link_sensed = MTRUE; wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED, MNULL); break; case EVENT_DEAUTHENTICATED: PRINTM(MEVENT, "EVENT: Deauthenticated\n"); pmadapter->dbg.num_event_deauth++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_DISASSOCIATED: PRINTM(MEVENT, "EVENT: Disassociated\n"); pmadapter->dbg.num_event_disassoc++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_LINK_LOST: PRINTM(MEVENT, "EVENT: Link lost\n"); pmadapter->dbg.num_event_link_lost++; wlan_handle_disconnect_event(pmpriv); break; case EVENT_PS_SLEEP: PRINTM(MINFO, "EVENT: SLEEP\n"); PRINTM(MEVENT, "_"); pmadapter->ps_state = PS_STATE_PRE_SLEEP; wlan_check_ps_cond(pmadapter); break; case EVENT_PS_AWAKE: PRINTM(MINFO, "EVENT: AWAKE \n"); PRINTM(MEVENT, "|"); pmadapter->tx_lock_flag = MFALSE; if (pmadapter->sleep_period.period) { if (MTRUE == wlan_check_last_packet_indication(pmpriv)) { if (!pmadapter->data_sent && pmpriv->gen_null_pkg) { wlan_send_null_packet(pmpriv, MRVDRV_TxPD_POWER_MGMT_NULL_PACKET | MRVDRV_TxPD_POWER_MGMT_LAST_PACKET); pmadapter->ps_state = PS_STATE_SLEEP; return MLAN_STATUS_SUCCESS; } } } pmadapter->ps_state = PS_STATE_AWAKE; pmadapter->pm_wakeup_card_req = MFALSE; pmadapter->pm_wakeup_fw_try = MFALSE; break; case EVENT_DEEP_SLEEP_AWAKE: wlan_pm_reset_card(pmadapter); PRINTM(MEVENT, "EVENT: DS_AWAKE\n"); if (pmadapter->is_deep_sleep == MTRUE) { pmadapter->is_deep_sleep = MFALSE; } wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DS_AWAKE, MNULL); break; case EVENT_HS_ACT_REQ: PRINTM(MEVENT, "EVENT: HS_ACT_REQ\n"); ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, 0, 0, MNULL, MNULL); break; case EVENT_MIC_ERR_UNICAST: PRINTM(MEVENT, "EVENT: UNICAST MIC ERROR\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_UNI, MNULL); break; case EVENT_MIC_ERR_MULTICAST: PRINTM(MEVENT, "EVENT: MULTICAST MIC ERROR\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_MUL, MNULL); break; case EVENT_MIB_CHANGED: case EVENT_INIT_DONE: break; case EVENT_ADHOC_BCN_LOST: PRINTM(MEVENT, "EVENT: ADHOC_BCN_LOST\n"); pmpriv->adhoc_is_link_sensed = MFALSE; wlan_clean_txrx(pmpriv); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_LOST, MNULL); break; case EVENT_BG_SCAN_REPORT: PRINTM(MEVENT, "EVENT: BGS_REPORT\n"); /* Clear the previous scan result */ memset(pmadapter->pscan_table, 0x00, sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST); pmadapter->num_in_scan_table = 0; pmadapter->pbcn_buf_end = pmadapter->bcn_buf; ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_BG_SCAN_QUERY, HostCmd_ACT_GEN_GET, 0, MNULL, MNULL); break; case EVENT_WMM_STATUS_CHANGE: PRINTM(MEVENT, "EVENT: WMM status changed\n"); ret = (mlan_status) wlan_cmd_wmm_status_change(pmpriv); break; case EVENT_RSSI_LOW: PRINTM(MEVENT, "EVENT: Beacon RSSI_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_RSSI_LOW, MNULL); break; case EVENT_SNR_LOW: PRINTM(MEVENT, "EVENT: Beacon SNR_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_LOW, MNULL); break; case EVENT_MAX_FAIL: PRINTM(MEVENT, "EVENT: MAX_FAIL\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MAX_FAIL, MNULL); break; case EVENT_RSSI_HIGH: PRINTM(MEVENT, "EVENT: Beacon RSSI_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_RSSI_HIGH, MNULL); break; case EVENT_SNR_HIGH: PRINTM(MEVENT, "EVENT: Beacon SNR_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_HIGH, MNULL); break; case EVENT_DATA_RSSI_LOW: PRINTM(MEVENT, "EVENT: Data RSSI_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_LOW, MNULL); break; case EVENT_DATA_SNR_LOW: PRINTM(MEVENT, "EVENT: Data SNR_LOW\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_LOW, MNULL); break; case EVENT_DATA_RSSI_HIGH: PRINTM(MEVENT, "EVENT: Data RSSI_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_HIGH, MNULL); break; case EVENT_DATA_SNR_HIGH: PRINTM(MEVENT, "EVENT: Data SNR_HIGH\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_HIGH, MNULL); break; case EVENT_LINK_QUALITY: PRINTM(MEVENT, "EVENT: Link Quality\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_LINK_QUALITY, MNULL); break; case EVENT_PRE_BEACON_LOST: PRINTM(MEVENT, "EVENT: Pre-Beacon Lost\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PRE_BCN_LOST, MNULL); break; case EVENT_IBSS_COALESCED: PRINTM(MEVENT, "EVENT: IBSS_COALESCED\n"); ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, HostCmd_ACT_GEN_GET, 0, MNULL, MNULL); break; case EVENT_PORT_RELEASE: PRINTM(MEVENT, "EVENT: PORT RELEASE\n"); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PORT_RELEASE, MNULL); pevent->bss_num = pmpriv->bss_num; pevent->event_id = MLAN_EVENT_ID_DRV_CONNECTED; pevent->event_len = MLAN_MAC_ADDR_LENGTH; memcpy((t_u8 *) pevent->event_buf, (t_u8 *) pmpriv->curr_bss_params.bss_descriptor.mac_address, MLAN_MAC_ADDR_LENGTH); wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_CONNECTED, pevent); /* Send OBSS scan param to the application */ wlan_2040_coex_event(pmpriv); break; case EVENT_ADDBA: PRINTM(MEVENT, "EVENT: ADDBA Request\n"); wlan_prepare_cmd(pmpriv, HostCmd_CMD_11N_ADDBA_RSP, HostCmd_ACT_GEN_SET, 0, MNULL, pmadapter->event_body); break; case EVENT_DELBA: PRINTM(MEVENT, "EVENT: DELBA Request\n"); wlan_11n_delete_bastream(pmpriv, pmadapter->event_body); break; case EVENT_BA_STREAM_TIEMOUT: PRINTM(MEVENT, "EVENT: BA Stream timeout\n"); wlan_11n_ba_stream_timeout(pmpriv, (HostCmd_DS_11N_BATIMEOUT *) pmadapter-> event_body); break; case EVENT_AMSDU_AGGR_CTRL: PRINTM(MEVENT, "EVENT: AMSDU_AGGR_CTRL %d\n", *(t_u16 *) pmadapter->event_body); pmpriv->adapter->tx_buf_size = MIN(pmpriv->adapter->max_tx_buf_size, wlan_le16_to_cpu(*(t_u16 *) pmadapter->event_body)); PRINTM(MEVENT, "tx_buf_size %d\n", pmpriv->adapter->tx_buf_size); break; case EVENT_WEP_ICV_ERR: PRINTM(MEVENT, "EVENT: WEP ICV error\n"); pevent->bss_num = pmpriv->bss_num; pevent->event_id = MLAN_EVENT_ID_FW_WEP_ICV_ERR; pevent->event_len = sizeof(Event_WEP_ICV_ERR); memcpy((t_u8 *) pevent->event_buf, pmadapter->event_body, pevent->event_len); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_WEP_ICV_ERR, pevent); break; case EVENT_BW_CHANGE: PRINTM(MEVENT, "EVENT: BW Change\n"); pevent->bss_num = pmpriv->bss_num; pevent->event_id = MLAN_EVENT_ID_FW_BW_CHANGED; pevent->event_len = sizeof(t_u8); /* Copy event body from the event buffer */ memcpy((t_u8 *) pevent->event_buf, pmadapter->event_body, pevent->event_len); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BW_CHANGED, pevent); break; default: PRINTM(MEVENT, "EVENT: unknown event id: %#x\n", eventcause); wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_UNKNOWN, MNULL); break; } LEAVE(); return ret; }
void wlan_fatal_error_handle(wlan_private * priv) { wlan_adapter *Adapter = priv->adapter; ulong flags; CmdCtrlNode *CmdNode = NULL; ENTER(); PRINTM(FATAL, "Fatal error handling...\n"); //Stop reassociation priv->adapter->Reassoc_on = FALSE; //stop access firmware priv->adapter->fwstate = FW_STATE_NREADY; if (priv->adapter->MediaConnectStatus == WlanMediaStateConnected) { union iwreq_data wrqu; //send disconnect event to app memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); #ifdef MOTO_DBG PRINTM(MOTO_MSG, "wlan_fatal_error_handle: Disconnected event sent to upper layer.\n"); #endif /* Free Tx and Rx packets */ /* report disconnect to upper layer */ wlan_clean_txrx(priv); Adapter->MediaConnectStatus = WlanMediaStateDisconnected; } //release ds_awake_q if (Adapter->IsDeepSleep == TRUE) { Adapter->IsDeepSleep = FALSE; wake_up_interruptible(&Adapter->ds_awake_q); sbi_reset_deepsleep_wakeup(priv); } //clean up host sleep flags Adapter->bWakeupDevRequired = FALSE; #ifdef MOTO_DBG PRINTM(INFO, "bWakeupDevRequired set to FALSE - KO for DSM\n"); #endif Adapter->WakeupTries = 0; #ifdef MOTO_DBG PRINTM(INFO, "WakeupTries set to 0 - OK for DSM\n"); #endif //Release all the pending command if (priv->adapter->CurCmd) { /* set error code that will be transferred back to PrepareAndSendCommand() */ Adapter->CurCmdRetCode = WLAN_STATUS_FAILURE; CleanupAndInsertCmd(priv, Adapter->CurCmd); spin_lock_irqsave(&Adapter->QueueSpinLock, flags); Adapter->CurCmd = NULL; spin_unlock_irqrestore(&Adapter->QueueSpinLock, flags); } while (TRUE) { spin_lock_irqsave(&Adapter->QueueSpinLock, flags); if (list_empty(&Adapter->CmdPendingQ)) { spin_unlock_irqrestore(&Adapter->QueueSpinLock, flags); break; } CmdNode = (CmdCtrlNode *) Adapter->CmdPendingQ.next; spin_unlock_irqrestore(&Adapter->QueueSpinLock, flags); if (!CmdNode) break; list_del((struct list_head *) CmdNode); CleanupAndInsertCmd(priv, CmdNode); } send_iwevcustom_event(priv, CUS_EVT_FATAL_ERR); #ifdef MOTO_DBG PRINTM(MOTO_MSG, "wlan_fatal_error_handle: Fatal error event sent to upper layer.\n"); #endif LEAVE(); return; }