/** 
 *  @brief This function handles the command response of
 *  		a block ack response
 *  
 *  @param priv    A pointer to mlan_private structure
 *  @param resp    A pointer to HostCmd_DS_COMMAND
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_11n_addba_resp(mlan_private * priv, HostCmd_DS_COMMAND * resp)
{
    HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp = (HostCmd_DS_11N_ADDBA_RSP *)
        & resp->params.add_ba_rsp;
    int tid;
    RxReorderTbl *rx_reor_tbl_ptr = MNULL;

    ENTER();

    padd_ba_rsp->status_code = wlan_le16_to_cpu(padd_ba_rsp->status_code);
    padd_ba_rsp->block_ack_param_set =
        wlan_le16_to_cpu(padd_ba_rsp->block_ack_param_set);
    padd_ba_rsp->block_ack_tmo = wlan_le16_to_cpu(padd_ba_rsp->block_ack_tmo);
    padd_ba_rsp->ssn = wlan_le16_to_cpu(padd_ba_rsp->ssn);

    tid = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_TID_MASK)
        >> BLOCKACKPARAM_TID_POS;
    /* Check if we had rejected the ADDBA, if yes then do not create the stream */
    if (padd_ba_rsp->status_code == BA_RESULT_SUCCESS) {
        PRINTM(MCMND,
               "ADDBA RSP: %02x:%02x:%02x:%02x:%02x:%02x tid=%d ssn=%d win_size=%d\n",
               padd_ba_rsp->peer_mac_addr[0], padd_ba_rsp->peer_mac_addr[1],
               padd_ba_rsp->peer_mac_addr[2], padd_ba_rsp->peer_mac_addr[3],
               padd_ba_rsp->peer_mac_addr[4], padd_ba_rsp->peer_mac_addr[5],
               tid, padd_ba_rsp->ssn,
               ((padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_WINSIZE_MASK)
                >> BLOCKACKPARAM_WINSIZE_POS));
    } else {
/** 
 *  @brief This function handles the command response of
 *  		a block ack response
 *  
 *  @param priv    A pointer to mlan_private structure
 *  @param resp    A pointer to HostCmd_DS_COMMAND
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_11n_addba_resp(mlan_private * priv, HostCmd_DS_COMMAND * resp)
{
    HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp = (HostCmd_DS_11N_ADDBA_RSP *)
        & resp->params.add_ba_rsp;
    int tid, win_size;

    ENTER();

    padd_ba_rsp->status_code = wlan_le16_to_cpu(padd_ba_rsp->status_code);
    padd_ba_rsp->block_ack_param_set =
        wlan_le16_to_cpu(padd_ba_rsp->block_ack_param_set);
    padd_ba_rsp->block_ack_tmo = wlan_le16_to_cpu(padd_ba_rsp->block_ack_tmo);
    padd_ba_rsp->ssn = wlan_le16_to_cpu(padd_ba_rsp->ssn);

    tid = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_TID_MASK)
        >> BLOCKACKPARAM_TID_POS;
    win_size = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_WINSIZE_MASK)
        >> BLOCKACKPARAM_WINSIZE_POS;

    wlan_11n_create_rxreorder_tbl(priv, padd_ba_rsp->peer_mac_addr, tid,
                                  win_size, padd_ba_rsp->ssn);

    PRINTM(MEVENT, "ADDBA: %02x:%02x:%02x:%02x:%02x:%02x tid=%d\n",
           padd_ba_rsp->peer_mac_addr[0], padd_ba_rsp->peer_mac_addr[1],
           padd_ba_rsp->peer_mac_addr[2], padd_ba_rsp->peer_mac_addr[3],
           padd_ba_rsp->peer_mac_addr[4], padd_ba_rsp->peer_mac_addr[5], tid);

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Пример #3
0
static int wlan_ret_802_11_snmp_mib(WlanCard *cardinfo,
		HostCmd_DS_COMMAND * resp)
{
	WlanCard *card = cardinfo;
	HostCmd_DS_802_11_SNMP_MIB *smib = &resp->params.smib;
	u16 OID = wlan_le16_to_cpu(smib->OID);
	u16 QueryType = wlan_le16_to_cpu(smib->QueryType);

	WlanDebug(WlanMsg, "SNMP_RESP: value of the OID = %x, QueryType=%x\n", OID,
			QueryType);

	if (QueryType == HostCmd_ACT_GEN_GET)
	{
		switch (OID)
		{
		case FragThresh_i:
			card->FragThsd = (*((u16*) (smib->Value)));
			WlanDebug(WlanEncy,"SNMP_RESP: FragThsd =%u\n",card->FragThsd);
			break;
		case RtsThresh_i:
			card->RTSThsd = (*((u16*) (smib->Value)));
			WlanDebug(WlanEncy,"SNMP_RESP: RTSThsd =%u\n", card->RTSThsd);
			break;
		case ShortRetryLim_i:
			card->TxRetryCount = (*((u16*) (smib->Value)));
			WlanDebug(WlanEncy,"SNMP_RESP: TxRetryCount =%u\n",card->TxRetryCount);
			break;
		default:
			break;
		}
	}

	return WLAN_STATUS_SUCCESS;
}
Пример #4
0
/**
 *  @brief This function implements command CMD_802_11D_DOMAIN_INFO
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure of
 *                        command buffer
 *  @param cmd_action   Command action
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_802_11d_domain_info(mlan_private * pmpriv,
			     HostCmd_DS_COMMAND * pcmd, t_u16 cmd_action)
{
	mlan_adapter *pmadapter = pmpriv->adapter;
	HostCmd_DS_802_11D_DOMAIN_INFO *pdomain_info =
		&pcmd->params.domain_info;
	MrvlIEtypes_DomainParamSet_t *domain = &pdomain_info->domain;
	t_u8 no_of_sub_band = pmadapter->domain_reg.no_of_sub_band;

	ENTER();

	PRINTM(MINFO, "11D: number of sub-band=0x%x\n", no_of_sub_band);

	pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO);
	pdomain_info->action = wlan_cpu_to_le16(cmd_action);
	if (cmd_action == HostCmd_ACT_GEN_GET) {
		/* Dump domain info */
		pcmd->size =
			wlan_cpu_to_le16(sizeof(pdomain_info->action) +
					 S_DS_GEN);
		HEXDUMP("11D: 802_11D_DOMAIN_INFO", (t_u8 *) pcmd,
			wlan_le16_to_cpu(pcmd->size));
		LEAVE();
		return MLAN_STATUS_SUCCESS;
	}

	/* Set domain info fields */
	domain->header.type = wlan_cpu_to_le16(TLV_TYPE_DOMAIN);
	memcpy(pmadapter, domain->country_code,
	       pmadapter->domain_reg.country_code,
	       sizeof(domain->country_code));

	domain->header.len =
		((no_of_sub_band * sizeof(IEEEtypes_SubbandSet_t)) +
		 sizeof(domain->country_code));

	if (no_of_sub_band) {
		memcpy(pmadapter, domain->sub_band,
		       pmadapter->domain_reg.sub_band,
		       MIN(MRVDRV_MAX_SUBBAND_802_11D,
			   no_of_sub_band) * sizeof(IEEEtypes_SubbandSet_t));

		pcmd->size = wlan_cpu_to_le16(sizeof(pdomain_info->action) +
					      domain->header.len +
					      sizeof(MrvlIEtypesHeader_t) +
					      S_DS_GEN);
	} else {
		pcmd->size =
			wlan_cpu_to_le16(sizeof(pdomain_info->action) +
					 S_DS_GEN);
	}
	domain->header.len = wlan_cpu_to_le16(domain->header.len);

	HEXDUMP("11D: 802_11D_DOMAIN_INFO", (t_u8 *) pcmd,
		wlan_le16_to_cpu(pcmd->size));

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}
Пример #5
0
static int
wlan_ret_802_11_rssi(WlanCard *cardinfo, HostCmd_DS_COMMAND * resp)
{
    HostCmd_DS_802_11_RSSI_RSP *rssirsp = &resp->params.rssirsp;
    WlanCard *card = cardinfo;

    rt_kprintf("snr: %d, noise: %d\n", wlan_le16_to_cpu(rssirsp->SNR), wlan_le16_to_cpu(rssirsp->NoiseFloor));
    rt_kprintf("avg snr: %d, avg noise: %d\n", wlan_le16_to_cpu(rssirsp->AvgSNR), wlan_le16_to_cpu(rssirsp->AvgNoiseFloor));

    return WLAN_STATUS_SUCCESS;
}
/** 
  *  @brief This function prepares command for adding a block ack
  *  		response.
  *  
  *  @param priv        A pointer to mlan_private structure
  *  @param cmd         A pointer to HostCmd_DS_COMMAND structure
  *  @param pdata_buf   A pointer to data buffer
  *
  *  @return            MLAN_STATUS_SUCCESS
  */
