Esempio n. 1
0
/**
 *
 *  @brief  Prepare the HostCmd_DS_Command structure for an 11h command.
 *
 *  Use the Command field to determine if the command being set up is for
 *     11h and call one of the local command handlers accordingly for:
 *
 *        - HostCmd_CMD_802_11_TPC_ADAPT_REQ
 *        - HostCmd_CMD_802_11_TPC_INFO
 *        - HostCmd_CMD_802_11_CHAN_SW_ANN
 *
 *  @param priv      Private driver information structure
 *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared 
 *                   for the firmware
 *  @param pinfo_buf Void buffer pass through with data necessary for a
 *                   specific command type
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 *
 *  @sa wlan_11h_cmd_tpc_request
 *  @sa wlan_11h_cmd_tpc_info
 *  @sa wlan_11h_cmd_chan_sw_ann
 */
int
wlan_11h_cmd_process(mlan_private * priv,
                     HostCmd_DS_COMMAND * pcmd_ptr, const t_void * pinfo_buf)
{
    int ret = MLAN_STATUS_SUCCESS;

    ENTER();
    switch (pcmd_ptr->command) {
    case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
        ret = wlan_11h_cmd_tpc_request(priv, pcmd_ptr, pinfo_buf);
        break;
    case HostCmd_CMD_802_11_TPC_INFO:
        ret = wlan_11h_cmd_tpc_info(priv, pcmd_ptr, pinfo_buf);
        break;
    case HostCmd_CMD_802_11_CHAN_SW_ANN:
        ret = wlan_11h_cmd_chan_sw_ann(priv, pcmd_ptr, pinfo_buf);
        break;
    default:
        ret = MLAN_STATUS_FAILURE;
    }

    pcmd_ptr->command = wlan_cpu_to_le16(pcmd_ptr->command);
    pcmd_ptr->size = wlan_cpu_to_le16(pcmd_ptr->size);
    LEAVE();
    return ret;
}
Esempio n. 2
0
/**
 *  @brief Convert an IEEE formatted IE to 16-bit ID/Len Marvell
 *         proprietary format
 *
 *  @param pout_buf Output parameter: Buffer to output Marvell formatted IE
 *  @param pin_ie   Pointer to IEEE IE to be converted to Marvell format
 *
 *  @return         Number of bytes output to pout_buf parameter return
 */
static int
wlan_11h_convert_ieee_to_mrvl_ie(char *pout_buf, const char *pin_ie)
{
    MrvlIEtypesHeader_t mrvl_ie_hdr;
    char *ptmp_buf = pout_buf;

    ENTER();
    /* Assign the Element Id and Len to the Marvell struct attributes */
    mrvl_ie_hdr.type = wlan_cpu_to_le16(pin_ie[0]);
    mrvl_ie_hdr.len = wlan_cpu_to_le16(pin_ie[1]);

    /* If the element ID is zero, return without doing any copying */
    if (!mrvl_ie_hdr.type)
        return 0;

    /* Copy the header to the buffer pointer */
    memcpy(ptmp_buf, &mrvl_ie_hdr, sizeof(mrvl_ie_hdr));

    /* Increment the temp buffer pointer by the size appended */
    ptmp_buf += sizeof(mrvl_ie_hdr);

    /* Append the data section of the IE; length given by the IEEE IE length */
    memcpy(ptmp_buf, pin_ie + 2, pin_ie[1]);

    LEAVE();
    /* Return the number of bytes appended to pout_buf */
    return (sizeof(mrvl_ie_hdr) + pin_ie[1]);
}
/** 
 *  @brief This function prepares command of reconfigure tx buf
 *  
 *  @param priv         A pointer to mlan_private structure
 *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   The action: GET or SET
 *  @param pdata_buf    A pointer to data buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_recfg_tx_buf(mlan_private * priv,
                      HostCmd_DS_COMMAND * cmd, int cmd_action, void *pdata_buf)
{
    HostCmd_DS_TXBUF_CFG *ptx_buf = &cmd->params.tx_buf;
    t_u16 action = (t_u16) cmd_action;
    t_u16 buf_size = *((t_u16 *) pdata_buf);

    ENTER();
    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF);
    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_TXBUF_CFG)
                                 + S_DS_GEN);
    ptx_buf->action = wlan_cpu_to_le16(action);
    switch (action) {
    case HostCmd_ACT_GEN_SET:
        PRINTM(MCMND, "set tx_buf = %d\n", buf_size);
        ptx_buf->buff_size = wlan_cpu_to_le16(buf_size);
        break;
    case HostCmd_ACT_GEN_GET:
    default:
        ptx_buf->buff_size = 0;
        break;
    }
    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
/** 
 *  @brief This function prepares command of amsdu aggr control
 *  
 *  @param priv         A pointer to mlan_private structure
 *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   The action: GET or SET
 *  @param pdata_buf    A pointer to data buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_amsdu_aggr_ctrl(mlan_private * priv,
                         HostCmd_DS_COMMAND * cmd,
                         int cmd_action, void *pdata_buf)
{
    HostCmd_DS_AMSDU_AGGR_CTRL *pamsdu_ctrl = &cmd->params.amsdu_aggr_ctrl;
    t_u16 action = (t_u16) cmd_action;
    mlan_ds_11n_amsdu_aggr_ctrl *aa_ctrl = (mlan_ds_11n_amsdu_aggr_ctrl *)
        pdata_buf;

    ENTER();

    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL);
    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_AMSDU_AGGR_CTRL)
                                 + S_DS_GEN);
    pamsdu_ctrl->action = wlan_cpu_to_le16(action);
    switch (action) {
    case HostCmd_ACT_GEN_SET:
        pamsdu_ctrl->enable = wlan_cpu_to_le16(aa_ctrl->enable);
        pamsdu_ctrl->curr_buf_size = 0;
        break;
    case HostCmd_ACT_GEN_GET:
    default:
        pamsdu_ctrl->curr_buf_size = 0;
        break;
    }
    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Esempio n. 5
0
int wifi_uap_tx_power_getset(uint8_t action, uint8_t *tx_power_dbm)
{
	uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1;

	wifi_get_command_lock();
	HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();

	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
	HostCmd_DS_SYS_CONFIG *sys_config_cmd =
	    (HostCmd_DS_SYS_CONFIG *) ((uint32_t) cmd + S_DS_GEN);
	uint8_t *tlv = sys_config_cmd->tlv_buffer;

	 MrvlIEtypes_tx_power_t *tlv_tx_power = (MrvlIEtypes_tx_power_t *) tlv;

	if (action == HostCmd_ACT_GEN_GET)
		sys_config_cmd->action = HostCmd_ACT_GEN_GET;
	else {
		sys_config_cmd->action = HostCmd_ACT_GEN_SET;
		tlv_tx_power->tx_power = *tx_power_dbm;
	}
	tlv_tx_power->header.type = wlan_cpu_to_le16(TLV_TYPE_UAP_TX_POWER);
	tlv_tx_power->header.len = wlan_cpu_to_le16(sizeof(t_u8));

	size += sizeof(MrvlIEtypes_tx_power_t);
	tlv += sizeof(MrvlIEtypes_tx_power_t);

	cmd->size = size;
	cmd->seq_num = (0x01) << 12;
	cmd->result = 0x00;

	wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ?
						tx_power_dbm : NULL);

	return wm_wifi.cmd_resp_status;
}
Esempio n. 6
0
int wlan_cmd_802_11_exit_pm(WlanCard *cardinfo)
{
	WlanCard *card = cardinfo;
	HostCmd_DS_COMMAND *cmd = NULL;
	int ret = WLAN_STATUS_SUCCESS;

	cmd = (HostCmd_DS_COMMAND*) rt_malloc (sizeof(HostCmd_DS_COMMAND));
	if (cmd != RT_NULL)
	{
		rt_memset(cmd, 0, sizeof(HostCmd_DS_COMMAND));

		card->SeqNum++;
		cmd->SeqNum = card->SeqNum;
		cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE);
		cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_CMD_802_11_PS_MODE) + S_DS_GEN);

		cmd->params.psmode.Action = 0x0031; /* PM EXIT */
		cmd->params.psmode.NullPktInterval = 0x2E;
		cmd->params.psmode.MultipleDtim = 0x00;

		ret = WlanExecuteCommand(card, cmd);
		if (ret)
		{
			WlanDebug(WlanErr,"faild to send command\n");
			ret = WLAN_STATUS_FAILURE;
		}

		rt_free(cmd);
		return ret;
	}
	ret = WLAN_STATUS_FAILURE;

	return ret;
}
Esempio n. 7
0
int wlan_cmd_802_11_get_log(WlanCard *cardinfo)
{
	WlanCard *card = cardinfo;
	HostCmd_DS_COMMAND *cmd = NULL;
	int ret = WLAN_STATUS_SUCCESS;

	cmd = (HostCmd_DS_COMMAND*) rt_malloc (sizeof(HostCmd_DS_COMMAND));
	if (cmd != RT_NULL)
	{
		rt_memset(cmd, 0, sizeof(HostCmd_DS_COMMAND));

		card->SeqNum++;
		cmd->SeqNum = card->SeqNum;
		cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
		cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_GET_LOG) + S_DS_GEN);

		ret = WlanExecuteCommand(card, cmd);
		if (ret)
		{
			WlanDebug(WlanErr,"Failure for send RSSI\n");
			ret = WLAN_STATUS_FAILURE;
		}

		rt_free(cmd);
		return ret;
	}
	ret = WLAN_STATUS_FAILURE;

	return ret;
}
Esempio n. 8
0
/**
 *  @brief Prepare CMD_802_11_TPC_INFO firmware command
 *
 *  @param priv      Private driver information structure
 *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared 
 *                   for the firmware
 *  @param pinfo_buf wlan_11h_tpc_info_param_t passed as void data block
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static int
wlan_11h_cmd_tpc_info(mlan_private * priv,
                      HostCmd_DS_COMMAND * pcmd_ptr, const t_void * pinfo_buf)
{
    HostCmd_DS_802_11_TPC_INFO *ptpc_info = &pcmd_ptr->params.tpc_info;
    MrvlIEtypes_LocalPowerConstraint_t *pconstraint =
        &ptpc_info->local_constraint;
    MrvlIEtypes_PowerCapability_t *pcap = &ptpc_info->power_cap;

    wlan_11h_state_t *pstate = &priv->adapter->state_11h;
    const wlan_11h_tpc_info_param_t *ptpc_info_param =
        (wlan_11h_tpc_info_param_t *) pinfo_buf;

    ENTER();

    pcap->min_power = pstate->min_tx_power_capability;
    pcap->max_power = pstate->max_tx_power_capability;
    pcap->header.len = wlan_cpu_to_le16(2);
    pcap->header.type = wlan_cpu_to_le16(TLV_TYPE_POWER_CAPABILITY);

    pconstraint->chan = ptpc_info_param->chan;
    pconstraint->constraint = ptpc_info_param->power_constraint;
    pconstraint->header.type = wlan_cpu_to_le16(TLV_TYPE_POWER_CONSTRAINT);
    pconstraint->header.len = wlan_cpu_to_le16(2);

    /* Converted to little endian in wlan_11h_cmd_process */
    pcmd_ptr->size = sizeof(HostCmd_DS_802_11_TPC_INFO) + S_DS_GEN;

    HEXDUMP("11h: TPC INFO", (t_u8 *) pcmd_ptr, (int) pcmd_ptr->size);

    LEAVE();

    return MLAN_STATUS_SUCCESS;
}
/**
 *  @brief This function allocates buffer for the members of adapter
 *  		structure like command buffer and BSSID list.
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *
 *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
wlan_allocate_adapter(pmlan_adapter pmadapter)
{
    int i;
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
    t_u32 buf_size;
    BSSDescriptor_t *ptemp_scan_table;

    ENTER();

    /* Allocate buffer to store the BSSID list */
    buf_size = sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST;
    ret = pcb->moal_malloc(buf_size, (t_u8 **) & ptemp_scan_table);
    if (ret != MLAN_STATUS_SUCCESS || !ptemp_scan_table) {
        PRINTM(ERROR, "Failed to allocate scan table\n");
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }
    pmadapter->pscan_table = ptemp_scan_table;

    /* Initialize cmd_free_q */
    util_init_list_head(&pmadapter->cmd_free_q, MTRUE,
                        pmadapter->callbacks.moal_init_lock);
    /* Initialize cmd_pending_q */
    util_init_list_head(&pmadapter->cmd_pending_q, MTRUE,
                        pmadapter->callbacks.moal_init_lock);
    /* Initialize scan_pending_q */
    util_init_list_head(&pmadapter->scan_pending_q, MTRUE,
                        pmadapter->callbacks.moal_init_lock);

    /* Allocate command buffer */
    if (wlan_alloc_cmd_buffer(pmadapter) != MLAN_STATUS_SUCCESS) {
        PRINTM(ERROR, "Failed to allocate command buffer\n");
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    memset(&pmadapter->sleep_cfm_buf.ps_cfm_sleep, 0,
           sizeof(PS_CMD_ConfirmSleep));
    pmadapter->sleep_cfm_buf.ps_cfm_sleep.command =
        wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE);
    pmadapter->sleep_cfm_buf.ps_cfm_sleep.size =
        wlan_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep));
    pmadapter->sleep_cfm_buf.ps_cfm_sleep.result = 0;
    pmadapter->sleep_cfm_buf.ps_cfm_sleep.action =
        wlan_cpu_to_le16(HostCmd_SubCmd_Sleep_Confirmed);

    for (i = 0; i < MLAN_MAX_BSS_NUM; ++i) {
        util_init_list_head(&pmadapter->bssprio_tbl[i].bssprio_head,
                            MTRUE, pmadapter->callbacks.moal_init_lock);

        pmadapter->bssprio_tbl[i].bssprio_cur = MNULL;
    }

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Esempio n. 10
0
/** 
 *  @brief This function handles the timeout of command sending.
 *  It will re-send the same command again.
 *  
 *  @param FunctionContext    A pointer to FunctionContext
 *  @return 	   n/a
 */
