/** 
 *  @brief This function sends the OBSS scan parameters to the application
 *  
 *  @param pmpriv     A pointer to mlan_private structure
 *
 *  @return           N/A
 */
t_void
wlan_2040_coex_event(pmlan_private pmpriv)
{
    t_u8 event_buf[100];
    mlan_event *pevent = (mlan_event *) event_buf;
    t_u8 ele_len;

    ENTER();

    if (pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param &&
        pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param->
        ieee_hdr.element_id == OVERLAPBSSSCANPARAM) {
        ele_len =
            pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param->
            ieee_hdr.len;
        pevent->bss_num = pmpriv->bss_index;
        pevent->event_id = MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM;
        /* Copy OBSS scan parameters */
        memcpy(pmpriv->adapter, (t_u8 *) pevent->event_buf,
               (t_u8 *) & pmpriv->curr_bss_params.bss_descriptor.
               poverlap_bss_scan_param->obss_scan_param, ele_len);
        pevent->event_len = ele_len;
        wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM, pevent);
    }

    LEAVE();
}
/** 
 *  @brief This function sends the HS_ACTIVATED event to the application
 *   
 *  @param priv         A pointer to mlan_private structure
 *  @param activated    MTRUE if activated, MFALSE if de-activated
 *
 *  @return             None
 */
t_void
wlan_host_sleep_activated_event(pmlan_private priv, t_u8 activated)
{
    ENTER();

    if (activated) {
        if (priv->adapter->is_hs_configured) {
            priv->adapter->hs_activated = MTRUE;
            wlan_recv_event(priv, MLAN_EVENT_ID_DRV_HS_ACTIVATED, MNULL);
        } else
            PRINTM(MWARN, "hs_activated: HS not configured !!!\n");
    } else {
        priv->adapter->hs_activated = MFALSE;
        wlan_recv_event(priv, MLAN_EVENT_ID_DRV_HS_DEACTIVATED, MNULL);
    }

    LEAVE();
}
/**
 *  @brief The main process
 *
 *  @param pmlan_adapter	A pointer to mlan_adapter structure
 *
 *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
mlan_rx_process(IN t_void * pmlan_adapter)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
    pmlan_callbacks pcb;
    pmlan_buffer pmbuf;

    ENTER();

    MASSERT(pmlan_adapter);
    pcb = &pmadapter->callbacks;
    pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock);
    if (pmadapter->mlan_rx_processing || pmadapter->rx_lock_flag) {
        pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                              pmadapter->prx_proc_lock);
        goto exit_rx_proc;
    } else {
        pmadapter->mlan_rx_processing = MTRUE;
        pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                              pmadapter->prx_proc_lock);
    }
    /* Check for Rx data */
    while ((pmbuf =
                (pmlan_buffer) util_dequeue_list(pmadapter->pmoal_handle,
                        &pmadapter->rx_data_queue,
                        pmadapter->callbacks.
                        moal_spin_lock,
                        pmadapter->callbacks.
                        moal_spin_unlock))) {
        util_scalar_decrement(pmadapter->pmoal_handle,
                              &pmadapter->rx_pkts_queued,
                              pmadapter->callbacks.moal_spin_lock,
                              pmadapter->callbacks.moal_spin_unlock);
        if (pmadapter->delay_task_flag &&
                (util_scalar_read
                 (pmadapter->pmoal_handle, &pmadapter->rx_pkts_queued,
                  pmadapter->callbacks.moal_spin_lock,
                  pmadapter->callbacks.moal_spin_unlock) <
                 LOW_RX_PENDING)) {
            PRINTM(MEVENT, "Run\n");
            pmadapter->delay_task_flag = MFALSE;
            wlan_recv_event(wlan_get_priv
                            (pmadapter, MLAN_BSS_ROLE_ANY),
                            MLAN_EVENT_ID_DRV_DEFER_HANDLING,
                            MNULL);
        }
        wlan_handle_rx_packet(pmadapter, pmbuf);
    }
    pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock);
    pmadapter->mlan_rx_processing = MFALSE;
    pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                          pmadapter->prx_proc_lock);
exit_rx_proc:
    LEAVE();
    return ret;
}
/** 
 *  @brief This function sends the HS_WAKEUP event to the application
 *   
 *  @param priv         A pointer to mlan_private structure
 *
 *  @return             None
 */