mlan_status
wlan_cmd_11n_addba_rspgen(mlan_private * priv,
                          HostCmd_DS_COMMAND * cmd, void *pdata_buf)
{
    HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp = (HostCmd_DS_11N_ADDBA_RSP *)
        & cmd->params.add_ba_rsp;
    HostCmd_DS_11N_ADDBA_REQ *pevt_addba_req =
        (HostCmd_DS_11N_ADDBA_REQ *) pdata_buf;
    t_u8 tid = 0;
    int win_size = 0;

    ENTER();

    pevt_addba_req->block_ack_param_set =
        wlan_le16_to_cpu(pevt_addba_req->block_ack_param_set);
    pevt_addba_req->block_ack_tmo =
        wlan_le16_to_cpu(pevt_addba_req->block_ack_tmo);
    pevt_addba_req->ssn = wlan_le16_to_cpu(pevt_addba_req->ssn);

    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP);
    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_ADDBA_RSP) + S_DS_GEN);

    memcpy(priv->adapter, padd_ba_rsp->peer_mac_addr,
           pevt_addba_req->peer_mac_addr, MLAN_MAC_ADDR_LENGTH);
    padd_ba_rsp->dialog_token = pevt_addba_req->dialog_token;
    padd_ba_rsp->block_ack_tmo =
        wlan_cpu_to_le16(pevt_addba_req->block_ack_tmo);
    padd_ba_rsp->ssn = wlan_cpu_to_le16(pevt_addba_req->ssn);

    padd_ba_rsp->block_ack_param_set = pevt_addba_req->block_ack_param_set;
    tid = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_TID_MASK)
        >> BLOCKACKPARAM_TID_POS;
    if (priv->addba_reject[tid])
        padd_ba_rsp->status_code = wlan_cpu_to_le16(ADDBA_RSP_STATUS_DECLINED);
    else
        padd_ba_rsp->status_code = wlan_cpu_to_le16(ADDBA_RSP_STATUS_ACCEPT);
    padd_ba_rsp->block_ack_param_set &= ~BLOCKACKPARAM_WINSIZE_MASK;
    /* We donot support AMSDU inside AMPDU, hence reset the bit */
    padd_ba_rsp->block_ack_param_set &= ~BLOCKACKPARAM_AMSDU_SUPP_MASK;
    padd_ba_rsp->block_ack_param_set |= (priv->add_ba_param.rx_win_size <<
                                         BLOCKACKPARAM_WINSIZE_POS);
    win_size = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_WINSIZE_MASK)
        >> BLOCKACKPARAM_WINSIZE_POS;
    padd_ba_rsp->block_ack_param_set =
        wlan_cpu_to_le16(padd_ba_rsp->block_ack_param_set);

    wlan_11n_create_rxreorder_tbl(priv, pevt_addba_req->peer_mac_addr, tid,
                                  win_size, pevt_addba_req->ssn);
    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
/** 
 *  @brief This function queues the command to cmd list.
 *  
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pcmd_node    A pointer to cmd_ctrl_node structure
 *  @param add_tail      Specify if the cmd needs to be queued in the header or tail
 *
 *  @return             N/A
 */