void
MrvDrvCommandTimerFunction(void *FunctionContext)
{
    wlan_private *priv = (wlan_private *) FunctionContext;
    wlan_adapter *Adapter = priv->adapter;
    CmdCtrlNode *pTempNode;
    HostCmd_DS_COMMAND *CmdPtr;

    ENTER();

    PRINTM(CMND, "Command timeout.\n");

    Adapter->CommandTimerIsSet = FALSE;

    if (!Adapter->num_cmd_timeout)
        Adapter->dbg.num_cmd_timeout++;

    pTempNode = Adapter->CurCmd;

    if (pTempNode == NULL) {
        PRINTM(INFO, "CurCmd Empty\n");
        goto exit;
    }

    CmdPtr = (HostCmd_DS_COMMAND *) pTempNode->BufVirtualAddr;
    if (CmdPtr == NULL) {
        goto exit;
    }

    if (CmdPtr->Size) {
        Adapter->dbg.TimeoutCmdId = wlan_cpu_to_le16(CmdPtr->Command);
        Adapter->dbg.TimeoutCmdAct =
            wlan_cpu_to_le16(*(u16 *) ((u8 *) CmdPtr + S_DS_GEN));
        PRINTM(CMND, "Timeout cmd = 0x%x, act = 0x%x\n",
               Adapter->dbg.TimeoutCmdId, Adapter->dbg.TimeoutCmdAct);
    }
#define MAX_CMD_TIMEOUT_COUNT	5
    Adapter->num_cmd_timeout++;
    if (Adapter->num_cmd_timeout > MAX_CMD_TIMEOUT_COUNT) {
        PRINTM(FATAL, "num_cmd_timeout=%d\n", Adapter->num_cmd_timeout);
        wlan_fatal_error_handle(priv);
        goto exit;
    }

    /* Restart the timer to trace command response again */
    ModTimer(&Adapter->MrvDrvCommandTimer, MRVDRV_TIMER_1S);
    Adapter->CommandTimerIsSet = TRUE;

    /* Wake up main thread to read int status register */
    Adapter->IntCounter++;
    wake_up_interruptible(&priv->MainThread.waitQ);

  exit:
    LEAVE();
    return;
}
/** 
 *  @brief This function prepares 11n cfg command
 *  
 *  @param pmpriv    	A pointer to mlan_private structure
 *  @param cmd	   	A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action 	the action: GET or SET
 *  @param pdata_buf 	A pointer to data buffer
 *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_cmd_11n_cfg(IN pmlan_private pmpriv,
                 IN HostCmd_DS_COMMAND * cmd,
                 IN t_u16 cmd_action, IN t_void * pdata_buf)
{
    HostCmd_DS_11N_CFG *htcfg = &cmd->params.htcfg;
    mlan_ds_11n_tx_cfg *txcfg = (mlan_ds_11n_tx_cfg *) pdata_buf;

    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_CFG);
    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_CFG) + S_DS_GEN);
    htcfg->action = wlan_cpu_to_le16(cmd_action);
    htcfg->ht_tx_cap = wlan_cpu_to_le16(txcfg->httxcap);
    htcfg->ht_tx_info = wlan_cpu_to_le16(txcfg->httxinfo);
    return MLAN_STATUS_SUCCESS;
}
Esempio n. 12
0
/** 
 *  @brief This function allocates buffer for the member of adapter
 *  structure like command buffer and BSSID list.
 *  
 *  @param priv    A pointer to wlan_private structure
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
static int
wlan_allocate_adapter(wlan_private * priv)
{
    u32 ulBufSize;
    wlan_adapter *Adapter = priv->adapter;
    BSSDescriptor_t *pTempScanTable;

    ENTER();

    /* Allocate buffer to store the BSSID list */
    ulBufSize = sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST;
    if (!(pTempScanTable = kmalloc(ulBufSize, GFP_KERNEL))) {
        LEAVE();
        return WLAN_STATUS_FAILURE;
    }

    Adapter->ScanTable = pTempScanTable;
    memset(Adapter->ScanTable, 0, ulBufSize);

    if (!(Adapter->bgScanConfig =
          kmalloc(sizeof(HostCmd_DS_802_11_BG_SCAN_CONFIG), GFP_KERNEL))) {
        LEAVE();
        return WLAN_STATUS_FAILURE;
    }
    Adapter->bgScanConfigSize = sizeof(HostCmd_DS_802_11_BG_SCAN_CONFIG);
    memset(Adapter->bgScanConfig, 0, Adapter->bgScanConfigSize);

    spin_lock_init(&Adapter->QueueSpinLock);
    INIT_LIST_HEAD(&Adapter->CmdFreeQ);
    INIT_LIST_HEAD(&Adapter->CmdPendingQ);

    /* Allocate the command buffers */
    if (wlan_alloc_cmd_buffer(priv) != WLAN_STATUS_SUCCESS)
        return WLAN_STATUS_FAILURE;

    memset(&Adapter->PSConfirmSleep, 0, sizeof(PS_CMD_ConfirmSleep));
    Adapter->PSConfirmSleep.SeqNum = wlan_cpu_to_le16(++Adapter->SeqNum);
    Adapter->PSConfirmSleep.Command =
        wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE);
    Adapter->PSConfirmSleep.Size =
        wlan_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep));
    Adapter->PSConfirmSleep.Result = 0;
    Adapter->PSConfirmSleep.Action =
        wlan_cpu_to_le16(HostCmd_SubCmd_Sleep_Confirmed);

    LEAVE();
    return WLAN_STATUS_SUCCESS;
}
Esempio n. 13
0
/**
 *  @brief Performs the ioctl operation to send the command to
 *  the driver for various modes.
 *
 *  @param  mode Mode value to set
 *  @return WPS_STATUS_SUCCESS or WPS_STATUS_FAIL
 */