t_void
wlan_host_sleep_wakeup_event(pmlan_private priv)
{
    ENTER();

    if (priv->adapter->is_hs_configured) {
        wlan_recv_event(priv, MLAN_EVENT_ID_FW_HS_WAKEUP, MNULL);
    } else {
        PRINTM(MWARN, "hs_wakeup: Host Sleep not configured !!!\n");
    }

    LEAVE();
}
Beispiel #5
0
/**
 *  @brief Retrieve a measurement report from the firmware
 *
 *  Callback from command processing when a measurement report is received
 *    from the firmware.  Perform the following when a report is received:
 *
 *   -# Debug displays the report if compiled with the appropriate flags
 *   -# If we are pending on a specific measurement report token, and it
 *      matches the received report's token, store the report and wake up
 *      any pending threads
 *
 *  @param pmpriv Private driver information structure
 *  @param resp HostCmd_DS_COMMAND struct returned from the firmware command
 *              passing a HostCmd_DS_MEASUREMENT_REPORT structure.
 *
 *  @return     MLAN_STATUS_SUCCESS
 */
static int
wlan_meas_cmdresp_get_report(mlan_private *pmpriv,
			     const HostCmd_DS_COMMAND *resp)
{
	mlan_adapter *pmadapter = pmpriv->adapter;
	const HostCmd_DS_MEASUREMENT_REPORT *pmeas_rpt = &resp->params.meas_rpt;

	ENTER();

	PRINTM(MINFO, "Meas: Rpt: %#x-%u, Seq=%u, Ret=%u\n",
	       resp->command, resp->size, resp->seq_num, resp->result);

	/* Debug displays the measurement report */
	wlan_meas_dump_meas_rpt(pmeas_rpt);

	/*
	 * Check if we are pending on a measurement report and it matches
	 *  the dialog token of the received report:
	 */
	if (pmadapter->state_meas.meas_rpt_pend_on
	    && pmadapter->state_meas.meas_rpt_pend_on ==
	    pmeas_rpt->dialog_token) {
		PRINTM(MINFO, "Meas: Rpt: RCV'd Pend on meas #%d\n",
		       pmadapter->state_meas.meas_rpt_pend_on);

		/* Clear the pending report indicator */
		pmadapter->state_meas.meas_rpt_pend_on = 0;

		/* Copy the received report into the measurement state for
		   retrieval */
		memcpy(pmadapter, &pmadapter->state_meas.meas_rpt_returned,
		       pmeas_rpt,
		       sizeof(pmadapter->state_meas.meas_rpt_returned));

		/*
		 * Wake up any threads pending on the wait queue
		 */
		wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_MEAS_REPORT, MNULL);
	}

	LEAVE();

	return MLAN_STATUS_SUCCESS;
}
/**
 *  @brief This function send the tdls teardown request event.
 *
 *  @param priv    A pointer to mlan_private
 *
 *  @return        N/A
 */