t_void
wlan_insert_cmd_to_pending_q(IN mlan_adapter * pmadapter,
                             IN cmd_ctrl_node * pcmd_node, IN t_u32 add_tail)
{
    HostCmd_DS_COMMAND *pcmd = MNULL;
    t_u16 command;

    ENTER();

    if (pcmd_node == MNULL) {
        PRINTM(MERROR, "QUEUE_CMD: pcmd_node is MNULL\n");
        goto done;
    }

    pcmd =
        (HostCmd_DS_COMMAND *) (pcmd_node->cmdbuf->pbuf +
                                pcmd_node->cmdbuf->data_offset);
    if (pcmd == MNULL) {
        PRINTM(MERROR, "QUEUE_CMD: pcmd is MNULL\n");
        goto done;
    }

    command = wlan_le16_to_cpu(pcmd->command);

/* Exit_PS command needs to be queued in the header always. */
    if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
        HostCmd_DS_802_11_PS_MODE_ENH *pm = &pcmd->params.psmode_enh;
        if (wlan_le16_to_cpu(pm->action) == DIS_PS) {
            if (pmadapter->ps_state != PS_STATE_AWAKE)
                add_tail = MFALSE;
        }
    }

    if (add_tail) {
        util_enqueue_list_tail(&pmadapter->cmd_pending_q,
                               (pmlan_linked_list) pcmd_node,
                               pmadapter->callbacks.moal_spin_lock,
                               pmadapter->callbacks.moal_spin_unlock);
    } else {
        util_enqueue_list_head(&pmadapter->cmd_pending_q,
                               (pmlan_linked_list) pcmd_node,
                               pmadapter->callbacks.moal_spin_lock,
                               pmadapter->callbacks.moal_spin_unlock);
    }

    PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x is queued\n", command);

  done:
    LEAVE();
    return;
}
Пример #8
0
/** 
 *  @brief This function handles the command response of 11ncfg
 *  
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         A pointer to HostCmd_DS_COMMAND
 *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_11n_cfg(IN pmlan_private pmpriv,
                 IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
{
    mlan_ds_11n_cfg *cfg = MNULL;
    HostCmd_DS_11N_CFG *htcfg = &resp->params.htcfg;

    ENTER();
    if (pioctl_buf) {
        cfg = (mlan_ds_11n_cfg *) pioctl_buf->pbuf;
        cfg->param.tx_cfg.httxcap = wlan_le16_to_cpu(htcfg->ht_tx_cap);
        cfg->param.tx_cfg.httxinfo = wlan_le16_to_cpu(htcfg->ht_tx_info);
    }
    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Пример #9
0
/** 
 *  @brief This function handles the command response of
 *              delete a block ack request
 *  
 *  @param priv    A pointer to mlan_private structure
 *  @param resp    A pointer to HostCmd_DS_COMMAND
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_11n_delba(mlan_private * priv, HostCmd_DS_COMMAND * resp)
{
    int tid;
    TxBAStreamTbl *ptx_ba_tbl;
    HostCmd_DS_11N_DELBA *pdel_ba =
        (HostCmd_DS_11N_DELBA *) & resp->params.del_ba;

    ENTER();

    pdel_ba->del_ba_param_set = wlan_le16_to_cpu(pdel_ba->del_ba_param_set);
    pdel_ba->reason_code = wlan_le16_to_cpu(pdel_ba->reason_code);

    tid = pdel_ba->del_ba_param_set >> DELBA_TID_POS;
    if (pdel_ba->del_result == BA_RESULT_SUCCESS) {
        mlan_11n_delete_bastream_tbl(priv, tid, pdel_ba->peer_mac_addr,
                                     TYPE_DELBA_SENT,
                                     INITIATOR_BIT(pdel_ba->del_ba_param_set));

        if ((ptx_ba_tbl = wlan_11n_get_txbastream_status(priv,
                                                         BA_STREAM_SETUP_INPROGRESS)))
        {
            wlan_send_addba(priv, ptx_ba_tbl->tid, ptx_ba_tbl->ra);
        }
    } else {                    /* 
                                 * In case of failure, recreate the deleted stream in
                                 * case we initiated the ADDBA
                                 */
        if (INITIATOR_BIT(pdel_ba->del_ba_param_set)) {
            wlan_11n_create_txbastream_tbl(priv, pdel_ba->peer_mac_addr, tid,
                                           BA_STREAM_SETUP_INPROGRESS);
            if ((ptx_ba_tbl = wlan_11n_get_txbastream_status(priv,
                                                             BA_STREAM_SETUP_INPROGRESS)))
            {
                mlan_11n_delete_bastream_tbl(priv, ptx_ba_tbl->tid,
                                             ptx_ba_tbl->ra, TYPE_DELBA_SENT,
                                             MTRUE);
            }
        }
    }

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
/**
 *  @brief This function reads data from the card.
 *
 *  @param pmadapter 	A pointer to mlan_adapter structure
 *  @param type	   	A pointer to keep type as data or command
 *  @param nb		A pointer to keep the data/cmd length returned in buffer
 *  @param pmbuf 	A pointer to the SDIO data/cmd buffer
 *  @param npayload	the length of data/cmd buffer
 *  @param ioport	the SDIO ioport
 *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
wlan_sdio_card_to_host(mlan_adapter * pmadapter,
		       t_u32 * type, t_u32 * nb, pmlan_buffer pmbuf,
		       t_u32 npayload, t_u32 ioport)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_callbacks pcb = &pmadapter->callbacks;

	ENTER();

	if (!pmbuf) {
		PRINTM(MWARN, "pmbuf is NULL!\n");
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

	ret = pcb->moal_read_data_sync(pmadapter->pmoal_handle, pmbuf, ioport,
				       0);

	if (ret != MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "card_to_host, read iomem failed: %d\n", ret);
		pmbuf->status_code = MLAN_ERROR_DATA_RX_FAIL;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}
	*nb = wlan_le16_to_cpu(*(t_u16 *) (pmbuf->pbuf + pmbuf->data_offset));
	if (*nb > npayload) {
		PRINTM(MERROR, "invalid packet, *nb=%d, npayload=%d\n", *nb,
		       npayload);
		pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

	DBG_HEXDUMP(MIF_D, "SDIO Blk Rd", pmbuf->pbuf + pmbuf->data_offset,
		    MIN(*nb, MAX_DATA_DUMP_LEN));

	*type = wlan_le16_to_cpu(*(t_u16 *)
				 (pmbuf->pbuf + pmbuf->data_offset + 2));

exit:
	LEAVE();
	return ret;
}
Пример #11
0
/** 
 *  @brief This function handle response of CMD_802_11D_DOMAIN_INFO
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         Pointer to command response buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_ret_802_11d_domain_info(mlan_private * pmpriv, HostCmd_DS_COMMAND * resp)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    HostCmd_DS_802_11D_DOMAIN_INFO_RSP *domain_info =
        &resp->params.domain_info_resp;
    MrvlIEtypes_DomainParamSet_t *domain = &domain_info->domain;
    t_u16 action = wlan_le16_to_cpu(domain_info->action);
    t_u8 no_of_sub_band = 0;

    ENTER();

    /* Dump domain info response data */
    HEXDUMP("11D: DOMAIN Info Rsp Data", (t_u8 *) resp, resp->size);

    no_of_sub_band =
        (t_u8) ((wlan_le16_to_cpu(domain->header.len) -
                 3) / sizeof(IEEEtypes_SubbandSet_t));
    /* Country code is 3 bytes */

    PRINTM(MINFO, "11D Domain Info Resp: number of sub-band=%d\n",
           no_of_sub_band);

    if (no_of_sub_band > MRVDRV_MAX_SUBBAND_802_11D) {
        PRINTM(MWARN, "11D: Invalid number of subbands %d returned!!\n",
               no_of_sub_band);
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    switch (action) {
    case HostCmd_ACT_GEN_SET:  /* Proc Set Action */
        break;
    case HostCmd_ACT_GEN_GET:
        break;
    default:
        PRINTM(MERROR, "11D: Invalid Action:%d\n", domain_info->action);
        ret = MLAN_STATUS_FAILURE;
        break;
    }

    LEAVE();
    return ret;
}
Пример #12
0
/** 
 *  @brief This function handles the command response of
 *              add a block ack request
 *  
 *  @param priv    A pointer to mlan_private structure
 *  @param resp    A pointer to HostCmd_DS_COMMAND
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_11n_addba_req(mlan_private * priv, HostCmd_DS_COMMAND * resp)
{
    int tid;
    HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp =
        (HostCmd_DS_11N_ADDBA_RSP *) & resp->params.add_ba_rsp;
    TxBAStreamTbl *ptx_ba_tbl;

    ENTER();

    padd_ba_rsp->block_ack_param_set =
        wlan_le16_to_cpu(padd_ba_rsp->block_ack_param_set);
    padd_ba_rsp->block_ack_tmo = wlan_le16_to_cpu(padd_ba_rsp->block_ack_tmo);
    padd_ba_rsp->ssn = (wlan_le16_to_cpu(padd_ba_rsp->ssn)) & SSN_MASK;
    padd_ba_rsp->status_code = wlan_le16_to_cpu(padd_ba_rsp->status_code);

    tid = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_TID_MASK)
        >> BLOCKACKPARAM_TID_POS;
    if (padd_ba_rsp->status_code == BA_RESULT_SUCCESS) {
        if ((ptx_ba_tbl = wlan_11n_get_txbastream_tbl(priv, tid,
                                                      padd_ba_rsp->
                                                      peer_mac_addr))) {
            PRINTM(MINFO, "BA stream complete\n");
            ptx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
        } else {
            PRINTM(MERROR, "BA stream not created\n");
        }
    } else {
        mlan_11n_delete_bastream_tbl(priv, tid, padd_ba_rsp->peer_mac_addr,
                                     TYPE_DELBA_SENT, MTRUE);
        if (padd_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) {
#ifdef UAP_SUPPORT
            if (priv->bss_type == MLAN_BSS_TYPE_UAP)
                disable_station_ampdu(priv, tid, padd_ba_rsp->peer_mac_addr);
#endif /* UAP_SUPPORT */
            priv->aggr_prio_tbl[tid].ampdu_ap = BA_STREAM_NOT_ALLOWED;
        }
    }

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Пример #13
0
/** 
 *  @brief This function handles the command response of
 *  		delete a block ack request
 *  
 *  @param priv		A pointer to mlan_private structure
 *  @param del_ba	A pointer to command response buffer
 *
 *  @return        N/A
 */
void
wlan_11n_delete_bastream(mlan_private * priv, t_u8 * del_ba)
{
    HostCmd_DS_11N_DELBA *pdel_ba = (HostCmd_DS_11N_DELBA *) del_ba;
    int tid;

    ENTER();

    DBG_HEXDUMP(MCMD_D, "Delba:", (t_u8 *) pdel_ba, 20);
    pdel_ba->del_ba_param_set = wlan_le16_to_cpu(pdel_ba->del_ba_param_set);
    pdel_ba->reason_code = wlan_le16_to_cpu(pdel_ba->reason_code);

    tid = pdel_ba->del_ba_param_set >> DELBA_TID_POS;

    mlan_11n_delete_bastream_tbl(priv, tid, pdel_ba->peer_mac_addr,
                                 TYPE_DELBA_RECEIVE,
                                 INITIATOR_BIT(pdel_ba->del_ba_param_set));

    LEAVE();
}
Пример #14
0
/** 
 *  @brief This function handles the command response of amsdu aggr ctrl
 *  
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         A pointer to HostCmd_DS_COMMAND
 *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_amsdu_aggr_ctrl(IN pmlan_private pmpriv,
                         IN HostCmd_DS_COMMAND * resp,
                         IN mlan_ioctl_req * pioctl_buf)
{
    mlan_ds_11n_cfg *cfg = MNULL;
    HostCmd_DS_AMSDU_AGGR_CTRL *amsdu_ctrl = &resp->params.amsdu_aggr_ctrl;

    ENTER();

    if (pioctl_buf) {
        cfg = (mlan_ds_11n_cfg *) pioctl_buf->pbuf;
        cfg->param.amsdu_aggr_ctrl.enable =
            wlan_le16_to_cpu(amsdu_ctrl->enable);
        cfg->param.amsdu_aggr_ctrl.curr_buf_size =
            wlan_le16_to_cpu(amsdu_ctrl->curr_buf_size);
    }
    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Пример #15
0
/** 
 *  @brief This function handles the command response of fw_wakeup_method
 *  
 *  @param priv    A pointer to wlan_private structure
 *  @param resp	   A pointer to HostCmd_DS_COMMAND
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
static int wlan_ret_fw_wakeup_method(WlanCard *cardInfo,
		HostCmd_DS_COMMAND * resp)
{
	WlanCard *card = cardInfo;
	HostCmd_DS_802_11_FW_WAKEUP_METHOD *fwwm = &resp->params.fwwakeupmethod;
	u16 action;

	action = wlan_le16_to_cpu(fwwm->Action);

	switch (action)
	{
	case HostCmd_ACT_GET:
	case HostCmd_ACT_SET:
		card->fwWakeupMethod = wlan_le16_to_cpu(fwwm->Method);
		break;
	default:
		break;
	}
	return WLAN_STATUS_SUCCESS;
}
Пример #16
0
/**
 *  @brief Debug print display of the input measurement report
 *
 *  @param pmeas_rpt  Pointer to measurement report to display
 *
 *  @return          N/A
 */