int wfd_set_mode(u16 mode)
{
	int ret = WPS_STATUS_SUCCESS;
	u16 cmd_len = 0;
	wfdcmdbuf *header = NULL;
	u8 *buffer = NULL, *cmd;
	wfd_mode_config *cmd_buf = NULL;
	u16 data = mode;

	ENTER();

	/* send hostcmd now */
	cmd_len = sizeof(wfd_mode_config);
	buffer = (u8 *) wps_mem_malloc(cmd_len);
	if (!buffer) {
		wmprintf("ERR:Cannot allocate memory!\r\n");
		return WPS_STATUS_FAIL;
	}

	cmd_buf = (wfd_mode_config *) buffer;
	cmd_buf->cmd_head.cmd_code = HostCmd_CMD_WFD_MODE_CONFIG;
	cmd_buf->cmd_head.size = cmd_len - BUF_HEADER_SIZE;
	cmd_buf->cmd_head.seq_num = (0x01) << 13;
	cmd_buf->cmd_head.result = 0;
	cmd_buf->action = ACTION_SET;
	cmd_buf->mode = wlan_cpu_to_le16(data);
	cmd_buf->action = wlan_cpu_to_le16(cmd_buf->action);

	cmd = (u8 *) buffer;

	*(u32 *) cmd = cmd_len - BUF_HEADER_SIZE;

	header = (wfdcmdbuf *) cmd;
	header->cmd_head.size = cmd_len - BUF_HEADER_SIZE;
	header->cmd_head.buf_size = header->cmd_head.size + BUF_HEADER_SIZE;
	endian_convert_request_header(header->cmd_head);

	ret = wfd_ioctl((u8 *) cmd, cmd_len);

	if (buffer)
		wps_mem_free(buffer);

	LEAVE();
	return ret;
}
Esempio n. 14
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;
}
Esempio n. 15
0
/*
 * This configures sticky TIM configuration for given MAC.
 *
 * Note that this is not present in mlan. So we have to add it here.
 */
void wifi_uap_enable_sticky_bit(const uint8_t *mac_addr)
{
	static bool global_sticky_enabled;

	uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1;

	wifi_get_command_lock();
	HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();

	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
	HostCmd_DS_SYS_CONFIG *sys_config_cmd =
	    (HostCmd_DS_SYS_CONFIG *) ((uint32_t) cmd + S_DS_GEN);
	sys_config_cmd->action = HostCmd_ACT_GEN_SET;
	uint8_t *tlv = sys_config_cmd->tlv_buffer;

	if (!global_sticky_enabled) {
		/*
		 * This enables the global sticky TIM bit enable. This
		 * needs to be done only once.
		 */
		tlvbuf_sticky_tim_config *tlv_sticky_tim_cfg =
		    (tlvbuf_sticky_tim_config *) tlv;

		tlv_sticky_tim_cfg->tag = MRVL_STICKY_TIM_CONFIG_TLV_ID;
		tlv_sticky_tim_cfg->length = sizeof(tlvbuf_sticky_tim_config)
		    - TLVHEADER_LEN;
		tlv_sticky_tim_cfg->enable = 1;
		/* Set it permanently */
		tlv_sticky_tim_cfg->duration = 0;
		/* MoreData bit and TIM bit is made sticky */
		tlv_sticky_tim_cfg->sticky_bitmask = (t_u16) 0x3;

		size +=
		    sizeof(MrvlIEtypesHeader_t) + tlv_sticky_tim_cfg->length;
		tlv += sizeof(MrvlIEtypesHeader_t) + tlv_sticky_tim_cfg->length;

		global_sticky_enabled = true;
	}

	tlvbuf_sticky_tim_sta_mac_addr *tim_cfg =
	    (tlvbuf_sticky_tim_sta_mac_addr *) tlv;

	tim_cfg->tag = MRVL_STICKY_TIM_STA_MAC_ADDR_TLV_ID;
	tim_cfg->length = sizeof(tlvbuf_sticky_tim_sta_mac_addr)
	    - TLVHEADER_LEN;
	memcpy(tim_cfg->sta_mac_address, mac_addr, MLAN_MAC_ADDR_LENGTH);
	tim_cfg->control = 1;

	size += sizeof(MrvlIEtypesHeader_t) + tim_cfg->length;

	cmd->size = size;
	cmd->seq_num = (0x01) << 12;
	cmd->result = 0x00;

	wifi_wait_for_cmdresp(NULL);
}
/** 
  *  @brief This function prepares command for deleting a block ack
  *  		request.
  *  
  *  @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_delba(mlan_private * priv,
                   HostCmd_DS_COMMAND * cmd, void *pdata_buf)
{
    HostCmd_DS_11N_DELBA *pdel_ba = (HostCmd_DS_11N_DELBA *)
        & cmd->params.del_ba;

    ENTER();

    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_DELBA);
    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_DELBA) + S_DS_GEN);

    memcpy(pdel_ba, pdata_buf, sizeof(HostCmd_DS_11N_DELBA));
    pdel_ba->del_ba_param_set = wlan_cpu_to_le16(pdel_ba->del_ba_param_set);
    pdel_ba->reason_code = wlan_cpu_to_le16(pdel_ba->reason_code);

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
/** 
  *  @brief This function prepares command for adding a block ack
  *  		request.
  *  
  *  @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_req(mlan_private * priv,
                       HostCmd_DS_COMMAND * cmd, t_void * pdata_buf)
{
    HostCmd_DS_11N_ADDBA_REQ *padd_ba_req = (HostCmd_DS_11N_ADDBA_REQ *)
        & cmd->params.add_ba_req;
    ENTER();

    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ);
    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_ADDBA_REQ) + S_DS_GEN);

    memcpy(padd_ba_req, pdata_buf, sizeof(HostCmd_DS_11N_ADDBA_REQ));
    padd_ba_req->block_ack_param_set =
        wlan_cpu_to_le16(padd_ba_req->block_ack_param_set);
    padd_ba_req->block_ack_tmo = wlan_cpu_to_le16(padd_ba_req->block_ack_tmo);
    padd_ba_req->ssn = wlan_cpu_to_le16(padd_ba_req->ssn);

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
/**
 *  @brief This function prepares command of SDIO GPIO interrupt
 *
 *  @param pmpriv	A pointer to mlan_private structure
 *  @param cmd	   	A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   The action: GET or SET
 *  @param pdata_buf    A pointer to data buffer
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_sdio_gpio_int(pmlan_private pmpriv,
		       IN HostCmd_DS_COMMAND * cmd,
		       IN t_u16 cmd_action, IN t_void * pdata_buf)
{
	HostCmd_DS_SDIO_GPIO_INT_CONFIG *psdio_gpio_int =
		&cmd->params.sdio_gpio_int;

	ENTER();

	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SDIO_GPIO_INT_CONFIG);
	cmd->size =
		wlan_cpu_to_le16((sizeof(HostCmd_DS_SDIO_GPIO_INT_CONFIG)) +
				 S_DS_GEN);

	memset(pmpriv->adapter, psdio_gpio_int, 0,
	       sizeof(HostCmd_DS_SDIO_GPIO_INT_CONFIG));
	if (cmd_action == HostCmd_ACT_GEN_SET) {
		memcpy(pmpriv->adapter, psdio_gpio_int, pdata_buf,
		       sizeof(HostCmd_DS_SDIO_GPIO_INT_CONFIG));
		psdio_gpio_int->action =
			wlan_cpu_to_le16(psdio_gpio_int->action);
		psdio_gpio_int->gpio_pin =
			wlan_cpu_to_le16(psdio_gpio_int->gpio_pin);
		psdio_gpio_int->gpio_int_edge =
			wlan_cpu_to_le16(psdio_gpio_int->gpio_int_edge);
		psdio_gpio_int->gpio_pulse_width =
			wlan_cpu_to_le16(psdio_gpio_int->gpio_pulse_width);
	}

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}
Esempio n. 19
0
int wifi_uap_rates_getset(uint8_t action, char *rates, uint8_t num_rates)
{
	int i = 0;
	uint32_t size = S_DS_GEN + sizeof(HostCmd_DS_SYS_CONFIG) - 1;

	wifi_get_command_lock();
	HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();

	cmd->command = wlan_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
	HostCmd_DS_SYS_CONFIG *sys_config_cmd =
	    (HostCmd_DS_SYS_CONFIG *) ((uint32_t) cmd + S_DS_GEN);
	uint8_t *tlv = sys_config_cmd->tlv_buffer;

	MrvlIEtypes_RatesParamSet_t *tlv_rates =
				(MrvlIEtypes_RatesParamSet_t *) tlv;

	if (action == HostCmd_ACT_GEN_GET)
		sys_config_cmd->action = HostCmd_ACT_GEN_GET;
	else {
		sys_config_cmd->action = HostCmd_ACT_GEN_SET;
		for (i = 0; i < num_rates; i++) {
			tlv_rates->rates[i] = rates[i];
		}
	}

	tlv_rates->header.type = wlan_cpu_to_le16(TLV_TYPE_RATES);
	tlv_rates->header.len = wlan_cpu_to_le16(i);

	size += sizeof(MrvlIEtypesHeader_t) + i;
	tlv += sizeof(MrvlIEtypesHeader_t) + i;

	cmd->size = size;
	cmd->seq_num = (0x01) << 12;
	cmd->result = 0x00;

	wifi_wait_for_cmdresp(action == HostCmd_ACT_GEN_GET ?
						rates : NULL);

	return wm_wifi.cmd_resp_status;
}
Esempio n. 20
0
/** 
  *  @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;

    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);
    padd_ba_rsp->block_ack_param_set =
        wlan_cpu_to_le16(padd_ba_rsp->block_ack_param_set);
    padd_ba_rsp->block_ack_tmo =
        (t_u16) wlan_cpu_to_le16(priv->add_ba_param.timeout);

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Esempio n. 21
0
/**
 *  @brief  Prepare the HostCmd_DS_Command structure for a measurement command.
 *
 *  Use the Command field to determine if the command being set up is for
 *     11h and call one of the local command handlers accordingly for:
 *
 *        - HostCmd_CMD_MEASUREMENT_REQUEST
 *        - HostCmd_CMD_MEASUREMENT_REPORT
 *
 *  @param pmpriv     Private driver information structure
 *  @param pcmd_ptr   Output parameter: Pointer to the command being prepared 
 *                    for the firmware
 *  @param pinfo_buf  Void buffer passthrough with data necessary for a
 *                    specific command type
 *
 *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 *
 */
