/** * * @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; }
/** * @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; }
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; }
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; }
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; }
/** * @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; }
/** * @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; }
/** * @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; }
/** * @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; }
/** * @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; }
/* * 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; }
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; }
/** * @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; }
/** * @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; }
/** * @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(); }
/** * @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; }
/* 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; }