static void
wlan_meas_dump_meas_rpt(const HostCmd_DS_MEASUREMENT_REPORT * pmeas_rpt)
{
    ENTER();

    PRINTM(MINFO, "Meas: Rpt: ------------------------------\n");
    PRINTM(MINFO, "Meas: Rpt: mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
           pmeas_rpt->mac_addr[0],
           pmeas_rpt->mac_addr[1],
           pmeas_rpt->mac_addr[2],
           pmeas_rpt->mac_addr[3],
           pmeas_rpt->mac_addr[4], pmeas_rpt->mac_addr[5]);

    PRINTM(MINFO, "Meas: Rpt:  dlgTkn: %d\n", pmeas_rpt->dialog_token);

    PRINTM(MINFO, "Meas: Rpt: rptMode: (%x): Rfs[%c] ICp[%c] Lt[%c]\n",
           *(t_u8 *) & pmeas_rpt->rpt_mode,
           pmeas_rpt->rpt_mode.refused ? 'X' : ' ',
           pmeas_rpt->rpt_mode.incapable ? 'X' : ' ',
           pmeas_rpt->rpt_mode.late ? 'X' : ' ');
#ifdef DEBUG_LEVEL2
    PRINTM(MINFO, "Meas: Rpt: measTyp: %s\n",
           wlan_meas_get_meas_type_str(pmeas_rpt->meas_type));
#endif

    switch (pmeas_rpt->meas_type) {
    case WLAN_MEAS_BASIC:
        PRINTM(MINFO, "Meas: Rpt: chan: %u\n", pmeas_rpt->rpt.basic.channel);
        PRINTM(MINFO, "Meas: Rpt: strt: %llu\n",
               wlan_le64_to_cpu(pmeas_rpt->rpt.basic.start_time));
        PRINTM(MINFO, "Meas: Rpt:  dur: %u\n",
               wlan_le16_to_cpu(pmeas_rpt->rpt.basic.duration));
        PRINTM(MINFO, "Meas: Rpt:  bas: (%x): unmsd[%c], radar[%c]\n",
               *(t_u8 *) & (pmeas_rpt->rpt.basic.map),
               pmeas_rpt->rpt.basic.map.unmeasured ? 'X' : ' ',
               pmeas_rpt->rpt.basic.map.radar ? 'X' : ' ');
        PRINTM(MINFO, "Meas: Rpt:  bas: unidSig[%c] ofdm[%c] bss[%c]\n",
               pmeas_rpt->rpt.basic.map.unidentified_sig ? 'X' : ' ',
               pmeas_rpt->rpt.basic.map.ofdm_preamble ? 'X' : ' ',
               pmeas_rpt->rpt.basic.map.bss ? 'X' : ' ');
        break;
    default:
        PRINTM(MINFO, "Meas: Rpt: <unhandled>\n");
        break;
    }

    PRINTM(MINFO, "Meas: Rpt: ------------------------------\n");
    LEAVE();
}
Пример #17
0
/**
 *  @brief Debug print display of the input measurement request
 *
 *  @param pmeas_req  Pointer to the measurement request to display
 *
 *  @return          N/A
 */
static void
wlan_meas_dump_meas_req(const HostCmd_DS_MEASUREMENT_REQUEST * pmeas_req)
{
    ENTER();

    PRINTM(MINFO, "Meas: Req: ------------------------------\n");

    PRINTM(MINFO, "Meas: Req: mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
           pmeas_req->mac_addr[0],
           pmeas_req->mac_addr[1],
           pmeas_req->mac_addr[2],
           pmeas_req->mac_addr[3],
           pmeas_req->mac_addr[4], pmeas_req->mac_addr[5]);

    PRINTM(MINFO, "Meas: Req:  dlgTkn: %d\n", pmeas_req->dialog_token);
    PRINTM(MINFO, "Meas: Req:    mode: dm[%c] rpt[%c] req[%c]\n",
           pmeas_req->req_mode.duration_mandatory ? 'X' : ' ',
           pmeas_req->req_mode.report ? 'X' : ' ',
           pmeas_req->req_mode.request ? 'X' : ' ');
    PRINTM(MINFO, "Meas: Req:        : en[%c] par[%c]\n",
           pmeas_req->req_mode.enable ? 'X' : ' ',
           pmeas_req->req_mode.parallel ? 'X' : ' ');
#ifdef DEBUG_LEVEL2
    PRINTM(MINFO, "Meas: Req: measTyp: %s\n",
           wlan_meas_get_meas_type_str(pmeas_req->meas_type));
#endif

    switch (pmeas_req->meas_type) {
    case WLAN_MEAS_BASIC:
        /* Lazy cheat, fields of bas, cca, rpi union match on the request */
        PRINTM(MINFO, "Meas: Req: chan: %u\n", pmeas_req->req.basic.channel);
        PRINTM(MINFO, "Meas: Req: strt: %llu\n",
               wlan_le64_to_cpu(pmeas_req->req.basic.start_time));
        PRINTM(MINFO, "Meas: Req:  dur: %u\n",
               wlan_le16_to_cpu(pmeas_req->req.basic.duration));
        break;
    default:
        PRINTM(MINFO, "Meas: Req: <unhandled>\n");
        break;
    }

    PRINTM(MINFO, "Meas: Req: ------------------------------\n");
    LEAVE();
}
Пример #18
0
/** 
 *  @brief This function handles the command response of rf_tx_power
 *  
 *  @param priv    A pointer to wlan_private structure
 *  @param resp	   A pointer to HostCmd_DS_COMMAND
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
static int wlan_ret_802_11_rf_tx_power(WlanCard *cardinfo,
		HostCmd_DS_COMMAND * resp)
{
	HostCmd_DS_802_11_RF_TX_POWER *rtp = &resp->params.txp;
	WlanCard *card = cardinfo;
	u16 Action = (rtp->Action);

	card->TxPowerLevel = wlan_le16_to_cpu(rtp->CurrentLevel);

	if (Action == HostCmd_ACT_GET)
	{
		card->MaxTxPowerLevel = rtp->MaxPower;
		card->MinTxPowerLevel = rtp->MinPower;
	}

	WlanDebug(WlanMsg,"Current TxPower Level = %d,Max Power=%d, Min Power=%d\n",
			card->TxPowerLevel, card->MaxTxPowerLevel,
			card->MinTxPowerLevel);
	return WLAN_STATUS_SUCCESS;
}
/** 
 *  @brief This function handles the command response of host_cmd
 *  
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         A pointer to HostCmd_DS_COMMAND
 *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
static mlan_status
wlan_ret_host_cmd(IN pmlan_private pmpriv,
                  IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
{
    mlan_ds_misc_cfg *misc;
    t_u16 size = wlan_le16_to_cpu(resp->size);

    ENTER();

    PRINTM(MINFO, "host command response size = %d\n", size);
    size = MIN(size, MRVDRV_SIZE_OF_CMD_BUFFER);
    if (pioctl_buf) {
        misc = (mlan_ds_misc_cfg *) pioctl_buf->pbuf;
        misc->param.hostcmd.len = size;
        memcpy(misc->param.hostcmd.cmd, (void *) resp, size);
    }

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Пример #20
0
/**
 *  @brief  Check if intended address field is configured.
 *          If yes, update the corresponding device ID.
 *  @param  wfd_buf      WFD buffer pointer
 *  @param  wfd_buf_len  WFD buffer length
 *
 *  @return  WPS_STATUS_SUCCESS--success, WPS_STATUS_FAIL--fail
 */