int
wlan_meas_cmd_process(mlan_private * pmpriv,
                      HostCmd_DS_COMMAND * pcmd_ptr, const void *pinfo_buf)
{
    int ret = MLAN_STATUS_SUCCESS;

    ENTER();
    switch (pcmd_ptr->command) {
    case HostCmd_CMD_MEASUREMENT_REQUEST:
        ret = wlan_meas_cmd_request(pmpriv, pcmd_ptr, pinfo_buf);
        break;
    case HostCmd_CMD_MEASUREMENT_REPORT:
        ret = wlan_meas_cmd_get_report(pmpriv, pcmd_ptr);
        break;
    default:
        ret = MLAN_STATUS_FAILURE;
    }

    pcmd_ptr->command = wlan_cpu_to_le16(pcmd_ptr->command);
    pcmd_ptr->size = wlan_cpu_to_le16(pcmd_ptr->size);
    LEAVE();
    return ret;
}
Esempio n. 22
0
/**
 *  @brief  Utility function to process a join to an infrastructure BSS
 *
 *  @param priv          Private driver information structure
 *  @param ppbuffer      Output parameter: Pointer to the TLV output buffer,
 *                       modified on return to point after the appended 11h TLVs
 *  @param channel       Channel on which we are joining the BSS
 *  @param p11h_bss_info Pointer to the 11h BSS information for this network
 *                       that was parsed out of the scan response.
 *
 *  @return              Integer number of bytes appended to the TLV output
 *                       buffer (ppbuffer)
 */
static int
wlan_11h_process_infra_join(mlan_private * priv,
                            t_u8 ** ppbuffer,
                            t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info)
{
    MrvlIEtypesHeader_t ie_header;
    IEEEtypes_SupportedChannels_t sup_chan_ie;
    int ret_len = 0;
    int sup_chan_len = 0;

    ENTER();

    /* Null Checks */
    if (!ppbuffer)
        return 0;
    if (!(*ppbuffer))
        return 0;

    /* Set the local constraint configured in the firmware */
    wlan_11h_set_local_power_constraint(priv, channel,
                                        (p11h_bss_info->
                                         power_constraint.local_constraint));

    /* Setup the Supported Channels IE */
    sup_chan_len = wlan_11h_set_supp_channels_ie(priv, &sup_chan_ie);

    /* 
     * If we returned a valid Supported Channels IE, wrap and append it
     */
    if (sup_chan_len) {
        /* Wrap the supported channels IE with a passthrough TLV type */
        ie_header.type = wlan_cpu_to_le16(TLV_TYPE_PASSTHROUGH);
        ie_header.len = sup_chan_len;
        memcpy(*ppbuffer, &ie_header, sizeof(ie_header));

        /* Increment the return size and the return buffer pointer param */
        *ppbuffer += sizeof(ie_header);
        ret_len += sizeof(ie_header);

        /* Copy the supported channels IE to the output buf, advance pointer */
        memcpy(*ppbuffer, &sup_chan_ie, sup_chan_len);
        *ppbuffer += sup_chan_len;
        ret_len += sup_chan_len;
    }

    LEAVE();
    return ret_len;
}
/**
 *  @brief Update the TxPktLength field in TxPD after the complete AMSDU
 *  packet is formed
 *
 *  @param priv     A pointer to mlan_private structure
 *  @param mbuf     TxPD buffer
 *
 *  @return         N/A
 */
static INLINE void
wlan_11n_update_pktlen_amsdu_txpd(mlan_private * priv, pmlan_buffer mbuf)
{
	TxPD *ptx_pd;
	ENTER();

	ptx_pd = (TxPD *) mbuf->pbuf;
	ptx_pd->tx_pkt_length =
		(t_u16) wlan_cpu_to_le16(mbuf->data_len - sizeof(TxPD));
#ifdef STA_SUPPORT
	if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) &&
	    (priv->adapter->pps_uapsd_mode)) {
		if (MTRUE == wlan_check_last_packet_indication(priv)) {
			priv->adapter->tx_lock_flag = MTRUE;
			ptx_pd->flags |= MRVDRV_TxPD_POWER_MGMT_LAST_PACKET;
		}
	}
#endif /* STA_SUPPORT */
	LEAVE();
}
Esempio n. 24
0
/**
 *  @brief Prepare CMD_802_11_TPC_ADAPT_REQ firmware command
 *
 *  @param priv      Private driver information structure
 *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared
 *                   for the firmware
 *  @param pinfo_buf HostCmd_DS_802_11_TPC_ADAPT_REQ passed as void data block
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static int
wlan_11h_cmd_tpc_request(mlan_private * priv,
                         HostCmd_DS_COMMAND * pcmd_ptr,
                         const t_void * pinfo_buf)
{
    ENTER();

    memcpy(&pcmd_ptr->params.tpc_req, pinfo_buf,
           sizeof(HostCmd_DS_802_11_TPC_ADAPT_REQ));

    pcmd_ptr->params.tpc_req.req.timeout =
        wlan_cpu_to_le16(pcmd_ptr->params.tpc_req.req.timeout);

    /* Converted to little endian in wlan_11h_cmd_process */
    pcmd_ptr->size = sizeof(HostCmd_DS_802_11_TPC_ADAPT_REQ) + S_DS_GEN;

    HEXDUMP("11h: 11_TPC_ADAPT_REQ:", (t_u8 *) pcmd_ptr, (int) pcmd_ptr->size);

    LEAVE();

    return MLAN_STATUS_SUCCESS;
}
/**
 *  @brief This function initializes the adapter structure
 *  		and sets default values to the members of adapter.
 *  
 *  @param pmadapter	A pointer to mlan_adapter structure
 *
 *  @return		N/A
 */
t_void
wlan_init_adapter(pmlan_adapter pmadapter)
{
    int i;
    opt_sleep_confirm_buffer *sleep_cfm_buf =
        (opt_sleep_confirm_buffer *) (pmadapter->psleep_cfm->pbuf +
                                      pmadapter->psleep_cfm->data_offset);

    ENTER();

    pmadapter->cmd_sent = MFALSE;
    pmadapter->data_sent = MTRUE;
    pmadapter->mp_rd_bitmap = 0;
    pmadapter->mp_wr_bitmap = 0;
    pmadapter->curr_rd_port = 1;
    pmadapter->curr_wr_port = 1;
    for (i = 0; i < MAX_NUM_TID; i++) {
        pmadapter->tx_eligibility[i] = 1;
    }

#ifdef SDIO_MULTI_PORT_TX_AGGR
    pmadapter->mpa_tx.buf_len = 0;
    pmadapter->mpa_tx.pkt_cnt = 0;
    pmadapter->mpa_tx.start_port = 0;

    pmadapter->mpa_tx.enabled = 1;
    pmadapter->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
#endif /* SDIO_MULTI_PORT_TX_AGGR */

#ifdef SDIO_MULTI_PORT_RX_AGGR
    pmadapter->mpa_rx.buf_len = 0;
    pmadapter->mpa_rx.pkt_cnt = 0;
    pmadapter->mpa_rx.start_port = 0;

    pmadapter->mpa_rx.enabled = 1;
    pmadapter->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
#endif /* SDIO_MULTI_PORT_RX_AGGR */

    pmadapter->cmd_resp_received = MFALSE;
    pmadapter->event_received = MFALSE;
    pmadapter->data_received = MFALSE;

    pmadapter->cmd_timer_is_set = MFALSE;

    /* PnP and power profile */
    pmadapter->surprise_removed = MFALSE;

    /* Status variables */
    pmadapter->hw_status = WlanHardwareStatusInitializing;

    pmadapter->ps_mode = Wlan802_11PowerModeCAM;
    pmadapter->ps_state = PS_STATE_AWAKE;
    pmadapter->need_to_wakeup = MFALSE;

    /* Scan type */
    pmadapter->scan_type = HostCmd_SCAN_TYPE_ACTIVE;
    /* Scan mode */
    pmadapter->scan_mode = HostCmd_BSS_MODE_ANY;
    /* Scan time */
    pmadapter->specific_scan_time = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
    pmadapter->active_scan_time = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
    pmadapter->passive_scan_time = MRVDRV_PASSIVE_SCAN_CHAN_TIME;

    pmadapter->num_in_scan_table = 0;
    memset(pmadapter->pscan_table, 0,
           (sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST));
    pmadapter->scan_probes = 0;

    memset(pmadapter->bcn_buf, 0, sizeof(pmadapter->bcn_buf));
    pmadapter->pbcn_buf_end = pmadapter->bcn_buf;

    pmadapter->radio_on = RADIO_ON;
    pmadapter->multiple_dtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;

    pmadapter->local_listen_interval = 0;       /* default value in firmware
                                                   will be used */
    pmadapter->fw_wakeup_method = WAKEUP_FW_UNCHANGED;

    pmadapter->is_deep_sleep = MFALSE;

    pmadapter->delay_null_pkt = MFALSE;
    pmadapter->delay_to_ps = 100;

    pmadapter->pm_wakeup_card_req = MFALSE;

    pmadapter->pm_wakeup_fw_try = MFALSE;

    pmadapter->max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;
    pmadapter->tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;

    pmadapter->is_hs_configured = MFALSE;
    pmadapter->hs_cfg.params.hs_config.conditions = HOST_SLEEP_CFG_CANCEL;
    pmadapter->hs_cfg.params.hs_config.gpio = 0;
    pmadapter->hs_cfg.params.hs_config.gap = 0;
    pmadapter->hs_activated = MFALSE;

    memset(pmadapter->event_body, 0, sizeof(pmadapter->event_body));
    pmadapter->hw_dot_11n_dev_cap = 0;
    pmadapter->hw_dev_mcs_support = 0;
    pmadapter->usr_dot_11n_dev_cap = 0;
    pmadapter->usr_dev_mcs_support = 0;
    pmadapter->chan_offset = 0;

    /* Initialize 802.11d */
    wlan_11d_init(pmadapter);

    wlan_wmm_init(pmadapter);

    pmadapter->psleep_cfm->buf_type = MLAN_BUF_TYPE_CMD;

    if ((wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY))->bss_type ==
        MLAN_BSS_TYPE_STA) {
        pmadapter->psleep_cfm->data_len = sizeof(HostCmd_DS_COMMAND);
        memset(&sleep_cfm_buf->ps_cfm_sleep, 0, sizeof(HostCmd_DS_COMMAND));
        sleep_cfm_buf->ps_cfm_sleep.command =
            wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
        sleep_cfm_buf->ps_cfm_sleep.size =
            wlan_cpu_to_le16(sizeof(HostCmd_DS_COMMAND));
        sleep_cfm_buf->ps_cfm_sleep.result = 0;
        sleep_cfm_buf->ps_cfm_sleep.params.psmode_enh.action =
            wlan_cpu_to_le16(SLEEP_CONFIRM);
    }

    memset(&pmadapter->sleep_params, 0, sizeof(pmadapter->sleep_params));
    memset(&pmadapter->sleep_period, 0, sizeof(pmadapter->sleep_period));
    pmadapter->tx_lock_flag = MFALSE;
    pmadapter->null_pkt_interval = 0;
    pmadapter->fw_bands = 0;
    pmadapter->config_bands = 0;
    pmadapter->adhoc_start_band = 0;
    pmadapter->pscan_channels = MNULL;
    pmadapter->fw_release_number = 0;
    pmadapter->fw_cap_info = 0;
    memset(&pmadapter->upld_buf, 0, sizeof(pmadapter->upld_buf));
    pmadapter->upld_len = 0;
    pmadapter->event_cause = 0;
    memset(&pmadapter->region_channel, 0, sizeof(pmadapter->region_channel));
    pmadapter->region_code = 0;
    pmadapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
    memset(&pmadapter->arp_filter, 0, sizeof(pmadapter->arp_filter));
    pmadapter->arp_filter_size = 0;

    LEAVE();
    return;
}
/**
 *  @brief This function append the 802_11N tlv
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pbss_desc    A pointer to BSSDescriptor_t structure
 *  @param ppbuffer     A Pointer to command buffer pointer
 *
 *  @return bytes added to the buffer       
 */
