MCUXpresso_MIMXRT1021xxxxx/middleware/wifi_nxp/wifidriver/mlan_misc.c
Yilin Sun 763d32be90
Updated SDK to v2.15.000
Signed-off-by: Yilin Sun <imi415@imi.moe>
2024-03-15 22:23:36 +08:00

845 lines
26 KiB
C

/** @file mlan_misc.c
*
* @brief This file provides Miscellaneous functions for MLAN module
*
* Copyright 2008-2023 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/*************************************************************
Change Log:
05/11/2009: initial version
************************************************************/
#include <mlan_api.h>
/* Additional WMSDK header files */
#include <wmerrno.h>
#include <wm_os.h>
#include <mlan_fw.h>
/* Always keep this include at the end of all include files */
#include <mlan_remap_mem_operations.h>
/**
* @brief This function allocates a mlan_buffer.
*
* @param pmadapter Pointer to mlan_adapter
* @param data_len Data length
* @param head_room head_room reserved in mlan_buffer
* @param malloc_flag flag to user moal_malloc
* @return mlan_buffer pointer or MNULL
*/
pmlan_buffer wlan_alloc_mlan_buffer(mlan_adapter *pmadapter, t_u32 data_len, t_u32 head_room, t_u32 malloc_flag)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_buffer pmbuf = MNULL;
t_u32 buf_size = 0;
/* t_u8 *tmp_buf = MNULL; */
pmlan_callbacks pcb = &pmadapter->callbacks;
ENTER();
/* make sure that the data length is at least SDIO block size */
data_len = ALIGN_SZ(data_len, MLAN_SDIO_BLOCK_SIZE);
/* head_room is not implemented for malloc mlan buffer */
if (malloc_flag == MTRUE)
{
buf_size = sizeof(mlan_buffer) + data_len + DMA_ALIGNMENT;
ret =
pcb->moal_malloc(pmadapter->pmoal_handle, buf_size, MLAN_MEM_DEF | MLAN_MEM_DMA, (t_u8 **)(void **)&pmbuf);
if ((ret != MLAN_STATUS_SUCCESS) || (pmbuf == MNULL))
{
pmbuf = MNULL;
goto exit;
}
(void)__memset(pmadapter, pmbuf, 0, sizeof(mlan_buffer));
pmbuf->pdesc = MNULL;
/* Align address */
pmbuf->pbuf = (t_u8 *)ALIGN_ADDR((t_u8 *)pmbuf + sizeof(mlan_buffer), DMA_ALIGNMENT);
pmbuf->data_offset = 0;
pmbuf->data_len = data_len;
pmbuf->flags |= MLAN_BUF_FLAG_MALLOC_BUF;
}
exit:
LEAVE();
return pmbuf;
}
/**
* @brief This function frees a mlan_buffer.
*
* @param pmadapter Pointer to mlan_adapter
* @param pmbuf Pointer to mlan_buffer
*
* @return N/A
*/
t_void wlan_free_mlan_buffer(mlan_adapter *pmadapter, pmlan_buffer pmbuf)
{
return;
}
/**
* @brief This function will check if station list is empty
*
* @param priv A pointer to mlan_private
*
* @return MFALSE/MTRUE
*/
t_u8 wlan_is_station_list_empty(mlan_private *priv)
{
ENTER();
if (!(util_peek_list(priv->adapter->pmoal_handle, &priv->sta_list, priv->adapter->callbacks.moal_spin_lock,
priv->adapter->callbacks.moal_spin_unlock)))
{
LEAVE();
return MTRUE;
}
LEAVE();
return MFALSE;
}
/**
* @brief This function will return the pointer to station entry in station list
* table which matches the give mac address
*
* @param priv A pointer to mlan_private
* @param mac mac address to find in station list table
*
* @return A pointer to structure sta_node
*/
sta_node *wlan_get_station_entry(mlan_private *priv, t_u8 *mac)
{
sta_node *sta_ptr;
ENTER();
if (!mac)
{
LEAVE();
return MNULL;
}
if (!(sta_ptr = (sta_node *)util_peek_list(priv->adapter->pmoal_handle, &priv->sta_list,
priv->adapter->callbacks.moal_spin_lock,
priv->adapter->callbacks.moal_spin_unlock)))
{
LEAVE();
return MNULL;
}
while (sta_ptr != (sta_node *)&priv->sta_list)
{
if (!__memcmp(priv->adapter, sta_ptr->mac_addr, mac, MLAN_MAC_ADDR_LENGTH))
{
LEAVE();
return sta_ptr;
}
sta_ptr = sta_ptr->pnext;
}
LEAVE();
return MNULL;
}
/**
* @brief This function will add a pointer to station entry in station list
* table with the give mac address, if it does not exist already
*
* @param priv A pointer to mlan_private
* @param mac mac address to find in station list table
*
* @return A pointer to structure sta_node
*/
sta_node *wlan_add_station_entry(mlan_private *priv, t_u8 *mac)
{
sta_node *sta_ptr = MNULL;
mlan_adapter *pmadapter = priv->adapter;
ENTER();
pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
sta_ptr = wlan_get_station_entry(priv, mac);
if (sta_ptr)
goto done;
if (priv->adapter->callbacks.moal_malloc(priv->adapter->pmoal_handle, sizeof(sta_node), MLAN_MEM_DEF,
(t_u8 **)&sta_ptr))
{
PRINTM(MERROR, "Failed to allocate memory for station node\n");
LEAVE();
return MNULL;
}
(void)__memset(priv->adapter, sta_ptr, 0, sizeof(sta_node));
(void)__memcpy(priv->adapter, sta_ptr->mac_addr, mac, MLAN_MAC_ADDR_LENGTH);
util_enqueue_list_tail(priv->adapter->pmoal_handle, &priv->sta_list, (pmlan_linked_list)sta_ptr,
priv->adapter->callbacks.moal_spin_lock, priv->adapter->callbacks.moal_spin_unlock);
done:
pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
LEAVE();
return sta_ptr;
}
/**
* @brief This function will delete a station entry from station list
*
*
* @param priv A pointer to mlan_private
* @param mac station's mac address
*
* @return N/A
*/
t_void wlan_delete_station_entry(mlan_private *priv, t_u8 *mac)
{
sta_node *sta_ptr = MNULL;
mlan_adapter *pmadapter = priv->adapter;
ENTER();
pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
if ((sta_ptr = wlan_get_station_entry(priv, mac)))
{
util_unlink_list(priv->adapter->pmoal_handle, &priv->sta_list, (pmlan_linked_list)sta_ptr,
priv->adapter->callbacks.moal_spin_lock, priv->adapter->callbacks.moal_spin_unlock);
priv->adapter->callbacks.moal_mfree(priv->adapter->pmoal_handle, (t_u8 *)sta_ptr);
}
pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
LEAVE();
return;
}
/**
* @brief Clean up wapi station list
*
* @param priv Pointer to the mlan_private driver data struct
*
* @return N/A
*/
t_void wlan_delete_station_list(pmlan_private priv)
{
sta_node *sta_ptr;
ENTER();
while ((sta_ptr = (sta_node *)util_dequeue_list(priv->adapter->pmoal_handle, &priv->sta_list,
priv->adapter->callbacks.moal_spin_lock,
priv->adapter->callbacks.moal_spin_unlock)))
{
priv->adapter->callbacks.moal_mfree(priv->adapter->pmoal_handle, (t_u8 *)sta_ptr);
}
LEAVE();
return;
}
/**
* @brief This function processes the 802.11 mgmt Frame
*
* @param priv A pointer to mlan_private
* @param payload A pointer to the received buffer
* @param payload_len Length of the received buffer
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status wlan_process_802dot11_mgmt_pkt(IN mlan_private *priv, IN t_u8 *payload, IN t_u32 payload_len, RxPD *rxpd)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
wlan_802_11_header *pieee_pkt_hdr = MNULL;
t_u16 sub_type = 0;
ENTER();
/* Check packet type-subtype and compare with mgmt_passthru_mask If event
is needed to host, just eventify it */
pieee_pkt_hdr = (wlan_802_11_header *)payload;
sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(pieee_pkt_hdr->frm_ctl);
if ((((1 << sub_type) & priv->mgmt_frame_passthru_mask) == 0) && (sub_type != SUBTYPE_ACTION))
{
PRINTM(MINFO, "Dropping mgmt frame for subtype %d.\n", sub_type);
LEAVE();
return ret;
}
switch (sub_type)
{
case SUBTYPE_ACTION:
ret = wlan_process_mgmt_action(payload, payload_len, rxpd);
if (ret == MLAN_STATUS_SUCCESS)
{
return ret;
}
break;
case SUBTYPE_ASSOC_REQUEST:
case SUBTYPE_REASSOC_REQUEST:
case SUBTYPE_DISASSOC:
case SUBTYPE_DEAUTH:
case SUBTYPE_AUTH:
case SUBTYPE_PROBE_RESP:
break;
default:
PRINTM(MINFO, "Unexpected pkt subtype \n");
break;
}
LEAVE();
return ret;
}
mlan_status wlan_bypass_802dot11_mgmt_pkt(void *data)
{
RxPD *rxpd = (RxPD *)data;
wlan_mgmt_pkt *pmgmt_pkt_hdr = NULL;
t_u16 sub_type = 0;
wlan_802_11_header *pieee_pkt_hdr = MNULL;
t_u8 category = 0;
mlan_private *priv = mlan_adap->priv[0];
mlan_status ret = MLAN_STATUS_SUCCESS;
pmgmt_pkt_hdr = (wlan_mgmt_pkt *)((t_u8 *)rxpd + rxpd->rx_pkt_offset);
pieee_pkt_hdr = (wlan_802_11_header *)&pmgmt_pkt_hdr->wlan_header;
sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(pieee_pkt_hdr->frm_ctl);
// coverity[overrun-local:SUPPRESS]
category = *((t_u8 *)pieee_pkt_hdr + sizeof(wlan_802_11_header));
if ((pmgmt_pkt_hdr->wlan_header.frm_ctl & IEEE80211_FC_MGMT_FRAME_TYPE_MASK) == 0)
{
if ((((1 << sub_type) & priv->mgmt_frame_passthru_mask) == 0) && (sub_type != SUBTYPE_ACTION))
{
PRINTM(MINFO, "Dropping mgmt frame for subtype %d.\n", sub_type);
LEAVE();
return ret;
}
if (sub_type == SUBTYPE_ACTION)
{
if (category == IEEE_MGMT_ACTION_CATEGORY_BLOCK_ACK)
{
PRINTM(MINFO, "Dropping mgmt frame for category %d.\n", category);
LEAVE();
return ret;
}
}
}
ret = MLAN_STATUS_FAILURE;
return ret;
}
/**
* @brief Add Extended Capabilities IE
*
* @param pmpriv A pointer to mlan_private structure
* @param pptlv_out A pointer to TLV to fill in
* @param BSSDescriptor A poiter to bss descriptor
* @return N/A
*/
void wlan_add_ext_capa_info_ie(IN mlan_private *pmpriv, IN BSSDescriptor_t *pbss_desc, OUT t_u8 **pptlv_out)
{
MrvlIETypes_ExtCap_t *pext_cap = MNULL;
ENTER();
pext_cap = (MrvlIETypes_ExtCap_t *)(void *)*pptlv_out;
(void)__memset(pmpriv->adapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
pext_cap->header.len = wlan_cpu_to_le16(sizeof(ExtCap_t));
if ((((t_u8)(pmpriv->hotspot_cfg >> 8)) & HOTSPOT_ENABLE_INTERWORKING_IND) != 0U)
{
pext_cap->ext_cap.Interworking = 1;
}
if ((((t_u8)(pmpriv->hotspot_cfg >> 8)) & HOTSPOT_ENABLE_TDLS_IND) != 0U)
{
pext_cap->ext_cap.TDLSSupport = 1;
}
#ifdef CONFIG_11AX
if (pbss_desc && pbss_desc->multi_bssid_ap)
SET_EXTCAP_MULTI_BSSID(pext_cap->ext_cap);
if (wlan_check_11ax_twt_supported(pmpriv, pbss_desc))
SET_EXTCAP_TWT_REQ(pext_cap->ext_cap);
#endif
#ifdef CONFIG_11V
pext_cap->ext_cap.BSS_Transition = 1;
#endif
*pptlv_out += sizeof(MrvlIETypes_ExtCap_t);
LEAVE();
}
/**
* @brief Get rate index
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_PENDING --success, otherwise fail
*/
static mlan_status wlan_rate_ioctl_get_rate_index(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req, MNULL);
if (ret == MLAN_STATUS_SUCCESS)
{
ret = MLAN_STATUS_PENDING;
}
LEAVE();
return ret;
}
/**
* @brief Set rate index
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_PENDING --success, otherwise fail
*/
static mlan_status wlan_rate_ioctl_set_rate_index(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
{
t_s32 rate_index;
mlan_rate_format rate_format;
#if defined(CONFIG_11AC) || defined(CONFIG_11AX)
t_u32 nss;
#endif
t_u32 i;
mlan_ds_rate *ds_rate = MNULL;
mlan_status ret = MLAN_STATUS_FAILURE;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
t_u16 shift_index = 1U;
ENTER();
ds_rate = (mlan_ds_rate *)(void *)pioctl_req->pbuf;
rate_format = ds_rate->param.rate_cfg.rate_format;
#if defined(CONFIG_11AC) || defined(CONFIG_11AX)
nss = ds_rate->param.rate_cfg.nss;
#endif
rate_index = (t_s32)ds_rate->param.rate_cfg.rate;
if (ds_rate->param.rate_cfg.is_rate_auto == MTRUE)
{
(void)__memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
/* Rates talbe [0]: HR/DSSS;[1]: OFDM; [2..9] HT; */
/* Support all HR/DSSS rates */
bitmap_rates[0] = 0x000F;
/* Support all OFDM rates */
bitmap_rates[1] = 0x00FF;
/* Support all HT-MCSs rate */
for (i = 2; i < 9U; i++)
{
bitmap_rates[i] = 0xFFFF;
}
bitmap_rates[9] = 0x3FFF;
#ifdef CONFIG_11AC
/* [10..17] VHT */
/* Support all VHT-MCSs rate for NSS 1 and 2 */
for (i = 10; i < 12; i++)
{
bitmap_rates[i] = 0x03FF; /* 10 Bits valid */
}
/* Set to 0 as default value for all other NSSs */
for (i = 12; i < NELEMENTS(bitmap_rates); i++)
{
bitmap_rates[i] = 0x0;
}
#endif
#ifdef CONFIG_11AX
/* [18..25] HE */
/* Support all HE-MCSs rate for NSS1 and 2 */
for (i = 18; i < 20; i++)
bitmap_rates[i] = 0x0FFF;
for (i = 20; i < NELEMENTS(bitmap_rates); i++)
bitmap_rates[i] = 0x0;
#endif
}
else
{
PRINTM(MINFO, "Rate index is %d\n", rate_index);
(void)__memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
if (rate_format == MLAN_RATE_FORMAT_LG)
{
/* Bitmap of HR/DSSS rates */
if (rate_index <= MLAN_RATE_INDEX_HRDSSS3)
{
bitmap_rates[0] = (shift_index << rate_index);
ret = MLAN_STATUS_SUCCESS;
/* Bitmap of OFDM rates */
}
else if (rate_index <= MLAN_RATE_INDEX_OFDM7)
{
bitmap_rates[1] = (shift_index << (rate_index - MLAN_RATE_INDEX_OFDM0));
ret = MLAN_STATUS_SUCCESS;
}
else
{
/*Do Nothing*/
}
}
else if (rate_format == MLAN_RATE_FORMAT_HT)
{
if (rate_index <= MLAN_RATE_INDEX_MCS32)
{
#ifdef SD8801
rate_index -= MLAN_RATE_INDEX_MCS0;
#endif
bitmap_rates[2 + (rate_index / 16)] = (shift_index << (rate_index % 16));
ret = MLAN_STATUS_SUCCESS;
}
}
else
{
/*DO Nothing*/
}
#ifdef CONFIG_11AC
if (rate_format == MLAN_RATE_FORMAT_VHT)
{
if ((rate_index <= MLAN_RATE_INDEX_MCS9) && (MLAN_RATE_NSS1 <= nss) && (nss <= MLAN_RATE_NSS2))
{
bitmap_rates[10 + nss - MLAN_RATE_NSS1] = (shift_index << rate_index);
ret = MLAN_STATUS_SUCCESS;
}
}
#endif
#ifdef CONFIG_11AX
if (rate_format == MLAN_RATE_FORMAT_HE)
{
if (IS_FW_SUPPORT_11AX(pmadapter))
{
if ((rate_index <= MLAN_RATE_INDEX_MCS11) && (MLAN_RATE_NSS1 <= nss) && (nss <= MLAN_RATE_NSS2))
{
bitmap_rates[18 + nss - MLAN_RATE_NSS1] = (1 << rate_index);
ret = MLAN_STATUS_SUCCESS;
}
}
else
{
PRINTM(MERROR, "Error! Fw doesn't support 11AX\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
}
#endif
if (ret == MLAN_STATUS_FAILURE)
{
PRINTM(MERROR, "Invalid MCS index=%d. \n", rate_index);
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
LEAVE();
return MLAN_STATUS_FAILURE;
}
}
PRINTM(MINFO,
"RateBitmap=%04x%04x%04x%04x%04x%04x%04x%04x"
"%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x, "
"IsRateAuto=%d, DataRate=%d\n",
bitmap_rates[17], bitmap_rates[16], bitmap_rates[15], bitmap_rates[14], bitmap_rates[13], bitmap_rates[12],
bitmap_rates[11], bitmap_rates[10], bitmap_rates[9], bitmap_rates[8], bitmap_rates[7], bitmap_rates[6],
bitmap_rates[5], bitmap_rates[4], bitmap_rates[3], bitmap_rates[2], bitmap_rates[1], bitmap_rates[0],
pmpriv->is_data_rate_auto, pmpriv->data_rate);
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
(t_void *)bitmap_rates);
if (ret == MLAN_STATUS_SUCCESS)
{
ret = MLAN_STATUS_PENDING;
}
LEAVE();
return ret;
}
/**
* @brief Rate configuration command handler
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success, otherwise fail
*/
mlan_status wlan_rate_ioctl_cfg(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
{
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
if (pioctl_req->action == MLAN_ACT_GET)
{
status = wlan_rate_ioctl_get_rate_index(pmadapter, pioctl_req);
}
else
{
status = wlan_rate_ioctl_set_rate_index(pmadapter, pioctl_req);
}
LEAVE();
return status;
}
/**
* @brief This function prepares command of rf_antenna.
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action The action: GET or SET
* @param pdata_buf A pointer to data buffer
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_802_11_rf_antenna(IN pmlan_private pmpriv,
IN HostCmd_DS_COMMAND *cmd,
IN t_u16 cmd_action,
IN t_void *pdata_buf)
{
HostCmd_DS_802_11_RF_ANTENNA *pantenna = &cmd->params.antenna;
mlan_ds_ant_cfg_1x1 *ant_cfg_1x1 = (mlan_ds_ant_cfg_1x1 *)pdata_buf;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_ANTENNA);
cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_ANTENNA) + S_DS_GEN);
if (cmd_action == HostCmd_ACT_GEN_SET)
{
pantenna->action = wlan_cpu_to_le16(HostCmd_ACT_SET_BOTH);
pantenna->antenna_mode = wlan_cpu_to_le16((t_u16)ant_cfg_1x1->antenna);
pantenna->evaluate_time = wlan_cpu_to_le16((t_u16)ant_cfg_1x1->evaluate_time);
}
else
{
pantenna->action = wlan_cpu_to_le16(HostCmd_ACT_GET_BOTH);
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
#ifdef WLAN_LOW_POWER_ENABLE
/**
* @brief Set/Get Low Power Mode
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_misc_ioctl_low_pwr_mode(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_misc_cfg *misc = MNULL;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_LOW_POWER_MODE, HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
&misc->param.low_pwr_mode);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
#endif // WLAN_LOW_POWER_ENABLE
#ifdef CONFIG_WIFI_CLOCKSYNC
/**
* @brief Set/Get GPIO TSF Latch config
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_SUCCESS --success, otherwise fail
*/
mlan_status wlan_misc_gpio_tsf_latch_config(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_misc_cfg *misc_cfg = MNULL;
t_u16 cmd_action = 0;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
cmd_action = HostCmd_ACT_GEN_GET;
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_GPIO_TSF_LATCH_PARAM_CONFIG, cmd_action, 0, (t_void *)pioctl_req,
&misc_cfg->param.gpio_tsf_latch_config);
LEAVE();
return ret;
}
/**
* @brief Get TSF info
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_SUCCESS --success, otherwise fail
*/
mlan_status wlan_misc_get_tsf_info(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_misc_cfg *misc_cfg = MNULL;
t_u16 cmd_action = 0;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
cmd_action = HostCmd_ACT_GEN_GET;
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_GPIO_TSF_LATCH_PARAM_CONFIG, cmd_action, 0, (t_void *)pioctl_req,
&misc_cfg->param.tsf_info);
LEAVE();
return ret;
}
#endif /* CONFIG_WIFI_CLOCKSYNC */
#ifdef CONFIG_RF_TEST_MODE
/**
* @brief RF Test Mode config
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_PENDING --success, otherwise fail
*/
mlan_status wlan_misc_ioctl_rf_test_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
mlan_private *pmpriv = MNULL;
mlan_ds_misc_cfg *pmisc = MNULL;
mlan_status ret = MLAN_STATUS_FAILURE;
t_u16 cmd_action = 0;
ENTER();
if (!pioctl_req)
goto done;
pmpriv = pmadapter->priv[pioctl_req->bss_index];
pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
switch (pmisc->sub_command)
{
case MLAN_OID_MISC_RF_TEST_GENERIC:
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
cmd_action = HostCmd_ACT_GEN_GET;
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
&(pmisc->param.mfg_generic_cfg));
break;
case MLAN_OID_MISC_RF_TEST_TX_CONT:
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
{
PRINTM(MERROR, "Unsupported cmd_action\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
&(pmisc->param.mfg_tx_cont));
break;
case MLAN_OID_MISC_RF_TEST_TX_FRAME:
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
{
PRINTM(MERROR, "Unsupported cmd_action\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
&(pmisc->param.mfg_tx_frame2));
break;
case MLAN_OID_MISC_RF_TEST_CONFIG_TRIGGER_FRAME:
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
{
PRINTM(MERROR, "Unsupported cmd_action\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
&(pmisc->param.mfg_tx_trigger_config));
break;
case MLAN_OID_MISC_RF_TEST_HE_POWER:
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
{
PRINTM(MERROR, "Unsupported cmd_action\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
&(pmisc->param.mfg_he_power));
break;
}
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
done:
LEAVE();
return ret;
}
#endif
#if defined(CONFIG_WIFI_IND_RESET) && defined(CONFIG_WIFI_IND_DNLD)
/**
* @brief Configure GPIO independent reset
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_PENDING --success, otherwise fail
*/
mlan_status wlan_misc_ioctl_ind_rst_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
mlan_status ret = MLAN_STATUS_SUCCESS;
t_u16 cmd_action = 0;
ENTER();
if (pioctl_req->action == MLAN_ACT_GET)
cmd_action = HostCmd_ACT_GEN_GET;
else
cmd_action = HostCmd_ACT_GEN_SET;
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_INDEPENDENT_RESET_CFG, cmd_action, 0, (t_void *)pioctl_req,
(t_void *)&misc->param.ind_rst_cfg);
LEAVE();
return ret;
}
#endif