mirror of
https://github.com/nxp-imx/mwifiex.git
synced 2024-11-15 03:25:35 +00:00
59094f8640
changes: 1. WSW-18043: Include txpwrlimit_cfg_iw416 files on MM driver 2. WSW-18325: Rename ed_mac_ctrl conf files from V3 to V2 3. WSW-16931: Observing timeout on STAUT with UL OFDMA BSR scenario 4. WCSWREL-227: Fixed the issue of CtsWifiTestCases case android.net.wifi.cts.WifiManagerTest#testTrafficStateCallback 5. WSW-17727: Fixed the issue of STA Connection failed with dmcs enable and host_mlme=1 6. WSW-17450: Fixed the issue of android.net.wifi.cts.WifiManagerTest failure 7. WSW-17491: Fixed the issue of android.cts.statsdatom.wifi.WifiStatsTests failure 8. WSW-18006: Set CAC period of 600 sec for weather channel for ETSI region 9. WSW-17906: Fixed the issue of APUT not advertise the support of MCS32 10. WSW-17575: Fixed the issue of Host cannot wake-up by ping during Hostsleep 11. WSW-17904: Fixed the issue of STAUT advertising VHT Tx/Rx MCS as 1SS when associating with 1SS AP 12. WSW-17427: Fixed the issue of uAPUTL failing to start BSS and returns "Core Dumped" error message 13. WSW-15856: Hotspot is turning off automatically after few minutes ~10mins with one client connected 14. WCSWREL-211: System reboot when switch wifi hotspot security mode from WPA2 to none Signed-off-by: Sherry Sun <sherry.sun@nxp.com> Approved-by: Tian Yang <yang.tian@nxp.com>
2263 lines
69 KiB
C
2263 lines
69 KiB
C
/** @file mlan_uap_ioctl.c
|
|
*
|
|
* @brief This file contains the handling of AP mode ioctls
|
|
*
|
|
*
|
|
* Copyright 2009-2021 NXP
|
|
*
|
|
* This software file (the File) is distributed by NXP
|
|
* under the terms of the GNU General Public License Version 2, June 1991
|
|
* (the License). You may use, redistribute and/or modify the File in
|
|
* accordance with the terms and conditions of the License, a copy of which
|
|
* is available by writing to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
|
|
* worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
|
*
|
|
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE EXPRESSLY DISCLAIMED. The License provides additional details about
|
|
* this warranty disclaimer.
|
|
*
|
|
*/
|
|
|
|
/********************************************************
|
|
Change log:
|
|
02/05/2009: initial version
|
|
********************************************************/
|
|
|
|
#include "mlan.h"
|
|
#include "mlan_util.h"
|
|
#include "mlan_fw.h"
|
|
#ifdef STA_SUPPORT
|
|
#include "mlan_join.h"
|
|
#endif
|
|
#include "mlan_main.h"
|
|
#include "mlan_uap.h"
|
|
#include "mlan_11n.h"
|
|
#include "mlan_fw.h"
|
|
#include "mlan_11h.h"
|
|
#include "mlan_11ac.h"
|
|
#include "mlan_11ax.h"
|
|
|
|
/********************************************************
|
|
Global Variables
|
|
********************************************************/
|
|
|
|
/********************************************************
|
|
Local Functions
|
|
********************************************************/
|
|
/**
|
|
* @brief Stop BSS
|
|
*
|
|
* @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_uap_bss_ioctl_stop(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
|
|
ENTER();
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP,
|
|
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
static t_bool wlan_can_radar_det_skip(mlan_private *priv)
|
|
{
|
|
mlan_private *priv_list[MLAN_MAX_BSS_NUM];
|
|
mlan_private *pmpriv;
|
|
mlan_adapter *pmadapter = priv->adapter;
|
|
t_u8 pcount, i;
|
|
|
|
/* In MBSS environment, if one of the BSS is already beaconing and DRCS
|
|
* is off then 11n_radar detection is not required for subsequent BSSes
|
|
* since they will follow the primary bss.
|
|
*/
|
|
if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)) {
|
|
memset(pmadapter, priv_list, 0x00, sizeof(priv_list));
|
|
pcount = wlan_get_privs_by_cond(pmadapter, wlan_is_intf_active,
|
|
priv_list);
|
|
for (i = 0; i < pcount; i++) {
|
|
pmpriv = priv_list[i];
|
|
if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP)
|
|
return MTRUE;
|
|
}
|
|
}
|
|
return MFALSE;
|
|
}
|
|
/**
|
|
* @brief Callback to finish BSS IOCTL START
|
|
* Not to be called directly to initiate bss_start
|
|
*
|
|
* @param priv A pointer to mlan_private structure (cast from t_void*)
|
|
*
|
|
* @return MLAN_STATUS_PENDING --success, otherwise fail
|
|
* @sa wlan_uap_bss_ioctl_start
|
|
*/
|
|
static mlan_status wlan_uap_callback_bss_ioctl_start(t_void *priv)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = (mlan_private *)priv;
|
|
mlan_callbacks *pcb = (mlan_callbacks *)&pmpriv->adapter->callbacks;
|
|
wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb;
|
|
t_u8 old_channel;
|
|
t_bool under_nop = MFALSE;
|
|
ENTER();
|
|
/* clear callback now that we're here */
|
|
puap_state_chan_cb->get_chan_callback = MNULL;
|
|
|
|
/*
|
|
* Check if the region and channel requires we check for radar.
|
|
*/
|
|
if ((puap_state_chan_cb->bandcfg.chanBand == BAND_5GHZ) &&
|
|
!wlan_can_radar_det_skip(pmpriv) &&
|
|
wlan_11h_radar_detect_required(pmpriv,
|
|
puap_state_chan_cb->channel)) {
|
|
/* If DFS repeater mode is on then before starting the uAP
|
|
* make sure that mlan0 is connected to some external AP
|
|
* for DFS channel operations.
|
|
*/
|
|
if (pmpriv->adapter->dfs_repeater) {
|
|
pmlan_private tmpriv = MNULL;
|
|
tmpriv = wlan_get_priv(pmpriv->adapter,
|
|
MLAN_BSS_ROLE_STA);
|
|
|
|
if (tmpriv && !tmpriv->media_connected) {
|
|
PRINTM(MERROR,
|
|
"BSS start is blocked when DFS-repeater\n"
|
|
"mode is on and STA is not connected\n");
|
|
pcb->moal_ioctl_complete(
|
|
pmpriv->adapter->pmoal_handle,
|
|
puap_state_chan_cb->pioctl_req_curr,
|
|
MLAN_STATUS_FAILURE);
|
|
goto done;
|
|
} else {
|
|
/* STA is connected.
|
|
* Skip DFS check for bss_start since its a
|
|
* repeater mode
|
|
*/
|
|
goto prep_bss_start;
|
|
}
|
|
}
|
|
|
|
/* first check if channel is under NOP */
|
|
if (wlan_11h_is_channel_under_nop(
|
|
pmpriv->adapter, puap_state_chan_cb->channel)) {
|
|
/* recently we've seen radar on this channel */
|
|
ret = MLAN_STATUS_FAILURE;
|
|
under_nop = MTRUE;
|
|
}
|
|
|
|
/* Check cached radar check on the channel */
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = wlan_11h_check_chan_report(
|
|
pmpriv, puap_state_chan_cb->channel);
|
|
|
|
/* Found radar: try to switch to a non-dfs channel */
|
|
if (ret != MLAN_STATUS_SUCCESS) {
|
|
old_channel = puap_state_chan_cb->channel;
|
|
ret = wlan_11h_switch_non_dfs_chan(
|
|
pmpriv, &puap_state_chan_cb->channel);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS) {
|
|
wlan_11h_update_bandcfg(
|
|
pmpriv,
|
|
&pmpriv->uap_state_chan_cb.bandcfg,
|
|
puap_state_chan_cb->channel);
|
|
PRINTM(MCMD_D,
|
|
"NOP: uap band config:0x%x channel=%d\n",
|
|
pmpriv->uap_state_chan_cb.bandcfg,
|
|
puap_state_chan_cb->channel);
|
|
|
|
ret = wlan_uap_set_channel(
|
|
pmpriv,
|
|
pmpriv->uap_state_chan_cb.bandcfg,
|
|
puap_state_chan_cb->channel);
|
|
if (ret == MLAN_STATUS_SUCCESS) {
|
|
if (under_nop) {
|
|
PRINTM(MMSG,
|
|
"Channel %d under NOP,"
|
|
" switched to new channel %d successfully.\n",
|
|
old_channel,
|
|
puap_state_chan_cb
|
|
->channel);
|
|
} else {
|
|
PRINTM(MMSG,
|
|
"Radar found on channel %d,"
|
|
" switched to new channel %d successfully.\n",
|
|
old_channel,
|
|
puap_state_chan_cb
|
|
->channel);
|
|
}
|
|
} else {
|
|
if (under_nop) {
|
|
PRINTM(MMSG,
|
|
"Channel %d under NOP,"
|
|
" switch to new channel %d failed.\n",
|
|
old_channel,
|
|
puap_state_chan_cb
|
|
->channel);
|
|
} else {
|
|
PRINTM(MMSG,
|
|
"Radar found on channel %d,"
|
|
" switch to new channel %d failed.\n",
|
|
old_channel,
|
|
puap_state_chan_cb
|
|
->channel);
|
|
}
|
|
pcb->moal_ioctl_complete(
|
|
pmpriv->adapter->pmoal_handle,
|
|
puap_state_chan_cb
|
|
->pioctl_req_curr,
|
|
MLAN_STATUS_FAILURE);
|
|
goto done;
|
|
}
|
|
} else {
|
|
if (under_nop) {
|
|
PRINTM(MMSG,
|
|
"Channel %d under NOP, no switch channel available.\n",
|
|
old_channel);
|
|
} else {
|
|
PRINTM(MMSG,
|
|
"Radar found on channel %d, no switch channel available.\n",
|
|
old_channel);
|
|
}
|
|
/* No command sent with the ioctl, need manually
|
|
* signal completion */
|
|
pcb->moal_ioctl_complete(
|
|
pmpriv->adapter->pmoal_handle,
|
|
puap_state_chan_cb->pioctl_req_curr,
|
|
MLAN_STATUS_FAILURE);
|
|
goto done;
|
|
}
|
|
} else {
|
|
PRINTM(MINFO, "No Radar found on channel %d\n",
|
|
puap_state_chan_cb->channel);
|
|
}
|
|
}
|
|
|
|
prep_bss_start:
|
|
/* else okay to send command: not DFS channel or no radar */
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_START,
|
|
HostCmd_ACT_GEN_SET, 0,
|
|
(t_void *)puap_state_chan_cb->pioctl_req_curr,
|
|
MNULL);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
done:
|
|
puap_state_chan_cb->pioctl_req_curr = MNULL; /* prevent re-use */
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Start BSS
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_PENDING --success, otherwise fail
|
|
*/
|
|
/**
|
|
* @sa wlan_uap_callback_bss_ioctl_start
|
|
*/
|
|
static mlan_status wlan_uap_bss_ioctl_start(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_bss *bss = MNULL;
|
|
|
|
ENTER();
|
|
|
|
bss = (mlan_ds_bss *)pioctl_req->pbuf;
|
|
pmpriv->uap_host_based = bss->param.host_based;
|
|
if (!pmpriv->intf_state_11h.is_11h_host &&
|
|
pmpriv->intf_state_11h.is_11h_active) {
|
|
/* if FW supports ACS+DFS then sequence is different */
|
|
|
|
/* First check channel report, defer BSS_START CMD to callback.
|
|
*/
|
|
/* store params, issue command to get UAP channel, whose
|
|
* CMD_RESP will callback remainder of bss_start handling */
|
|
pmpriv->uap_state_chan_cb.pioctl_req_curr = pioctl_req;
|
|
pmpriv->uap_state_chan_cb.get_chan_callback =
|
|
wlan_uap_callback_bss_ioctl_start;
|
|
pmpriv->intf_state_11h.is_11h_host = MFALSE;
|
|
ret = wlan_uap_get_channel(pmpriv);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
} else {
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_START,
|
|
HostCmd_ACT_GEN_SET, 0,
|
|
(t_void *)pioctl_req, MNULL);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
}
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief reset BSS
|
|
*
|
|
* @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_uap_bss_ioctl_reset(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
t_u8 i = 0;
|
|
|
|
ENTER();
|
|
|
|
/*
|
|
* Reset any uap private parameters here
|
|
*/
|
|
for (i = 0; i < pmadapter->max_mgmt_ie_index; i++)
|
|
memset(pmadapter, &pmpriv->mgmt_ie[i], 0, sizeof(custom_ie));
|
|
pmpriv->add_ba_param.timeout = MLAN_DEFAULT_BLOCK_ACK_TIMEOUT;
|
|
pmpriv->add_ba_param.tx_win_size = MLAN_UAP_AMPDU_DEF_TXWINSIZE;
|
|
pmpriv->add_ba_param.rx_win_size = MLAN_UAP_AMPDU_DEF_RXWINSIZE;
|
|
pmpriv->user_rxwinsize = pmpriv->add_ba_param.rx_win_size;
|
|
|
|
for (i = 0; i < MAX_NUM_TID; i++) {
|
|
pmpriv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i];
|
|
pmpriv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i];
|
|
pmpriv->addba_reject[i] = ADDBA_RSP_STATUS_ACCEPT;
|
|
}
|
|
pmpriv->aggr_prio_tbl[6].amsdu = BA_STREAM_NOT_ALLOWED;
|
|
pmpriv->aggr_prio_tbl[7].amsdu = BA_STREAM_NOT_ALLOWED;
|
|
|
|
pmpriv->aggr_prio_tbl[6].ampdu_user =
|
|
pmpriv->aggr_prio_tbl[7].ampdu_user = BA_STREAM_NOT_ALLOWED;
|
|
pmpriv->addba_reject[6] = pmpriv->addba_reject[7] =
|
|
ADDBA_RSP_STATUS_REJECT;
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_RESET,
|
|
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief This function to process add station.
|
|
*
|
|
* @param pmadapter A pointer to pmadapter.
|
|
*
|
|
* @param pioctl_req A pointer to pioctl_req
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS/MLAN_STATUS_FAILURE
|
|
*/
|
|
static mlan_status wlan_uap_bss_ioctl_add_station(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_ADD_NEW_STATION,
|
|
HostCmd_ACT_ADD_STA, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get MAC address
|
|
*
|
|
* @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_uap_bss_ioctl_mac_address(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_bss *bss = MNULL;
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 cmd_action = 0;
|
|
|
|
ENTER();
|
|
|
|
bss = (mlan_ds_bss *)pioctl_req->pbuf;
|
|
if (pioctl_req->action == MLAN_ACT_SET) {
|
|
memcpy_ext(pmadapter, pmpriv->curr_addr, &bss->param.mac_addr,
|
|
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
|
|
cmd_action = HostCmd_ACT_GEN_SET;
|
|
} else
|
|
cmd_action = HostCmd_ACT_GEN_GET;
|
|
/* Send request to firmware */
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action,
|
|
0, (t_void *)pioctl_req, MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get wmm param
|
|
*
|
|
* @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_uap_bss_ioctl_uap_wmm_param(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 cmd_action = 0;
|
|
|
|
ENTER();
|
|
|
|
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, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action,
|
|
0, (t_void *)pioctl_req, MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Handle channel switch
|
|
*
|
|
* @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_uap_bss_ioctl_action_chan_switch(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 cmd_action = 0;
|
|
|
|
ENTER();
|
|
|
|
cmd_action = HostCmd_ACT_GEN_SET;
|
|
|
|
/* Send request to firmware */
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action,
|
|
0, (t_void *)pioctl_req, MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get scan channels
|
|
*
|
|
* @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_uap_bss_ioctl_uap_scan_channels(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 cmd_action = 0;
|
|
|
|
ENTER();
|
|
|
|
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, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action,
|
|
0, (t_void *)pioctl_req, MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get UAP channel
|
|
*
|
|
* @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_uap_bss_ioctl_uap_channel(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 cmd_action = 0;
|
|
|
|
ENTER();
|
|
|
|
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, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action,
|
|
0, (t_void *)pioctl_req, MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get UAP operation control vaule
|
|
*
|
|
* @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_uap_bss_ioctl_uap_oper_ctrl(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 cmd_action = 0;
|
|
|
|
ENTER();
|
|
|
|
if (pmadapter->fw_ver == HOST_API_VERSION_V15 &&
|
|
pmadapter->fw_min_ver >= FW_MINOR_VERSION_1) {
|
|
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, HOST_CMD_APCMD_OPER_CTRL,
|
|
cmd_action, 0, (t_void *)pioctl_req,
|
|
(t_void *)pioctl_req->pbuf);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
} else {
|
|
PRINTM(MMSG, "FW don't support uap oper ctrl\n");
|
|
}
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Get Uap statistics
|
|
*
|
|
* @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_uap_get_stats(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
|
|
ENTER();
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SNMP_MIB,
|
|
HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Get Uap MIB counters
|
|
*
|
|
* @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_uap_get_stats_log(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
pmlan_private pmpriv = MNULL;
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
|
|
if (pioctl_req != MNULL) {
|
|
pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
} else {
|
|
PRINTM(MERROR, "MLAN IOCTL information is not present\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto exit;
|
|
}
|
|
|
|
/* Check information buffer length of MLAN IOCTL */
|
|
if (pioctl_req->buf_len < sizeof(mlan_ds_get_stats)) {
|
|
PRINTM(MWARN,
|
|
"MLAN IOCTL information buffer length is too short.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
pioctl_req->buf_len_needed = sizeof(mlan_ds_get_stats);
|
|
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
|
|
ret = MLAN_STATUS_RESOURCE;
|
|
goto exit;
|
|
}
|
|
|
|
/* Send request to firmware */
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_GET_LOG,
|
|
HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
exit:
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get AP 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
|
|
*/
|
|
static mlan_status wlan_uap_bss_ioctl_config(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 cmd_action = 0;
|
|
|
|
ENTER();
|
|
|
|
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, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action,
|
|
0, (t_void *)pioctl_req, MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief deauth sta
|
|
*
|
|
* @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_uap_bss_ioctl_deauth_sta(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_bss *bss = MNULL;
|
|
|
|
ENTER();
|
|
|
|
bss = (mlan_ds_bss *)pioctl_req->pbuf;
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_STA_DEAUTH,
|
|
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
|
|
(t_void *)&bss->param.deauth_param);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Get station list
|
|
*
|
|
* @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_uap_get_sta_list(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
|
|
/* Send request to firmware */
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_STA_LIST,
|
|
HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief soft_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
|
|
*/
|
|
static mlan_status wlan_uap_misc_ioctl_soft_reset(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SOFT_RESET,
|
|
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Tx data pause
|
|
*
|
|
* @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_uap_misc_ioctl_txdatapause(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_misc_cfg *pmisc = (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_SET)
|
|
cmd_action = HostCmd_ACT_GEN_SET;
|
|
else
|
|
cmd_action = HostCmd_ACT_GEN_GET;
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CFG_TX_DATA_PAUSE,
|
|
cmd_action, 0, (t_void *)pioctl_req,
|
|
&(pmisc->param.tx_datapause));
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get Power mode
|
|
*
|
|
* @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_uap_pm_ioctl_mode(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_pm_cfg *pm = MNULL;
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 cmd_action = 0;
|
|
t_u32 cmd_oid = 0;
|
|
|
|
ENTER();
|
|
|
|
pm = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
|
|
if (pioctl_req->action == MLAN_ACT_SET) {
|
|
if (pm->param.ps_mgmt.ps_mode == PS_MODE_INACTIVITY) {
|
|
cmd_action = EN_AUTO_PS;
|
|
cmd_oid = BITMAP_UAP_INACT_PS;
|
|
} else if (pm->param.ps_mgmt.ps_mode == PS_MODE_PERIODIC_DTIM) {
|
|
cmd_action = EN_AUTO_PS;
|
|
cmd_oid = BITMAP_UAP_DTIM_PS;
|
|
} else {
|
|
cmd_action = DIS_AUTO_PS;
|
|
cmd_oid = BITMAP_UAP_INACT_PS | BITMAP_UAP_DTIM_PS;
|
|
}
|
|
} else {
|
|
cmd_action = GET_PS;
|
|
cmd_oid = BITMAP_UAP_INACT_PS | BITMAP_UAP_DTIM_PS;
|
|
}
|
|
/* Send request to firmware */
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_PS_MODE_ENH,
|
|
cmd_action, cmd_oid, (t_void *)pioctl_req,
|
|
(t_void *)&pm->param.ps_mgmt);
|
|
if ((ret == MLAN_STATUS_SUCCESS) &&
|
|
(pioctl_req->action == MLAN_ACT_SET) &&
|
|
(cmd_action == DIS_AUTO_PS)) {
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_PS_MODE_ENH,
|
|
GET_PS, 0, MNULL, MNULL);
|
|
}
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set WAPI IE
|
|
*
|
|
* @param priv A pointer to mlan_private structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_PENDING --success, otherwise fail
|
|
*/
|
|
static mlan_status wlan_uap_set_wapi_ie(mlan_private *priv,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_ds_misc_cfg *misc = MNULL;
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
|
|
if (misc->param.gen_ie.len) {
|
|
if (misc->param.gen_ie.len > sizeof(priv->wapi_ie)) {
|
|
PRINTM(MWARN, "failed to copy WAPI IE, too big\n");
|
|
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
|
|
LEAVE();
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
memcpy_ext(priv->adapter, priv->wapi_ie,
|
|
misc->param.gen_ie.ie_data, misc->param.gen_ie.len,
|
|
sizeof(priv->wapi_ie));
|
|
priv->wapi_ie_len = misc->param.gen_ie.len;
|
|
PRINTM(MIOCTL, "Set wapi_ie_len=%d IE=%#x\n", priv->wapi_ie_len,
|
|
priv->wapi_ie[0]);
|
|
DBG_HEXDUMP(MCMD_D, "wapi_ie", priv->wapi_ie,
|
|
priv->wapi_ie_len);
|
|
if (priv->wapi_ie[0] == WAPI_IE)
|
|
priv->sec_info.wapi_enabled = MTRUE;
|
|
} else {
|
|
memset(priv->adapter, priv->wapi_ie, 0, sizeof(priv->wapi_ie));
|
|
priv->wapi_ie_len = misc->param.gen_ie.len;
|
|
PRINTM(MINFO, "Reset wapi_ie_len=%d IE=%#x\n",
|
|
priv->wapi_ie_len, priv->wapi_ie[0]);
|
|
priv->sec_info.wapi_enabled = MFALSE;
|
|
}
|
|
|
|
/* Send request to firmware */
|
|
ret = wlan_prepare_cmd(priv, HOST_CMD_APCMD_SYS_CONFIGURE,
|
|
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set generic IE
|
|
*
|
|
* @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
|
|
*/
|
|
static mlan_status wlan_uap_misc_ioctl_gen_ie(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_misc_cfg *misc = MNULL;
|
|
IEEEtypes_VendorHeader_t *pvendor_ie = MNULL;
|
|
|
|
ENTER();
|
|
|
|
misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
|
|
|
|
if ((misc->param.gen_ie.type == MLAN_IE_TYPE_GEN_IE) &&
|
|
(pioctl_req->action == MLAN_ACT_SET)) {
|
|
if (misc->param.gen_ie.len) {
|
|
pvendor_ie = (IEEEtypes_VendorHeader_t *)
|
|
misc->param.gen_ie.ie_data;
|
|
if (pvendor_ie->element_id == WAPI_IE) {
|
|
/* IE is a WAPI IE so call set_wapi function */
|
|
ret = wlan_uap_set_wapi_ie(pmpriv, pioctl_req);
|
|
}
|
|
} else {
|
|
/* clear WAPI IE */
|
|
ret = wlan_uap_set_wapi_ie(pmpriv, pioctl_req);
|
|
}
|
|
}
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get WAPI status
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS --success
|
|
*/
|
|
static mlan_status wlan_uap_sec_ioctl_wapi_enable(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_sec_cfg *sec = MNULL;
|
|
ENTER();
|
|
sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
|
|
if (pioctl_req->action == MLAN_ACT_GET) {
|
|
if (pmpriv->wapi_ie_len)
|
|
sec->param.wapi_enabled = MTRUE;
|
|
else
|
|
sec->param.wapi_enabled = MFALSE;
|
|
} else {
|
|
if (sec->param.wapi_enabled == MFALSE) {
|
|
memset(pmpriv->adapter, pmpriv->wapi_ie, 0,
|
|
sizeof(pmpriv->wapi_ie));
|
|
pmpriv->wapi_ie_len = 0;
|
|
PRINTM(MINFO, "Reset wapi_ie_len=%d IE=%#x\n",
|
|
pmpriv->wapi_ie_len, pmpriv->wapi_ie[0]);
|
|
pmpriv->sec_info.wapi_enabled = MFALSE;
|
|
}
|
|
}
|
|
pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief report mic error
|
|
*
|
|
* @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_uap_sec_ioctl_report_mic_error(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_sec_cfg *sec = MNULL;
|
|
|
|
ENTER();
|
|
|
|
sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_REPORT_MIC,
|
|
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
|
|
(t_void *)sec->param.sta_mac);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set encrypt key
|
|
*
|
|
* @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
|
|
*/
|
|
static mlan_status
|
|
wlan_uap_sec_ioctl_set_encrypt_key(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_sec_cfg *sec = MNULL;
|
|
|
|
ENTER();
|
|
sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
|
|
if (pioctl_req->action != MLAN_ACT_SET) {
|
|
pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
|
|
LEAVE();
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
if (!sec->param.encrypt_key.key_remove &&
|
|
!sec->param.encrypt_key.key_len) {
|
|
PRINTM(MCMND, "Skip set key with key_len = 0\n");
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
|
|
HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
|
|
(t_void *)pioctl_req, &sec->param.encrypt_key);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Get BSS information
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS --success
|
|
*/
|
|
static mlan_status wlan_uap_get_bss_info(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_ds_get_info *info;
|
|
|
|
ENTER();
|
|
|
|
info = (mlan_ds_get_info *)pioctl_req->pbuf;
|
|
/* Connection status */
|
|
info->param.bss_info.media_connected = pmpriv->media_connected;
|
|
|
|
/* Radio status */
|
|
info->param.bss_info.radio_on = pmadapter->radio_on;
|
|
|
|
/* BSSID */
|
|
memcpy_ext(pmadapter, &info->param.bss_info.bssid, pmpriv->curr_addr,
|
|
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
|
|
info->param.bss_info.scan_block = pmadapter->scan_block;
|
|
|
|
info->param.bss_info.is_hs_configured = pmadapter->is_hs_configured;
|
|
info->param.bss_info.is_11h_active =
|
|
pmpriv->intf_state_11h.is_11h_active;
|
|
info->param.bss_info.dfs_check_channel =
|
|
pmpriv->adapter->state_dfs.dfs_check_channel;
|
|
pioctl_req->data_read_written =
|
|
sizeof(mlan_bss_info) + MLAN_SUB_COMMAND_SIZE;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set Host Sleep configurations
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_SUCCES/MLAN_STATUS_PENDING --success,
|
|
* otherwise fail
|
|
*/
|
|
static mlan_status wlan_uap_pm_ioctl_deepsleep(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_pm_cfg *pm = MNULL;
|
|
mlan_ds_auto_ds auto_ds;
|
|
t_u32 mode;
|
|
|
|
ENTER();
|
|
|
|
if (pioctl_req->buf_len < sizeof(mlan_ds_pm_cfg)) {
|
|
PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
pioctl_req->buf_len_needed = sizeof(mlan_ds_pm_cfg);
|
|
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
|
|
LEAVE();
|
|
return MLAN_STATUS_RESOURCE;
|
|
}
|
|
pm = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
|
|
|
|
if (pioctl_req->action == MLAN_ACT_GET) {
|
|
if (pmadapter->is_deep_sleep) {
|
|
pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_ON;
|
|
pm->param.auto_deep_sleep.idletime =
|
|
pmadapter->idle_time;
|
|
} else
|
|
pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_OFF;
|
|
} else {
|
|
if (pmadapter->is_deep_sleep &&
|
|
pm->param.auto_deep_sleep.auto_ds == DEEP_SLEEP_ON) {
|
|
PRINTM(MMSG, "uAP already in deep sleep mode\n");
|
|
LEAVE();
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
if (((mlan_ds_pm_cfg *)pioctl_req->pbuf)
|
|
->param.auto_deep_sleep.auto_ds == DEEP_SLEEP_ON) {
|
|
auto_ds.auto_ds = DEEP_SLEEP_ON;
|
|
mode = EN_AUTO_PS;
|
|
PRINTM(MINFO, "Auto Deep Sleep: on\n");
|
|
} else {
|
|
mode = DIS_AUTO_PS;
|
|
auto_ds.auto_ds = DEEP_SLEEP_OFF;
|
|
PRINTM(MINFO, "Auto Deep Sleep: off\n");
|
|
}
|
|
if (((mlan_ds_pm_cfg *)pioctl_req->pbuf)
|
|
->param.auto_deep_sleep.idletime)
|
|
auto_ds.idletime =
|
|
((mlan_ds_pm_cfg *)pioctl_req->pbuf)
|
|
->param.auto_deep_sleep.idletime;
|
|
else
|
|
auto_ds.idletime = pmadapter->idle_time;
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_PS_MODE_ENH,
|
|
(t_u16)mode, BITMAP_AUTO_DS,
|
|
(t_void *)pioctl_req, &auto_ds);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
}
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set Band Steering configurations
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_SUCCES/MLAN_STATUS_PENDING --success,
|
|
* otherwise fail
|
|
*/
|
|
static mlan_status wlan_misc_band_steering_cfg(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_misc_cfg *pm = MNULL;
|
|
|
|
ENTER();
|
|
|
|
if (pioctl_req->buf_len < sizeof(mlan_ds_band_steer_cfg)) {
|
|
PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
pioctl_req->buf_len_needed = sizeof(mlan_ds_band_steer_cfg);
|
|
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
|
|
LEAVE();
|
|
return MLAN_STATUS_RESOURCE;
|
|
}
|
|
pm = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_BAND_STEERING,
|
|
(t_u16)pm->param.band_steer_cfg.action, 0,
|
|
(t_void *)pioctl_req,
|
|
(t_void *)&pm->param.band_steer_cfg);
|
|
LEAVE();
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set Beacon Stuck Detect Mechanism Configurations
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_SUCCES/MLAN_STATUS_PENDING --success,
|
|
* otherwise fail
|
|
*/
|
|
static mlan_status wlan_misc_beacon_stuck_cfg(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];
|
|
mlan_ds_misc_cfg *pm = MNULL;
|
|
|
|
ENTER();
|
|
|
|
if (pioctl_req->buf_len < sizeof(mlan_ds_beacon_stuck_param_cfg)) {
|
|
PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
pioctl_req->buf_len_needed =
|
|
sizeof(mlan_ds_beacon_stuck_param_cfg);
|
|
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
|
|
LEAVE();
|
|
return MLAN_STATUS_RESOURCE;
|
|
}
|
|
pm = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_UAP_BEACON_STUCK_CFG,
|
|
(t_u16)pm->param.beacon_stuck_cfg.action, 0,
|
|
(t_void *)pioctl_req,
|
|
(t_void *)&pm->param.beacon_stuck_cfg);
|
|
|
|
LEAVE();
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set SNMP MIB for 11D
|
|
*
|
|
* @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_uap_snmp_mib_11d(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_snmp_mib *snmp = MNULL;
|
|
state_11d_t flag;
|
|
|
|
ENTER();
|
|
|
|
if (pioctl_req->buf_len < sizeof(mlan_ds_snmp_mib)) {
|
|
PRINTM(MWARN, "MLAN snmp_mib IOCTL length is too short.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
pioctl_req->buf_len_needed = sizeof(mlan_ds_snmp_mib);
|
|
LEAVE();
|
|
return MLAN_STATUS_RESOURCE;
|
|
}
|
|
|
|
if ((pioctl_req->action == MLAN_ACT_SET) && pmpriv->uap_bss_started) {
|
|
PRINTM(MIOCTL,
|
|
"11D setting cannot be changed while UAP bss is started.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
LEAVE();
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
snmp = (mlan_ds_snmp_mib *)pioctl_req->pbuf;
|
|
flag = (snmp->param.oid_value) ? ENABLE_11D : DISABLE_11D;
|
|
|
|
ret = wlan_11d_enable(pmpriv, (t_void *)pioctl_req, flag);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Callback to finish domain_info handling
|
|
* Not to be called directly to initiate domain_info setting.
|
|
*
|
|
* @param pmpriv A pointer to mlan_private structure (cast from t_void*)
|
|
*
|
|
* @return MLAN_STATUS_PENDING --success, otherwise fail
|
|
* @sa wlan_uap_domain_info
|
|
*/
|
|
static mlan_status wlan_uap_callback_domain_info(t_void *priv)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = (mlan_private *)priv;
|
|
wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb;
|
|
mlan_ds_11d_cfg *cfg11d;
|
|
t_u8 band;
|
|
pmlan_adapter pmadapter = pmpriv->adapter;
|
|
pmlan_callbacks pcb = &pmadapter->callbacks;
|
|
|
|
ENTER();
|
|
/* clear callback now that we're here */
|
|
puap_state_chan_cb->get_chan_callback = MNULL;
|
|
|
|
if (!puap_state_chan_cb->pioctl_req_curr) {
|
|
PRINTM(MERROR, "pioctl_req_curr is null\n");
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
cfg11d = (mlan_ds_11d_cfg *)puap_state_chan_cb->pioctl_req_curr->pbuf;
|
|
band = (puap_state_chan_cb->bandcfg.chanBand == BAND_5GHZ) ? BAND_A :
|
|
BAND_B;
|
|
|
|
ret = wlan_11d_handle_uap_domain_info(
|
|
pmpriv, band, cfg11d->param.domain_tlv,
|
|
puap_state_chan_cb->pioctl_req_curr);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
else {
|
|
puap_state_chan_cb->pioctl_req_curr->status_code =
|
|
MLAN_STATUS_FAILURE;
|
|
pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
|
|
puap_state_chan_cb->pioctl_req_curr,
|
|
MLAN_STATUS_FAILURE);
|
|
}
|
|
|
|
puap_state_chan_cb->pioctl_req_curr = MNULL; /* prevent re-use */
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set Domain Info for 11D
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_PENDING --success, otherwise fail
|
|
* @sa wlan_uap_callback_domain_info
|
|
*/
|
|
static mlan_status wlan_uap_domain_info(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
|
|
ENTER();
|
|
|
|
if (pioctl_req->buf_len < sizeof(mlan_ds_11d_cfg)) {
|
|
PRINTM(MWARN, "MLAN 11d_cfg IOCTL length is too short.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
pioctl_req->buf_len_needed = sizeof(mlan_ds_11d_cfg);
|
|
LEAVE();
|
|
return MLAN_STATUS_RESOURCE;
|
|
}
|
|
|
|
if ((pioctl_req->action == MLAN_ACT_SET) && pmpriv->uap_bss_started) {
|
|
PRINTM(MIOCTL,
|
|
"Domain_info cannot be changed while UAP bss is started.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
LEAVE();
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* store params, issue command to get UAP channel, whose CMD_RESP will
|
|
* callback remainder of domain_info handling */
|
|
pmpriv->uap_state_chan_cb.pioctl_req_curr = pioctl_req;
|
|
pmpriv->uap_state_chan_cb.get_chan_callback =
|
|
wlan_uap_callback_domain_info;
|
|
|
|
ret = wlan_uap_get_channel(pmpriv);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Callback to finish 11H channel check handling.
|
|
* Not to be called directly to initiate channel check.
|
|
*
|
|
* @param priv A pointer to mlan_private structure (cast from t_void*)
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS/PENDING --success, otherwise fail
|
|
* @sa wlan_uap_11h_channel_check_req
|
|
*/
|
|
static mlan_status wlan_uap_callback_11h_channel_check_req(t_void *priv)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_FAILURE;
|
|
mlan_private *pmpriv = (mlan_private *)priv;
|
|
mlan_callbacks *pcb = (mlan_callbacks *)&pmpriv->adapter->callbacks;
|
|
wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb;
|
|
Band_Config_t *pband_cfg = &puap_state_chan_cb->bandcfg;
|
|
/* keep copy as local variable */
|
|
pmlan_ioctl_req pioctl = puap_state_chan_cb->pioctl_req_curr;
|
|
ENTER();
|
|
/* clear callback now that we're here */
|
|
puap_state_chan_cb->get_chan_callback = MNULL;
|
|
/* clear early to avoid race condition */
|
|
puap_state_chan_cb->pioctl_req_curr = MNULL;
|
|
|
|
/*
|
|
* Check if the region and channel requires a channel availability
|
|
* check.
|
|
*/
|
|
if ((puap_state_chan_cb->bandcfg.chanBand == BAND_5GHZ) &&
|
|
!wlan_can_radar_det_skip(pmpriv) &&
|
|
wlan_11h_radar_detect_required(pmpriv,
|
|
puap_state_chan_cb->channel) &&
|
|
!wlan_11h_is_channel_under_nop(pmpriv->adapter,
|
|
puap_state_chan_cb->channel)) {
|
|
/*
|
|
* Radar detection is required for this channel, make sure
|
|
* 11h is activated in the firmware
|
|
*/
|
|
ret = wlan_11h_activate(pmpriv, MNULL, MTRUE);
|
|
ret = wlan_11h_config_master_radar_det(pmpriv, MTRUE);
|
|
ret = wlan_11h_check_update_radar_det_state(pmpriv);
|
|
|
|
/* Check for radar on the channel */
|
|
ret = wlan_11h_issue_radar_detect(pmpriv, pioctl,
|
|
puap_state_chan_cb->channel,
|
|
*pband_cfg);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
} else {
|
|
/* No command sent with the ioctl, need manually signal
|
|
* completion */
|
|
pcb->moal_ioctl_complete(pmpriv->adapter->pmoal_handle, pioctl,
|
|
MLAN_STATUS_COMPLETE);
|
|
}
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief 802.11h uap start channel check
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_PENDING --success, otherwise fail
|
|
* @sa wlan_uap_callback_11h_channel_check_req
|
|
*/
|
|
static mlan_status wlan_uap_11h_channel_check_req(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_11h_cfg *p11h_cfg;
|
|
|
|
ENTER();
|
|
|
|
if (pioctl_req->buf_len < sizeof(mlan_ds_11h_cfg)) {
|
|
PRINTM(MWARN, "MLAN 11h_cfg IOCTL length is too short.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
pioctl_req->buf_len_needed = sizeof(mlan_ds_11h_cfg);
|
|
LEAVE();
|
|
return MLAN_STATUS_RESOURCE;
|
|
}
|
|
p11h_cfg = (mlan_ds_11h_cfg *)pioctl_req->pbuf;
|
|
pmpriv->intf_state_11h.is_11h_host =
|
|
p11h_cfg->param.chan_rpt_req.host_based;
|
|
|
|
if (!pmpriv->intf_state_11h.is_11h_host) {
|
|
/* store params, issue command to get UAP channel, whose
|
|
* CMD_RESP will callback remainder of 11H channel check
|
|
* handling */
|
|
pmpriv->uap_state_chan_cb.pioctl_req_curr = pioctl_req;
|
|
pmpriv->uap_state_chan_cb.get_chan_callback =
|
|
wlan_uap_callback_11h_channel_check_req;
|
|
|
|
ret = wlan_uap_get_channel(pmpriv);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
} else {
|
|
if (!wlan_11h_is_active(pmpriv)) {
|
|
/* active 11h extention in Fw */
|
|
ret = wlan_11h_activate(pmpriv, MNULL, MTRUE);
|
|
ret = wlan_11h_config_master_radar_det(pmpriv, MTRUE);
|
|
ret = wlan_11h_check_update_radar_det_state(pmpriv);
|
|
}
|
|
if (p11h_cfg->param.chan_rpt_req.millisec_dwell_time) {
|
|
if (pmpriv->adapter->dfs_test_params
|
|
.user_cac_period_msec) {
|
|
PRINTM(MCMD_D,
|
|
"cfg80211 dfs_testing - user CAC period=%d (msec)\n",
|
|
pmpriv->adapter->dfs_test_params
|
|
.user_cac_period_msec);
|
|
p11h_cfg->param.chan_rpt_req
|
|
.millisec_dwell_time =
|
|
pmpriv->adapter->dfs_test_params
|
|
.user_cac_period_msec;
|
|
}
|
|
ret = wlan_prepare_cmd(
|
|
pmpriv, HostCmd_CMD_CHAN_REPORT_REQUEST,
|
|
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
|
|
(t_void *)&p11h_cfg->param.chan_rpt_req);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
}
|
|
}
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Callback to finish 11H handling
|
|
* Not to be called directly to initiate 11H setting.
|
|
*
|
|
* @param pmpriv A pointer to mlan_private structure (cast from t_void*)
|
|
*
|
|
* @return MLAN_STATUS_PENDING --success, otherwise fail
|
|
* @sa wlan_uap_snmp_mib_11h
|
|
*/
|
|
static mlan_status wlan_uap_callback_snmp_mib_11h(t_void *priv)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = (mlan_private *)priv;
|
|
wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb;
|
|
mlan_callbacks *pcb = (mlan_callbacks *)&pmpriv->adapter->callbacks;
|
|
mlan_ds_snmp_mib *snmp;
|
|
t_bool enable_11h;
|
|
|
|
ENTER();
|
|
/* clear callback now that we're here */
|
|
puap_state_chan_cb->get_chan_callback = MNULL;
|
|
|
|
snmp = (mlan_ds_snmp_mib *)puap_state_chan_cb->pioctl_req_curr->pbuf;
|
|
enable_11h = (snmp->param.oid_value) ? MTRUE : MFALSE;
|
|
|
|
if (enable_11h) {
|
|
if ((puap_state_chan_cb->bandcfg.chanBand == BAND_5GHZ) &&
|
|
!wlan_can_radar_det_skip(pmpriv) &&
|
|
wlan_11h_radar_detect_required(
|
|
pmpriv, puap_state_chan_cb->channel)) {
|
|
if (!wlan_11h_is_master_radar_det_active(pmpriv))
|
|
wlan_11h_config_master_radar_det(pmpriv, MTRUE);
|
|
} else {
|
|
puap_state_chan_cb->pioctl_req_curr->status_code =
|
|
MLAN_STATUS_SUCCESS;
|
|
pcb->moal_ioctl_complete(
|
|
pmpriv->adapter->pmoal_handle,
|
|
puap_state_chan_cb->pioctl_req_curr,
|
|
MLAN_STATUS_SUCCESS);
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
ret = wlan_11h_activate(pmpriv,
|
|
(t_void *)puap_state_chan_cb->pioctl_req_curr,
|
|
enable_11h);
|
|
wlan_11h_check_update_radar_det_state(pmpriv);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
done:
|
|
puap_state_chan_cb->pioctl_req_curr = MNULL; /* prevent re-use */
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set SNMP MIB for 11H
|
|
*
|
|
* @param pmadapter A pointer to mlan_adapter structure
|
|
* @param pioctl_req A pointer to ioctl request buffer
|
|
*
|
|
* @return MLAN_STATUS_PENDING --success, otherwise fail
|
|
* @sa wlan_uap_callback_snmp_mib_11h
|
|
*/
|
|
static mlan_status wlan_uap_snmp_mib_11h(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_ds_snmp_mib *snmp = MNULL;
|
|
t_bool enable;
|
|
|
|
ENTER();
|
|
|
|
if (pioctl_req->buf_len < sizeof(mlan_ds_snmp_mib)) {
|
|
PRINTM(MWARN, "MLAN snmp_mib IOCTL length is too short.\n");
|
|
pioctl_req->data_read_written = 0;
|
|
pioctl_req->buf_len_needed = sizeof(mlan_ds_snmp_mib);
|
|
LEAVE();
|
|
return MLAN_STATUS_RESOURCE;
|
|
}
|
|
snmp = (mlan_ds_snmp_mib *)pioctl_req->pbuf;
|
|
enable = (snmp->param.oid_value) ? MTRUE : MFALSE;
|
|
|
|
if (enable) {
|
|
/* first enable 11D if it is not enabled */
|
|
if (!wlan_fw_11d_is_enabled(pmpriv)) {
|
|
ret = wlan_11d_enable(pmpriv, MNULL, ENABLE_11D);
|
|
if (ret != MLAN_STATUS_SUCCESS) {
|
|
PRINTM(MERROR,
|
|
"Failed to first enable 11D before enabling 11H.\n");
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* store params, issue command to get UAP channel, whose CMD_RESP will
|
|
* callback remainder of 11H handling (and radar detect if DFS chan) */
|
|
pmpriv->uap_state_chan_cb.pioctl_req_curr = pioctl_req;
|
|
pmpriv->uap_state_chan_cb.get_chan_callback =
|
|
wlan_uap_callback_snmp_mib_11h;
|
|
|
|
ret = wlan_uap_get_channel(pmpriv);
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief ACS scan
|
|
*
|
|
* @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_uap_bss_ioctl_acs_scan(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
if (pmadapter->uap_fw_ver < UAP_FW_VERSION_2) {
|
|
PRINTM(MIOCTL, "FW don't support ACS SCAN API\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
/* Send request to firmware */
|
|
ret = wlan_prepare_cmd(pmpriv, HostCMD_APCMD_ACS_SCAN,
|
|
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
|
|
MNULL);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/********************************************************
|
|
Global Functions
|
|
********************************************************/
|
|
|
|
/**
|
|
* @brief Issue CMD to UAP firmware to get current channel
|
|
*
|
|
* @param pmpriv A pointer to mlan_private structure
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS --success, otherwise fail
|
|
*/
|
|
mlan_status wlan_uap_get_channel(pmlan_private pmpriv)
|
|
{
|
|
MrvlIEtypes_channel_band_t tlv_chan_band;
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
memset(pmpriv->adapter, &tlv_chan_band, 0, sizeof(tlv_chan_band));
|
|
tlv_chan_band.header.type = TLV_TYPE_UAP_CHAN_BAND_CONFIG;
|
|
tlv_chan_band.header.len = sizeof(MrvlIEtypes_channel_band_t) -
|
|
sizeof(MrvlIEtypesHeader_t);
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE,
|
|
HostCmd_ACT_GEN_GET, 0, MNULL, &tlv_chan_band);
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Issue CMD to UAP firmware to set current channel
|
|
*
|
|
* @param pmpriv A pointer to mlan_private structure
|
|
* @param uap_band_cfg UAP band configuration
|
|
* @param channel New channel
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS --success, otherwise fail
|
|
*/
|
|
mlan_status wlan_uap_set_channel(pmlan_private pmpriv,
|
|
Band_Config_t uap_band_cfg, t_u8 channel)
|
|
{
|
|
MrvlIEtypes_channel_band_t tlv_chan_band;
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
memset(pmpriv->adapter, &tlv_chan_band, 0, sizeof(tlv_chan_band));
|
|
tlv_chan_band.header.type = TLV_TYPE_UAP_CHAN_BAND_CONFIG;
|
|
tlv_chan_band.header.len = sizeof(MrvlIEtypes_channel_band_t) -
|
|
sizeof(MrvlIEtypesHeader_t);
|
|
tlv_chan_band.bandcfg = uap_band_cfg;
|
|
tlv_chan_band.channel = channel;
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE,
|
|
HostCmd_ACT_GEN_SET, 0, MNULL, &tlv_chan_band);
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Issue CMD to UAP firmware to get current beacon and dtim periods
|
|
*
|
|
* @param pmpriv A pointer to mlan_private structure
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS --success, otherwise fail
|
|
*/
|
|
mlan_status wlan_uap_get_beacon_dtim(pmlan_private pmpriv)
|
|
{
|
|
t_u8 tlv_buffer[sizeof(MrvlIEtypes_beacon_period_t) +
|
|
sizeof(MrvlIEtypes_dtim_period_t)];
|
|
MrvlIEtypes_beacon_period_t *ptlv_beacon_pd;
|
|
MrvlIEtypes_dtim_period_t *ptlv_dtim_pd;
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
|
|
ENTER();
|
|
|
|
memset(pmpriv->adapter, &tlv_buffer, 0, sizeof(tlv_buffer));
|
|
ptlv_beacon_pd = (MrvlIEtypes_beacon_period_t *)tlv_buffer;
|
|
ptlv_beacon_pd->header.type = TLV_TYPE_UAP_BEACON_PERIOD;
|
|
ptlv_beacon_pd->header.len = sizeof(MrvlIEtypes_beacon_period_t) -
|
|
sizeof(MrvlIEtypesHeader_t);
|
|
|
|
ptlv_dtim_pd =
|
|
(MrvlIEtypes_dtim_period_t
|
|
*)(tlv_buffer + sizeof(MrvlIEtypes_beacon_period_t));
|
|
ptlv_dtim_pd->header.type = TLV_TYPE_UAP_DTIM_PERIOD;
|
|
ptlv_dtim_pd->header.len =
|
|
sizeof(MrvlIEtypes_dtim_period_t) - sizeof(MrvlIEtypesHeader_t);
|
|
|
|
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE,
|
|
HostCmd_ACT_GEN_GET, 0, MNULL, tlv_buffer);
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set/Get deauth control.
|
|
*
|
|
* @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_uap_snmp_mib_ctrl_deauth(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req)
|
|
{
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
mlan_status ret = MLAN_STATUS_SUCCESS;
|
|
mlan_ds_snmp_mib *mib = (mlan_ds_snmp_mib *)pioctl_req->pbuf;
|
|
t_u16 cmd_action = 0;
|
|
|
|
ENTER();
|
|
|
|
mib = (mlan_ds_snmp_mib *)pioctl_req->pbuf;
|
|
if (pioctl_req->action == MLAN_ACT_SET) {
|
|
cmd_action = HostCmd_ACT_GEN_SET;
|
|
} else {
|
|
cmd_action = HostCmd_ACT_GEN_GET;
|
|
}
|
|
|
|
/* Send command to firmware */
|
|
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SNMP_MIB, cmd_action,
|
|
StopDeauth_i, (t_void *)pioctl_req,
|
|
&mib->param.deauthctrl);
|
|
|
|
if (ret == MLAN_STATUS_SUCCESS)
|
|
ret = MLAN_STATUS_PENDING;
|
|
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief MLAN uap ioctl handler
|
|
*
|
|
* @param adapter 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_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
|
|
{
|
|
pmlan_adapter pmadapter = (pmlan_adapter)adapter;
|
|
mlan_status status = MLAN_STATUS_SUCCESS;
|
|
mlan_ds_bss *bss = MNULL;
|
|
mlan_ds_get_info *pget_info = MNULL;
|
|
mlan_ds_misc_cfg *misc = MNULL;
|
|
mlan_ds_sec_cfg *sec = MNULL;
|
|
mlan_ds_power_cfg *power = MNULL;
|
|
mlan_ds_pm_cfg *pm = MNULL;
|
|
mlan_ds_11d_cfg *cfg11d = MNULL;
|
|
mlan_ds_snmp_mib *snmp = MNULL;
|
|
mlan_ds_11h_cfg *cfg11h = MNULL;
|
|
mlan_ds_radio_cfg *radiocfg = MNULL;
|
|
mlan_ds_rate *rate = MNULL;
|
|
mlan_ds_reg_mem *reg_mem = MNULL;
|
|
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
|
|
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
|
|
pmlan_ds_scan pscan;
|
|
#endif
|
|
|
|
ENTER();
|
|
switch (pioctl_req->req_id) {
|
|
case MLAN_IOCTL_BSS:
|
|
bss = (mlan_ds_bss *)pioctl_req->pbuf;
|
|
if (bss->sub_command == MLAN_OID_BSS_MAC_ADDR)
|
|
status = wlan_uap_bss_ioctl_mac_address(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_BSS_STOP)
|
|
status = wlan_uap_bss_ioctl_stop(pmadapter, pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_BSS_START)
|
|
status =
|
|
wlan_uap_bss_ioctl_start(pmadapter, pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_BSS_CONFIG)
|
|
status = wlan_uap_bss_ioctl_config(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_DEAUTH_STA)
|
|
status = wlan_uap_bss_ioctl_deauth_sta(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_BSS_RESET)
|
|
status =
|
|
wlan_uap_bss_ioctl_reset(pmadapter, pioctl_req);
|
|
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
|
|
else if (bss->sub_command == MLAN_OID_BSS_ROLE) {
|
|
util_enqueue_list_tail(
|
|
pmadapter->pmoal_handle,
|
|
&pmadapter->ioctl_pending_q,
|
|
(pmlan_linked_list)pioctl_req,
|
|
pmadapter->callbacks.moal_spin_lock,
|
|
pmadapter->callbacks.moal_spin_unlock);
|
|
pmadapter->pending_ioctl = MTRUE;
|
|
status = MLAN_STATUS_PENDING;
|
|
}
|
|
#endif
|
|
#ifdef WIFI_DIRECT_SUPPORT
|
|
else if (bss->sub_command == MLAN_OID_WIFI_DIRECT_MODE)
|
|
status = wlan_bss_ioctl_wifi_direct_mode(pmadapter,
|
|
pioctl_req);
|
|
#endif
|
|
else if (bss->sub_command == MLAN_OID_BSS_REMOVE)
|
|
status = wlan_bss_ioctl_bss_remove(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_CFG_WMM_PARAM)
|
|
status = wlan_uap_bss_ioctl_uap_wmm_param(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_SCAN_CHANNELS)
|
|
status = wlan_uap_bss_ioctl_uap_scan_channels(
|
|
pmadapter, pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_CHANNEL)
|
|
status = wlan_uap_bss_ioctl_uap_channel(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_ACS_SCAN)
|
|
status = wlan_uap_bss_ioctl_acs_scan(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_OPER_CTRL)
|
|
status = wlan_uap_bss_ioctl_uap_oper_ctrl(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_UAP_ADD_STATION)
|
|
status = wlan_uap_bss_ioctl_add_station(pmadapter,
|
|
pioctl_req);
|
|
else if (bss->sub_command == MLAN_OID_ACTION_CHAN_SWITCH)
|
|
status = wlan_uap_bss_ioctl_action_chan_switch(
|
|
pmadapter, pioctl_req);
|
|
break;
|
|
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
|
|
case MLAN_IOCTL_SCAN:
|
|
pscan = (mlan_ds_scan *)pioctl_req->pbuf;
|
|
if ((pscan->sub_command == MLAN_OID_SCAN_NORMAL) &&
|
|
(pioctl_req->action == MLAN_ACT_GET)) {
|
|
PRINTM(MIOCTL, "Get scan table in uap\n");
|
|
pscan->param.scan_resp.pscan_table =
|
|
(t_u8 *)pmadapter->pscan_table;
|
|
pscan->param.scan_resp.num_in_scan_table =
|
|
pmadapter->num_in_scan_table;
|
|
pscan->param.scan_resp.age_in_secs =
|
|
pmadapter->age_in_secs;
|
|
pioctl_req->data_read_written =
|
|
sizeof(mlan_scan_resp) + MLAN_SUB_COMMAND_SIZE;
|
|
pscan->param.scan_resp.pchan_stats =
|
|
(t_u8 *)pmadapter->pchan_stats;
|
|
pscan->param.scan_resp.num_in_chan_stats =
|
|
pmadapter->num_in_chan_stats;
|
|
}
|
|
break;
|
|
#endif
|
|
case MLAN_IOCTL_GET_INFO:
|
|
pget_info = (mlan_ds_get_info *)pioctl_req->pbuf;
|
|
if (pget_info->sub_command == MLAN_OID_GET_VER_EXT)
|
|
status = wlan_get_info_ver_ext(pmadapter, pioctl_req);
|
|
else if (pget_info->sub_command == MLAN_OID_GET_DEBUG_INFO)
|
|
status =
|
|
wlan_get_info_debug_info(pmadapter, pioctl_req);
|
|
else if (pget_info->sub_command == MLAN_OID_GET_STATS)
|
|
status = wlan_uap_get_stats(pmadapter, pioctl_req);
|
|
else if (pget_info->sub_command == MLAN_OID_GET_UAP_STATS_LOG)
|
|
status = wlan_uap_get_stats_log(pmadapter, pioctl_req);
|
|
else if (pget_info->sub_command == MLAN_OID_UAP_STA_LIST)
|
|
status = wlan_uap_get_sta_list(pmadapter, pioctl_req);
|
|
else if (pget_info->sub_command == MLAN_OID_GET_BSS_INFO)
|
|
status = wlan_uap_get_bss_info(pmadapter, pioctl_req);
|
|
else if (pget_info->sub_command == MLAN_OID_GET_FW_INFO) {
|
|
pioctl_req->data_read_written =
|
|
sizeof(mlan_fw_info) + MLAN_SUB_COMMAND_SIZE;
|
|
memcpy_ext(pmadapter,
|
|
&pget_info->param.fw_info.mac_addr,
|
|
pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH,
|
|
MLAN_MAC_ADDR_LENGTH);
|
|
pget_info->param.fw_info.fw_ver =
|
|
pmadapter->fw_release_number;
|
|
pget_info->param.fw_info.hotfix_version =
|
|
pmadapter->fw_hotfix_ver;
|
|
pget_info->param.fw_info.tx_buf_size =
|
|
pmadapter->tx_buf_size;
|
|
|
|
pget_info->param.fw_info.fw_bands = pmadapter->fw_bands;
|
|
pget_info->param.fw_info.ecsa_enable =
|
|
pmadapter->ecsa_enable;
|
|
pget_info->param.fw_info.getlog_enable =
|
|
pmadapter->getlog_enable;
|
|
pget_info->param.fw_info.hw_dev_mcs_support =
|
|
pmadapter->hw_dev_mcs_support;
|
|
pget_info->param.fw_info.hw_dot_11n_dev_cap =
|
|
pmadapter->hw_dot_11n_dev_cap;
|
|
pget_info->param.fw_info.usr_dev_mcs_support =
|
|
pmpriv->usr_dev_mcs_support;
|
|
if (IS_FW_SUPPORT_NO_80MHZ(pmadapter))
|
|
pget_info->param.fw_info.prohibit_80mhz = MTRUE;
|
|
else
|
|
pget_info->param.fw_info.prohibit_80mhz =
|
|
MFALSE;
|
|
pget_info->param.fw_info.hw_dot_11ac_mcs_support =
|
|
pmadapter->hw_dot_11ac_mcs_support;
|
|
pget_info->param.fw_info.hw_dot_11ac_dev_cap =
|
|
pmadapter->hw_dot_11ac_dev_cap;
|
|
pget_info->param.fw_info.usr_dot_11ac_dev_cap_bg =
|
|
pmpriv->usr_dot_11ac_dev_cap_bg;
|
|
pget_info->param.fw_info.usr_dot_11ac_mcs_support =
|
|
pmpriv->usr_dot_11ac_mcs_support;
|
|
pget_info->param.fw_info.usr_dot_11ac_dev_cap_a =
|
|
pmpriv->usr_dot_11ac_dev_cap_a;
|
|
pget_info->param.fw_info.hw_hecap_len =
|
|
pmadapter->hw_hecap_len;
|
|
pget_info->param.fw_info.hw_2g_hecap_len =
|
|
pmadapter->hw_2g_hecap_len;
|
|
memcpy_ext(pmadapter,
|
|
pget_info->param.fw_info.hw_he_cap,
|
|
pmadapter->hw_he_cap,
|
|
pmadapter->hw_hecap_len,
|
|
sizeof(pget_info->param.fw_info.hw_he_cap));
|
|
memcpy_ext(
|
|
pmadapter,
|
|
pget_info->param.fw_info.hw_2g_he_cap,
|
|
pmadapter->hw_2g_he_cap,
|
|
pmadapter->hw_2g_hecap_len,
|
|
sizeof(pget_info->param.fw_info.hw_2g_he_cap));
|
|
pget_info->param.fw_info.region_code =
|
|
pmadapter->region_code;
|
|
if (pmadapter->otp_region &&
|
|
pmadapter->otp_region->force_reg)
|
|
pget_info->param.fw_info.force_reg = MTRUE;
|
|
else
|
|
pget_info->param.fw_info.force_reg = MFALSE;
|
|
pget_info->param.fw_info.fw_supplicant_support =
|
|
IS_FW_SUPPORT_SUPPLICANT(pmadapter) ? 0x01 :
|
|
0x00;
|
|
pget_info->param.fw_info.antinfo = pmadapter->antinfo;
|
|
pget_info->param.fw_info.max_ap_assoc_sta =
|
|
pmadapter->max_sta_conn;
|
|
} else if (pget_info->sub_command == MLAN_OID_LINK_STATS)
|
|
status = wlan_ioctl_link_statistic(pmpriv, pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_MISC_CFG:
|
|
misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
|
|
if (misc->sub_command == MLAN_OID_MISC_INIT_SHUTDOWN)
|
|
status = wlan_misc_ioctl_init_shutdown(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_SOFT_RESET)
|
|
status = wlan_uap_misc_ioctl_soft_reset(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_HOST_CMD)
|
|
status =
|
|
wlan_misc_ioctl_host_cmd(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_REGION)
|
|
status = wlan_misc_ioctl_region(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_GEN_IE)
|
|
status = wlan_uap_misc_ioctl_gen_ie(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_CUSTOM_IE)
|
|
status = wlan_misc_ioctl_custom_ie_list(
|
|
pmadapter, pioctl_req, MTRUE);
|
|
if (misc->sub_command == MLAN_OID_MISC_TX_DATAPAUSE)
|
|
status = wlan_uap_misc_ioctl_txdatapause(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_RX_MGMT_IND)
|
|
status = wlan_reg_rx_mgmt_ind(pmadapter, pioctl_req);
|
|
#ifdef DEBUG_LEVEL1
|
|
if (misc->sub_command == MLAN_OID_MISC_DRVDBG)
|
|
status = wlan_set_drvdbg(pmadapter, pioctl_req);
|
|
#endif
|
|
|
|
if (misc->sub_command == MLAN_OID_MISC_TXCONTROL)
|
|
status = wlan_misc_ioctl_txcontrol(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_MAC_CONTROL)
|
|
status = wlan_misc_ioctl_mac_control(pmadapter,
|
|
pioctl_req);
|
|
#ifdef RX_PACKET_COALESCE
|
|
if (misc->sub_command == MLAN_OID_MISC_RX_PACKET_COALESCE)
|
|
status = wlan_misc_ioctl_rx_pkt_coalesce_config(
|
|
pmadapter, pioctl_req);
|
|
#endif
|
|
#ifdef WIFI_DIRECT_SUPPORT
|
|
if (misc->sub_command == MLAN_OID_MISC_WIFI_DIRECT_CONFIG)
|
|
status = wlan_misc_p2p_config(pmadapter, pioctl_req);
|
|
#endif
|
|
if (misc->sub_command == MLAN_OID_MISC_GPIO_TSF_LATCH)
|
|
status = wlan_misc_gpio_tsf_latch_config(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_GET_TSF_INFO)
|
|
status = wlan_misc_get_tsf_info(pmadapter, pioctl_req);
|
|
|
|
if (misc->sub_command == MLAN_OID_MISC_DFS_REAPTER_MODE) {
|
|
mlan_ds_misc_cfg *misc_cfg = MNULL;
|
|
|
|
misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
|
|
misc_cfg->param.dfs_repeater.mode =
|
|
pmadapter->dfs_repeater;
|
|
pioctl_req->data_read_written =
|
|
sizeof(mlan_ds_misc_dfs_repeater);
|
|
|
|
status = MLAN_STATUS_SUCCESS;
|
|
}
|
|
if (misc->sub_command == MLAN_OID_MISC_IND_RST_CFG)
|
|
status = wlan_misc_ioctl_ind_rst_cfg(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_GET_TSF)
|
|
status = wlan_misc_ioctl_get_tsf(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_GET_CHAN_REGION_CFG)
|
|
status = wlan_misc_chan_reg_cfg(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_OPER_CLASS_CHECK)
|
|
status = wlan_misc_ioctl_operclass_validation(
|
|
pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_OPER_CLASS)
|
|
status = wlan_misc_ioctl_oper_class(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_AGGR_CTRL)
|
|
status = wlan_misc_ioctl_aggr_ctrl(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_PER_PKT_CFG)
|
|
status = wlan_misc_per_pkt_cfg(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_FW_DUMP_EVENT)
|
|
status = wlan_misc_ioctl_fw_dump_event(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_RX_ABORT_CFG)
|
|
status = wlan_misc_ioctl_rxabortcfg(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_RX_ABORT_CFG_EXT)
|
|
status = wlan_misc_ioctl_rxabortcfg_ext(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_TX_AMPDU_PROT_MODE)
|
|
status = wlan_misc_ioctl_tx_ampdu_prot_mode(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_DOT11MC_UNASSOC_FTM_CFG)
|
|
status = wlan_misc_ioctl_dot11mc_unassoc_ftm_cfg(
|
|
pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_HAL_PHY_CFG)
|
|
status = wlan_misc_hal_phy_cfg(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_RATE_ADAPT_CFG)
|
|
status = wlan_misc_ioctl_rate_adapt_cfg(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_CCK_DESENSE_CFG)
|
|
status = wlan_misc_ioctl_cck_desense_cfg(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_ROBUSTCOEX)
|
|
status = wlan_misc_robustcoex(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_DMCS_CONFIG)
|
|
status = wlan_misc_dmcs_config(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_GET_TX_RX_HISTOGRAM)
|
|
status =
|
|
wlan_get_tx_rx_histogram(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_CFP_INFO)
|
|
status = wlan_get_cfpinfo(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_BOOT_SLEEP)
|
|
status = wlan_misc_bootsleep(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_DYN_BW)
|
|
status = wlan_misc_ioctl_dyn_bw(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_GET_CHAN_TRPC_CFG)
|
|
status = wlan_get_chan_trpc_cfg(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_BAND_STEERING)
|
|
status = wlan_misc_band_steering_cfg(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_BEACON_STUCK)
|
|
status = wlan_misc_beacon_stuck_cfg(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_GET_REGIONPWR_CFG)
|
|
status = wlan_get_rgchnpwr_cfg(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_CFP_TABLE)
|
|
status = wlan_get_cfp_table(pmadapter, pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_RANGE_EXT)
|
|
status = wlan_misc_ioctl_range_ext(pmadapter,
|
|
pioctl_req);
|
|
if (misc->sub_command == MLAN_OID_MISC_WACP_MODE)
|
|
status = wlan_misc_ioctl_wacp_mode(pmadapter,
|
|
pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_POWER_CFG:
|
|
power = (mlan_ds_power_cfg *)pioctl_req->pbuf;
|
|
if (power->sub_command == MLAN_OID_POWER_LOW_POWER_MODE)
|
|
status = wlan_power_ioctl_set_get_lpm(pmadapter,
|
|
pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_PM_CFG:
|
|
pm = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
|
|
if (pm->sub_command == MLAN_OID_PM_CFG_PS_MODE)
|
|
status = wlan_uap_pm_ioctl_mode(pmadapter, pioctl_req);
|
|
if (pm->sub_command == MLAN_OID_PM_CFG_DEEP_SLEEP)
|
|
status = wlan_uap_pm_ioctl_deepsleep(pmadapter,
|
|
pioctl_req);
|
|
if (pm->sub_command == MLAN_OID_PM_CFG_HS_CFG)
|
|
status = wlan_pm_ioctl_hscfg(pmadapter, pioctl_req);
|
|
if (pm->sub_command == MLAN_OID_PM_HS_WAKEUP_REASON)
|
|
status = wlan_get_hs_wakeup_reason(pmadapter,
|
|
pioctl_req);
|
|
if (pm->sub_command == MLAN_OID_PM_MGMT_FILTER)
|
|
status = wlan_config_mgmt_filter(pmadapter, pioctl_req);
|
|
if (pm->sub_command == MLAN_OID_PM_INFO)
|
|
status = wlan_get_pm_info(pmadapter, pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_SNMP_MIB:
|
|
snmp = (mlan_ds_snmp_mib *)pioctl_req->pbuf;
|
|
if (snmp->sub_command == MLAN_OID_SNMP_MIB_CTRL_DEAUTH)
|
|
status = wlan_uap_snmp_mib_ctrl_deauth(pmadapter,
|
|
pioctl_req);
|
|
if (snmp->sub_command == MLAN_OID_SNMP_MIB_DOT11D)
|
|
status = wlan_uap_snmp_mib_11d(pmadapter, pioctl_req);
|
|
if (snmp->sub_command == MLAN_OID_SNMP_MIB_DOT11H)
|
|
status = wlan_uap_snmp_mib_11h(pmadapter, pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_SEC_CFG:
|
|
sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
|
|
if (sec->sub_command == MLAN_OID_SEC_CFG_ENCRYPT_KEY)
|
|
status = wlan_uap_sec_ioctl_set_encrypt_key(pmadapter,
|
|
pioctl_req);
|
|
if (sec->sub_command == MLAN_OID_SEC_CFG_WAPI_ENABLED)
|
|
status = wlan_uap_sec_ioctl_wapi_enable(pmadapter,
|
|
pioctl_req);
|
|
if (sec->sub_command == MLAN_OID_SEC_CFG_REPORT_MIC_ERR)
|
|
status = wlan_uap_sec_ioctl_report_mic_error(
|
|
pmadapter, pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_11N_CFG:
|
|
status = wlan_11n_cfg_ioctl(pmadapter, pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_11D_CFG:
|
|
cfg11d = (mlan_ds_11d_cfg *)pioctl_req->pbuf;
|
|
if (cfg11d->sub_command == MLAN_OID_11D_DOMAIN_INFO)
|
|
status = wlan_uap_domain_info(pmadapter, pioctl_req);
|
|
else if (cfg11d->sub_command == MLAN_OID_11D_DOMAIN_INFO_EXT)
|
|
status =
|
|
wlan_11d_cfg_domain_info(pmadapter, pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_11H_CFG:
|
|
cfg11h = (mlan_ds_11h_cfg *)pioctl_req->pbuf;
|
|
if (cfg11h->sub_command == MLAN_OID_11H_CHANNEL_CHECK)
|
|
status = wlan_uap_11h_channel_check_req(pmadapter,
|
|
pioctl_req);
|
|
if (cfg11h->sub_command == MLAN_OID_11H_DFS_TESTING)
|
|
status = wlan_11h_ioctl_dfs_testing(pmadapter,
|
|
pioctl_req);
|
|
if (cfg11h->sub_command == MLAN_OID_11H_CHAN_NOP_INFO)
|
|
status = wlan_11h_ioctl_channel_nop_info(pmadapter,
|
|
pioctl_req);
|
|
if (cfg11h->sub_command == MLAN_OID_11H_CHAN_REPORT_REQUEST)
|
|
status = wlan_11h_ioctl_dfs_chan_report(pmpriv,
|
|
pioctl_req);
|
|
if (cfg11h->sub_command == MLAN_OID_11H_CHAN_SWITCH_COUNT)
|
|
status = wlan_11h_ioctl_chan_switch_count(pmadapter,
|
|
pioctl_req);
|
|
if (cfg11h->sub_command == MLAN_OID_11H_DFS_W53_CFG)
|
|
status = wlan_11h_ioctl_dfs_w53_cfg(pmadapter,
|
|
pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_RADIO_CFG:
|
|
radiocfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
|
|
if (radiocfg->sub_command == MLAN_OID_MIMO_SWITCH)
|
|
status = wlan_radio_ioctl_mimo_switch_cfg(pmadapter,
|
|
pioctl_req);
|
|
if (radiocfg->sub_command == MLAN_OID_RADIO_CTRL)
|
|
status = wlan_radio_ioctl_radio_ctl(pmadapter,
|
|
pioctl_req);
|
|
if (radiocfg->sub_command == MLAN_OID_REMAIN_CHAN_CFG)
|
|
status = wlan_radio_ioctl_remain_chan_cfg(pmadapter,
|
|
pioctl_req);
|
|
if (radiocfg->sub_command == MLAN_OID_ANT_CFG)
|
|
status =
|
|
wlan_radio_ioctl_ant_cfg(pmadapter, pioctl_req);
|
|
if (radiocfg->sub_command == MLAN_OID_BAND_CFG)
|
|
status = wlan_radio_ioctl_band_cfg(pmadapter,
|
|
pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_RATE:
|
|
rate = (mlan_ds_rate *)pioctl_req->pbuf;
|
|
if (rate->sub_command == MLAN_OID_RATE_CFG)
|
|
status = wlan_rate_ioctl_cfg(pmadapter, pioctl_req);
|
|
else if (rate->sub_command == MLAN_OID_GET_DATA_RATE)
|
|
status = wlan_rate_ioctl_get_data_rate(pmadapter,
|
|
pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_11AC_CFG:
|
|
status = wlan_11ac_cfg_ioctl(pmadapter, pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_11AX_CFG:
|
|
status = wlan_11ax_cfg_ioctl(pmadapter, pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_REG_MEM:
|
|
reg_mem = (mlan_ds_reg_mem *)pioctl_req->pbuf;
|
|
if (reg_mem->sub_command == MLAN_OID_REG_RW)
|
|
status = wlan_reg_mem_ioctl_reg_rw(pmadapter,
|
|
pioctl_req);
|
|
else if (reg_mem->sub_command == MLAN_OID_EEPROM_RD)
|
|
status = wlan_reg_mem_ioctl_read_eeprom(pmadapter,
|
|
pioctl_req);
|
|
else if (reg_mem->sub_command == MLAN_OID_MEM_RW)
|
|
status = wlan_reg_mem_ioctl_mem_rw(pmadapter,
|
|
pioctl_req);
|
|
break;
|
|
case MLAN_IOCTL_WMM_CFG:
|
|
status = wlan_wmm_cfg_ioctl(pmadapter, pioctl_req);
|
|
break;
|
|
default:
|
|
pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
|
|
break;
|
|
}
|
|
LEAVE();
|
|
return status;
|
|
}
|