int
wlan_cmd_append_11n_tlv(IN mlan_private * pmpriv,
                        IN BSSDescriptor_t * pbss_desc, OUT t_u8 ** ppbuffer)
{
    pmlan_adapter pmadapter = pmpriv->adapter;
    MrvlIETypes_HTCap_t *pht_cap;
    MrvlIETypes_HTInfo_t *pht_info;
    MrvlIEtypes_ChanListParamSet_t *pchan_list;
    MrvlIETypes_2040BSSCo_t *p2040_bss_co;
    MrvlIETypes_ExtCap_t *pext_cap;
    int ret_len = 0;

    ENTER();

    /* Null Checks */
    if (ppbuffer == 0) {
        LEAVE();
        return 0;
    }
    if (*ppbuffer == 0) {
        LEAVE();
        return 0;
    }

    if (pbss_desc->pht_cap) {
        pht_cap = (MrvlIETypes_HTCap_t *) * ppbuffer;
        memset(pmadapter, pht_cap, 0, sizeof(MrvlIETypes_HTCap_t));
        pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY);
        pht_cap->header.len = sizeof(HTCap_t);
        memcpy(pmadapter, (t_u8 *) pht_cap + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pht_cap + sizeof(IEEEtypes_Header_t),
               pht_cap->header.len);

        pht_cap->ht_cap.ht_cap_info =
            wlan_le16_to_cpu(pht_cap->ht_cap.ht_cap_info);
        wlan_fill_cap_info(pmpriv, pht_cap);
        pht_cap->ht_cap.ht_cap_info =
            wlan_cpu_to_le16(pht_cap->ht_cap.ht_cap_info);

        HEXDUMP("HT_CAPABILITIES IE", (t_u8 *) pht_cap,
                sizeof(MrvlIETypes_HTCap_t));
        *ppbuffer += sizeof(MrvlIETypes_HTCap_t);
        ret_len += sizeof(MrvlIETypes_HTCap_t);
        pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len);
    }

    if (pbss_desc->pht_info) {
        if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) {
            pht_info = (MrvlIETypes_HTInfo_t *) * ppbuffer;
            memset(pmadapter, pht_info, 0, sizeof(MrvlIETypes_HTInfo_t));
            pht_info->header.type = wlan_cpu_to_le16(HT_OPERATION);
            pht_info->header.len = sizeof(HTInfo_t);

            memcpy(pmadapter, (t_u8 *) pht_info + sizeof(MrvlIEtypesHeader_t),
                   (t_u8 *) pbss_desc->pht_info + sizeof(IEEEtypes_Header_t),
                   pht_info->header.len);

            if (!ISSUPP_CHANWIDTH40(pmadapter->hw_dot_11n_dev_cap) ||
                !ISSUPP_CHANWIDTH40(pmadapter->usr_dot_11n_dev_cap)) {
                RESET_CHANWIDTH40(pht_info->ht_info.field2);
            }

            *ppbuffer += sizeof(MrvlIETypes_HTInfo_t);
            ret_len += sizeof(MrvlIETypes_HTInfo_t);
            pht_info->header.len = wlan_cpu_to_le16(pht_info->header.len);
        }

        pchan_list = (MrvlIEtypes_ChanListParamSet_t *) * ppbuffer;
        memset(pmadapter, pchan_list, 0,
               sizeof(MrvlIEtypes_ChanListParamSet_t));
        pchan_list->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
        pchan_list->header.len = sizeof(MrvlIEtypes_ChanListParamSet_t) -
            sizeof(MrvlIEtypesHeader_t);
        pchan_list->chan_scan_param[0].chan_number =
            pbss_desc->pht_info->ht_info.pri_chan;
        pchan_list->chan_scan_param[0].radio_type =
            wlan_band_to_radio_type((t_u8) pbss_desc->bss_band);

        if ((ISSUPP_CHANWIDTH40(pmadapter->hw_dot_11n_dev_cap) &&
             ISSUPP_CHANWIDTH40(pmadapter->usr_dot_11n_dev_cap)) &&
            ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.field2))
            SET_SECONDARYCHAN(pchan_list->chan_scan_param[0].radio_type,
                              GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info.
                                                field2));

        HEXDUMP("ChanList", (t_u8 *) pchan_list,
                sizeof(MrvlIEtypes_ChanListParamSet_t));
        HEXDUMP("pht_info", (t_u8 *) pbss_desc->pht_info,
                sizeof(MrvlIETypes_HTInfo_t) - 2);
        *ppbuffer += sizeof(MrvlIEtypes_ChanListParamSet_t);
        ret_len += sizeof(MrvlIEtypes_ChanListParamSet_t);
        pchan_list->header.len = wlan_cpu_to_le16(pchan_list->header.len);
    }

    if (pbss_desc->pbss_co_2040) {
        p2040_bss_co = (MrvlIETypes_2040BSSCo_t *) * ppbuffer;
        memset(pmadapter, p2040_bss_co, 0, sizeof(MrvlIETypes_2040BSSCo_t));
        p2040_bss_co->header.type = wlan_cpu_to_le16(BSSCO_2040);
        p2040_bss_co->header.len = sizeof(BSSCo2040_t);

        memcpy(pmadapter, (t_u8 *) p2040_bss_co + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pbss_co_2040 + sizeof(IEEEtypes_Header_t),
               p2040_bss_co->header.len);

        HEXDUMP("20/40 BSS Coexistence IE", (t_u8 *) p2040_bss_co,
                sizeof(MrvlIETypes_2040BSSCo_t));
        *ppbuffer += sizeof(MrvlIETypes_2040BSSCo_t);
        ret_len += sizeof(MrvlIETypes_2040BSSCo_t);
        p2040_bss_co->header.len = wlan_cpu_to_le16(p2040_bss_co->header.len);
    }

    if (pbss_desc->pext_cap) {
        pext_cap = (MrvlIETypes_ExtCap_t *) * ppbuffer;
        memset(pmadapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
        pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
        pext_cap->header.len = sizeof(ExtCap_t);

        memcpy(pmadapter, (t_u8 *) pext_cap + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pext_cap + sizeof(IEEEtypes_Header_t),
               pext_cap->header.len);

        HEXDUMP("Extended Capabilities IE", (t_u8 *) pext_cap,
                sizeof(MrvlIETypes_ExtCap_t));
        *ppbuffer += sizeof(MrvlIETypes_ExtCap_t);
        ret_len += sizeof(MrvlIETypes_ExtCap_t);
        pext_cap->header.len = wlan_cpu_to_le16(pext_cap->header.len);
    }

    LEAVE();
    return ret_len;
}
/**
 *  @brief This function initializes the adapter structure
 *  		and sets default values to the members of adapter.
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *
 *  @return		N/A
 */