static int wfd_check_set_intended_addr(u8 *wfd_buf, u16 wfd_buf_len)
{
	tlvbuf_wfd_intended_addr *wfd_tlv;
	u8 *ptr = wfd_buf;
	s16 left_len = wfd_buf_len;
	u16 len = 0;

	ENTER();

	ptr += sizeof(wifidir_oui_type);

	while (left_len > WFD_IE_HEADER_LEN) {

		if (*ptr == TLV_TYPE_WFD_INTENDED_ADDRESS) {
			wfd_tlv = (tlvbuf_wfd_intended_addr *) ptr;

			/* Address is found, set it now */
			wps_printf(DEBUG_WFD_DISCOVERY,
				   "Intended address. " MACSTR,
				   MAC2STR(wfd_tlv->group_address));

			memcpy(gpwps_info->wfd_intended_addr,
			       wfd_tlv->group_address, ETH_ALEN);
			LEAVE();
			return WPS_STATUS_SUCCESS;
		}

		memcpy(&len, ptr + 1, sizeof(u16));
		len = wlan_le16_to_cpu(len);

		ptr += len + WFD_IE_HEADER_LEN;
		left_len -= len + WFD_IE_HEADER_LEN;
	}

	LEAVE();
	return WPS_STATUS_FAIL;
}
Пример #21
0
/**
 *  @brief  Check if P2P capability attr is present in the P2P IE.
 *          If yes, return the value of it.
 *  @param  wfd_buf      WFD buffer pointer
 *  @param  wfd_buf_len  WFD buffer length
 *  @param  dev_cap pointer to device capability
 *  @param  grp_cap pointer to group capability
 *
 *  @return  WPS_STATUS_SUCCESS--success, WPS_STATUS_FAIL--fail
 */
static int
wfd_get_p2p_cap_attribute(u8 *wfd_buf, u16 wfd_buf_len,
			  u8 *dev_cap, u8 *grp_cap)
{
	tlvbuf_wfd_capability *wfd_tlv;
	u8 *ptr = wfd_buf;
	s16 left_len = wfd_buf_len;
	u16 len = 0;

	ENTER();

	wps_hexdump(DEBUG_WLAN, "WFD IE:", (u8 *) wfd_buf, wfd_buf_len);

	ptr += sizeof(wifidir_oui_type);

	while (left_len > WFD_IE_HEADER_LEN) {

		if (*ptr == TLV_TYPE_WFD_CAPABILITY) {
			wfd_tlv = (tlvbuf_wfd_capability *) ptr;
			*dev_cap = wfd_tlv->dev_capability;
			*grp_cap = wfd_tlv->group_capability;

			LEAVE();
			return WPS_STATUS_SUCCESS;
		}

		memcpy(&len, ptr + 1, sizeof(u16));
		len = wlan_le16_to_cpu(len);

		ptr += len + WFD_IE_HEADER_LEN;
		left_len -= len + WFD_IE_HEADER_LEN;
	}

	LEAVE();
	return WPS_STATUS_FAIL;
}
/**
 *  @brief This function will process tx pause event
 *
 *  @param priv    A pointer to mlan_private
 *  @param pevent  A pointer to event buf
 *
 *  @return        N/A
 */
static void
wlan_process_sta_tx_pause_event(pmlan_private priv, pmlan_buffer pevent)
{
	t_u16 tlv_type, tlv_len;
	int tlv_buf_left = pevent->data_len - sizeof(t_u32);
	MrvlIEtypesHeader_t *tlv =
		(MrvlIEtypesHeader_t *)(pevent->pbuf + pevent->data_offset +
					sizeof(t_u32));
	MrvlIEtypes_tx_pause_t *tx_pause_tlv;
	sta_node *sta_ptr = MNULL;
	tdlsStatus_e status;
	t_u8 *bssid = MNULL;
	ENTER();
	if (priv->media_connected)
		bssid = priv->curr_bss_params.bss_descriptor.mac_address;
	while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
		tlv_type = wlan_le16_to_cpu(tlv->type);
		tlv_len = wlan_le16_to_cpu(tlv->len);
		if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
		    (unsigned int)tlv_buf_left) {
			PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
			       tlv_len, tlv_buf_left);
			break;
		}
		if (tlv_type == TLV_TYPE_TX_PAUSE) {
			tx_pause_tlv = (MrvlIEtypes_tx_pause_t *)tlv;
			PRINTM(MCMND, "TxPause: " MACSTR " pause=%d, pkts=%d\n",
			       MAC2STR(tx_pause_tlv->peermac),
			       tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt);
			if (bssid &&
			    !memcmp(priv->adapter, bssid, tx_pause_tlv->peermac,
				    MLAN_MAC_ADDR_LENGTH)) {
				if (tx_pause_tlv->tx_pause)
					priv->port_open = MFALSE;
				else
					priv->port_open = MTRUE;
			} else {
				status = wlan_get_tdls_link_status(priv,
								   tx_pause_tlv->
								   peermac);
				if (MTRUE == wlan_is_tdls_link_setup(status)) {
					sta_ptr =
						wlan_get_station_entry(priv,
								       tx_pause_tlv->
								       peermac);
					if (sta_ptr) {
						if (sta_ptr->tx_pause !=
						    tx_pause_tlv->tx_pause) {
							sta_ptr->tx_pause =
								tx_pause_tlv->
								tx_pause;
							wlan_update_ralist_tx_pause
								(priv,
								 tx_pause_tlv->
								 peermac,
								 tx_pause_tlv->
								 tx_pause);
						}
					}
				}
			}
		}
		tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
		tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
					      sizeof(MrvlIEtypesHeader_t));
	}

	LEAVE();
	return;
}
Пример #23
0
/**
 *  @brief This function processes received packet and forwards it
 *          to kernel/upper layer
 *
 *  @param adapter   A pointer to mlan_adapter
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_ops_uap_process_rx_packet(IN t_void *adapter, IN pmlan_buffer pmbuf)
{
	pmlan_adapter pmadapter = (pmlan_adapter)adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	UapRxPD *prx_pd;
	wlan_mgmt_pkt *puap_pkt_hdr = MNULL;

	RxPacketHdr_t *prx_pkt;
	pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
	t_u8 ta[MLAN_MAC_ADDR_LENGTH];
	t_u16 rx_pkt_type = 0;
	sta_node *sta_ptr = MNULL;
	t_u8 adj_rx_rate = 0;

	ENTER();

	prx_pd = (UapRxPD *)(pmbuf->pbuf + pmbuf->data_offset);
	/* Endian conversion */
	uap_endian_convert_RxPD(prx_pd);
	priv->rxpd_rate = prx_pd->rx_rate;

	priv->rxpd_rate_info = prx_pd->rate_info;
	if (!priv->adapter->psdio_device->v15_fw_api)
		priv->rxpd_rate_info =
			wlan_convert_v14_rate_ht_info(priv->rxpd_rate_info);

	if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
		adj_rx_rate =
			wlan_adjust_data_rate(priv, priv->rxpd_rate,
					      priv->rxpd_rate_info);
		pmadapter->callbacks.moal_hist_data_add(pmadapter->pmoal_handle,
							pmbuf->bss_index,
							adj_rx_rate,
							prx_pd->snr, prx_pd->nf,
							prx_pd->antenna);
	}

	rx_pkt_type = prx_pd->rx_pkt_type;
	prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);

	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);

	if ((prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length) !=
	    (t_u16)pmbuf->data_len) {
		PRINTM(MERROR,
		       "Wrong rx packet: len=%d,rx_pkt_offset=%d,"
		       " rx_pkt_length=%d\n", pmbuf->data_len,
		       prx_pd->rx_pkt_offset, prx_pd->rx_pkt_length);
		pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
		ret = MLAN_STATUS_FAILURE;
		wlan_free_mlan_buffer(pmadapter, pmbuf);
		goto done;
	}
	pmbuf->data_len = prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length;

	if (pmadapter->priv[pmbuf->bss_index]->mgmt_frame_passthru_mask &&
	    prx_pd->rx_pkt_type == PKT_TYPE_MGMT_FRAME) {
		/* Check if this is mgmt packet and needs to forwarded to app
		   as an event */
		puap_pkt_hdr =
			(wlan_mgmt_pkt *)((t_u8 *)prx_pd +
					  prx_pd->rx_pkt_offset);
		puap_pkt_hdr->frm_len = wlan_le16_to_cpu(puap_pkt_hdr->frm_len);
		if ((puap_pkt_hdr->wlan_header.
		     frm_ctl & IEEE80211_FC_MGMT_FRAME_TYPE_MASK) == 0)
			wlan_process_802dot11_mgmt_pkt(pmadapter->
						       priv[pmbuf->bss_index],
						       (t_u8 *)&puap_pkt_hdr->
						       wlan_header,
						       puap_pkt_hdr->frm_len +
						       sizeof(wlan_mgmt_pkt) -
						       sizeof(puap_pkt_hdr->
							      frm_len),
						       (RxPD *)prx_pd);
		wlan_free_mlan_buffer(pmadapter, pmbuf);
		goto done;
	}

	pmbuf->priority = prx_pd->priority;
	memcpy(pmadapter, ta, prx_pkt->eth803_hdr.src_addr,
	       MLAN_MAC_ADDR_LENGTH);
	if ((rx_pkt_type != PKT_TYPE_BAR) && (prx_pd->priority < MAX_NUM_TID)) {
		sta_ptr = wlan_get_station_entry(priv, ta);
		if (sta_ptr)
			sta_ptr->rx_seq[prx_pd->priority] = prx_pd->seq_num;
	}
	/* check if UAP enable 11n */
	if (!priv->is_11n_enabled ||
	    (!wlan_11n_get_rxreorder_tbl
	     ((mlan_private *)priv, prx_pd->priority, ta)
	     && (prx_pd->rx_pkt_type != PKT_TYPE_AMSDU)
	    )) {
		if (priv->pkt_fwd)
			wlan_process_uap_rx_packet(priv, pmbuf);
		else
			wlan_upload_uap_rx_packet(pmadapter, pmbuf);
		goto done;
	}
	/* Reorder and send to OS */
	ret = mlan_11n_rxreorder_pkt(priv, prx_pd->seq_num,
				     prx_pd->priority, ta,
				     (t_u8)prx_pd->rx_pkt_type, (void *)pmbuf);
	if (ret || (rx_pkt_type == PKT_TYPE_BAR)) {
		wlan_free_mlan_buffer(pmadapter, pmbuf);
	}
