mxm_wifiex: update to mxm5x17368 release

Driver Bug Fixes:
-----------------
1. WCSWREL-357: WiFi crash when enable Android Global CFI configuration
2. WSW-23818: DUT setup DFS channel failed
3. WSW-20079: Tx RvR and TP Improvement
4. WSW-23330: Fix P2P-GO start failure post auto recovery
5. WSW-22914: Fixed WiFiHAL can't print hotfix release version

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
This commit is contained in:
Sherry Sun 2022-12-20 15:45:49 +08:00
parent d819b6d266
commit 9bbd4d8c52
56 changed files with 3618 additions and 717 deletions

View file

@ -87,7 +87,15 @@ CONFIG_OPENWRT_SUPPORT=n
# Big-endian platform
CONFIG_BIG_ENDIAN=n
#ifdef EMBEDDED_AUTH
# Enable driver based authenticator
CONFIG_DRV_EMBEDDED_AUTHENTICATOR=n
#endif
#ifdef EMBEDDED_SUPP
# Enable driver based supplicant
CONFIG_DRV_EMBEDDED_SUPPLICANT=n
#endif
ifeq ($(CONFIG_DRV_EMBEDDED_SUPPLICANT), y)
CONFIG_EMBEDDED_SUPP_AUTH=y
@ -105,6 +113,8 @@ CONFIG_SDIO_SUSPEND_RESUME=y
# DFS testing support
CONFIG_DFS_TESTING_SUPPORT=y
# Multi-channel support
CONFIG_MULTI_CHAN_SUPPORT=y
@ -126,6 +136,12 @@ ccflags-y += -DLINUX
#if defined(EMBEDDED_SUPP) || defined(EMBEDDED_AUTH)
ifeq ($(CONFIG_EMBEDDED_SUPP_AUTH), y)
ccflags-y += -I$(M)/mlan/esa
ccflags-y += -I$(M)/mlan/esa/common
endif
#endif
@ -208,6 +224,9 @@ ifeq ($(CONFIG_SDIO_SUSPEND_RESUME),y)
endif
#endif
ifeq ($(CONFIG_MULTI_CHAN_SUPPORT),y)
ccflags-y += -DMULTI_CHAN_SUPPORT
endif
ifeq ($(CONFIG_DFS_TESTING_SUPPORT),y)
ccflags-y += -DDFS_TESTING_SUPPORT
@ -480,7 +499,17 @@ endif
endif
#ifdef EMBEDDED_AUTH
ifeq ($(CONFIG_DRV_EMBEDDED_AUTHENTICATOR), y)
ccflags-y += -DDRV_EMBEDDED_AUTHENTICATOR
endif
#endif
#ifdef EMBEDDED_SUPP
ifeq ($(CONFIG_DRV_EMBEDDED_SUPPLICANT), y)
ccflags-y += -DDRV_EMBEDDED_SUPPLICANT
endif
#endif
MOALOBJS = mlinux/moal_main.o \
@ -560,9 +589,37 @@ endif
#if defined(EMBEDDED_SUPP) || defined(EMBEDDED_AUTH)
ifeq ($(CONFIG_EMBEDDED_SUPP_AUTH), y)
MLANOBJS += mlan/esa/common/crypto_api.o \
mlan/esa/common/aes_cmac_rom.o \
mlan/esa/common/crypt_new_rom.o \
mlan/esa/common/pmkCache.o \
mlan/esa/common/pmkCache_rom.o \
mlan/esa/common/parser.o \
mlan/esa/common/parser_rom.o \
mlan/esa/keyMgmtApStaCommon.o \
mlan/esa/hostsa_init.o \
mlan/esa/authenticator_api.o
endif
#endif
#ifdef EMBEDDED_SUPP
ifeq ($(CONFIG_DRV_EMBEDDED_SUPPLICANT),y)
MLANOBJS += mlan/esa/keyMgmtSta.o \
mlan/esa/keyMgmtSta_rom.o \
mlan/esa/supplicant.o
endif
#endif
#ifdef EMBEDDED_AUTH
ifeq ($(CONFIG_DRV_EMBEDDED_AUTHENTICATOR),y)
MLANOBJS += mlan/esa/AssocAp_srv_rom.o \
mlan/esa/keyMgmtAp_rom.o \
mlan/esa/keyMgmtAp.o
endif
#endif
obj-m := mlan.o
mlan-objs := $(MLANOBJS)

View file

@ -44,6 +44,9 @@
To load driver with MFG firmware file, use mfg_mode=1 when insmod WLAN driver and
specify MFG firmware name if needed.
To load driver with rf_test firmware file, use rf_test_mode=1 when insmod WLAN driver.
This parameter only used for 9177(FC)
There are some other parameters for debugging purpose etc. Use modinfo to check details.
drvdbg=<bit mask of driver debug message control>
dev_cap_mask=<Bit mask of the device capability>
@ -95,6 +98,7 @@
Bit 1: uAP WEXT
Bit 2: STA CFG80211
Bit 3: uAP CFG80211
cfg80211_drcs=1|0 <Enable DRCS support (default) | Disable DRCS support>
reg_alpha2=<Regulatory alpha2 (default NULL)>
skip_fwdnld=0|1 <enable FW download support (default) | disable FW download support>
wq_sched_prio: Priority for work queue
@ -126,6 +130,11 @@
GoAgeoutTime=0|x <use default ageout time (default) | set Go age out time xTU(TU 100ms)>
multi_dtim=0|x <use default DTIM interval(default) | set x*beacon_period as DTIM interval>
inact_tmo=0|x <use default IEEE ps inactivity timout value (default) | use IEEE ps inactivity timeout value x ms>
drcs_chantime_mode=0|x <channel time and mode for DRCS, use default value (default) | use setting value>
Bit31~Bit24:Channel time for channel index0;
Bit23~Bit16:mode for channel index0; 0|1 <PM1 | Null2Self>
Bit15~Bit8:Channel time for channel index1;
Bit7~Bit0:mode for channel index1; 0|1 <PM1 | Null2Self>
roamoffload_in_hs=0|1 <always enable fw roaming (default) | enable fw roaming only when host suspend>
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 64)
host_mlme=0|1 <Operate in non-host_mlme mode | Operate in host_mlme mode (default)>
@ -524,6 +533,7 @@ SYNOPSIS
mlanutl uapX clear_nop
mlanutl uapX nop_list
mlanutl uapX fake_radar
mlanutl uapX getchload <duration> [<cca_threshold>]
mlanutl uapX getchload <duration>
mlanutl dfsX dfs_cac <channel> [<bw> <cac-period>]
mlanutl dfsX autodfs <stop | start> [conf_file]
@ -611,7 +621,6 @@ SYNOPSIS
mlanutl mlanX mgmtframetx <mgmt_frame.conf>
mlanutl mlanX mpactrl [tx_ena] [rx_ena] [tx_size] [rx_size] [tx_ports] [rx_ports]
mlanutl mlanX netmon [<act> [<filter> <band> <chan> <opt>]]
mlanutl mlanX monitormode [l]
mlanutl mlanX offchannel [<l> <m> <n> <bandwidth>]
mlanutl mlanX otpuserdata <l>
mlanutl mlanX passphrase [l]
@ -691,6 +700,9 @@ SYNOPSIS
[AC_VI AIFSN ECW_MAX ECW_MIN TX_OP]
[AC_VO AIFSN ECW_MAX ECW_MIN TX_OP]
mlanutl mlanX wwscfg [m]
mlanutl mlanX mc_cfg [n]
mlanutl mlanX mc_policy [n]
mlanutl mlanX mc_cfg_ext [c] [s] [u] [m] <a> <b> <d> <e>
mlanutl p2pX cfg_noa [h] [i] [j] [k] [l]
mlanutl p2pX cfg_opp_ps [m] [n]
mlanutl mlanX get_sensor_temp
@ -1416,7 +1428,7 @@ htcapinfo
This command is used to config 11ax HE capability using command.
Usage:
mlanutl <mlanX|uapX> 11axcmd <subcmd> [value_1] [value_2]
mlanutl <mlanX|uapX> 11axcmd <subcmd> [value_1] [value_2] [value_3]
<subcmd = obss_pd_offset > : spatial reuse configuration
set obss_pd offset, [value_1] = NON_SRG_OffSET, [value_2] = SRG_OFFSET
@ -1439,12 +1451,21 @@ htcapinfo
Bit 0-9: TXOP RTS Threshold
<subcmd = tx_omi > : set/get omi value
used for OMI transmission in MAC header HTC+ field, please see 11ax spec for OMI definition
set OMI when [value_1 = <omi>], where <omi> is defined as:
Bit 0-2: Rx NSS
Bit 3-4: Channel Width
Bit 6 : Tx NSTS (applies to client mode only)
All other bits are not supported currently.
get OMI without value_1 and value_2
set OMI: [value_1 = <omi>] [value_2 = <tx_option>] [value_3 = <num_data_packeets>]
where
<omi> is defined as:
Bit 0-2: Rx NSS
Bit 3-4: Channel Width
Bit 6 : Tx NSTS (applies to client mode only)
All other bits are not supported currently.
<tx_option> is defined as:
0: OMI is transmitted in QoS NULL frame;
1: OMI is transmitted in QoS data frame;
0xFF: OMI is transmitted in both QoS NULL and QoS data frame.
<num_data_packeets> is applied only if OMI is sent in QoS data frame.
It specifies the number of consecutive data frames containing the OMI.
get OMI without any value
<subcmd = obssnbru_toltime> : set/get OBSS narrow band RU tolerance time value in seconds
set tolerance time when [value_1 = <time>], where <time> indicates:
@ -2111,12 +2132,13 @@ authtype
0: 802.11 open system authentication
1: 802.11 shared key authentication
3: 802.11 WPA3 SAE authentication
4: 802.11 OWE authentication
255: allow open system or shared key authentication (default)
Examples:
mlanutl mlan0 authtype 0 : use open system authentication
mlanutl mlan0 authtype 1 : use shared key authentication
mlanutl mlan0 authtype 255 : allow open system or shared key authentication
mlanutl mlan0 authtype 255 : allow WEP open system or shared key authentication, embedded supplicant WPA2/WPA3 roaming
mlanutl mlan0 authtype : get current setting
autotdls
@ -2457,15 +2479,19 @@ Usage:
mlanutl uap0 fake_radar : trigger fake rader event
getchload
This command gets the current channel load (in %), noise floor value (in dbm) and rx_quality (in %, higher % indicates better rx quality)
This command gets the current channel load (in %), noise floor value (in dbm) and rx_quality (in %, higher % indicates better rx quality)
This command also sets cca threhold value when provided and enables OFDM desense (Only for IW416)
Usage:
mlanutl uapX getchload <duration>
mlanutl uapX getchload <duration> [<cca_threshold>]
<duration> can be within 1-10(specifying 10ms to 100ms), default duration will be 100ms
[<cca_threshold>] can be within 1 to 120 and also sets OFDM desense (Only for IW416)
Examples:
mlanutl uap0 getchload : gets channel load (in %), noise floor (in dbm) and rx_quality (in %) for 100ms duration
mlanutl uap0 getchload 1 : gets channel load (in %), noise floor (in dbm) and rx_quality (in %) for 10ms duration
mlanutl uap0 getchload 6 : gets channel load (in %), noise floor (in dbm) and rx_quality (in %) for 60ms duration
mlanutl uap0 getchload 4 70 : gets channel load (in %), noise floor (in dbm) and rx_quality (in %) for 40ms duration
and sets cca threshold as -70dBm setting OFDM desense (Only for IW416)
dfs_repeater
This command is used to get/set DFS Repeater mode.
@ -3393,26 +3419,6 @@ netmon
management, control and data frame, band A/AN,
channel 64 and secondary channel above
monitormode
This command is used to set/get monitor mode.
Note: The enable monitor mode setting should be issued when no active interface exist.
Before we want to use sniffer mode, need enable monitor mode.
After this can only use sniffer mode, don't make STA/P2P/UAP work.
When sniffer mode using done, should disable monitor mode.
Usage:
mlanutl mlanX monitormode [l]
where the parameter:
[l]
0 : Disable monitor mode
1 : Enable monitor mode
<none>: Get monitor mode
Examples:
mlanutl mlan0 monitormode : Get monitor mode.
mlanutl mlan0 monitormode 1 : Enable monitor mode.
offchannel
This command is used to set/cancel the offchannel configuration.
Note: This command only can be used when cfg80211 is enabled during load time.
@ -4434,6 +4440,64 @@ wwscfg
mlanutl mlan0 wwscfg 1 : Enable WWS mode
mlanutl mlan0 wwscfg 0 : Disable WWS mode
mc_cfg
This command is used to set/get the channel time.
Usage:
mlanutl mlanX mc_cfg [n]
where <n> : Channel time in microseconds.
Examples:
mlanutl mlanX mc_cfg : Get Channel time and buffer weight.
mlanutl mlanX mc_cfg 10000 : Set Channel time to 10000us.
mc_policy
This command is used to set/get the multi-channel policy.
Note: This is a device specific command. Hence, setting on one interface is
reflected on all other interfaces.
Usage:
mlanutl mlanX mc_policy [n]
where <n> : Multi-channel policy
Examples:
mlanutl mlanX mc_policy : Get multi-channel policy setting.
mlanutl mlanX mc_policy 1 : Set multi-channel policy to 1.
mlanutl mlanX mc_policy 0 : Disable multi-channel policy
mc_cfg_ext
This command is used to set/get the drcs parameters.
Usage:
mlanutl mlanX mc_cfg_ext [c] [s] [u] [m] <a> <b> <d> <e>
where:
channel index0:
[c] : chantime(in TU)
[s] : switchtime(in TU)
[u] : undozetime(in TU)
[m] : mode :0x0 --- PM1(default)
0x1 --- Null2Self
channel index1:
<a> : chantime(in TU)
<b> : switchtime(in TU)
<d> : undozetime(in TU)
<e> : mode :0x0 --- PM1(default)
0x1 --- Null2Self
Note:
channel index0: the first channel
channel index1: the second channel
undozetime should be less than other channel's switchtime
If want to set two channels the same parameters, just ignore the last four parameters and
use [c] [s] [u] [m] to set.
Examples:
mlanutl mlanX mc_cfg_ext : Get the drcs parameters for two channels.
mlanutl mlanX mc_cfg_ext 15 10 5 0 : Set two channels:channeltime 15TU, switchtime 10TU, undozetime 5TU, mode PM1
mlanutl mlanX mc_cfg_ext 15 10 5 0 25 15 9 0 : Set channel index0: channeltime 17TU, switchtime 10TU, undozetime 5TU, mode PM1;
set channel index1: channeltime 25TU, switchtime 15TU, undozetime 9TU, mode PM1.
cfg_noa
This is used to get/set P2P NoA (Notice of Absence) parameters only for P2P GO.

View file

@ -957,8 +957,9 @@ mlan_status wlan_cmd_11ax_cmd(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
break;
case MLAN_11AXCMD_TXOMI_SUBID:
memcpy_ext(pmadapter, axcmd->val, &txomi_cmd->omi,
sizeof(t_u16), sizeof(t_u16));
cmd->size += sizeof(t_u16);
sizeof(mlan_ds_11ax_txomi_cmd),
sizeof(mlan_ds_11ax_txomi_cmd));
cmd->size += sizeof(mlan_ds_11ax_txomi_cmd);
break;
case MLAN_11AXCMD_OBSS_TOLTIME_SUBID:
memcpy_ext(pmadapter, axcmd->val, &toltime_cmd->tol_time,
@ -1034,7 +1035,8 @@ mlan_status wlan_ret_11ax_cmd(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
break;
case MLAN_11AXCMD_TXOMI_SUBID:
memcpy_ext(pmadapter, &cfg->param.txomi_cfg.omi, axcmd->val,
sizeof(t_u16), sizeof(t_u16));
sizeof(mlan_ds_11ax_txomi_cmd),
sizeof(mlan_ds_11ax_txomi_cmd));
break;
case MLAN_11AXCMD_OBSS_TOLTIME_SUBID:
memcpy_ext(pmadapter, &cfg->param.toltime_cfg.tol_time,

View file

@ -3171,7 +3171,10 @@ mlan_status wlan_11h_handle_event_chanswann(mlan_private *priv)
ENTER();
#ifdef UAP_SUPPORT
if (priv->adapter->state_11h.is_master_radar_det_active) {
/** No need handle AP if mc_policy is disabled, FW will move the AP to
* client's new channel */
if (pmadapter->mc_policy &&
priv->adapter->state_11h.is_master_radar_det_active) {
for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM);
i++) {
if (pmadapter->priv[i] &&
@ -3811,8 +3814,13 @@ void wlan_dfs_rep_disconnect(mlan_adapter *pmadapter)
if (wlan_11h_radar_detect_required(pmpriv,
pmadapter->dfsr_channel)) {
wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP,
HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
mlan_status ret = MLAN_STATUS_SUCCESS;
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP,
HostCmd_ACT_GEN_SET, 0, MNULL,
MNULL);
if (ret) {
PRINTM(MMSG, "Error sending message to FW\n");
}
}
}
}
@ -3829,6 +3837,7 @@ void wlan_dfs_rep_bw_change(mlan_adapter *pmadapter)
mlan_private *priv_list[MLAN_MAX_BSS_NUM];
mlan_private *pmpriv = MNULL;
t_u8 pcount, i;
mlan_status ret = MLAN_STATUS_SUCCESS;
memset(pmadapter, priv_list, 0x00, sizeof(priv_list));
pcount = wlan_get_privs_by_cond(pmadapter, wlan_is_intf_active,
@ -3855,8 +3864,12 @@ void wlan_dfs_rep_bw_change(mlan_adapter *pmadapter)
pmpriv, pmadapter->dfsr_channel))
return;
wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP,
HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP,
HostCmd_ACT_GEN_SET, 0, MNULL,
MNULL);
if (ret) {
PRINTM(MERROR, "Error sending message to FW\n");
}
}
}
@ -3865,8 +3878,12 @@ void wlan_dfs_rep_bw_change(mlan_adapter *pmadapter)
pmpriv = priv_list[i];
if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP) {
wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_START,
HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_START,
HostCmd_ACT_GEN_SET, 0, MNULL,
MNULL);
if (ret) {
PRINTM(MERROR, "Error sending message to FW\n");
}
}
}
}
@ -4215,7 +4232,8 @@ mlan_status wlan_11h_radar_detected_handling(mlan_adapter *pmadapter,
/* check next intf */
while ((++pstate_rdh->priv_curr_idx) <
pstate_rdh->priv_list_count) {
pstate_rdh->priv_list_count &&
(pstate_rdh->priv_curr_idx < MLAN_MAX_BSS_NUM)) {
pmpriv =
pstate_rdh->priv_list[pstate_rdh->priv_curr_idx];

View file

@ -61,9 +61,24 @@ static mlan_status wlan_11n_ioctl_max_tx_buf_size(pmlan_adapter pmadapter,
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_11n_cfg *cfg = MNULL;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
if (pioctl_req->action == MLAN_ACT_SET) {
if (cfg->param.tx_buf_size == 0xffff) {
PRINTM(MIOCTL, "Send reconfigure tx buf to FW\n");
ret = wlan_prepare_cmd(pmpriv,
HostCmd_CMD_RECONFIGURE_TX_BUFF,
HostCmd_ACT_GEN_SET, 0,
(t_void *)pioctl_req,
&cfg->param.tx_buf_size);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
}
cfg->param.tx_buf_size = (t_u32)pmadapter->max_tx_buf_size;
pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;

View file

@ -1156,6 +1156,7 @@ void wlan_11n_ba_stream_timeout(mlan_private *priv,
HostCmd_DS_11N_BATIMEOUT *event)
{
HostCmd_DS_11N_DELBA delba;
mlan_status ret = MLAN_STATUS_SUCCESS;
ENTER();
@ -1169,7 +1170,10 @@ void wlan_11n_ba_stream_timeout(mlan_private *priv,
delba.del_ba_param_set |= (t_u16)event->origninator
<< DELBA_INITIATOR_POS;
delba.reason_code = REASON_CODE_STA_TIMEOUT;
wlan_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, MNULL, &delba);
ret = wlan_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, MNULL,
&delba);
if (ret)
PRINTM(MERROR, "Failed to send cmd to FW\n");
LEAVE();
return;

View file

@ -2446,9 +2446,6 @@ static oper_bw_chan *wlan_get_nonglobal_operclass_table(mlan_private *pmpriv,
poper_bw_chan = oper_bw_chan_eu;
*arraysize = sizeof(oper_bw_chan_eu);
break;
default:
PRINTM(MERROR, "Country not support!\n");
break;
}
LEAVE();

View file

@ -4477,6 +4477,32 @@ mlan_status wlan_adapter_init_cmd(pmlan_adapter pmadapter)
goto done;
}
}
if (pmadapter->init_para.drcs_chantime_mode) {
mlan_ds_drcs_cfg drcs_init_cfg[2];
drcs_init_cfg[0].chan_idx = 0x1;
drcs_init_cfg[0].chantime =
(t_u8)(pmadapter->init_para.drcs_chantime_mode >> 8);
/* switchtime use default value in fw*/
drcs_init_cfg[0].switchtime = 10;
drcs_init_cfg[0].undozetime = 5;
drcs_init_cfg[0].mode =
(t_u8)(pmadapter->init_para.drcs_chantime_mode);
drcs_init_cfg[1].chan_idx = 0x2;
drcs_init_cfg[1].chantime =
(t_u8)(pmadapter->init_para.drcs_chantime_mode >> 24);
/* switchtime use default value in fw*/
drcs_init_cfg[1].switchtime = 10;
drcs_init_cfg[1].undozetime = 5;
drcs_init_cfg[1].mode =
(t_u8)(pmadapter->init_para.drcs_chantime_mode >> 16);
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_DRCS_CONFIG,
HostCmd_ACT_GEN_SET, 0, MNULL,
(t_void *)drcs_init_cfg);
if (ret) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
}
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RF_ANTENNA,
HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
@ -4673,10 +4699,19 @@ static mlan_status wlan_get_vdll_image(pmlan_adapter pmadapter, t_u32 vdll_len)
ENTER();
if (ctrl->vdll_mem) {
PRINTM(MCMND, "VDLL mem is not empty: %p len=%d\n",
ctrl->vdll_mem, ctrl->vdll_len);
goto done;
PRINTM(MCMND,
"VDLL mem is not empty: %p old_len=%d new_len=%d\n",
ctrl->vdll_mem, ctrl->vdll_len, vdll_len);
if (pcb->moal_vmalloc && pcb->moal_vfree)
pcb->moal_vfree(pmadapter->pmoal_handle,
(t_u8 *)ctrl->vdll_mem);
else
pcb->moal_mfree(pmadapter->pmoal_handle,
(t_u8 *)ctrl->vdll_mem);
ctrl->vdll_mem = MNULL;
ctrl->vdll_len = 0;
}
if (pcb->moal_vmalloc && pcb->moal_vfree)
status = pcb->moal_vmalloc(pmadapter->pmoal_handle, vdll_len,
(t_u8 **)&ctrl->vdll_mem);
@ -4836,6 +4871,454 @@ mlan_status wlan_process_csi_event(pmlan_private pmpriv)
return status;
}
/**
* @brief This function handle the multi_chan info event
*
* @param pmpriv A pointer to mlan_private structure
* @param pevent A pointer to event buffer
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_handle_event_multi_chan_info(pmlan_private pmpriv,
pmlan_buffer pevent)
{
pmlan_adapter pmadapter = pmpriv->adapter;
t_u32 interfaces = 0;
MrvlIEtypes_multi_chan_info_t *pmulti_chan_info = MNULL;
MrvlIEtypes_multi_chan_group_info_t *pmulti_chan_grp_info = MNULL;
int tlv_buf_left = pevent->data_len - sizeof(mlan_event_id);
t_u16 tlv_type, tlv_len;
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_private intf_priv = MNULL;
int num_intf = 0, bss_type = 0, bss_num = 0;
MrvlIEtypesHeader_t *tlv = MNULL;
ENTER();
PRINTM(MEVENT, "multi channel event\n");
pmulti_chan_info =
(MrvlIEtypes_multi_chan_info_t *)(pevent->pbuf +
pevent->data_offset +
sizeof(mlan_event_id));
if (tlv_buf_left < (int)(sizeof(MrvlIEtypes_multi_chan_info_t)) ||
wlan_le16_to_cpu(pmulti_chan_info->header.type) !=
TLV_TYPE_MULTI_CHAN_INFO) {
PRINTM(MERROR, "Invalid multi channel event\n");
goto done;
}
pmadapter->mc_status = wlan_le16_to_cpu(pmulti_chan_info->status);
PRINTM(MEVENT, "mc_status=%d\n", pmadapter->mc_status);
tlv_buf_left -= sizeof(MrvlIEtypes_multi_chan_info_t);
tlv = (MrvlIEtypesHeader_t *)pmulti_chan_info->tlv_buffer;
while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
tlv_type = wlan_le16_to_cpu(tlv->type);
tlv_len = wlan_le16_to_cpu(tlv->len);
if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
(unsigned int)tlv_buf_left) {
PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
tlv_len, tlv_buf_left);
break;
}
if (tlv_type != TLV_TYPE_MULTI_CHAN_GROUP_INFO_TLV_ID) {
PRINTM(MERROR, "wrong tlv type:0x%x\n", tlv_type);
break;
}
pmulti_chan_grp_info =
(MrvlIEtypes_multi_chan_group_info_t *)tlv;
PRINTM(MEVENT, "mc_info: groupid=%d chan=%d, numintf=%d\n",
pmulti_chan_grp_info->chan_group_id,
pmulti_chan_grp_info->chan_band_info.chan_num,
pmulti_chan_grp_info->num_intf);
num_intf = pmulti_chan_grp_info->num_intf;
for (interfaces = 0; interfaces < (t_u32)num_intf;
interfaces++) {
bss_type = pmulti_chan_grp_info
->bss_type_numlist[interfaces] >>
4;
bss_num = pmulti_chan_grp_info
->bss_type_numlist[interfaces] &
BSS_NUM_MASK;
PRINTM(MEVENT, "intf%d: bss_type=%d bss_num=%d\n",
interfaces, bss_type, bss_num);
intf_priv = wlan_get_priv_by_id(pmadapter, bss_num,
bss_type);
if (intf_priv) {
#ifdef USB
if (IS_USB(pmadapter->card_type)) {
if (pmulti_chan_grp_info->hid_num
.usb_epnum ==
MLAN_USB_EP_DATA ||
pmulti_chan_grp_info->hid_num
.usb_epnum ==
MLAN_USB_EP_DATA_CH2 ||
pmulti_chan_grp_info->hid_num
.usb_epnum ==
MLAN_USB_EP_DATA_IF2 ||
pmulti_chan_grp_info->hid_num
.usb_epnum ==
MLAN_USB_EP_DATA_CH2_IF2) {
intf_priv->port =
pmulti_chan_grp_info
->hid_num
.usb_epnum;
intf_priv->port_index =
wlan_get_port_index(
pmadapter,
intf_priv->port);
PRINTM(MEVENT,
"intf%d: bss_type=%d bss_num=%d port=%d index=%d\n",
interfaces, bss_type,
bss_num, intf_priv->port,
intf_priv->port_index);
} else
PRINTM(MERROR,
"Invalid Endpoint num in multi_channel event\n");
}
#endif
} else {
PRINTM(MERROR,
"Invalid bss_type, bss_num in multi_channel event\n");
}
}
tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
sizeof(MrvlIEtypesHeader_t));
}
#ifdef USB
if (IS_USB(pmadapter->card_type)) {
wlan_resync_usb_port(pmadapter);
}
#endif
done:
LEAVE();
return ret;
}
/**
* @brief This function prepares the command MULTI_CHAN_CFG
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action Command action: GET or SET
* @param pdata_buf A pointer to new setting buf
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_multi_chan_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
t_void *pdata_buf)
{
mlan_ds_multi_chan_cfg *multi_chan_cfg =
(mlan_ds_multi_chan_cfg *)pdata_buf;
HostCmd_DS_MULTI_CHAN_CFG *pmchan_cfg =
(HostCmd_DS_MULTI_CHAN_CFG *)&cmd->params.multi_chan_cfg;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MULTI_CHAN_CONFIG);
pmchan_cfg->action = wlan_cpu_to_le16(cmd_action);
if (cmd_action == HostCmd_ACT_GEN_SET) {
pmchan_cfg->buffer_weight = multi_chan_cfg->buffer_weight;
pmchan_cfg->channel_time =
wlan_cpu_to_le32(multi_chan_cfg->channel_time);
PRINTM(MCMND,
"Set multi-channel: buffer_weight=%d channel_time=%d\n",
multi_chan_cfg->buffer_weight,
multi_chan_cfg->channel_time);
cmd->size = wlan_cpu_to_le16(S_DS_GEN +
sizeof(HostCmd_DS_MULTI_CHAN_CFG));
} else {
cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(cmd_action));
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the command response of MULTI_CHAN_CFG
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @param pioctl_buf A pointer to mlan_ioctl_req structure
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_ret_multi_chan_cfg(pmlan_private pmpriv,
const HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf)
{
mlan_ds_misc_cfg *pcfg = MNULL;
const HostCmd_DS_MULTI_CHAN_CFG *presp_cfg =
&resp->params.multi_chan_cfg;
ENTER();
if (pioctl_buf) {
pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
pcfg->param.multi_chan_cfg.channel_time =
wlan_le32_to_cpu(presp_cfg->channel_time);
pcfg->param.multi_chan_cfg.buffer_weight =
presp_cfg->buffer_weight;
pcfg->param.multi_chan_cfg.tlv_len =
resp->size - (sizeof(HostCmd_DS_GEN) +
sizeof(HostCmd_DS_MULTI_CHAN_CFG));
PRINTM(MCMND,
"Get multi-channel: buffer_weight=%d channel_time=%d tlv_len=%d\n",
pcfg->param.multi_chan_cfg.buffer_weight,
pcfg->param.multi_chan_cfg.channel_time,
pcfg->param.multi_chan_cfg.tlv_len);
memcpy_ext(pmpriv->adapter, pcfg->param.multi_chan_cfg.tlv_buf,
presp_cfg->tlv_buf,
pcfg->param.multi_chan_cfg.tlv_len,
pcfg->param.multi_chan_cfg.tlv_len);
pioctl_buf->buf_len = sizeof(mlan_ds_multi_chan_cfg) +
pcfg->param.multi_chan_cfg.tlv_len;
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares the command MULTI_CHAN_POLICY
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action Command action: GET or SET
* @param pdata_buf A pointer to new setting buf
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_multi_chan_policy(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_void *pdata_buf)
{
t_u16 policy = 0;
HostCmd_DS_MULTI_CHAN_POLICY *pmulti_chan_policy =
(HostCmd_DS_MULTI_CHAN_POLICY *)&cmd->params.multi_chan_policy;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MULTI_CHAN_POLICY);
pmulti_chan_policy->action = wlan_cpu_to_le16(cmd_action);
cmd->size = wlan_cpu_to_le16(S_DS_GEN +
sizeof(HostCmd_DS_MULTI_CHAN_POLICY));
if (cmd_action == HostCmd_ACT_GEN_SET) {
policy = *((t_u16 *)pdata_buf);
pmulti_chan_policy->policy = wlan_cpu_to_le16(policy);
PRINTM(MCMND, "Set multi-channel policy: %d\n", policy);
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the command response of MULTI_CHAN_POLICY
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @param pioctl_buf A pointer to mlan_ioctl_req structure
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_ret_multi_chan_policy(pmlan_private pmpriv,
const HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf)
{
mlan_ds_misc_cfg *pcfg = MNULL;
const HostCmd_DS_MULTI_CHAN_POLICY *presp_cfg =
&resp->params.multi_chan_policy;
ENTER();
if (pioctl_buf) {
pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
pcfg->param.multi_chan_policy =
wlan_le16_to_cpu(presp_cfg->policy);
if (pioctl_buf->action == HostCmd_ACT_GEN_SET) {
if (pcfg->param.multi_chan_policy)
pmpriv->adapter->mc_policy = MTRUE;
else
pmpriv->adapter->mc_policy = MFALSE;
}
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares the command DRCD_CFG
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action Command action: GET or SET
* @param pdata_buf A pointer to new setting buf
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_drcs_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_void *pdata_buf)
{
mlan_ds_drcs_cfg *drcs_cfg = (mlan_ds_drcs_cfg *)pdata_buf;
HostCmd_DS_DRCS_CFG *pdrcs_cfg =
(HostCmd_DS_DRCS_CFG *)&cmd->params.drcs_cfg;
MrvlTypes_DrcsTimeSlice_t *channel_time_slicing =
&pdrcs_cfg->time_slicing;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_DRCS_CONFIG);
pdrcs_cfg->action = wlan_cpu_to_le16(cmd_action);
if (cmd_action == HostCmd_ACT_GEN_SET) {
channel_time_slicing->header.type =
wlan_cpu_to_le16(MRVL_DRCS_TIME_SLICE_TLV_ID);
channel_time_slicing->header.len =
wlan_cpu_to_le16(sizeof(MrvlTypes_DrcsTimeSlice_t) -
sizeof(MrvlIEtypesHeader_t));
channel_time_slicing->chan_idx =
wlan_cpu_to_le16(drcs_cfg->chan_idx);
channel_time_slicing->chantime = drcs_cfg->chantime;
channel_time_slicing->switchtime = drcs_cfg->switchtime;
channel_time_slicing->undozetime = drcs_cfg->undozetime;
channel_time_slicing->mode = drcs_cfg->mode;
PRINTM(MCMND,
"Set multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n",
channel_time_slicing->chan_idx,
channel_time_slicing->chantime,
channel_time_slicing->switchtime,
channel_time_slicing->undozetime,
channel_time_slicing->mode);
cmd->size = wlan_cpu_to_le16(S_DS_GEN +
sizeof(HostCmd_DS_DRCS_CFG));
/* Set two channels different parameters */
if (0x3 != channel_time_slicing->chan_idx) {
drcs_cfg++;
channel_time_slicing = pdrcs_cfg->drcs_buf;
channel_time_slicing->header.type =
wlan_cpu_to_le16(MRVL_DRCS_TIME_SLICE_TLV_ID);
channel_time_slicing->header.len = wlan_cpu_to_le16(
sizeof(MrvlTypes_DrcsTimeSlice_t) -
sizeof(MrvlIEtypesHeader_t));
channel_time_slicing->chan_idx =
wlan_cpu_to_le16(drcs_cfg->chan_idx);
channel_time_slicing->chantime = drcs_cfg->chantime;
channel_time_slicing->switchtime = drcs_cfg->switchtime;
channel_time_slicing->undozetime = drcs_cfg->undozetime;
channel_time_slicing->mode = drcs_cfg->mode;
PRINTM(MCMND,
"Set multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n",
channel_time_slicing->chan_idx,
channel_time_slicing->chantime,
channel_time_slicing->switchtime,
channel_time_slicing->undozetime,
channel_time_slicing->mode);
cmd->size += wlan_cpu_to_le16(
sizeof(MrvlTypes_DrcsTimeSlice_t));
}
} else {
cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(cmd_action));
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the command response of DRCS_CFG
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @param pioctl_buf A pointer to mlan_ioctl_req structure
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_ret_drcs_cfg(pmlan_private pmpriv,
const HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf)
{
mlan_ds_misc_cfg *pcfg = MNULL;
const HostCmd_DS_DRCS_CFG *presp_cfg = &resp->params.drcs_cfg;
const MrvlTypes_DrcsTimeSlice_t *channel_time_slicing =
&presp_cfg->time_slicing;
const MrvlTypes_DrcsTimeSlice_t *channel_time_slicing1 = MNULL;
mlan_ds_drcs_cfg *drcs_cfg1 = MNULL;
ENTER();
if (pioctl_buf) {
pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
if (wlan_le16_to_cpu(channel_time_slicing->header.type) !=
MRVL_DRCS_TIME_SLICE_TLV_ID ||
wlan_le16_to_cpu(channel_time_slicing->header.len) !=
sizeof(MrvlTypes_DrcsTimeSlice_t) -
sizeof(MrvlIEtypesHeader_t)) {
LEAVE();
return MLAN_STATUS_FAILURE;
}
pcfg->param.drcs_cfg[0].chan_idx =
wlan_le16_to_cpu(channel_time_slicing->chan_idx);
pcfg->param.drcs_cfg[0].chantime =
channel_time_slicing->chantime;
pcfg->param.drcs_cfg[0].switchtime =
channel_time_slicing->switchtime;
pcfg->param.drcs_cfg[0].undozetime =
channel_time_slicing->undozetime;
pcfg->param.drcs_cfg[0].mode = channel_time_slicing->mode;
PRINTM(MCMND,
"multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n",
pcfg->param.drcs_cfg[0].chan_idx,
channel_time_slicing->chantime,
channel_time_slicing->switchtime,
channel_time_slicing->undozetime,
channel_time_slicing->mode);
pioctl_buf->buf_len = sizeof(mlan_ds_drcs_cfg);
/*Channel for chan_idx 1 and 2 have different parameters*/
if (0x3 != pcfg->param.drcs_cfg[0].chan_idx) {
channel_time_slicing1 = presp_cfg->drcs_buf;
if (wlan_le16_to_cpu(
channel_time_slicing1->header.type) !=
MRVL_DRCS_TIME_SLICE_TLV_ID ||
wlan_le16_to_cpu(
channel_time_slicing1->header.len) !=
sizeof(MrvlTypes_DrcsTimeSlice_t) -
sizeof(MrvlIEtypesHeader_t)) {
LEAVE();
return MLAN_STATUS_FAILURE;
}
drcs_cfg1 =
(mlan_ds_drcs_cfg *)&pcfg->param.drcs_cfg[1];
drcs_cfg1->chan_idx = wlan_le16_to_cpu(
channel_time_slicing1->chan_idx);
drcs_cfg1->chantime = channel_time_slicing1->chantime;
drcs_cfg1->switchtime =
channel_time_slicing1->switchtime;
drcs_cfg1->undozetime =
channel_time_slicing1->undozetime;
drcs_cfg1->mode = channel_time_slicing1->mode;
PRINTM(MCMND,
"multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n",
drcs_cfg1->chan_idx, drcs_cfg1->chantime,
drcs_cfg1->switchtime, drcs_cfg1->undozetime,
drcs_cfg1->mode);
pioctl_buf->buf_len += sizeof(mlan_ds_drcs_cfg);
}
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of get_hw_spec.
*
@ -5422,7 +5905,7 @@ mlan_status wlan_cmd_802_11_radio_control(pmlan_private pmpriv,
t_u16 cmd_action, t_void *pdata_buf)
{
HostCmd_DS_802_11_RADIO_CONTROL *pradio_control = &cmd->params.radio;
t_u32 radio_ctl;
t_u32 radio_ctl = 0;
ENTER();
cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_RADIO_CONTROL)) +
S_DS_GEN);
@ -7495,8 +7978,12 @@ mlan_status wlan_ret_chan_region_cfg(pmlan_private pmpriv,
/* Add FW cfp tables and region info */
wlan_add_fw_cfp_tables(pmpriv, tlv_buf, tlv_buf_left);
if (pmadapter->otp_region) {
wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
pmadapter->fw_bands);
if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
pmadapter->fw_bands)) {
PRINTM(MERROR,
"Set region table failure!! region_code = 0x%X, fw_bands = 0x%X\n",
pmadapter->region_code, pmadapter->fw_bands);
}
}
if (!pioctl_buf)
goto done;
@ -9211,6 +9698,7 @@ mlan_status wlan_cmd_get_ch_load(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
cfg_cmd->noise = wlan_cpu_to_le16(cfg->noise);
cfg_cmd->rx_quality = wlan_cpu_to_le16(cfg->rx_quality);
cfg_cmd->duration = wlan_cpu_to_le16(cfg->duration);
cfg_cmd->cca_th = wlan_cpu_to_le16(cfg->cca_th);
LEAVE();
return MLAN_STATUS_SUCCESS;
}