void
wlan_send_tdls_tear_down_request(pmlan_private priv)
{
	t_u8 event_buf[100];
	mlan_event *ptdls_event = (mlan_event *)event_buf;
	tdls_tear_down_event *tdls_evt =
		(tdls_tear_down_event *)ptdls_event->event_buf;
	sta_node *sta_ptr = MNULL;

	ENTER();

	sta_ptr = (sta_node *)util_peek_list(priv->adapter->pmoal_handle,
					     &priv->sta_list,
					     priv->adapter->callbacks.
					     moal_spin_lock,
					     priv->adapter->callbacks.
					     moal_spin_unlock);
	if (!sta_ptr) {
		LEAVE();
		return;
	}
	while (sta_ptr != (sta_node *)&priv->sta_list) {
		if (sta_ptr->external_tdls) {
			ptdls_event->bss_index = priv->bss_index;
			ptdls_event->event_id =
				MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
			ptdls_event->event_len = sizeof(tdls_tear_down_event);
			memcpy(priv->adapter, (t_u8 *)tdls_evt->peer_mac_addr,
			       sta_ptr->mac_addr, MLAN_MAC_ADDR_LENGTH);
			tdls_evt->reason_code =
				MLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
			wlan_recv_event(priv,
					MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ,
					ptdls_event);
		}
		sta_ptr = sta_ptr->pnext;
	}
	LEAVE();
	return;
}
Beispiel #7
0
/**
 *  @brief This function processes received packet and forwards it
 *          to kernel/upper layer or send back to firmware
 *
 *  @param priv      A pointer to mlan_private
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_uap_rx_packet(IN mlan_private *priv, IN pmlan_buffer pmbuf)
{
	pmlan_adapter pmadapter = priv->adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	UapRxPD *prx_pd;
	RxPacketHdr_t *prx_pkt;
	pmlan_buffer newbuf = MNULL;

	ENTER();

	prx_pd = (UapRxPD *)(pmbuf->pbuf + pmbuf->data_offset);
	prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);

	DBG_HEXDUMP(MDAT_D, "uAP RxPD", prx_pd,
		    MIN(sizeof(UapRxPD), MAX_DATA_DUMP_LEN));
	DBG_HEXDUMP(MDAT_D, "uAP Rx Payload",
		    ((t_u8 *)prx_pd + prx_pd->rx_pkt_offset),
		    MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));

	PRINTM(MINFO,
	       "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
	       pmbuf->data_len, prx_pd->rx_pkt_offset,
	       pmbuf->data_len - prx_pd->rx_pkt_offset);
	PRINTM(MDATA, "Rx dest " MACSTR "\n",
	       MAC2STR(prx_pkt->eth803_hdr.dest_addr));

	/* don't do packet forwarding in disconnected state */
	/* don't do packet forwarding when packet > 1514 */
	if ((priv->media_connected == MFALSE) ||
	    ((pmbuf->data_len - prx_pd->rx_pkt_offset) > MV_ETH_FRAME_LEN))
		goto upload;

	if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01) {
		if (!(priv->pkt_fwd & PKT_FWD_INTRA_BCAST)) {
			/* Multicast pkt */
			newbuf = wlan_alloc_mlan_buffer(pmadapter,
							MLAN_TX_DATA_BUF_SIZE_2K,
							0, MOAL_MALLOC_BUFFER);
			if (newbuf) {
				newbuf->bss_index = pmbuf->bss_index;
				newbuf->buf_type = pmbuf->buf_type;
				newbuf->priority = pmbuf->priority;
				newbuf->in_ts_sec = pmbuf->in_ts_sec;
				newbuf->in_ts_usec = pmbuf->in_ts_usec;
				newbuf->data_offset =
					(sizeof(UapTxPD) + INTF_HEADER_LEN +
					 DMA_ALIGNMENT);
				util_scalar_increment(pmadapter->pmoal_handle,
						      &pmadapter->
						      pending_bridge_pkts,
						      pmadapter->callbacks.
						      moal_spin_lock,
						      pmadapter->callbacks.
						      moal_spin_unlock);
				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

				/* copy the data, skip rxpd */
				memcpy(pmadapter,
				       (t_u8 *)newbuf->pbuf +
				       newbuf->data_offset,
				       pmbuf->pbuf + pmbuf->data_offset +
				       prx_pd->rx_pkt_offset,
				       pmbuf->data_len - prx_pd->rx_pkt_offset);
				newbuf->data_len =
					pmbuf->data_len - prx_pd->rx_pkt_offset;
				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
				if (util_scalar_read(pmadapter->pmoal_handle,
						     &pmadapter->
						     pending_bridge_pkts,
						     pmadapter->callbacks.
						     moal_spin_lock,
						     pmadapter->callbacks.
						     moal_spin_unlock) >
				    RX_HIGH_THRESHOLD)
					wlan_drop_tx_pkts(priv);
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_DEFER_HANDLING,
						MNULL);
			}
		}
	} else {
		if ((!(priv->pkt_fwd & PKT_FWD_INTRA_UCAST)) &&
		    (wlan_get_station_entry
		     (priv, prx_pkt->eth803_hdr.dest_addr))) {
			/* Forwarding Intra-BSS packet */
			pmbuf->data_len -= prx_pd->rx_pkt_offset;
			pmbuf->data_offset += prx_pd->rx_pkt_offset;
			pmbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;
			util_scalar_increment(pmadapter->pmoal_handle,
					      &pmadapter->pending_bridge_pkts,
					      pmadapter->callbacks.
					      moal_spin_lock,
					      pmadapter->callbacks.
					      moal_spin_unlock);
			wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
			if (util_scalar_read(pmadapter->pmoal_handle,
					     &pmadapter->pending_bridge_pkts,
					     pmadapter->callbacks.
					     moal_spin_lock,
					     pmadapter->callbacks.
					     moal_spin_unlock) >
			    RX_HIGH_THRESHOLD)
				wlan_drop_tx_pkts(priv);
			wlan_recv_event(priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
					MNULL);
			goto done;
		} else if (MLAN_STATUS_FAILURE ==
			   wlan_check_unicast_packet(priv,
						     prx_pkt->eth803_hdr.
						     dest_addr)) {
			PRINTM(MDATA, "Drop Pkts: Rx dest " MACSTR "\n",
			       MAC2STR(prx_pkt->eth803_hdr.dest_addr));
			pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
			wlan_free_mlan_buffer(pmadapter, pmbuf);
			goto done;
		}
	}

upload:
	/* Chop off RxPD */
	pmbuf->data_len -= prx_pd->rx_pkt_offset;
	pmbuf->data_offset += prx_pd->rx_pkt_offset;
	pmbuf->pparent = MNULL;

	pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
						  &pmbuf->out_ts_sec,
						  &pmbuf->out_ts_usec);
	PRINTM_NETINTF(MDATA, priv);
	PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n",
	       pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num,
	       prx_pd->priority);
	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
						    pmbuf);
	if (ret == MLAN_STATUS_FAILURE) {
		PRINTM(MERROR,
		       "uAP Rx Error: moal_recv_packet returned error\n");
		pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
	}

	if (ret != MLAN_STATUS_PENDING)
		wlan_free_mlan_buffer(pmadapter, pmbuf);