done:
	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
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 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 receives data from the card in aggregate mode.
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *  @param pmbuf      A pointer to the SDIO data/cmd buffer
 *  @param port      Current port on which packet needs to be rxed
 *  @param rx_len    Length of received packet
 *  @return 	     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
wlan_sdio_card_to_host_mp_aggr(mlan_adapter * pmadapter, mlan_buffer
			       * pmbuf, t_u8 port, t_u16 rx_len)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	t_s32 f_do_rx_aggr = 0;
	t_s32 f_do_rx_cur = 0;
	t_s32 f_aggr_cur = 0;
	mlan_buffer mbuf_aggr;
	mlan_buffer *mbuf_deaggr;
	t_u32 pind = 0;
	t_u32 pkt_len, pkt_type = 0;
	t_u8 *curr_ptr;
	t_u32 cmd53_port = 0;

	ENTER();

	if (port == CTRL_PORT) {
		/* Read the command response or event without aggr */
		PRINTM(MINFO,
		       "card_2_host_mp_aggr: No aggr for control port\n");

		f_do_rx_cur = 1;
		goto rx_curr_single;
	}

	if (!pmadapter->mpa_rx.enabled) {
		PRINTM(MINFO,
		       "card_2_host_mp_aggr: rx aggregation disabled !\n");

		f_do_rx_cur = 1;
		goto rx_curr_single;
	}

	if (pmadapter->mp_rd_bitmap & (~((t_u32) CTRL_PORT_MASK))) {
		/* Some more data RX pending */
		PRINTM(MINFO, "card_2_host_mp_aggr: Not last packet\n");

		if (MP_RX_AGGR_IN_PROGRESS(pmadapter)) {
			if (MP_RX_AGGR_BUF_HAS_ROOM(pmadapter, rx_len)) {
				f_aggr_cur = 1;
			} else {
				/* No room in Aggr buf, do rx aggr now */
				f_do_rx_aggr = 1;
				f_do_rx_cur = 1;
			}
		} else {
			/* Rx aggr not in progress */
			f_aggr_cur = 1;
		}

	} else {
		/* No more data RX pending */
		PRINTM(MINFO, "card_2_host_mp_aggr: Last packet\n");

		if (MP_RX_AGGR_IN_PROGRESS(pmadapter)) {
			f_do_rx_aggr = 1;
			if (MP_RX_AGGR_BUF_HAS_ROOM(pmadapter, rx_len)) {
				f_aggr_cur = 1;
			} else {
				/* No room in Aggr buf, do rx aggr now */
				f_do_rx_cur = 1;
			}
		} else {
			f_do_rx_cur = 1;
		}

	}

	if (f_aggr_cur) {
		PRINTM(MINFO, "Current packet aggregation.\n");
		/* Curr pkt can be aggregated */
		MP_RX_AGGR_SETUP(pmadapter, pmbuf, port, rx_len);

		if (MP_RX_AGGR_PKT_LIMIT_REACHED(pmadapter) ||
		    MP_RX_AGGR_PORT_LIMIT_REACHED(pmadapter)) {
			PRINTM(MINFO,
			       "card_2_host_mp_aggr: Aggregation Packet limit reached\n");
			/* No more pkts allowed in Aggr buf, rx it */
			f_do_rx_aggr = 1;
		}
	}

	if (f_do_rx_aggr) {
		/* do aggr RX now */
		PRINTM(MINFO, "do_rx_aggr: num of packets: %d\n",
		       pmadapter->mpa_rx.pkt_cnt);

		memset(pmadapter, &mbuf_aggr, 0, sizeof(mlan_buffer));

		mbuf_aggr.pbuf = (t_u8 *) pmadapter->mpa_rx.buf;
		mbuf_aggr.data_len = pmadapter->mpa_rx.buf_len;
		cmd53_port = (pmadapter->ioport | SDIO_MPA_ADDR_BASE |
			      (pmadapter->mpa_rx.ports << 4)) +
			pmadapter->mpa_rx.start_port;
		if (MLAN_STATUS_SUCCESS !=
		    pcb->moal_read_data_sync(pmadapter->pmoal_handle,
					     &mbuf_aggr, cmd53_port, 0)) {
			pmbuf->status_code = MLAN_ERROR_DATA_RX_FAIL;
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}

		DBG_HEXDUMP(MIF_D, "SDIO MP-A Blk Rd", pmadapter->mpa_rx.buf,
			    MIN(pmadapter->mpa_rx.buf_len, MAX_DATA_DUMP_LEN));

		curr_ptr = pmadapter->mpa_rx.buf;

		for (pind = 0; pind < pmadapter->mpa_rx.pkt_cnt; pind++) {

			/* get curr PKT len & type */
			pkt_len = wlan_le16_to_cpu(*(t_u16 *) & curr_ptr[0]);
			pkt_type = wlan_le16_to_cpu(*(t_u16 *) & curr_ptr[2]);

			PRINTM(MINFO, "RX: [%d] pktlen: %d pkt_type: 0x%x\n",
			       pind, pkt_len, pkt_type);

			/* copy pkt to deaggr buf */
			mbuf_deaggr = pmadapter->mpa_rx.mbuf_arr[pind];
			if ((pkt_type == MLAN_TYPE_DATA) &&
			    (pkt_len <= pmadapter->mpa_rx.len_arr[pind])) {
				memcpy(pmadapter,
				       mbuf_deaggr->pbuf +
				       mbuf_deaggr->data_offset, curr_ptr,
				       pkt_len);
				pmadapter->upld_len = pkt_len;
				/* Process de-aggr packet */
				wlan_decode_rx_packet(pmadapter, mbuf_deaggr,
						      pkt_type);
			} else {
				PRINTM(MERROR,
				       "Wrong aggr packet: type=%d, len=%d, max_len=%d\n",
				       pkt_type, pkt_len,
				       pmadapter->mpa_rx.len_arr[pind]);
				wlan_free_mlan_buffer(pmadapter, mbuf_deaggr);
			}
			curr_ptr += pmadapter->mpa_rx.len_arr[pind];
		}
		MP_RX_AGGR_BUF_RESET(pmadapter);
	}