View file

@ -24,7 +24,7 @@
#define _MLAN_DECL_H_
/** MLAN release version */
#define MLAN_RELEASE_VERSION "366.p5"
#define MLAN_RELEASE_VERSION "368"
/** Re-define generic data types for MLAN/MOAL */
/** Signed char (1-byte) */
@ -1747,6 +1747,15 @@ typedef struct {
t_u32 time_usec;
} wifi_timeval;
#define timeval_to_msec(timeval) \
(t_u64)((t_u64)(timeval.time_sec) * 1000 + \
(t_u64)(timeval.time_usec) / 1000)
#define timeval_to_usec(timeval) \
(t_u64)((t_u64)(timeval.time_sec) * 1000 * 1000 + \
(t_u64)(timeval.time_usec))
#define is_zero_timeval(timeval) \
((timeval.time_sec == 0) && (timeval.time_usec == 0))
#define MAX_NUM_RATE 32
#define MAX_RADIO 2
#define MAX_NUM_CHAN 1
@ -1828,15 +1837,6 @@ typedef struct {
t_u32 cca_busy_time;
} wifi_channel_stat;
#define timeval_to_msec(timeval) \
(t_u64)((t_u64)(timeval.time_sec) * 1000 + \
(t_u64)(timeval.time_usec) / 1000)
#define timeval_to_usec(timeval) \
(t_u64)((t_u64)(timeval.time_sec) * 1000 * 1000 + \
(t_u64)(timeval.time_usec))
#define is_zero_timeval(timeval) \
((timeval.time_sec == 0) && (timeval.time_usec == 0))
/** radio statistics */
typedef struct {
/** wifi radio (if multiple radio supported) */
@ -2322,6 +2322,8 @@ typedef struct _mlan_device {
t_u8 indication_gpio;
/** Dynamic MIMO-SISO switch for hscfg*/
t_u8 hs_mimo_switch;
/** channel time and mode for DRCS*/
t_u32 drcs_chantime_mode;
#ifdef USB
/** Tx CMD endpoint address */
t_u8 tx_cmd_ep;
@ -2332,6 +2334,8 @@ typedef struct _mlan_device {
t_u8 rx_data_ep;
/** Tx data endpoint address */
t_u8 tx_data_ep;
/** Tx data second endpoint address */
t_u8 tx_data2_ep;
#endif
/** passive to active scan */
t_u8 passive_to_active_scan;

View file

@ -94,6 +94,9 @@ typedef MLAN_PACK_START struct {
/** Setup the number of rates passed in the driver/firmware API */
#define A_SUPPORTED_RATES 9
/** IEEEtypes Data Frame Subtype of QoS pkt */
#define QOS_DATA 8
/** CapInfo Short Slot Time Disabled */
/* #define SHORT_SLOT_TIME_DISABLED(CapInfo)
* ((IEEEtypes_CapInfo_t)(CapInfo).short_slot_time = 0) */
@ -245,7 +248,7 @@ typedef enum _KEY_INFO_WAPI {
#define MRVDRV_SNAP_HEADER_LEN 8
/** The number of times to try when polling for status bits */
#define MAX_POLL_TRIES 100
#define MAX_POLL_TRIES 300
/** The number of times to try when waiting for downloaded firmware to
become active when multiple interface is present */
@ -1298,6 +1301,19 @@ typedef enum _WLAN_802_11_WEP_STATUS {
/** Host Command ID : ROAMING OFFLOAD TO FW*/
#define HostCmd_CMD_ROAM_OFFLOAD 0x0245
/** Host Command ID: Multi chan config */
#define HostCmd_CMD_MULTI_CHAN_CONFIG 0x011e
/** Host Command ID: Multi chan policy */
#define HostCmd_CMD_MULTI_CHAN_POLICY 0x0121
/** TLV ID for multi chan info */
#define TLV_TYPE_MULTI_CHAN_INFO (PROPRIETARY_TLV_BASE_ID + 0xb7)
/** TLV ID for multi chan group info */
#define TLV_TYPE_MULTI_CHAN_GROUP_INFO_TLV_ID (PROPRIETARY_TLV_BASE_ID + 0xb8)
/** TLV ID for DRCS TimeSlice */
#define MRVL_DRCS_TIME_SLICE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 263)
/** Host Command ID: DRCS config */
#define HostCmd_CMD_DRCS_CONFIG 0x024a
#ifdef RX_PACKET_COALESCE
/** TLV ID for RX pkt coalesce config */
#define TLV_TYPE_RX_PKT_COAL_CONFIG (PROPRIETARY_TLV_BASE_ID + 0xC9)
@ -1553,6 +1569,12 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_He_Op_t {
t_u8 option[9];
} MLAN_PACK_END MrvlIEtypes_He_Op_t;
/** fw_cap_info bit30 for Embedded OWE Support*/
#define FW_CAPINFO_EMBEDDED_OWE_SUPPORT MBIT(30)
/** Check if Embedded OWE is supported by firmware */
#define IS_FW_SUPPORT_EMBEDDED_OWE(_adapter) \
(_adapter->fw_cap_info & FW_CAPINFO_EMBEDDED_OWE_SUPPORT)
#ifdef RX_PACKET_COALESCE
/** Host Command ID : Rx packet coalescing configuration */
#define HostCmd_CMD_RX_PKT_COALESCE_CFG 0x012c
@ -2063,6 +2085,9 @@ typedef enum _ENH_PS_MODES {
/** Event ID: SAD Report */
#define EVENT_SAD_REPORT 0x00000066
/** Event ID: Multi Chan Info*/
#define EVENT_MULTI_CHAN_INFO 0x0000006a
#define EVENT_FW_DUMP_INFO 0x00000073
/** Event ID: Tx status */
#define EVENT_TX_STATUS_REPORT 0x00000074
@ -2171,6 +2196,8 @@ typedef enum _tdls_error_code_e {
#define RXPD_FLAG_EXTRA_HEADER (1 << 1)
#define RXPD_FLAG_UCAST_PKT (1 << 3)
/** Event_WEP_ICV_ERR structure */
typedef MLAN_PACK_START struct _Event_WEP_ICV_ERR {
/** Reason code */
@ -2220,6 +2247,10 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_TDLS_Idle_Timeout_t {
#define PAIRWISE_CIPHER_SUITE_LEN 4
/** AKM Suite length */
#define AKM_SUITE_LEN 4
/** PMKID length */
#define PMKID_LEN 16
/** Group mgmt Cipher Suite length */
#define GROUP_MGMT_CIPHER_SUITE_LEN 4
/** MFPC bit in RSN capability */
#define MFPC_BIT 7
/** MFPR bit in RSN capability */
@ -3645,6 +3676,7 @@ typedef MLAN_PACK_START struct _HostCmd_DS_GET_CH_LOAD {
t_s16 noise;
t_u16 rx_quality;
t_u16 duration;
t_u16 cca_th;
} MLAN_PACK_END HostCmd_DS_GET_CH_LOAD;
/** HostCmd_DS_CMD_802_11_RSSI_INFO */
@ -6975,6 +7007,92 @@ typedef MLAN_PACK_START struct _HostCmd_DS_RX_PKT_COAL_CFG {
} MLAN_PACK_END HostCmd_DS_RX_PKT_COAL_CFG;
#endif
typedef MLAN_PACK_START struct _MrvlTypes_DrcsTimeSlice_t {
/** Header */
MrvlIEtypesHeader_t header;
/** Channel Index*/
t_u16 chan_idx;
/** Channel time (in TU) for chan_idx*/
t_u8 chantime;
/** Channel swith time (in TU) for chan_idx*/
t_u8 switchtime;
/** Undoze time (in TU) for chan_idx*/
t_u8 undozetime;
/** Rx traffic control scheme when channel switch*/
/** only valid for GC/STA interface*/
t_u8 mode;
} MLAN_PACK_END MrvlTypes_DrcsTimeSlice_t;
typedef MLAN_PACK_START struct _HostCmd_DS_MULTI_CHAN_CFG {
/** Action */
t_u16 action;
/** Channel time */
t_u32 channel_time;
/** Buffer weight */
t_u8 buffer_weight;
/** TLV buffer */
t_u8 tlv_buf[];
/* t_u8 *tlv_buf; */
} MLAN_PACK_END HostCmd_DS_MULTI_CHAN_CFG;
typedef MLAN_PACK_START struct _HostCmd_DS_DRCS_CFG {
/** Action */
t_u16 action;
/** TLV buffer */
MrvlTypes_DrcsTimeSlice_t time_slicing;
/** TLV buffer */
MrvlTypes_DrcsTimeSlice_t drcs_buf[];
/* t_u8 *tlv_buf; */
} MLAN_PACK_END HostCmd_DS_DRCS_CFG;
typedef MLAN_PACK_START struct _HostCmd_DS_MULTI_CHAN_POLICY {
/** Action */
t_u16 action;
/** Multi-channel Policy */
t_u16 policy;
} MLAN_PACK_END HostCmd_DS_MULTI_CHAN_POLICY;
/** Channel band info */
typedef MLAN_PACK_START struct _ChannelBandInfo {
/* band config */
Band_Config_t bandcfg;
/** channel num for specificed band */
t_u8 chan_num;
} MLAN_PACK_END ChannelBandInfo;
/** MrvlIETypes_mutli_chan_group_info_t */
typedef MLAN_PACK_START struct _MrvlIETypes_mutli_chan_group_info_t {
/** Header */
MrvlIEtypesHeader_t header;
/** channel group id */
t_u8 chan_group_id;
/** buffer weight for this channel group */
t_u8 chan_buff_weight;
/** channel number and band information */
ChannelBandInfo chan_band_info;
/** Max channel time (us) */
t_u32 channel_time;
/** Reserved */
t_u32 reserved;
MLAN_PACK_START union {
t_u8 sdio_func_num;
t_u8 usb_epnum;
} MLAN_PACK_END hid_num;
/** interface number in this group */
t_u8 num_intf;
/** bss_type list */
t_u8 bss_type_numlist[];
} MLAN_PACK_END MrvlIEtypes_multi_chan_group_info_t;
/** MrvlIEtypes_multi_chan_info_t */
typedef MLAN_PACK_START struct _MrvlIETypes_mutli_chan_info_t {
/** Header */
MrvlIEtypesHeader_t header;
/** multi channel operation status */
t_u16 status;
/** Tlv buffer */
t_u8 tlv_buffer[];
} MLAN_PACK_END MrvlIEtypes_multi_chan_info_t;
/** TLV buffer : firmware roam keys */
typedef MLAN_PACK_START struct _MrvlIEtypes_keyParams_t {
/** Header */
@ -8130,6 +8248,9 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND {
#ifdef USB
HostCmd_DS_PACKET_AGGR_OVER_HOST_INTERFACE packet_aggr;
#endif
HostCmd_DS_MULTI_CHAN_CFG multi_chan_cfg;
HostCmd_DS_MULTI_CHAN_POLICY multi_chan_policy;
HostCmd_DS_DRCS_CFG drcs_cfg;
HostCmd_CONFIG_LOW_PWR_MODE low_pwr_mode_cfg;
HostCmd_DS_TSF tsf;
HostCmd_DS_DFS_REPEATER_MODE dfs_repeater;

View file

@ -1939,6 +1939,11 @@ typedef MLAN_PACK_START struct {
} MLAN_PACK_END wlan_bgscan_cfg;
#endif /* STA_SUPPORT */
/** The open AP in OWE transmition Mode */
#define OWE_TRANS_MODE_OPEN 1
/** The security AP in OWE trsnsition Mode */
#define OWE_TRANS_MODE_OWE 2
#ifdef PRAGMA_PACK
#pragma pack(pop)
#endif
@ -1953,6 +1958,15 @@ typedef struct _BSSDescriptor_t {
/** SSID */
mlan_802_11_ssid ssid;
/** Transition MAC address */
mlan_802_11_mac_addr trans_mac_address;
/** Transition SSID */
mlan_802_11_ssid trans_ssid;
/** OWE Transition mode */
t_u8 owe_transition_mode;
/** WEP encryption requirement */
t_u32 privacy;

View file

@ -614,6 +614,7 @@ mlan_status wlan_init_priv(pmlan_private priv)
priv->intf_hr_len = MLAN_USB_TX_AGGR_HEADER;
}
priv->port = pmadapter->tx_data_ep;
priv->port_index = 0;
}
#endif
ret = wlan_add_bsspriotbl(priv);
@ -823,6 +824,9 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter)
#ifdef USB
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
pmadapter->pcard_usb->usb_port_status[i] = MFALSE;
}
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
pmadapter->pcard_usb->usb_tx_aggr[i].aggr_ctrl.enable =
MFALSE;
@ -842,7 +846,7 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter)
pmadapter->pcard_usb->usb_tx_aggr[i].hold_timeout_msec =
MLAN_USB_TX_AGGR_TIMEOUT_MSEC;
pmadapter->pcard_usb->usb_tx_aggr[i].port =
pmadapter->tx_data_ep;
pmadapter->usb_tx_ports[i];
pmadapter->pcard_usb->usb_tx_aggr[i].phandle =
(t_void *)pmadapter;
}
@ -946,6 +950,8 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter)
pmadapter->arp_filter_size = 0;
#endif /* STA_SUPPORT */
pmadapter->mc_status = MFALSE;
#ifdef PCIE
if (IS_PCIE(pmadapter->card_type)) {
pmadapter->pcard_pcie->txbd_wrptr = 0;

View file

@ -293,6 +293,8 @@ enum _mlan_ioctl_req_id {
#if defined(STA_SUPPORT)
MLAN_OID_MISC_PMFCFG = 0x00200022,
#endif
MLAN_OID_MISC_MULTI_CHAN_CFG = 0x00200023,
MLAN_OID_MISC_MULTI_CHAN_POLICY = 0x00200024,
#ifdef WIFI_DIRECT_SUPPORT
MLAN_OID_MISC_WIFI_DIRECT_CONFIG = 0x00200025,
#endif
@ -319,6 +321,7 @@ enum _mlan_ioctl_req_id {
MLAN_OID_MISC_GET_CHAN_REGION_CFG = 0x00200046,
MLAN_OID_MISC_CLOUD_KEEP_ALIVE = 0x00200048,
MLAN_OID_MISC_OPER_CLASS_CHECK = 0x00200049,
MLAN_OID_MISC_DRCS_CFG = 0x00200050,
MLAN_OID_MISC_CWMODE_CTRL = 0x00200051,
MLAN_OID_MISC_AGGR_CTRL = 0x00200052,
@ -766,6 +769,11 @@ typedef struct _mlan_ssid_bssid {
t_u8 host_mlme;
/** assoicate resp frame/ie from firmware */
mlan_ds_misc_assoc_rsp assoc_rsp;
t_u8 owe_transition_mode;
/** Transition SSID */
mlan_802_11_ssid trans_ssid;
/** Transition BSSID */
mlan_802_11_mac_addr trans_bssid;
} mlan_ssid_bssid, *pmlan_ssid_bssid;
/** Data structure of WMM ECW */
@ -911,6 +919,8 @@ typedef struct _mlan_deauth_param {
#define PROTOCOL_WAPI 0x80
/** WPA3 SAE */
#define PROTOCOL_WPA3_SAE 0x100
/** OWE */
#define PROTOCOL_OWE 0x200
/** Key_mgmt_psk */
#define KEY_MGMT_NONE 0x04
@ -2592,6 +2602,7 @@ enum _mlan_auth_mode {
MLAN_AUTH_MODE_SHARED = 0x01,
MLAN_AUTH_MODE_FT = 0x02,
MLAN_AUTH_MODE_SAE = 0x03,
MLAN_AUTH_MODE_OWE = 0x04,
MLAN_AUTH_MODE_NETWORKEAP = 0x80,
MLAN_AUTH_MODE_AUTO = 0xFF,
};
@ -2604,6 +2615,7 @@ typedef enum {
AssocAgentAuth_FastBss_Skip,
AssocAgentAuth_Network_EAP,
AssocAgentAuth_Wpa3Sae = 6,
AssocAgentAuth_Owe = 7,
AssocAgentAuth_Auto,
} AssocAgentAuthType_e;
@ -4065,10 +4077,19 @@ typedef struct _mlan_ds_11ax_txop_cmd {
} mlan_ds_11ax_txop_cmd, *pmlan_ds_11ax_txop_cmd;
/** Type definition of mlan_ds_11ax_htc_cmd for MLAN_OID_11AX_CMD_CFG */
typedef struct _mlan_ds_11ax_txomi_cmd {
typedef struct MLAN_PACK_START_mlan_ds_11ax_txomi_cmd {
/* 11ax spec 9.2.4.6a.2 OM Control 12 bits. Bit 0 to bit 11 */
t_u16 omi;
} mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd;
/* tx option
* 0: send OMI in QoS NULL; 1: send OMI in QoS data; 0xFF: set OMI in
* both
*/
t_u8 tx_option;
/* if OMI is sent in QoS data, specify the number of consecutive data
* packets containing the OMI
*/
t_u8 num_data_pkts;
} MLAN_PACK_END mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd;
/** Type definition of mlan_ds_11ax_toltime_cmd for MLAN_OID_11AX_CMD_CFG */
typedef struct _mlan_ds_11ax_toltime_cmd {
@ -4471,12 +4492,13 @@ enum _mlan_func_cmd {
MLAN_FUNC_SHUTDOWN,
};
/** Net monitor filter: management frame */
#define MLAN_NETMON_MANAGEMENT_FRAME MBIT(0)
/** Net monitor filter: control frame */
#define MLAN_NETMON_CONTROL_FRAME MBIT(1)
/** Net monitor filter: data frame */
#define MLAN_NETMON_DATA_FRAME MBIT(2)
/* Net monitor filters: */
/* management frame */
#define MLAN_NETMON_MANAGEMENT MBIT(0)
/* control frame */
#define MLAN_NETMON_CONTROL MBIT(1)
/* data frame */
#define MLAN_NETMON_DATA MBIT(2)
typedef struct _mlan_ds_misc_net_monitor {
/** Enable/disable network monitor */
@ -4912,6 +4934,31 @@ typedef struct _mlan_ds_misc_pmfcfg {
} mlan_ds_misc_pmfcfg;
#endif
typedef MLAN_PACK_START struct _mlan_ds_multi_chan_cfg {
/** Channel Time */
t_u32 channel_time;
/** Buffer Weight */
t_u8 buffer_weight;
/** tlv len */
t_u16 tlv_len;
/** TLV buffer */
t_u8 tlv_buf[];
} MLAN_PACK_END mlan_ds_multi_chan_cfg;
typedef MLAN_PACK_START struct _mlan_ds_drcs_cfg {
/** Channel Index*/
t_u16 chan_idx;
/** Channel time (in TU) for chan_idx */
t_u8 chantime;
/** Channel swith time (in TU) for chan_idx */
t_u8 switchtime;
/** Undoze time (in TU) for chan_idx */
t_u8 undozetime;
/** Rx traffic control scheme when channel switch*/
/** only valid for GC/STA interface*/
t_u8 mode;
} MLAN_PACK_END mlan_ds_drcs_cfg;
#define MAX_SSID_NUM 16
#define MAX_AP_LIST 8
#define RETRY_UNLIMITED_TIME 0xFF
@ -5627,7 +5674,7 @@ struct MLAN_PACK_START mfg_Cmd_HE_TBTx_t {
/** AXQ Mu Timer */
t_u16 axq_mu_timer;
/** Tx Power */
t_u16 tx_power;
t_s16 tx_power;
} MLAN_PACK_END;
typedef struct _mlan_ds_misc_chnrgpwr_cfg {
@ -5684,6 +5731,7 @@ typedef struct _mlan_ds_ch_load {
t_s16 noise;
t_u16 rx_quality;
t_u16 duration;
t_u16 cca_th;
} mlan_ds_ch_load;
/** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */
@ -5770,6 +5818,13 @@ typedef struct _mlan_ds_misc_cfg {
#if defined(STA_SUPPORT)
mlan_ds_misc_pmfcfg pmfcfg;
#endif
/** Multi-channel config for MLAN_OID_MISC_MULTI_CHAN_CFG */
mlan_ds_multi_chan_cfg multi_chan_cfg;
/** Multi-channel policy for MLAN_OID_MISC_MULTI_CHAN_POLICY */
t_u16 multi_chan_policy;
/** channel drcs time slicing config for MLAN_OID_MISC_DRCS_CFG
*/
mlan_ds_drcs_cfg drcs_cfg[2];
#ifdef WIFI_DIRECT_SUPPORT
mlan_ds_wifi_direct_config p2p_config;
#endif

View file

@ -351,7 +351,7 @@ static mlan_status wlan_setup_rates_from_bssdesc(mlan_private *pmpriv,
t_u8 *pout_rates,
t_u32 *pout_rates_size)
{
t_u8 card_rates[WLAN_SUPPORTED_RATES];
t_u8 card_rates[WLAN_SUPPORTED_RATES] = {0};
t_u32 card_rates_size = 0;
ENTER();
/* Copy AP supported rates */
@ -625,19 +625,53 @@ static t_u8 wlan_use_mfp(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc)
* @param ptlv_rsn_ie A pointer to rsn_ie TLV
*/
static int wlan_update_rsn_ie(mlan_private *pmpriv,
MrvlIEtypes_RsnParamSet_t *ptlv_rsn_ie)
MrvlIEtypes_RsnParamSet_t *ptlv_rsn_ie,
t_u16 *rsn_ie_len, t_u8 *akm_type)
{
t_u16 *prsn_cap;
t_u16 *ptr;
t_u16 *akm_suite_count_ptr;
t_u8 *ptr;
t_u8 *pairwise_cipher_count_ptr;
t_u8 *group_mgmt_cipher_suite_ptr = MNULL;
t_u8 *pmkid_list_ptr = MNULL;
t_u8 *end_ptr;
t_u16 pmf_mask = 0x00;
t_u8 *temp;
t_u16 pairwise_cipher_count = 0;
t_u16 akm_suite_count = 0;
t_u16 temp_akm_suite_count = 0;
int found = 0;
t_u8 sha_256_oui[4] = {0x00, 0x0f, 0xac, 0x06};
t_u8 sae_oui[4] = {0x00, 0x0f, 0xac, 0x08};
t_u16 pmkid_count = 0;
t_u8 i;
#define PREFERENCE_TKIP 1
/* Cipher Perference Order:
(5) CIPHER_SYITE_TYPE_GCMP_256 = 9
(4) CIPHER_SYITE_TYPE_GCMP_128 = 8
(3) CIPHER_SYITE_TYPE_CCMP_256 = 10
(2) CIPHER_SYITE_TYPE_CCMP_128 = 4
(1) CIPHER_SYITE_TYPE_TKIP = 2
(0) Skip
*/
t_u8 preference_selected;
t_u8 cipher_selected_id;
#if 0 // defined(ENABLE_GCMP_SUPPORT)
// embedded supplicant doesn't support GCMP yet
t_u8 cipher_preference[11] = {0, 0, 1, 0, 2, 0, 0, 0, 4, 5, 3};
#else
t_u8 cipher_preference[5] = {0, 0, 1, 0, 2};
#endif
t_u8 oui[4] = {0x00, 0x0f, 0xac, 0x00};
/* AKM Perference Order:
(6) AKM_SUITE_TYPE_FT_SAE = 9 //Not supported in esupp
(5) AKM_SUITE_TYPE_SAE = 8
(4) AKM_SUITE_TYPE_OWE = 18
(3) AKM_SUITE_TYPE_FT_PSK = 4 //Not supported in esupp
(2) AKM_SUITE_TYPE_PSK_SHA256 = 6
(1) AKM_SUITE_TYPE_PSK = 2
(0) Skip
*/
t_u8 akm_type_selected;
t_u8 akm_type_id = 0;
t_u8 akm_preference[19] = {0, 0, 1, 0, 0, 0, 2, 0, 5, 0,
0, 0, 0, 0, 0, 0, 0, 0, 4};
mlan_adapter *pmadapter = pmpriv->adapter;
int ap_mfpc = 0, ap_mfpr = 0, ret = MLAN_STATUS_SUCCESS;
@ -650,82 +684,114 @@ static int wlan_update_rsn_ie(mlan_private *pmpriv,
* pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN + 2 bytes
* akm_suite_count + akm_suite_count * AKM_SUITE_LEN
*/
ptr = (t_u16 *)(ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8));
pairwise_cipher_count = wlan_le16_to_cpu(*ptr);
ptr = (t_u16 *)(ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) +
pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN);
temp_akm_suite_count = wlan_le16_to_cpu(*ptr);
akm_suite_count = wlan_le16_to_cpu(*ptr);
/* Save pointer to akm_suite_count in RSN IE to update it later */
akm_suite_count_ptr = ptr;
temp = ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) +
pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN +
sizeof(t_u16);
/* ptr now points to the 1st AKM suite */
if (temp_akm_suite_count > 1) {
while (temp_akm_suite_count) {
if (pmpriv->sec_info.authentication_mode ==
MLAN_AUTH_MODE_SAE) {
if (!memcmp(pmadapter, temp, sae_oui,
AKM_SUITE_LEN)) {
found = 1;
end_ptr = ptlv_rsn_ie->rsn_ie + *rsn_ie_len;
ptr = ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8);
pairwise_cipher_count_ptr = ptr;
pairwise_cipher_count = wlan_le16_to_cpu(*(t_u16 *)ptr);
ptr += sizeof(t_u16);
preference_selected = 0;
cipher_selected_id = 0;
for (i = 0; i < pairwise_cipher_count; i++) {
if ((ptr[3] < sizeof(cipher_preference)) &&
(cipher_preference[ptr[3]] > preference_selected)) {
preference_selected = cipher_preference[ptr[3]];
cipher_selected_id = ptr[3];
}
ptr += PAIRWISE_CIPHER_SUITE_LEN;
}
if (preference_selected == 0) {
PRINTM(MERROR, "RSNE: PAIRWISE_CIPHER not supported\n");
return MLAN_STATUS_FAILURE;
}
if ((preference_selected == PREFERENCE_TKIP) &&
((*akm_type == AssocAgentAuth_Wpa3Sae) ||
(*akm_type == AssocAgentAuth_Owe))) {
PRINTM(MERROR,
"RSNE: PAIRWISE_CIPHER TKIP not allowed for AKM %s\n",
(*akm_type == AssocAgentAuth_Wpa3Sae) ? "SAE" : "ÖWE");
return MLAN_STATUS_FAILURE;
}
if ((preference_selected == PREFERENCE_TKIP) &&
(*akm_type == AssocAgentAuth_Auto)) {
*akm_type = AssocAgentAuth_Open;
}
/* Process AKM
* Preference order for AssocAgentAuth_Auto:
* FT Authentication using SAE 00-0F-AC:9 (not supported in embedded
* supplicant) SAE Authentication 00-0F-AC:8 OWE Authentication
* 00-0F-AC:18 FT Authentication using PSK 00-0F-AC:4 (not supported in
* embedded supplicant) PSK using SHA-256 00-0F-AC:6 PSK 00-0F-AC:2
*/
ptr = ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) + pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN;
akm_suite_count = wlan_le16_to_cpu(*(t_u16 *)ptr);
ptr += sizeof(t_u16); // move pointer to AKM suite
akm_type_selected = 0;
if (*akm_type == AssocAgentAuth_Auto) {
// find the best one
for (i = 0; i < akm_suite_count; i++) {
if ((ptr[3] < sizeof(akm_preference)) &&
(akm_preference[ptr[3]] > akm_type_selected)) {
akm_type_selected = akm_preference[ptr[3]];
akm_type_id = ptr[3];
}
ptr += AKM_SUITE_LEN;
}
if (akm_type_selected) {
if (akm_type_id == 6)
*akm_type = AssocAgentAuth_Open;
else if (akm_type_id == 2)
*akm_type = AssocAgentAuth_Open;
else if (akm_type_id == 18)
*akm_type = AssocAgentAuth_Owe;
else if (akm_type_id == 8)
*akm_type = AssocAgentAuth_Wpa3Sae;
}
} else {
// find the matched AKM
for (i = 0; i < akm_suite_count; i++) {
if (ptr[3] < sizeof(akm_preference)) {
if ((*akm_type == AssocAgentAuth_Open) &&
(ptr[3] == 6)) {
break;
} else if ((*akm_type == AssocAgentAuth_Open) &&
(ptr[3] == 2)) {
break;
} else if ((*akm_type ==
AssocAgentAuth_Wpa3Sae) &&
(ptr[3] == 8)) {
break;
} else if ((*akm_type == AssocAgentAuth_Owe) &&
(ptr[3] == 18)) {
break;
}
} else if (!memcmp(pmadapter, temp, sha_256_oui,
AKM_SUITE_LEN)) {
found = 1;
break;
}
temp += AKM_SUITE_LEN;
temp_akm_suite_count--;
ptr += AKM_SUITE_LEN;
}
if (found) {
/* Copy SHA256 as AKM suite */
memcpy_ext(pmadapter,
ptlv_rsn_ie->rsn_ie +
(sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) +
pairwise_cipher_count *
PAIRWISE_CIPHER_SUITE_LEN +
sizeof(t_u16)),
temp, AKM_SUITE_LEN, AKM_SUITE_LEN);
/* Shift remaining bytes of RSN IE after this */
memmove(pmadapter,
ptlv_rsn_ie->rsn_ie +
(sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) +
pairwise_cipher_count *
PAIRWISE_CIPHER_SUITE_LEN +
sizeof(t_u16) + AKM_SUITE_LEN),
ptlv_rsn_ie->rsn_ie +
(sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) +
pairwise_cipher_count *
PAIRWISE_CIPHER_SUITE_LEN +
sizeof(t_u16) +
akm_suite_count * AKM_SUITE_LEN),
ptlv_rsn_ie->header.len -
(sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) +
pairwise_cipher_count *
PAIRWISE_CIPHER_SUITE_LEN +
sizeof(t_u16) +
akm_suite_count * AKM_SUITE_LEN));
ptlv_rsn_ie->header.len =
ptlv_rsn_ie->header.len -
(akm_suite_count - 1) * AKM_SUITE_LEN;
/* Update akm suite count */
akm_suite_count = 1;
*akm_suite_count_ptr = akm_suite_count;
if (i == akm_suite_count) {
akm_type_selected = 0; // not found
} else {
akm_type_selected = akm_preference[ptr[3]];
akm_type_id = ptr[3];
}
}
ptr = (t_u16 *)(ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) +
pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN +
sizeof(t_u16) + akm_suite_count * AKM_SUITE_LEN);
prsn_cap = ptr;
if (akm_type_selected == 0) {
PRINTM(MERROR, "RSNE: AKM Suite not found for authtype %d\n",
*akm_type);
return MLAN_STATUS_FAILURE;
}
/* Process RSNCAP */
ptr = ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) +
sizeof(t_u16) +
pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN +
sizeof(t_u16) + akm_suite_count * AKM_SUITE_LEN;
prsn_cap = (t_u16 *)ptr;
ap_mfpc = ((*prsn_cap & (0x1 << MFPC_BIT)) == (0x1 << MFPC_BIT));
ap_mfpr = ((*prsn_cap & (0x1 << MFPR_BIT)) == (0x1 << MFPR_BIT));
@ -734,15 +800,61 @@ static int wlan_update_rsn_ie(mlan_private *pmpriv,
((!ap_mfpc) && ap_mfpr) ||
(ap_mfpc && ap_mfpr && (!pmpriv->pmfcfg.mfpc))) {
PRINTM(MERROR,
"Mismatch in PMF config of STA and AP, can't associate to AP\n");
"RSNE: Mismatch in PMF config of STA and AP, can't associate to AP\n");
return MLAN_STATUS_FAILURE;
}
if ((pmpriv->pmfcfg.mfpr && pmpriv->pmfcfg.mfpc) ||
pmpriv->pmfcfg.mfpc) {
*prsn_cap |= PMF_MASK;
*prsn_cap &= pmf_mask;
}
*prsn_cap |= PMF_MASK;
*prsn_cap &= pmf_mask;
// PMKID
ptr += sizeof(t_u16);
if (end_ptr > ptr) {
pmkid_count = wlan_le16_to_cpu(*(t_u16 *)ptr);
ptr += sizeof(t_u16);
pmkid_list_ptr = ptr;
ptr += pmkid_count * PMKID_LEN;
}
// Group Mgmt Cipher Suite
if ((end_ptr > ptr) && (pmf_mask & PMF_MASK)) {
group_mgmt_cipher_suite_ptr = ptr;
}
/* Compose new RSNE */
// pairwiase
ptr = pairwise_cipher_count_ptr;
*(t_u16 *)ptr = wlan_cpu_to_le16(1);
ptr += sizeof(t_u16);
oui[3] = cipher_selected_id;
*(t_u32 *)ptr = *(t_u32 *)oui;
ptr += PAIRWISE_CIPHER_SUITE_LEN;
// akm
*(t_u16 *)ptr = wlan_cpu_to_le16(1);
ptr += sizeof(t_u16);
oui[3] = akm_type_id;
*(t_u32 *)ptr = *(t_u32 *)oui;
ptr += AKM_SUITE_LEN;
// RSNCAP
*(t_u16 *)ptr = wlan_cpu_to_le16(*prsn_cap);
ptr += sizeof(t_u16);
// PMKID list
if (pmkid_list_ptr || group_mgmt_cipher_suite_ptr) {
// Add PMKID
*(t_u16 *)ptr = wlan_cpu_to_le16(pmkid_count);
ptr += sizeof(t_u16);
if (pmkid_count) {
memcpy_ext(pmadapter, ptr, (t_u8 *)pmkid_list_ptr,
(pmkid_count * PMKID_LEN), (end_ptr - ptr));
ptr += pmkid_count * PMKID_LEN;
}
if (group_mgmt_cipher_suite_ptr) {
// Add Group Mgmt Cipher Suite
memcpy_ext(pmadapter, ptr,
(t_u8 *)group_mgmt_cipher_suite_ptr,
GROUP_MGMT_CIPHER_SUITE_LEN,
(end_ptr - ptr));
ptr += GROUP_MGMT_CIPHER_SUITE_LEN;
}
}
*rsn_ie_len = ptr - ptlv_rsn_ie->rsn_ie;
return ret;
}
@ -884,6 +996,7 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv,
t_u8 ft_akm = 0;
t_u8 oper_class;
t_u8 oper_class_flag = MFALSE;
t_u8 akm_type = 0;
MrvlIEtypes_HostMlme_t *host_mlme_tlv = MNULL;
MrvlIEtypes_PrevBssid_t *prev_bssid_tlv = MNULL;
t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0};
@ -961,7 +1074,8 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv,
PRINTM(MINFO, "ASSOC_CMD: Rates size = %d\n", rates_size);
/* Add the Authentication type to be used for Auth frames if needed */
if ((pmpriv->sec_info.authentication_mode != MLAN_AUTH_MODE_AUTO)) {
if ((pmpriv->sec_info.authentication_mode != MLAN_AUTH_MODE_AUTO) ||
(pbss_desc->owe_transition_mode == OWE_TRANS_MODE_OWE)) {
pauth_tlv = (MrvlIEtypes_AuthType_t *)pos;
pauth_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_AUTH_TYPE);
pauth_tlv->header.len = sizeof(pauth_tlv->auth_type);
@ -978,9 +1092,16 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv,
MLAN_AUTH_MODE_SAE)
pauth_tlv->auth_type =
wlan_cpu_to_le16(AssocAgentAuth_Wpa3Sae);
else if (!pmpriv->curr_bss_params.host_mlme &&
((pbss_desc->owe_transition_mode ==
OWE_TRANS_MODE_OWE) ||
pmpriv->sec_info.authentication_mode ==
MLAN_AUTH_MODE_OWE))
pauth_tlv->auth_type =
wlan_cpu_to_le16(AssocAgentAuth_Owe);
else
pauth_tlv->auth_type =
wlan_cpu_to_le16(MLAN_AUTH_MODE_OPEN);
wlan_cpu_to_le16(AssocAgentAuth_Open);
pos += sizeof(pauth_tlv->header) + pauth_tlv->header.len;
pauth_tlv->header.len = wlan_cpu_to_le16(pauth_tlv->header.len);
}
@ -1097,7 +1218,11 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv,
pmpriv->psapriv, rsn_wpa_ie_tmp, prsn_ie_tlv);
}
#endif
else if (pmpriv->sec_info.ewpa_enabled) {
else if (pmpriv->sec_info.ewpa_enabled ||
(pbss_desc->owe_transition_mode ==
OWE_TRANS_MODE_OWE) ||
(pmpriv->sec_info.authentication_mode ==
MLAN_AUTH_MODE_OWE)) {
prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *)pos;
if (pbss_desc->pwpa_ie) {
prsn_ie_tlv->header.type =
@ -1156,8 +1281,16 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv,
.data[0]),
prsn_ie_tlv->header.len,
prsn_ie_tlv->header.len);
ret = wlan_update_rsn_ie(pmpriv,
prsn_ie_tlv);
akm_type =
pauth_tlv ?
wlan_le16_to_cpu(
pauth_tlv
->auth_type) :
AssocAgentAuth_Auto;
ret = wlan_update_rsn_ie(
pmpriv, prsn_ie_tlv,
&prsn_ie_tlv->header.len,
&akm_type);
if (ret != MLAN_STATUS_SUCCESS) {
goto done;
}
@ -1174,8 +1307,29 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv,
prsn_ie_tlv->header.len;
prsn_ie_tlv->header.len = wlan_cpu_to_le16(
prsn_ie_tlv->header.len);
if ((pauth_tlv == MNULL) &&
(pmpriv->sec_info.authentication_mode ==
MLAN_AUTH_MODE_AUTO)) {
pauth_tlv =
(MrvlIEtypes_AuthType_t *)pos;
pauth_tlv->header.type =
wlan_cpu_to_le16(
TLV_TYPE_AUTH_TYPE);
pauth_tlv->header.len =
sizeof(pauth_tlv->auth_type);
pauth_tlv->auth_type =
wlan_cpu_to_le16(akm_type);
pos += sizeof(pauth_tlv->header) +
pauth_tlv->header.len;
pauth_tlv->header.len =
wlan_cpu_to_le16(
pauth_tlv->header.len);
}
}
if (pbss_desc->prsnx_ie) {
if ((pbss_desc->prsnx_ie) &&
(akm_type == AssocAgentAuth_Wpa3Sae)) {
prsnx_ie_tlv =
(MrvlIEtypes_SAE_PWE_Mode_t *)pos;
prsnx_ie_tlv->header.type =

View file

@ -1343,6 +1343,8 @@ typedef struct _mlan_private {
#ifdef USB
/** USB data port */
t_u32 port;
/** port Index */
t_u32 port_index;
#endif
/** Control TX AMPDU on infra link */
t_u8 txaggrctrl;
@ -1817,7 +1819,7 @@ typedef struct _usb_rx_deaggr_params {
usb_aggr_ctrl_cfg aggr_ctrl;
} usb_rx_deaggr_params;
#define MAX_USB_TX_PORT_NUM 1
#define MAX_USB_TX_PORT_NUM 2
/** data structure for USB Tx Aggregation */
typedef struct _usb_tx_aggr_params {
/** Tx aggregation control */
@ -1920,6 +1922,8 @@ typedef struct _mlan_init_para {
t_u32 dev_cap_mask;
/** oob independent reset mode */
t_u32 indrstcfg;
/** drcs channel time mode */
t_u32 drcs_chantime_mode;
/** passive to active scan */
t_u8 passive_to_active_scan;
/** uap max sta */
@ -2258,6 +2262,8 @@ typedef struct _mlan_usb_card {
/** USB sggregation supported by FW */
t_u8 fw_usb_aggr;
/** port status: MFALSE-port available MTRUE--port busy*/
t_u8 usb_port_status[MAX_USB_TX_PORT_NUM];
} mlan_usb_card, *pmlan_usb_card;
#endif
@ -2633,6 +2639,14 @@ struct _mlan_adapter {
/** Tx data endpoint address */
t_u8 tx_data_ep;
#endif
/** Multi channel status */
t_u8 mc_status;
#ifdef USB
/** port status: MFALSE-port available MTRUE--port busy*/
t_u8 usb_port_status[MAX_USB_TX_PORT_NUM];
/** usb tx ports */
t_u8 usb_tx_ports[MAX_USB_TX_PORT_NUM];
#endif
/** sleep_params_t */
sleep_params_t sleep_params;
@ -2808,6 +2822,7 @@ struct _mlan_adapter {
t_u8 coex_rx_winsize;
t_bool dfs_repeater;
t_u32 dfsr_channel;
t_bool mc_policy;
t_u8 chanrpt_param_bandcfg;
#if defined(PCIE)
mlan_buffer *ssu_buf;
@ -2860,6 +2875,19 @@ struct _mlan_adapter {
/** Ethernet packet type offset */
#define MLAN_ETHER_PKT_TYPE_OFFSET (12)
/** Rx packet Sniffer Operation Mode
*
* MODE1 : Can be enabled only in disconnected state.
*
* MODE3 : Can be enabled irrespective of active connection state.
* Both 802.11 and rtap headers are attached to all destined
* unicast data frames in the FW and uploaded to the host driver.
* Such frame will be duplicated in mlan, one for monitor interface
* and other for data interface, by reconstructing the 802.3 header.
*/
#define NET_MON_MODE_DISABLED 0
#define NET_MON_MODE1 1
#define NET_MON_MODE3 3
mlan_status wlan_cmd_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_void *pdata_buf);
@ -3328,11 +3356,61 @@ mlan_status wlan_ret_rx_pkt_coalesce_cfg(pmlan_private pmpriv,
const HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
#endif
mlan_status wlan_handle_event_multi_chan_info(pmlan_private pmpriv,
pmlan_buffer pevent);
#ifdef USB
/**
* @brief This function update the port status
*
* @param pmadapter A pointer to mlan_adapter
* @param port USB port
* @param status port status
*
* @return N/A
*/
static INLINE void wlan_update_port_status(pmlan_adapter pmadapter, t_u32 port,
t_u8 status)
{
int i;
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (port == pmadapter->usb_tx_ports[i]) {
pmadapter->pcard_usb->usb_port_status[i] = status;
break;
}
}
return;
}
inline t_u8 wlan_usb_data_sent(pmlan_adapter pmadapter);
void wlan_resync_usb_port(pmlan_adapter pmadapter);
/**
* @brief This function return port index
*
* @param pmadapter A pointer to mlan_adapter
* @param port USB port
* @return port index
*
*/
static INLINE t_u8 wlan_get_port_index(pmlan_adapter pmadapter, t_u32 port)
{
t_u8 i;
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (port == pmadapter->usb_tx_ports[i]) {
return i;
}
}
return 0;
}
#endif
#ifdef STA_SUPPORT
/** warm reset */
mlan_status wlan_misc_ioctl_warm_reset(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
#ifdef STA_SUPPORT
/** Process received packet */
mlan_status wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf);
/** ioctl handler for station mode */
@ -3699,6 +3777,15 @@ void wlan_check_sta_capability(pmlan_private priv, pmlan_buffer pevent,
t_u8 *wlan_get_specific_ie(pmlan_private priv, t_u8 *ie_buf, t_u8 ie_len,
IEEEtypes_ElementId_e id, t_u8 ext_id);
t_u8 wlan_is_wmm_ie_present(pmlan_adapter pmadapter, t_u8 *pbuf, t_u16 buf_len);
/** Ethernet II header */
typedef struct {
/** Ethernet II header destination address */
t_u8 dest_addr[MLAN_MAC_ADDR_LENGTH];
/** Ethernet II header source address */
t_u8 src_addr[MLAN_MAC_ADDR_LENGTH];
/** Ethernet II header length */
t_u16 ethertype;
} EthII_Hdr_t;
/**
* @brief This function checks whether a station TDLS link is enabled or not
@ -3789,6 +3876,27 @@ static INLINE int wlan_is_tx_pause(mlan_private *priv, t_u8 *ra)
}
t_u16 wlan_update_ralist_tx_pause(pmlan_private priv, t_u8 *mac, t_u8 tx_pause);
#if defined(USB)
/**
* @brief This function used to check if specific port is ready
*
* @param pmadapter A pointer to mlan_adapter
* @param port_index port index;
*
* @return MTRUE -- port is ready.
* MFALSE -- port is busy.
*/
static inline t_u8 wlan_is_port_ready(pmlan_adapter pmadapter, t_u32 port_index)
{
if (IS_USB(pmadapter->card_type))
return (pmadapter->pcard_usb->usb_port_status[port_index]) ?
MFALSE :
MTRUE;
else
return MTRUE;
}
#endif
#ifdef UAP_SUPPORT
mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf);
t_void wlan_drop_tx_pkts(pmlan_private priv);
@ -3985,6 +4093,38 @@ mlan_status wlan_misc_ioctl_rx_pkt_coalesce_config(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
#endif
mlan_status wlan_misc_ioctl_multi_chan_config(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
mlan_status wlan_cmd_multi_chan_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
t_void *pdata_buf);
mlan_status wlan_ret_multi_chan_cfg(pmlan_private pmpriv,
const HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
mlan_status wlan_misc_ioctl_multi_chan_policy(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
mlan_status wlan_cmd_multi_chan_policy(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_void *pdata_buf);
mlan_status wlan_ret_multi_chan_policy(pmlan_private pmpriv,
const HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
mlan_status wlan_misc_ioctl_drcs_config(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
mlan_status wlan_cmd_drcs_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_void *pdata_buf);
mlan_status wlan_ret_drcs_cfg(pmlan_private pmpriv,
const HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
void wlan_bt_coex_wlan_param_update_event(pmlan_private priv,
pmlan_buffer pevent);
@ -4140,6 +4280,10 @@ mlan_status wlan_ret_get_sensor_temp(pmlan_private pmpriv,
HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
/** Set/Get Country code */
mlan_status wlan_misc_ioctl_country_code(pmlan_adapter pmadapter,
mlan_ioctl_req *pioctl_req);
/**
* @brief RA based queueing
*

View file

@ -224,7 +224,7 @@ static mlan_status wlan_custom_ioctl_auto_delete(pmlan_private pmpriv,
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_adapter pmadapter = pmpriv->adapter;
t_u16 index = 0, insert = MFALSE, del_len;
t_u8 del_ie[MAX_IE_SIZE], ie[MAX_IE_SIZE];
t_u8 del_ie[MAX_IE_SIZE], ie[MAX_IE_SIZE] = {0};
t_s32 cnt, tmp_len = 0;
t_u8 *tmp_ie;
@ -1136,7 +1136,9 @@ t_void wlan_delay_func(mlan_adapter *pmadapter, t_u32 delay, t_delay_unit u)
break;
case MSEC:
delay *= 1000;
/* fall through */
upto_tv_sec += (delay / 1000000);
upto_tv_usec += (delay % 1000000);
break;
case USEC:
upto_tv_sec += (delay / 1000000);
upto_tv_usec += (delay % 1000000);
@ -2130,8 +2132,11 @@ t_void wlan_tdls_config(pmlan_private pmpriv, t_u8 enable)
tdls_all_cfg->u.tdls_config.enable = enable;
tdls_config->tdls_action = WLAN_TDLS_CONFIG;
/* Send command to firmware */
wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
0, MNULL, tdls_config);
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG,
HostCmd_ACT_GEN_SET, 0, MNULL, tdls_config);
if (ret)
PRINTM(MERROR, "Error sending cmd to FW\n");
PRINTM(MCMND, "tdls_config: enable=%d\n", enable);
if (tdls_config)
@ -2175,8 +2180,10 @@ static t_void wlan_tdls_cs_param_config(pmlan_private pmpriv)
tdls_all_cfg->u.tdls_cs_params.threshold_directlink = 0;
/* Send command to firmware */
wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
0, MNULL, tdls_config);
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG,
HostCmd_ACT_GEN_SET, 0, MNULL, tdls_config);
if (ret)
PRINTM(MERROR, "Error sending cmd to FW\n");
if (tdls_config)
pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);
@ -2259,8 +2266,10 @@ static t_void wlan_tdls_cs_start(pmlan_private pmpriv, t_u8 *peer_mac_addr,
tdls_all_cfg->u.tdls_chan_switch.periodicity = 1;
/* Send command to firmware */
wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
0, MNULL, tdls_config);
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG,
HostCmd_ACT_GEN_SET, 0, MNULL, tdls_config);
if (ret)
PRINTM(MERROR, "Error sending cmd to FW\n");
if (tdls_config)
pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);
@ -4942,6 +4951,122 @@ mlan_status wlan_misc_ioctl_rx_pkt_coalesce_config(pmlan_adapter pmadapter,
return ret;
}
#endif
/**
* @brief Get/Set channel time and buffer weight configuration
*
* @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_multi_chan_config(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_misc_cfg *misc = MNULL;
t_u16 cmd_action = 0;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
misc = (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_CMD_MULTI_CHAN_CONFIG,
cmd_action, 0, (t_void *)pioctl_req,
&misc->param.multi_chan_cfg);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
/**
* @brief Get/Set multi-channel policy setting
*
* @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_multi_chan_policy(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_misc_cfg *misc = MNULL;
t_u16 cmd_action = 0;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
if (pioctl_req->action == MLAN_ACT_SET) {
if (pmadapter->dfs_repeater) {
PRINTM(MMSG,
"DFS-Repeater is on, can not enable DRCS\n");
ret = MLAN_STATUS_FAILURE;
goto fail;
}
cmd_action = HostCmd_ACT_GEN_SET;
} else {
cmd_action = HostCmd_ACT_GEN_GET;
}
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MULTI_CHAN_POLICY,
cmd_action, 0, (t_void *)pioctl_req,
&misc->param.multi_chan_policy);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
fail:
LEAVE();
return ret;
}
/**
* @brief Get/Set DRCS configuration
*
* @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_drcs_config(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_misc_cfg *misc = MNULL;
t_u16 cmd_action = 0;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
misc = (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_CMD_DRCS_CONFIG, cmd_action, 0,
(t_void *)pioctl_req, &misc->param.drcs_cfg);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
/**
* @brief Is any uAP started or STA connected?
@ -5008,6 +5133,14 @@ mlan_status wlan_misc_ioctl_dfs_repeater_cfg(pmlan_adapter pmadapter,
goto done;
}
/* If DRCS is on then we should not set
* DFS-repeater mode */
if (pmadapter->mc_policy) {
PRINTM(MERROR,
"DFS-repeater cannot be started when DRCS is on\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
cmd_action = HostCmd_ACT_GEN_SET;
} else {
cmd_action = HostCmd_ACT_GEN_GET;
@ -6324,18 +6457,6 @@ mlan_status wlan_misc_ioctl_net_monitor(pmlan_adapter pmadapter,
pmpriv = pmadapter->priv[pioctl_req->bss_index];
misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
if (misc->param.net_mon.enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) {
/* Net monitor IOCTL not allowed in connected state */
if (pmpriv->media_connected == MTRUE) {
PRINTM(MERROR,
"IOCTL not allowed in connected state\n");
pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
LEAVE();
return MLAN_STATUS_FAILURE;
}
}
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
@ -6899,6 +7020,98 @@ mlan_status wlan_misc_ioctl_range_ext(pmlan_adapter pmadapter,
return ret;
}
/**
* @brief Perform warm reset
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_PENDING --success, MLAN_STATUS_FAILURE
*/
mlan_status wlan_misc_ioctl_warm_reset(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
pmlan_buffer pmbuf;
t_s32 i = 0;
t_u16 mc_policy = pmadapter->mc_policy;
mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
ENTER();
mlan_block_rx_process(pmadapter, MTRUE);
/* Cancel all pending commands and complete ioctls */
if (misc->param.fw_reload)
wlan_cancel_all_pending_cmd(pmadapter, MTRUE);
/** Init all the head nodes and free all the locks here */
for (i = 0; i < pmadapter->priv_num; i++)
wlan_free_priv(pmadapter->priv[i]);
while ((pmbuf = (pmlan_buffer)util_dequeue_list(
pmadapter->pmoal_handle, &pmadapter->rx_data_queue,
pcb->moal_spin_lock, pcb->moal_spin_unlock))) {
pmadapter->ops.data_complete(pmadapter, pmbuf,
MLAN_STATUS_FAILURE);
}
pmadapter->rx_pkts_queued = 0;
/* Initialize adapter structure */
wlan_init_adapter(pmadapter);
pmadapter->hw_status = WlanHardwareStatusInitializing;
/* Initialize private structures */
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
wlan_init_priv(pmadapter->priv[i]);
}
mlan_block_rx_process(pmadapter, MFALSE);
if (misc->param.fw_reload != MTRUE) {
/* Restart the firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_FUNC_SHUTDOWN,
HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
if (ret)
goto done;
}
/* Issue firmware initialize commands for first BSS,
* for other interfaces it will be called after getting
* the last init command response of previous interface
*/
pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
if (!pmpriv) {
ret = MLAN_STATUS_FAILURE;
LEAVE();
return ret;
}
ret = wlan_adapter_get_hw_spec(pmpriv->adapter);
if (ret == MLAN_STATUS_FAILURE) {
LEAVE();
return ret;
}
ret = pmpriv->ops.init_cmd(pmpriv, MTRUE);
if (ret == MLAN_STATUS_FAILURE) {
LEAVE();
return ret;
}
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MULTI_CHAN_POLICY,
HostCmd_ACT_GEN_SET, 0, MNULL, &mc_policy);
if (ret == MLAN_STATUS_FAILURE) {
LEAVE();
return ret;
}
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
if (ret == MLAN_STATUS_PENDING)
pmadapter->pwarm_reset_ioctl_req = pioctl_req;
done:
LEAVE();
return ret;
}
#ifdef UAP_SUPPORT
/**
* @brief set wacp mode
@ -6964,3 +7177,72 @@ mlan_status wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter,
LEAVE();
return ret;
}
/**
* @brief This function sets up country code and downloads CMD to FW
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req Pointer to the IOCTL request buffer
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status wlan_misc_ioctl_country_code(pmlan_adapter pmadapter,
mlan_ioctl_req *pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_misc_country_code *country_code = MNULL;
mlan_ds_misc_cfg *cfg_misc = MNULL;
t_u8 cfp_bg = 0, cfp_a = 0;
ENTER();
cfg_misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
country_code = &cfg_misc->param.country_code;
if (pioctl_req->action == MLAN_ACT_SET) {
if (pmadapter->otp_region && pmadapter->otp_region->force_reg) {
PRINTM(MERROR,
"ForceRegionRule is set in the on-chip OTP"
"memory\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
/* Update region code and table based on country code */
if (wlan_misc_country_2_cfp_table_code(
pmadapter, country_code->country_code, &cfp_bg,
&cfp_a)) {
PRINTM(MERROR, "Country code not found!\n");
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
ret = MLAN_STATUS_FAILURE;
goto done;
}
pmadapter->cfp_code_bg = cfp_bg;
pmadapter->cfp_code_a = cfp_a;
if (cfp_a)
pmadapter->region_code = cfp_a;
else if (cfp_bg)
pmadapter->region_code = cfp_bg;
else
pmadapter->region_code = 0;
if (wlan_set_regiontable(pmpriv, pmadapter->region_code,
pmadapter->config_bands |
pmadapter->adhoc_start_band)) {
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
ret = MLAN_STATUS_FAILURE;
goto done;
}
memcpy_ext(pmadapter, pmadapter->country_code,
country_code->country_code, COUNTRY_CODE_LEN,
COUNTRY_CODE_LEN);
} else {
/* GET operation */
memcpy_ext(pmadapter, country_code->country_code,
pmadapter->country_code, COUNTRY_CODE_LEN,
COUNTRY_CODE_LEN);
}
done:
LEAVE();
return ret;
}

View file

@ -1740,6 +1740,7 @@ static mlan_status wlan_interpret_bss_desc_with_ie(pmlan_adapter pmadapter,
IEEEtypes_VendorSpecific_t *pvendor_ie;
const t_u8 wpa_oui[4] = {0x00, 0x50, 0xf2, 0x01};
const t_u8 wmm_oui[4] = {0x00, 0x50, 0xf2, 0x02};
const t_u8 owe_oui[4] = {0x50, 0x6f, 0x9a, 0x1c};
const t_u8 osen_oui[] = {0x50, 0x6f, 0x9a, 0x12};
IEEEtypes_CountryInfoSet_t *pcountry_info;
@ -2079,6 +2080,54 @@ static mlan_status wlan_interpret_bss_desc_with_ie(pmlan_adapter pmadapter,
(t_u8 *)&pbss_entry->wmm_ie,
total_ie_len);
}
} else if (IS_FW_SUPPORT_EMBEDDED_OWE(pmadapter) &&
!memcmp(pmadapter, pvendor_ie->vend_hdr.oui,
owe_oui, sizeof(owe_oui))) {
/* Current Format of OWE IE is
* element_id:element_len:oui:MAC Address:SSID
* length:SSID */
t_u8 trans_ssid_len = *(
pcurrent_ptr +
sizeof(IEEEtypes_Header_t) +
sizeof(owe_oui) + MLAN_MAC_ADDR_LENGTH);
if (!trans_ssid_len ||
trans_ssid_len > MRVDRV_MAX_SSID_LENGTH) {
bytes_left_for_current_beacon = 0;
continue;
}
if (!pcap_info->privacy)
pbss_entry->owe_transition_mode =
OWE_TRANS_MODE_OPEN;
else
pbss_entry->owe_transition_mode =
OWE_TRANS_MODE_OWE;
memcpy_ext(
pmadapter,
pbss_entry->trans_mac_address,
(pcurrent_ptr +
sizeof(IEEEtypes_Header_t) +
sizeof(owe_oui)),
MLAN_MAC_ADDR_LENGTH,
sizeof(pbss_entry->trans_mac_address));
pbss_entry->trans_ssid.ssid_len =
trans_ssid_len;
memcpy_ext(
pmadapter, pbss_entry->trans_ssid.ssid,
(pcurrent_ptr +
sizeof(IEEEtypes_Header_t) +
sizeof(owe_oui) +
MLAN_MAC_ADDR_LENGTH + sizeof(t_u8)),
trans_ssid_len,
sizeof(pbss_entry->trans_ssid.ssid));
PRINTM(MCMND,
"InterpretIE: OWE Transition AP privacy=%d MAC Addr-" MACSTR
" ssid %s\n",
pbss_entry->owe_transition_mode,
MAC2STR(pbss_entry->trans_mac_address),
pbss_entry->trans_ssid.ssid);
} else if (!memcmp(pmadapter, pvendor_ie->vend_hdr.oui,
osen_oui, sizeof(osen_oui))) {
pbss_entry->posen_ie =
@ -3781,6 +3830,13 @@ t_s32 wlan_is_network_compatible(mlan_private *pmpriv, t_u32 index, t_u32 mode)
LEAVE();
return index;
}
if ((pbss_desc->owe_transition_mode == OWE_TRANS_MODE_OPEN) &&
(pmpriv->sec_info.authentication_mode != MLAN_AUTH_MODE_OWE)) {
PRINTM(MINFO,
"Return success directly in OWE Transition mode\n");
LEAVE();
return index;
}
if (pmpriv->sec_info.osen_enabled && pbss_desc->posen_ie &&
((*(pbss_desc->posen_ie)).ieee_hdr.element_id ==
@ -3799,7 +3855,8 @@ t_s32 wlan_is_network_compatible(mlan_private *pmpriv, t_u32 index, t_u32 mode)
#ifdef DRV_EMBEDDED_SUPPLICANT
|| supplicantIsEnabled(pmpriv->psapriv)
#endif
)) {
|| pmpriv->sec_info.authentication_mode == MLAN_AUTH_MODE_OWE ||
pbss_desc->owe_transition_mode == OWE_TRANS_MODE_OWE)) {
if (((pbss_desc->pwpa_ie) &&
((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE)) ||
((pbss_desc->prsn_ie) &&
@ -4142,7 +4199,6 @@ mlan_status wlan_scan_networks(mlan_private *pmpriv, t_void *pioctl_buf,
t_u8 filtered_scan;
t_u8 scan_current_chan_only;
t_u8 max_chan_per_scan;
t_u8 i;
ENTER();
@ -4209,8 +4265,6 @@ mlan_status wlan_scan_networks(mlan_private *pmpriv, t_void *pioctl_buf,
} else {
wlan_scan_delete_ageout_entry(pmpriv);
}
for (i = 0; i < pmadapter->num_in_chan_stats; i++)
pmadapter->pchan_stats[i].cca_scan_duration = 0;
pmadapter->idx_chan_stats = 0;
ret = wlan_scan_channel_list(pmpriv, pioctl_buf, max_chan_per_scan,

View file

@ -976,7 +976,7 @@ static mlan_status wlan_sdio_prog_fw_w_helper(pmlan_adapter pmadapter, t_u8 *fw,
t_u8 *firmware = fw;
t_u32 firmwarelen = fw_len;
t_u32 offset = 0;
t_u32 base0, base1;
t_u32 base0 = 0, base1;
t_void *tmpfwbuf = MNULL;
t_u32 tmpfwbufsz;
t_u8 *fwbuf;

View file

@ -170,7 +170,6 @@ static void wlan_process_pending_ioctl(mlan_adapter *pmadapter)
}
break;
#endif
#ifdef STA_SUPPORT
case MLAN_IOCTL_MISC_CFG:
misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
if (misc->sub_command == MLAN_OID_MISC_WARM_RESET) {
@ -179,7 +178,6 @@ static void wlan_process_pending_ioctl(mlan_adapter *pmadapter)
pioctl_buf);
}
break;
#endif
default:
break;
}
@ -442,6 +440,7 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
pmadapter->multiple_dtim = pmdevice->multi_dtim;
pmadapter->inact_tmo = pmdevice->inact_tmo;
pmadapter->init_para.drcs_chantime_mode = pmdevice->drcs_chantime_mode;
pmadapter->hs_wake_interval = pmdevice->hs_wake_interval;
if (pmdevice->indication_gpio != 0xff) {
pmadapter->ind_gpio = pmdevice->indication_gpio & 0x0f;
@ -459,6 +458,8 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
pmadapter->rx_cmd_ep = pmdevice->rx_cmd_ep;
pmadapter->tx_data_ep = pmdevice->tx_data_ep;
pmadapter->rx_data_ep = pmdevice->rx_data_ep;
pmadapter->usb_tx_ports[0] = pmdevice->tx_data_ep;
pmadapter->usb_tx_ports[1] = pmdevice->tx_data2_ep;
}
#endif
pmadapter->init_para.dfs53cfg = pmdevice->dfs53cfg;
@ -1525,6 +1526,9 @@ mlan_status mlan_write_data_async_complete(t_void *padapter, pmlan_buffer pmbuf,
wlan_free_mlan_buffer(pmadapter, pmbuf);
} else {
pmadapter->data_sent = MFALSE;
wlan_update_port_status(pmadapter, port, MFALSE);
PRINTM(MDATA, "mlan_write_data_async_complete: DATA(%d)\n",
port);
ret = wlan_write_data_complete(pmadapter, pmbuf, status);
}
@ -1548,9 +1552,9 @@ mlan_status mlan_recv(t_void *padapter, pmlan_buffer pmbuf, t_u32 port)
mlan_adapter *pmadapter = (mlan_adapter *)padapter;
t_u8 *pbuf;
t_u32 len, recv_type;
t_u32 event_cause;
t_u32 event_cause = 0;
#ifdef DEBUG_LEVEL1
t_u32 sec, usec;
t_u32 sec = 0, usec = 0;
#endif
t_u32 max_rx_data_size = MLAN_RX_DATA_BUF_SIZE;

View file

@ -2669,13 +2669,15 @@ mlan_status wlan_cmd_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
cmd->command = wlan_cpu_to_le16(cmd->command);
cmd_net_mon->action = wlan_cpu_to_le16(cmd_action);
if (cmd_action == HostCmd_ACT_GEN_SET) {
cmd_net_mon->enable_net_mon =
wlan_cpu_to_le16((t_u16)net_mon->enable_net_mon);
if (net_mon->enable_net_mon) {
pchan_band =
&cmd_net_mon->monitor_chan.chan_band_param[0];
cmd_net_mon->enable_net_mon =
wlan_cpu_to_le16((t_u16)NET_MON_MODE1);
cmd_net_mon->filter_flag =
wlan_cpu_to_le16((t_u16)net_mon->filter_flag);
}
if (net_mon->enable_net_mon && net_mon->channel) {
pchan_band =
&cmd_net_mon->monitor_chan.chan_band_param[0];
cmd_net_mon->monitor_chan.header.type =
wlan_cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
cmd_net_mon->monitor_chan.header.len =
@ -4017,6 +4019,17 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
pdata_buf);
break;
#endif
case HostCmd_CMD_MULTI_CHAN_CONFIG:
ret = wlan_cmd_multi_chan_cfg(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_MULTI_CHAN_POLICY:
ret = wlan_cmd_multi_chan_policy(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_DRCS_CONFIG:
ret = wlan_cmd_drcs_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
break;
case HostCMD_CONFIG_LOW_POWER_MODE:
ret = wlan_cmd_low_pwr_mode(pmpriv, cmd_ptr, pdata_buf);
break;

View file

@ -1318,11 +1318,16 @@ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv,
}
if (memcmp(pmpriv->adapter, pmpriv->gtk_rekey.kek,
zero_kek, sizeof(zero_kek)) != 0) {
wlan_prepare_cmd(
mlan_status ret = MLAN_STATUS_SUCCESS;
ret = wlan_prepare_cmd(
pmpriv,
HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
HostCmd_ACT_GEN_SET, 0, MNULL,
&pmpriv->gtk_rekey);
if (ret) {
PRINTM(MINFO,
"Error sending message to FW\n");
}
memset(pmpriv->adapter, &pmpriv->gtk_rekey, 0,
sizeof(mlan_ds_misc_gtk_rekey_data));
}
@ -1391,13 +1396,16 @@ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv,
wlan_le16_to_cpu(
pkey->key_param_set.key_params
.aes.key_len);
memcpy_ext(
pmpriv->adapter,
sec->param.encrypt_key.key_material,
pkey->key_param_set.key_params.aes.key,
sec->param.encrypt_key
.key_len = MIN(
sec->param.encrypt_key.key_len,
sizeof(sec->param.encrypt_key
.key_material));
sizeof(pkey->key_param_set.key_params
.aes.key)),
memcpy_ext(pmpriv->adapter,
sec->param.encrypt_key.key_material,
pkey->key_param_set.key_params.aes.key,
sec->param.encrypt_key.key_len,
sizeof(sec->param.encrypt_key.key_material));
memcpy_ext(
pmpriv->adapter,
sec->param.encrypt_key.pn,
@ -1410,13 +1418,16 @@ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv,
wlan_le16_to_cpu(
pkey->key_param_set.key_params
.cmac_aes.key_len);
memcpy_ext(pmpriv->adapter,
sec->param.encrypt_key.key_material,
pkey->key_param_set.key_params
.cmac_aes.key,
sec->param.encrypt_key.key_len,
sizeof(sec->param.encrypt_key
.key_material));
sec->param.encrypt_key
.key_len = MIN(
sec->param.encrypt_key.key_len,
sizeof(pkey->key_param_set.key_params
.cmac_aes.key)),
memcpy_ext(pmpriv->adapter,
sec->param.encrypt_key.key_material,
pkey->key_param_set.key_params.cmac_aes.key,
sec->param.encrypt_key.key_len,
sizeof(sec->param.encrypt_key.key_material));
memcpy_ext(pmpriv->adapter,
sec->param.encrypt_key.pn,
pkey->key_param_set.key_params
@ -1429,13 +1440,16 @@ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv,
wlan_le16_to_cpu(
pkey->key_param_set.key_params
.wep.key_len);
memcpy_ext(
pmpriv->adapter,
sec->param.encrypt_key.key_material,
pkey->key_param_set.key_params.wep.key,
sec->param.encrypt_key
.key_len = MIN(
sec->param.encrypt_key.key_len,
sizeof(sec->param.encrypt_key
.key_material));
sizeof(pkey->key_param_set.key_params
.wep.key)),
memcpy_ext(pmpriv->adapter,
sec->param.encrypt_key.key_material,
pkey->key_param_set.key_params.wep.key,
sec->param.encrypt_key.key_len,
sizeof(sec->param.encrypt_key.key_material));
break;
}
}
@ -3216,6 +3230,10 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
break;
case HostCmd_CMD_RECONFIGURE_TX_BUFF:
wlan_set_tx_pause_flag(pmpriv, MFALSE);
#if defined(USB)
if (IS_USB(pmadapter->card_type))
wlan_resync_usb_port(pmadapter);
#endif
pmadapter->tx_buf_size =
(t_u16)wlan_le16_to_cpu(resp->params.tx_buf.buff_size);
@ -3383,6 +3401,15 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
ret = wlan_ret_rx_pkt_coalesce_cfg(pmpriv, resp, pioctl_buf);
break;
#endif
case HostCmd_CMD_MULTI_CHAN_CONFIG:
ret = wlan_ret_multi_chan_cfg(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_MULTI_CHAN_POLICY:
ret = wlan_ret_multi_chan_policy(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_DRCS_CONFIG:
ret = wlan_ret_drcs_cfg(pmpriv, resp, pioctl_buf);
break;
case HostCMD_CONFIG_LOW_POWER_MODE:
break;
case HostCmd_DFS_REPEATER_MODE:

View file

@ -171,6 +171,7 @@ static void wlan_parse_tdls_event(pmlan_private priv, pmlan_buffer pevent)
case TDLS_EVENT_TYPE_LINK_TORN_DOWN:
if (sta_ptr) {
if (sta_ptr->external_tdls) {
mlan_status ret = MLAN_STATUS_SUCCESS;
PRINTM(MMSG,
"Receive TDLS TEAR DOWN event, Disable TDLS LINK\n");
pmadapter->tdls_status = TDLS_TEAR_DOWN;
@ -183,10 +184,13 @@ static void wlan_parse_tdls_event(pmlan_private priv, pmlan_buffer pevent)
MLAN_MAC_ADDR_LENGTH);
/* Send command to firmware to delete tdls
* link*/
wlan_prepare_cmd(priv,
HostCmd_CMD_TDLS_OPERATION,
HostCmd_ACT_GEN_SET, 0,
(t_void *)MNULL, &tdls_oper);
ret = wlan_prepare_cmd(
priv, HostCmd_CMD_TDLS_OPERATION,
HostCmd_ACT_GEN_SET, 0, (t_void *)MNULL,
&tdls_oper);
if (ret)
PRINTM(MERROR,
"11D: failed to send cmd to FW\n");
ptdls_event->bss_index = priv->bss_index;
ptdls_event->event_id =
MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
@ -799,7 +803,12 @@ mlan_status wlan_ops_sta_process_event(t_void *priv)
if (pmadapter->pps_uapsd_mode && pmadapter->gen_null_pkt) {
if (MTRUE ==
wlan_check_last_packet_indication(pmpriv)) {
if (!pmadapter->data_sent) {
if (!pmadapter->data_sent
#if defined(USB)
&& wlan_is_port_ready(pmadapter,
pmpriv->port_index)
#endif
) {
if (wlan_send_null_packet(
pmpriv,
MRVDRV_TxPD_POWER_MGMT_NULL_PACKET |
@ -1258,6 +1267,10 @@ mlan_status wlan_ops_sta_process_event(t_void *priv)
eventcause, pevt_dat[0] + 1, pevt_dat[1] + 1,
pevt_dat[2], pevt_dat[3]);
} break;
case EVENT_MULTI_CHAN_INFO:
PRINTM(MEVENT, "EVENT: MULTI_CHAN_INFO\n");
wlan_handle_event_multi_chan_info(pmpriv, pmbuf);
break;
case EVENT_FW_DUMP_INFO:
PRINTM(MINFO, "EVENT: Dump FW info\n");

View file

@ -1016,12 +1016,6 @@ static mlan_status wlan_bss_ioctl_start(pmlan_adapter pmadapter,
ENTER();
if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) {
PRINTM(MINFO,
"Association is blocked in Channel Specified Network Monitor mode...\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
/* Before ASSOC REQ, If "port ctrl" mode is enabled,
* move the port to CLOSED state */
if (pmpriv->port_ctrl_mode == MTRUE) {
@ -2945,7 +2939,9 @@ static mlan_status wlan_sec_ioctl_set_wep_key(pmlan_adapter pmadapter,
goto exit;
if (!sec->param.encrypt_key.key_len) {
sec->param.encrypt_key.key_index = pwep_key->key_index;
sec->param.encrypt_key.key_len = pwep_key->key_length;
sec->param.encrypt_key.key_len =
MIN(pwep_key->key_length,
sizeof(pwep_key->key_material));
memcpy_ext(pmadapter,
sec->param.encrypt_key.key_material,
pwep_key->key_material,
@ -3994,89 +3990,6 @@ static mlan_status wlan_misc_ioctl_gen_ie(pmlan_adapter pmadapter,
return ret;
}
/**
* @brief Perform warm reset
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_PENDING --success, MLAN_STATUS_FAILURE
*/
mlan_status wlan_misc_ioctl_warm_reset(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
pmlan_buffer pmbuf;
t_s32 i = 0;
mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
ENTER();
mlan_block_rx_process(pmadapter, MTRUE);
/* Cancel all pending commands and complete ioctls */
if (misc->param.fw_reload)
wlan_cancel_all_pending_cmd(pmadapter, MTRUE);
/** Init all the head nodes and free all the locks here */
for (i = 0; i < pmadapter->priv_num; i++)
wlan_free_priv(pmadapter->priv[i]);
while ((pmbuf = (pmlan_buffer)util_dequeue_list(
pmadapter->pmoal_handle, &pmadapter->rx_data_queue,
pcb->moal_spin_lock, pcb->moal_spin_unlock))) {
pmadapter->ops.data_complete(pmadapter, pmbuf,
MLAN_STATUS_FAILURE);
}
pmadapter->rx_pkts_queued = 0;
/* Initialize adapter structure */
wlan_init_adapter(pmadapter);
pmadapter->hw_status = WlanHardwareStatusInitializing;
/* Initialize private structures */
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
wlan_init_priv(pmadapter->priv[i]);
}
mlan_block_rx_process(pmadapter, MFALSE);
if (misc->param.fw_reload != MTRUE) {
/* Restart the firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_FUNC_SHUTDOWN,
HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
if (ret)
goto done;
}
/* Issue firmware initialize commands for first BSS,
* for other interfaces it will be called after getting
* the last init command response of previous interface
*/
pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
if (!pmpriv) {
ret = MLAN_STATUS_FAILURE;
LEAVE();
return ret;
}
ret = wlan_adapter_get_hw_spec(pmpriv->adapter);
if (ret == MLAN_STATUS_FAILURE) {
LEAVE();
return ret;
}
ret = pmpriv->ops.init_cmd(pmpriv, MTRUE);
if (ret == MLAN_STATUS_FAILURE) {
LEAVE();
return ret;
}
if (ret == MLAN_STATUS_PENDING)
pmadapter->pwarm_reset_ioctl_req = pioctl_req;
done:
LEAVE();
return ret;
}
#ifdef SDIO
/**
* @brief Reconfigure SDIO multiport aggregation parameters
@ -4762,75 +4675,6 @@ done:
return ret;
}
/**
* @brief This function sets up country code and downloads CMD to FW
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req Pointer to the IOCTL request buffer
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
static mlan_status wlan_misc_ioctl_country_code(pmlan_adapter pmadapter,
mlan_ioctl_req *pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_misc_country_code *country_code = MNULL;
mlan_ds_misc_cfg *cfg_misc = MNULL;
t_u8 cfp_bg = 0, cfp_a = 0;
ENTER();
cfg_misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
country_code = &cfg_misc->param.country_code;
if (pioctl_req->action == MLAN_ACT_SET) {
if (pmadapter->otp_region && pmadapter->otp_region->force_reg) {
PRINTM(MERROR,
"ForceRegionRule is set in the on-chip OTP"
"memory\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
/* Update region code and table based on country code */
if (wlan_misc_country_2_cfp_table_code(
pmadapter, country_code->country_code, &cfp_bg,
&cfp_a)) {
PRINTM(MERROR, "Country code not found!\n");
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
ret = MLAN_STATUS_FAILURE;
goto done;
}
pmadapter->cfp_code_bg = cfp_bg;
pmadapter->cfp_code_a = cfp_a;
if (cfp_a)
pmadapter->region_code = cfp_a;
else if (cfp_bg)
pmadapter->region_code = cfp_bg;
else
pmadapter->region_code = 0;
if (wlan_set_regiontable(pmpriv, pmadapter->region_code,
pmadapter->config_bands |
pmadapter->adhoc_start_band)) {
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
ret = MLAN_STATUS_FAILURE;
goto done;
}
memcpy_ext(pmadapter, pmadapter->country_code,
country_code->country_code, COUNTRY_CODE_LEN,
COUNTRY_CODE_LEN);
} else {
/* GET operation */
memcpy_ext(pmadapter, country_code->country_code,
pmadapter->country_code, COUNTRY_CODE_LEN,
COUNTRY_CODE_LEN);
}
done:
LEAVE();
return ret;
}
/**
* @brief Configure MFPC and MFPR for management frame protection
*
@ -5318,6 +5162,17 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter,
case MLAN_OID_MISC_PMFCFG:
status = wlan_misc_pmfcfg(pmadapter, pioctl_req);
break;
case MLAN_OID_MISC_MULTI_CHAN_CFG:
status = wlan_misc_ioctl_multi_chan_config(pmadapter,
pioctl_req);
break;
case MLAN_OID_MISC_MULTI_CHAN_POLICY:
status = wlan_misc_ioctl_multi_chan_policy(pmadapter,
pioctl_req);
break;
case MLAN_OID_MISC_DRCS_CFG:
status = wlan_misc_ioctl_drcs_config(pmadapter, pioctl_req);
break;
#ifdef RX_PACKET_COALESCE
case MLAN_OID_MISC_RX_PACKET_COALESCE:
status = wlan_misc_ioctl_rx_pkt_coalesce_config(pmadapter,
@ -5579,13 +5434,6 @@ static mlan_status wlan_scan_ioctl(pmlan_adapter pmadapter,
return status;
}
if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) {
PRINTM(MINFO,
"Scan is blocked in Channel Specified Network Monitor mode...\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
if (pmadapter->scan_block && pioctl_req->action == MLAN_ACT_SET) {
PRINTM(MERROR, "Scan is blocked during association...\n");
LEAVE();
@ -5792,6 +5640,18 @@ mlan_status wlan_find_bss(mlan_private *pmpriv, pmlan_ioctl_req pioctl_req)
memcpy_ext(pmadapter, (t_u8 *)&bss->param.ssid_bssid.bssid,
(t_u8 *)&pbss_desc->mac_address,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
if (pbss_desc->owe_transition_mode) {
bss->param.ssid_bssid.owe_transition_mode =
pbss_desc->owe_transition_mode;
memcpy_ext(pmadapter, &bss->param.ssid_bssid.trans_ssid,
&pbss_desc->trans_ssid,
sizeof(mlan_802_11_ssid),
sizeof(mlan_802_11_ssid));
memcpy_ext(pmadapter,
(t_u8 *)&bss->param.ssid_bssid.trans_bssid,
(t_u8 *)&pbss_desc->trans_mac_address,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
}
bss->param.ssid_bssid.rssi = pbss_desc->rssi;
bss->param.ssid_bssid.channel = (t_u16)pbss_desc->channel;

View file

@ -42,17 +42,6 @@ Change log:
Local Variables
********************************************************/
/** Ethernet II header */
typedef struct {
/** Ethernet II header destination address */
t_u8 dest_addr[MLAN_MAC_ADDR_LENGTH];
/** Ethernet II header source address */
t_u8 src_addr[MLAN_MAC_ADDR_LENGTH];
/** Ethernet II header length */
t_u16 ethertype;
} EthII_Hdr_t;
/** IPv4 ARP request header */
typedef MLAN_PACK_START struct {
/** Hardware type */
@ -614,8 +603,10 @@ mlan_status wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num,
prx_pd->priority);
if (pmadapter->enable_net_mon) {
pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR;
goto mon_process;
if (prx_pd->rx_pkt_type == PKT_TYPE_802DOT11) {
pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR;
goto mon_process;
}
}
#ifdef DRV_EMBEDDED_SUPPLICANT

View file

@ -256,6 +256,12 @@ mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags)
ret = MLAN_STATUS_FAILURE;
goto done;
}
#if defined(USB)
if (!wlan_is_port_ready(pmadapter, priv->port_index)) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
#endif
pmbuf = wlan_alloc_mlan_buffer(pmadapter, data_len, 0,
MOAL_MALLOC_BUFFER);

View file

@ -315,7 +315,28 @@ t_void wlan_add_buf_bypass_txqueue(mlan_adapter *pmadapter, pmlan_buffer pmbuf)
*/
INLINE t_u8 wlan_bypass_tx_list_empty(mlan_adapter *pmadapter)
{
return (pmadapter->bypass_pkt_count) ? MFALSE : MTRUE;
#if defined(USB)
if (IS_USB(pmadapter->card_type)) {
pmlan_callbacks pcb = &pmadapter->callbacks;
pmlan_private priv;
int j = 0;
for (j = 0; j < pmadapter->priv_num; ++j) {
priv = pmadapter->priv[j];
if (priv) {
if (!wlan_is_port_ready(pmadapter,
priv->port_index))
continue;
if (util_peek_list(pmadapter->pmoal_handle,
&priv->bypass_txq,
pcb->moal_spin_lock,
pcb->moal_spin_unlock))
return MFALSE;
}
}
return MTRUE;
} else
#endif
return (pmadapter->bypass_pkt_count) ? MFALSE : MTRUE;
}
/**
@ -364,6 +385,11 @@ t_void wlan_process_bypass_tx(pmlan_adapter pmadapter)
for (j = 0; j < pmadapter->priv_num; ++j) {
priv = pmadapter->priv[j];
if (priv) {
#if defined(USB)
if (!wlan_is_port_ready(pmadapter,
priv->port_index))
continue;
#endif
pmbuf = (pmlan_buffer)util_dequeue_list(
pmadapter->pmoal_handle,
&priv->bypass_txq,

View file

@ -2293,6 +2293,11 @@ static mlan_status wlan_uap_ret_cmd_ap_config(pmlan_private pmpriv,
bss->param.bss_config.wpa_cfg
.pairwise_cipher_wpa2 =
tlv_pwk_cipher->pairwise_cipher;
if (wlan_le16_to_cpu(tlv_pwk_cipher->protocol) &
PROTOCOL_OWE)
bss->param.bss_config.wpa_cfg
.pairwise_cipher_wpa2 =
tlv_pwk_cipher->pairwise_cipher;
if (wlan_le16_to_cpu(tlv_pwk_cipher->protocol) &
PROTOCOL_WPA3_SAE)
bss->param.bss_config.wpa_cfg
@ -2670,6 +2675,7 @@ static mlan_status wlan_uap_ret_sys_config(pmlan_private pmpriv,
chan_band_tlv->bandcfg;
bss->param.ap_channel.channel =
chan_band_tlv->channel;
bss->param.ap_channel.center_chan = 0;
bss->param.ap_channel.is_11n_enabled =
pmpriv->is_11n_enabled;
pmpriv->uap_channel =
@ -3816,6 +3822,7 @@ static void wlan_check_uap_capability(pmlan_private priv, pmlan_buffer pevent)
priv->is_11n_enabled = MFALSE;
priv->is_11ac_enabled = MFALSE;
priv->is_11ax_enabled = MFALSE;
event->event_id = 0;
while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
tlv_type = wlan_le16_to_cpu(tlv->type);
@ -4788,6 +4795,17 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no,
case HostCmd_CMD_WMM_QUEUE_CONFIG:
ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf);
break;
case HostCmd_CMD_MULTI_CHAN_CONFIG:
ret = wlan_cmd_multi_chan_cfg(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_MULTI_CHAN_POLICY:
ret = wlan_cmd_multi_chan_policy(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_DRCS_CONFIG:
ret = wlan_cmd_drcs_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
break;
#ifdef RX_PACKET_COALESCE
case HostCmd_CMD_RX_PKT_COALESCE_CFG:
ret = wlan_cmd_rx_pkt_coalesce_cfg(pmpriv, cmd_ptr, cmd_action,
@ -5108,6 +5126,10 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
break;
case HostCmd_CMD_RECONFIGURE_TX_BUFF:
wlan_set_tx_pause_flag(pmpriv, MFALSE);
#if defined(USB)
if (IS_USB(pmadapter->card_type))
wlan_resync_usb_port(pmadapter);
#endif
pmadapter->tx_buf_size =
(t_u16)wlan_le16_to_cpu(resp->params.tx_buf.buff_size);
@ -5217,6 +5239,15 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
case HostCmd_CMD_WMM_QUEUE_CONFIG:
ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_MULTI_CHAN_CONFIG:
ret = wlan_ret_multi_chan_cfg(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_MULTI_CHAN_POLICY:
ret = wlan_ret_multi_chan_policy(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_DRCS_CONFIG:
ret = wlan_ret_drcs_cfg(pmpriv, resp, pioctl_buf);
break;
#ifdef RX_PACKET_COALESCE
case HostCmd_CMD_RX_PKT_COALESCE_CFG:
ret = wlan_ret_rx_pkt_coalesce_cfg(pmpriv, resp, pioctl_buf);
@ -5772,6 +5803,10 @@ mlan_status wlan_ops_uap_process_event(t_void *priv)
wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_FLUSH_RX_WORK, MNULL);
pevent->event_id = MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED;
break;
case EVENT_MULTI_CHAN_INFO:
PRINTM(MEVENT, "EVENT: MULTI_CHAN_INFO\n");
wlan_handle_event_multi_chan_info(pmpriv, pmbuf);
break;
case EVENT_FW_DEBUG_INFO:
memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE);

View file

@ -83,7 +83,8 @@ static t_bool wlan_can_radar_det_skip(mlan_private *priv)
* 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)) {
if (!priv->adapter->mc_policy &&
(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);
@ -285,13 +286,6 @@ static mlan_status wlan_uap_bss_ioctl_start(pmlan_adapter pmadapter,
ENTER();
if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) {
PRINTM(MINFO,
"BSS start is blocked in Channel Specified Network Monitor mode...\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
bss = (mlan_ds_bss *)pioctl_req->pbuf;
pmpriv->uap_host_based = bss->param.host_based;
if (!pmpriv->intf_state_11h.is_11h_host &&
@ -2165,6 +2159,17 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req 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_WARM_RESET) {
PRINTM(MCMND, "Request UAP WARM RESET\n");
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;
}
if (misc->sub_command == MLAN_OID_MISC_HOST_CMD)
status =
wlan_misc_ioctl_host_cmd(pmadapter, pioctl_req);
@ -2192,6 +2197,15 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
if (misc->sub_command == MLAN_OID_MISC_MAC_CONTROL)
status = wlan_misc_ioctl_mac_control(pmadapter,
pioctl_req);
if (misc->sub_command == MLAN_OID_MISC_MULTI_CHAN_CFG)
status = wlan_misc_ioctl_multi_chan_config(pmadapter,
pioctl_req);
if (misc->sub_command == MLAN_OID_MISC_MULTI_CHAN_POLICY)
status = wlan_misc_ioctl_multi_chan_policy(pmadapter,
pioctl_req);
if (misc->sub_command == MLAN_OID_MISC_DRCS_CFG)
status = wlan_misc_ioctl_drcs_config(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(
@ -2303,6 +2317,9 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
if (misc->sub_command == MLAN_OID_MISC_WACP_MODE)
status = wlan_misc_ioctl_wacp_mode(pmadapter,
pioctl_req);
if (misc->sub_command == MLAN_OID_MISC_COUNTRY_CODE)
status = wlan_misc_ioctl_country_code(pmadapter,
pioctl_req);
break;
case MLAN_IOCTL_POWER_CFG:
power = (mlan_ds_power_cfg *)pioctl_req->pbuf;

View file

@ -420,6 +420,7 @@ mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf)
pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
goto done;
}
if (rx_pkt_type != PKT_TYPE_BAR) {
priv->rxpd_rate = prx_pd->rx_rate;
priv->rxpd_rate_info = prx_pd->rate_info;
@ -465,6 +466,11 @@ mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf)
#endif
pmbuf->priority |= prx_pd->priority;
if (pmadapter->enable_net_mon &&
(prx_pd->rx_pkt_type == PKT_TYPE_802DOT11)) {
wlan_process_uap_rx_packet(priv, pmbuf);
goto done;
}
memcpy_ext(pmadapter, ta, prx_pkt->eth803_hdr.src_addr,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
if ((rx_pkt_type != PKT_TYPE_BAR) && (prx_pd->priority < MAX_NUM_TID)) {
@ -675,8 +681,10 @@ mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf)
MAC2STR(prx_pkt->eth803_hdr.dest_addr));
if (pmadapter->enable_net_mon) {
pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR;
goto upload;
if (prx_pd->rx_pkt_type == PKT_TYPE_802DOT11) {
pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR;
goto upload;
}
}
/* don't do packet forwarding in disconnected state */

View file

@ -688,7 +688,8 @@ static inline t_void wlan_usb_tx_send_aggr(pmlan_adapter pmadapter,
}
if (pmbuf_aggr && pmbuf_aggr->data_len) {
pmadapter->data_sent = MTRUE;
wlan_update_port_status(pmadapter, pusb_tx_aggr->port, MTRUE);
pmadapter->data_sent = wlan_usb_data_sent(pmadapter);
ret = pmadapter->callbacks.moal_write_data_async(
pmadapter->pmoal_handle, pmbuf_aggr,
pusb_tx_aggr->port);
@ -710,6 +711,8 @@ static inline t_void wlan_usb_tx_send_aggr(pmlan_adapter pmadapter,
wlan_write_data_complete(pmadapter, pmbuf_aggr, ret);
break;
case MLAN_STATUS_FAILURE:
wlan_update_port_status(pmadapter, pusb_tx_aggr->port,
MFALSE);
pmadapter->data_sent = MFALSE;
PRINTM(MERROR,
"Error: moal_write_data_async failed: 0x%X\n",
@ -719,6 +722,8 @@ static inline t_void wlan_usb_tx_send_aggr(pmlan_adapter pmadapter,
wlan_write_data_complete(pmadapter, pmbuf_aggr, ret);
break;
case MLAN_STATUS_PENDING:
wlan_update_port_status(pmadapter, pusb_tx_aggr->port,
MFALSE);
pmadapter->data_sent = MFALSE;
break;
case MLAN_STATUS_SUCCESS:
@ -964,13 +969,16 @@ t_void wlan_usb_tx_aggr_timeout_func(t_void *function_context)
{
usb_tx_aggr_params *pusb_tx_aggr =
(usb_tx_aggr_params *)function_context;
t_u8 port_index = 0;
pmlan_adapter pmadapter = (mlan_adapter *)pusb_tx_aggr->phandle;
pmlan_callbacks pcb = &pmadapter->callbacks;
ENTER();
pcb->moal_spin_lock(pmadapter->pmoal_handle, pusb_tx_aggr->paggr_lock);
pusb_tx_aggr->aggr_hold_timer_is_set = MFALSE;
if (pusb_tx_aggr->pmbuf_aggr && !pmadapter->data_sent &&
port_index = wlan_get_port_index(pmadapter, pusb_tx_aggr->port);
if (pusb_tx_aggr->pmbuf_aggr &&
wlan_is_port_ready(pmadapter, port_index) &&
!wlan_is_port_tx_paused(pmadapter, pusb_tx_aggr))
wlan_usb_tx_send_aggr(pmadapter, pusb_tx_aggr);
pcb->moal_spin_unlock(pmadapter->pmoal_handle,
@ -1135,6 +1143,98 @@ mlan_status wlan_usb_host_to_card_aggr(pmlan_adapter pmadapter,
return ret;
}
/**
* @brief This function used to check if any USB port still available
*
* @param pmadapter A pointer to mlan_adapter
*
* @return MTRUE--non of the port is available.
* MFALSE -- still have port available.
*/
inline t_u8 wlan_usb_data_sent(pmlan_adapter pmadapter)
{
int i;
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (pmadapter->pcard_usb->usb_port_status[i] == MFALSE)
return MFALSE;
}
return MTRUE;
}
/**
* @brief This function resync the USB tx port
*
* @param pmadapter A pointer to mlan_adapter
*
* @return N/A
*/
void wlan_resync_usb_port(pmlan_adapter pmadapter)
{
t_u32 active_port = pmadapter->usb_tx_ports[0];
int i;
/* MC is enabled */
if (pmadapter->mc_status) {
for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM);
i++) {
if (pmadapter->priv[i]) {
if (((GET_BSS_ROLE(pmadapter->priv[i]) ==
MLAN_BSS_ROLE_UAP) &&
!pmadapter->priv[i]->uap_bss_started) ||
((GET_BSS_ROLE(pmadapter->priv[i]) ==
MLAN_BSS_ROLE_STA) &&
!pmadapter->priv[i]->media_connected)) {
PRINTM(MINFO,
"Set deactive interface to default EP\n");
pmadapter->priv[i]->port =
pmadapter->usb_tx_ports[0];
;
pmadapter->priv[i]->port_index = 0;
}
}
}
/** Enable all the ports */
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++)
pmadapter->pcard_usb->usb_port_status[i] = MFALSE;
} else {
/* Get active port from connected interface */
for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM);
i++) {
if (pmadapter->priv[i]) {
if (((GET_BSS_ROLE(pmadapter->priv[i]) ==
MLAN_BSS_ROLE_UAP) &&
pmadapter->priv[i]->uap_bss_started) ||
((GET_BSS_ROLE(pmadapter->priv[i]) ==
MLAN_BSS_ROLE_STA) &&
pmadapter->priv[i]->media_connected)) {
active_port = pmadapter->priv[i]->port;
PRINTM(MEVENT, "active port=%d\n",
active_port);
break;
}
}
}
/** set all the interface to the same port */
for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM);
i++) {
if (pmadapter->priv[i]) {
pmadapter->priv[i]->port = active_port;
pmadapter->priv[i]->port_index =
wlan_get_port_index(pmadapter,
active_port);
}
}
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
if (active_port == pmadapter->usb_tx_ports[i])
pmadapter->pcard_usb->usb_port_status[i] =
MFALSE;
else
pmadapter->pcard_usb->usb_port_status[i] =
MTRUE;
}
}
return;
}
/**
* @brief This function wakes up the card.
*
@ -1214,7 +1314,9 @@ static mlan_status wlan_usb_host_to_card(pmlan_private pmpriv, t_u8 type,
ret = wlan_usb_host_to_card_aggr(pmadapter, pmbuf, tx_param,
pusb_tx_aggr);
} else {
pmadapter->data_sent = MTRUE;
pmadapter->pcard_usb->usb_port_status[pmpriv->port_index] =
MTRUE;
pmadapter->data_sent = wlan_usb_data_sent(pmadapter);
ret = pmadapter->callbacks.moal_write_data_async(
pmadapter->pmoal_handle, pmbuf, pmpriv->port);
switch (ret) {
@ -1225,9 +1327,13 @@ static mlan_status wlan_usb_host_to_card(pmlan_private pmpriv, t_u8 type,
break;
case MLAN_STATUS_FAILURE:
pmadapter->pcard_usb
->usb_port_status[pmpriv->port_index] = MFALSE;
pmadapter->data_sent = MFALSE;
break;
case MLAN_STATUS_PENDING:
pmadapter->pcard_usb
->usb_port_status[pmpriv->port_index] = MFALSE;
pmadapter->data_sent = MFALSE;
break;
case MLAN_STATUS_SUCCESS:

View file

@ -661,6 +661,18 @@ static raListTbl *wlan_wmm_get_highest_priolist_ptr(pmlan_adapter pmadapter,
/* Ignore data pkts from a BSS if tx pause */
goto next_intf;
}
#if defined(USB)
if (!wlan_is_port_ready(pmadapter,
priv_tmp->port_index)) {
PRINTM(MINFO,
"get_highest_prio_ptr(): "
"usb port is busy,Ignore pkts from BSS%d\n",
priv_tmp->bss_index);
/* Ignore data pkts from a BSS if usb port is
* busy */
goto next_intf;
}
#endif
pmadapter->callbacks.moal_spin_lock(
pmadapter->pmoal_handle,
@ -1945,6 +1957,10 @@ int wlan_wmm_lists_empty(pmlan_adapter pmadapter)
}
if (priv->tx_pause)
continue;
#if defined(USB)
if (!wlan_is_port_ready(pmadapter, priv->port_index))
continue;
#endif
if (util_scalar_read(
pmadapter->pmoal_handle,

View file

@ -24,7 +24,7 @@
#define _MLAN_DECL_H_
/** MLAN release version */
#define MLAN_RELEASE_VERSION "366.p5"
#define MLAN_RELEASE_VERSION "368"
/** Re-define generic data types for MLAN/MOAL */
/** Signed char (1-byte) */
@ -1747,6 +1747,15 @@ typedef struct {
t_u32 time_usec;
} wifi_timeval;
#define timeval_to_msec(timeval) \
(t_u64)((t_u64)(timeval.time_sec) * 1000 + \
(t_u64)(timeval.time_usec) / 1000)
#define timeval_to_usec(timeval) \
(t_u64)((t_u64)(timeval.time_sec) * 1000 * 1000 + \
(t_u64)(timeval.time_usec))
#define is_zero_timeval(timeval) \
((timeval.time_sec == 0) && (timeval.time_usec == 0))
#define MAX_NUM_RATE 32
#define MAX_RADIO 2
#define MAX_NUM_CHAN 1
@ -1828,15 +1837,6 @@ typedef struct {
t_u32 cca_busy_time;
} wifi_channel_stat;
#define timeval_to_msec(timeval) \
(t_u64)((t_u64)(timeval.time_sec) * 1000 + \
(t_u64)(timeval.time_usec) / 1000)
#define timeval_to_usec(timeval) \
(t_u64)((t_u64)(timeval.time_sec) * 1000 * 1000 + \
(t_u64)(timeval.time_usec))
#define is_zero_timeval(timeval) \
((timeval.time_sec == 0) && (timeval.time_usec == 0))
/** radio statistics */
typedef struct {
/** wifi radio (if multiple radio supported) */
@ -2322,6 +2322,8 @@ typedef struct _mlan_device {
t_u8 indication_gpio;
/** Dynamic MIMO-SISO switch for hscfg*/
t_u8 hs_mimo_switch;
/** channel time and mode for DRCS*/
t_u32 drcs_chantime_mode;
#ifdef USB
/** Tx CMD endpoint address */
t_u8 tx_cmd_ep;
@ -2332,6 +2334,8 @@ typedef struct _mlan_device {
t_u8 rx_data_ep;
/** Tx data endpoint address */
t_u8 tx_data_ep;
/** Tx data second endpoint address */
t_u8 tx_data2_ep;
#endif
/** passive to active scan */
t_u8 passive_to_active_scan;

View file

@ -1939,6 +1939,11 @@ typedef MLAN_PACK_START struct {
} MLAN_PACK_END wlan_bgscan_cfg;
#endif /* STA_SUPPORT */
/** The open AP in OWE transmition Mode */
#define OWE_TRANS_MODE_OPEN 1
/** The security AP in OWE trsnsition Mode */
#define OWE_TRANS_MODE_OWE 2
#ifdef PRAGMA_PACK
#pragma pack(pop)
#endif
@ -1953,6 +1958,15 @@ typedef struct _BSSDescriptor_t {
/** SSID */
mlan_802_11_ssid ssid;
/** Transition MAC address */
mlan_802_11_mac_addr trans_mac_address;
/** Transition SSID */
mlan_802_11_ssid trans_ssid;
/** OWE Transition mode */
t_u8 owe_transition_mode;
/** WEP encryption requirement */
t_u32 privacy;

View file

@ -293,6 +293,8 @@ enum _mlan_ioctl_req_id {
#if defined(STA_SUPPORT)
MLAN_OID_MISC_PMFCFG = 0x00200022,
#endif
MLAN_OID_MISC_MULTI_CHAN_CFG = 0x00200023,
MLAN_OID_MISC_MULTI_CHAN_POLICY = 0x00200024,
#ifdef WIFI_DIRECT_SUPPORT
MLAN_OID_MISC_WIFI_DIRECT_CONFIG = 0x00200025,
#endif
@ -319,6 +321,7 @@ enum _mlan_ioctl_req_id {
MLAN_OID_MISC_GET_CHAN_REGION_CFG = 0x00200046,
MLAN_OID_MISC_CLOUD_KEEP_ALIVE = 0x00200048,
MLAN_OID_MISC_OPER_CLASS_CHECK = 0x00200049,
MLAN_OID_MISC_DRCS_CFG = 0x00200050,
MLAN_OID_MISC_CWMODE_CTRL = 0x00200051,
MLAN_OID_MISC_AGGR_CTRL = 0x00200052,
@ -766,6 +769,11 @@ typedef struct _mlan_ssid_bssid {
t_u8 host_mlme;
/** assoicate resp frame/ie from firmware */
mlan_ds_misc_assoc_rsp assoc_rsp;
t_u8 owe_transition_mode;
/** Transition SSID */
mlan_802_11_ssid trans_ssid;
/** Transition BSSID */
mlan_802_11_mac_addr trans_bssid;
} mlan_ssid_bssid, *pmlan_ssid_bssid;
/** Data structure of WMM ECW */
@ -911,6 +919,8 @@ typedef struct _mlan_deauth_param {
#define PROTOCOL_WAPI 0x80
/** WPA3 SAE */
#define PROTOCOL_WPA3_SAE 0x100
/** OWE */
#define PROTOCOL_OWE 0x200
/** Key_mgmt_psk */
#define KEY_MGMT_NONE 0x04
@ -2592,6 +2602,7 @@ enum _mlan_auth_mode {
MLAN_AUTH_MODE_SHARED = 0x01,
MLAN_AUTH_MODE_FT = 0x02,
MLAN_AUTH_MODE_SAE = 0x03,
MLAN_AUTH_MODE_OWE = 0x04,
MLAN_AUTH_MODE_NETWORKEAP = 0x80,
MLAN_AUTH_MODE_AUTO = 0xFF,
};
@ -2604,6 +2615,7 @@ typedef enum {
AssocAgentAuth_FastBss_Skip,
AssocAgentAuth_Network_EAP,
AssocAgentAuth_Wpa3Sae = 6,
AssocAgentAuth_Owe = 7,
AssocAgentAuth_Auto,
} AssocAgentAuthType_e;
@ -4065,10 +4077,19 @@ typedef struct _mlan_ds_11ax_txop_cmd {
} mlan_ds_11ax_txop_cmd, *pmlan_ds_11ax_txop_cmd;
/** Type definition of mlan_ds_11ax_htc_cmd for MLAN_OID_11AX_CMD_CFG */
typedef struct _mlan_ds_11ax_txomi_cmd {
typedef struct MLAN_PACK_START_mlan_ds_11ax_txomi_cmd {
/* 11ax spec 9.2.4.6a.2 OM Control 12 bits. Bit 0 to bit 11 */
t_u16 omi;
} mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd;
/* tx option
* 0: send OMI in QoS NULL; 1: send OMI in QoS data; 0xFF: set OMI in
* both
*/
t_u8 tx_option;
/* if OMI is sent in QoS data, specify the number of consecutive data
* packets containing the OMI
*/
t_u8 num_data_pkts;
} MLAN_PACK_END mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd;
/** Type definition of mlan_ds_11ax_toltime_cmd for MLAN_OID_11AX_CMD_CFG */
typedef struct _mlan_ds_11ax_toltime_cmd {
@ -4471,12 +4492,13 @@ enum _mlan_func_cmd {
MLAN_FUNC_SHUTDOWN,
};
/** Net monitor filter: management frame */
#define MLAN_NETMON_MANAGEMENT_FRAME MBIT(0)
/** Net monitor filter: control frame */
#define MLAN_NETMON_CONTROL_FRAME MBIT(1)
/** Net monitor filter: data frame */
#define MLAN_NETMON_DATA_FRAME MBIT(2)
/* Net monitor filters: */
/* management frame */
#define MLAN_NETMON_MANAGEMENT MBIT(0)
/* control frame */
#define MLAN_NETMON_CONTROL MBIT(1)
/* data frame */
#define MLAN_NETMON_DATA MBIT(2)
typedef struct _mlan_ds_misc_net_monitor {
/** Enable/disable network monitor */
@ -4912,6 +4934,31 @@ typedef struct _mlan_ds_misc_pmfcfg {
} mlan_ds_misc_pmfcfg;
#endif
typedef MLAN_PACK_START struct _mlan_ds_multi_chan_cfg {
/** Channel Time */
t_u32 channel_time;
/** Buffer Weight */
t_u8 buffer_weight;
/** tlv len */
t_u16 tlv_len;
/** TLV buffer */
t_u8 tlv_buf[];
} MLAN_PACK_END mlan_ds_multi_chan_cfg;
typedef MLAN_PACK_START struct _mlan_ds_drcs_cfg {
/** Channel Index*/
t_u16 chan_idx;
/** Channel time (in TU) for chan_idx */
t_u8 chantime;
/** Channel swith time (in TU) for chan_idx */
t_u8 switchtime;
/** Undoze time (in TU) for chan_idx */
t_u8 undozetime;
/** Rx traffic control scheme when channel switch*/
/** only valid for GC/STA interface*/
t_u8 mode;
} MLAN_PACK_END mlan_ds_drcs_cfg;
#define MAX_SSID_NUM 16
#define MAX_AP_LIST 8
#define RETRY_UNLIMITED_TIME 0xFF
@ -5627,7 +5674,7 @@ struct MLAN_PACK_START mfg_Cmd_HE_TBTx_t {
/** AXQ Mu Timer */
t_u16 axq_mu_timer;
/** Tx Power */
t_u16 tx_power;
t_s16 tx_power;
} MLAN_PACK_END;
typedef struct _mlan_ds_misc_chnrgpwr_cfg {
@ -5684,6 +5731,7 @@ typedef struct _mlan_ds_ch_load {
t_s16 noise;
t_u16 rx_quality;
t_u16 duration;
t_u16 cca_th;
} mlan_ds_ch_load;
/** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */
@ -5770,6 +5818,13 @@ typedef struct _mlan_ds_misc_cfg {
#if defined(STA_SUPPORT)
mlan_ds_misc_pmfcfg pmfcfg;
#endif
/** Multi-channel config for MLAN_OID_MISC_MULTI_CHAN_CFG */
mlan_ds_multi_chan_cfg multi_chan_cfg;
/** Multi-channel policy for MLAN_OID_MISC_MULTI_CHAN_POLICY */
t_u16 multi_chan_policy;
/** channel drcs time slicing config for MLAN_OID_MISC_DRCS_CFG
*/
mlan_ds_drcs_cfg drcs_cfg[2];
#ifdef WIFI_DIRECT_SUPPORT
mlan_ds_wifi_direct_config p2p_config;
#endif

View file

@ -169,7 +169,8 @@ extern const struct net_device_ops woal_netdev_ops;
********************************************************/
#ifdef UAP_SUPPORT
#if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg);
int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg,
t_u8 wait_option);
#endif
#endif
@ -1483,7 +1484,7 @@ fail:
*/
#endif
int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index,
@ -1542,7 +1543,7 @@ int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
*/
#endif
int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index,
@ -1601,7 +1602,7 @@ int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
#endif
int woal_cfg80211_set_default_key(struct wiphy *wiphy,
struct net_device *netdev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index
@ -1636,7 +1637,7 @@ int woal_cfg80211_set_default_key(struct wiphy *wiphy,
#if KERNEL_VERSION(2, 6, 30) <= CFG80211_VERSION_CODE
int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
struct net_device *netdev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index)
@ -1650,7 +1651,7 @@ int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
#if KERNEL_VERSION(5, 10, 0) <= CFG80211_VERSION_CODE
int woal_cfg80211_set_default_beacon_key(struct wiphy *wiphy,
struct net_device *netdev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index)
@ -3572,9 +3573,10 @@ static t_u16 woal_filter_beacon_ies(moal_private *priv, const t_u8 *ie, int len,
"Retrieve 11ax cfg by channel=%d band=%d\n",
priv->channel, he_cfg.band);
if (0 == woal_11ax_cfg(priv,
MLAN_ACT_GET,
&he_cfg)) {
if (0 ==
woal_11ax_cfg(priv, MLAN_ACT_GET,
&he_cfg,
MOAL_IOCTL_WAIT)) {
hecap_ie = (IEEEtypes_HECap_t
*)&he_cfg
.he_cap.len;
@ -4041,7 +4043,8 @@ int woal_cfg80211_mgmt_frame_ie(
if ((beacon_ies && beacon_ies_len &&
beacon_ies_data->ie_length) ||
(beacon_ies_data->mgmt_subtype_mask ==
MLAN_CUSTOM_IE_DELETE_MASK)) {
MLAN_CUSTOM_IE_DELETE_MASK &&
beacon_vendor_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)) {
if (MLAN_STATUS_FAILURE ==
woal_cfg80211_custom_ie(
priv, beacon_ies_data, &beacon_vendor_index,
@ -4501,7 +4504,6 @@ done:
}
#endif
#if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE
/*
===============
11AX CAP for uAP
@ -4655,6 +4657,7 @@ static void woal_uap_update_11ax_ie(t_u8 band, mlan_ds_11ax_he_capa *hecap_ie)
return;
}
#if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE
/**
* @brief Sets up the CFG802.11 specific HE capability fields * with default
* values
@ -4745,7 +4748,71 @@ void woal_cfg80211_setup_he_cap(moal_private *priv,
done:
LEAVE();
}
#else
/**
* @brief setup uap he_cap based on FW he_cap
*
* @param priv A pointer to moal private structure
* @param wait_option wait_option
*
* @return N/A
*/
void woal_cfg80211_setup_uap_he_cap(moal_private *priv, t_u8 wait_option)
{
mlan_ds_11ax_he_capa *phe_cap = NULL;
mlan_ds_11ax_he_cfg he_cfg;
t_u8 hw_hecap_len;
mlan_fw_info fw_info;
#ifdef UAP_SUPPORT
int ret = 0;
#endif
woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info);
// Enable 2G 11AX on UAP
if (fw_info.fw_bands & BAND_GAX) {
memset(&he_cfg, 0, sizeof(he_cfg));
phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_2g_he_cap;
hw_hecap_len = fw_info.hw_2g_hecap_len;
if (hw_hecap_len) {
woal_uap_update_11ax_ie(BAND_2GHZ, phe_cap);
he_cfg.band = MBIT(0);
moal_memcpy_ext(priv->phandle, &he_cfg.he_cap, phe_cap,
hw_hecap_len,
sizeof(mlan_ds_11ax_he_capa));
DBG_HEXDUMP(MCMD_D, "2G HE_CFG ", (t_u8 *)&he_cfg,
sizeof(he_cfg));
#ifdef UAP_SUPPORT
ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg,
wait_option);
if (ret)
PRINTM(MERROR, "Fail to set 2G HE CAP\n");
#endif
}
}
// Enable 5G 11AX on UAP
if (fw_info.fw_bands & BAND_AAX) {
memset(&he_cfg, 0, sizeof(he_cfg));
phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_he_cap;
hw_hecap_len = fw_info.hw_hecap_len;
if (hw_hecap_len) {
woal_uap_update_11ax_ie(BAND_5GHZ, phe_cap);
he_cfg.band = MBIT(1);
moal_memcpy_ext(priv->phandle, &he_cfg.he_cap, phe_cap,
hw_hecap_len,
sizeof(mlan_ds_11ax_he_capa));
DBG_HEXDUMP(MCMD_D, "5G HE_CFG ", (t_u8 *)&he_cfg,
sizeof(he_cfg));
#ifdef UAP_SUPPORT
ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg,
wait_option);
if (ret)
PRINTM(MERROR, "Fail to set 5G HE CAP\n");
#endif
}
}
return;
}
#endif
/**

View file

@ -128,7 +128,7 @@ int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
int woal_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index,
@ -138,7 +138,7 @@ int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
const t_u8 *mac_addr, struct key_params *params);
int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index,
@ -213,7 +213,7 @@ int woal_cfg80211_set_channel(struct wiphy *wiphy,
#if KERNEL_VERSION(2, 6, 37) < CFG80211_VERSION_CODE
int woal_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *dev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index, bool ucast, bool mcast);
@ -225,7 +225,7 @@ int woal_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *dev,
#if KERNEL_VERSION(2, 6, 30) <= CFG80211_VERSION_CODE
int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
struct net_device *netdev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index);
@ -234,7 +234,7 @@ int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
#if KERNEL_VERSION(5, 10, 0) <= CFG80211_VERSION_CODE
int woal_cfg80211_set_default_beacon_key(struct wiphy *wiphy,
struct net_device *netdev,
#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13)
#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13)
int link_id,
#endif
t_u8 key_index);
@ -514,6 +514,8 @@ mlan_status woal_chandef_create(moal_private *priv,
#if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE
void woal_cfg80211_setup_he_cap(moal_private *priv,
struct ieee80211_supported_band *band);
#else
void woal_cfg80211_setup_uap_he_cap(moal_private *priv, t_u8 wait_option);
#endif
void woal_cfg80211_free_bands(struct wiphy *wiphy);
@ -542,4 +544,7 @@ void woal_clear_wiphy_dfs_state(struct wiphy *wiphy);
void woal_update_channel_dfs_state(t_u8 channel, t_u8 dfs_state);
int woal_get_wiphy_chan_dfs_state(struct wiphy *wiphy,
mlan_ds_11h_chan_dfs_state *ch_dfs_state);
mlan_status woal_reset_wifi(moal_handle *handle, t_u8 cnt, char *reason);
#endif /* _MOAL_CFG80211_H_ */

View file

@ -616,6 +616,7 @@ static int woal_cfg80211_subcmd_get_fw_version(struct wiphy *wiphy,
char end_c = '\0';
int ret = 0;
char fw_ver[32] = {0};
t_u8 hotfix_ver = 0;
union {
t_u32 l;
t_u8 c[4];
@ -623,9 +624,15 @@ static int woal_cfg80211_subcmd_get_fw_version(struct wiphy *wiphy,
ENTER();
hotfix_ver = priv->phandle->fw_hotfix_version;
ver.l = priv->phandle->fw_release_number;
snprintf(fw_ver, sizeof(fw_ver), "%u.%u.%u.p%u%c", ver.c[2], ver.c[1],
ver.c[0], ver.c[3], end_c);
if (hotfix_ver) {
snprintf(fw_ver, sizeof(fw_ver), "%u.%u.%u.p%u.%u%c", ver.c[2],
ver.c[1], ver.c[0], ver.c[3], hotfix_ver, end_c);
} else {
snprintf(fw_ver, sizeof(fw_ver), "%u.%u.%u.p%u%c", ver.c[2],
ver.c[1], ver.c[0], ver.c[3], end_c);
}
reply_len = strlen(fw_ver) + 1;
/** Allocate skb for cmd reply*/
@ -2851,7 +2858,7 @@ static int woal_cfg80211_subcmd_link_statistic_get(struct wiphy *wiphy,
* 24days.
*/
if (inter_msec > max_msec) {
PRINTM(MMSG,
PRINTM(MINFO,
"Out of range, set inter_msec=%llu to max_msec=%llu\n",
inter_msec, max_msec);
inter_msec = max_msec;

View file

@ -56,6 +56,9 @@ Change log:
#include "moal_cfg80211_util.h"
#endif
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
#include <linux/compat.h>
#endif
/********************************************************
Local Variables
@ -439,7 +442,7 @@ static int woal_setget_priv_11axcmdcfg(moal_private *priv, t_u8 *respbuf,
int ret = 0;
mlan_status status = MLAN_STATUS_SUCCESS;
int header_len = 0, user_data_len = 0;
int data[3] = {0};
int data[4] = {0};
ENTER();
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11ax_cmd_cfg));
@ -459,7 +462,7 @@ static int woal_setget_priv_11axcmdcfg(moal_private *priv, t_u8 *respbuf,
PRINTM(MINFO, "data_len=%d,data=%d,%d,%d\n", user_data_len, data[0],
data[1], data[2]);
if (user_data_len > 3 || user_data_len == 0) {
if (user_data_len > 4 || user_data_len == 0) {
PRINTM(MERROR, "Invalid parameters\n");
ret = -EFAULT;
goto done;
@ -496,6 +499,8 @@ static int woal_setget_priv_11axcmdcfg(moal_private *priv, t_u8 *respbuf,
case MLAN_11AXCMD_CFG_ID_TX_OMI:
cfg->sub_id = MLAN_11AXCMD_TXOMI_SUBID;
cfg->param.txomi_cfg.omi = data[1];
cfg->param.txomi_cfg.tx_option = data[2];
cfg->param.txomi_cfg.num_data_pkts = data[3];
break;
case MLAN_11AXCMD_CFG_ID_OBSSNBRU_TOLTIME:
cfg->sub_id = MLAN_11AXCMD_OBSS_TOLTIME_SUBID;
@ -3660,6 +3665,53 @@ done:
return ret;
}
/**
* @brief Get country code
*
* @param priv A pointer to moal_private structure
* @param country A pointer to country string
*
* @return 0--success, otherwise failure
*/
static int woal_get_countrycode(moal_private *priv, t_u8 *country)
{
int ret = 0;
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *pcfg_misc = NULL;
mlan_ds_misc_country_code *country_code = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
/* Fill request buffer */
pcfg_misc = (mlan_ds_misc_cfg *)req->pbuf;
country_code = &pcfg_misc->param.country_code;
pcfg_misc->sub_command = MLAN_OID_MISC_COUNTRY_CODE;
req->req_id = MLAN_IOCTL_MISC_CFG;
req->action = MLAN_ACT_GET;
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
moal_memcpy_ext(priv->phandle, country, country_code->country_code,
COUNTRY_CODE_LEN, COUNTRY_CODE_LEN);
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief Get cfp information
*
@ -8247,6 +8299,216 @@ done:
return ret;
}
/**
* @brief Set/Get channel time and buffer weight
*
* @param priv A pointer to moal_private structure
* @param respbuf A pointer to response buffer
* @param respbuflen Available length of response buffer
*
* @return Number of bytes written, negative for failure.
*/
static int woal_priv_multi_chan_config(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen)
{
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *cfg = NULL;
t_u8 *data_ptr;
int ret = 0;
int user_data_len = 0, header_len = 0;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
data_ptr = respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_MULTI_CHAN_CFG);
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MULTI_CHAN_CFG);
if ((int)strlen(respbuf) == header_len) {
/* GET operation */
user_data_len = 0;
} else {
/* SET operation */
user_data_len = sizeof(mlan_ds_multi_chan_cfg);
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
cfg = (mlan_ds_misc_cfg *)req->pbuf;
cfg->sub_command = MLAN_OID_MISC_MULTI_CHAN_CFG;
req->req_id = MLAN_IOCTL_MISC_CFG;
if (user_data_len == 0) {
req->action = MLAN_ACT_GET;
} else {
req->action = MLAN_ACT_SET;
moal_memcpy_ext(priv->phandle, &cfg->param.multi_chan_cfg,
data_ptr, sizeof(mlan_ds_multi_chan_cfg),
sizeof(mlan_ds_multi_chan_cfg));
}
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
moal_memcpy_ext(priv->phandle, respbuf,
(mlan_ds_multi_chan_cfg *)&cfg->param.multi_chan_cfg,
req->buf_len, respbuflen);
ret = req->buf_len;
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief Set/Get multi_channel policy setting
*
* @param priv A pointer to moal_private structure
* @param respbuf A pointer to response buffer
* @param respbuflen Available length of response buffer
*
* @return Number of bytes written, negative for failure.
*/
static int woal_priv_multi_chan_policy(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen)
{
int ret = 0;
int user_data_len = 0, header_len = 0;
int data = 0;
t_u16 enable;
t_u8 action;
ENTER();
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MULTI_CHAN_POLICY);
if ((int)strlen(respbuf) == header_len) {
/* GET operation */
user_data_len = 0;
} else {
/* SET operation */
parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
}
if (user_data_len > 1) {
PRINTM(MERROR, "Invalid number of arguments\n");
ret = -EINVAL;
goto done;
}
if (user_data_len == 0) {
action = MLAN_ACT_GET;
} else {
action = MLAN_ACT_SET;
enable = (t_u16)data;
}
if (MLAN_STATUS_SUCCESS !=
woal_mc_policy_cfg(priv, &enable, MOAL_IOCTL_WAIT, action)) {
ret = -EFAULT;
goto done;
}
moal_memcpy_ext(priv->phandle, respbuf, &enable, sizeof(t_u16),
respbuflen);
ret = sizeof(t_u16);
done:
LEAVE();
return ret;
}
/**
* @brief Set/Get drcs time slicing parameters
*
* @param priv A pointer to moal_private structure
* @param respbuf A pointer to response buffer
* @param respbuflen Available length of response buffer
*
* @return Number of bytes written, negative for failure.
*/
static int woal_priv_drcs_time_slicing_cfg(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen)
{
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *cfg = NULL;
mlan_ds_drcs_cfg *drcs_cfg = NULL;
t_u8 *data_ptr;
int ret = 0;
int user_data_len = 0, header_len = 0;
int data[8];
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
data_ptr = respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_DRCS_CFG);
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DRCS_CFG);
if ((int)strlen(respbuf) == header_len) {
/* GET operation */
user_data_len = 0;
} else {
/* SET operation */
memset((char *)data, 0, sizeof(data));
parse_arguments(data_ptr, data, ARRAY_SIZE(data),
&user_data_len);
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
cfg = (mlan_ds_misc_cfg *)req->pbuf;
cfg->sub_command = MLAN_OID_MISC_DRCS_CFG;
req->req_id = MLAN_IOCTL_MISC_CFG;
if (user_data_len == 0) {
req->action = MLAN_ACT_GET;
} else {
req->action = MLAN_ACT_SET;
drcs_cfg = (mlan_ds_drcs_cfg *)&cfg->param.drcs_cfg[0];
drcs_cfg->chantime = (t_u8)data[0];
drcs_cfg->switchtime = (t_u8)data[1];
drcs_cfg->undozetime = (t_u8)data[2];
drcs_cfg->mode = (t_u8)data[3];
/* Set the same parameters for two channels*/
if (user_data_len < (int)ARRAY_SIZE(data))
drcs_cfg->chan_idx = 0x03;
else {
/* Set the different parameters for two channels*/
drcs_cfg->chan_idx = 0x1;
drcs_cfg = (mlan_ds_drcs_cfg *)&cfg->param.drcs_cfg[1];
drcs_cfg->chan_idx = 0x2;
drcs_cfg->chantime = (t_u8)data[4];
drcs_cfg->switchtime = (t_u8)data[5];
drcs_cfg->undozetime = (t_u8)data[6];
drcs_cfg->mode = (t_u8)data[7];
}
}
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&cfg->param.drcs_cfg,
req->buf_len, respbuflen);
ret = req->buf_len;
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
#ifdef RX_PACKET_COALESCE
/**
* @brief Set/Get RX packet coalesceing setting
@ -9286,7 +9548,7 @@ static int woal_priv_auth_type(moal_private *priv, t_u8 *respbuf,
if (user_data_len == 1) {
PRINTM(MINFO, "SET: auth_type %d\n", auth_type);
if (((auth_type < MLAN_AUTH_MODE_OPEN) ||
(auth_type > MLAN_AUTH_MODE_SAE)) &&
(auth_type > MLAN_AUTH_MODE_OWE)) &&
(auth_type != MLAN_AUTH_MODE_AUTO)) {
ret = -EINVAL;
goto done;
@ -10851,27 +11113,20 @@ static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf,
/* SET operation */
parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
&user_data_len);
if (user_data_len == 1 || user_data_len == 4 ||
user_data_len == 5) {
if (data[0] != MFALSE &&
data[0] != CHANNEL_SPEC_SNIFFER_MODE) {
if (user_data_len == 1 || user_data_len == 2 ||
user_data_len == 4 || user_data_len == 5) {
if (data[0] != MTRUE && data[0] != MFALSE) {
PRINTM(MERROR,
"NET_MON: Activity should be enable(=1/2)/disable(=0)\n");
ret = -EINVAL;
goto done;
}
if ((data[0] == MFALSE && user_data_len != 1) ||
(data[0] == CHANNEL_SPEC_SNIFFER_MODE &&
(user_data_len != 4 && user_data_len != 5))) {
PRINTM(MERROR,
"NET_MON: Sniffer activity not match with user_data_len\n");
"NET_MON: Activity should be enable(=1)/"
"disable(=0)\n");
ret = -EINVAL;
goto done;
}
net_mon->enable_net_mon = data[0];
if (data[0] == CHANNEL_SPEC_SNIFFER_MODE) {
if (data[0] == MTRUE) {
int i;
if (user_data_len != 4 && user_data_len != 5) {
if (user_data_len != 2 && user_data_len != 4 &&
user_data_len != 5) {
PRINTM(MERROR,
"NET_MON: Invalid number of args!\n");
ret = -EINVAL;
@ -10879,9 +11134,9 @@ static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf,
}
/* Supported filter flags */
if (!data[1] ||
data[1] & ~(MLAN_NETMON_DATA_FRAME |
MLAN_NETMON_MANAGEMENT_FRAME |
MLAN_NETMON_CONTROL_FRAME)) {
data[1] & ~(MLAN_NETMON_DATA |
MLAN_NETMON_MANAGEMENT |
MLAN_NETMON_CONTROL)) {
PRINTM(MERROR,
"NET_MON: Invalid filter flag\n");
ret = -EINVAL;
@ -10962,8 +11217,7 @@ static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf,
if (req->action == MLAN_ACT_SET) {
if (data[0]) { /** Enable sniffer mode: 1/2 */
if (!handle->mon_if) {
mon_if = woal_prepare_mon_if(priv, "rtap", 0,
data[0]);
mon_if = woal_prepare_mon_if(priv, "rtap", 0);
if (!mon_if) {
PRINTM(MFATAL,
"Prepare mon_if fail.\n");
@ -10988,6 +11242,7 @@ static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf,
net_mon->channel;
handle->mon_if->band_chan_cfg.chan_bandwidth =
net_mon->chan_bandwidth;
handle->mon_if->flag = net_mon->filter_flag;
} else { /** Disable sniffer mode: 0 */
if (handle->mon_if) {
ndev = handle->mon_if->mon_ndev;
@ -11017,69 +11272,6 @@ done:
}
#endif
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
/**
* @brief Set/Get monitor mode
*
* @param priv A pointer to moal_private structure
* @param respbuf A pointer to response buffer
* @param respbuflen Available length of response buffer
*
* @return 0 --success, otherwise fail
*/
static int woal_priv_set_get_monitor_mode(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen)
{
int ret = 0;
int data = 0;
int user_data_len = 0, header_len = 0;
t_u32 action = MLAN_ACT_GET;
ENTER();
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MONITOR_MODE);
if ((int)strlen(respbuf) == header_len) {
/* GET operation */
user_data_len = 0;
action = MLAN_ACT_GET;
} else {
/* SET operation */
parse_arguments(respbuf + header_len, &data,
sizeof(data) / sizeof(int), &user_data_len);
action = MLAN_ACT_SET;
}
if (sizeof(int) * user_data_len > sizeof(data)) {
PRINTM(MERROR, "Too many arguments\n");
ret = -EINVAL;
goto done;
}
if (action == MLAN_ACT_SET) {
if (data == 1) {
priv->phandle->wiphy->interface_modes |=
MBIT(NL80211_IFTYPE_MONITOR);
} else if (data == 0) {
priv->phandle->wiphy->interface_modes &=
~(MBIT(NL80211_IFTYPE_MONITOR));
} else {
PRINTM(MERROR, "Invalid input arguments\n");
ret = -EINVAL;
goto done;
}
}
data = !!(priv->phandle->wiphy->interface_modes &
MBIT(NL80211_IFTYPE_MONITOR));
ret = sprintf(respbuf, "Monitor mode: %d\n", data) + 1;
done:
LEAVE();
return ret;
}
#endif
/**
* @brief This function get nop list.
*
@ -12266,6 +12458,8 @@ static void woal_auto_uap_channel_switch(moal_private *priv, t_u8 channel)
moal_handle *ref_handle;
t_u8 band_width = CHANNEL_BW_20MHZ;
memset(&chaninfo, 0, sizeof(chaninfo));
pmpriv = woal_get_active_uap_interface(priv->phandle);
if (!pmpriv) {
ref_handle = (moal_handle *)priv->phandle->pref_mac;
@ -12430,6 +12624,18 @@ static int woal_priv_do_dfs_cac(moal_private *priv, t_u8 *respbuf,
}
priv->chan_rpt_pending = MFALSE;
}
#ifdef UAP_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
if (!data[0] && priv->chan_rpt_req.chanNum) {
woal_update_channels_dfs_state(
priv,
priv->chan_rpt_req.chanNum,
priv->chan_rpt_req.bandcfg
.chanWidth,
DFS_USABLE);
}
#endif
#endif
memset(&priv->chan_rpt_req, 0,
sizeof(mlan_ds_11h_chan_rep_req));
PRINTM(MCMND, "DFS: Stop Radar detect\n");
@ -13055,6 +13261,7 @@ static int woal_priv_get_ch_load(moal_private *priv, t_u8 *respbuf,
misc->param.ch_load.noise = cl_cfg->noise;
misc->param.ch_load.rx_quality = cl_cfg->rx_quality;
misc->param.ch_load.duration = cl_cfg->duration;
misc->param.ch_load.cca_th = cl_cfg->cca_th;
status = woal_request_ioctl(priv, ioctl_req, MOAL_NO_WAIT);
if (status != MLAN_STATUS_SUCCESS && status != MLAN_STATUS_PENDING) {
ret = -EFAULT;
@ -19422,6 +19629,26 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
len = woal_priv_region_code(priv, buf,
priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DRCS_CFG,
strlen(PRIV_CMD_DRCS_CFG)) == 0) {
/* DRCS configuration for mc_cfg_ext*/
len = woal_priv_drcs_time_slicing_cfg(
priv, buf, priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP),
PRIV_CMD_MULTI_CHAN_CFG,
strlen(PRIV_CMD_MULTI_CHAN_CFG)) == 0) {
/* Channel time and buffer weight configuration */
len = woal_priv_multi_chan_config(priv, buf,
priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP),
PRIV_CMD_MULTI_CHAN_POLICY,
strlen(PRIV_CMD_MULTI_CHAN_POLICY)) == 0) {
/* Multi-channel Policy enable/disable */
len = woal_priv_multi_chan_policy(priv, buf,
priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_FWMACADDR,
strlen(PRIV_CMD_FWMACADDR)) == 0) {
/* Set FW MAC address */
@ -19668,20 +19895,6 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
len = woal_priv_net_monitor_ioctl(priv, buf,
priv_cmd.total_len);
goto handled;
#endif
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
} else if (strnicmp(buf + strlen(CMD_NXP),
PRIV_CMD_MONITOR_MODE,
strlen(PRIV_CMD_MONITOR_MODE)) == 0) {
if (IS_STA_CFG80211(cfg80211_wext)) {
/* Set/Get monitor mode */
len = woal_priv_set_get_monitor_mode(
priv, buf, priv_cmd.total_len);
} else
len = sprintf(buf,
"CFG80211 is not enabled\n") +
1;
goto handled;
#endif
} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS_TESTING,
strlen(PRIV_CMD_DFS_TESTING)) == 0) {
@ -20158,6 +20371,14 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
}
#endif
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "COUNTRYCODE", strlen("COUNTRYCODE")) == 0) {
memset(country_code, 0, sizeof(country_code));
if (MLAN_STATUS_SUCCESS !=
woal_get_countrycode(priv, country_code)) {
ret = -EFAULT;
goto done;
}
len = sprintf(buf, "%s\n", country_code) + 1;
} else if (strncmp(buf, "COUNTRY", strlen("COUNTRY")) == 0) {
copy_len = strlen(buf) - strlen("COUNTRY") - 1;
if (copy_len > COUNTRY_CODE_LEN || copy_len <= 0) {
@ -20180,14 +20401,16 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
}
#ifdef STA_CFG80211
if (IS_STA_CFG80211(cfg80211_wext)) {
PRINTM(MIOCTL, "Notify country code=%s\n",
country_code);
if (!moal_extflg_isset(priv->phandle,
EXT_DISABLE_REGD_BY_DRIVER))
EXT_DISABLE_REGD_BY_DRIVER)) {
PRINTM(MIOCTL, "Notify country code=%s\n",
country_code);
regulatory_hint(priv->wdev->wiphy,
country_code);
len = sprintf(buf, "OK\n") + 1;
goto done;
len = sprintf(buf, "OK\n") + 1;
goto done;
}
}
#endif
if (MLAN_STATUS_SUCCESS !=
@ -20788,9 +21011,11 @@ int woal_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ENTER();
#ifdef CONFIG_COMPAT
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
if (in_compat_syscall()) /* not implemented yet */
return -EOPNOTSUPP;
#endif
#endif
PRINTM(MINFO, "woal_do_ioctl: ioctl cmd = 0x%x\n", cmd);

View file

@ -215,9 +215,6 @@ typedef struct _chan_stats {
#endif
#define PRIV_CMD_SLEEP_PARAMS "sleepparams"
#define PRIV_CMD_NET_MON "netmon"
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
#define PRIV_CMD_MONITOR_MODE "monitormode"
#endif
#define PRIV_CMD_DFS_TESTING "dfstesting"
#define PRIV_CMD_CLEAR_NOP "clear_nop"
#define PRIV_CMD_NOP_LIST "nop_list"
@ -241,6 +238,9 @@ typedef struct _chan_stats {
#ifdef RX_PACKET_COALESCE
#define PRIV_CMD_RX_COAL_CFG "rxpktcoal_cfg"
#endif
#define PRIV_CMD_MULTI_CHAN_CFG "mc_cfg"
#define PRIV_CMD_MULTI_CHAN_POLICY "mc_policy"
#define PRIV_CMD_DRCS_CFG "mc_cfg_ext"
#ifdef WIFI_DIRECT_SUPPORT
#if defined(UAP_CFG80211)
#define PRIV_CMD_CFG_NOA "cfg_noa"

View file

@ -42,6 +42,7 @@ static char *mod_para;
/** Mfg mode */
int mfg_mode;
#endif
int rf_test_mode;
#if defined(SDIO)
/** SDIO interrupt mode (0: INT_MODE_SDIO, 1: INT_MODE_GPIO) */
@ -59,6 +60,7 @@ static int country_ie_ignore;
static int beacon_hints;
#endif
#endif
static int cfg80211_drcs;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
@ -68,6 +70,8 @@ static int host_mlme = 1;
static int roamoffload_in_hs;
static int drcs_chantime_mode;
/** Auto deep sleep */
static int auto_ds;
@ -131,6 +135,23 @@ static int slew_rate = 3;
#endif
int tx_work = 0;
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
/**
* RPS to steer packets to specific CPU
* Default value of 0 keeps rps disabled by default
*/
static int rps = 0;
/**
* rps cpu mask
* rps can be configure to any value between 0x1 - 0xf
* ex: value of 0x3(0011) indicates to use cpu-0 and cpu-1
*/
#define RPS_CPU_MASK 0xf
#endif
#endif
static int tx_skb_clone = 0;
#ifdef IMX_SUPPORT
static int pmqos = 1;
@ -647,7 +668,15 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size,
PRINTM(MMSG, "mfg_mode = %d\n", params->mfg_mode);
}
#endif
else if (strncmp(line, "drv_mode", strlen("drv_mode")) == 0) {
else if (strncmp(line, "rf_test_mode",
strlen("rf_test_mode")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->rf_test_mode = out_data;
PRINTM(MMSG, "rf_test_mode = %d\n",
params->rf_test_mode);
} else if (strncmp(line, "drv_mode", strlen("drv_mode")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
@ -1179,8 +1208,22 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size,
PRINTM(MMSG, "tx_work %s\n",
moal_extflg_isset(handle, EXT_TX_WORK) ? "on" :
"off");
} else if (strncmp(line, "tx_skb_clone",
strlen("tx_skb_clone")) == 0) {
}
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
else if (strncmp(line, "rps", strlen("rps")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
handle->params.rps = out_data & RPS_CPU_MASK;
PRINTM(MMSG, "rps set to %x from cfg\n",
handle->params.rps);
}
#endif
#endif
else if (strncmp(line, "tx_skb_clone",
strlen("tx_skb_clone")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
@ -1220,8 +1263,29 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size,
"off");
}
#endif
else if (strncmp(line, "roamoffload_in_hs",
strlen("roamoffload_in_hs")) == 0) {
else if (strncmp(line, "cfg80211_drcs",
strlen("cfg80211_drcs")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
if (out_data)
moal_extflg_set(handle, EXT_CFG80211_DRCS);
else
moal_extflg_clear(handle, EXT_CFG80211_DRCS);
PRINTM(MMSG, "cfg80211_drcs %s\n",
moal_extflg_isset(handle, EXT_CFG80211_DRCS) ?
"on" :
"off");
} else if (strncmp(line, "drcs_chantime_mode",
strlen("drcs_chantime_mode")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->drcs_chantime_mode = out_data;
PRINTM(MMSG, "drcs_chantime_mode=%d\n",
params->drcs_chantime_mode);
} else if (strncmp(line, "roamoffload_in_hs",
strlen("roamoffload_in_hs")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
@ -1417,6 +1481,10 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params)
if (params)
handle->params.mfg_mode = params->mfg_mode;
#endif
handle->params.rf_test_mode = rf_test_mode;
if (params)
handle->params.rf_test_mode = params->rf_test_mode;
handle->params.drv_mode = drv_mode;
if (params)
handle->params.drv_mode = params->drv_mode;
@ -1625,6 +1693,13 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params)
if (tx_work)
moal_extflg_set(handle, EXT_TX_WORK);
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
handle->params.rps = rps & RPS_CPU_MASK;
PRINTM(MMSG, "rps set to %x from module param\n", handle->params.rps);
#endif
#endif
if (tx_skb_clone)
moal_extflg_set(handle, EXT_TX_SKB_CLONE);
if (pmqos)
@ -1645,6 +1720,11 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params)
moal_extflg_set(handle, EXT_HOST_MLME);
#endif
#endif
if (cfg80211_drcs)
moal_extflg_set(handle, EXT_CFG80211_DRCS);
handle->params.drcs_chantime_mode = drcs_chantime_mode;
if (params)
handle->params.drcs_chantime_mode = params->drcs_chantime_mode;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
if (disable_regd_by_driver)
moal_extflg_set(handle, EXT_DISABLE_REGD_BY_DRIVER);
@ -1853,8 +1933,19 @@ void woal_init_from_dev_tree(void)
PRINTM(MIOCTL, "tx_work=0x%x\n", data);
tx_work = data;
}
} else if (!strncmp(prop->name, "tx_skb_clone",
strlen("tx_skb_clone"))) {
}
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
else if (!strncmp(prop->name, "rps", strlen("rps"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
PRINTM(MIOCTL, "rps=0x%x\n", data);
rps = data;
}
}
#endif
#endif
else if (!strncmp(prop->name, "tx_skb_clone",
strlen("tx_skb_clone"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
PRINTM(MIOCTL, "tx_skb_clone=0x%x\n", data);
tx_skb_clone = data;
@ -1878,7 +1969,14 @@ void woal_init_from_dev_tree(void)
}
}
#endif
else if (!strncmp(prop->name, "mac_addr", strlen("mac_addr"))) {
else if (!strncmp(prop->name, "rf_test_mode",
strlen("rf_test_mode"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
PRINTM(MIOCTL, "rf_test_mode=0x%x\n", data);
rf_test_mode = data;
}
} else if (!strncmp(prop->name, "mac_addr",
strlen("mac_addr"))) {
if (!of_property_read_string(dt_node, prop->name,
&string_data)) {
mac_addr = (char *)string_data;
@ -1965,6 +2063,12 @@ void woal_init_from_dev_tree(void)
PRINTM(MIOCTL, "max_vir_bss=0x%x\n", data);
max_vir_bss = data;
}
} else if (!strncmp(prop->name, "cfg80211_drcs",
strlen("cfg80211_drcs"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
PRINTM(MIOCTL, "cfg80211_drcs=0x%x\n", data);
cfg80211_drcs = data;
}
}
#endif
#endif
@ -2069,6 +2173,13 @@ void woal_init_from_dev_tree(void)
indrstcfg = data;
PRINTM(MIOCTL, "indrstcfg=%d\n", indrstcfg);
}
} else if (!strncmp(prop->name, "drcs_chantime_mode",
strlen("drcs_chantime_mode"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
drcs_chantime_mode = data;
PRINTM(MIOCTL, "drcs_chantime_mode=%d\n",
drcs_chantime_mode);
}
} else if (!strncmp(prop->name, "fixed_beacon_buffer",
strlen("fixed_beacon_buffer"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
@ -2383,6 +2494,10 @@ module_param(mfg_mode, int, 0660);
MODULE_PARM_DESC(mfg_mode,
"0: Download normal firmware; 1: Download MFG firmware");
#endif /* MFG_CMD_SUPPORT */
module_param(rf_test_mode, int, 0660);
MODULE_PARM_DESC(
rf_test_mode,
"0: Download normal firmware; 1: Download RF_TEST_MODE firmware");
module_param(drv_mode, int, 0660);
MODULE_PARM_DESC(drv_mode,
"Bit 0: STA; Bit 1: uAP; Bit 2: WIFIDIRECT; Bit 7: ZERO_DFS");
@ -2466,6 +2581,14 @@ MODULE_PARM_DESC(
#endif
module_param(tx_work, uint, 0660);
MODULE_PARM_DESC(tx_work, "1: Enable tx_work; 0: Disable tx_work");
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
module_param(rps, uint, 0660);
MODULE_PARM_DESC(
rps,
"bit0-bit4(0x1 - 0xf): Enables rps on specific cpu ; 0: Disables rps");
#endif
#endif
module_param(tx_skb_clone, uint, 0660);
MODULE_PARM_DESC(tx_skb_clone,
"1: Enable tx_skb_clone; 0: Disable tx_skb_clone");
@ -2616,6 +2739,14 @@ module_param(dfs_offload, int, 0);
MODULE_PARM_DESC(dfs_offload, "1: enable dfs offload; 0: disable dfs offload.");
#endif
module_param(drcs_chantime_mode, int, 0);
MODULE_PARM_DESC(
drcs_chantime_mode,
"0: use default value;Bit31~Bit24:Channel time for channel index0;Bit23~Bit16:mode for channel index0;Bit15~Bit8:Channel time for channel index1;Bit7~Bit0:mode for channel index1; mode:0--PM1,1--Null2Self.");
module_param(cfg80211_drcs, int, 0);
MODULE_PARM_DESC(cfg80211_drcs,
"1: Enable DRCS support; 0: Disable DRCS support");
module_param(roamoffload_in_hs, int, 0);
MODULE_PARM_DESC(
roamoffload_in_hs,

View file

@ -267,6 +267,7 @@ t_u8 woal_get_second_channel_offset(moal_private *priv, int chan)
t_u8 chan2Offset = SEC_CHAN_NONE;
mlan_bss_info bss_info;
memset(&bss_info, 0, sizeof(bss_info));
/* Special Case: 20Mhz-only Channel */
woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
if (bss_info.region_code != COUNTRY_CODE_US && chan == 165)
@ -1029,6 +1030,202 @@ done:
}
#endif
#ifdef UAP_SUPPORT
/**
* @brief Check current uap/go connection status
* Need handle channel switch if current channel is DFS channel
*
* @param priv A pointer to moal_private structure
* @param wait_option Wait option
* @param new channel new channel
* @return N/A
*/
static void woal_check_uap_dfs_status(moal_private *priv, t_u8 wait_option,
t_u8 new_channel)
{
chan_band_info channel;
mlan_bss_info bss_info;
#if defined(UAP_SUPPORT)
IEEEtypes_ChanSwitchAnn_t *chan_switch = NULL;
IEEEtypes_ExtChanSwitchAnn_t *ext_chan_switch = NULL;
custom_ie *pcust_chansw_ie = NULL;
mlan_ioctl_req *ioctl_req = NULL;
mlan_ds_misc_cfg *misc = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
t_u8 bw = 0, oper_class = 0;
#endif
/* Get BSS information */
if (MLAN_STATUS_SUCCESS !=
woal_get_bss_info(priv, wait_option, &bss_info))
goto done;
if (MLAN_STATUS_SUCCESS !=
woal_set_get_ap_channel(priv, MLAN_ACT_GET, wait_option, &channel))
goto done;
PRINTM(MCMND, "is_11h_active=%d dfs_check_channel=%d\n",
bss_info.is_11h_active, bss_info.dfs_check_channel);
PRINTM(MCMND, "uap current channel=%d new_channel=%d\n",
channel.channel, new_channel);
#if defined(UAP_SUPPORT)
if (new_channel == channel.channel)
goto done;
if (bss_info.is_11h_active &&
(bss_info.dfs_check_channel == channel.channel)) {
if (new_channel < MAX_BG_CHANNEL) {
bw = 20;
} else {
switch (channel.bandcfg.chanWidth) {
case CHAN_BW_20MHZ:
bw = 20;
break;
case CHAN_BW_40MHZ:
bw = 40;
break;
case CHAN_BW_80MHZ:
bw = 80;
break;
default:
break;
}
}
woal_priv_get_nonglobal_operclass_by_bw_channel(
priv, bw, new_channel, &oper_class);
PRINTM(MCMND,
"Switch the uap channel from %d to %d, oper_class=%d bw=%d\n",
channel.channel, new_channel, oper_class, bw);
ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (ioctl_req) {
misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
misc->sub_command = MLAN_OID_MISC_CUSTOM_IE;
ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;
ioctl_req->action = MLAN_ACT_SET;
misc->param.cust_ie.type = TLV_TYPE_MGMT_IE;
misc->param.cust_ie.len =
sizeof(custom_ie) - MAX_IE_SIZE;
pcust_chansw_ie = (custom_ie *)&misc->param.cust_ie
.ie_data_list[0];
pcust_chansw_ie->ie_index = 0xffff; /*Auto index */
if (!oper_class) {
pcust_chansw_ie->ie_length =
sizeof(IEEEtypes_ChanSwitchAnn_t);
pcust_chansw_ie->mgmt_subtype_mask =
MGMT_MASK_BEACON |
MGMT_MASK_PROBE_RESP; /*Add IE for
BEACON/probe
resp*/
chan_switch =
(IEEEtypes_ChanSwitchAnn_t *)
pcust_chansw_ie->ie_buffer;
chan_switch->element_id = CHANNEL_SWITCH_ANN;
chan_switch->len =
sizeof(IEEEtypes_ChanSwitchAnn_t) -
sizeof(IEEEtypes_Header_t);
chan_switch->chan_switch_mode = 1; /* STA should
not
transmit
*/
chan_switch->new_channel_num = new_channel;
chan_switch->chan_switch_count =
DEF_CHAN_SWITCH_COUNT;
DBG_HEXDUMP(MCMD_D, "CSA IE",
(t_u8 *)pcust_chansw_ie->ie_buffer,
pcust_chansw_ie->ie_length);
} else {
pcust_chansw_ie->ie_length =
sizeof(IEEEtypes_ExtChanSwitchAnn_t);
pcust_chansw_ie->mgmt_subtype_mask =
MGMT_MASK_BEACON |
MGMT_MASK_PROBE_RESP; /*Add IE for
BEACON/probe
resp*/
ext_chan_switch =
(IEEEtypes_ExtChanSwitchAnn_t *)
pcust_chansw_ie->ie_buffer;
ext_chan_switch->element_id =
EXTEND_CHANNEL_SWITCH_ANN;
ext_chan_switch->len =
sizeof(IEEEtypes_ExtChanSwitchAnn_t) -
sizeof(IEEEtypes_Header_t);
ext_chan_switch->chan_switch_mode =
1; /* STA should not transmit */
ext_chan_switch->new_channel_num = new_channel;
ext_chan_switch->chan_switch_count =
DEF_CHAN_SWITCH_COUNT;
ext_chan_switch->new_oper_class = oper_class;
DBG_HEXDUMP(MCMD_D, "ECSA IE",
(t_u8 *)pcust_chansw_ie->ie_buffer,
pcust_chansw_ie->ie_length);
}
status = woal_request_ioctl(priv, ioctl_req,
wait_option);
if (status != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "Failed to set CSA IE\n");
goto done;
}
PRINTM(MCMND, "CSA/ECSA ie index=%d\n",
pcust_chansw_ie->ie_index);
priv->phandle->chsw_wait_q_woken = MFALSE;
/* wait for channel switch to complete */
wait_event_interruptible_timeout(
priv->phandle->chsw_wait_q,
priv->phandle->chsw_wait_q_woken,
(u32)HZ * (DEF_CHAN_SWITCH_COUNT + 2) * 110 /
1000);
pcust_chansw_ie->ie_index = 0xffff;
pcust_chansw_ie->mgmt_subtype_mask =
MLAN_CUSTOM_IE_DELETE_MASK;
status = woal_request_ioctl(priv, ioctl_req,
MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "Failed to clear CSA/ECSA IE\n");
}
}
}
#endif
done:
#if defined(UAP_SUPPORT)
if (status != MLAN_STATUS_PENDING)
kfree(ioctl_req);
#endif
return;
}
/**
* @brief Check current multi-channel connections
*
* @param priv A pointer to moal_private structure
* @param wait_option Wait option
* @param new channel new channel
*
* @return N/A
*/
void woal_check_mc_connection(moal_private *priv, t_u8 wait_option,
t_u8 new_channel)
{
moal_handle *handle = priv->phandle;
#ifdef UAP_SUPPORT
int i;
#endif
t_u16 enable = 0;
woal_mc_policy_cfg(priv, &enable, wait_option, MLAN_ACT_GET);
if (!enable)
return;
#ifdef UAP_SUPPORT
for (i = 0; i < handle->priv_num; i++) {
if (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_UAP) {
if (handle->priv[i]->bss_started == MTRUE)
woal_check_uap_dfs_status(handle->priv[i],
wait_option,
new_channel);
}
}
#endif
return;
}
#endif
/**
* @brief Send bss_start command to MLAN
*
@ -1045,6 +1242,9 @@ mlan_status woal_bss_start(moal_private *priv, t_u8 wait_option,
mlan_ioctl_req *req = NULL;
mlan_ds_bss *bss = NULL;
mlan_status status;
#ifdef UAP_SUPPORT
mlan_ssid_bssid temp_ssid_bssid;
#endif
ENTER();
@ -1054,6 +1254,18 @@ mlan_status woal_bss_start(moal_private *priv, t_u8 wait_option,
if (netif_carrier_ok(priv->netdev))
netif_carrier_off(priv->netdev);
}
#ifdef UAP_SUPPORT
if (!ssid_bssid) {
LEAVE();
return MLAN_STATUS_FAILURE;
}
moal_memcpy_ext(priv->phandle, &temp_ssid_bssid, ssid_bssid,
sizeof(mlan_ssid_bssid), sizeof(mlan_ssid_bssid));
if (MLAN_STATUS_SUCCESS ==
woal_find_best_network(priv, wait_option, &temp_ssid_bssid))
woal_check_mc_connection(priv, wait_option,
temp_ssid_bssid.channel);
#endif
/* Allocate an IOCTL request buffer */
req = (mlan_ioctl_req *)woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
@ -2941,6 +3153,7 @@ done:
return ret;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
/**
* @brief Enable IPv6 Neighbor Solicitation offload
*
@ -3016,6 +3229,7 @@ done:
LEAVE();
return ret;
}
#endif
/**
* @brief Set auto arp resp
@ -4546,6 +4760,10 @@ int woal_11h_channel_check_ioctl(moal_private *priv, t_u8 wait_option)
mlan_ioctl_req *req = NULL;
mlan_ds_11h_cfg *ds_11hcfg = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
#ifdef UAP_SUPPORT
chan_band_info chan;
chan_band_info uapchan;
#endif
ENTER();
@ -4566,6 +4784,41 @@ int woal_11h_channel_check_ioctl(moal_private *priv, t_u8 wait_option)
}
if (woal_is_any_interface_active(priv->phandle)) {
#ifdef UAP_SUPPORT
/* When any other interface is active
* Get rid of CAC timer when drcs is disabled */
t_u16 enable = 0;
if (priv->phandle->card_info->drcs)
ret = woal_mc_policy_cfg(priv, &enable, wait_option,
MLAN_ACT_GET);
if (!enable) {
LEAVE();
return ret;
} else {
woal_get_active_intf_channel(priv, &chan);
woal_set_get_ap_channel(priv, MLAN_ACT_GET,
MOAL_IOCTL_WAIT, &uapchan);
if (chan.channel != uapchan.channel) {
if (uapchan.is_dfs_chan) {
PRINTM(MERROR,
"DFS channel is not allowed when another connection exists on different channel\n");
PRINTM(MERROR,
"Another connection's channel=%d, dfs channel=%d\n",
chan.channel, uapchan.channel);
return -EINVAL;
} else {
// check if we need move first uap0 from
// DFS channel to new non dfs channel
woal_check_mc_connection(
priv, wait_option,
uapchan.channel);
}
}
}
#else
LEAVE();
return status;
#endif
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg));
@ -7274,6 +7527,50 @@ done:
}
#endif
/**
* @brief Set/Get configure multi-channel policy
*
* @param priv A pointer to moal_private structure
* @param enable A pointer to enable
* @param wait_option wait_option of ioctl
* @param action action of ioctl
*
* @return MLAN_STATUS_SUCCESS -- success, otherwise fail
*/
mlan_status woal_mc_policy_cfg(moal_private *priv, t_u16 *enable,
t_u8 wait_option, t_u8 action)
{
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *cfg = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
status = MLAN_STATUS_FAILURE;
goto done;
}
cfg = (mlan_ds_misc_cfg *)req->pbuf;
cfg->sub_command = MLAN_OID_MISC_MULTI_CHAN_POLICY;
req->req_id = MLAN_IOCTL_MISC_CFG;
req->action = action;
if (MLAN_ACT_SET == action)
cfg->param.multi_chan_policy = *enable;
status = woal_request_ioctl(priv, req, wait_option);
if (status != MLAN_STATUS_SUCCESS)
goto done;
if (MLAN_ACT_GET == action)
*enable = cfg->param.multi_chan_policy;
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return status;
}
/**
* @brief Set hotspot configuration value to mlan layer
*
@ -7354,7 +7651,7 @@ mlan_status woal_set_net_monitor(moal_private *priv, t_u8 wait_option,
net_mon->enable_net_mon = enable;
if (net_mon->enable_net_mon) {
net_mon->filter_flag = filter;
if (net_mon->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) {
if (band_chan_cfg && band_chan_cfg->channel) {
net_mon->band = band_chan_cfg->band;
net_mon->channel = band_chan_cfg->channel;
net_mon->chan_bandwidth = band_chan_cfg->chan_bandwidth;
@ -7367,6 +7664,14 @@ mlan_status woal_set_net_monitor(moal_private *priv, t_u8 wait_option,
goto done;
}
/* update chan band values from response in band_chan_cfg */
if (net_mon->enable_net_mon) {
if (band_chan_cfg) {
band_chan_cfg->band = net_mon->band;
band_chan_cfg->channel = net_mon->channel;
band_chan_cfg->chan_bandwidth = net_mon->chan_bandwidth;
}
}
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
@ -7541,15 +7846,16 @@ static int parse_radio_mode_string(const char *s, size_t len,
return ret;
}
#ifdef SD9177
/*
* @brief PoweLevelToDUT11Bits
* @brief PowerLevelToDUT11Bits
*
* @param Pwr A user txpwr values of type int
* @param PowerLevel A Pointer of uint32 type for converted txpwr vals
* @return nothing just exit
*/
static void PoweLevelToDUT11Bits(int Pwr, t_u32 *PowerLevel)
static void PowerLevelToDUT11Bits(int Pwr, t_u32 *PowerLevel)
{
int Z = 0;
@ -7564,6 +7870,7 @@ static void PoweLevelToDUT11Bits(int Pwr, t_u32 *PowerLevel)
return;
}
#endif
/*
* @brief Parse mfg cmd tx pwr string
@ -7583,9 +7890,11 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len,
char *tmp = NULL;
char *pos = NULL;
gfp_t flag;
#ifdef SD9177
t_u32 tx_pwr_converted = 0xffffffff;
int tx_pwr_local = 0;
t_u8 fc_card = MFALSE;
#endif
ENTER();
if (!s || !d) {
@ -7611,13 +7920,16 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len,
/* tx power value */
pos = strsep(&string, " \t");
#ifdef SD9177
if (fc_card && pos) {
/* for sd9177 we need to convert user power vals including -ve
* vals as per labtool */
tx_pwr_local = woal_string_to_number(pos);
PoweLevelToDUT11Bits(tx_pwr_local, &tx_pwr_converted);
PowerLevelToDUT11Bits(tx_pwr_local, &tx_pwr_converted);
d->data1 = tx_pwr_converted;
} else if (pos) {
} else
#endif
if (pos) {
d->data1 = (t_u32)woal_string_to_number(pos);
}
/* modulation */
@ -7630,7 +7942,11 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len,
if (pos)
d->data3 = (t_u32)woal_string_to_number(pos);
#ifdef SD9177
if (((!fc_card) && (d->data1 > 24)) || (d->data2 > 2))
#else
if ((d->data1 > 24) || (d->data2 > 2))
#endif
ret = -EINVAL;
kfree(tmp);
@ -8184,7 +8500,7 @@ mlan_status woal_process_rf_test_mode_cmd(moal_handle *handle, t_u32 cmd,
handle->rf_data->he_tb_tx[2] = misc->param.mfg_he_power.aid;
handle->rf_data->he_tb_tx[3] =
misc->param.mfg_he_power.axq_mu_timer;
handle->rf_data->he_tb_tx[4] =
handle->rf_data->he_tb_tx_power[0] =
misc->param.mfg_he_power.tx_power;
break;
}

View file

@ -1284,8 +1284,7 @@ static int woal_netdevice_event(struct notifier_block *nb, unsigned long event,
sizeof(priv->ip_addr));
priv->ip_addr_type = IPADDR_TYPE_IPV4;
#ifdef STA_CFG80211
if (!moal_extflg_isset(priv->phandle, EXT_HW_TEST) &&
priv->roaming_enabled) {
if (!moal_extflg_isset(priv->phandle, EXT_HW_TEST)) {
snprintf(rssi_low, sizeof(rssi_low), "%d",
priv->rssi_low);
if (MLAN_STATUS_SUCCESS !=
@ -2085,6 +2084,7 @@ mlan_status woal_init_sw(moal_handle *handle)
device.rx_cmd_ep = cardp->rx_cmd_ep;
device.tx_data_ep = cardp->tx_data_ep;
device.rx_data_ep = cardp->rx_data_ep;
device.tx_data2_ep = cardp->tx_data2_ep;
}
#endif
#ifdef MFG_CMD_SUPPORT
@ -2104,6 +2104,7 @@ mlan_status woal_init_sw(moal_handle *handle)
device.cfg_11d = (t_u32)handle->params.cfg_11d;
#endif
device.indrstcfg = (t_u32)handle->params.indrstcfg;
device.drcs_chantime_mode = (t_u32)handle->params.drcs_chantime_mode;
#ifdef PCIE
if (IS_PCIE(handle->card_type))
device.ring_size = handle->params.ring_size;
@ -3433,6 +3434,87 @@ done:
return status;
}
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
static ssize_t woal_set_rps_map(struct netdev_rx_queue *queue, const char *buf,
size_t len)
{
struct rps_map *old_map, *map;
cpumask_var_t mask;
int err, cpu, i;
static DEFINE_MUTEX(local_rps_map_mutex);
if (!queue || !queue->dev) {
PRINTM(MERROR, "%s: queue=%px or queue->dev is NULL\n",
__func__, queue);
return -EINVAL;
}
if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
PRINTM(MERROR, "%s: alloc_cpumask_var fail.\n", __func__);
return -ENOMEM;
}
err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
if (err) {
PRINTM(MERROR, "%s: bitmap_parse fail err=%d.\n", __func__,
err);
free_cpumask_var(mask);
return err;
}
map = kzalloc(max_t(unsigned int, RPS_MAP_SIZE(cpumask_weight(mask)),
L1_CACHE_BYTES),
GFP_KERNEL);
if (!map) {
PRINTM(MERROR, "%s: kzalloc map fail.\n", __func__);
free_cpumask_var(mask);
return -ENOMEM;
}
i = 0;
for_each_cpu_and (cpu, mask, cpu_online_mask) {
PRINTM(MCMND, "map->cpus[%d]=%d\n", i, cpu);
map->cpus[i++] = cpu;
}
if (i) {
map->len = i;
PRINTM(MCMND, "map->len=%d\n", map->len);
} else {
kfree(map);
map = NULL;
}
mutex_lock(&local_rps_map_mutex);
old_map = rcu_dereference_protected(
queue->rps_map, mutex_is_locked(&local_rps_map_mutex));
rcu_assign_pointer(queue->rps_map, map);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
if (map)
static_branch_inc(&rps_needed);
if (old_map)
static_branch_dec(&rps_needed);
#else
if (map)
static_key_slow_inc(&rps_needed);
if (old_map)
static_key_slow_dec(&rps_needed);
#endif
mutex_unlock(&local_rps_map_mutex);
if (old_map)
kfree_rcu(old_map, rcu);
PRINTM(MMSG, "%s on %s: buf=%s(%u) (%d i=%d)\n", __func__,
queue->dev->name, buf, (t_u32)len, nr_cpumask_bits, i);
free_cpumask_var(mask);
return len;
}
#endif
#endif
/**
* @brief Add interfaces DPC
*
@ -3446,6 +3528,13 @@ static mlan_status woal_add_card_dpc(moal_handle *handle)
int i;
char str_buf[MLAN_MAX_VER_STR_LEN];
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
moal_private *priv_rps = NULL;
t_u8 rps_buf[2];
#endif
#endif
ENTER();
#if defined(USB)
@ -3563,6 +3652,28 @@ static mlan_status woal_add_card_dpc(moal_handle *handle)
#endif
#endif
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
if (handle->params.rps) {
priv_rps = woal_get_priv_bss_type(handle, MLAN_BSS_TYPE_STA);
sprintf(rps_buf, "%x", handle->params.rps);
if (priv_rps) {
PRINTM(MCMND,
"num_rx_queues=%u real_num_rx_queues=%u\n",
priv_rps->netdev->num_rx_queues,
priv_rps->netdev->real_num_rx_queues);
for (i = 0;
i < (int)MIN(priv_rps->netdev->num_rx_queues,
priv_rps->netdev->real_num_rx_queues);
i++) {
woal_set_rps_map(&(priv_rps->netdev->_rx[i]),
rps_buf, strlen(rps_buf));
}
}
}
#endif
#endif
#ifdef MFG_CMD_SUPPORT
done:
#endif
@ -4534,13 +4645,11 @@ static void woal_mon_if_setup(struct net_device *dev)
* @param priv A pointer to moal_private
* @param name Virtual interface name
* @param name_assign_type Interface name assignment type
* @param sniffer_mode Sniffer mode
*
* @return A pointer to monitor_iface
*/
monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name,
unsigned char name_assign_type,
int sniffer_mode)
unsigned char name_assign_type)
{
int ret = 0;
moal_handle *handle = priv->phandle;
@ -4549,19 +4658,6 @@ monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name,
ENTER();
if (sniffer_mode != CHANNEL_SPEC_SNIFFER_MODE) {
PRINTM(MERROR, "Sniffer mode is not valid\n");
ret = -EFAULT;
goto fail;
}
if ((sniffer_mode == CHANNEL_SPEC_SNIFFER_MODE) &&
woal_is_any_interface_active(handle)) {
PRINTM(MERROR,
"Cannot start channel specified net monitor when Interface Active\n");
ret = -EFAULT;
goto fail;
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
@ -4601,7 +4697,6 @@ monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name,
mon_if->priv = priv;
mon_if->mon_ndev = ndev;
mon_if->base_ndev = priv->netdev;
mon_if->sniffer_mode = sniffer_mode;
mon_if->radiotap_enabled = 1;
mon_if->flag = 1;
@ -5799,6 +5894,20 @@ int woal_close(struct net_device *dev)
woal_flush_tx_stat_queue(priv);
if ((priv->media_connected == MTRUE)
#ifdef UAP_SUPPORT
|| (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)
#endif
) {
if (MLAN_STATUS_SUCCESS !=
woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL,
DEF_DEAUTH_REASON_CODE)) {
PRINTM(MERROR, "%s: woal_disconnect failed \n",
__func__);
}
priv->media_connected = MFALSE;
}
#ifdef STA_SUPPORT
#ifdef STA_CFG80211
if (IS_STA_CFG80211(cfg80211_wext))
@ -6703,7 +6812,7 @@ static void woal_tdls_check_tx(moal_private *priv, struct sk_buff *skb)
{
struct tdls_peer *peer = NULL;
unsigned long flags;
t_u8 ra[MLAN_MAC_ADDR_LENGTH];
t_u8 ra[MLAN_MAC_ADDR_LENGTH] = {0};
ENTER();
moal_memcpy_ext(priv->phandle, ra, skb->data, MLAN_MAC_ADDR_LENGTH,
sizeof(ra));
@ -7090,29 +7199,6 @@ static int woal_process_tcp_ack(moal_private *priv, mlan_buffer *pmbuf)
return ret;
}
}
#if 0
/* Might have race conditions with woal_tcp_ack_timer_func
* Causing kernel panic, ageout handler will free tcp_sess
* for now.
*/
else if((*((t_u8 *)tcph + 13) & 0x11) == 0x11){
/* TCP ACK + Fin */
spin_lock_irqsave(&priv->tcp_sess_lock, flags);
tcp_session = woal_get_tcp_sess(priv, (__force t_u32)iph->saddr, (__force t_u16)tcph->source,
(__force t_u32)iph->daddr, (__force t_u16)tcph->dest);
if (tcp_session) {
PRINTM(MDATA,"wlan: delete TCP seesion %p\n",tcp_session);
list_del(&tcp_session->link);
if (atomic_read(&tcp_session->is_timer_set))
woal_cancel_timer(&tcp_session->ack_timer);
skb = (struct sk_buff *)tcp_session->ack_skb;
if (skb)
dev_kfree_skb_any(skb);
kfree(tcp_session);
}
spin_unlock_irqrestore(&priv->tcp_sess_lock, flags);
}
#endif
done:
LEAVE();
@ -7194,6 +7280,7 @@ static void woal_start_xmit(moal_private *priv, struct sk_buff *skb)
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
index = skb_get_queue_mapping(skb);
index = MIN(index, 3);
#endif
if (is_zero_timeval(priv->phandle->tx_time_start)) {
@ -9237,6 +9324,8 @@ static int woal_dump_moal_drv_info(moal_handle *phandle, t_u8 *buf)
atomic_read(&cardp->tx_cmd_urb_pending));
ptr += sprintf(ptr, "tx_data_urb_pending = %d\n",
atomic_read(&cardp->tx_data_urb_pending));
ptr += sprintf(ptr, "tx_data2_urb_pending = %d\n",
atomic_read(&cardp->tx_data2_urb_pending));
#ifdef USB_CMD_DATA_EP
ptr += sprintf(ptr, "rx_cmd_urb_pending = %d\n",
atomic_read(&cardp->rx_cmd_urb_pending));
@ -9632,7 +9721,7 @@ done:
int woal_save_dump_info_to_buf(moal_handle *phandle, t_u8 *src, t_u32 len,
t_u32 type)
{
mem_dump_header header;
mem_dump_header header = {0};
t_u32 left_len = 0;
t_u32 len_to_copy = 0;
int total_len = 0;
@ -9734,6 +9823,8 @@ void woal_moal_debug_info(moal_private *priv, moal_handle *handle, u8 flag)
atomic_read(&cardp->tx_cmd_urb_pending));
PRINTM(MERROR, "tx_data_urb_pending = %d\n",
atomic_read(&cardp->tx_data_urb_pending));
PRINTM(MERROR, "tx_data2_urb_pending = %d\n",
atomic_read(&cardp->tx_data2_urb_pending));
#ifdef USB_CMD_DATA_EP
PRINTM(MERROR, "rx_cmd_urb_pending = %d\n",
atomic_read(&cardp->rx_cmd_urb_pending));
@ -10735,10 +10826,11 @@ moal_handle *woal_add_card(void *card, struct device *dev, moal_if_ops *if_ops,
#define NAPI_BUDGET 64
if (moal_extflg_isset(handle, EXT_NAPI)) {
init_dummy_netdev(&handle->napi_dev);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
netif_napi_add(&handle->napi_dev, &handle->napi_rx,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
woal_netdev_poll_rx);
#else
netif_napi_add(&handle->napi_dev, &handle->napi_rx,
woal_netdev_poll_rx, NAPI_BUDGET);
#endif
napi_enable(&handle->napi_rx);
@ -11358,8 +11450,10 @@ static void woal_post_reset(moal_handle *handle)
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *misc = NULL;
int intf_num;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
char str_buf[MLAN_MAX_VER_STR_LEN];
mlan_fw_info fw_info;
moal_private *priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
t_u8 country_code[COUNTRY_CODE_LEN];
#endif
#ifdef WIFI_DIRECT_SUPPORT
@ -11396,9 +11490,16 @@ static void woal_post_reset(moal_handle *handle)
handle->fw_dump_status = MFALSE;
handle->driver_status = MFALSE;
handle->hardware_status = HardwareStatusReady;
handle->remain_on_channel = MFALSE;
#ifdef STA_CFG80211
handle->scan_timeout = SCAN_TIMEOUT_25S;
#endif
if (MLAN_STATUS_SUCCESS !=
woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info)) {
PRINTM(MERROR, "%s: get_fw_info failed \n", __func__);
}
woal_get_version(handle, str_buf, sizeof(str_buf) - 1);
PRINTM(MMSG, "wlan: version = %s\n", str_buf);
if (!handle->wifi_hal_flag) {
PRINTM(MMSG, "wlan: post_reset remove/add interface\n");
handle->surprise_removed = MTRUE;
@ -11434,6 +11535,9 @@ static void woal_post_reset(moal_handle *handle)
PRINTM(MMSG, "wlan: post_reset remove/add interface done\n");
goto done;
}
PRINTM(MMSG, "wlan: start interfaces reset\n");
/* Reset all interfaces */
woal_reset_intf(woal_get_priv(handle, MLAN_BSS_ROLE_ANY),
MOAL_IOCTL_WAIT, MTRUE);
@ -11831,8 +11935,11 @@ static void woal_cleanup_module(void)
/** cancel dfs monitor on deinit */
if (handle->priv[i] &&
handle->priv[i]->bss_type == MLAN_BSS_TYPE_DFS) {
woal_11h_cancel_chan_report_ioctl(
handle->priv[i], MOAL_IOCTL_WAIT);
if (woal_11h_cancel_chan_report_ioctl(
handle->priv[i], MOAL_IOCTL_WAIT))
PRINTM(MERROR,
"%s: woal_11h_cancel_chan_report_ioctl failed \n",
__func__);
continue;
}
#ifdef STA_SUPPORT

View file

@ -306,6 +306,9 @@ extern int fw_reload;
extern int mfg_mode;
#endif
/** rf_test mode */
extern int rf_test_mode;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
extern int fw_region;
@ -860,6 +863,9 @@ mlan_status woal_do_dfs_cac(moal_private *priv,
/** Custom event : Channel Switch Announcment */
#define CUS_EVT_CHANNEL_SWITCH_ANN "EVENT=CHANNEL_SWITCH_ANN"
/** Custom event : Channel Switch complete */
#define CUS_EVT_CHAN_SWITCH_COMPLETE "EVENT=CHANNEL_SWITCH_COMPLETE"
/** Custom indiciation message sent to the application layer for WMM changes */
#define WMM_CONFIG_CHANGE_INDICATION "WMM_CONFIG_CHANGE.indication"
@ -1329,7 +1335,8 @@ struct rf_test_mode_data {
/* Tx frame config values */
t_u32 tx_frame_data[20];
/* HE TB Tx values */
t_u32 he_tb_tx[5];
t_u32 he_tb_tx[4];
t_s32 he_tb_tx_power[1];
/* BSSID */
t_u8 bssid[ETH_ALEN];
};
@ -1633,6 +1640,10 @@ struct _moal_private {
t_u8 auth_flag;
/** flag for auth algorithm */
t_u16 auth_alg;
/** auth tx cnt */
t_u8 auth_tx_cnt;
/** deauth evt cnt */
t_u8 deauth_evt_cnt;
#endif
#ifdef CONFIG_PROC_FS
/** Proc entry */
@ -2046,11 +2057,6 @@ typedef struct _monitor_iface {
/* The priv data of interface on which the monitor iface is based */
moal_private *priv;
struct wireless_dev wdev;
/** 0 - Disabled
* 1 - Channel Specified sniffer mode
* 2 - In-Channel sniffer mode
*/
int sniffer_mode;
int radiotap_enabled;
/* The net_device on which the monitor iface is based. */
struct net_device *base_ndev;
@ -2119,6 +2125,7 @@ enum ext_mod_params {
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
EXT_DFS_OFFLOAD,
#endif
EXT_CFG80211_DRCS,
EXT_DISABLE_REGD_BY_DRIVER,
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
EXT_COUNTRY_IE_IGNORE,
@ -2149,6 +2156,7 @@ typedef struct _moal_mod_para {
#ifdef MFG_CMD_SUPPORT
int mfg_mode;
#endif /* MFG_CMD_SUPPORT */
int rf_test_mode;
char *hw_name;
int drv_mode;
#ifdef DEBUG_LEVEL1
@ -2224,10 +2232,17 @@ typedef struct _moal_mod_para {
int gtk_rekey_offload;
t_u16 multi_dtim;
t_u16 inact_tmo;
int drcs_chantime_mode;
char *reg_alpha2;
int dfs53cfg;
t_u8 mcs32;
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
/* rps module param */
int rps;
#endif
#endif
int keep_previous_scan;
} moal_mod_para;
@ -3827,6 +3842,12 @@ void woal_remove_mcast_node(moal_private *priv, t_u8 *mcast_addr);
t_u8 woal_find_mcast_node_tx(moal_private *priv, struct sk_buff *skb);
mlan_status woal_request_country_power_table(moal_private *priv, char *region);
mlan_status woal_mc_policy_cfg(moal_private *priv, t_u16 *enable,
t_u8 wait_option, t_u8 action);
#ifdef UAP_SUPPORT
void woal_check_mc_connection(moal_private *priv, t_u8 wait_option,
t_u8 new_channel);
#endif
#ifdef RX_PACKET_COALESCE
mlan_status woal_rx_pkt_coalesce_cfg(moal_private *priv, t_u16 *enable,
t_u8 wait_option, t_u8 action);
@ -3877,8 +3898,7 @@ mlan_status woal_init_aggr_ctrl(moal_handle *handle, t_u8 wait_option);
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name,
unsigned char name_assign_type,
int sniffer_mode);
unsigned char name_assign_type);
#endif
#if defined(STA_CFG80211) || defined(UAP_CFG80211)

View file

@ -1285,7 +1285,7 @@ static mlan_status woal_pcie_init(pcie_service_card *card)
goto err_iomap2;
}
PRINTM(MINFO,
PRINTM(MMSG,
"PCI memory map Virt0: %p PCI memory map Virt2: "
"%p\n",
card->pci_mmap, card->pci_mmap1);

View file

@ -691,7 +691,7 @@ done:
*/
static int woal_11n_tx_cfg(moal_private *priv, struct iwreq *wrq)
{
int data[2], copy_len;
int data[2] = {0}, copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
int ret = 0;
@ -794,7 +794,7 @@ done:
*/
static int woal_11n_prio_tbl(moal_private *priv, struct iwreq *wrq)
{
int data[MAX_NUM_TID * 2], i, j, copy_len;
int data[MAX_NUM_TID * 2] = {0}, i, j, copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
int ret = 0;
@ -968,7 +968,7 @@ error:
*/
static int woal_addba_para_updt(moal_private *priv, struct iwreq *wrq)
{
int data[5], ret = 0, copy_len;
int data[5] = {0}, ret = 0, copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
int data_length = wrq->u.data.length;
@ -1848,10 +1848,9 @@ static int woal_net_monitor_ioctl(moal_private *priv, struct iwreq *wrq)
goto done;
}
/* Supported filter flags */
if (!data[1] ||
data[1] & ~(MLAN_NETMON_DATA_FRAME |
MLAN_NETMON_MANAGEMENT_FRAME |
MLAN_NETMON_CONTROL_FRAME)) {
if (!data[1] || data[1] & ~(MLAN_NETMON_DATA |
MLAN_NETMON_MANAGEMENT |
MLAN_NETMON_CONTROL)) {
PRINTM(MERROR,
"NET_MON: Invalid filter flag\n");
ret = -EINVAL;
@ -6433,7 +6432,7 @@ done:
*/
static int woal_ind_rst_ioctl(moal_private *priv, struct iwreq *wrq)
{
int data[2], data_length = wrq->u.data.length, copy_len;
int data[2] = {0}, data_length = wrq->u.data.length, copy_len;
int ret = 0;
mlan_ds_misc_cfg *misc = NULL;
mlan_ioctl_req *req = NULL;

View file

@ -409,6 +409,7 @@ static int parse_cmd52_string(const char *buffer, size_t len, int *func,
{
int ret = MLAN_STATUS_SUCCESS;
char *string = NULL;
char *tmp;
char *pos = NULL;
gfp_t flag;
@ -420,6 +421,7 @@ static int parse_cmd52_string(const char *buffer, size_t len, int *func,
moal_memcpy_ext(NULL, string, buffer + strlen("sdcmd52rw="),
len - strlen("sdcmd52rw="), CMD52_STR_LEN - 1);
tmp = string;
string = strstrip(string);
*func = -1;
@ -440,7 +442,7 @@ static int parse_cmd52_string(const char *buffer, size_t len, int *func,
pos = strsep(&string, " \t");
if (pos)
*val = woal_string_to_number(pos);
kfree(string);
kfree(tmp);
LEAVE();
return ret;
}
@ -785,7 +787,8 @@ static int woal_config_read(struct seq_file *sfp, void *data)
seq_printf(sfp, " %u", handle->rf_data->he_tb_tx[1]);
seq_printf(sfp, " %u", handle->rf_data->he_tb_tx[2]);
seq_printf(sfp, " %u", handle->rf_data->he_tb_tx[3]);
seq_printf(sfp, " %u", handle->rf_data->he_tb_tx[4]);
seq_printf(sfp, " %d",
handle->rf_data->he_tb_tx_power[0]);
}
seq_printf(sfp, "\n");
}

View file

@ -157,6 +157,9 @@ Change log:
#define SDUART9177_DEFAULT_COMBO_V1_FW_NAME "nxp/sduart_nw61x_v1.bin"
#define SDSD9177_DEFAULT_COMBO_V1_FW_NAME "nxp/sdsd_nw61x_v1.bin"
#define SD9177_DEFAULT_WLAN_V1_FW_NAME "nxp/sd_w61x_v1.bin"
#define SDUART9177_DEFAULT_RFTM_COMBO_V1_FW_NAME "nxp/sduart_nw61x_rftm_v1.bin"
#define SDSD9177_DEFAULT_RFTM_COMBO_V1_FW_NAME "nxp/sdsd_nw61x_rftm_v1.bin"
#define SD9177_DEFAULT_RFTM_WLAN_V1_FW_NAME "nxp/sd_w61x_rftm_v1.bin"
#endif /* SD9177 */
/********************************************************

View file

@ -1564,15 +1564,32 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle)
break;
case SD9177_A1:
if (magic == CHIP_MAGIC_VALUE) {
if (strap == CARD_TYPE_SD9177_UART)
strcpy(handle->card_info->fw_name,
SDUART9177_DEFAULT_COMBO_V1_FW_NAME);
else
strcpy(handle->card_info->fw_name,
SDSD9177_DEFAULT_COMBO_V1_FW_NAME);
if (strap == CARD_TYPE_SD9177_UART) {
if (handle->params.rf_test_mode)
strcpy(handle->card_info
->fw_name,
SDUART9177_DEFAULT_RFTM_COMBO_V1_FW_NAME);
else
strcpy(handle->card_info
->fw_name,
SDUART9177_DEFAULT_COMBO_V1_FW_NAME);
} else {
if (handle->params.rf_test_mode)
strcpy(handle->card_info
->fw_name,
SDSD9177_DEFAULT_RFTM_COMBO_V1_FW_NAME);
else
strcpy(handle->card_info
->fw_name,
SDSD9177_DEFAULT_COMBO_V1_FW_NAME);
}
}
strcpy(handle->card_info->fw_name_wlan,
SD9177_DEFAULT_WLAN_V1_FW_NAME);
if (handle->params.rf_test_mode)
strcpy(handle->card_info->fw_name,
SD9177_DEFAULT_RFTM_WLAN_V1_FW_NAME);
else
strcpy(handle->card_info->fw_name_wlan,
SD9177_DEFAULT_WLAN_V1_FW_NAME);
break;
default:
break;

View file

@ -1953,12 +1953,16 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf)
skb_put(skb, pmbuf->data_len);
}
ethh = (struct ethhdr *)(skb->data);
if (ntohs(ethh->h_proto) == ETH_P_PAE)
if (ntohs(ethh->h_proto) == ETH_P_PAE) {
PRINTM(MEVENT,
"wlan: %s Rx EAPOL pkt from " MACSTR
"\n",
priv->netdev->name,
MAC2STR(ethh->h_source));
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
priv->deauth_evt_cnt = 0;
#endif
}
if (!netdev)
netdev = priv->netdev;
skb->dev = netdev;
@ -2810,6 +2814,9 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_PORT_RELEASE);
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
priv->deauth_evt_cnt = 0;
#endif
woal_broadcast_event(priv, CUS_EVT_PORT_RELEASE,
strlen(CUS_EVT_PORT_RELEASE));
@ -3293,7 +3300,9 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
wake_up_interruptible(&priv->phandle->chsw_wait_q);
}
#endif
snprintf(event_buf, sizeof(event_buf) - 1, "%s %d",
CUS_EVT_CHAN_SWITCH_COMPLETE, pchan_info->channel);
woal_broadcast_event(priv, event_buf, strlen(event_buf));
if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
PRINTM(MMSG,
"CSA/ECSA: Switch to new channel %d complete!\n",
@ -3757,6 +3766,7 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
((struct ieee80211_mgmt *)
pkt)
->frame_control)) {
priv->auth_tx_cnt = 0;
PRINTM(MEVENT,
"HostMlme %s: Received auth frame type = 0x%x\n",
priv->netdev->name,
@ -3801,6 +3811,27 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
"HostMlme: Drop deauth/disassociate, current_bss = null\n");
break;
}
if (ieee80211_is_deauth(
((struct ieee80211_mgmt
*)pkt)
->frame_control)) {
/* subtype 12 deauth
* packet */
priv->deauth_evt_cnt++;
#define MAX_DEAUTH_COUNTER 5
if (priv->deauth_evt_cnt >=
MAX_DEAUTH_COUNTER) {
if (woal_reset_wifi(
priv->phandle,
priv->deauth_evt_cnt,
"EAPOL timeout") ==
MLAN_STATUS_SUCCESS) {
priv->deauth_evt_cnt =
0;
}
}
}
priv->cfg_disconnect = MTRUE;
woal_mgmt_frame_register(
priv,

View file

@ -606,7 +606,12 @@ static int woal_cfg80211_set_monitor_channel(struct wiphy *wiphy,
ret = 0;
goto done;
}
if (woal_is_any_interface_active(handle)) {
PRINTM(MERROR,
"Cannot change monitor channel for an active"
" interface\n");
goto done;
}
memset(&band_chan_cfg, 0x00, sizeof(band_chan_cfg));
/* Set channel */
band_chan_cfg.channel = ieee80211_frequency_to_channel(
@ -637,8 +642,8 @@ static int woal_cfg80211_set_monitor_channel(struct wiphy *wiphy,
band_chan_cfg.chan_bandwidth = bandwidth;
if (MLAN_STATUS_SUCCESS !=
woal_set_net_monitor(priv, MOAL_IOCTL_WAIT,
CHANNEL_SPEC_SNIFFER_MODE, 0x7,
woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, MTRUE,
handle->mon_if->flag,
&band_chan_cfg)) {
PRINTM(MERROR, "%s: woal_set_net_monitor fail\n",
__func__);
@ -1468,6 +1473,35 @@ static int woal_cfg80211_set_auth(moal_private *priv, int encrypt_mode,
return ret;
}
/**
* @brief Reset the wifi
*
* @param handle A pointer to moal_handle structure
* @param cnt wifi reset count
* @param reason wifi reset reason
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_PENDING
*/
mlan_status woal_reset_wifi(moal_handle *handle, t_u8 cnt, char *reason)
{
static wifi_timeval reset_time;
wifi_timeval ts;
t_u64 diff;
#define MAX_WIFI_RESET_INTERVAL 15 * 60 * 1000000 // 15 minute
woal_get_monotonic_time(&ts);
diff = (t_u64)(timeval_to_usec(ts) - timeval_to_usec(reset_time));
PRINTM(MERROR, "WiFi Reset diff %lld\n", diff);
if (reset_time.time_sec == 0 || diff >= MAX_WIFI_RESET_INTERVAL) {
reset_time = ts;
PRINTM(MERROR, "WiFi Reset due to %s cnt %d\n", reason, cnt);
/* Do wifi independent reset */
woal_process_hang(handle);
return MLAN_STATUS_SUCCESS;
}
return MLAN_STATUS_PENDING;
}
/**
* @brief Informs the CFG802.11 subsystem of a new BSS connection.
*
@ -1952,6 +1986,10 @@ static void woal_save_assoc_params(moal_private *priv,
sizeof(priv->conn_ssid));
priv->conn_ssid_len = ssid_bssid->ssid.ssid_len;
}
if (priv->sinfo)
memset(priv->sinfo, 0, sizeof(struct station_info));
else
priv->sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
LEAVE();
}
@ -2423,6 +2461,15 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy,
case MLAN_STATUS_PENDING:
atomic_inc(&priv->phandle->tx_pending);
queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
#define MAX_AUTH_COUNTER 5
priv->auth_tx_cnt++;
if (priv->auth_tx_cnt >= MAX_AUTH_COUNTER) {
if (woal_reset_wifi(priv->phandle, priv->auth_tx_cnt,
"auth timeout") ==
MLAN_STATUS_SUCCESS) {
priv->auth_tx_cnt = 0;
}
}
break;
case MLAN_STATUS_SUCCESS:
woal_free_mlan_buffer(priv->phandle, pmbuf);
@ -4323,6 +4370,9 @@ static t_u8 woal_is_uap_scan_result_expired(moal_private *priv)
mlan_scan_resp scan_resp;
wifi_timeval t;
ENTER();
memset(&scan_resp, 0, sizeof(scan_resp));
if (MLAN_STATUS_SUCCESS !=
woal_get_scan_table(priv, MOAL_IOCTL_WAIT, &scan_resp)) {
LEAVE();
@ -4355,6 +4405,7 @@ t_u8 wlan_check_scan_table_ageout(moal_private *priv)
mlan_scan_resp scan_resp;
wifi_timeval t;
ENTER();
memset(&scan_resp, 0, sizeof(scan_resp));
if (MLAN_STATUS_SUCCESS !=
woal_get_scan_table(priv, MOAL_IOCTL_WAIT, &scan_resp)) {
LEAVE();
@ -5230,6 +5281,7 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
if (bss_info.mdid == ssid_bssid->ft_md &&
bss_info.ft_cap == ssid_bssid->ft_cap) {
ret = woal_start_ft_roaming(priv, ssid_bssid);
kfree(ssid_bssid);
LEAVE();
return 0;
}
@ -5243,6 +5295,7 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
if (!assoc_rsp) {
PRINTM(MERROR, "Failed to allocate memory for assoc_rsp\n");
ret = -ENOMEM;
kfree(ssid_bssid);
LEAVE();
return ret;
}
@ -5459,11 +5512,8 @@ static int woal_cfg80211_deauthenticate(struct wiphy *wiphy,
struct cfg80211_deauth_request *req)
{
int ret = 0;
#if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
moal_private *pmpriv = (moal_private *)woal_get_netdev_priv(dev);
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
if (priv->host_mlme) {
priv->host_mlme = MFALSE;
priv->auth_flag = 0;
@ -5476,10 +5526,12 @@ static int woal_cfg80211_deauthenticate(struct wiphy *wiphy,
ret = woal_cfg80211_disconnect(wiphy, dev, req->reason_code);
#if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
if (pmpriv->wdev->iftype == NL80211_IFTYPE_STATION ||
pmpriv->wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)
cfg80211_disconnected(pmpriv->netdev, 0, NULL, 0, GFP_KERNEL);
if (priv->wdev->iftype == NL80211_IFTYPE_STATION ||
priv->wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)
cfg80211_disconnected(priv->netdev, 0, NULL, 0, GFP_KERNEL);
#endif
if (priv->media_connected)
woal_send_disconnect_to_system(priv, DEF_DEAUTH_REASON_CODE);
return ret;
}
@ -5501,11 +5553,8 @@ static int woal_cfg80211_disassociate(struct wiphy *wiphy,
struct cfg80211_disassoc_request *req)
{
int ret = 0;
#if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
moal_private *pmpriv = (moal_private *)woal_get_netdev_priv(dev);
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
if (priv->host_mlme) {
priv->host_mlme = MFALSE;
priv->auth_flag = 0;
@ -5518,10 +5567,13 @@ static int woal_cfg80211_disassociate(struct wiphy *wiphy,
ret = woal_cfg80211_disconnect(wiphy, dev, req->reason_code);
#if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
if (pmpriv->wdev->iftype == NL80211_IFTYPE_STATION ||
pmpriv->wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)
cfg80211_disconnected(pmpriv->netdev, 0, NULL, 0, GFP_KERNEL);
if (priv->wdev->iftype == NL80211_IFTYPE_STATION ||
priv->wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)
cfg80211_disconnected(priv->netdev, 0, NULL, 0, GFP_KERNEL);
#endif
if (priv->media_connected)
woal_send_disconnect_to_system(priv, DEF_DEAUTH_REASON_CODE);
return ret;
}
#endif
@ -9460,10 +9512,11 @@ static int woal_cfg80211_probe_client(struct wiphy *wiphy,
void woal_host_mlme_disconnect(moal_private *priv, u16 reason_code, u8 *sa)
{
t_u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
t_u8 frame_buf[26];
t_u8 frame_buf[100];
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)frame_buf;
ENTER();
memset(frame_buf, 0, sizeof(frame_buf));
mgmt->frame_control = (__force __le16)IEEE80211_STYPE_DEAUTH;
mgmt->duration = 0;
mgmt->seq_ctrl = 0;
@ -9629,6 +9682,9 @@ static mlan_status woal_cfg80211_init_wiphy(moal_private *priv,
t_u32 hw_dev_cap;
#ifdef UAP_SUPPORT
pmlan_uap_bss_param sys_cfg = NULL;
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
t_u16 enable = 0;
#endif
int mcs_supp = 0;
@ -9793,6 +9849,17 @@ static mlan_status woal_cfg80211_init_wiphy(moal_private *priv,
if (frag_thr < MLAN_RTS_MIN_VALUE || frag_thr > MLAN_RTS_MAX_VALUE)
frag_thr = MLAN_FRAG_RTS_DISABLED;
wiphy->frag_threshold = (t_u32)frag_thr;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
/* Enable multi-channel by default if multi-channel is supported */
if (cfg80211_iface_comb_ap_sta.num_different_channels > 1) {
if (priv->phandle->card_info->drcs &&
moal_extflg_isset(priv->phandle, EXT_CFG80211_DRCS)) {
enable = 1;
ret = woal_mc_policy_cfg(priv, &enable, wait_option,
MLAN_ACT_SET);
}
}
#endif
done:
LEAVE();
@ -9968,6 +10035,14 @@ mlan_status woal_register_cfg80211(moal_private *priv)
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
if ((moal_extflg_isset(priv->phandle, EXT_CFG80211_DRCS) &&
priv->phandle->card_info->drcs) ||
IS_CARD9098(priv->phandle->card_type)) {
cfg80211_iface_comb_ap_sta.num_different_channels = 2;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
cfg80211_iface_comb_ap_sta.radar_detect_widths = 0;
#endif
}
/* Initialize interface combinations */
wiphy->iface_combinations = &cfg80211_iface_comb_ap_sta;
wiphy->n_iface_combinations = 1;
@ -10178,8 +10253,6 @@ mlan_status woal_register_cfg80211(moal_private *priv)
goto err_wiphy;
}
wiphy->interface_modes &= ~(MBIT(NL80211_IFTYPE_MONITOR));
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
if (fw_info.force_reg) {
PRINTM(MCMND, "FW region_code=%d force_reg=%d\n",

View file

@ -35,6 +35,9 @@ Change log:
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
#include "moal_cfg80211.h"
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
#include <linux/compat.h>
#endif
/********************************************************
Local Variables
@ -3690,10 +3693,12 @@ done:
* @param priv A pointer to moal_private structure
* @param action MLAN_ACT_SET or MLAN_ACT_GET
* @param he_cfg a pointer to mlan_ds_11ax_he_cfg
* @param wait_option wait_option
*
* @return 0--success, otherwise failure
*/
int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg)
int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg,
t_u8 wait_option)
{
int ret = 0;
mlan_status status = MLAN_STATUS_SUCCESS;
@ -3711,14 +3716,12 @@ int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg)
moal_memcpy_ext(priv->phandle, &cfg_11ax->param.he_cfg, he_cfg,
sizeof(mlan_ds_11ax_he_cfg),
sizeof(mlan_ds_11ax_he_cfg));
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
status = woal_request_ioctl(priv, req, wait_option);
if (status == MLAN_STATUS_SUCCESS) {
moal_memcpy_ext(priv->phandle, he_cfg, &cfg_11ax->param.he_cfg,
sizeof(mlan_ds_11ax_he_cfg),
sizeof(mlan_ds_11ax_he_cfg));
}
moal_memcpy_ext(priv->phandle, he_cfg, &cfg_11ax->param.he_cfg,
sizeof(mlan_ds_11ax_he_cfg),
sizeof(mlan_ds_11ax_he_cfg));
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
@ -3762,7 +3765,7 @@ int woal_uap_set_11ax_status(moal_private *priv, t_u8 action, t_u8 band,
ret = -EFAULT;
goto done;
}
if (woal_11ax_cfg(priv, MLAN_ACT_GET, &he_cfg)) {
if (woal_11ax_cfg(priv, MLAN_ACT_GET, &he_cfg, MOAL_IOCTL_WAIT)) {
PRINTM(MERROR, "Fail to get 11ax cfg!\n");
ret = -EFAULT;
goto done;
@ -3792,7 +3795,7 @@ int woal_uap_set_11ax_status(moal_private *priv, t_u8 action, t_u8 band,
}
}
DBG_HEXDUMP(MCMD_D, "HE_CFG ", (t_u8 *)&he_cfg, sizeof(he_cfg));
ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg);
ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg, MOAL_IOCTL_WAIT);
done:
LEAVE();
return ret;
@ -4482,9 +4485,11 @@ int woal_uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
int ret = 0;
ENTER();
#ifdef CONFIG_COMPAT
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
if (in_compat_syscall()) /* not implemented yet */
return -EOPNOTSUPP;
#endif
#endif
switch (cmd) {

View file

@ -592,7 +592,8 @@ int woal_uap_set_ap_cfg(moal_private *priv, t_u8 *data, int len);
int woal_uap_set_11ac_status(moal_private *priv, t_u8 action, t_u8 vht20_40,
IEEEtypes_VHTCap_t *vhtcap_ie);
int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg);
int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg,
t_u8 wait_option);
int woal_uap_set_11ax_status(moal_private *priv, t_u8 action, t_u8 band,
IEEEtypes_HECap_t *hecap_ie);
int woal_set_uap_ht_tx_cfg(moal_private *priv, Band_Config_t bandcfg,

View file

@ -581,7 +581,7 @@ static t_u8 woal_check_11ax_capability(moal_private *priv, t_u8 band,
he_cfg.band = MBIT(1);
else if (band == BAND_2GHZ)
he_cfg.band = MBIT(0);
if (0 == woal_11ax_cfg(priv, MLAN_ACT_GET, &he_cfg)) {
if (0 == woal_11ax_cfg(priv, MLAN_ACT_GET, &he_cfg, MOAL_IOCTL_WAIT)) {
if (he_cfg.he_cap.len &&
(he_cfg.he_cap.ext_id == HE_CAPABILITY)) {
if (memcmp(he_cfg.he_cap.he_txrx_mcs_support,
@ -1003,6 +1003,7 @@ static int woal_cfg80211_beacon_config(moal_private *priv,
#endif
if (priv->channel) {
woal_check_mc_connection(priv, MOAL_IOCTL_WAIT, priv->channel);
memset(sys_config->rates, 0, sizeof(sys_config->rates));
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
@ -1513,8 +1514,7 @@ static int woal_cfg80211_add_mon_if(struct wiphy *wiphy,
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
name_assign_type_tmp = name_assign_type;
#endif
mon_if = woal_prepare_mon_if(priv, name, name_assign_type_tmp,
CHANNEL_SPEC_SNIFFER_MODE);
mon_if = woal_prepare_mon_if(priv, name, name_assign_type_tmp);
if (!mon_if) {
PRINTM(MFATAL, "Prepare mon_if fail.\n");
goto fail;
@ -1536,24 +1536,44 @@ static int woal_cfg80211_add_mon_if(struct wiphy *wiphy,
mon_if->wdev.wiphy = wiphy;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
/* Set default band channel config */
mon_if->band_chan_cfg.band = BAND_B | BAND_G;
mon_if->band_chan_cfg.band |= BAND_GN;
mon_if->band_chan_cfg.channel = 1;
mon_if->band_chan_cfg.chan_bandwidth = CHANNEL_BW_20MHZ;
memset(&chan_info, 0x00, sizeof(chan_info));
chan_info.channel = 1;
chan_info.is_11n_enabled = MTRUE;
if (MLAN_STATUS_FAILURE ==
woal_chandef_create(priv, &mon_if->chandef, &chan_info)) {
mon_if->band_chan_cfg.channel = 0;
if (!woal_is_any_interface_active(handle)) {
/* Set default band channel config */
mon_if->band_chan_cfg.band = BAND_B | BAND_G;
mon_if->band_chan_cfg.band |= BAND_GN;
mon_if->band_chan_cfg.channel = 1;
mon_if->band_chan_cfg.chan_bandwidth = CHANNEL_BW_20MHZ;
memset(&chan_info, 0x00, sizeof(chan_info));
chan_info.channel = 1;
chan_info.is_11n_enabled = MTRUE;
}
mon_if->flag = 0x7;
if (MLAN_STATUS_SUCCESS !=
woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, MTRUE, mon_if->flag,
&mon_if->band_chan_cfg)) {
PRINTM(MERROR, "%s: woal_set_net_monitor fail\n", __func__);
ret = -EFAULT;
goto fail;
}
if (MLAN_STATUS_SUCCESS !=
woal_set_net_monitor(priv, MOAL_IOCTL_WAIT,
CHANNEL_SPEC_SNIFFER_MODE, 0x7,
&mon_if->band_chan_cfg)) {
PRINTM(MERROR, "%s: woal_set_net_monitor fail\n", __func__);
if (woal_is_any_interface_active(handle)) {
/* set current band channel config */
chan_info.bandcfg.chanBand = mon_if->band_chan_cfg.band;
if (mon_if->band_chan_cfg.band &
(BAND_B | BAND_G | BAND_GN | BAND_GAC))
chan_info.bandcfg.chanBand = BAND_2GHZ;
else
/* TODO: Add support for BAND_4GHZ */
chan_info.bandcfg.chanBand = BAND_5GHZ;
chan_info.bandcfg.chanWidth =
mon_if->band_chan_cfg.chan_bandwidth;
chan_info.channel = mon_if->band_chan_cfg.channel;
chan_info.is_11n_enabled = MTRUE;
}
if (MLAN_STATUS_FAILURE ==
woal_chandef_create(priv, &mon_if->chandef, &chan_info)) {
/* stop monitor mode on error */
woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, MFALSE, 0, NULL);
ret = -EFAULT;
goto fail;
}
@ -2665,7 +2685,7 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
ENTER();
if (priv->phandle->driver_status) {
if (priv->phandle->driver_status || priv->phandle->surprise_removed) {
PRINTM(MERROR,
"Block woal_cfg80211_del_beacon in abnormal driver state\n");
LEAVE();
@ -2725,6 +2745,9 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
ret = -EFAULT;
goto done;
}
#if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
woal_cfg80211_setup_uap_he_cap(priv, MOAL_NO_WAIT);
#endif
}
woal_clear_all_mgmt_ies(priv, MOAL_NO_WAIT);
#ifdef STA_SUPPORT
@ -3546,6 +3569,8 @@ int woal_cfg80211_start_radar_detection(struct wiphy *wiphy,
mlan_ds_11h_cfg *p11h_cfg = NULL;
int ret = 0;
mlan_status status = MLAN_STATUS_SUCCESS;
chan_band_info channel;
t_u16 enable = 0;
ENTER();
@ -3568,6 +3593,25 @@ int woal_cfg80211_start_radar_detection(struct wiphy *wiphy,
ret = -EBUSY;
goto done;
}
if (MLAN_STATUS_SUCCESS ==
woal_mc_policy_cfg(priv, &enable, MOAL_IOCTL_WAIT, MLAN_ACT_GET)) {
if (enable) {
if (MLAN_STATUS_SUCCESS ==
woal_get_active_intf_channel(priv, &channel)) {
if (channel.channel !=
chandef->chan->hw_value) {
PRINTM(MERROR,
"DFS channel is not allowed when another connection exists on different channel\n");
PRINTM(MERROR,
"Another connection's channel=%d, dfs channel=%d\n",
channel.channel,
chandef->chan->hw_value);
ret = -EINVAL;
goto done;
}
}
}
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg));
if (NULL == req) {
ret = -ENOMEM;
@ -3745,8 +3789,12 @@ mlan_status woal_register_uap_cfg80211(struct net_device *dev, t_u8 bss_type)
return MLAN_STATUS_FAILURE;
}
if (bss_type == MLAN_BSS_TYPE_UAP)
if (bss_type == MLAN_BSS_TYPE_UAP) {
wdev->iftype = NL80211_IFTYPE_AP;
#if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
woal_cfg80211_setup_uap_he_cap(priv, MOAL_IOCTL_WAIT);
#endif
}
dev_net_set(dev, wiphy_net(wdev->wiphy));
dev->ieee80211_ptr = wdev;

View file

@ -406,6 +406,8 @@ static void woal_usb_tx_complete(struct urb *urb)
atomic_dec(&cardp->tx_cmd_urb_pending);
else if (context->ep == cardp->tx_data_ep)
atomic_dec(&cardp->tx_data_urb_pending);
else if (context->ep == cardp->tx_data2_ep)
atomic_dec(&cardp->tx_data2_urb_pending);
queue_work(handle->workqueue, &handle->main_work);
@ -635,6 +637,10 @@ static void woal_usb_unlink_urb(void *card_desc)
usb_kill_urb(
cardp->tx_data_list[i].urb);
}
if (cardp->tx_data2_list[i].urb) {
usb_kill_urb(
cardp->tx_data2_list[i].urb);
}
}
}
}
@ -674,6 +680,10 @@ void woal_usb_free(struct usb_card_rec *cardp)
usb_free_urb(cardp->tx_data_list[i].urb);
cardp->tx_data_list[i].urb = NULL;
}
if (cardp->tx_data2_list[i].urb) {
usb_free_urb(cardp->tx_data2_list[i].urb);
cardp->tx_data2_list[i].urb = NULL;
}
}
/* Free Tx cmd URB */
if (cardp->tx_cmd.urb) {
@ -1003,6 +1013,24 @@ static int woal_usb_probe(struct usb_interface *intf,
(__force int)woal_le16_to_cpu(
endpoint->wMaxPacketSize);
}
if (usb_endpoint_is_bulk_out(endpoint) &&
(usb_endpoint_num(endpoint) ==
MLAN_USB_EP_DATA_CH2 ||
usb_endpoint_num(endpoint) ==
MLAN_USB_EP_DATA_CH2_IF2)) {
/* We found a bulk out data endpoint */
PRINTM(MCMND,
"Bulk OUT2: max packet size = %d, address = %d\n",
woal_le16_to_cpu(
endpoint->wMaxPacketSize),
endpoint->bEndpointAddress);
usb_cardp->tx_data2_ep =
endpoint->bEndpointAddress;
atomic_set(&usb_cardp->tx_data2_urb_pending, 0);
usb_cardp->tx_data2_maxpktsize =
(__force int)woal_le16_to_cpu(
endpoint->wMaxPacketSize);
}
if ((usb_endpoint_is_bulk_out(endpoint) ||
usb_endpoint_is_int_out(endpoint)) &&
@ -1041,6 +1069,14 @@ static int woal_usb_probe(struct usb_interface *intf,
__FUNCTION__);
goto error;
}
if (!usb_cardp->tx_data2_ep) {
PRINTM(MERROR,
"%s: invalid endpoint assignment\n",
__FUNCTION__);
PRINTM(MERROR,
"%s: DATA2 endpoint is not enumarated\n",
__FUNCTION__);
}
}
usb_cardp->tx_aggr_ctrl.enable = MFALSE;
@ -1254,6 +1290,9 @@ static int woal_usb_suspend(struct usb_interface *intf, pm_message_t message)
if (cardp->tx_data_list[i].urb) {
usb_kill_urb(cardp->tx_data_list[i].urb);
}
if (cardp->tx_data2_list[i].urb) {
usb_kill_urb(cardp->tx_data2_list[i].urb);
}
}
/* Unlink Tx cmd URB */
if (cardp->tx_cmd.urb) {
@ -1385,6 +1424,15 @@ mlan_status woal_usb_tx_init(moal_handle *handle)
ret = MLAN_STATUS_FAILURE;
goto init_exit;
}
cardp->tx_data2_list[i].handle = handle;
cardp->tx_data2_list[i].ep = cardp->tx_data2_ep;
/* Allocate URB for data */
cardp->tx_data2_list[i].urb = usb_alloc_urb(0, GFP_KERNEL);
if (!cardp->tx_data2_list[i].urb) {
PRINTM(MERROR, "Tx data URB allocation failed\n");
ret = MLAN_STATUS_FAILURE;
goto init_exit;
}
}
init_exit:
@ -1513,6 +1561,8 @@ static mlan_status woal_usb_write_data_sync(moal_handle *handle,
bulk_out_maxpktsize = cardp->tx_cmd_maxpktsize;
else if (ep == cardp->tx_data_ep)
bulk_out_maxpktsize = cardp->tx_data_maxpktsize;
else if (ep == cardp->tx_data2_ep)
bulk_out_maxpktsize = cardp->tx_data2_maxpktsize;
if (length % bulk_out_maxpktsize == 0)
length++;
@ -1599,6 +1649,11 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf,
(atomic_read(&cardp->tx_data_urb_pending) >= MVUSB_TX_HIGH_WMARK)) {
ret = MLAN_STATUS_RESOURCE;
goto tx_ret;
} else if ((ep == cardp->tx_data2_ep) &&
(atomic_read(&cardp->tx_data2_urb_pending) >=
MVUSB_TX_HIGH_WMARK)) {
ret = MLAN_STATUS_RESOURCE;
goto tx_ret;
}
PRINTM(MINFO, "woal_write_data_async: ep=%d\n", ep);
@ -1611,6 +1666,11 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf,
if (cardp->tx_data_ix >= MVUSB_TX_HIGH_WMARK)
cardp->tx_data_ix = 0;
context = &cardp->tx_data_list[cardp->tx_data_ix++];
} else if (ep == cardp->tx_data2_ep) {
bulk_out_maxpktsize = cardp->tx_data2_maxpktsize;
if (cardp->tx_data2_ix >= MVUSB_TX_HIGH_WMARK)
cardp->tx_data2_ix = 0;
context = &cardp->tx_data2_list[cardp->tx_data2_ix++];
}
}
@ -1652,6 +1712,8 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf,
atomic_inc(&cardp->tx_cmd_urb_pending);
else if (ep == cardp->tx_data_ep)
atomic_inc(&cardp->tx_data_urb_pending);
else if (ep == cardp->tx_data2_ep)
atomic_inc(&cardp->tx_data2_urb_pending);
if (usb_submit_urb(tx_urb, GFP_ATOMIC)) {
/* Submit URB failure */
PRINTM(MERROR, "Submit EP %d Tx URB failed: %d\n", ep, ret);
@ -1664,6 +1726,13 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf,
cardp->tx_data_ix--;
else
cardp->tx_data_ix = MVUSB_TX_HIGH_WMARK;
} else if (ep == cardp->tx_data2_ep) {
atomic_dec(&cardp->tx_data2_urb_pending);
if (cardp->tx_data2_ix)
cardp->tx_data2_ix--;
else
cardp->tx_data2_ix =
MVUSB_TX_HIGH_WMARK;
}
}
ret = MLAN_STATUS_FAILURE;
@ -1672,6 +1741,10 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf,
(atomic_read(&cardp->tx_data_urb_pending) ==
MVUSB_TX_HIGH_WMARK))
ret = MLAN_STATUS_PRESOURCE;
else if (ep == cardp->tx_data2_ep &&
(atomic_read(&cardp->tx_data2_urb_pending) ==
MVUSB_TX_HIGH_WMARK))
ret = MLAN_STATUS_PRESOURCE;
else
ret = MLAN_STATUS_SUCCESS;
}

View file

@ -243,6 +243,16 @@ struct usb_card_rec {
t_u8 resubmit_urbs;
/** USB card type */
t_u16 card_type;
/** Tx data endpoint address */
t_u8 tx_data2_ep;
/** Tx data endpoint max pkt size */
int tx_data2_maxpktsize;
/** Tx data2 URB pending count */
atomic_t tx_data2_urb_pending;
/** Index to point to next data urb to use */
int tx_data2_ix;
/** Pre-allocated urb for data */
urb_context tx_data2_list[MVUSB_TX_HIGH_WMARK];
t_u8 second_mac;
};

View file

@ -790,30 +790,31 @@ static int woal_get_sens(struct net_device *dev, struct iw_request_info *info,
*
* @param dev A pointer to net_device structure
* @param info A pointer to iw_request_info structure
* @param vwrq A pointer to iw_param structure
* @param vwrq A pointer to iwreq_data structure
* @param extra A pointer to extra data buf
*
* @return 0 --success, otherwise fail
*/
static int woal_set_txpow(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
union iwreq_data *vwrq, char *extra)
{
int ret = 0;
struct iw_param *vwrq_ = (struct iw_param *)vwrq;
moal_private *priv = (moal_private *)netdev_priv(dev);
mlan_power_cfg_t power_cfg;
ENTER();
if (vwrq->disabled) {
if (vwrq_->disabled) {
woal_set_radio(priv, 0);
goto done;
}
woal_set_radio(priv, 1);
if (!vwrq->fixed)
if (!vwrq_->fixed)
power_cfg.is_power_auto = 1;
else {
power_cfg.is_power_auto = 0;
power_cfg.power_level = vwrq->value;
power_cfg.power_level = vwrq_->value;
}
if (MLAN_STATUS_SUCCESS !=
@ -832,15 +833,16 @@ done:
*
* @param dev A pointer to net_device structure
* @param info A pointer to iw_request_info structure
* @param vwrq A pointer to iw_param structure
* @param vwrq A pointer to iwreq_data structure
* @param extra A pointer to extra data buf
*
* @return 0 --success, otherwise fail
*/
static int woal_get_txpow(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
union iwreq_data *vwrq, char *extra)
{
int ret = 0;
struct iw_param *vwrq_ = (struct iw_param *)vwrq;
moal_private *priv = (moal_private *)netdev_priv(dev);
mlan_power_cfg_t power_cfg;
mlan_bss_info bss_info;
@ -857,16 +859,16 @@ static int woal_get_txpow(struct net_device *dev, struct iw_request_info *info,
goto done;
}
vwrq->value = power_cfg.power_level;
vwrq_->value = power_cfg.power_level;
if (power_cfg.is_power_auto)
vwrq->fixed = 0;
vwrq_->fixed = 0;
else
vwrq->fixed = 1;
vwrq_->fixed = 1;
if (bss_info.radio_on) {
vwrq->disabled = 0;
vwrq->flags = IW_TXPOW_DBM;
vwrq_->disabled = 0;
vwrq_->flags = IW_TXPOW_DBM;
} else {
vwrq->disabled = 1;
vwrq_->disabled = 1;
}
done:
@ -2586,6 +2588,59 @@ done:
return ret;
}
/**
* @brief Request scan based on connect parameter
*
* @param priv A pointer to moal_private structure
* @param ssid_bssid A pointer to mlan_ssid_bssid structure
*
* @return 0 -- success, otherwise fail
*/
static int woal_owe_specific_scan(moal_private *priv,
mlan_ssid_bssid *ssid_bssid)
{
moal_handle *handle = priv->phandle;
int ret = 0;
wlan_user_scan_cfg *scan_req;
ENTER();
if (handle->scan_pending_on_block == MTRUE) {
PRINTM(MINFO, "scan already in processing...\n");
LEAVE();
return ret;
}
scan_req = (wlan_user_scan_cfg *)kmalloc(sizeof(wlan_user_scan_cfg),
GFP_KERNEL);
if (!scan_req) {
PRINTM(MERROR, "Malloc buffer failed\n");
LEAVE();
return -ENOMEM;
}
priv->report_scan_result = MTRUE;
memset(scan_req, 0x00, sizeof(wlan_user_scan_cfg));
scan_req->keep_previous_scan = MTRUE;
moal_memcpy_ext(priv->phandle, scan_req->ssid_list[0].ssid,
ssid_bssid->trans_ssid.ssid,
ssid_bssid->trans_ssid.ssid_len,
sizeof(scan_req->ssid_list[0].ssid));
scan_req->ssid_list[0].max_len = 0;
scan_req->chan_list[0].chan_number = ssid_bssid->channel;
if (ssid_bssid->bss_band == BAND_A)
scan_req->chan_list[0].radio_type = BAND_5GHZ;
else
scan_req->chan_list[0].radio_type = BAND_2GHZ;
scan_req->chan_list[0].scan_time = 0;
// TODO need set to PASSIVE TO ACTIVE on DFS channel
scan_req->chan_list[0].scan_type = MLAN_SCAN_TYPE_ACTIVE;
moal_memcpy_ext(priv->phandle, scan_req->random_mac, priv->random_mac,
ETH_ALEN, sizeof(scan_req->random_mac));
ret = woal_request_userscan(priv, MOAL_IOCTL_WAIT, scan_req);
kfree(scan_req);
LEAVE();
return ret;
}
/**
* @brief Set essid
*
@ -2603,6 +2658,7 @@ static int woal_set_essid(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq = &wrqu->data;
mlan_802_11_ssid req_ssid;
mlan_ssid_bssid ssid_bssid;
mlan_ssid_bssid *owe_ssid_bssid = NULL;
#ifdef REASSOCIATION
moal_handle *handle = priv->phandle;
mlan_bss_info bss_info;
@ -2740,6 +2796,34 @@ static int woal_set_essid(struct net_device *dev, struct iw_request_info *info,
ret = -EFAULT;
goto setessid_ret;
}
if (ssid_bssid.trans_ssid.ssid_len &&
(ssid_bssid.owe_transition_mode == OWE_TRANS_MODE_OPEN)) {
// We need scan for OWE AP
owe_ssid_bssid = (mlan_ssid_bssid *)kmalloc(
sizeof(mlan_ssid_bssid), GFP_KERNEL);
if (!owe_ssid_bssid) {
PRINTM(MERROR, "Malloc buffer failed\n");
ret = -ENOMEM;
goto setessid_ret;
}
woal_owe_specific_scan(priv, &ssid_bssid);
memset(owe_ssid_bssid, 0, sizeof(mlan_ssid_bssid));
moal_memcpy_ext(priv->phandle, &owe_ssid_bssid->ssid,
&ssid_bssid.trans_ssid,
sizeof(mlan_802_11_ssid),
sizeof(owe_ssid_bssid->ssid));
moal_memcpy_ext(priv->phandle, &owe_ssid_bssid->bssid,
&ssid_bssid.trans_bssid,
sizeof(mlan_802_11_mac_addr),
sizeof(owe_ssid_bssid->bssid));
if (MLAN_STATUS_SUCCESS ==
woal_find_essid(priv, owe_ssid_bssid,
MOAL_IOCTL_WAIT))
moal_memcpy_ext(priv->phandle, &ssid_bssid,
owe_ssid_bssid,
sizeof(mlan_ssid_bssid),
sizeof(ssid_bssid));
}
if (MLAN_STATUS_SUCCESS !=
woal_11d_check_ap_channel(priv, MOAL_IOCTL_WAIT,
&ssid_bssid)) {
@ -2793,6 +2877,8 @@ setessid_ret:
#ifdef REASSOCIATION
MOAL_REL_SEMAPHORE(&handle->reassoc_sem);
#endif
if (owe_ssid_bssid)
kfree(owe_ssid_bssid);
LEAVE();
return ret;
}