done:
	LEAVE();
	return ret;
}
Beispiel #8
0
/**
 *  @brief This function processes received packet and forwards it
 *          to kernel/upper layer or send back to firmware
 *
 *  @param priv      A pointer to mlan_private
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_uap_recv_packet(IN mlan_private *priv, IN pmlan_buffer pmbuf)
{
	pmlan_adapter pmadapter = priv->adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	RxPacketHdr_t *prx_pkt;
	pmlan_buffer newbuf = MNULL;

	ENTER();

	prx_pkt = (RxPacketHdr_t *)((t_u8 *)pmbuf->pbuf + pmbuf->data_offset);

	DBG_HEXDUMP(MDAT_D, "uap_recv_packet", pmbuf->pbuf + pmbuf->data_offset,
		    MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));

	PRINTM(MDATA, "AMSDU dest " MACSTR "\n",
	       MAC2STR(prx_pkt->eth803_hdr.dest_addr));

	/* don't do packet forwarding in disconnected state */
	if ((priv->media_connected == MFALSE) ||
	    (pmbuf->data_len > MV_ETH_FRAME_LEN))
		goto upload;

	if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01) {
		if (!(priv->pkt_fwd & PKT_FWD_INTRA_BCAST)) {
			/* Multicast pkt */
			newbuf = wlan_alloc_mlan_buffer(pmadapter,
							MLAN_TX_DATA_BUF_SIZE_2K,
							0, MOAL_MALLOC_BUFFER);
			if (newbuf) {
				newbuf->bss_index = pmbuf->bss_index;
				newbuf->buf_type = pmbuf->buf_type;
				newbuf->priority = pmbuf->priority;
				newbuf->in_ts_sec = pmbuf->in_ts_sec;
				newbuf->in_ts_usec = pmbuf->in_ts_usec;
				newbuf->data_offset =
					(sizeof(UapTxPD) + INTF_HEADER_LEN +
					 DMA_ALIGNMENT);
				util_scalar_increment(pmadapter->pmoal_handle,
						      &pmadapter->
						      pending_bridge_pkts,
						      pmadapter->callbacks.
						      moal_spin_lock,
						      pmadapter->callbacks.
						      moal_spin_unlock);

				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

				/* copy the data */
				memcpy(pmadapter,
				       (t_u8 *)newbuf->pbuf +
				       newbuf->data_offset,
				       pmbuf->pbuf + pmbuf->data_offset,
				       pmbuf->data_len);
				newbuf->data_len = pmbuf->data_len;
				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
				if (util_scalar_read(pmadapter->pmoal_handle,
						     &pmadapter->
						     pending_bridge_pkts,
						     pmadapter->callbacks.
						     moal_spin_lock,
						     pmadapter->callbacks.
						     moal_spin_unlock) >
				    RX_HIGH_THRESHOLD)
					wlan_drop_tx_pkts(priv);
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_DEFER_HANDLING,
						MNULL);
			}
		}
	} else {
		if ((!(priv->pkt_fwd & PKT_FWD_INTRA_UCAST)) &&
		    (wlan_get_station_entry
		     (priv, prx_pkt->eth803_hdr.dest_addr))) {
			/* Intra BSS packet */
			newbuf = wlan_alloc_mlan_buffer(pmadapter,
							MLAN_TX_DATA_BUF_SIZE_2K,
							0, MOAL_MALLOC_BUFFER);
			if (newbuf) {
				newbuf->bss_index = pmbuf->bss_index;
				newbuf->buf_type = pmbuf->buf_type;
				newbuf->priority = pmbuf->priority;
				newbuf->in_ts_sec = pmbuf->in_ts_sec;
				newbuf->in_ts_usec = pmbuf->in_ts_usec;
				newbuf->data_offset =
					(sizeof(UapTxPD) + INTF_HEADER_LEN +
					 DMA_ALIGNMENT);
				util_scalar_increment(pmadapter->pmoal_handle,
						      &pmadapter->
						      pending_bridge_pkts,
						      pmadapter->callbacks.
						      moal_spin_lock,
						      pmadapter->callbacks.
						      moal_spin_unlock);
				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

				/* copy the data */
				memcpy(pmadapter,
				       (t_u8 *)newbuf->pbuf +
				       newbuf->data_offset,
				       pmbuf->pbuf + pmbuf->data_offset,
				       pmbuf->data_len);
				newbuf->data_len = pmbuf->data_len;
				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
				if (util_scalar_read(pmadapter->pmoal_handle,
						     &pmadapter->
						     pending_bridge_pkts,
						     pmadapter->callbacks.
						     moal_spin_lock,
						     pmadapter->callbacks.
						     moal_spin_unlock) >
				    RX_HIGH_THRESHOLD)
					wlan_drop_tx_pkts(priv);
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_DEFER_HANDLING,
						MNULL);
			}
			goto done;
		} else if (MLAN_STATUS_FAILURE ==
			   wlan_check_unicast_packet(priv,
						     prx_pkt->eth803_hdr.
						     dest_addr)) {
			/* drop packet */
			PRINTM(MDATA, "Drop AMSDU dest " MACSTR "\n",
			       MAC2STR(prx_pkt->eth803_hdr.dest_addr));
			goto done;
		}
	}