rx_curr_single:
	if (f_do_rx_cur) {
		PRINTM(MINFO, "RX: f_do_rx_cur: port: %d rx_len: %d\n", port,
		       rx_len);

		if (MLAN_STATUS_SUCCESS !=
		    wlan_sdio_card_to_host(pmadapter, &pkt_type,
					   (t_u32 *) & pmadapter->upld_len,
					   pmbuf, rx_len,
					   pmadapter->ioport + port)) {
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		if ((port == CTRL_PORT) && ((pkt_type != MLAN_TYPE_EVENT) &&
					    (pkt_type != MLAN_TYPE_CMD))) {
			PRINTM(MERROR,
			       "Wrong pkt from CTRL PORT: type=%d, len=%dd\n",
			       pkt_type, pmbuf->data_len);
			pmbuf->status_code = MLAN_ERROR_DATA_RX_FAIL;
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		wlan_decode_rx_packet(pmadapter, pmbuf, pkt_type);
	}

done:
	if (ret == MLAN_STATUS_FAILURE) {
		if (MP_RX_AGGR_IN_PROGRESS(pmadapter)) {
			/* MP-A transfer failed - cleanup */
			for (pind = 0; pind < pmadapter->mpa_rx.pkt_cnt; pind++) {
				wlan_free_mlan_buffer(pmadapter,
						      pmadapter->mpa_rx.
						      mbuf_arr[pind]);
			}
			MP_RX_AGGR_BUF_RESET(pmadapter);
		}

		if (f_do_rx_cur) {
			/* Single Transfer pending */
			/* Free curr buff also */
			wlan_free_mlan_buffer(pmadapter, pmbuf);
		}
	}

	LEAVE();
	return ret;

}
Пример #27
0
/**
 *   @brief This function processes the received buffer
 *
 *   @param adapter A pointer to mlan_adapter
 *   @param pmbuf     A pointer to the received buffer
 *
 *   @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_ops_sta_process_rx_packet(IN t_void * adapter, IN pmlan_buffer pmbuf)
{
	pmlan_adapter pmadapter = (pmlan_adapter) adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	RxPD *prx_pd;
	RxPacketHdr_t *prx_pkt;
	pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
	t_u8 ta[MLAN_MAC_ADDR_LENGTH];
	t_u16 rx_pkt_type = 0;
	wlan_mgmt_pkt *pmgmt_pkt_hdr = MNULL;
	ENTER();

	prx_pd = (RxPD *) (pmbuf->pbuf + pmbuf->data_offset);
	/* Endian conversion */
	endian_convert_RxPD(prx_pd);
	rx_pkt_type = prx_pd->rx_pkt_type;
	prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset);

	if ((prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length) >
	    (t_u16) pmbuf->data_len) {
		PRINTM(MERROR,
		       "Wrong rx packet: len=%d,rx_pkt_offset=%d,"
		       " rx_pkt_length=%d\n", pmbuf->data_len,
		       prx_pd->rx_pkt_offset, prx_pd->rx_pkt_length);
		pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
		ret = MLAN_STATUS_FAILURE;
		wlan_free_mlan_buffer(pmadapter, pmbuf);
		goto done;
	}
	pmbuf->data_len = prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length;

	if (pmadapter->priv[pmbuf->bss_index]->mgmt_frame_passthru_mask &&
	    prx_pd->rx_pkt_type == PKT_TYPE_MGMT_FRAME) {
		/* Check if this is mgmt packet and needs to forwarded to app
		   as an event */
		pmgmt_pkt_hdr =
			(wlan_mgmt_pkt *) ((t_u8 *) prx_pd +
					   prx_pd->rx_pkt_offset);
		pmgmt_pkt_hdr->frm_len =
			wlan_le16_to_cpu(pmgmt_pkt_hdr->frm_len);

		if ((pmgmt_pkt_hdr->wlan_header.frm_ctl
		     & IEEE80211_FC_MGMT_FRAME_TYPE_MASK) == 0)
			wlan_process_802dot11_mgmt_pkt(pmadapter->
						       priv[pmbuf->bss_index],
						       (t_u8 *) &
						       pmgmt_pkt_hdr->
						       wlan_header,
						       pmgmt_pkt_hdr->frm_len +
						       sizeof(wlan_mgmt_pkt)
						       -
						       sizeof(pmgmt_pkt_hdr->
							      frm_len));
		wlan_free_mlan_buffer(pmadapter, pmbuf);
		goto done;
	}

	/*
	 * If the packet is not an unicast packet then send the packet
	 * directly to os. Don't pass thru rx reordering
	 */
	if (!IS_11N_ENABLED(priv) ||
	    memcmp(priv->adapter, priv->curr_addr,
		   prx_pkt->eth803_hdr.dest_addr, MLAN_MAC_ADDR_LENGTH)) {
		wlan_process_rx_packet(pmadapter, pmbuf);
		goto done;
	}

	if (queuing_ra_based(priv)) {
		memcpy(pmadapter, ta, prx_pkt->eth803_hdr.src_addr,
		       MLAN_MAC_ADDR_LENGTH);
	} else {
		if ((rx_pkt_type != PKT_TYPE_BAR) &&
		    (prx_pd->priority < MAX_NUM_TID))
			priv->rx_seq[prx_pd->priority] = prx_pd->seq_num;
		memcpy(pmadapter, ta,
		       priv->curr_bss_params.bss_descriptor.mac_address,
		       MLAN_MAC_ADDR_LENGTH);
	}

	/* Reorder and send to OS */
	if ((ret = mlan_11n_rxreorder_pkt(priv, prx_pd->seq_num,
					  prx_pd->priority, ta,
					  (t_u8) prx_pd->rx_pkt_type,
					  (void *)pmbuf)) ||
	    (rx_pkt_type == PKT_TYPE_BAR)
		) {
		wlan_free_mlan_buffer(pmadapter, pmbuf);
	}

done:

	LEAVE();
	return (ret);
}
Пример #28
0
/**
 *   @brief This function processes the received buffer
 *
 *   @param adapter A pointer to mlan_adapter
 *   @param pmbuf     A pointer to the received buffer
 *
 *   @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_ops_sta_process_rx_packet(IN t_void *adapter, IN pmlan_buffer pmbuf)
{
	pmlan_adapter pmadapter = (pmlan_adapter)adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	RxPD *prx_pd;
	RxPacketHdr_t *prx_pkt;
	pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
	t_u8 ta[MLAN_MAC_ADDR_LENGTH];
	t_u16 rx_pkt_type = 0;
	wlan_mgmt_pkt *pmgmt_pkt_hdr = MNULL;
	sta_node *sta_ptr = MNULL;
	ENTER();

	prx_pd = (RxPD *)(pmbuf->pbuf + pmbuf->data_offset);
	/* Endian conversion */
	endian_convert_RxPD(prx_pd);
	rx_pkt_type = prx_pd->rx_pkt_type;
	prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);

	if ((prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length) >
	    (t_u16)pmbuf->data_len) {
		PRINTM(MERROR,
		       "Wrong rx packet: len=%d,rx_pkt_offset=%d,"
		       " rx_pkt_length=%d\n", pmbuf->data_len,
		       prx_pd->rx_pkt_offset, prx_pd->rx_pkt_length);
		pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
		ret = MLAN_STATUS_FAILURE;
		wlan_free_mlan_buffer(pmadapter, pmbuf);
		goto done;
	}
	pmbuf->data_len = prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length;

	if (pmadapter->priv[pmbuf->bss_index]->mgmt_frame_passthru_mask &&
	    prx_pd->rx_pkt_type == PKT_TYPE_MGMT_FRAME) {
		/* Check if this is mgmt packet and needs to forwarded to app
		   as an event */
		pmgmt_pkt_hdr =
			(wlan_mgmt_pkt *)((t_u8 *)prx_pd +
					  prx_pd->rx_pkt_offset);
		pmgmt_pkt_hdr->frm_len =
			wlan_le16_to_cpu(pmgmt_pkt_hdr->frm_len);

		if ((pmgmt_pkt_hdr->wlan_header.frm_ctl
		     & IEEE80211_FC_MGMT_FRAME_TYPE_MASK) == 0){
			wlan_process_802dot11_mgmt_pkt(pmadapter->
						       priv[pmbuf->bss_index],
						       (t_u8 *)&pmgmt_pkt_hdr->
						       wlan_header,
						       pmgmt_pkt_hdr->frm_len +
						       sizeof(wlan_mgmt_pkt)
						       -
						       sizeof(pmgmt_pkt_hdr->
							      frm_len),prx_pd);

			wlan_sta_check_mgmt_frame(pmadapter->priv[pmbuf->bss_index],
						  (t_u8 *) &pmgmt_pkt_hdr->wlan_header,
						  pmgmt_pkt_hdr->frm_len +
						  sizeof(wlan_mgmt_pkt) -
						  sizeof(pmgmt_pkt_hdr->frm_len),
						  prx_pd);
		}
		wlan_free_mlan_buffer(pmadapter, pmbuf);
		goto done;
	}

	/*
	 * If the packet is not an unicast packet then send the packet
	 * directly to os. Don't pass thru rx reordering
	 */
	if ((!IS_11N_ENABLED(priv) &&
	     !(prx_pd->flags & RXPD_FLAG_PKT_DIRECT_LINK)) ||
	    memcmp(priv->adapter, priv->curr_addr,
		   prx_pkt->eth803_hdr.dest_addr, MLAN_MAC_ADDR_LENGTH)) {
		wlan_process_rx_packet(pmadapter, pmbuf);
		goto done;
	}

	if (queuing_ra_based(priv) ||
	    (prx_pd->flags & RXPD_FLAG_PKT_DIRECT_LINK)) {
		memcpy(pmadapter, ta, prx_pkt->eth803_hdr.src_addr,
		       MLAN_MAC_ADDR_LENGTH);
		if ((prx_pd->flags & RXPD_FLAG_PKT_DIRECT_LINK) &&
		    (prx_pd->priority < MAX_NUM_TID)) {
			PRINTM(MDATA, "tdls packet %p " MACSTR "\n", pmbuf,
			       MAC2STR(ta));
			sta_ptr = wlan_get_station_entry(priv, ta);
			if (sta_ptr) {
				sta_ptr->rx_seq[prx_pd->priority] =
					prx_pd->seq_num;
				sta_ptr->snr = prx_pd->snr;
				sta_ptr->nf = prx_pd->nf;
				pmadapter->callbacks.
					moal_updata_peer_signal(pmadapter->
								pmoal_handle,
								pmbuf->
								bss_index, ta,
								prx_pd->snr,
								prx_pd->nf);
			}
		}
	} else {
		if ((rx_pkt_type != PKT_TYPE_BAR) &&
		    (prx_pd->priority < MAX_NUM_TID))
			priv->rx_seq[prx_pd->priority] = prx_pd->seq_num;
		memcpy(pmadapter, ta,
		       priv->curr_bss_params.bss_descriptor.mac_address,
		       MLAN_MAC_ADDR_LENGTH);
	}

	if ((priv->port_ctrl_mode == MTRUE && priv->port_open == MFALSE) &&
	    (rx_pkt_type != PKT_TYPE_BAR)) {
		mlan_11n_rxreorder_pkt(priv, prx_pd->seq_num, prx_pd->priority,
				       ta, (t_u8)prx_pd->rx_pkt_type,
				       (t_void *)RX_PKT_DROPPED_IN_FW);
		wlan_process_rx_packet(pmadapter, pmbuf);
		goto done;
	}

	/* Reorder and send to OS */
	ret = mlan_11n_rxreorder_pkt(priv, prx_pd->seq_num,
				     prx_pd->priority, ta,
				     (t_u8)prx_pd->rx_pkt_type, (void *)pmbuf);
	if (ret || (rx_pkt_type == PKT_TYPE_BAR)
		) {
		wlan_free_mlan_buffer(pmadapter, pmbuf);
	}

