/** @file mlan_sta_cmdresp.c * * @brief This file contains the handling of command * responses generated by firmware. * * * Copyright 2008-2022 NXP * * NXP CONFIDENTIAL * The source code contained or described herein and all documents related to * the source code (Materials) are owned by NXP, its * suppliers and/or its licensors. Title to the Materials remains with NXP, * its suppliers and/or its licensors. The Materials contain * trade secrets and proprietary and confidential information of NXP, its * suppliers and/or its licensors. The Materials are protected by worldwide * copyright and trade secret laws and treaty provisions. No part of the * Materials may be used, copied, reproduced, modified, published, uploaded, * posted, transmitted, distributed, or disclosed in any way without NXP's * prior express written permission. * * No license under any patent, copyright, trade secret or other intellectual * property right is granted to or conferred upon you by disclosure or delivery * of the Materials, either expressly, by implication, inducement, estoppel or * otherwise. Any license under such intellectual property rights must be * express and approved by NXP in writing. * * Alternatively, this software may be distributed under the terms of GPL v2. * SPDX-License-Identifier: GPL-2.0 * * */ /****************************************************** * Change log: * 10/21/2008: initial version ******************************************************/ #include "mlan.h" #include "mlan_join.h" #include "mlan_util.h" #include "mlan_fw.h" #include "mlan_main.h" #include "mlan_wmm.h" #include "mlan_11n.h" #include "mlan_11ac.h" #include "mlan_11ax.h" #include "mlan_11h.h" #include "mlan_meas.h" /******************************************************** * Local Variables ********************************************************/ /******************************************************** * Global Variables ********************************************************/ /******************************************************** * Local Functions ********************************************************/ /** * @brief This function handles the command response error for TDLS operation * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * * @return N/A */ static void wlan_process_cmdreps_error_tdls_operation(mlan_private *pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_adapter *pmadapter = pmpriv->adapter; HostCmd_DS_TDLS_OPER *ptdls_oper_data = &(resp->params.tdls_oper_data); sta_node *sta_ptr = MNULL; t_u16 reason; ENTER(); ptdls_oper_data->tdls_action = wlan_le16_to_cpu(ptdls_oper_data->tdls_action); reason = wlan_le16_to_cpu(ptdls_oper_data->reason); sta_ptr = wlan_get_station_entry(pmpriv, ptdls_oper_data->peer_mac); switch (ptdls_oper_data->tdls_action) { case TDLS_CREATE: /* TDLS create command error */ if (reason != TDLS_LINK_EXISTS && sta_ptr) { PRINTM(MERROR, "TDLS CREATE operation: cmd error reason %d\n", reason); sta_ptr->status = TDLS_SETUP_FAILURE; } if (reason == TDLS_LINK_EXISTS && pioctl_buf) pioctl_buf->status_code = MLAN_STATUS_SUCCESS; break; case TDLS_CONFIG: /* TDLS config command error */ PRINTM(MERROR, "TDLS CONFIG operation: command error, reason %d\n", reason); if (sta_ptr) sta_ptr->status = TDLS_SETUP_FAILURE; break; case TDLS_DELETE: /* TDLS delete command error */ wlan_restore_tdls_packets(pmpriv, ptdls_oper_data->peer_mac, TDLS_TEAR_DOWN); if (sta_ptr) { /**tdls cs stop*/ if (ISSUPP_EXTCAP_TDLS_CHAN_SWITCH( sta_ptr->ExtCap.ext_cap)) wlan_tdls_config(pmpriv, MFALSE); if (sta_ptr->is_11n_enabled) { wlan_cleanup_reorder_tbl( pmpriv, ptdls_oper_data->peer_mac); wlan_11n_cleanup_txbastream_tbl( pmpriv, ptdls_oper_data->peer_mac); } if (sta_ptr->status >= TDLS_SETUP_INPROGRESS) wlan_delete_station_entry( pmpriv, ptdls_oper_data->peer_mac); } if (wlan_is_station_list_empty(pmpriv) == MTRUE) pmadapter->tdls_status = TDLS_NOT_SETUP; else pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL; if (reason == TDLS_LINK_NONEXISTENT) { if (pioctl_buf) pioctl_buf->status_code = MLAN_STATUS_SUCCESS; } else { PRINTM(MERROR, "TDLS DELETE operation: cmd error, reason %d\n", reason); } break; } LEAVE(); return; } /** * @brief This function handles the command response error * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to command buffer * * @return N/A */ static mlan_status wlan_process_cmdresp_error(mlan_private *pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_adapter *pmadapter = pmpriv->adapter; pmlan_ioctl_req pscan_ioctl_req = MNULL; mlan_callbacks *pcb = MNULL; tdls_all_config *tdls_all_cfg = MNULL; HostCmd_DS_TDLS_CONFIG *ptdls_config_data = &(resp->params.tdls_config_data); #if defined(USB) t_s32 i = 0; #endif mlan_status ret = MLAN_STATUS_FAILURE; ENTER(); if (resp->command != HostCmd_CMD_WMM_PARAM_CONFIG && resp->command != HostCmd_CMD_CHAN_REGION_CFG) PRINTM(MERROR, "CMD_RESP: cmd %#x error, result=%#x\n", resp->command, resp->result); if (pioctl_buf) pioctl_buf->status_code = MLAN_ERROR_FW_CMDRESP; switch (resp->command) { case HostCmd_CMD_802_11_PS_MODE_ENH: { HostCmd_DS_802_11_PS_MODE_ENH *pm = &resp->params.psmode_enh; PRINTM(MERROR, "PS_MODE_ENH command failed: result=0x%x action=0x%X\n", resp->result, wlan_le16_to_cpu(pm->action)); /* * We do not re-try enter-ps command in ad-hoc mode. */ if (wlan_le16_to_cpu(pm->action) == EN_AUTO_PS && (wlan_le16_to_cpu(pm->params.auto_ps.ps_bitmap) & BITMAP_STA_PS) && pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) pmadapter->ps_mode = Wlan802_11PowerModeCAM; } break; case HostCmd_CMD_802_11_SCAN_EXT: case HostCmd_CMD_802_11_SCAN: /* Cancel all pending scan command */ wlan_flush_scan_queue(pmadapter); pcb = (pmlan_callbacks)&pmadapter->callbacks; wlan_request_cmd_lock(pmadapter); pmadapter->scan_processing = MFALSE; pscan_ioctl_req = pmadapter->pscan_ioctl_req; pmadapter->pscan_ioctl_req = MNULL; /* Need to indicate IOCTL complete */ if (pscan_ioctl_req) { pscan_ioctl_req->status_code = MLAN_ERROR_NO_ERROR; /* Indicate ioctl complete */ pcb->moal_ioctl_complete( pmadapter->pmoal_handle, (pmlan_ioctl_req)pscan_ioctl_req, MLAN_STATUS_SUCCESS); } wlan_release_cmd_lock(pmadapter); wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_SCAN_REPORT, MNULL); break; case HostCmd_CMD_MAC_CONTROL: break; case HostCmd_CMD_TDLS_CONFIG: ptdls_config_data->tdls_info.tdls_action = wlan_le16_to_cpu( ptdls_config_data->tdls_info.tdls_action); switch (ptdls_config_data->tdls_info.tdls_action) { case WLAN_TDLS_SETUP_REQ: /* TDLS link setup error ;display error in logs */ tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; PRINTM(MERROR, "TDLS Setup Failed, error %d\n", wlan_le16_to_cpu(tdls_all_cfg->u.tdls_cmd_resp .reason_code)); break; case WLAN_TDLS_INIT_CHAN_SWITCH: tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; PRINTM(MERROR, "TDLS init channel switch failed," MACSTR ": reason=%d\n", MAC2STR(tdls_all_cfg->u.tdls_cmd_resp .peer_mac_addr), wlan_le16_to_cpu(tdls_all_cfg->u.tdls_cmd_resp .reason_code)); break; } break; case HostCmd_CMD_TDLS_OPERATION: wlan_process_cmdreps_error_tdls_operation(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_PACKET_AGGR_CTRL: #ifdef USB if (IS_USB(pmadapter->card_type)) { for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) pmadapter->pcard_usb->usb_tx_aggr[i] .aggr_ctrl.enable = MFALSE; pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.enable = MFALSE; } #endif break; #ifdef USB case HostCmd_CMD_PACKET_AGGR_OVER_HOST_INTERFACE: pmadapter->pcard_usb->fw_usb_aggr = MFALSE; for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) pmadapter->pcard_usb->usb_tx_aggr[i].aggr_ctrl.enable = MFALSE; pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.enable = MFALSE; break; #endif case HostCmd_CMD_802_11_ASSOCIATE: wlan_reset_connect_state(pmpriv, MTRUE); break; #ifdef SDIO case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG: pmadapter->pcard_sd->sdio_rx_aggr_enable = MFALSE; PRINTM(MMSG, "FW don't support SDIO single port rx aggr\n"); break; #endif case HostCmd_CMD_MGMT_IE_LIST: { HostCmd_DS_MGMT_IE_LIST_CFG *pmgmt_ie_list = &(resp->params.mgmt_ie_list); t_u16 resp_len = 0, travel_len = 0, index; mlan_ds_misc_custom_ie *cust_ie = MNULL; custom_ie *cptr; if (wlan_le16_to_cpu(pmgmt_ie_list->action) == HostCmd_ACT_GEN_GET) break; cust_ie = (mlan_ds_misc_custom_ie *)&pmgmt_ie_list->ds_mgmt_ie; if (cust_ie) { cust_ie->type = wlan_le16_to_cpu(cust_ie->type); resp_len = cust_ie->len = wlan_le16_to_cpu(cust_ie->len); travel_len = 0; /* conversion for index, mask, len */ if (resp_len == sizeof(t_u16)) cust_ie->ie_data_list[0] .ie_index = wlan_cpu_to_le16( cust_ie->ie_data_list[0].ie_index); while (resp_len > sizeof(t_u16)) { cptr = (custom_ie *)(((t_u8 *)cust_ie ->ie_data_list) + travel_len); index = cptr->ie_index = wlan_le16_to_cpu(cptr->ie_index); cptr->mgmt_subtype_mask = wlan_le16_to_cpu( cptr->mgmt_subtype_mask); cptr->ie_length = wlan_le16_to_cpu(cptr->ie_length); travel_len += cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE; resp_len -= cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE; if ((pmpriv->mgmt_ie[index].mgmt_subtype_mask == cptr->mgmt_subtype_mask) && (pmpriv->mgmt_ie[index].ie_length == cptr->ie_length) && !memcmp(pmpriv->adapter, pmpriv->mgmt_ie[index].ie_buffer, cptr->ie_buffer, cptr->ie_length)) { PRINTM(MERROR, "set custom ie fail, remove ie index :%d\n", index); memset(pmadapter, &pmpriv->mgmt_ie[index], 0, sizeof(custom_ie)); } } } } break; case HostCmd_CMD_ROAM_OFFLOAD: wlan_clear_fw_roaming_pmk(pmpriv); pmpriv->adapter->fw_roaming = MFALSE; PRINTM(MERROR, "FW do not support roaming!\n"); break; case HostCmd_CMD_CHAN_REGION_CFG: ret = MLAN_STATUS_SUCCESS; PRINTM(MCMND, "FW don't support chan region cfg command!\n"); break; #if defined(DRV_EMBEDDED_SUPPLICANT) case HostCmd_CMD_CRYPTO: PRINTM(MCMND, "crypto cmd result=0x%x!\n", resp->result); ret = wlan_ret_crypto(pmpriv, resp, pioctl_buf); break; #endif default: break; } /* * Handling errors here */ wlan_request_cmd_lock(pmadapter); wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd); pmadapter->curr_cmd = MNULL; wlan_release_cmd_lock(pmadapter); LEAVE(); return ret; } /** * @brief This function handles the command response of RSSI info * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_rssi_info_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_RSSI_INFO_EXT *prssi_info_rsp = &resp->params.rssi_info_ext; mlan_ds_get_signal *signal = MNULL; mlan_ds_get_info *info = MNULL; MrvlIEtypes_RSSI_EXT_t *signal_info_tlv = MNULL; t_u16 tlv_left_len = 0, tlv_num = 0; t_u16 tlv_id, tlv_len; ENTER(); /* Need to indicate IOCTL complete */ if (pioctl_buf != MNULL) { info = (mlan_ds_get_info *)pioctl_buf->pbuf; signal_info_tlv = (MrvlIEtypes_RSSI_EXT_t *)(prssi_info_rsp->tlv_buf); tlv_left_len = resp->size - (sizeof(HostCmd_DS_802_11_RSSI_INFO_EXT) + S_DS_GEN); while (tlv_left_len >= sizeof(MrvlIEtypes_RSSI_EXT_t)) { tlv_id = wlan_le16_to_cpu(signal_info_tlv->header.type); tlv_len = wlan_le16_to_cpu(signal_info_tlv->header.len); if ((tlv_id != TLV_TYPE_RSSI_INFO) || (tlv_len != sizeof(MrvlIEtypes_RSSI_EXT_t) - sizeof(MrvlIEtypesHeader_t))) { PRINTM(MERROR, "Invalid RSSI INFO TLV, type=%d, len=%d\n", tlv_id, tlv_len); break; } signal = (mlan_ds_get_signal *)&info->param .signal_ext[tlv_num]; /* PATH ID */ signal->selector = wlan_le16_to_cpu(signal_info_tlv->path_id); /* RSSI */ signal->bcn_rssi_last = wlan_le16_to_cpu( signal_info_tlv->bcn_rssi_last); signal->bcn_rssi_avg = wlan_le16_to_cpu(signal_info_tlv->bcn_rssi_avg); signal->data_rssi_last = wlan_le16_to_cpu( signal_info_tlv->data_rssi_last); signal->data_rssi_avg = wlan_le16_to_cpu( signal_info_tlv->data_rssi_avg); /* SNR */ signal->bcn_snr_last = CAL_SNR( wlan_le16_to_cpu( signal_info_tlv->bcn_rssi_last), wlan_le16_to_cpu(signal_info_tlv->bcn_nf_last)); signal->bcn_snr_avg = CAL_SNR( wlan_le16_to_cpu(signal_info_tlv->bcn_rssi_avg), wlan_le16_to_cpu(signal_info_tlv->bcn_nf_avg)); signal->data_snr_last = CAL_SNR( wlan_le16_to_cpu( signal_info_tlv->data_rssi_last), wlan_le16_to_cpu( signal_info_tlv->data_nf_last)); signal->data_snr_avg = CAL_SNR( wlan_le16_to_cpu( signal_info_tlv->data_rssi_avg), wlan_le16_to_cpu(signal_info_tlv->data_nf_avg)); /* NF */ signal->bcn_nf_last = wlan_le16_to_cpu(signal_info_tlv->bcn_nf_last); signal->bcn_nf_avg = wlan_le16_to_cpu(signal_info_tlv->bcn_nf_avg); signal->data_nf_last = wlan_le16_to_cpu(signal_info_tlv->data_nf_last); signal->data_nf_avg = wlan_le16_to_cpu(signal_info_tlv->data_nf_avg); tlv_left_len -= sizeof(MrvlIEtypes_RSSI_EXT_t); signal_info_tlv++; tlv_num++; if (tlv_num > MAX_PATH_NUM) break; } pioctl_buf->data_read_written = tlv_num * sizeof(mlan_ds_get_signal) + sizeof(t_u32); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of RSSI info * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_rssi_info(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_RSSI_INFO_RSP *prssi_info_rsp = &resp->params.rssi_info_rsp; mlan_ds_get_info *pget_info = MNULL; BSSDescriptor_t *pbss_desc; t_s32 tbl_idx = 0; ENTER(); pmpriv->data_rssi_last = wlan_le16_to_cpu(prssi_info_rsp->data_rssi_last); pmpriv->data_nf_last = wlan_le16_to_cpu(prssi_info_rsp->data_nf_last); pmpriv->data_rssi_avg = wlan_le16_to_cpu(prssi_info_rsp->data_rssi_avg); pmpriv->data_nf_avg = wlan_le16_to_cpu(prssi_info_rsp->data_nf_avg); pmpriv->bcn_rssi_last = wlan_le16_to_cpu(prssi_info_rsp->bcn_rssi_last); pmpriv->bcn_nf_last = wlan_le16_to_cpu(prssi_info_rsp->bcn_nf_last); pmpriv->bcn_rssi_avg = wlan_le16_to_cpu(prssi_info_rsp->bcn_rssi_avg); pmpriv->bcn_nf_avg = wlan_le16_to_cpu(prssi_info_rsp->bcn_nf_avg); /* Get current BSS info */ pbss_desc = &pmpriv->curr_bss_params.bss_descriptor; pbss_desc->rssi = -pmpriv->bcn_rssi_avg; tbl_idx = wlan_find_ssid_in_list(pmpriv, &pbss_desc->ssid, pbss_desc->mac_address, pmpriv->bss_mode); if (tbl_idx >= 0) { pbss_desc = &pmpriv->adapter->pscan_table[tbl_idx]; pbss_desc->rssi = -pmpriv->bcn_rssi_avg; } /* Need to indicate IOCTL complete */ if (pioctl_buf != MNULL) { pget_info = (mlan_ds_get_info *)pioctl_buf->pbuf; memset(pmpriv->adapter, &pget_info->param.signal, 0, sizeof(mlan_ds_get_signal)); pget_info->param.signal.selector = ALL_RSSI_INFO_MASK; /* RSSI */ pget_info->param.signal.bcn_rssi_last = pmpriv->bcn_rssi_last; pget_info->param.signal.bcn_rssi_avg = pmpriv->bcn_rssi_avg; pget_info->param.signal.data_rssi_last = pmpriv->data_rssi_last; pget_info->param.signal.data_rssi_avg = pmpriv->data_rssi_avg; /* SNR */ pget_info->param.signal.bcn_snr_last = CAL_SNR(pmpriv->bcn_rssi_last, pmpriv->bcn_nf_last); pget_info->param.signal.bcn_snr_avg = CAL_SNR(pmpriv->bcn_rssi_avg, pmpriv->bcn_nf_avg); pget_info->param.signal.data_snr_last = CAL_SNR(pmpriv->data_rssi_last, pmpriv->data_nf_last); pget_info->param.signal.data_snr_avg = CAL_SNR(pmpriv->data_rssi_avg, pmpriv->data_nf_avg); /* NF */ pget_info->param.signal.bcn_nf_last = pmpriv->bcn_nf_last; pget_info->param.signal.bcn_nf_avg = pmpriv->bcn_nf_avg; pget_info->param.signal.data_nf_last = pmpriv->data_nf_last; pget_info->param.signal.data_nf_avg = pmpriv->data_nf_avg; pioctl_buf->data_read_written = sizeof(mlan_ds_get_info); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of snmp_mib * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_snmp_mib(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_SNMP_MIB *psmib = &resp->params.smib; t_u16 oid = wlan_le16_to_cpu(psmib->oid); t_u16 query_type = wlan_le16_to_cpu(psmib->query_type); t_u32 ul_temp; mlan_ds_snmp_mib *mib = MNULL; ENTER(); if (pioctl_buf) mib = (mlan_ds_snmp_mib *)pioctl_buf->pbuf; PRINTM(MINFO, "SNMP_RESP: value of the oid = 0x%x, query_type=0x%x\n", oid, query_type); PRINTM(MINFO, "SNMP_RESP: Buf size = 0x%x\n", wlan_le16_to_cpu(psmib->buf_size)); if (query_type == HostCmd_ACT_GEN_GET) { switch (oid) { case DtimPeriod_i: ul_temp = psmib->value[0]; PRINTM(MINFO, "SNMP_RESP: DTIM Period =%u\n", ul_temp); if (mib) mib->param.dtim_period = ul_temp; break; case FragThresh_i: ul_temp = wlan_le16_to_cpu(*((t_u16 *)(psmib->value))); PRINTM(MINFO, "SNMP_RESP: FragThsd =%u\n", ul_temp); if (mib) mib->param.frag_threshold = ul_temp; break; case RtsThresh_i: ul_temp = wlan_le16_to_cpu(*((t_u16 *)(psmib->value))); PRINTM(MINFO, "SNMP_RESP: RTSThsd =%u\n", ul_temp); if (mib) mib->param.rts_threshold = ul_temp; break; case ShortRetryLim_i: ul_temp = wlan_le16_to_cpu(*((t_u16 *)(psmib->value))); PRINTM(MINFO, "SNMP_RESP: TxRetryCount=%u\n", ul_temp); if (mib) mib->param.retry_count = ul_temp; break; case WwsMode_i: ul_temp = wlan_le16_to_cpu(*((t_u16 *)(psmib->value))); PRINTM(MINFO, "SNMP_RESP: WWSCfg =%u\n", ul_temp); if (pioctl_buf) ((mlan_ds_misc_cfg *)pioctl_buf->pbuf) ->param.wws_cfg = ul_temp; break; case Thermal_i: ul_temp = wlan_le32_to_cpu(*((t_u32 *)(psmib->value))); PRINTM(MINFO, "SNMP_RESP: Thermal =%u\n", ul_temp); if (pioctl_buf) ((mlan_ds_misc_cfg *)pioctl_buf->pbuf) ->param.thermal = ul_temp; break; case NullPktPeriod_i: ul_temp = psmib->value[0]; PRINTM(MINFO, "SNMP_RESP: Auto NULL Pkt Period =%u\n", ul_temp); break; default: break; } } else { /* (query_type == HostCmd_ACT_GEN_SET) */ /* Update state for 11d */ if (oid == Dot11D_i) { ul_temp = wlan_le16_to_cpu(*((t_u16 *)(psmib->value))); /* Set 11d state to private */ pmpriv->state_11d.enable_11d = ul_temp; /* Set user enable flag if called from ioctl */ if (pioctl_buf) pmpriv->state_11d.user_enable_11d = ul_temp; } /* Update state for 11h */ if (oid == Dot11H_i) { ul_temp = wlan_le16_to_cpu(*((t_u16 *)(psmib->value))); /* Set 11h state to priv */ pmpriv->intf_state_11h.is_11h_active = (ul_temp & ENABLE_11H_MASK); /* Set radar_det state to adapter */ pmpriv->adapter->state_11h.is_master_radar_det_active = (ul_temp & MASTER_RADAR_DET_MASK) ? MTRUE : MFALSE; pmpriv->adapter->state_11h.is_slave_radar_det_active = (ul_temp & SLAVE_RADAR_DET_MASK) ? MTRUE : MFALSE; } } if (pioctl_buf) { /* Indicate ioctl complete */ pioctl_buf->data_read_written = sizeof(mlan_ds_snmp_mib); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of get_log * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_get_log(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_GET_LOG *pget_log = (HostCmd_DS_802_11_GET_LOG *)&resp->params.get_log; mlan_ds_get_info *pget_info = MNULL; int i = 0; ENTER(); if (pioctl_buf) { pget_info = (mlan_ds_get_info *)pioctl_buf->pbuf; pget_info->param.stats.mcast_tx_frame = wlan_le32_to_cpu(pget_log->mcast_tx_frame); pget_info->param.stats.failed = wlan_le32_to_cpu(pget_log->failed); pget_info->param.stats.retry = wlan_le32_to_cpu(pget_log->retry); pget_info->param.stats.multi_retry = wlan_le32_to_cpu(pget_log->multiretry); pget_info->param.stats.frame_dup = wlan_le32_to_cpu(pget_log->frame_dup); pget_info->param.stats.rts_success = wlan_le32_to_cpu(pget_log->rts_success); pget_info->param.stats.rts_failure = wlan_le32_to_cpu(pget_log->rts_failure); pget_info->param.stats.ack_failure = wlan_le32_to_cpu(pget_log->ack_failure); pget_info->param.stats.rx_frag = wlan_le32_to_cpu(pget_log->rx_frag); pget_info->param.stats.mcast_rx_frame = wlan_le32_to_cpu(pget_log->mcast_rx_frame); pget_info->param.stats.fcs_error = wlan_le32_to_cpu(pget_log->fcs_error); pget_info->param.stats.tx_frame = wlan_le32_to_cpu(pget_log->tx_frame); pget_info->param.stats.wep_icv_error[0] = wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[0]); pget_info->param.stats.wep_icv_error[1] = wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[1]); pget_info->param.stats.wep_icv_error[2] = wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[2]); pget_info->param.stats.wep_icv_error[3] = wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[3]); pget_info->param.stats.bcn_rcv_cnt = wlan_le32_to_cpu(pget_log->bcn_rcv_cnt); pget_info->param.stats.bcn_miss_cnt = wlan_le32_to_cpu(pget_log->bcn_miss_cnt); pget_info->param.stats.amsdu_rx_cnt = pmpriv->amsdu_rx_cnt; pget_info->param.stats.msdu_in_rx_amsdu_cnt = pmpriv->msdu_in_rx_amsdu_cnt; pget_info->param.stats.amsdu_tx_cnt = pmpriv->amsdu_tx_cnt; pget_info->param.stats.msdu_in_tx_amsdu_cnt = pmpriv->msdu_in_tx_amsdu_cnt; pget_info->param.stats.rx_stuck_issue_cnt[0] = wlan_le32_to_cpu(pget_log->rx_stuck_issue_cnt[0]); pget_info->param.stats.rx_stuck_issue_cnt[1] = wlan_le32_to_cpu(pget_log->rx_stuck_issue_cnt[1]); pget_info->param.stats.rx_stuck_recovery_cnt = wlan_le32_to_cpu(pget_log->rx_stuck_recovery_cnt); pget_info->param.stats.rx_stuck_tsf[0] = wlan_le64_to_cpu(pget_log->rx_stuck_tsf[0]); pget_info->param.stats.rx_stuck_tsf[1] = wlan_le64_to_cpu(pget_log->rx_stuck_tsf[1]); pget_info->param.stats.tx_watchdog_recovery_cnt = wlan_le32_to_cpu(pget_log->tx_watchdog_recovery_cnt); pget_info->param.stats.tx_watchdog_tsf[0] = wlan_le64_to_cpu(pget_log->tx_watchdog_tsf[0]); pget_info->param.stats.tx_watchdog_tsf[1] = wlan_le64_to_cpu(pget_log->tx_watchdog_tsf[1]); pget_info->param.stats.channel_switch_ann_sent = wlan_le32_to_cpu(pget_log->channel_switch_ann_sent); pget_info->param.stats.channel_switch_state = wlan_le32_to_cpu(pget_log->channel_switch_state); pget_info->param.stats.reg_class = wlan_le32_to_cpu(pget_log->reg_class); pget_info->param.stats.channel_number = wlan_le32_to_cpu(pget_log->channel_number); pget_info->param.stats.channel_switch_mode = wlan_le32_to_cpu(pget_log->channel_switch_mode); pget_info->param.stats.rx_reset_mac_recovery_cnt = wlan_le32_to_cpu(pget_log->rx_reset_mac_recovery_cnt); pget_info->param.stats.rx_Isr2_NotDone_Cnt = wlan_le32_to_cpu(pget_log->rx_Isr2_NotDone_Cnt); pget_info->param.stats.gdma_abort_cnt = wlan_le32_to_cpu(pget_log->gdma_abort_cnt); pget_info->param.stats.g_reset_rx_mac_cnt = wlan_le32_to_cpu(pget_log->g_reset_rx_mac_cnt); // Ownership error counters pget_info->param.stats.dwCtlErrCnt = wlan_le32_to_cpu(pget_log->dwCtlErrCnt); pget_info->param.stats.dwBcnErrCnt = wlan_le32_to_cpu(pget_log->dwBcnErrCnt); pget_info->param.stats.dwMgtErrCnt = wlan_le32_to_cpu(pget_log->dwMgtErrCnt); pget_info->param.stats.dwDatErrCnt = wlan_le32_to_cpu(pget_log->dwDatErrCnt); pget_info->param.stats.bigtk_mmeGoodCnt = wlan_le32_to_cpu(pget_log->bigtk_mmeGoodCnt); pget_info->param.stats.bigtk_replayErrCnt = wlan_le32_to_cpu(pget_log->bigtk_replayErrCnt); pget_info->param.stats.bigtk_micErrCnt = wlan_le32_to_cpu(pget_log->bigtk_micErrCnt); pget_info->param.stats.bigtk_mmeNotFoundCnt = wlan_le32_to_cpu(pget_log->bigtk_mmeNotFoundCnt); if (pmpriv->adapter->getlog_enable) { pget_info->param.stats.tx_frag_cnt = wlan_le32_to_cpu(pget_log->tx_frag_cnt); for (i = 0; i < 8; i++) { pget_info->param.stats.qos_tx_frag_cnt[i] = wlan_le32_to_cpu( pget_log->qos_tx_frag_cnt[i]); pget_info->param.stats.qos_failed_cnt[i] = wlan_le32_to_cpu( pget_log->qos_failed_cnt[i]); pget_info->param.stats.qos_retry_cnt[i] = wlan_le32_to_cpu( pget_log->qos_retry_cnt[i]); pget_info->param.stats.qos_multi_retry_cnt[i] = wlan_le32_to_cpu( pget_log->qos_multi_retry_cnt[i]); pget_info->param.stats.qos_frm_dup_cnt[i] = wlan_le32_to_cpu( pget_log->qos_frm_dup_cnt[i]); pget_info->param.stats.qos_rts_suc_cnt[i] = wlan_le32_to_cpu( pget_log->qos_rts_suc_cnt[i]); pget_info->param.stats.qos_rts_failure_cnt[i] = wlan_le32_to_cpu( pget_log->qos_rts_failure_cnt[i]); pget_info->param.stats.qos_ack_failure_cnt[i] = wlan_le32_to_cpu( pget_log->qos_ack_failure_cnt[i]); pget_info->param.stats.qos_rx_frag_cnt[i] = wlan_le32_to_cpu( pget_log->qos_rx_frag_cnt[i]); pget_info->param.stats.qos_tx_frm_cnt[i] = wlan_le32_to_cpu( pget_log->qos_tx_frm_cnt[i]); pget_info->param.stats.qos_discarded_frm_cnt [i] = wlan_le32_to_cpu( pget_log->qos_discarded_frm_cnt[i]); pget_info->param.stats.qos_mpdus_rx_cnt[i] = wlan_le32_to_cpu( pget_log->qos_mpdus_rx_cnt[i]); pget_info->param.stats.qos_retries_rx_cnt[i] = wlan_le32_to_cpu( pget_log->qos_retries_rx_cnt[i]); } pget_info->param.stats.cmacicv_errors = wlan_le32_to_cpu(pget_log->cmacicv_errors); pget_info->param.stats.cmac_replays = wlan_le32_to_cpu(pget_log->cmac_replays); pget_info->param.stats.mgmt_ccmp_replays = wlan_le32_to_cpu(pget_log->mgmt_ccmp_replays); pget_info->param.stats.tkipicv_errors = wlan_le32_to_cpu(pget_log->tkipicv_errors); pget_info->param.stats.tkip_replays = wlan_le32_to_cpu(pget_log->tkip_replays); pget_info->param.stats.ccmp_decrypt_errors = wlan_le32_to_cpu(pget_log->ccmp_decrypt_errors); pget_info->param.stats.ccmp_replays = wlan_le32_to_cpu(pget_log->ccmp_replays); pget_info->param.stats.tx_amsdu_cnt = wlan_le32_to_cpu(pget_log->tx_amsdu_cnt); pget_info->param.stats.failed_amsdu_cnt = wlan_le32_to_cpu(pget_log->failed_amsdu_cnt); pget_info->param.stats.retry_amsdu_cnt = wlan_le32_to_cpu(pget_log->retry_amsdu_cnt); pget_info->param.stats.multi_retry_amsdu_cnt = wlan_le32_to_cpu( pget_log->multi_retry_amsdu_cnt); pget_info->param.stats.tx_octets_in_amsdu_cnt = wlan_le64_to_cpu( pget_log->tx_octets_in_amsdu_cnt); pget_info->param.stats.amsdu_ack_failure_cnt = wlan_le32_to_cpu( pget_log->amsdu_ack_failure_cnt); pget_info->param.stats.rx_amsdu_cnt = wlan_le32_to_cpu(pget_log->rx_amsdu_cnt); pget_info->param.stats.rx_octets_in_amsdu_cnt = wlan_le64_to_cpu( pget_log->rx_octets_in_amsdu_cnt); pget_info->param.stats.tx_ampdu_cnt = wlan_le32_to_cpu(pget_log->tx_ampdu_cnt); pget_info->param.stats.tx_mpdus_in_ampdu_cnt = wlan_le32_to_cpu( pget_log->tx_mpdus_in_ampdu_cnt); pget_info->param.stats.tx_octets_in_ampdu_cnt = wlan_le64_to_cpu( pget_log->tx_octets_in_ampdu_cnt); pget_info->param.stats.ampdu_rx_cnt = wlan_le32_to_cpu(pget_log->ampdu_rx_cnt); pget_info->param.stats.mpdu_in_rx_ampdu_cnt = wlan_le32_to_cpu( pget_log->mpdu_in_rx_ampdu_cnt); pget_info->param.stats.rx_octets_in_ampdu_cnt = wlan_le64_to_cpu( pget_log->rx_octets_in_ampdu_cnt); pget_info->param.stats.ampdu_delimiter_crc_error_cnt = wlan_le32_to_cpu( pget_log->ampdu_delimiter_crc_error_cnt); /* Indicate ioctl complete */ pioctl_buf->data_read_written = sizeof(mlan_ds_get_info); } else pioctl_buf->data_read_written = sizeof(mlan_ds_get_stats_org) + sizeof(pget_info->sub_command); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief Get power level and rate index * * @param pmpriv A pointer to mlan_private structure * @param pdata_buf Pointer to the data buffer * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ static mlan_status wlan_get_power_level(pmlan_private pmpriv, void *pdata_buf) { t_u16 length = 0; t_s8 max_power = -1, min_power = -1; MrvlTypes_Power_Group_t *ppg_tlv = MNULL; Power_Group_t *pg = MNULL; ENTER(); if (pdata_buf) { ppg_tlv = (MrvlTypes_Power_Group_t *)((t_u8 *)pdata_buf + sizeof(HostCmd_DS_TXPWR_CFG)); pg = (Power_Group_t *)((t_u8 *)ppg_tlv + sizeof(MrvlTypes_Power_Group_t)); length = ppg_tlv->length; if (length > 0) { max_power = pg->power_max; min_power = pg->power_min; length -= sizeof(Power_Group_t); } while (length) { pg++; if (max_power < pg->power_max) max_power = pg->power_max; if (min_power > pg->power_min) min_power = pg->power_min; length -= sizeof(Power_Group_t); } if (ppg_tlv->length > 0) { pmpriv->min_tx_power_level = min_power; pmpriv->max_tx_power_level = max_power; } } else { LEAVE(); return MLAN_STATUS_FAILURE; } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of tx_power_cfg * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_tx_power_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_TXPWR_CFG *ptxp_cfg = &resp->params.txp_cfg; MrvlTypes_Power_Group_t *ppg_tlv = MNULL; Power_Group_t *pg = MNULL; t_u16 action = wlan_le16_to_cpu(ptxp_cfg->action); mlan_ds_power_cfg *power = MNULL; mlan_power_group *pwr_grp = MNULL; t_u8 i = 0; ENTER(); ppg_tlv = (MrvlTypes_Power_Group_t *)(ptxp_cfg->tlv_buf); pg = (Power_Group_t *)((t_u8 *)ppg_tlv + sizeof(MrvlTypes_Power_Group_t)); switch (action) { case HostCmd_ACT_GEN_GET: ppg_tlv->length = wlan_le16_to_cpu(ppg_tlv->length); if (pmpriv->adapter->hw_status == WlanHardwareStatusInitializing) wlan_get_power_level(pmpriv, ptxp_cfg); pmpriv->tx_power_level = (t_s16)pg->power_min; break; case HostCmd_ACT_GEN_SET: if (wlan_le32_to_cpu(ptxp_cfg->mode)) { if (pg->power_max == pg->power_min) pmpriv->tx_power_level = (t_s16)pg->power_min; } break; default: PRINTM(MERROR, "CMD_RESP: unknown command action %d\n", action); LEAVE(); return MLAN_STATUS_SUCCESS; } PRINTM(MINFO, "Current TxPower Level = %d,Max Power=%d, Min Power=%d\n", pmpriv->tx_power_level, pmpriv->max_tx_power_level, pmpriv->min_tx_power_level); if (pioctl_buf) { power = (mlan_ds_power_cfg *)pioctl_buf->pbuf; if (action == HostCmd_ACT_GEN_GET) { if (power->sub_command == MLAN_OID_POWER_CFG) { pioctl_buf->data_read_written = sizeof(mlan_power_cfg_t) + MLAN_SUB_COMMAND_SIZE; power->param.power_cfg.power_level = pmpriv->tx_power_level; if (wlan_le32_to_cpu(ptxp_cfg->mode)) power->param.power_cfg.is_power_auto = 0; else power->param.power_cfg.is_power_auto = 1; } else { power->param.power_ext.num_pwr_grp = 0; i = 0; while ((ppg_tlv->length) && (i < MAX_POWER_GROUP)) { pwr_grp = (mlan_power_group *)&power ->param.power_ext .power_group[i]; pwr_grp->first_rate_ind = 0; pwr_grp->last_rate_ind = 0; if (pg->modulation_class == MOD_CLASS_HR_DSSS) { pwr_grp->rate_format = MLAN_RATE_FORMAT_LG; pwr_grp->first_rate_ind = pg->first_rate_code; pwr_grp->last_rate_ind = pg->last_rate_code; } else if (pg->modulation_class == MOD_CLASS_OFDM) { pwr_grp->rate_format = MLAN_RATE_FORMAT_LG; pwr_grp->first_rate_ind = MLAN_RATE_INDEX_OFDM0 + pg->first_rate_code; pwr_grp->last_rate_ind = MLAN_RATE_INDEX_OFDM0 + pg->last_rate_code; } else if (pg->modulation_class == MOD_CLASS_HT) { pwr_grp->rate_format = MLAN_RATE_FORMAT_HT; pwr_grp->first_rate_ind = pg->first_rate_code; pwr_grp->last_rate_ind = pg->last_rate_code; } else if (pg->modulation_class == MOD_CLASS_VHT) { pwr_grp->rate_format = MLAN_RATE_FORMAT_VHT; pwr_grp->first_rate_ind = (pg->first_rate_code) & 0xF; pwr_grp->last_rate_ind = (pg->last_rate_code) & 0xF; // pwr_grp->nss = 1 + // (pg->first_rate_code >> 4); pwr_grp->nss = 1 + (pg->last_rate_code >> 4); } pwr_grp->bandwidth = pg->ht_bandwidth; pwr_grp->power_min = pg->power_min; pwr_grp->power_max = pg->power_max; pwr_grp->power_step = pg->power_step; ppg_tlv->length -= sizeof(Power_Group_t); pg++; i++; } power->param.power_ext.num_pwr_grp = i; pioctl_buf->data_read_written = sizeof(mlan_power_cfg_ext) + MLAN_SUB_COMMAND_SIZE; } } } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of rf_tx_power * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_rf_tx_power(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_RF_TX_POWER *rtp = &resp->params.txp; t_u16 action = wlan_le16_to_cpu(rtp->action); mlan_ds_power_cfg *power = MNULL; ENTER(); pmpriv->tx_power_level = wlan_le16_to_cpu(rtp->current_level); if (action == HostCmd_ACT_GEN_GET) { pmpriv->max_tx_power_level = rtp->max_power; pmpriv->min_tx_power_level = rtp->min_power; if (pioctl_buf) { power = (mlan_ds_power_cfg *)pioctl_buf->pbuf; if (power->sub_command == MLAN_OID_POWER_CFG) { pioctl_buf->data_read_written = sizeof(mlan_power_cfg_t) + MLAN_SUB_COMMAND_SIZE; power->param.power_cfg.power_level = pmpriv->tx_power_level; } } } PRINTM(MINFO, "Current TxPower Level = %d,Max Power=%d, Min Power=%d\n", pmpriv->tx_power_level, pmpriv->max_tx_power_level, pmpriv->min_tx_power_level); LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of sleep_period * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_sleep_period(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_SLEEP_PERIOD *pcmd_sleep_pd = &resp->params.sleep_pd; mlan_ds_pm_cfg *pm_cfg = MNULL; t_u16 sleep_pd = 0; ENTER(); sleep_pd = wlan_le16_to_cpu(pcmd_sleep_pd->sleep_pd); if (pioctl_buf) { pm_cfg = (mlan_ds_pm_cfg *)pioctl_buf->pbuf; pm_cfg->param.sleep_period = (t_u32)sleep_pd; pioctl_buf->data_read_written = sizeof(pm_cfg->param.sleep_period) + MLAN_SUB_COMMAND_SIZE; } pmpriv->adapter->sleep_period.period = sleep_pd; pmpriv->adapter->saved_sleep_period.period = sleep_pd; pmpriv->adapter->pps_uapsd_mode = MFALSE; if ((pmpriv->adapter->sleep_period.period != 0) && (pmpriv->adapter->sleep_period.period != SLEEP_PERIOD_RESERVED_FF)) { pmpriv->adapter->gen_null_pkt = MTRUE; } else { pmpriv->adapter->delay_null_pkt = MFALSE; pmpriv->adapter->gen_null_pkt = MFALSE; } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of sleep_params * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_sleep_params(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_SLEEP_PARAMS *presp_sp = &resp->params.sleep_param; mlan_ds_pm_cfg *pm_cfg = MNULL; mlan_ds_sleep_params *psp = MNULL; sleep_params_t *psleep_params = &pmpriv->adapter->sleep_params; ENTER(); psleep_params->sp_reserved = wlan_le16_to_cpu(presp_sp->reserved); psleep_params->sp_error = wlan_le16_to_cpu(presp_sp->error); psleep_params->sp_offset = wlan_le16_to_cpu(presp_sp->offset); psleep_params->sp_stable_time = wlan_le16_to_cpu(presp_sp->stable_time); psleep_params->sp_cal_control = presp_sp->cal_control; psleep_params->sp_ext_sleep_clk = presp_sp->external_sleep_clk; if (pioctl_buf) { pm_cfg = (mlan_ds_pm_cfg *)pioctl_buf->pbuf; psp = (mlan_ds_sleep_params *)&pm_cfg->param.sleep_params; psp->error = (t_u32)psleep_params->sp_error; psp->offset = (t_u32)psleep_params->sp_offset; psp->stable_time = (t_u32)psleep_params->sp_stable_time; psp->cal_control = (t_u32)psleep_params->sp_cal_control; psp->ext_sleep_clk = (t_u32)psleep_params->sp_ext_sleep_clk; psp->reserved = (t_u32)psleep_params->sp_reserved; pioctl_buf->data_read_written = sizeof(pm_cfg->param.sleep_params) + MLAN_SUB_COMMAND_SIZE; } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of multicast_address * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_mac_multicast_adr(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { ENTER(); if (pioctl_buf) { pioctl_buf->data_read_written = sizeof(mlan_multicast_list) + MLAN_SUB_COMMAND_SIZE; } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of deauthenticate * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_deauthenticate(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_adapter *pmadapter = pmpriv->adapter; t_u8 event_buf[32]; mlan_event *pevent = (mlan_event *)event_buf; ENTER(); pmadapter->dbg.num_cmd_deauth++; if (!memcmp(pmadapter, resp->params.deauth.mac_addr, &pmpriv->curr_bss_params.bss_descriptor.mac_address, sizeof(resp->params.deauth.mac_addr))) { wlan_reset_connect_state(pmpriv, MTRUE); } if (pmpriv->adapter->state_rdh.stage == RDH_STOP_INTFS) wlan_11h_radar_detected_callback((t_void *)pmpriv); memset(pmadapter, event_buf, 0, sizeof(event_buf)); pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_DRV_DISCONNECT_LOGGER; pevent->event_len = sizeof(resp->params.deauth.reason_code); memcpy_ext(pmpriv->adapter, (t_u8 *)pevent->event_buf, &resp->params.deauth.reason_code, pevent->event_len, pevent->event_len); wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DISCONNECT_LOGGER, pevent); LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of ad_hoc_stop * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_ad_hoc_stop(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { ENTER(); wlan_reset_connect_state(pmpriv, MTRUE); if (pmpriv->adapter->state_rdh.stage == RDH_STOP_INTFS) wlan_11h_radar_detected_callback((t_void *)pmpriv); LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of key_material * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_KEY_MATERIAL *pkey = &resp->params.key_material; mlan_ds_sec_cfg *sec = MNULL; t_u8 zero_kek[MLAN_KEK_LEN] = {0}; ENTER(); if (wlan_le16_to_cpu(pkey->action) == HostCmd_ACT_GEN_SET) { if ((wlan_le16_to_cpu(pkey->key_param_set.key_info) & KEY_INFO_TKIP_MCAST)) { PRINTM(MINFO, "key: GTK is set\n"); pmpriv->wpa_is_gtk_set = MTRUE; if (pmpriv->port_ctrl_mode == MTRUE) { /* GTK is set, open the port */ PRINTM(MINFO, "GTK_SET: Open port: WPA/WPA2 h-supp mode\n"); pmpriv->port_open = MTRUE; } if (memcmp(pmpriv->adapter, pmpriv->gtk_rekey.kek, zero_kek, sizeof(zero_kek)) != 0) { wlan_prepare_cmd( pmpriv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG, HostCmd_ACT_GEN_SET, 0, MNULL, &pmpriv->gtk_rekey); memset(pmpriv->adapter, &pmpriv->gtk_rekey, 0, sizeof(mlan_ds_misc_gtk_rekey_data)); } pmpriv->adapter->scan_block = MFALSE; } } else if (wlan_le16_to_cpu(pkey->action) == HostCmd_ACT_GEN_GET) { if (pioctl_buf && (wlan_le16_to_cpu(pkey->key_param_set.type) == TLV_TYPE_KEY_PARAM_V2)) { sec = (mlan_ds_sec_cfg *)pioctl_buf->pbuf; memcpy_ext(pmpriv->adapter, sec->param.encrypt_key.mac_addr, pkey->key_param_set.mac_addr, MLAN_MAC_ADDR_LENGTH, sizeof(sec->param.encrypt_key.mac_addr)); sec->param.encrypt_key.key_index = pkey->key_param_set.key_idx; PRINTM(MIOCTL, "key_type=%d, key_index=%d, key_info=0x%x " MACSTR "\n", pkey->key_param_set.key_type, pkey->key_param_set.key_idx, wlan_le16_to_cpu(pkey->key_param_set.key_info), MAC2STR(sec->param.encrypt_key.mac_addr)); switch (pkey->key_param_set.key_type) { case KEY_TYPE_ID_WAPI: sec->param.encrypt_key.is_wapi_key = MTRUE; sec->param.encrypt_key.key_len = wlan_le16_to_cpu( pkey->key_param_set.key_params .wapi.key_len); memcpy_ext( pmpriv->adapter, sec->param.encrypt_key.key_material, pkey->key_param_set.key_params.wapi.key, sec->param.encrypt_key.key_len, sizeof(sec->param.encrypt_key .key_material)); memcpy_ext( pmpriv->adapter, sec->param.encrypt_key.pn, pkey->key_param_set.key_params.wapi.pn, PN_SIZE, sizeof(sec->param.encrypt_key.pn)); break; case KEY_TYPE_ID_TKIP: sec->param.encrypt_key.key_len = wlan_le16_to_cpu( pkey->key_param_set.key_params .tkip.key_len); memcpy_ext( pmpriv->adapter, sec->param.encrypt_key.key_material, pkey->key_param_set.key_params.tkip.key, sec->param.encrypt_key.key_len, sizeof(sec->param.encrypt_key .key_material)); memcpy_ext( pmpriv->adapter, sec->param.encrypt_key.pn, pkey->key_param_set.key_params.tkip.pn, WPA_PN_SIZE, sizeof(sec->param.encrypt_key.pn)); break; case KEY_TYPE_ID_AES: sec->param.encrypt_key.key_len = wlan_le16_to_cpu( pkey->key_param_set.key_params .aes.key_len); memcpy_ext( pmpriv->adapter, sec->param.encrypt_key.key_material, pkey->key_param_set.key_params.aes.key, sec->param.encrypt_key.key_len, sizeof(sec->param.encrypt_key .key_material)); memcpy_ext( pmpriv->adapter, sec->param.encrypt_key.pn, pkey->key_param_set.key_params.aes.pn, WPA_PN_SIZE, sizeof(sec->param.encrypt_key.pn)); break; case KEY_TYPE_ID_AES_CMAC: sec->param.encrypt_key.key_len = wlan_le16_to_cpu( pkey->key_param_set.key_params .cmac_aes.key_len); memcpy_ext(pmpriv->adapter, sec->param.encrypt_key.key_material, pkey->key_param_set.key_params .cmac_aes.key, sec->param.encrypt_key.key_len, sizeof(sec->param.encrypt_key .key_material)); memcpy_ext(pmpriv->adapter, sec->param.encrypt_key.pn, pkey->key_param_set.key_params .cmac_aes.ipn, IGTK_PN_SIZE, sizeof(sec->param.encrypt_key.pn)); break; case KEY_TYPE_ID_WEP: sec->param.encrypt_key.key_len = wlan_le16_to_cpu( pkey->key_param_set.key_params .wep.key_len); memcpy_ext( pmpriv->adapter, sec->param.encrypt_key.key_material, pkey->key_param_set.key_params.wep.key, sec->param.encrypt_key.key_len, sizeof(sec->param.encrypt_key .key_material)); break; } } } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief Handle the supplicant profile response * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_supplicant_profile(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_SUPPLICANT_PROFILE *psup_profile = &resp->params.esupplicant_profile; MrvlIEtypesHeader_t *head; MrvlIEtypes_EncrProto_t *encr_proto_tlv = MNULL; MrvlIEtypes_Cipher_t *pcipher_tlv = MNULL; mlan_ds_sec_cfg *sec = MNULL; t_u8 *tlv; int len; ENTER(); len = resp->size - S_DS_GEN - sizeof(t_u16); tlv = psup_profile->tlv_buf; if (pioctl_buf) { sec = (mlan_ds_sec_cfg *)pioctl_buf->pbuf; while (len > 0) { head = (MrvlIEtypesHeader_t *)tlv; head->type = wlan_le16_to_cpu(head->type); head->len = wlan_le16_to_cpu(head->len); switch (head->type) { case TLV_TYPE_ENCRYPTION_PROTO: encr_proto_tlv = (MrvlIEtypes_EncrProto_t *)head; sec->param.esupp_mode.rsn_mode = wlan_le16_to_cpu( encr_proto_tlv->rsn_mode); PRINTM(MINFO, "rsn_mode=0x%x\n", sec->param.esupp_mode.rsn_mode); break; case TLV_TYPE_CIPHER: pcipher_tlv = (MrvlIEtypes_Cipher_t *)head; sec->param.esupp_mode.act_paircipher = pcipher_tlv->pair_cipher; sec->param.esupp_mode.act_groupcipher = pcipher_tlv->group_cipher; PRINTM(MINFO, "paircipher=0x%x, groupcipher=0x%x\n", sec->param.esupp_mode.act_paircipher, sec->param.esupp_mode.act_groupcipher); break; } len -= (head->len - sizeof(MrvlIEtypesHeader_t)); tlv = tlv + (head->len + sizeof(MrvlIEtypesHeader_t)); } } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of rf_channel * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_802_11_rf_channel(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_802_11_RF_CHANNEL *prf_channel = &resp->params.rf_channel; t_u16 new_channel = wlan_le16_to_cpu(prf_channel->current_channel); mlan_ds_bss *bss = MNULL; ENTER(); if (pmpriv->curr_bss_params.bss_descriptor.channel != new_channel) { PRINTM(MINFO, "Channel Switch: %d to %d\n", pmpriv->curr_bss_params.bss_descriptor.channel, new_channel); /* Update the channel again */ pmpriv->curr_bss_params.bss_descriptor.channel = new_channel; } if (pioctl_buf) { bss = (mlan_ds_bss *)pioctl_buf->pbuf; bss->param.bss_chan.channel = new_channel; } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief Handle the ibss_coalescing_status resp * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_ibss_coalescing_status(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp) { HostCmd_DS_802_11_IBSS_STATUS *pibss_coal_resp = &(resp->params.ibss_coalescing); t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0, 0, 0, 0, 0, 0}; ENTER(); if (wlan_le16_to_cpu(pibss_coal_resp->action) == HostCmd_ACT_GEN_SET) { LEAVE(); return MLAN_STATUS_SUCCESS; } PRINTM(MINFO, "New BSSID " MACSTR "\n", MAC2STR(pibss_coal_resp->bssid)); /* If rsp has MNULL BSSID, Just return..... No Action */ if (!memcmp(pmpriv->adapter, pibss_coal_resp->bssid, zero_mac, MLAN_MAC_ADDR_LENGTH)) { PRINTM(MMSG, "New BSSID is MNULL\n"); LEAVE(); return MLAN_STATUS_SUCCESS; } /* If BSSID is diff, modify current BSS parameters */ if (memcmp(pmpriv->adapter, pmpriv->curr_bss_params.bss_descriptor.mac_address, pibss_coal_resp->bssid, MLAN_MAC_ADDR_LENGTH)) { /* BSSID */ memcpy_ext(pmpriv->adapter, pmpriv->curr_bss_params.bss_descriptor.mac_address, pibss_coal_resp->bssid, MLAN_MAC_ADDR_LENGTH, sizeof(pmpriv->curr_bss_params.bss_descriptor .mac_address)); /* Beacon Interval and ATIM window */ pmpriv->curr_bss_params.bss_descriptor.beacon_period = wlan_le16_to_cpu(pibss_coal_resp->beacon_interval); pmpriv->curr_bss_params.bss_descriptor.atim_window = wlan_le16_to_cpu(pibss_coal_resp->atim_window); /* ERP Information */ pmpriv->curr_bss_params.bss_descriptor.erp_flags = (t_u8)wlan_le16_to_cpu( pibss_coal_resp->use_g_rate_protect); pmpriv->adhoc_state = ADHOC_COALESCED; } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of MGMT_IE_LIST * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_mgmt_ie_list(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { t_u16 resp_len = 0, travel_len = 0; int i = 0; mlan_ds_misc_cfg *misc = MNULL; mlan_ds_misc_custom_ie *cust_ie = MNULL; custom_ie *cptr; tlvbuf_max_mgmt_ie *max_mgmt_ie = MNULL; HostCmd_DS_MGMT_IE_LIST_CFG *pmgmt_ie_list = &(resp->params.mgmt_ie_list); ENTER(); if (wlan_le16_to_cpu(pmgmt_ie_list->action) == HostCmd_ACT_GEN_SET) { if ((pmpriv->adapter->state_rdh.stage == RDH_SET_CUSTOM_IE) || (pmpriv->adapter->state_rdh.stage == RDH_REM_CUSTOM_IE)) if (!pmpriv->adapter->ecsa_enable) wlan_11h_radar_detected_callback( (t_void *)pmpriv); LEAVE(); return MLAN_STATUS_SUCCESS; } misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; cust_ie = (mlan_ds_misc_custom_ie *)&pmgmt_ie_list->ds_mgmt_ie; if (cust_ie) { cust_ie->type = wlan_le16_to_cpu(cust_ie->type); resp_len = cust_ie->len = wlan_le16_to_cpu(cust_ie->len); travel_len = 0; /* conversion for index, mask, len */ if (resp_len == sizeof(t_u16)) cust_ie->ie_data_list[0].ie_index = wlan_cpu_to_le16( cust_ie->ie_data_list[0].ie_index); while (resp_len > sizeof(t_u16)) { cptr = (custom_ie *)(((t_u8 *)cust_ie->ie_data_list) + travel_len); cptr->ie_index = wlan_le16_to_cpu(cptr->ie_index); cptr->mgmt_subtype_mask = wlan_le16_to_cpu(cptr->mgmt_subtype_mask); cptr->ie_length = wlan_le16_to_cpu(cptr->ie_length); travel_len += cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE; resp_len -= cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE; } memcpy_ext(pmpriv->adapter, &misc->param.cust_ie, cust_ie, (cust_ie->len + sizeof(MrvlIEtypesHeader_t)), sizeof(misc->param.cust_ie)); max_mgmt_ie = (tlvbuf_max_mgmt_ie *)((t_u8 *)cust_ie + cust_ie->len + sizeof(MrvlIEtypesHeader_t)); if (max_mgmt_ie) { max_mgmt_ie->type = wlan_le16_to_cpu(max_mgmt_ie->type); if (max_mgmt_ie->type == TLV_TYPE_MAX_MGMT_IE) { max_mgmt_ie->len = wlan_le16_to_cpu(max_mgmt_ie->len); max_mgmt_ie->count = wlan_le16_to_cpu(max_mgmt_ie->count); for (i = 0; i < max_mgmt_ie->count; i++) { max_mgmt_ie->info[i] .buf_size = wlan_le16_to_cpu( max_mgmt_ie->info[i].buf_size); max_mgmt_ie->info[i] .buf_count = wlan_le16_to_cpu( max_mgmt_ie->info[i].buf_count); } /* Append max_mgmt_ie TLV after custom_ie */ memcpy_ext( pmpriv->adapter, (t_u8 *)&misc->param.cust_ie + (cust_ie->len + sizeof(MrvlIEtypesHeader_t)), max_mgmt_ie, max_mgmt_ie->len + sizeof(MrvlIEtypesHeader_t), sizeof(misc->param.cust_ie) - (cust_ie->len + sizeof(MrvlIEtypesHeader_t))); } } } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function enable/disable tdls powermode * * @param pmpriv A pointer to mlan_private structure * @param powermode 1--enable, 0--disable * * @return N/A */ static void wlan_set_tdls_powermode(pmlan_private pmpriv, t_u8 powermode) { ENTER(); if (powermode) { pmpriv->wmm_qosinfo = DEFAULT_TDLS_WMM_QOS_INFO; if (!pmpriv->adapter->sleep_period.period) pmpriv->adapter->sleep_period.period = DEFAULT_TDLS_SLEEP_PERIOD; } else { pmpriv->wmm_qosinfo = pmpriv->saved_wmm_qosinfo; pmpriv->adapter->sleep_period.period = pmpriv->adapter->saved_sleep_period.period; } pmpriv->adapter->pps_uapsd_mode = MFALSE; if ((pmpriv->adapter->sleep_period.period != 0) && (pmpriv->adapter->sleep_period.period != SLEEP_PERIOD_RESERVED_FF)) { pmpriv->adapter->gen_null_pkt = MTRUE; } else { pmpriv->adapter->delay_null_pkt = MFALSE; pmpriv->adapter->gen_null_pkt = MFALSE; } LEAVE(); return; } /** * @brief This function handles the command response of TDLS_CONFIG * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ static mlan_status wlan_ret_tdls_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { t_u8 i = 0; t_u16 link_length = 0, final_data_rate = 0; mlan_ds_misc_cfg *misc = MNULL; tdls_all_config *tdls_all_cfg = MNULL; sta_node *sta_ptr = MNULL; HostCmd_DS_TDLS_CONFIG *ptdls_config_data = &(resp->params.tdls_config_data); pmlan_adapter pmadapter = pmpriv->adapter; tdls_each_link_status *link_ptr = MNULL; ENTER(); ptdls_config_data->tdls_info.tdls_action = wlan_le16_to_cpu(ptdls_config_data->tdls_info.tdls_action); switch (ptdls_config_data->tdls_info.tdls_action) { case WLAN_TDLS_CONFIG: misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; if (pmpriv->host_tdls_cs_support || pmpriv->host_tdls_uapsd_support) break; if (wlan_le16_to_cpu(tdls_all_cfg->u.tdls_config.enable) == 0) { PRINTM(MINFO, "TDLS disable successful.\n"); wlan_delete_station_list(pmpriv); pmadapter->tdls_status = TDLS_NOT_SETUP; if (pmpriv->saved_wmm_qosinfo) pmpriv->wmm_qosinfo = pmpriv->saved_wmm_qosinfo; if (pmadapter->saved_sleep_period.period) pmadapter->sleep_period.period = pmadapter->saved_sleep_period.period; } break; case WLAN_TDLS_SET_INFO: break; case WLAN_TDLS_DISCOVERY_REQ: misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; tdls_all_cfg->u.tdls_discovery_resp.payload_len = wlan_le16_to_cpu( tdls_all_cfg->u.tdls_discovery_resp.payload_len); tdls_all_cfg->u.tdls_discovery_resp.cap_info = wlan_le16_to_cpu( tdls_all_cfg->u.tdls_discovery_resp.cap_info); memcpy_ext(pmpriv->adapter, &misc->param.tdls_config, &ptdls_config_data->tdls_info, (resp->size - S_DS_GEN), sizeof(mlan_ds_misc_tdls_config)); PRINTM(MCMND, "TDLS_DISCOVERY_REQ: " MACSTR "\n", MAC2STR(tdls_all_cfg->u.tdls_discovery_resp .peer_mac_addr)); break; case WLAN_TDLS_SETUP_REQ: /* * TDLS link being setup, block all data for this Peer */ tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; PRINTM(MCMND, "TDLS_SETUP_REQ: " MACSTR "\n", MAC2STR(tdls_all_cfg->u.tdls_setup.peer_mac_addr)); sta_ptr = wlan_get_station_entry( pmpriv, tdls_all_cfg->u.tdls_setup.peer_mac_addr); if (!sta_ptr) { sta_ptr = wlan_add_station_entry( pmpriv, tdls_all_cfg->u.tdls_setup.peer_mac_addr); if (sta_ptr) { sta_ptr->status = TDLS_SETUP_INPROGRESS; wlan_hold_tdls_packets( pmpriv, tdls_all_cfg->u.tdls_setup .peer_mac_addr); } } break; case WLAN_TDLS_TEAR_DOWN_REQ: /* * TDLS link torn down, open data ports if blocked */ tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; wlan_restore_tdls_packets( pmpriv, tdls_all_cfg->u.tdls_tear_down.peer_mac_addr, TDLS_TEAR_DOWN); PRINTM(MCMND, "TDLS_TEARDOWN_REQ: " MACSTR "\n", MAC2STR(tdls_all_cfg->u.tdls_tear_down.peer_mac_addr)); sta_ptr = wlan_get_station_entry( pmpriv, tdls_all_cfg->u.tdls_tear_down.peer_mac_addr); if (sta_ptr) { if (sta_ptr->is_11n_enabled) { wlan_cleanup_reorder_tbl( pmpriv, tdls_all_cfg->u.tdls_tear_down .peer_mac_addr); wlan_11n_cleanup_txbastream_tbl( pmpriv, tdls_all_cfg->u.tdls_tear_down .peer_mac_addr); } wlan_delete_station_entry( pmpriv, tdls_all_cfg->u.tdls_tear_down.peer_mac_addr); if (MTRUE == wlan_is_station_list_empty(pmpriv)) pmadapter->tdls_status = TDLS_NOT_SETUP; else pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL; } break; case WLAN_TDLS_INIT_CHAN_SWITCH: tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; PRINTM(MCMND, "TDLS_INIT_CHANNEL_SWITCH: " MACSTR " chan=%d periodicity=%d\n", MAC2STR(tdls_all_cfg->u.tdls_chan_switch.peer_mac_addr), (int)tdls_all_cfg->u.tdls_chan_switch.primary_channel, (int)tdls_all_cfg->u.tdls_chan_switch.periodicity); break; case WLAN_TDLS_LINK_STATUS: misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; tdls_all_cfg->u.tdls_link_status_resp.payload_len = wlan_le16_to_cpu(tdls_all_cfg->u.tdls_link_status_resp .payload_len); link_ptr = tdls_all_cfg->u.tdls_link_status_resp.link_stats; for (i = 0; i < tdls_all_cfg->u.tdls_link_status_resp.active_links; i++) { link_ptr->active_channel = wlan_le32_to_cpu(link_ptr->active_channel); link_ptr->data_rssi_last = wlan_le16_to_cpu(link_ptr->data_rssi_last); link_ptr->data_nf_last = wlan_le16_to_cpu(link_ptr->data_nf_last); link_ptr->data_rssi_avg = wlan_le16_to_cpu(link_ptr->data_rssi_avg); link_ptr->data_nf_avg = wlan_le16_to_cpu(link_ptr->data_nf_avg); link_length = sizeof(tdls_each_link_status) - 1; /* adjust as per open or secure network */ if (link_ptr->link_flags & 0x02) { link_ptr->key_lifetime = wlan_le32_to_cpu( link_ptr->key_lifetime); link_length += link_ptr->key_length; } else { link_length -= sizeof(link_ptr->security_method) + sizeof(link_ptr->key_lifetime) + sizeof(link_ptr->key_length); } final_data_rate = (t_u16)wlan_index_to_data_rate( pmadapter, link_ptr->u.rate_info.tx_data_rate, link_ptr->u.rate_info.tx_rate_htinfo, 0); link_ptr->u.final_data_rate = final_data_rate / 2; link_ptr = (tdls_each_link_status *)(((t_u8 *)link_ptr) + link_length); } memcpy_ext(pmpriv->adapter, &misc->param.tdls_config, &ptdls_config_data->tdls_info, (resp->size - S_DS_GEN), sizeof(mlan_ds_misc_tdls_config)); break; case WLAN_TDLS_POWER_MODE: misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; tdls_all_cfg->u.tdls_power_mode.power_mode = wlan_le16_to_cpu( tdls_all_cfg->u.tdls_power_mode.power_mode); wlan_set_tdls_powermode( pmpriv, (t_u8)tdls_all_cfg->u.tdls_power_mode.power_mode); break; case WLAN_TDLS_STOP_CHAN_SWITCH: tdls_all_cfg = (tdls_all_config *) ptdls_config_data->tdls_info.tdls_data; PRINTM(MCMND, "TDLS_STOP_CHANNEL_SWITCH: " MACSTR "\n", MAC2STR(tdls_all_cfg->u.tdls_stop_chan_switch .peer_mac_addr)); break; case WLAN_TDLS_CS_PARAMS: case WLAN_TDLS_CS_DISABLE: case WLAN_TDLS_DEBUG_STOP_RX: case WLAN_TDLS_DEBUG_ALLOW_WEAK_SECURITY: case WLAN_TDLS_DEBUG_SETUP_SAME_LINK: case WLAN_TDLS_DEBUG_FAIL_SETUP_CONFIRM: case WLAN_TDLS_DEBUG_WRONG_BSS: case WLAN_TDLS_DEBUG_SETUP_PROHIBITED: case WLAN_TDLS_DEBUG_HIGHER_LOWER_MAC: case WLAN_TDLS_DEBUG_IGNORE_KEY_EXPIRY: case WLAN_TDLS_DEBUG_CS_RET_IM: break; default: if (pioctl_buf) pioctl_buf->status_code = MLAN_ERROR_CMD_RESP_FAIL; LEAVE(); return MLAN_STATUS_FAILURE; } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of TDLS_OPERATION * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ static mlan_status wlan_ret_tdls_oper(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_TDLS_OPER *ptdls_oper = &(resp->params.tdls_oper_data); sta_node *sta_ptr = MNULL; t_u16 reason = 0; pmlan_adapter pmadapter = pmpriv->adapter; ENTER(); ptdls_oper->tdls_action = wlan_le16_to_cpu(ptdls_oper->tdls_action); sta_ptr = wlan_get_station_entry(pmpriv, ptdls_oper->peer_mac); reason = wlan_le16_to_cpu(ptdls_oper->reason); switch (ptdls_oper->tdls_action) { case TDLS_CREATE: if (reason) { PRINTM(MMSG, "TDLS: create link " MACSTR " fail, reason=%d\n", MAC2STR(ptdls_oper->peer_mac), reason); if (reason != TDLS_LINK_EXISTS && sta_ptr) sta_ptr->status = TDLS_SETUP_FAILURE; } else { PRINTM(MMSG, "TDLS: create link " MACSTR " success\n", MAC2STR(ptdls_oper->peer_mac), reason); } break; case TDLS_CONFIG: if (reason) { PRINTM(MMSG, "TDLS: Config link " MACSTR " fail, reason=%d\n", MAC2STR(ptdls_oper->peer_mac), reason); if (sta_ptr) sta_ptr->status = TDLS_SETUP_FAILURE; } else { PRINTM(MMSG, "TDLS: Config link " MACSTR " success\n", MAC2STR(ptdls_oper->peer_mac)); } break; case TDLS_DELETE: wlan_restore_tdls_packets(pmpriv, ptdls_oper->peer_mac, TDLS_TEAR_DOWN); if (sta_ptr) { /**tdls cs stop*/ if (ISSUPP_EXTCAP_TDLS_CHAN_SWITCH( sta_ptr->ExtCap.ext_cap)) wlan_tdls_config(pmpriv, MFALSE); if (sta_ptr->is_11n_enabled) { wlan_cleanup_reorder_tbl(pmpriv, ptdls_oper->peer_mac); wlan_11n_cleanup_txbastream_tbl( pmpriv, ptdls_oper->peer_mac); } if (sta_ptr->status >= TDLS_SETUP_INPROGRESS) wlan_delete_station_entry(pmpriv, ptdls_oper->peer_mac); } if (MTRUE == wlan_is_station_list_empty(pmpriv)) pmadapter->tdls_status = TDLS_NOT_SETUP; else pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL; if (reason) PRINTM(MMSG, "TDLS: Delete link " MACSTR " fail, reason=%d\n", MAC2STR(ptdls_oper->peer_mac), reason); else PRINTM(MMSG, "TDLS: Delete link " MACSTR " success\n", MAC2STR(ptdls_oper->peer_mac)); break; default: break; } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of sysclock * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_sysclock_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_ds_misc_cfg *mis_ccfg = MNULL; HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG *clk_cfg = &resp->params.sys_clock_cfg; int i = 0; ENTER(); if (pioctl_buf) { mis_ccfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; mis_ccfg->param.sys_clock.cur_sys_clk = wlan_le16_to_cpu(clk_cfg->cur_sys_clk); mis_ccfg->param.sys_clock.sys_clk_type = wlan_le16_to_cpu(clk_cfg->sys_clk_type); mis_ccfg->param.sys_clock.sys_clk_num = wlan_le16_to_cpu(clk_cfg->sys_clk_len) / sizeof(t_u16); for (i = 0; i < mis_ccfg->param.sys_clock.sys_clk_num; i++) mis_ccfg->param.sys_clock.sys_clk[i] = wlan_le16_to_cpu(clk_cfg->sys_clk[i]); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of inactivity timeout * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to command buffer * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_inactivity_timeout(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_ds_pm_cfg *pmcfg = MNULL; mlan_ds_inactivity_to *inac_to = MNULL; HostCmd_DS_INACTIVITY_TIMEOUT_EXT *cmd_inac_to = (HostCmd_DS_INACTIVITY_TIMEOUT_EXT *)&resp->params.inactivity_to; ENTER(); if (pioctl_buf) { pmcfg = (mlan_ds_pm_cfg *)pioctl_buf->pbuf; inac_to = &pmcfg->param.inactivity_to; inac_to->timeout_unit = wlan_le16_to_cpu(cmd_inac_to->timeout_unit); inac_to->unicast_timeout = wlan_le16_to_cpu(cmd_inac_to->unicast_timeout); inac_to->mcast_timeout = wlan_le16_to_cpu(cmd_inac_to->mcast_timeout); inac_to->ps_entry_timeout = wlan_le16_to_cpu(cmd_inac_to->ps_entry_timeout); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of * network monitor * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to command buffer * * @return MLAN_STATUS_SUCCESS */ mlan_status wlan_ret_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_ds_misc_cfg *pmisc = MNULL; mlan_ds_misc_net_monitor *net_mon = MNULL; HostCmd_DS_802_11_NET_MONITOR *cmd_net_mon = (HostCmd_DS_802_11_NET_MONITOR *)&resp->params.net_mon; ChanBandParamSet_t *pchan_band = MNULL; t_u16 band_info = 0; ENTER(); if (pioctl_buf && (pioctl_buf->action == MLAN_ACT_GET)) { pmisc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; net_mon = &pmisc->param.net_mon; net_mon->enable_net_mon = wlan_le16_to_cpu(cmd_net_mon->enable_net_mon); net_mon->filter_flag = wlan_le16_to_cpu(cmd_net_mon->filter_flag); pchan_band = &cmd_net_mon->monitor_chan.chan_band_param[0]; /* Band information in the TLV is bits[1:0] */ band_info = pchan_band->bandcfg.chanBand; net_mon->channel = pchan_band->chan_number; if (band_info == BAND_2GHZ) net_mon->band |= (BAND_B | BAND_G); if (band_info == BAND_5GHZ) net_mon->band |= BAND_A; net_mon->chan_bandwidth = GET_SECONDARYCHAN(pchan_band->bandcfg.chan2Offset); if (band_info == BAND_2GHZ) net_mon->band |= BAND_GN; if (band_info == BAND_5GHZ) net_mon->band |= BAND_AN; if (band_info == BAND_2GHZ) net_mon->band |= BAND_GAC; if (band_info == BAND_5GHZ) net_mon->band |= BAND_AAC; } pmpriv->adapter->enable_net_mon = wlan_le16_to_cpu(cmd_net_mon->enable_net_mon); LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of * subscribe event * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to command buffer * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_subscribe_event(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_SUBSCRIBE_EVENT *evt = (HostCmd_DS_SUBSCRIBE_EVENT *)&resp->params.subscribe_event; mlan_ds_subscribe_evt *sub_evt = MNULL; mlan_ds_misc_cfg *misc = MNULL; ENTER(); if (pioctl_buf && (pioctl_buf->action == MLAN_ACT_GET)) { misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; sub_evt = &misc->param.subscribe_event; sub_evt->evt_bitmap = wlan_le16_to_cpu(evt->event_bitmap); pioctl_buf->data_read_written = sizeof(mlan_ds_misc_cfg); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of * OTP user data * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to command buffer * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_otp_user_data(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_OTP_USER_DATA *cmd_user_data = (HostCmd_DS_OTP_USER_DATA *)&resp->params.otp_user_data; mlan_ds_misc_otp_user_data *user_data = MNULL; ENTER(); if (pioctl_buf && (pioctl_buf->action == MLAN_ACT_GET)) { user_data = (mlan_ds_misc_otp_user_data *)pioctl_buf->pbuf; user_data->user_data_length = MIN(MAX_OTP_USER_DATA_LEN, wlan_le16_to_cpu(cmd_user_data->user_data_length)); memcpy_ext(pmpriv->adapter, user_data->user_data, cmd_user_data->user_data, user_data->user_data_length, sizeof(user_data->user_data)); pioctl_buf->data_read_written = sizeof(mlan_ds_misc_otp_user_data) + user_data->user_data_length; } LEAVE(); return MLAN_STATUS_SUCCESS; } #ifdef USB /** * @brief This function handles the command response of * packet aggregation * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to command buffer * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_packet_aggr_over_host_interface(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_ds_misc_cfg *misc = MNULL; HostCmd_DS_PACKET_AGGR_OVER_HOST_INTERFACE *packet_aggr = (HostCmd_DS_PACKET_AGGR_OVER_HOST_INTERFACE *)&resp->params .packet_aggr; MrvlIETypes_USBAggrParam_t *usb_aggr_param_tlv = MNULL; mlan_ds_misc_usb_aggr_ctrl *usb_aggr_ctrl = MNULL; t_u8 *ptlv_buffer = (t_u8 *)packet_aggr->tlv_buf; mlan_adapter *pmadapter = pmpriv->adapter; t_u16 tlv = 0; int tlv_buf_len = 0; t_u8 changed = 0; #if defined(USB) t_s32 i = 0; #endif ENTER(); tlv_buf_len = resp->size - (sizeof(HostCmd_DS_PACKET_AGGR_OVER_HOST_INTERFACE) + S_DS_GEN); if (!pioctl_buf) { LEAVE(); return MLAN_STATUS_SUCCESS; } while (tlv_buf_len > 0) { changed = 0; tlv = (*ptlv_buffer) | (*(ptlv_buffer + 1) << 8); switch (tlv) { case MRVL_USB_AGGR_PARAM_TLV_ID: usb_aggr_param_tlv = (MrvlIETypes_USBAggrParam_t *)ptlv_buffer; misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; usb_aggr_ctrl = (mlan_ds_misc_usb_aggr_ctrl *)&( misc->param.usb_aggr_params); usb_aggr_param_tlv->header.len = wlan_le16_to_cpu( usb_aggr_param_tlv->header.len); usb_aggr_param_tlv->enable = wlan_le16_to_cpu(usb_aggr_param_tlv->enable); #if defined(USB) if (pioctl_buf->action == MLAN_ACT_SET) { /* Update the Tx aggregation values in * MLAN */ for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) { pmadapter->pcard_usb->usb_tx_aggr[i] .aggr_ctrl.enable = usb_aggr_ctrl->tx_aggr_ctrl .enable; if (pmadapter->pcard_usb->usb_tx_aggr[i] .aggr_ctrl.aggr_mode != usb_aggr_ctrl->tx_aggr_ctrl .aggr_mode) { pmadapter->pcard_usb ->usb_tx_aggr[i] .aggr_ctrl.aggr_mode = usb_aggr_ctrl ->tx_aggr_ctrl .aggr_mode; changed = 1; } if (pmadapter->pcard_usb->usb_tx_aggr[i] .aggr_ctrl.aggr_align != usb_aggr_ctrl->tx_aggr_ctrl .aggr_align) { pmadapter->pcard_usb ->usb_tx_aggr[i] .aggr_ctrl.aggr_align = usb_aggr_ctrl ->tx_aggr_ctrl .aggr_align; changed = 1; } if (pmadapter->pcard_usb->usb_tx_aggr[i] .aggr_ctrl.aggr_max != usb_aggr_ctrl->tx_aggr_ctrl .aggr_max) { pmadapter->pcard_usb ->usb_tx_aggr[i] .aggr_ctrl.aggr_max = usb_aggr_ctrl ->tx_aggr_ctrl .aggr_max; changed = 1; } pmadapter->pcard_usb->usb_tx_aggr[i] .aggr_ctrl.aggr_tmo = usb_aggr_ctrl->tx_aggr_ctrl .aggr_tmo; } } else { if (usb_aggr_param_tlv->enable & MBIT(1)) usb_aggr_ctrl->tx_aggr_ctrl.enable = MTRUE; else usb_aggr_ctrl->tx_aggr_ctrl.enable = MFALSE; usb_aggr_ctrl->tx_aggr_ctrl .aggr_align = wlan_le16_to_cpu( usb_aggr_param_tlv->tx_aggr_align); usb_aggr_ctrl->tx_aggr_ctrl.aggr_mode = pmadapter->pcard_usb->usb_tx_aggr[0] .aggr_ctrl.aggr_mode; usb_aggr_ctrl->tx_aggr_ctrl.aggr_max = pmadapter->pcard_usb->usb_tx_aggr[0] .aggr_ctrl.aggr_max; usb_aggr_ctrl->tx_aggr_ctrl.aggr_tmo = pmadapter->pcard_usb->usb_tx_aggr[0] .aggr_ctrl.aggr_tmo; } if (changed) wlan_reset_usb_tx_aggr(pmadapter); #endif #if defined(USB) if (pioctl_buf->action == MLAN_ACT_SET) { /* Update the Rx deaggregation values in * MLAN */ pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl .enable = usb_aggr_ctrl->rx_deaggr_ctrl.enable; if (pmadapter->pcard_usb->usb_rx_deaggr .aggr_ctrl.aggr_mode != usb_aggr_ctrl->rx_deaggr_ctrl.aggr_mode) pmadapter->pcard_usb->usb_rx_deaggr .aggr_ctrl.aggr_mode = usb_aggr_ctrl->rx_deaggr_ctrl .aggr_mode; if (pmadapter->pcard_usb->usb_rx_deaggr .aggr_ctrl.aggr_align != usb_aggr_ctrl->rx_deaggr_ctrl.aggr_align) pmadapter->pcard_usb->usb_rx_deaggr .aggr_ctrl.aggr_align = usb_aggr_ctrl->rx_deaggr_ctrl .aggr_align; if (pmadapter->pcard_usb->usb_rx_deaggr .aggr_ctrl.aggr_max != usb_aggr_ctrl->rx_deaggr_ctrl.aggr_max) pmadapter->pcard_usb->usb_rx_deaggr .aggr_ctrl.aggr_max = usb_aggr_ctrl->rx_deaggr_ctrl .aggr_max; pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl .aggr_tmo = usb_aggr_ctrl->rx_deaggr_ctrl.aggr_tmo; } else { if (usb_aggr_param_tlv->enable & MBIT(0)) usb_aggr_ctrl->rx_deaggr_ctrl.enable = MTRUE; else usb_aggr_ctrl->rx_deaggr_ctrl.enable = MFALSE; usb_aggr_ctrl->rx_deaggr_ctrl .aggr_mode = wlan_le16_to_cpu( usb_aggr_param_tlv->rx_aggr_mode); usb_aggr_ctrl->rx_deaggr_ctrl .aggr_align = wlan_le16_to_cpu( usb_aggr_param_tlv->rx_aggr_align); usb_aggr_ctrl->rx_deaggr_ctrl.aggr_max = wlan_le16_to_cpu( usb_aggr_param_tlv->rx_aggr_max); usb_aggr_ctrl->rx_deaggr_ctrl.aggr_tmo = wlan_le16_to_cpu( usb_aggr_param_tlv->rx_aggr_tmo); } #endif ptlv_buffer += usb_aggr_param_tlv->header.len + sizeof(MrvlIEtypesHeader_t); tlv_buf_len -= (usb_aggr_param_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); break; default: break; } } LEAVE(); return MLAN_STATUS_SUCCESS; } #endif /** * @brief This function handles the command response of * DFS Repeater mode configuration * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to command buffer * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_dfs_repeater_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_DFS_REPEATER_MODE *cmd_dfs_repeater = &resp->params.dfs_repeater; mlan_ds_misc_cfg *misc = MNULL; mlan_ds_misc_dfs_repeater *dfs_cfg = MNULL; ENTER(); if (pioctl_buf && (pioctl_buf->action == MLAN_ACT_GET)) { misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; dfs_cfg = (mlan_ds_misc_dfs_repeater *)&misc->param.dfs_repeater; dfs_cfg->mode = wlan_le16_to_cpu(cmd_dfs_repeater->mode); } if (pioctl_buf && (pioctl_buf->action == MLAN_ACT_SET)) { if (wlan_le16_to_cpu(cmd_dfs_repeater->mode) == 1) { /* Set dfs_repeater mode to true/enabled * for futher references. */ pmpriv->adapter->dfs_repeater = MTRUE; } else { pmpriv->adapter->dfs_repeater = MFALSE; } } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of coalesce config * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_coalesce_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { ENTER(); LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of arb Cfg * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ mlan_status wlan_ret_arb_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_CMD_ARB_CONFIG *cfg_cmd = (HostCmd_DS_CMD_ARB_CONFIG *)&resp->params.arb_cfg; mlan_ds_misc_cfg *misc_cfg = MNULL; ENTER(); if (pioctl_buf) { misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; misc_cfg->param.arb_cfg.arb_mode = wlan_le32_to_cpu(cfg_cmd->arb_mode); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of ipv6 ra offload feature * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ mlan_status wlan_ret_ipv6_ra_offload(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_IPV6_RA_OFFLOAD *ipv6_ra_resp = &resp->params.ipv6_ra_offload; mlan_ds_misc_cfg *misc = MNULL; mlan_ds_misc_ipv6_ra_offload *ipv6_ra = MNULL; ENTER(); if (pioctl_buf && (pioctl_buf->action == MLAN_ACT_GET)) { misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; ipv6_ra = (mlan_ds_misc_ipv6_ra_offload *)&misc->param .ipv6_ra_offload; ipv6_ra->enable = ipv6_ra_resp->enable; memcpy_ext(pmpriv->adapter, ipv6_ra->ipv6_addr, ipv6_ra_resp->ipv6_addr_param.ipv6_addr, 16, sizeof(ipv6_ra->ipv6_addr)); } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function handles the command response of sta get band and * channel * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_sta_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_STA_CONFIGURE *cmdrsp_sta_cfg = (HostCmd_DS_STA_CONFIGURE *)&resp->params.sta_cfg; mlan_ds_bss *bss = MNULL; MrvlIEtypes_channel_band_t *tlv_band_channel = MNULL; ENTER(); if (pioctl_buf) { if (pioctl_buf->req_id == MLAN_IOCTL_BSS) { bss = (mlan_ds_bss *)pioctl_buf->pbuf; if (bss->sub_command == MLAN_OID_BSS_CHAN_INFO) { tlv_band_channel = (MrvlIEtypes_channel_band_t *) cmdrsp_sta_cfg->tlv_buffer; bss->param.sta_channel.bandcfg = tlv_band_channel->bandcfg; bss->param.sta_channel.channel = tlv_band_channel->channel; bss->param.sta_channel.is_11n_enabled = IS_11N_ENABLED(pmpriv); if (bss->param.sta_channel.bandcfg.chanWidth == CHAN_BW_80MHZ) bss->param.sta_channel.center_chan = wlan_get_center_freq_idx( pmpriv, BAND_AAC, bss->param.sta_channel .channel, CHANNEL_BW_80MHZ); PRINTM(MCMND, "Get STA channel, band=0x%x, channel=%d, is_11n_enabled=%d center_chan=%d\n", bss->param.sta_channel.bandcfg, bss->param.sta_channel.channel, bss->param.sta_channel.is_11n_enabled, bss->param.sta_channel.center_chan); pioctl_buf->data_read_written = sizeof(mlan_ds_bss); } } } LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function clears PMK in fw for fw roaming * * @param pmpriv A pointer to mlan_private structure * * @return MLAN_STATUS_SUCCESS */ mlan_status wlan_clear_fw_roaming_pmk(pmlan_private pmpriv) { mlan_status ret = MLAN_STATUS_SUCCESS; ENTER(); ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SUPPLICANT_PMK, HostCmd_ACT_GEN_REMOVE, 0, MNULL, MNULL); if (ret == MLAN_STATUS_SUCCESS) { ret = MLAN_STATUS_FAILURE; } LEAVE(); return ret; } /** * @brief This function handles the command response of enable/disable roaming * offload to fw * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_roam_offload(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_ROAM_OFFLOAD *cmdrsp_roam_offload = (HostCmd_DS_ROAM_OFFLOAD *)&resp->params.roam_offload; mlan_status status = MLAN_STATUS_SUCCESS; MrvlIEtypesHeader_t *header = MNULL; MrvlIEtypes_fw_roam_enable_t *roam_offload_enable = MNULL; ENTER(); if (resp->result == HostCmd_RESULT_OK) { header = (MrvlIEtypesHeader_t *)cmdrsp_roam_offload->tlv; header->type = wlan_le16_to_cpu(header->type); if (header->type == TLV_TYPE_ROAM) { roam_offload_enable = (MrvlIEtypes_fw_roam_enable_t *) cmdrsp_roam_offload->tlv; if ((t_u8)roam_offload_enable->roam_enable) pmpriv->adapter->fw_roaming = MTRUE; else { pmpriv->adapter->fw_roaming = MFALSE; wlan_clear_fw_roaming_pmk(pmpriv); } } } LEAVE(); return status; } /** * @brief This function handles the command response of set/get auto tx * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_auto_tx(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { HostCmd_DS_AUTO_TX *cmdrsp_auto_tx = (HostCmd_DS_AUTO_TX *)&resp->params.auto_tx; mlan_status status = MLAN_STATUS_SUCCESS; MrvlIEtypesHeader_t *header = MNULL; mlan_ds_misc_cfg *misc = MNULL; t_u16 action; t_u16 len = 0; MrvlIEtypes_Cloud_Keep_Alive_t *keep_alive_tlv = MNULL; MrvlIEtypes_Keep_Alive_Pkt_t *pkt_tlv = MNULL; mlan_ds_misc_keep_alive *misc_keep_alive = MNULL; ENTER(); action = wlan_le16_to_cpu(cmdrsp_auto_tx->action); if (!pioctl_buf) { PRINTM(MERROR, "ioctl is null\n"); LEAVE(); return MLAN_STATUS_FAILURE; } misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; if (!misc) { PRINTM(MERROR, "misc is null\n"); LEAVE(); return MLAN_STATUS_FAILURE; } if (resp->result == HostCmd_RESULT_OK) { header = (MrvlIEtypesHeader_t *)cmdrsp_auto_tx->tlv_buffer; header->type = wlan_le16_to_cpu(header->type); len = wlan_le16_to_cpu(header->len); if (header->type == TLV_TYPE_CLOUD_KEEP_ALIVE) { keep_alive_tlv = (MrvlIEtypes_Cloud_Keep_Alive_t *) cmdrsp_auto_tx->tlv_buffer; misc_keep_alive = (mlan_ds_misc_keep_alive *)&misc ->param.keep_alive; misc_keep_alive->mkeep_alive_id = keep_alive_tlv->keep_alive_id; misc_keep_alive->enable = keep_alive_tlv->enable; if (((action == HostCmd_ACT_GEN_SET) || (action == HostCmd_ACT_GEN_RESET)) && !keep_alive_tlv->enable) { len = len - sizeof(keep_alive_tlv->keep_alive_id) - sizeof(keep_alive_tlv->enable); if (len > sizeof(MrvlIEtypesHeader_t)) { header = (MrvlIEtypesHeader_t *) keep_alive_tlv->tlv; header->type = wlan_le16_to_cpu(header->type); len = wlan_le16_to_cpu(header->len) - sizeof(Eth803Hdr_t); if (header->type == TLV_TYPE_KEEP_ALIVE_PKT) { pkt_tlv = (MrvlIEtypes_Keep_Alive_Pkt_t *)keep_alive_tlv ->tlv; memcpy_ext( pmpriv->adapter, misc_keep_alive->dst_mac, pkt_tlv->eth_header .dest_addr, MLAN_MAC_ADDR_LENGTH, sizeof(misc_keep_alive ->dst_mac)); memcpy_ext( pmpriv->adapter, misc_keep_alive->src_mac, pkt_tlv->eth_header .src_addr, MLAN_MAC_ADDR_LENGTH, sizeof(misc_keep_alive ->src_mac)); memcpy_ext( pmpriv->adapter, misc_keep_alive->packet, pkt_tlv->ip_packet, len, sizeof(misc_keep_alive ->packet)); misc_keep_alive->pkt_len = len; } } } } } LEAVE(); return status; } /******************************************************** Global Functions ********************************************************/ /** * @brief This function prepares command resp of MFG Continuous Tx * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_mfg_tx_cont(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_ds_misc_cfg *misc = MNULL; struct mfg_cmd_tx_cont *mcmd = (struct mfg_cmd_tx_cont *)&resp->params.mfg_tx_cont; struct mfg_cmd_tx_cont *cfg = MNULL; ENTER(); if (!pioctl_buf) { LEAVE(); return MLAN_STATUS_FAILURE; } misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; cfg = (struct mfg_cmd_tx_cont *)&misc->param.mfg_tx_cont; cfg->error = wlan_le32_to_cpu(mcmd->error); cfg->enable_tx = wlan_le32_to_cpu(mcmd->enable_tx); cfg->cw_mode = wlan_le32_to_cpu(mcmd->cw_mode); cfg->payload_pattern = wlan_le32_to_cpu(mcmd->payload_pattern); cfg->cs_mode = wlan_le32_to_cpu(mcmd->cs_mode); cfg->act_sub_ch = wlan_le32_to_cpu(mcmd->act_sub_ch); cfg->tx_rate = wlan_le32_to_cpu(mcmd->tx_rate); LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function prepares command resp of MFG Tx frame * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_mfg_tx_frame(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_ds_misc_cfg *misc = MNULL; struct mfg_cmd_tx_frame2 *mcmd = (struct mfg_cmd_tx_frame2 *)&resp->params.mfg_tx_frame2; struct mfg_cmd_tx_frame2 *cfg = MNULL; ENTER(); if (!pioctl_buf) { LEAVE(); return MLAN_STATUS_FAILURE; } misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; cfg = (struct mfg_cmd_tx_frame2 *)&misc->param.mfg_tx_frame2; cfg->error = wlan_le32_to_cpu(mcmd->error); cfg->enable = wlan_le32_to_cpu(mcmd->enable); cfg->data_rate = wlan_le32_to_cpu(mcmd->data_rate); cfg->frame_pattern = wlan_le32_to_cpu(mcmd->frame_pattern); cfg->frame_length = wlan_le32_to_cpu(mcmd->frame_length); cfg->adjust_burst_sifs = wlan_le16_to_cpu(mcmd->adjust_burst_sifs); cfg->burst_sifs_in_us = wlan_le32_to_cpu(mcmd->burst_sifs_in_us); cfg->short_preamble = wlan_le32_to_cpu(mcmd->short_preamble); cfg->act_sub_ch = wlan_le32_to_cpu(mcmd->act_sub_ch); cfg->short_gi = wlan_le32_to_cpu(mcmd->short_gi); cfg->tx_bf = wlan_le32_to_cpu(mcmd->tx_bf); cfg->gf_mode = wlan_le32_to_cpu(mcmd->gf_mode); cfg->stbc = wlan_le32_to_cpu(mcmd->stbc); cfg->NumPkt = wlan_le32_to_cpu(mcmd->NumPkt); cfg->MaxPE = wlan_le32_to_cpu(mcmd->MaxPE); cfg->BeamChange = wlan_le32_to_cpu(mcmd->BeamChange); cfg->Dcm = wlan_le32_to_cpu(mcmd->Dcm); cfg->Doppler = wlan_le32_to_cpu(mcmd->Doppler); cfg->MidP = wlan_le32_to_cpu(mcmd->MidP); cfg->QNum = wlan_le32_to_cpu(mcmd->QNum); memcpy_ext(pmpriv->adapter, cfg->bssid, mcmd->bssid, MLAN_MAC_ADDR_LENGTH, sizeof(cfg->bssid)); LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function prepares command resp of MFG HE TB Tx * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ static mlan_status wlan_ret_mfg_he_tb_tx(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_ds_misc_cfg *misc = MNULL; struct mfg_Cmd_HE_TBTx_t *mcmd = (struct mfg_Cmd_HE_TBTx_t *)&resp->params.mfg_he_power; struct mfg_Cmd_HE_TBTx_t *cfg = MNULL; ENTER(); if (!pioctl_buf) { LEAVE(); return MLAN_STATUS_FAILURE; } misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; cfg = (struct mfg_Cmd_HE_TBTx_t *)&misc->param.mfg_he_power; cfg->enable = wlan_le16_to_cpu(mcmd->enable); cfg->qnum = wlan_le16_to_cpu(mcmd->qnum); cfg->aid = wlan_le16_to_cpu(mcmd->aid); cfg->axq_mu_timer = wlan_le16_to_cpu(mcmd->axq_mu_timer); cfg->tx_power = wlan_le16_to_cpu(mcmd->tx_power); LEAVE(); return MLAN_STATUS_SUCCESS; } /** * @brief This function prepares command resp of MFG Cmd * * @param pmpriv A pointer to mlan_private structure * @param resp A pointer to HostCmd_DS_COMMAND * @param pioctl_buf A pointer to mlan_ioctl_req structure * * @return MLAN_STATUS_SUCCESS */ mlan_status wlan_ret_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf) { mlan_ds_misc_cfg *misc = MNULL; struct mfg_cmd_generic_cfg *mcmd = (struct mfg_cmd_generic_cfg *)&resp->params.mfg_generic_cfg; struct mfg_cmd_generic_cfg *cfg = MNULL; mlan_status ret = MLAN_STATUS_SUCCESS; ENTER(); if (!pioctl_buf) { LEAVE(); return MLAN_STATUS_FAILURE; } switch (wlan_le32_to_cpu(mcmd->mfg_cmd)) { case MFG_CMD_TX_CONT: ret = wlan_ret_mfg_tx_cont(pmpriv, resp, pioctl_buf); goto cmd_mfg_done; case MFG_CMD_TX_FRAME: ret = wlan_ret_mfg_tx_frame(pmpriv, resp, pioctl_buf); goto cmd_mfg_done; case MFG_CMD_CONFIG_MAC_HE_TB_TX: ret = wlan_ret_mfg_he_tb_tx(pmpriv, resp, pioctl_buf); goto cmd_mfg_done; case MFG_CMD_SET_TEST_MODE: case MFG_CMD_UNSET_TEST_MODE: case MFG_CMD_TX_ANT: case MFG_CMD_RX_ANT: case MFG_CMD_RF_CHAN: case MFG_CMD_CLR_RX_ERR: case MFG_CMD_RF_BAND_AG: case MFG_CMD_RF_CHANNELBW: case MFG_CMD_RADIO_MODE_CFG: case MFG_CMD_RFPWR: break; default: ret = MLAN_STATUS_FAILURE; goto cmd_mfg_done; } misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; cfg = (struct mfg_cmd_generic_cfg *)&misc->param.mfg_generic_cfg; cfg->error = wlan_le32_to_cpu(mcmd->error); cfg->data1 = wlan_le32_to_cpu(mcmd->data1); cfg->data2 = wlan_le32_to_cpu(mcmd->data2); cfg->data3 = wlan_le32_to_cpu(mcmd->data3); cmd_mfg_done: LEAVE(); return ret; } /** * @brief This function handles the station command response * * @param priv A pointer to mlan_private structure * @param cmdresp_no cmd no * @param pcmd_buf cmdresp buf * @param pioctl A pointer to ioctl buf * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, t_void *pcmd_buf, t_void *pioctl) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_private *pmpriv = (mlan_private *)priv; HostCmd_DS_COMMAND *resp = (HostCmd_DS_COMMAND *)pcmd_buf; mlan_ioctl_req *pioctl_buf = (mlan_ioctl_req *)pioctl; mlan_adapter *pmadapter = pmpriv->adapter; #ifdef SDIO int ctr; #endif ENTER(); /* If the command is not successful, cleanup and return failure */ if ((resp->result != HostCmd_RESULT_OK)) { ret = wlan_process_cmdresp_error(pmpriv, resp, pioctl_buf); LEAVE(); return ret; } /* Command successful, handle response */ switch (cmdresp_no) { case HostCmd_CMD_GET_HW_SPEC: ret = wlan_ret_get_hw_spec(pmpriv, resp, pioctl_buf); break; #ifdef SDIO case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG: ret = wlan_ret_sdio_rx_aggr_cfg(pmpriv, resp); break; #endif case HostCmd_CMD_CFG_DATA: ret = wlan_ret_cfg_data(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_MAC_CONTROL: ret = wlan_ret_mac_control(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_MAC_ADDRESS: ret = wlan_ret_802_11_mac_address(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_MAC_MULTICAST_ADR: ret = wlan_ret_mac_multicast_adr(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_TX_RATE_CFG: ret = wlan_ret_tx_rate_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_SCAN: ret = wlan_ret_802_11_scan(pmpriv, resp, pioctl_buf); pioctl_buf = MNULL; pmadapter->curr_cmd->pioctl_buf = MNULL; break; case HostCmd_CMD_802_11_SCAN_EXT: ret = wlan_ret_802_11_scan_ext(pmpriv, resp, pioctl_buf); pioctl_buf = MNULL; pmadapter->curr_cmd->pioctl_buf = MNULL; break; case HostCmd_CMD_802_11_BG_SCAN_CONFIG: ret = wlan_ret_bgscan_config(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_BG_SCAN_QUERY: ret = wlan_ret_802_11_bgscan_query(pmpriv, resp, pioctl_buf); wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_BGSCAN_RESULT, MNULL); PRINTM(MINFO, "CMD_RESP: BG_SCAN result is ready!\n"); break; case HostCmd_CMD_TXPWR_CFG: ret = wlan_ret_tx_power_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_RF_TX_POWER: ret = wlan_ret_802_11_rf_tx_power(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_PS_MODE_ENH: ret = wlan_ret_enh_power_mode(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_HS_CFG_ENH: ret = wlan_ret_802_11_hs_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_SLEEP_PERIOD: ret = wlan_ret_802_11_sleep_period(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_SLEEP_PARAMS: ret = wlan_ret_802_11_sleep_params(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_ROBUSTCOEX: break; case HostCmd_CMD_DMCS_CONFIG: ret = wlan_ret_dmcs_config(pmpriv, resp, pioctl_buf); break; #if defined(PCIE) case HostCmd_CMD_SSU: PRINTM(MCMND, "SSU cmdresp:number_of_buffers %d, buffer_size %d rec_len %d\n", resp->params.ssu_params.number_of_buffers, resp->params.ssu_params.buffer_size, resp->params.ssu_params.rec_len); break; #endif case HostCmd_CMD_CSI: if (resp->params.csi_params.action == CSI_CMD_ENABLE) { pmadapter->csi_enabled = 1; PRINTM(MCMND, "CSI ENABLE cmdresp\n"); } else { pmadapter->csi_enabled = 0; PRINTM(MCMND, "CSI DISABLE cmdresp\n"); } break; case HostCmd_CMD_802_11_ASSOCIATE: ret = wlan_ret_802_11_associate(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_DEAUTHENTICATE: case HostCmd_CMD_802_11_DISASSOCIATE: ret = wlan_ret_802_11_deauthenticate(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_AD_HOC_START: case HostCmd_CMD_802_11_AD_HOC_JOIN: ret = wlan_ret_802_11_ad_hoc(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_AD_HOC_STOP: ret = wlan_ret_802_11_ad_hoc_stop(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_GET_LOG: ret = wlan_ret_get_log(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_LINK_STATS: ret = wlan_ret_get_link_statistic(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_RSSI_INFO_EXT: ret = wlan_ret_802_11_rssi_info_ext(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_RSSI_INFO: ret = wlan_ret_802_11_rssi_info(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_SNMP_MIB: ret = wlan_ret_802_11_snmp_mib(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_RADIO_CONTROL: ret = wlan_ret_802_11_radio_control(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_TX_RATE_QUERY: ret = wlan_ret_802_11_tx_rate_query(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_RF_CHANNEL: ret = wlan_ret_802_11_rf_channel(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_RF_ANTENNA: ret = wlan_ret_802_11_rf_antenna(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_CW_MODE_CTRL: ret = wlan_ret_cw_mode_ctrl(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_VERSION_EXT: ret = wlan_ret_ver_ext(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_RX_MGMT_IND: ret = wlan_ret_rx_mgmt_ind(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_FUNC_INIT: case HostCmd_CMD_FUNC_SHUTDOWN: break; case HostCmd_CMD_802_11_KEY_MATERIAL: ret = wlan_ret_802_11_key_material(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG: break; case HostCmd_CMD_SUPPLICANT_PMK: ret = wlan_ret_802_11_supplicant_pmk(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_SUPPLICANT_PROFILE: ret = wlan_ret_802_11_supplicant_profile(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_EAPOL_PKT: break; case HostCmd_CMD_802_11D_DOMAIN_INFO: ret = wlan_ret_802_11d_domain_info(pmpriv, resp); break; case HostCmd_CMD_802_11_TPC_ADAPT_REQ: case HostCmd_CMD_802_11_TPC_INFO: case HostCmd_CMD_802_11_CHAN_SW_ANN: case HostCmd_CMD_CHAN_REPORT_REQUEST: ret = wlan_11h_cmdresp_process(pmpriv, resp); break; case HostCmd_CMD_11N_ADDBA_REQ: ret = wlan_ret_11n_addba_req(pmpriv, resp); break; case HostCmd_CMD_11N_DELBA: ret = wlan_ret_11n_delba(pmpriv, resp); break; case HostCmd_CMD_11N_ADDBA_RSP: ret = wlan_ret_11n_addba_resp(pmpriv, resp); break; case HostCmd_CMD_RECONFIGURE_TX_BUFF: wlan_set_tx_pause_flag(pmpriv, MFALSE); pmadapter->tx_buf_size = (t_u16)wlan_le16_to_cpu(resp->params.tx_buf.buff_size); #ifdef SDIO if (IS_SD(pmadapter->card_type)) { pmadapter->tx_buf_size = (pmadapter->tx_buf_size / MLAN_SDIO_BLOCK_SIZE) * MLAN_SDIO_BLOCK_SIZE; pmadapter->pcard_sd->mp_end_port = wlan_le16_to_cpu( resp->params.tx_buf.mp_end_port); pmadapter->pcard_sd->mp_data_port_mask = pmadapter->pcard_sd->reg->data_port_mask; for (ctr = 1; ctr <= pmadapter->pcard_sd->max_ports - pmadapter->pcard_sd->mp_end_port; ctr++) { pmadapter->pcard_sd->mp_data_port_mask &= ~(1 << (pmadapter->pcard_sd->max_ports - ctr)); } pmadapter->pcard_sd->curr_wr_port = pmadapter->pcard_sd->reg->start_wr_port; pmadapter->pcard_sd->mpa_tx.pkt_aggr_limit = MIN(pmadapter->pcard_sd->mp_aggr_pkt_limit, (pmadapter->pcard_sd->mp_end_port >> 1)); PRINTM(MCMND, "end port %d, data port mask %x\n", wlan_le16_to_cpu( resp->params.tx_buf.mp_end_port), pmadapter->pcard_sd->mp_data_port_mask); } #endif pmadapter->curr_tx_buf_size = pmadapter->tx_buf_size; PRINTM(MCMND, "max_tx_buf_size=%d, tx_buf_size=%d\n", pmadapter->max_tx_buf_size, pmadapter->tx_buf_size); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: ret = wlan_ret_amsdu_aggr_ctrl(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_WMM_GET_STATUS: ret = wlan_ret_wmm_get_status( pmpriv, resp->params.get_wmm_status.queue_status_tlv, resp->size - S_DS_GEN); break; case HostCmd_CMD_WMM_ADDTS_REQ: ret = wlan_ret_wmm_addts_req(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_WMM_DELTS_REQ: ret = wlan_ret_wmm_delts_req(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_WMM_QUEUE_CONFIG: ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_WMM_QUEUE_STATS: ret = wlan_ret_wmm_queue_stats(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_WMM_TS_STATUS: ret = wlan_ret_wmm_ts_status(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_WMM_PARAM_CONFIG: ret = wlan_ret_wmm_param_config(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: ret = wlan_ret_ibss_coalescing_status(pmpriv, resp); break; case HostCmd_CMD_MGMT_IE_LIST: ret = wlan_ret_mgmt_ie_list(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_TDLS_CONFIG: ret = wlan_ret_tdls_config(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_TDLS_OPERATION: ret = wlan_ret_tdls_oper(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_11N_CFG: ret = wlan_ret_11n_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_11AC_CFG: ret = wlan_ret_11ac_cfg(pmpriv, resp, pioctl_buf); break; #if 0 case HostCmd_CMD_RECONFIGURE_TX_BUFF: pmadapter->tx_buf_size = (t_u16)wlan_le16_to_cpu(resp->params. tx_buf.buff_size); break; #endif case HostCmd_CMD_TX_BF_CFG: ret = wlan_ret_tx_bf_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG: ret = wlan_ret_sysclock_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_MAC_REG_ACCESS: case HostCmd_CMD_BBP_REG_ACCESS: case HostCmd_CMD_RF_REG_ACCESS: case HostCmd_CMD_CAU_REG_ACCESS: case HostCmd_CMD_TARGET_ACCESS: case HostCmd_CMD_802_11_EEPROM_ACCESS: case HostCmd_CMD_BCA_REG_ACCESS: case HostCmd_CMD_REG_ACCESS: ret = wlan_ret_reg_access(pmpriv->adapter, cmdresp_no, resp, pioctl_buf); break; case HostCmd_CMD_MEM_ACCESS: ret = wlan_ret_mem_access(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_INACTIVITY_TIMEOUT_EXT: ret = wlan_ret_inactivity_timeout(pmpriv, resp, pioctl_buf); break; #if defined(SDIO) case HostCmd_CMD_SDIO_GPIO_INT_CONFIG: break; #endif case HostCmd_CMD_SET_BSS_MODE: break; case HostCmd_CMD_MEASUREMENT_REQUEST: case HostCmd_CMD_MEASUREMENT_REPORT: ret = wlan_meas_cmdresp_process(pmpriv, resp); break; case HostCmd_CMD_802_11_NET_MONITOR: ret = wlan_ret_net_monitor(pmpriv, resp, pioctl_buf); break; #if defined(PCIE) #if defined(PCIE8997) || defined(PCIE8897) case HostCmd_CMD_PCIE_HOST_BUF_DETAILS: PRINTM(MINFO, "PCIE host buffer configuration successful.\n"); break; #endif #endif case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL: ret = wlan_ret_remain_on_channel(pmpriv, resp, pioctl_buf); break; #ifdef WIFI_DIRECT_SUPPORT case HOST_CMD_WIFI_DIRECT_MODE_CONFIG: ret = wlan_ret_wifi_direct_mode(pmpriv, resp, pioctl_buf); break; #endif case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: ret = wlan_ret_subscribe_event(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_OTP_READ_USER_DATA: ret = wlan_ret_otp_user_data(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_HS_WAKEUP_REASON: ret = wlan_ret_hs_wakeup_reason(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_REJECT_ADDBA_REQ: ret = wlan_ret_reject_addba_req(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_PACKET_AGGR_CTRL: ret = wlan_ret_packet_aggr_ctrl(pmpriv, resp, pioctl_buf); break; #ifdef USB case HostCmd_CMD_PACKET_AGGR_OVER_HOST_INTERFACE: ret = wlan_ret_packet_aggr_over_host_interface(pmpriv, resp, pioctl_buf); break; #endif #ifdef RX_PACKET_COALESCE case HostCmd_CMD_RX_PKT_COALESCE_CFG: ret = wlan_ret_rx_pkt_coalesce_cfg(pmpriv, resp, pioctl_buf); break; #endif case HostCMD_CONFIG_LOW_POWER_MODE: break; case HostCmd_DFS_REPEATER_MODE: ret = wlan_ret_dfs_repeater_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_COALESCE_CFG: ret = wlan_ret_coalesce_config(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_MEF_CFG: break; case HostCmd_DS_GET_SENSOR_TEMP: ret = wlan_ret_get_sensor_temp(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_MIMO_SWITCH: break; case HostCmd_CMD_IPV6_RA_OFFLOAD_CFG: ret = wlan_ret_ipv6_ra_offload(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_STA_CONFIGURE: ret = wlan_ret_sta_config(pmpriv, resp, pioctl_buf); break; case HOST_CMD_PMIC_CONFIGURE: break; case HostCmd_CMD_INDEPENDENT_RESET_CFG: ret = wlan_ret_ind_rst_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_PS_INACTIVITY_TIMEOUT: break; case HostCmd_CMD_ROAM_OFFLOAD: ret = wlan_ret_roam_offload(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_GET_TSF: ret = wlan_ret_get_tsf(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_CHAN_REGION_CFG: ret = wlan_ret_chan_region_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_AUTO_TX: ret = wlan_ret_auto_tx(pmpriv, resp, pioctl_buf); break; case HOST_CMD_TX_RX_PKT_STATS: ret = wlan_ret_tx_rx_pkt_stats(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_DYN_BW: ret = wlan_ret_dyn_bw(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_BOOT_SLEEP: ret = wlan_ret_boot_sleep(pmpriv, resp, pioctl_buf); break; #if defined(DRV_EMBEDDED_SUPPLICANT) case HostCmd_CMD_CRYPTO: ret = wlan_ret_crypto(pmpriv, resp, pioctl_buf); break; #endif case HostCmd_CMD_11AX_CFG: ret = wlan_ret_11ax_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_11AX_CMD: ret = wlan_ret_11ax_cmd(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_RANGE_EXT: ret = wlan_ret_range_ext(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_TWT_CFG: break; case HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG: ret = wlan_ret_gpio_tsf_latch(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_RX_ABORT_CFG: ret = wlan_ret_rxabortcfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_RX_ABORT_CFG_EXT: ret = wlan_ret_rxabortcfg_ext(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_ARB_CONFIG: ret = wlan_ret_arb_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_TX_AMPDU_PROT_MODE: ret = wlan_ret_tx_ampdu_prot_mode(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_DOT11MC_UNASSOC_FTM_CFG: ret = wlan_ret_dot11mc_unassoc_ftm_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_HAL_PHY_CFG: ret = wlan_ret_hal_phy_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_IPS_CONFIG: ret = wlan_ret_ips_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_RATE_ADAPT_CFG: ret = wlan_ret_rate_adapt_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_CCK_DESENSE_CFG: ret = wlan_ret_cck_desense_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CHANNEL_TRPC_CONFIG: ret = wlan_ret_get_chan_trpc_config(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_LOW_POWER_MODE_CFG: ret = wlan_ret_set_get_low_power_mode_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_MFG_COMMAND: ret = wlan_ret_mfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_MC_AGGR_CFG: ret = wlan_ret_mc_aggr_cfg(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_GET_CH_LOAD: ret = wlan_ret_ch_load(pmpriv, resp, pioctl_buf); break; default: PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n", resp->command); break; } LEAVE(); return ret; }