upload:
    /** send packet to moal */
	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
						    pmbuf);
done:
	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
 *
 *  @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 The main process
 *
 *  @param pmlan_adapter	A pointer to mlan_adapter structure
 *
 *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
mlan_main_process(IN t_void * pmlan_adapter)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
    pmlan_callbacks pcb;

    ENTER();

    MASSERT(pmlan_adapter);

    pcb = &pmadapter->callbacks;

    pcb->moal_spin_lock(pmadapter->pmoal_handle,
                        pmadapter->pmain_proc_lock);

    /* Check if already processing */
    if (pmadapter->mlan_processing) {
        pmadapter->more_task_flag = MTRUE;
        pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                              pmadapter->pmain_proc_lock);
        goto exit_main_proc;
    } else {
        pmadapter->mlan_processing = MTRUE;
        pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                              pmadapter->pmain_proc_lock);
    }
process_start:
    do {
        pcb->moal_spin_lock(pmadapter->pmoal_handle,
                            pmadapter->pmain_proc_lock);
        pmadapter->more_task_flag = MFALSE;
        pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                              pmadapter->pmain_proc_lock);
        /* Is MLAN shutting down or not ready? */
        if ((pmadapter->hw_status == WlanHardwareStatusClosing) ||
                (pmadapter->hw_status == WlanHardwareStatusNotReady))
            break;
        if (util_scalar_read
                (pmadapter->pmoal_handle, &pmadapter->rx_pkts_queued,
                 pmadapter->callbacks.moal_spin_lock,
                 pmadapter->callbacks.moal_spin_unlock) > HIGH_RX_PENDING) {
            PRINTM(MEVENT, "Pause\n");
            pmadapter->delay_task_flag = MTRUE;
            break;
        }
        /* Handle pending SDIO interrupts if any */
        if (pmadapter->sdio_ireg) {
            if (pmadapter->hs_activated == MTRUE)
                wlan_process_hs_config(pmadapter);
            wlan_process_int_status(pmadapter);
            if (pmadapter->data_received && pmadapter->rx_work_flag)
                wlan_recv_event(wlan_get_priv
                                (pmadapter, MLAN_BSS_ROLE_ANY),
                                MLAN_EVENT_ID_DRV_DEFER_RX_WORK,
                                MNULL);
        }
        /* Need to wake up the card ? */
        if ((pmadapter->ps_state == PS_STATE_SLEEP) &&
                (pmadapter->pm_wakeup_card_req &&
                 !pmadapter->pm_wakeup_fw_try) &&
                (util_peek_list
                 (pmadapter->pmoal_handle, &pmadapter->cmd_pending_q,
                  pcb->moal_spin_lock, pcb->moal_spin_unlock)
                 || !wlan_bypass_tx_list_empty(pmadapter)
                 || !wlan_wmm_lists_empty(pmadapter)
                )) {
            wlan_pm_wakeup_card(pmadapter);
            pmadapter->pm_wakeup_fw_try = MTRUE;
            continue;
        }
        if (IS_CARD_RX_RCVD(pmadapter)) {
            pmadapter->data_received = MFALSE;
            if (pmadapter->hs_activated == MTRUE) {
                pmadapter->is_hs_configured = MFALSE;
                wlan_host_sleep_activated_event(wlan_get_priv
                                                (pmadapter,
                                                 MLAN_BSS_ROLE_ANY),
                                                MFALSE);
            }
            pmadapter->pm_wakeup_fw_try = MFALSE;
            if (pmadapter->ps_state == PS_STATE_SLEEP)
                pmadapter->ps_state = PS_STATE_AWAKE;
        } else {
            /* We have tried to wakeup the card already */
            if (pmadapter->pm_wakeup_fw_try)
                break;
            if (pmadapter->ps_state != PS_STATE_AWAKE ||
                    (pmadapter->tx_lock_flag == MTRUE))
                break;

            if (pmadapter->scan_processing
                    || pmadapter->data_sent
                    || (wlan_bypass_tx_list_empty(pmadapter) &&
                        wlan_wmm_lists_empty(pmadapter))
                    || wlan_11h_radar_detected_tx_blocked(pmadapter)
               ) {
                if (pmadapter->cmd_sent || pmadapter->curr_cmd
                        ||
                        (!util_peek_list
                         (pmadapter->pmoal_handle,
                          &pmadapter->cmd_pending_q,
                          pcb->moal_spin_lock,
                          pcb->moal_spin_unlock))) {
                    break;
                }
            }
        }

        /* Check for Cmd Resp */
        if (pmadapter->cmd_resp_received) {
            pmadapter->cmd_resp_received = MFALSE;
            wlan_process_cmdresp(pmadapter);

            /* call moal back when init_fw is done */
            if (pmadapter->hw_status == WlanHardwareStatusInitdone) {
                pmadapter->hw_status = WlanHardwareStatusReady;
                wlan_init_fw_complete(pmadapter);
            }
        }

        /* Check for event */
        if (pmadapter->event_received) {
            pmadapter->event_received = MFALSE;
            wlan_process_event(pmadapter);
        }

        /* Check if we need to confirm Sleep Request received
           previously */
        if (pmadapter->ps_state == PS_STATE_PRE_SLEEP) {
            if (!pmadapter->cmd_sent && !pmadapter->curr_cmd) {
                wlan_check_ps_cond(pmadapter);
            }
        }

        /*
         * The ps_state may have been changed during processing of
         * Sleep Request event.
         */
        if ((pmadapter->ps_state == PS_STATE_SLEEP)
                || (pmadapter->ps_state == PS_STATE_PRE_SLEEP)
                || (pmadapter->ps_state == PS_STATE_SLEEP_CFM)
                || (pmadapter->tx_lock_flag == MTRUE)
           )
            continue;

        if (!pmadapter->cmd_sent && !pmadapter->curr_cmd) {
            if (wlan_exec_next_cmd(pmadapter) ==
                    MLAN_STATUS_FAILURE) {
                ret = MLAN_STATUS_FAILURE;
                break;
            }
        }

        if (!pmadapter->scan_processing
                && !pmadapter->data_sent &&
                !wlan_11h_radar_detected_tx_blocked(pmadapter) &&
                !wlan_bypass_tx_list_empty(pmadapter)) {
            PRINTM(MINFO, "mlan_send_pkt(): deq(bybass_txq)\n");
            wlan_process_bypass_tx(pmadapter);
            if (pmadapter->hs_activated == MTRUE) {
                pmadapter->is_hs_configured = MFALSE;
                wlan_host_sleep_activated_event(wlan_get_priv
                                                (pmadapter,
                                                 MLAN_BSS_ROLE_ANY),
                                                MFALSE);
            }
        }

        if (!pmadapter->scan_processing
                && !pmadapter->data_sent && !wlan_wmm_lists_empty(pmadapter)
                && !wlan_11h_radar_detected_tx_blocked(pmadapter)
           ) {
            wlan_wmm_process_tx(pmadapter);
            if (pmadapter->hs_activated == MTRUE) {
                pmadapter->is_hs_configured = MFALSE;
                wlan_host_sleep_activated_event(wlan_get_priv
                                                (pmadapter,
                                                 MLAN_BSS_ROLE_ANY),
                                                MFALSE);
            }
        }