t_void
wlan_init_adapter(pmlan_adapter pmadapter)
{
    int i;
    opt_sleep_confirm_buffer *sleep_cfm_buf = MNULL;

    ENTER();

    sleep_cfm_buf = (opt_sleep_confirm_buffer *) (pmadapter->psleep_cfm->pbuf +
                    pmadapter->psleep_cfm->
                    data_offset);

#ifdef MFG_CMD_SUPPORT
    if (pmadapter->init_para.mfg_mode == MLAN_INIT_PARA_DISABLED) {
        pmadapter->mfg_mode = MFALSE;
    } else {
        pmadapter->mfg_mode = pmadapter->init_para.mfg_mode;
    }
#endif

    pmadapter->int_mode = pmadapter->init_para.int_mode;
    pmadapter->gpio_pin = pmadapter->init_para.gpio_pin;

#if defined(STA_SUPPORT)
    pmadapter->pwarm_reset_ioctl_req = MNULL;
#endif
    pmadapter->cmd_sent = MFALSE;
    pmadapter->data_sent = MTRUE;
    pmadapter->mp_rd_bitmap = 0;
    pmadapter->mp_wr_bitmap = 0;
    pmadapter->curr_rd_port = 1;
    pmadapter->curr_wr_port = 1;
    for (i = 0; i < MAX_NUM_TID; i++) {
        pmadapter->tx_eligibility[i] = 1;
    }
    pmadapter->mp_data_port_mask = DATA_PORT_MASK;

#ifdef SDIO_MULTI_PORT_TX_AGGR
    pmadapter->mpa_tx.buf_len = 0;
    pmadapter->mpa_tx.pkt_cnt = 0;
    pmadapter->mpa_tx.start_port = 0;

    if (!pmadapter->init_para.mpa_tx_cfg) {
        pmadapter->mpa_tx.enabled = MFALSE;
    } else if (pmadapter->init_para.mpa_tx_cfg == MLAN_INIT_PARA_DISABLED) {
        pmadapter->mpa_tx.enabled = MFALSE;
    } else {
        pmadapter->mpa_tx.enabled = MTRUE;
    }
    pmadapter->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
#endif /* SDIO_MULTI_PORT_TX_AGGR */

#ifdef SDIO_MULTI_PORT_RX_AGGR
    pmadapter->mpa_rx.buf_len = 0;
    pmadapter->mpa_rx.pkt_cnt = 0;
    pmadapter->mpa_rx.start_port = 0;

    if (!pmadapter->init_para.mpa_rx_cfg) {
        pmadapter->mpa_rx.enabled = MFALSE;
    } else if (pmadapter->init_para.mpa_rx_cfg == MLAN_INIT_PARA_DISABLED) {
        pmadapter->mpa_rx.enabled = MFALSE;
    } else {
        pmadapter->mpa_rx.enabled = MTRUE;
    }
    pmadapter->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
#endif /* SDIO_MULTI_PORT_RX_AGGR */

    pmadapter->cmd_resp_received = MFALSE;
    pmadapter->event_received = MFALSE;
    pmadapter->data_received = MFALSE;

    pmadapter->cmd_timer_is_set = MFALSE;

    /* PnP and power profile */
    pmadapter->surprise_removed = MFALSE;

    /* Status variables */
    pmadapter->hw_status = WlanHardwareStatusInitializing;

    if (!pmadapter->init_para.ps_mode) {
        pmadapter->ps_mode = DEFAULT_PS_MODE;
    } else if (pmadapter->init_para.ps_mode == MLAN_INIT_PARA_DISABLED) {
        pmadapter->ps_mode = Wlan802_11PowerModeCAM;
    } else {
        pmadapter->ps_mode = Wlan802_11PowerModePSP;
    }
    pmadapter->ps_state = PS_STATE_AWAKE;
    pmadapter->need_to_wakeup = MFALSE;

#ifdef STA_SUPPORT
    /* Scan type */
    pmadapter->scan_type = MLAN_SCAN_TYPE_ACTIVE;
    /* Scan mode */
    pmadapter->scan_mode = HostCmd_BSS_MODE_ANY;
    /* Scan time */
    pmadapter->specific_scan_time = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
    pmadapter->active_scan_time = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
    pmadapter->passive_scan_time = MRVDRV_PASSIVE_SCAN_CHAN_TIME;

    pmadapter->num_in_scan_table = 0;
    memset(pmadapter, pmadapter->pscan_table, 0,
           (sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST));
    pmadapter->ext_scan = 0;
    pmadapter->scan_probes = DEFAULT_PROBES;

    memset(pmadapter, pmadapter->bcn_buf, 0, pmadapter->bcn_buf_size);
    pmadapter->pbcn_buf_end = pmadapter->bcn_buf;

    pmadapter->radio_on = RADIO_ON;
    pmadapter->multiple_dtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;

    pmadapter->local_listen_interval = 0;       /* default value in firmware
                                                   will be used */
#endif /* STA_SUPPORT */

    pmadapter->is_deep_sleep = MFALSE;
    pmadapter->idle_time = DEEP_SLEEP_IDLE_TIME;
    if (!pmadapter->init_para.auto_ds) {
        pmadapter->init_auto_ds = DEFAULT_AUTO_DS_MODE;
    } else if (pmadapter->init_para.auto_ds == MLAN_INIT_PARA_DISABLED) {
        pmadapter->init_auto_ds = MFALSE;
    } else {
        pmadapter->init_auto_ds = MTRUE;
    }

    pmadapter->delay_null_pkt = MFALSE;
    pmadapter->delay_to_ps = DELAY_TO_PS_DEFAULT;
    pmadapter->enhanced_ps_mode = PS_MODE_AUTO;

    pmadapter->gen_null_pkt = MFALSE;   /* Disable NULL Pkt generation-default */
    pmadapter->pps_uapsd_mode = MFALSE; /* Disable pps/uapsd mode -default */

    pmadapter->pm_wakeup_card_req = MFALSE;

    pmadapter->pm_wakeup_fw_try = MFALSE;

    if (!pmadapter->init_para.max_tx_buf)
        pmadapter->max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;
    else
        pmadapter->max_tx_buf_size = (t_u16) pmadapter->init_para.max_tx_buf;
    pmadapter->tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;
    pmadapter->curr_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;

    pmadapter->is_hs_configured = MFALSE;
    pmadapter->hs_cfg.conditions = HOST_SLEEP_DEF_COND;
    pmadapter->hs_cfg.gpio = HOST_SLEEP_DEF_GPIO;
    pmadapter->hs_cfg.gap = HOST_SLEEP_DEF_GAP;
    pmadapter->hs_activated = MFALSE;

    memset(pmadapter, pmadapter->event_body, 0, sizeof(pmadapter->event_body));
    pmadapter->hw_dot_11n_dev_cap = 0;
    pmadapter->hw_dev_mcs_support = 0;
    pmadapter->usr_dot_11n_dev_cap = 0;
    pmadapter->usr_dev_mcs_support = 0;
#ifdef STA_SUPPORT
    pmadapter->chan_offset = 0;
    pmadapter->adhoc_11n_enabled = MFALSE;
#endif /* STA_SUPPORT */

    /* Initialize 802.11d */
    wlan_11d_init(pmadapter);

    wlan_11h_init(pmadapter);

    wlan_wmm_init(pmadapter);

    if (pmadapter->psleep_cfm) {
        pmadapter->psleep_cfm->buf_type = MLAN_BUF_TYPE_CMD;
        pmadapter->psleep_cfm->data_len = sizeof(OPT_Confirm_Sleep);
        memset(pmadapter, &sleep_cfm_buf->ps_cfm_sleep, 0,
               sizeof(OPT_Confirm_Sleep));
        sleep_cfm_buf->ps_cfm_sleep.command =
            wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
        sleep_cfm_buf->ps_cfm_sleep.size =
            wlan_cpu_to_le16(sizeof(OPT_Confirm_Sleep));
        sleep_cfm_buf->ps_cfm_sleep.result = 0;
        sleep_cfm_buf->ps_cfm_sleep.action = wlan_cpu_to_le16(SLEEP_CONFIRM);
        sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl =
            wlan_cpu_to_le16(RESP_NEEDED);
    }
    memset(pmadapter, &pmadapter->sleep_params, 0,
           sizeof(pmadapter->sleep_params));
    memset(pmadapter, &pmadapter->sleep_period, 0,
           sizeof(pmadapter->sleep_period));
    pmadapter->tx_lock_flag = MFALSE;
    pmadapter->null_pkt_interval = 0;
    pmadapter->fw_bands = 0;
    pmadapter->config_bands = 0;
    pmadapter->adhoc_start_band = 0;
    pmadapter->pscan_channels = MNULL;
    pmadapter->fw_release_number = 0;
    pmadapter->fw_cap_info = 0;
    memset(pmadapter, &pmadapter->upld_buf, 0, sizeof(pmadapter->upld_buf));
    pmadapter->upld_len = 0;
    pmadapter->event_cause = 0;
    pmadapter->pmlan_buffer_event = MNULL;
    memset(pmadapter, &pmadapter->region_channel, 0,
           sizeof(pmadapter->region_channel));
    pmadapter->region_code = 0;
    pmadapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
    pmadapter->adhoc_awake_period = 0;
#ifdef STA_SUPPORT
    memset(pmadapter, &pmadapter->arp_filter, 0, sizeof(pmadapter->arp_filter));
    pmadapter->arp_filter_size = 0;
#endif /* STA_SUPPORT */

    LEAVE();
    return;
}
Esempio n. 28
0
/* borrowed from mlanconfig.c and bg_scan_wifidir.conf.  This function is hard
 * coded for our WIFIDIR set up and may not be suitable for all applications.
 */