done:

	LEAVE();
	return ret;
}
Пример #29
0
/**
 *   @brief This function processes the received buffer
 *     
 *   @param adapter A pointer to mlan_adapter
 *   @param pmbuf     A pointer to the received buffer
 *
 *   @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_ops_sta_process_rx_packet(IN t_void * adapter, IN pmlan_buffer pmbuf)
{
    pmlan_adapter pmadapter = (pmlan_adapter) adapter;
    mlan_status ret = MLAN_STATUS_SUCCESS;
    RxPD *prx_pd;
    RxPacketHdr_t *prx_pkt;
    pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
    t_u8 ta[MLAN_MAC_ADDR_LENGTH];
    t_u16 rx_pkt_type = 0;
    /* wlan_mgmt_pkt *pmgmt_pkt_hdr = MNULL; */
    ENTER();

    prx_pd = (RxPD *) (pmbuf->pbuf + pmbuf->data_offset);
    /* Endian conversion */
    endian_convert_RxPD(prx_pd);
    rx_pkt_type = prx_pd->rx_pkt_type;
    
    /* Note: We do not have data @ some offset of pbuf. pbuf only has RxPD */
    /* prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset); */
    prx_pkt = (RxPacketHdr_t *) pmbuf->pdesc;

    /* wmprintf("%p + %d: O: %d PL: %d DL: %d\n\r", */
    /* 	     pmbuf->pbuf, pmbuf->data_offset, */
    /* 	     prx_pd->rx_pkt_offset, prx_pd->rx_pkt_length, pmbuf->data_len); */

    if ((prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length) >
        (t_u16) pmbuf->data_len) {
        PRINTM(MERROR,
               "Wrong rx packet: len=%d,rx_pkt_offset=%d,"
               " rx_pkt_length=%d\n", pmbuf->data_len, prx_pd->rx_pkt_offset,
               prx_pd->rx_pkt_length);
        pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
        ret = MLAN_STATUS_FAILURE;
        wlan_free_mlan_buffer(pmadapter, pmbuf);
        goto done;
    }
    pmbuf->data_len = prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length;

    if (pmadapter->priv[pmbuf->bss_index]->mgmt_frame_passthru_mask &&
        prx_pd->rx_pkt_type == PKT_TYPE_MGMT_FRAME) {
        /* Check if this is mgmt packet and needs to forwarded to app as an
           event */

	    /* fixme */
	    wmprintf("Is a management packet expected here?\n\r");
	    os_enter_critical_section();
	    while(1){}
#ifndef CONFIG_MLAN_WMSDK
    /* Note: We do not have data @ some offset of pbuf. pbuf only has RxPD */
        /* pmgmt_pkt_hdr = */
        /*     (wlan_mgmt_pkt *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset); */
	pmgmt_pkt_hdr = (wlan_mgmt_pkt *)pmbuf->pdesc;

        pmgmt_pkt_hdr->frm_len = wlan_le16_to_cpu(pmgmt_pkt_hdr->frm_len);

        if ((pmgmt_pkt_hdr->wlan_header.frm_ctl
             & IEEE80211_FC_MGMT_FRAME_TYPE_MASK) == 0)
            wlan_process_802dot11_mgmt_pkt(pmadapter->priv[pmbuf->bss_index],
                                           (t_u8 *) & pmgmt_pkt_hdr->
                                           wlan_header,
                                           pmgmt_pkt_hdr->frm_len +
                                           sizeof(wlan_mgmt_pkt)
                                           - sizeof(pmgmt_pkt_hdr->frm_len));
        wlan_free_mlan_buffer(pmadapter, pmbuf);
        goto done;
#endif /* CONFIG_MLAN_WMSDK */
    }

#ifdef DUMP_PACKET_MAC
    dump_mac_addr("Own: ", priv->curr_addr);
    dump_mac_addr("Dest: ", prx_pkt->eth803_hdr.dest_addr);
#endif /* DUMP_PACKET_MAC */

    /* 
     * If the packet is not an unicast packet then send the packet
     * directly to os. Don't pass thru rx reordering
     */
    if (!IS_11N_ENABLED(priv) ||
        memcmp(priv->adapter, priv->curr_addr, prx_pkt->eth803_hdr.dest_addr,
               MLAN_MAC_ADDR_LENGTH)) {
        wlan_process_rx_packet(pmadapter, pmbuf);
        goto done;
    }

    if (queuing_ra_based(priv)) {
        memcpy(pmadapter, ta, prx_pkt->eth803_hdr.src_addr,
               MLAN_MAC_ADDR_LENGTH);
    } else {
        if ((rx_pkt_type != PKT_TYPE_BAR) && (prx_pd->priority < MAX_NUM_TID))
            priv->rx_seq[prx_pd->priority] = prx_pd->seq_num;
        memcpy(pmadapter, ta,
               priv->curr_bss_params.bss_descriptor.mac_address,
               MLAN_MAC_ADDR_LENGTH);
    }

    /* Reorder and send to OS */
    if ((ret = mlan_11n_rxreorder_pkt(priv, prx_pd->seq_num,
                                      prx_pd->priority, ta,
                                      (t_u8) prx_pd->rx_pkt_type,
                                      (void *) pmbuf)) ||
        (rx_pkt_type == PKT_TYPE_BAR)
        ) {
        wlan_free_mlan_buffer(pmadapter, pmbuf);
    }

  done:

    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;
}