#ifdef STA_SUPPORT
        if (pmadapter->delay_null_pkt && !pmadapter->cmd_sent &&
                !pmadapter->curr_cmd && !IS_COMMAND_PENDING(pmadapter) &&
                wlan_bypass_tx_list_empty(pmadapter) &&
                wlan_wmm_lists_empty(pmadapter)) {
            if (wlan_send_null_packet
                    (wlan_get_priv(pmadapter, MLAN_BSS_ROLE_STA),
                     MRVDRV_TxPD_POWER_MGMT_NULL_PACKET |
                     MRVDRV_TxPD_POWER_MGMT_LAST_PACKET)
                    == MLAN_STATUS_SUCCESS) {
                pmadapter->delay_null_pkt = MFALSE;
            }
            break;
        }
#endif

    } while (MTRUE);

    pcb->moal_spin_lock(pmadapter->pmoal_handle,
                        pmadapter->pmain_proc_lock);
    if (pmadapter->more_task_flag == MTRUE) {
        pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                              pmadapter->pmain_proc_lock);
        goto process_start;
    }
    pmadapter->mlan_processing = MFALSE;
    pcb->moal_spin_unlock(pmadapter->pmoal_handle,
                          pmadapter->pmain_proc_lock);

exit_main_proc:
    if (pmadapter->hw_status == WlanHardwareStatusClosing)
        mlan_shutdown_fw(pmadapter);
    LEAVE();
    return ret;
}
/**
 *  @brief This function will parse the TDLS event for further wlan action
 *
 *  @param priv     A pointer to mlan_private
 *  @param pevent   A pointer to event buf
 *
 *  @return         N/A
 */