int mlanconfig_bgscan(int mode)
{
	unsigned char *buf;
	wfdcmdbuf *header = NULL;
	mrvl_cmd_head_buf *hostcmd;
	int ret = WPS_STATUS_SUCCESS;
	mlanconfig_bgscfg_cmd_hdr *hdr;
	ssid_header_tlv *ssid_tlv;
	probe_header_tlv *probe_tlv;
	channel_header_tlv *chan_tlv;
	snr_header_tlv *snr_tlv;
	start_later_header_tlv *start_later_tlv;
	u8 *cmd;

	buf = (unsigned char *)wps_mem_malloc(MRVDRV_SIZE_OF_CMD_BUFFER);
	if (buf == NULL) {
		wmprintf("allocate memory for hostcmd failed\r\n");
		return WPS_STATUS_FAIL;
	}

	/* prepare the bgscan command */
	memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
	hostcmd = (mrvl_cmd_head_buf *) buf;
	hostcmd->cmd_code = wlan_cpu_to_le16(HostCmd_CMD_BGSCAN_CFG);
	hostcmd->seq_num = (0x01) << 13;
	hostcmd->result = 0;
	hostcmd->size = sizeof(mrvl_cmd_head_buf);

	/* These are all magic numbers from the bg_scan_wifidir.conf
	file supplied by Marvell */
	hdr = (mlanconfig_bgscfg_cmd_hdr *) (buf + sizeof(mrvl_cmd_head_buf));
	hdr->Action = 1;
	hdr->Enable = mode;
	hdr->BssType = 3;
	hdr->ChannelsPerScan = 3;
	hdr->ScanInterval = wlan_cpu_to_le32(1000);
	hdr->StoreCondition = wlan_cpu_to_le32(1);
	hdr->ReportConditions = wlan_cpu_to_le32(1);
	hostcmd->size += sizeof(mlanconfig_bgscfg_cmd_hdr);

	ssid_tlv = (ssid_header_tlv *) (buf + hostcmd->size);
	ssid_tlv->type = MLANCONFIG_SSID_HEADER_TYPE;
	ssid_tlv->len = wlan_cpu_to_le16(SIZEOF_VALUE(ssid_header_tlv));
	ssid_tlv->MaxSSIDLen = wlan_cpu_to_le16(0);
	memcpy(ssid_tlv->ssid, "DIRECT-", sizeof(ssid_tlv->ssid));
	hostcmd->size += sizeof(tlv) + ssid_tlv->len;

	probe_tlv = (probe_header_tlv *) (buf + hostcmd->size);
	probe_tlv->type = MLANCONFIG_PROBE_HEADER_TYPE;
	probe_tlv->len = wlan_cpu_to_le16(SIZEOF_VALUE(probe_header_tlv));
	probe_tlv->NumProbes = wlan_cpu_to_le16(2);
	hostcmd->size += sizeof(tlv) + probe_tlv->len;

	chan_tlv = (channel_header_tlv *) (buf + hostcmd->size);
	chan_tlv->type = MLANCONFIG_CHANNEL_HEADER_TYPE;
	chan_tlv->len = wlan_cpu_to_le16(SIZEOF_VALUE(channel_header_tlv));
	chan_tlv->Chan1_RadioType = 0;
	chan_tlv->Chan1_ChanNumber = 1;
	chan_tlv->Chan1_ScanType = 2;
	chan_tlv->Chan1_MinScanTime = wlan_cpu_to_le16(50);
	chan_tlv->Chan1_ScanTime = wlan_cpu_to_le16(100);
	chan_tlv->Chan2_RadioType = 0;
	chan_tlv->Chan2_ChanNumber = 6;
	chan_tlv->Chan2_ScanType = 2;
	chan_tlv->Chan2_MinScanTime = wlan_cpu_to_le16(50);
	chan_tlv->Chan2_ScanTime = wlan_cpu_to_le16(100);
	chan_tlv->Chan3_RadioType = 0;
	chan_tlv->Chan3_ChanNumber = 11;
	chan_tlv->Chan3_ScanType = 2;
	chan_tlv->Chan3_MinScanTime = wlan_cpu_to_le16(50);
	chan_tlv->Chan3_ScanTime = wlan_cpu_to_le16(100);
	hostcmd->size += sizeof(tlv) + chan_tlv->len;

	snr_tlv = (snr_header_tlv *) (buf + hostcmd->size);
	snr_tlv->type = MLANCONFIG_SNR_HEADER_TYPE;
	snr_tlv->len = wlan_cpu_to_le16(SIZEOF_VALUE(snr_header_tlv));
	snr_tlv->SNRValue = 40;
	hostcmd->size += sizeof(tlv) + snr_tlv->len;

	start_later_tlv = (start_later_header_tlv *) (buf + hostcmd->size);
	start_later_tlv->type = MLANCONFIG_START_LATER_HEADER_TYPE;
	start_later_tlv->len =
	    wlan_cpu_to_le16(SIZEOF_VALUE(start_later_header_tlv));
	start_later_tlv->StartLaterValue = 0;
	hostcmd->size += sizeof(tlv) + start_later_tlv->len;

	hostcmd->size = wlan_cpu_to_le16(hostcmd->size);

	cmd = (u8 *) buf;

	*(u32 *) cmd = hostcmd->size - BUF_HEADER_SIZE;

	header = (wfdcmdbuf *) cmd;
	header->cmd_head.size = hostcmd->size;
	header->cmd_head.buf_size = header->cmd_head.size + BUF_HEADER_SIZE;
	endian_convert_request_header(header->cmd_head);

	wps_hexdump(DEBUG_WFD_DISCOVERY, "Scan config", (unsigned char *)buf,
		    hostcmd->size);

	if (wfd_ioctl((u8 *) buf, hostcmd->size) == WPS_STATUS_SUCCESS) {
		wps_printf(DEBUG_WFD_DISCOVERY, "Scan config command sent.\n");
	} else {
		wps_printf(DEBUG_WFD_DISCOVERY,
			   "Scan config command send failed.\n");
		ret = WPS_STATUS_FAIL;
	}

	if (buf)
		wps_mem_free(buf);

	return ret;
}
/**
 *  @brief This function initializes the adapter structure
 *  		and sets default values to the members of adapter.
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *
 *  @return		N/A
 */
t_void
wlan_init_adapter(pmlan_adapter pmadapter)
{
    ENTER();

    pmadapter->cmd_sent = MFALSE;
    pmadapter->data_sent = MFALSE;
    pmadapter->cmd_resp_received = MFALSE;
    pmadapter->event_received = MFALSE;
    pmadapter->data_received = MFALSE;

    pmadapter->cmd_timer_is_set = MFALSE;

    /* PnP and power profile */
    pmadapter->surprise_removed = MFALSE;

    /* Status variables */
    pmadapter->hw_status = WlanHardwareStatusInitializing;

    /* Scan type */
    pmadapter->scan_type = HostCmd_SCAN_TYPE_ACTIVE;
    /* Scan mode */
    pmadapter->scan_mode = HostCmd_BSS_TYPE_ANY;
    /* Scan time */
    pmadapter->specific_scan_time = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
    pmadapter->active_scan_time = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
    pmadapter->passive_scan_time = MRVDRV_PASSIVE_SCAN_CHAN_TIME;

    pmadapter->num_in_scan_table = 0;
    memset(pmadapter->pscan_table, 0,
           (sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST));
    pmadapter->scan_probes = 0;

    memset(pmadapter->bcn_buf, 0, sizeof(pmadapter->bcn_buf));
    pmadapter->pbcn_buf_end = pmadapter->bcn_buf;

    pmadapter->radio_on = RADIO_ON;

    pmadapter->ps_mode = Wlan802_11PowerModeCAM;
    pmadapter->multiple_dtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;

    pmadapter->ps_state = PS_STATE_FULL_POWER;
    pmadapter->need_to_wakeup = MFALSE;
    pmadapter->local_listen_interval = 0;       /* default value in firmware
                                                   will be used */

    pmadapter->pm_wakeup_card_req = MFALSE;
    pmadapter->pm_wakeup_fw_try = MFALSE;

    pmadapter->max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;
    pmadapter->tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;

    pmadapter->is_hs_configured = MFALSE;
    pmadapter->hs_cfg.conditions = HOST_SLEEP_CFG_CANCEL;
    pmadapter->hs_cfg.gpio = 0;
    pmadapter->hs_cfg.gap = 0;
    pmadapter->hs_activated = MFALSE;

    memset(pmadapter->event_body, 0, sizeof(pmadapter->event_body));
    pmadapter->hw_dot_11n_dev_cap = 0;
    pmadapter->hw_dev_mcs_support = 0;
    pmadapter->usr_dot_11n_dev_cap = 0;
    pmadapter->usr_dev_mcs_support = 0;
    pmadapter->chan_offset = 0;

    /* Initialize 802.11d */
    wlan_11d_init(pmadapter);

    wlan_wmm_init(pmadapter);
    util_init_list_head(&pmadapter->rx_data_queue, MTRUE,
                        pmadapter->callbacks.moal_init_lock);

    memset(&pmadapter->sleep_cfm_buf.ps_cfm_sleep, 0,
           sizeof(PS_CMD_ConfirmSleep));
    pmadapter->sleep_cfm_buf.ps_cfm_sleep.command =
        wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE);
    pmadapter->sleep_cfm_buf.ps_cfm_sleep.size =
        wlan_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep));
    pmadapter->sleep_cfm_buf.ps_cfm_sleep.result = 0;
    pmadapter->sleep_cfm_buf.ps_cfm_sleep.action =
        wlan_cpu_to_le16(HostCmd_SubCmd_Sleep_Confirmed);

    memset(&pmadapter->sleep_params, 0, sizeof(pmadapter->sleep_params));
    memset(&pmadapter->sleep_period, 0, sizeof(pmadapter->sleep_period));
    pmadapter->tx_lock_flag = MFALSE;
    pmadapter->null_pkt_interval = 0;
    pmadapter->fw_bands = 0;
    pmadapter->config_bands = 0;
    pmadapter->adhoc_start_band = 0;
    pmadapter->pscan_channels = MNULL;
    pmadapter->fw_release_number = 0;
    pmadapter->fw_cap_info = 0;
    memset(&pmadapter->upld_buf, 0, sizeof(pmadapter->upld_buf));
    pmadapter->upld_len = 0;
    pmadapter->event_cause = 0;
    memset(&pmadapter->region_channel, 0, sizeof(pmadapter->region_channel));
    pmadapter->region_code = 0;
    pmadapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
    pmadapter->adhoc_awake_period = 0;
    memset(&pmadapter->arp_filter, 0, sizeof(pmadapter->arp_filter));
    pmadapter->arp_filter_size = 0;

    LEAVE();
    return;
}
/**
 *  @brief This function checks the interrupt status and handle it accordingly.
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_int_status(mlan_adapter * pmadapter)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	t_u8 sdio_ireg;
	mlan_buffer *pmbuf = MNULL;
	t_u8 port = 0;
	t_u32 len_reg_l, len_reg_u;
	t_u32 rx_blocks;
	t_u32 ps_state = pmadapter->ps_state;
	t_u16 rx_len;
#if !defined(SDIO_MULTI_PORT_RX_AGGR)
	t_u32 upld_typ = 0;
#endif
	t_u32 cr = 0;

	ENTER();

	pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->pint_lock);
	sdio_ireg = pmadapter->sdio_ireg;
	pmadapter->sdio_ireg = 0;
	pcb->moal_spin_unlock(pmadapter->pmoal_handle, pmadapter->pint_lock);

	if (!sdio_ireg)
		goto done;

	if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
		pmadapter->mp_wr_bitmap =
			(t_u32) pmadapter->mp_regs[WR_BITMAP_L];
		pmadapter->mp_wr_bitmap |=
			((t_u32) pmadapter->mp_regs[WR_BITMAP_U]) << 8;
		PRINTM(MINTR, "DNLD: wr_bitmap=0x%08x\n",
		       pmadapter->mp_wr_bitmap);
		if (pmadapter->data_sent &&
		    (pmadapter->mp_wr_bitmap & pmadapter->mp_data_port_mask)) {
			PRINTM(MINFO, " <--- Tx DONE Interrupt --->\n");
			pmadapter->data_sent = MFALSE;
		}
	}

	/* As firmware will not generate download ready interrupt if the port
	   updated is command port only, cmd_sent should be done for any SDIO
	   interrupt. */
	if (pmadapter->cmd_sent == MTRUE) {
		/* Check if firmware has attach buffer at command port and
		   update just that in wr_bit_map. */
		pmadapter->mp_wr_bitmap |=
			(t_u32) pmadapter->
			mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
		if (pmadapter->mp_wr_bitmap & CTRL_PORT_MASK)
			pmadapter->cmd_sent = MFALSE;
	}

	PRINTM(MINFO, "cmd_sent=%d, data_sent=%d\n", pmadapter->cmd_sent,
	       pmadapter->data_sent);

	if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
		pmadapter->mp_rd_bitmap =
			(t_u32) pmadapter->mp_regs[RD_BITMAP_L];
		pmadapter->mp_rd_bitmap |=
			((t_u32) pmadapter->mp_regs[RD_BITMAP_U]) << 8;
		PRINTM(MINTR, "UPLD: rd_bitmap=0x%08x\n",
		       pmadapter->mp_rd_bitmap);

		while (MTRUE) {
			ret = wlan_get_rd_port(pmadapter, &port);
			if (ret != MLAN_STATUS_SUCCESS) {
				PRINTM(MINFO,
				       "no more rd_port to be handled\n");
				break;
			}
			len_reg_l = RD_LEN_P0_L + (port << 1);
			len_reg_u = RD_LEN_P0_U + (port << 1);
			rx_len = ((t_u16) pmadapter->mp_regs[len_reg_u]) << 8;
			rx_len |= (t_u16) pmadapter->mp_regs[len_reg_l];
			PRINTM(MINFO, "RX: port=%d rx_len=%u\n", port, rx_len);
			rx_blocks =
				(rx_len + MLAN_SDIO_BLOCK_SIZE -
				 1) / MLAN_SDIO_BLOCK_SIZE;
			if (rx_len <= INTF_HEADER_LEN ||
			    (rx_blocks * MLAN_SDIO_BLOCK_SIZE) >
			    ALLOC_BUF_SIZE) {
				PRINTM(MERROR, "invalid rx_len=%d\n", rx_len);
				ret = MLAN_STATUS_FAILURE;
				goto done;
			}
			rx_len = (t_u16) (rx_blocks * MLAN_SDIO_BLOCK_SIZE);
			if (port == CTRL_PORT)
				pmbuf = wlan_alloc_mlan_buffer(pmadapter,
							       rx_len, 0,
							       MOAL_MALLOC_BUFFER);
			else
				pmbuf = wlan_alloc_mlan_buffer(pmadapter,
							       rx_len,
							       MLAN_RX_HEADER_LEN,
							       MOAL_ALLOC_MLAN_BUFFER);
			if (pmbuf == MNULL) {
				PRINTM(MERROR,
				       "Failed to allocate 'mlan_buffer'\n");
				ret = MLAN_STATUS_FAILURE;
				goto done;
			}
			PRINTM(MINFO, "rx_len = %d\n", rx_len);
#ifdef SDIO_MULTI_PORT_RX_AGGR
			if (MLAN_STATUS_SUCCESS !=
			    wlan_sdio_card_to_host_mp_aggr(pmadapter, pmbuf,
							   port, rx_len)) {
#else
			/* Transfer data from card */
			if (MLAN_STATUS_SUCCESS !=
			    wlan_sdio_card_to_host(pmadapter, &upld_typ,
						   (t_u32 *) & pmadapter->
						   upld_len, pmbuf, rx_len,
						   pmadapter->ioport + port)) {
#endif /* SDIO_MULTI_PORT_RX_AGGR */

				if (port == CTRL_PORT)
					pmadapter->dbg.
						num_cmdevt_card_to_host_failure++;
				else
					pmadapter->dbg.
						num_rx_card_to_host_failure++;

				PRINTM(MERROR,
				       "Card to host failed: int status=0x%x\n",
				       sdio_ireg);
#ifndef SDIO_MULTI_PORT_RX_AGGR
				wlan_free_mlan_buffer(pmadapter, pmbuf);
#endif
				ret = MLAN_STATUS_FAILURE;
				goto term_cmd53;
			}
#ifndef SDIO_MULTI_PORT_RX_AGGR
			wlan_decode_rx_packet(pmadapter, pmbuf, upld_typ);
#endif
		}
		/* We might receive data/sleep_cfm at the same time */
		/* reset data_receive flag to avoid ps_state change */
		if ((ps_state == PS_STATE_SLEEP_CFM) &&
		    (pmadapter->ps_state == PS_STATE_SLEEP))
			pmadapter->data_received = MFALSE;
	}

	ret = MLAN_STATUS_SUCCESS;
	goto done;