static void
wlan_parse_tdls_event(pmlan_private priv, pmlan_buffer pevent)
{
	Event_tdls_generic *tdls_event = (Event_tdls_generic *)
		(pevent->pbuf + pevent->data_offset + sizeof(mlan_event_id));
	sta_node *sta_ptr = MNULL;
	pmlan_adapter pmadapter = priv->adapter;
	t_u8 i = 0;
	IEEEtypes_HTCap_t *pht_cap = MNULL;
	t_u16 ie_len = 0;
	mlan_ds_misc_tdls_oper tdls_oper;
	t_u8 event_buf[100];
	mlan_event *ptdls_event = (mlan_event *)event_buf;
	tdls_tear_down_event *tdls_evt =
		(tdls_tear_down_event *)ptdls_event->event_buf;
	ENTER();

	/* reason code is not mandatory, hence less by sizeof(t_u16) */
	if (pevent->data_len < (sizeof(Event_tdls_generic) -
				sizeof(t_u16) - sizeof(mlan_event_id))) {
		PRINTM(MERROR, "Invalid length %d for TDLS event\n",
		       pevent->data_len);
		LEAVE();
		return;
	}
	sta_ptr = wlan_get_station_entry(priv, tdls_event->peer_mac_addr);
	PRINTM(MEVENT, "TDLS_EVENT: %d " MACSTR "\n",
	       wlan_le16_to_cpu(tdls_event->event_type),
	       MAC2STR(tdls_event->peer_mac_addr));
	switch (wlan_le16_to_cpu(tdls_event->event_type)) {
	case TDLS_EVENT_TYPE_SETUP_REQ:
		if (sta_ptr == MNULL) {
			sta_ptr =
				wlan_add_station_entry(priv,
						       tdls_event->
						       peer_mac_addr);
			if (sta_ptr) {
				sta_ptr->status = TDLS_SETUP_INPROGRESS;
				wlan_hold_tdls_packets(priv,
						       tdls_event->
						       peer_mac_addr);
			}
		}
		break;

	case TDLS_EVENT_TYPE_LINK_ESTABLISHED:
		if (sta_ptr) {
			sta_ptr->status = TDLS_SETUP_COMPLETE;
			/* parse the TLV for station's capability */
			ie_len = wlan_le16_to_cpu(tdls_event->u.ie_data.
						  ie_length);
			if (ie_len) {
				pht_cap =
					(IEEEtypes_HTCap_t *)
					wlan_get_specific_ie(priv,
							     tdls_event->u.
							     ie_data.ie_ptr,
							     ie_len,
							     HT_CAPABILITY);
				if (pht_cap) {
					sta_ptr->is_11n_enabled = MTRUE;
					if (GETHT_MAXAMSDU
					    (pht_cap->ht_cap.ht_cap_info))
						sta_ptr->max_amsdu =
							MLAN_TX_DATA_BUF_SIZE_8K;
					else
						sta_ptr->max_amsdu =
							MLAN_TX_DATA_BUF_SIZE_4K;
				}
			}
			for (i = 0; i < MAX_NUM_TID; i++) {
				if (sta_ptr->is_11n_enabled)
					sta_ptr->ampdu_sta[i] =
						priv->aggr_prio_tbl[i].
						ampdu_user;
				else
					sta_ptr->ampdu_sta[i] =
						BA_STREAM_NOT_ALLOWED;
			}
			memset(priv->adapter, sta_ptr->rx_seq, 0xff,
			       sizeof(sta_ptr->rx_seq));
			wlan_restore_tdls_packets(priv,
						  tdls_event->peer_mac_addr,
						  TDLS_SETUP_COMPLETE);
			pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
		}
		break;

	case TDLS_EVENT_TYPE_SETUP_FAILURE:
		wlan_restore_tdls_packets(priv, tdls_event->peer_mac_addr,
					  TDLS_SETUP_FAILURE);
		if (sta_ptr)
			wlan_delete_station_entry(priv,
						  tdls_event->peer_mac_addr);
		if (MTRUE == wlan_is_station_list_empty(priv))
			pmadapter->tdls_status = TDLS_NOT_SETUP;
		else
			pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
		break;
	case TDLS_EVENT_TYPE_LINK_TORN_DOWN:
		if (sta_ptr) {
			if (sta_ptr->external_tdls) {
				PRINTM(MMSG,
				       "Receive TDLS TEAR DOWN event, Disable TDLS LINK\n");
				memset(pmadapter, &tdls_oper, 0,
				       sizeof(tdls_oper));
				tdls_oper.tdls_action = WLAN_TDLS_DISABLE_LINK;
				memcpy(priv->adapter, tdls_oper.peer_mac,
				       tdls_event->peer_mac_addr,
				       MLAN_MAC_ADDR_LENGTH);
				/* Send command to firmware to delete tdls link */
				wlan_prepare_cmd(priv,
						 HostCmd_CMD_TDLS_OPERATION,
						 HostCmd_ACT_GEN_SET,
						 0,
						 (t_void *)MNULL, &tdls_oper);
				ptdls_event->bss_index = priv->bss_index;
				ptdls_event->event_id =
					MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
				ptdls_event->event_len =
					sizeof(tdls_tear_down_event);
				memcpy(priv->adapter,
				       (t_u8 *)tdls_evt->peer_mac_addr,
				       tdls_event->peer_mac_addr,
				       MLAN_MAC_ADDR_LENGTH);
				tdls_evt->reason_code =
					wlan_le16_to_cpu(tdls_event->u.
							 reason_code);
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ,
						ptdls_event);
				/* Signal MOAL to trigger mlan_main_process */
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_DEFER_HANDLING,
						MNULL);
				LEAVE();
				return;
			}
			wlan_restore_tdls_packets(priv,
						  tdls_event->peer_mac_addr,
						  TDLS_TEAR_DOWN);
			if (sta_ptr->is_11n_enabled) {
				wlan_cleanup_reorder_tbl(priv,
							 tdls_event->
							 peer_mac_addr);
				pmadapter->callbacks.moal_spin_lock(pmadapter->
								    pmoal_handle,
								    priv->wmm.
								    ra_list_spinlock);
				wlan_11n_cleanup_txbastream_tbl(priv,
								tdls_event->
								peer_mac_addr);
				pmadapter->callbacks.
					moal_spin_unlock(pmadapter->
							 pmoal_handle,
							 priv->wmm.
							 ra_list_spinlock);
			}
			wlan_delete_station_entry(priv,
						  tdls_event->peer_mac_addr);
			if (MTRUE == wlan_is_station_list_empty(priv))
				pmadapter->tdls_status = TDLS_NOT_SETUP;
			else
				pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
		}
		break;
	case TDLS_EVENT_TYPE_CHAN_SWITCH_RESULT:
		PRINTM(MEVENT,
		       "TDLS_CHAN_SWITCH_RESULT: status=0x%x, reason=0x%x current_channel=%d\n",
		       tdls_event->u.switch_result.status,
		       tdls_event->u.switch_result.reason,
		       (int)tdls_event->u.switch_result.current_channel);
		if (tdls_event->u.switch_result.status == MLAN_STATUS_SUCCESS) {
			if (tdls_event->u.switch_result.current_channel ==
			    TDLS_BASE_CHANNEL) {
				/* enable traffic to AP */
				if (pmadapter->tdls_status !=
				    TDLS_IN_BASE_CHANNEL) {
					wlan_update_non_tdls_ralist(priv,
								    tdls_event->
								    peer_mac_addr,
								    MFALSE);
					pmadapter->tdls_status =
						TDLS_IN_BASE_CHANNEL;
				}
			} else if (tdls_event->u.switch_result.
				   current_channel == TDLS_OFF_CHANNEL) {
				/* pause traffic to AP */
				if (pmadapter->tdls_status !=
				    TDLS_IN_OFF_CHANNEL) {
					wlan_update_non_tdls_ralist(priv,
								    tdls_event->
								    peer_mac_addr,
								    MTRUE);
					pmadapter->tdls_status =
						TDLS_IN_OFF_CHANNEL;
				}
			}
		} else {
			if (tdls_event->u.switch_result.current_channel ==
			    TDLS_BASE_CHANNEL)
				pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
			else if (tdls_event->u.switch_result.current_channel ==
				 TDLS_OFF_CHANNEL)
				pmadapter->tdls_status = TDLS_IN_OFF_CHANNEL;
		}
		break;
	case TDLS_EVENT_TYPE_START_CHAN_SWITCH:
		PRINTM(MEVENT, "TDLS start channel switch....\n");
		pmadapter->tdls_status = TDLS_SWITCHING_CHANNEL;
		break;
	case TDLS_EVENT_TYPE_CHAN_SWITCH_STOPPED:
		PRINTM(MEVENT, "TDLS channel switch stopped, reason=%d\n",
		       tdls_event->u.cs_stop_reason);
		break;
	case TDLS_EVENT_TYPE_DEBUG:
	case TDLS_EVENT_TYPE_PACKET:
		break;
	default:
		PRINTM(MERROR, "unknown event type %d\n",
		       wlan_le16_to_cpu(tdls_event->event_type));
		break;
	}
	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
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;
}