term_cmd53:
	/* terminate cmd53 */
	if (MLAN_STATUS_SUCCESS != pcb->moal_read_reg(pmadapter->pmoal_handle,
						      HOST_TO_CARD_EVENT_REG,
						      &cr))
		PRINTM(MERROR, "read CFG reg failed\n");
	PRINTM(MINFO, "Config Reg val = %d\n", cr);
	if (MLAN_STATUS_SUCCESS != pcb->moal_write_reg(pmadapter->pmoal_handle,
						       HOST_TO_CARD_EVENT_REG,
						       (cr | HOST_TERM_CMD53)))
		PRINTM(MERROR, "write CFG reg failed\n");
	PRINTM(MINFO, "write success\n");
	if (MLAN_STATUS_SUCCESS != pcb->moal_read_reg(pmadapter->pmoal_handle,
						      HOST_TO_CARD_EVENT_REG,
						      &cr))
		PRINTM(MERROR, "read CFG reg failed\n");
	PRINTM(MINFO, "Config reg val =%x\n", cr);

done:
	LEAVE();
	return ret;
}

/**
 *  @brief This function sends data to the card.
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *  @param type	     data or command
 *  @param pmbuf     A pointer to mlan_buffer (pmbuf->data_len should include SDIO header)
 *  @param tx_param  A pointer to mlan_tx_param
 *  @return 	     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_sdio_host_to_card(mlan_adapter * pmadapter, t_u8 type, mlan_buffer * pmbuf,
		       mlan_tx_param * tx_param)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u32 buf_block_len;
	t_u32 blksz;
	t_u8 port = 0;
	t_u32 cmd53_port = 0;
	t_u8 *payload = pmbuf->pbuf + pmbuf->data_offset;

	ENTER();

	/* Allocate buffer and copy payload */
	blksz = MLAN_SDIO_BLOCK_SIZE;
	buf_block_len = (pmbuf->data_len + blksz - 1) / blksz;
	*(t_u16 *) & payload[0] = wlan_cpu_to_le16((t_u16) pmbuf->data_len);
	*(t_u16 *) & payload[2] = wlan_cpu_to_le16(type);

	/*
	 * This is SDIO specific header
	 *  t_u16 length,
	 *  t_u16 type (MLAN_TYPE_DATA = 0, MLAN_TYPE_CMD = 1, MLAN_TYPE_EVENT = 3)
	 */
	if (type == MLAN_TYPE_DATA) {
		ret = wlan_get_wr_port_data(pmadapter, &port);
		if (ret != MLAN_STATUS_SUCCESS) {
			PRINTM(MERROR, "no wr_port available: %d\n", ret);
			goto exit;
		}
		/* Transfer data to card */
		pmbuf->data_len = buf_block_len * blksz;

#ifdef SDIO_MULTI_PORT_TX_AGGR
		if (tx_param)
			ret = wlan_host_to_card_mp_aggr(pmadapter, pmbuf, port,
							tx_param->next_pkt_len);
		else
			ret = wlan_host_to_card_mp_aggr(pmadapter, pmbuf, port,
							0);
#else
		ret = wlan_write_data_sync(pmadapter, pmbuf,
					   pmadapter->ioport + port);
#endif /* SDIO_MULTI_PORT_TX_AGGR */

	} else {
		/* Type must be MLAN_TYPE_CMD */
		pmadapter->cmd_sent = MTRUE;
		/* clear CTRL PORT */
		pmadapter->mp_wr_bitmap &= (t_u32) (~(1 << CTRL_PORT));
		if (pmbuf->data_len <= INTF_HEADER_LEN ||
		    pmbuf->data_len > WLAN_UPLD_SIZE)
			PRINTM(MWARN,
			       "wlan_sdio_host_to_card(): Error: payload=%p, nb=%d\n",
			       payload, pmbuf->data_len);
		/* Transfer data to card */
		pmbuf->data_len = buf_block_len * blksz;
		cmd53_port = pmadapter->ioport + CTRL_PORT;
		ret = wlan_write_data_sync(pmadapter, pmbuf, cmd53_port);
	}

	if (ret != MLAN_STATUS_SUCCESS) {
		if (type == MLAN_TYPE_CMD)
			pmadapter->cmd_sent = MFALSE;
		if (type == MLAN_TYPE_DATA)
			pmadapter->data_sent = MFALSE;
	} else {
		if (type == MLAN_TYPE_DATA) {
			if (!
			    (pmadapter->
			     mp_wr_bitmap & (1 << pmadapter->curr_wr_port)))
				pmadapter->data_sent = MTRUE;
			else
				pmadapter->data_sent = MFALSE;
		}
		DBG_HEXDUMP(MIF_D, "SDIO Blk Wr",
			    pmbuf->pbuf + pmbuf->data_offset,
			    MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));
	}
exit:
	LEAVE();
	return ret;
}