summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Yang <yangyang@marvell.com>2013-05-10 17:48:52 -0700
committerRiham Haidar <rhaidar@nvidia.com>2013-06-12 18:52:10 -0700
commit2b28a245f5f773ec11de585aeaa641f35696f818 (patch)
treea59aee9a84d34171cd24f828d6a2dd24ee08277e
parent339d494c5790e7a96d00e94e7e6c68716644c18a (diff)
net: wireless: sd8797: Update SD8797 WLAN driver
Signed-off-by: Marc Yang <yangyang@marvell.com> Bug 1279040 Change-Id: Ifee06a06feb304b039f62f2a3730dc4f04f1e7b5 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: http://git-master/r/235721 Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--drivers/net/wireless/sd8797/Makefile155
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11d.c97
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n.c128
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c23
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c86
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_cfp.c18
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c752
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_decl.h160
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_fw.h176
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_ieee.h164
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_init.c49
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_ioctl.h313
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_join.c195
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_main.h134
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_meas.c16
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_misc.c357
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_scan.c100
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sdio.c5
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sdio.h8
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_shim.c115
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c501
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c119
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_event.c53
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c719
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c4
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c9
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_txrx.c111
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c486
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c24
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c31
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_wmm.c482
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_wmm.h20
-rw-r--r--drivers/net/wireless/sd8797/mlinux/mlan_decl.h160
-rw-r--r--drivers/net/wireless/sd8797/mlinux/mlan_ieee.h164
-rw-r--r--drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h313
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c996
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h124
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_debug.c29
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c1362
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h24
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_ioctl.c522
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_main.c1026
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_main.h377
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_priv.c402
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_priv.h6
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_proc.c20
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_sdio.h12
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c119
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_shim.c407
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_shim.h6
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c1583
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.h1
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap.c34
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap.h40
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c1000
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.h1
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap_wext.c73
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_wext.c85
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_wext.h64
59 files changed, 10496 insertions, 4064 deletions
diff --git a/drivers/net/wireless/sd8797/Makefile b/drivers/net/wireless/sd8797/Makefile
index 4efa18a5b58e..394d5e542266 100644
--- a/drivers/net/wireless/sd8797/Makefile
+++ b/drivers/net/wireless/sd8797/Makefile
@@ -18,32 +18,46 @@
# ARE EXPRESSLY DISCLAIMED. The License provides additional details about
# this warranty disclaimer.
-# Enable CFG80211 for STA
-ifeq ($(CONFIG_CFG80211),y)
-CONFIG_STA_CFG80211=y
-else
-ifeq ($(CONFIG_CFG80211),m)
-CONFIG_STA_CFG80211=y
-else
-CONFIG_STA_CFG80211=n
-endif
-endif
+CC= $(CROSS_COMPILE)gcc
+LD= $(CROSS_COMPILE)ld
+BACKUP= /root/backup
+YMD= `date +%Y%m%d%H%M`
-# Enable CFG80211 for uAP
-ifeq ($(CONFIG_CFG80211),y)
-CONFIG_UAP_CFG80211=y
-else
-ifeq ($(CONFIG_CFG80211),m)
-CONFIG_UAP_CFG80211=y
-else
-CONFIG_UAP_CFG80211=n
-endif
-endif
+#############################################################################
+# Configuration Options
+#############################################################################
+
+# Re-association in driver
+CONFIG_REASSOCIATION=y
+
+# Manufacturing firmware support
+CONFIG_MFG_CMD_SUPPORT=y
+
+# Big-endian platform
+CONFIG_BIG_ENDIAN=n
+
+# DFS testing support
+CONFIG_DFS_TESTING_SUPPORT=y
+
+# Use static link for app build
+export CONFIG_STATIC_LINK=y
+
+MODEXT = ko
#############################################################################
# Compiler Flags
#############################################################################
+EXTRA_CFLAGS += -I$(KERNELDIR)/include
+
+EXTRA_CFLAGS += -Idrivers/net/wireless/sd8797/mlan
+EXTRA_CFLAGS += -DLINUX
+EXTRA_CFLAGS += -DFPNUM='"69"'
+EXTRA_CFLAGS += -DDEBUG_LEVEL1
+EXTRA_CFLAGS += -DPROC_DEBUG
+EXTRA_CFLAGS += -DSDIO_MULTI_PORT_TX_AGGR
+EXTRA_CFLAGS += -DSDIO_MULTI_PORT_RX_AGGR
+
ifeq ($(CONFIG_DEBUG),1)
EXTRA_CFLAGS += -DDEBUG_LEVEL1
endif
@@ -54,50 +68,26 @@ ifeq ($(CONFIG_DEBUG),2)
DBG= -dbg
endif
-EXTRA_CFLAGS += -Idrivers/net/wireless/sd8797/mlan
-EXTRA_CFLAGS += -DLINUX
-EXTRA_CFLAGS += -DFPNUM='"69"'
-EXTRA_CFLAGS += -DDEBUG_LEVEL1
-EXTRA_CFLAGS += -DPROC_DEBUG
-EXTRA_CFLAGS += -DSDIO_MULTI_PORT_TX_AGGR
-EXTRA_CFLAGS += -DSDIO_MULTI_PORT_RX_AGGR
-EXTRA_CFLAGS += -DSDIO_SUSPEND_RESUME
-EXTRA_CFLAGS += -DMMC_PM_KEEP_POWER
-EXTRA_CFLAGS += -DDFS_TESTING_SUPPORT
-EXTRA_CFLAGS += -DMFG_CMD_SUPPORT
-
ifeq ($(CONFIG_64BIT), y)
EXTRA_CFLAGS += -DMLAN_64BIT
endif
ifeq ($(CONFIG_STA_SUPPORT),y)
EXTRA_CFLAGS += -DSTA_SUPPORT
+ifeq ($(CONFIG_REASSOCIATION),y)
EXTRA_CFLAGS += -DREASSOCIATION
-ifeq ($(CONFIG_STA_WEXT),y)
- EXTRA_CFLAGS += -DSTA_WEXT
-endif
-ifeq ($(CONFIG_STA_CFG80211),y)
- EXTRA_CFLAGS += -DSTA_CFG80211
endif
else
CONFIG_WIFI_DIRECT_SUPPORT=n
CONFIG_WIFI_DISPLAY_SUPPORT=n
-CONFIG_STA_WEXT=n
CONFIG_STA_CFG80211=n
endif
ifeq ($(CONFIG_UAP_SUPPORT),y)
EXTRA_CFLAGS += -DUAP_SUPPORT
-ifeq ($(CONFIG_UAP_WEXT),y)
- EXTRA_CFLAGS += -DUAP_WEXT
-endif
-ifeq ($(CONFIG_UAP_CFG80211),y)
- EXTRA_CFLAGS += -DUAP_CFG80211
-endif
else
CONFIG_WIFI_DIRECT_SUPPORT=n
CONFIG_WIFI_DISPLAY_SUPPORT=n
-CONFIG_UAP_WEXT=n
CONFIG_UAP_CFG80211=n
endif
@@ -108,14 +98,81 @@ ifeq ($(CONFIG_WIFI_DISPLAY_SUPPORT),y)
EXTRA_CFLAGS += -DWIFI_DISPLAY_SUPPORT
endif
+ifeq ($(CONFIG_MFG_CMD_SUPPORT),y)
+ EXTRA_CFLAGS += -DMFG_CMD_SUPPORT
+endif
+
ifeq ($(CONFIG_BIG_ENDIAN),y)
EXTRA_CFLAGS += -DBIG_ENDIAN_SUPPORT
endif
+ifeq ($(CONFIG_DFS_TESTING_SUPPORT),y)
+ EXTRA_CFLAGS += -DDFS_TESTING_SUPPORT
+endif
+
#############################################################################
# Make Targets
#############################################################################
+# Enable CFG80211 for STA
+ifeq ($(CONFIG_CFG80211),y)
+ CONFIG_STA_CFG80211=y
+else
+ifeq ($(CONFIG_CFG80211),m)
+ CONFIG_STA_CFG80211=y
+else
+ CONFIG_STA_CFG80211=n
+endif
+endif
+
+# Enable CFG80211 for uAP
+ifeq ($(CONFIG_CFG80211),y)
+ CONFIG_UAP_CFG80211=y
+else
+ifeq ($(CONFIG_CFG80211),m)
+ CONFIG_UAP_CFG80211=y
+else
+ CONFIG_UAP_CFG80211=n
+endif
+endif
+
+ifneq ($(CONFIG_STA_SUPPORT),y)
+ CONFIG_WIFI_DIRECT_SUPPORT=n
+ CONFIG_WIFI_DISPLAY_SUPPORT=n
+ CONFIG_STA_CFG80211=n
+endif
+
+ifneq ($(CONFIG_UAP_SUPPORT),y)
+ CONFIG_WIFI_DIRECT_SUPPORT=n
+ CONFIG_WIFI_DISPLAY_SUPPORT=n
+ CONFIG_UAP_CFG80211=n
+endif
+
+ifeq ($(CONFIG_STA_SUPPORT),y)
+ifeq ($(CONFIG_STA_CFG80211),y)
+ EXTRA_CFLAGS += -DSTA_CFG80211
+endif
+endif
+ifeq ($(CONFIG_UAP_SUPPORT),y)
+ifeq ($(CONFIG_UAP_CFG80211),y)
+ EXTRA_CFLAGS += -DUAP_CFG80211
+endif
+endif
+
+print:
+ifeq ($(CONFIG_STA_SUPPORT),y)
+ifeq ($(CONFIG_STA_CFG80211),n)
+ @echo "Can not build STA without WEXT or CFG80211"
+ exit 2
+endif
+endif
+ifeq ($(CONFIG_UAP_SUPPORT),y)
+ifeq ($(CONFIG_UAP_CFG80211),n)
+ @echo "Can not build UAP without WEXT or CFG80211"
+ exit 2
+endif
+endif
+
MOALOBJS = mlinux/moal_main.o \
mlinux/moal_ioctl.o \
mlinux/moal_shim.o \
@@ -176,11 +233,11 @@ MOALOBJS += mlinux/moal_proc.o
MOALOBJS += mlinux/moal_debug.o
endif
-obj-m := mlan.o
-mlan-objs := $(MLANOBJS)
+obj-m := sd8797mlan.o
+sd8797mlan-objs := $(MLANOBJS)
MOALOBJS += mlinux/moal_sdio_mmc.o
-obj-m += sd8xxx.o
-sd8xxx-objs := $(MOALOBJS)
+obj-m += sd8797.o
+sd8797-objs := $(MOALOBJS)
###############################################################
# End of file
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11d.c b/drivers/net/wireless/sd8797/mlan/mlan_11d.c
index 837349b1a34b..6c5672569aae 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_11d.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_11d.c
@@ -34,6 +34,7 @@ Change log:
Local Variables
********************************************************/
+#ifdef STA_SUPPORT
/** Region code mapping */
typedef struct _region_code_mapping
{
@@ -59,7 +60,6 @@ static region_code_mapping_t region_code_mapping[] = {
{"JP ", 0xFF}, /* Japan special */
};
-#ifdef STA_SUPPORT
/** Default Tx power */
#define TX_PWR_DEFAULT 10
@@ -133,38 +133,6 @@ channels for 11J JP 10M channel gap */
/********************************************************
Local Functions
********************************************************/
-
-/**
- * @brief This function converts region string to integer code
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param region Region string
- * @param code [output] Region code
- *
- * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
- */
-static mlan_status
-wlan_11d_region_2_code(pmlan_adapter pmadapter, t_u8 * region, OUT t_u8 * code)
-{
- t_u8 i;
- t_u8 size = sizeof(region_code_mapping) / sizeof(region_code_mapping_t);
-
- ENTER();
-
- /* Look for code in mapping table */
- for (i = 0; i < size; i++) {
- if (!memcmp(pmadapter, region_code_mapping[i].region,
- region, COUNTRY_CODE_LEN)) {
- *code = region_code_mapping[i].code;
- LEAVE();
- return MLAN_STATUS_SUCCESS;
- }
- }
-
- LEAVE();
- return MLAN_STATUS_FAILURE;
-}
-
#ifdef STA_SUPPORT
/**
* @brief This function converts integer code to region string
@@ -1434,22 +1402,14 @@ wlan_11d_cfg_domain_info(IN pmlan_adapter pmadapter,
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_11d_domain_info *domain_info = MNULL;
mlan_ds_11d_cfg *cfg_11d = MNULL;
- t_u8 region_code = 0;
+ t_u8 cfp_bg = 0, cfp_a = 0;
ENTER();
cfg_11d = (mlan_ds_11d_cfg *) pioctl_req->pbuf;
domain_info = &cfg_11d->param.domain_info;
-
- /* Update region code and table based on country code */
- if (wlan_11d_region_2_code(pmadapter, domain_info->country_code,
- &region_code) == MLAN_STATUS_SUCCESS) {
- pmadapter->region_code = region_code;
- ret = wlan_set_regiontable(pmpriv, region_code, pmadapter->fw_bands);
- if (ret != MLAN_STATUS_SUCCESS)
- goto done;
- }
-
+ memcpy(pmadapter, pmadapter->country_code, domain_info->country_code,
+ COUNTRY_CODE_LEN);
wlan_11d_set_domain_info(pmpriv, domain_info->band,
domain_info->country_code,
domain_info->no_of_sub_band,
@@ -1459,6 +1419,26 @@ wlan_11d_cfg_domain_info(IN pmlan_adapter pmadapter,
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
+ /* Update region code and table based on country code */
+ if (wlan_misc_country_2_cfp_table_code(pmadapter,
+ domain_info->country_code, &cfp_bg,
+ &cfp_a)) {
+ PRINTM(MIOCTL, "Country code %c%c not found!\n",
+ domain_info->country_code[0], domain_info->country_code[1]);
+ goto done;
+ }
+ pmadapter->cfp_code_bg = cfp_bg;
+ pmadapter->cfp_code_a = cfp_a;
+ if (cfp_bg && cfp_a && (cfp_bg == cfp_a))
+ pmadapter->region_code = cfp_a;
+ else
+ pmadapter->region_code = 0;
+ if (wlan_set_regiontable(pmpriv, pmadapter->region_code,
+ pmadapter->config_bands | pmadapter->
+ adhoc_start_band)) {
+ PRINTM(MIOCTL, "Fail to set regiontabl\n");
+ goto done;
+ }
done:
LEAVE();
return ret;
@@ -1486,21 +1466,35 @@ wlan_11d_handle_uap_domain_info(mlan_private * pmpriv,
mlan_adapter *pmadapter = pmpriv->adapter;
MrvlIEtypes_DomainParamSet_t *pdomain_tlv;
t_u8 num_sub_band = 0;
- t_u8 region_code = 0;
+ t_u8 cfp_bg = 0, cfp_a = 0;
ENTER();
pdomain_tlv = (MrvlIEtypes_DomainParamSet_t *) domain_tlv;
// update region code & table based on country string
- if (wlan_11d_region_2_code(pmadapter, pdomain_tlv->country_code,
- &region_code) == MLAN_STATUS_SUCCESS) {
- pmadapter->region_code = region_code;
- ret = wlan_set_regiontable(pmpriv, region_code, pmadapter->fw_bands);
+ if (wlan_misc_country_2_cfp_table_code(pmadapter,
+ pdomain_tlv->country_code, &cfp_bg,
+ &cfp_a) == MLAN_STATUS_SUCCESS) {
+ pmadapter->cfp_code_bg = cfp_bg;
+ pmadapter->cfp_code_a = cfp_a;
+ if (cfp_bg && cfp_a && (cfp_bg == cfp_a))
+ pmadapter->region_code = cfp_a;
+ else
+ pmadapter->region_code = 0;
+ if (wlan_set_regiontable(pmpriv, pmadapter->region_code,
+ pmadapter->config_bands | pmadapter->
+ adhoc_start_band)) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
}
- num_sub_band = ((pdomain_tlv->header.len - COUNTRY_CODE_LEN) /
- sizeof(IEEEtypes_SubbandSet_t));
+ memcpy(pmadapter, pmadapter->country_code, pdomain_tlv->country_code,
+ COUNTRY_CODE_LEN);
+ num_sub_band =
+ ((pdomain_tlv->header.len -
+ COUNTRY_CODE_LEN) / sizeof(IEEEtypes_SubbandSet_t));
// TODO: don't just clobber pmadapter->domain_reg.
// Add some checking or merging between STA & UAP domain_info
@@ -1509,6 +1503,7 @@ wlan_11d_handle_uap_domain_info(mlan_private * pmpriv,
num_sub_band, pdomain_tlv->sub_band);
ret = wlan_11d_send_domain_info(pmpriv, pioctl_buf);
+ done:
LEAVE();
return ret;
}
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11n.c b/drivers/net/wireless/sd8797/mlan/mlan_11n.c
index 9ff5da752a41..4114ff551588 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_11n.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_11n.c
@@ -61,7 +61,6 @@ wlan_11n_ioctl_max_tx_buf_size(IN pmlan_adapter pmadapter,
mlan_ds_11n_cfg *cfg = MNULL;
ENTER();
-
cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
cfg->param.tx_buf_size = (t_u32) pmadapter->max_tx_buf_size;
pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
@@ -405,6 +404,45 @@ wlan_11n_ioctl_addba_param(IN pmlan_adapter pmadapter,
return ret;
}
+/**
+ * @brief This function send delba to specific tid
+ *
+ * @param priv A pointer to mlan_priv
+ * @param tid tid
+ * @return N/A
+ */
+void
+wlan_11n_delba(mlan_private * priv, int tid)
+{
+ RxReorderTbl *rx_reor_tbl_ptr;
+
+ ENTER();
+
+ if (!
+ (rx_reor_tbl_ptr =
+ (RxReorderTbl *) util_peek_list(priv->adapter->pmoal_handle,
+ &priv->rx_reorder_tbl_ptr,
+ priv->adapter->callbacks.
+ moal_spin_lock,
+ priv->adapter->callbacks.
+ moal_spin_unlock))) {
+ LEAVE();
+ return;
+ }
+
+ while (rx_reor_tbl_ptr != (RxReorderTbl *) & priv->rx_reorder_tbl_ptr) {
+ if (rx_reor_tbl_ptr->tid == tid) {
+ PRINTM(MIOCTL, "Send delba to tid=%d, " MACSTR "\n", tid,
+ MAC2STR(rx_reor_tbl_ptr->ta));
+ wlan_send_delba(priv, MNULL, tid, rx_reor_tbl_ptr->ta, 0);
+ }
+ rx_reor_tbl_ptr = rx_reor_tbl_ptr->pnext;
+ }
+
+ LEAVE();
+ return;
+}
+
/**
* @brief Set/get addba reject set
*
@@ -432,13 +470,14 @@ wlan_11n_ioctl_addba_reject(IN pmlan_adapter pmadapter,
MAX_NUM_TID);
} else {
if (pmpriv->media_connected == MTRUE) {
- PRINTM(MERROR, "Can not set aggr priority table in connected"
- " state\n");
- pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ for (i = 0; i < MAX_NUM_TID; i++) {
+ if (cfg->param.addba_reject[i] == ADDBA_RSP_STATUS_REJECT) {
+ PRINTM(MIOCTL, "Receive addba reject: tid=%d\n", i);
+ wlan_11n_delba(pmpriv, i);
+ }
+ }
+ wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL);
}
-
for (i = 0; i < MAX_NUM_TID; i++) {
/* For AMPDU */
if (cfg->param.addba_reject[i] > ADDBA_RSP_STATUS_REJECT) {
@@ -605,10 +644,8 @@ wlan_11n_ioctl_delba(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
tid = cfg->param.del_ba.tid;
peer_address = cfg->param.del_ba.peer_mac_addr;
- PRINTM(MINFO,
- "DelBA: direction %d, TID %d, peer address %02x:%02x:%02x:%02x:%02x:%02x\n",
- cfg->param.del_ba.direction, tid, peer_address[0], peer_address[1],
- peer_address[2], peer_address[3], peer_address[4], peer_address[5]);
+ PRINTM(MINFO, "DelBA: direction %d, TID %d, peer address " MACSTR "\n",
+ cfg->param.del_ba.direction, tid, MAC2STR(peer_address));
if (cfg->param.del_ba.direction & DELBA_RX) {
rx_reor_tbl_ptr =
@@ -730,6 +767,51 @@ wlan_11n_ioctl_rejectaddbareq(IN pmlan_adapter pmadapter,
return ret;
}
+/**
+ * @brief This function will send DELBA to entries in the priv's
+ * Tx BA stream table
+ *
+ * @param priv A pointer to mlan_private
+ * @param tid TID
+ *
+ * @return N/A
+ */
+static void
+wlan_send_delba_txbastream_tbl(pmlan_private priv, t_u8 tid)
+{
+ pmlan_adapter pmadapter = priv->adapter;
+ TxBAStreamTbl *tx_ba_stream_tbl_ptr;
+
+ ENTER();
+
+ if (!
+ (tx_ba_stream_tbl_ptr =
+ (TxBAStreamTbl *) util_peek_list(pmadapter->pmoal_handle,
+ &priv->tx_ba_stream_tbl_ptr,
+ pmadapter->callbacks.moal_spin_lock,
+ pmadapter->callbacks.
+ moal_spin_unlock))) {
+ LEAVE();
+ return;
+ }
+
+ while (tx_ba_stream_tbl_ptr !=
+ (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
+ if (tx_ba_stream_tbl_ptr->ba_status == BA_STREAM_SETUP_COMPLETE) {
+ if (tid == tx_ba_stream_tbl_ptr->tid) {
+ PRINTM(MIOCTL, "Tx:Send delba to tid=%d, " MACSTR "\n", tid,
+ MAC2STR(tx_ba_stream_tbl_ptr->ra));
+ wlan_send_delba(priv, MNULL, tx_ba_stream_tbl_ptr->tid,
+ tx_ba_stream_tbl_ptr->ra, 1);
+ }
+ }
+ tx_ba_stream_tbl_ptr = tx_ba_stream_tbl_ptr->pnext;
+ }
+
+ LEAVE();
+ return;
+}
+
/**
* @brief Set/get aggr_prio_tbl
*
@@ -759,11 +841,14 @@ wlan_11n_ioctl_aggr_prio_tbl(IN pmlan_adapter pmadapter,
}
} else {
if (pmpriv->media_connected == MTRUE) {
- PRINTM(MERROR, "Can not set aggr priority table in connected"
- " state\n");
- pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ for (i = 0; i < MAX_NUM_TID; i++) {
+ if (cfg->param.aggr_prio_tbl.ampdu[i] == BA_STREAM_NOT_ALLOWED) {
+ PRINTM(MIOCTL,
+ "Receive aggrpriotbl: BA not allowed tid=%d\n", i);
+ wlan_send_delba_txbastream_tbl(pmpriv, i);
+ }
+ }
+ wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL);
}
for (i = 0; i < MAX_NUM_TID; i++) {
@@ -1233,11 +1318,8 @@ wlan_ret_11n_addba_req(mlan_private * priv, HostCmd_DS_COMMAND * resp)
padd_ba_rsp->
peer_mac_addr))) {
PRINTM(MCMND,
- "ADDBA REQ: %02x:%02x:%02x:%02x:%02x:%02x tid=%d ssn=%d win_size=%d,amsdu=%d\n",
- padd_ba_rsp->peer_mac_addr[0], padd_ba_rsp->peer_mac_addr[1],
- padd_ba_rsp->peer_mac_addr[2], padd_ba_rsp->peer_mac_addr[3],
- padd_ba_rsp->peer_mac_addr[4], padd_ba_rsp->peer_mac_addr[5],
- tid, padd_ba_rsp->ssn,
+ "ADDBA REQ: " MACSTR " tid=%d ssn=%d win_size=%d,amsdu=%d\n",
+ MAC2STR(padd_ba_rsp->peer_mac_addr), tid, padd_ba_rsp->ssn,
((padd_ba_rsp->
block_ack_param_set & BLOCKACKPARAM_WINSIZE_MASK) >>
BLOCKACKPARAM_WINSIZE_POS),
@@ -1797,6 +1879,10 @@ wlan_cmd_append_11n_tlv(IN mlan_private * pmpriv,
memcpy(pmadapter, (t_u8 *) pext_cap + sizeof(MrvlIEtypesHeader_t),
(t_u8 *) pbss_desc->pext_cap + sizeof(IEEEtypes_Header_t),
pbss_desc->pext_cap->ieee_hdr.len);
+ if (!ISSUPP_EXTCAP_TDLS(pmpriv->ext_cap))
+ RESET_EXTCAP_TDLS(pext_cap->ext_cap);
+ if (!ISSUPP_EXTCAP_INTERWORKING(pmpriv->ext_cap))
+ RESET_EXTCAP_INTERWORKING(pext_cap->ext_cap);
HEXDUMP("Extended Capabilities IE", (t_u8 *) pext_cap,
sizeof(MrvlIETypes_ExtCap_t));
*ppbuffer += sizeof(MrvlIETypes_ExtCap_t);
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c b/drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c
index 991670c4fcaa..7acaaa4b4aee 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c
@@ -182,11 +182,17 @@ static int
wlan_11n_get_num_aggrpkts(t_u8 * data, int total_pkt_len)
{
int pkt_count = 0, pkt_len, pad;
+ t_u8 hdr_len = sizeof(Eth803Hdr_t);
ENTER();
- while (total_pkt_len > 0) {
+ while (total_pkt_len >= hdr_len) {
/* Length will be in network format, change it to host */
pkt_len = mlan_ntohs((*(t_u16 *) (data + (2 * MLAN_MAC_ADDR_LENGTH))));
+ if (pkt_len > total_pkt_len) {
+ PRINTM(MERROR, "Error in packet length.\n");
+ break;
+ }
+
pad = (((pkt_len + sizeof(Eth803Hdr_t)) & 3)) ?
(4 - ((pkt_len + sizeof(Eth803Hdr_t)) & 3)) : 0;
data += pkt_len + pad + sizeof(Eth803Hdr_t);
@@ -224,6 +230,7 @@ wlan_11n_deaggregate_pkt(mlan_private * priv, pmlan_buffer pmbuf)
t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = { 0xaa, 0xaa, 0x03,
0x00, 0x00, 0x00
};
+ t_u8 hdr_len = sizeof(Eth803Hdr_t);
ENTER();
@@ -239,7 +246,7 @@ wlan_11n_deaggregate_pkt(mlan_private * priv, pmlan_buffer pmbuf)
pmbuf->use_count = wlan_11n_get_num_aggrpkts(data, total_pkt_len);
- while (total_pkt_len > 0) {
+ while (total_pkt_len >= hdr_len) {
prx_pkt = (RxPacketHdr_t *) data;
/* Length will be in network format, change it to host */
pkt_len = mlan_ntohs((*(t_u16 *) (data + (2 * MLAN_MAC_ADDR_LENGTH))));
@@ -285,14 +292,16 @@ wlan_11n_deaggregate_pkt(mlan_private * priv, pmlan_buffer pmbuf)
pkt_len);
#ifdef UAP_SUPPORT
- if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)
+ if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
ret = wlan_uap_recv_packet(priv, daggr_mbuf);
- else
+ } else {
#endif /* UAP_SUPPORT */
ret =
pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
daggr_mbuf);
-
+#ifdef UAP_SUPPORT
+ }
+#endif /* UAP_SUPPORT */
switch (ret) {
case MLAN_STATUS_PENDING:
break;
@@ -337,7 +346,7 @@ wlan_11n_aggregate_pkt(mlan_private * priv, raListTbl * pra_list,
int pad = 0;
mlan_status ret = MLAN_STATUS_SUCCESS;
#ifdef DEBUG_LEVEL1
- t_u32 sec, usec;
+ t_u32 sec = 0, usec = 0;
#endif
mlan_tx_param tx_param;
#ifdef STA_SUPPORT
@@ -368,6 +377,8 @@ wlan_11n_aggregate_pkt(mlan_private * priv, raListTbl * pra_list,
pmbuf_aggr->priority = pmbuf_src->priority;
pmbuf_aggr->pbuf = data;
pmbuf_aggr->data_offset = 0;
+ pmbuf_aggr->in_ts_sec = pmbuf_src->in_ts_sec;
+ pmbuf_aggr->in_ts_usec = pmbuf_src->in_ts_usec;
/* Form AMSDU */
wlan_11n_form_amsdu_txpd(priv, pmbuf_aggr);
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c b/drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c
index 1dd3f94431f9..0db9b99a4d12 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c
@@ -426,10 +426,9 @@ wlan_11n_create_rxreorder_tbl(mlan_private * priv, t_u8 * ta, int tid,
if ((rx_reor_tbl_ptr = wlan_11n_get_rxreorder_tbl(priv, tid, ta))) {
wlan_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, seq_num);
} else {
- PRINTM(MDAT_D, "%s: seq_num %d, tid %d, ta %02x:%02x:%02x:%02x:"
- "%02x:%02x, win_size %d\n", __FUNCTION__,
- seq_num, tid, ta[0], ta[1], ta[2], ta[3],
- ta[4], ta[5], win_size);
+ PRINTM(MDAT_D, "%s: seq_num %d, tid %d, ta " MACSTR
+ ", win_size %d\n", __FUNCTION__,
+ seq_num, tid, MAC2STR(ta), win_size);
if (pmadapter->callbacks.
moal_malloc(pmadapter->pmoal_handle, sizeof(RxReorderTbl),
MLAN_MEM_DEF, (t_u8 **) & new_node)) {
@@ -453,13 +452,10 @@ wlan_11n_create_rxreorder_tbl(mlan_private * priv, t_u8 * ta, int tid,
} else {
last_seq = priv->rx_seq[tid];
}
- if ((last_seq != DEFAULT_SEQ_NUM) && (last_seq >= new_node->start_win)) {
- PRINTM(MDAT_D, "Update start_win: last_seq=%d, start_win=%d\n",
- last_seq, new_node->start_win);
- new_node->start_win = last_seq + 1;
- }
+ new_node->last_seq = last_seq;
new_node->win_size = win_size;
new_node->force_no_drop = MFALSE;
+ new_node->check_start_win = MTRUE;
if (pmadapter->callbacks.
moal_malloc(pmadapter->pmoal_handle, sizeof(t_void *) * win_size,
@@ -471,7 +467,8 @@ wlan_11n_create_rxreorder_tbl(mlan_private * priv, t_u8 * ta, int tid,
return;
}
- PRINTM(MDAT_D, "Create ReorderPtr: %p\n", new_node);
+ PRINTM(MDAT_D, "Create ReorderPtr: %p start_win=%d last_seq=%d\n",
+ new_node, new_node->start_win, last_seq);
new_node->timer_context.ptr = new_node;
new_node->timer_context.priv = priv;
new_node->timer_context.timer_is_set = MFALSE;
@@ -731,13 +728,41 @@ mlan_11n_rxreorder_pkt(void *priv, t_u16 seq_num, t_u16 tid,
if (pkt_type == PKT_TYPE_AMSDU)
PRINTM(MDAT_D, "AMSDU ");
+ if (rx_reor_tbl_ptr->check_start_win) {
+ rx_reor_tbl_ptr->check_start_win = MFALSE;
+ if ((seq_num != rx_reor_tbl_ptr->start_win) &&
+ (rx_reor_tbl_ptr->last_seq != DEFAULT_SEQ_NUM)) {
+ end_win =
+ (rx_reor_tbl_ptr->start_win + rx_reor_tbl_ptr->win_size -
+ 1) & (MAX_TID_VALUE - 1);
+ if (((end_win > rx_reor_tbl_ptr->start_win)
+ && (rx_reor_tbl_ptr->last_seq >=
+ rx_reor_tbl_ptr->start_win)
+ && (rx_reor_tbl_ptr->last_seq < end_win)) ||
+ ((end_win < rx_reor_tbl_ptr->start_win) &&
+ ((rx_reor_tbl_ptr->last_seq >= rx_reor_tbl_ptr->start_win)
+ || (rx_reor_tbl_ptr->last_seq < end_win)))) {
+ PRINTM(MDAT_D,
+ "Update start_win: last_seq=%d, start_win=%d seq_num=%d\n",
+ rx_reor_tbl_ptr->last_seq,
+ rx_reor_tbl_ptr->start_win, seq_num);
+ rx_reor_tbl_ptr->start_win = rx_reor_tbl_ptr->last_seq + 1;
+ } else if ((seq_num < rx_reor_tbl_ptr->start_win) &&
+ (seq_num > rx_reor_tbl_ptr->last_seq)) {
+ PRINTM(MDAT_D,
+ "Update start_win: last_seq=%d, start_win=%d seq_num=%d\n",
+ rx_reor_tbl_ptr->last_seq,
+ rx_reor_tbl_ptr->start_win, seq_num);
+ rx_reor_tbl_ptr->start_win = rx_reor_tbl_ptr->last_seq + 1;
+ }
+ }
+ }
+
prev_start_win = start_win = rx_reor_tbl_ptr->start_win;
win_size = rx_reor_tbl_ptr->win_size;
end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
- PRINTM(MDAT_D,
- "TID %d, TA %02x:%02x:%02x:%02x:%02x:%02x\n",
- tid, ta[0], ta[1], ta[2], ta[3], ta[4], ta[5]);
+ PRINTM(MDAT_D, "TID %d, TA " MACSTR "\n", tid, MAC2STR(ta));
PRINTM(MDAT_D,
"1:seq_num %d start_win %d win_size %d end_win %d\n",
seq_num, start_win, win_size, end_win);
@@ -864,10 +889,8 @@ mlan_11n_delete_bastream_tbl(mlan_private * priv, int tid,
else
cleanup_rx_reorder_tbl = (initiator) ? MFALSE : MTRUE;
- PRINTM(MEVENT, "DELBA: %02x:%02x:%02x:%02x:%02x:%02x tid=%d,"
- "initiator=%d\n", peer_mac[0],
- peer_mac[1], peer_mac[2],
- peer_mac[3], peer_mac[4], peer_mac[5], tid, initiator);
+ PRINTM(MEVENT, "DELBA: " MACSTR " tid=%d,"
+ "initiator=%d\n", MAC2STR(peer_mac), tid, initiator);
if (cleanup_rx_reorder_tbl) {
if (!(rx_reor_tbl_ptr = wlan_11n_get_rxreorder_tbl(priv, tid,
@@ -920,11 +943,8 @@ wlan_ret_11n_addba_resp(mlan_private * priv, HostCmd_DS_COMMAND * resp)
/* Check if we had rejected the ADDBA, if yes then do not create the stream */
if (padd_ba_rsp->status_code == BA_RESULT_SUCCESS) {
PRINTM(MCMND,
- "ADDBA RSP: %02x:%02x:%02x:%02x:%02x:%02x tid=%d ssn=%d win_size=%d,amsdu=%d\n",
- padd_ba_rsp->peer_mac_addr[0], padd_ba_rsp->peer_mac_addr[1],
- padd_ba_rsp->peer_mac_addr[2], padd_ba_rsp->peer_mac_addr[3],
- padd_ba_rsp->peer_mac_addr[4], padd_ba_rsp->peer_mac_addr[5],
- tid, padd_ba_rsp->ssn,
+ "ADDBA RSP: " MACSTR " tid=%d ssn=%d win_size=%d,amsdu=%d\n",
+ MAC2STR(padd_ba_rsp->peer_mac_addr), tid, padd_ba_rsp->ssn,
((padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_WINSIZE_MASK)
>> BLOCKACKPARAM_WINSIZE_POS),
padd_ba_rsp->
@@ -943,15 +963,11 @@ wlan_ret_11n_addba_resp(mlan_private * priv, HostCmd_DS_COMMAND * resp)
rx_reor_tbl_ptr->amsdu = MFALSE;
}
} else {
- PRINTM(MERROR,
- "ADDBA RSP: Failed(%02x:%02x:%02x:%02x:%02x:%02x tid=%d)\n",
- padd_ba_rsp->peer_mac_addr[0], padd_ba_rsp->peer_mac_addr[1],
- padd_ba_rsp->peer_mac_addr[2], padd_ba_rsp->peer_mac_addr[3],
- padd_ba_rsp->peer_mac_addr[4], padd_ba_rsp->peer_mac_addr[5],
- tid);
- if ((rx_reor_tbl_ptr =
- wlan_11n_get_rxreorder_tbl(priv, tid,
- padd_ba_rsp->peer_mac_addr))) {
+ PRINTM(MERROR, "ADDBA RSP: Failed(" MACSTR " tid=%d)\n",
+ MAC2STR(padd_ba_rsp->peer_mac_addr), tid);
+ if ((rx_reor_tbl_ptr = wlan_11n_get_rxreorder_tbl(priv, tid,
+ padd_ba_rsp->
+ peer_mac_addr))) {
wlan_11n_delete_rxreorder_tbl_entry(priv, rx_reor_tbl_ptr);
}
}
@@ -1047,11 +1063,9 @@ wlan_11n_rxba_sync_event(mlan_private * priv, t_u8 * event_buf, t_u16 len)
}
tlv_rxba->seq_num = wlan_le16_to_cpu(tlv_rxba->seq_num);
tlv_rxba->bitmap_len = wlan_le16_to_cpu(tlv_rxba->bitmap_len);
- PRINTM(MEVENT,
- "%02x:%02x:%02x:%02x:%02x:%02x tid=%d seq_num=%d bitmap_len=%d\n",
- tlv_rxba->mac[0], tlv_rxba->mac[1], tlv_rxba->mac[2],
- tlv_rxba->mac[3], tlv_rxba->mac[4], tlv_rxba->mac[5],
- tlv_rxba->tid, tlv_rxba->seq_num, tlv_rxba->bitmap_len);
+ PRINTM(MEVENT, MACSTR " tid=%d seq_num=%d bitmap_len=%d\n",
+ MAC2STR(tlv_rxba->mac), tlv_rxba->tid, tlv_rxba->seq_num,
+ tlv_rxba->bitmap_len);
rx_reor_tbl_ptr =
wlan_11n_get_rxreorder_tbl(priv, tlv_rxba->tid, tlv_rxba->mac);
if (!rx_reor_tbl_ptr) {
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_cfp.c b/drivers/net/wireless/sd8797/mlan/mlan_cfp.c
index fbc2a7c4d208..e9369ecfed24 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_cfp.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_cfp.c
@@ -944,17 +944,17 @@ wlan_misc_country_2_cfp_table_code(pmlan_adapter pmadapter, t_u8 * country_code,
/**
* @brief Use index to get the data rate
*
- * @param pmadapter A pointer to mlan_adapter structure
- * @param index The index of data rate
- * @param ht_info ht info
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param index The index of data rate
+ * @param ht_info HT info
*
- * @return Data rate or 0
+ * @return Data rate or 0
*/
-
t_u32
wlan_index_to_data_rate(pmlan_adapter pmadapter, t_u8 index, t_u8 ht_info)
{
#define MCS_NUM_SUPP 16
+ t_u16 mcs_num_supp = MCS_NUM_SUPP;
t_u16 mcs_rate[4][MCS_NUM_SUPP] =
{ {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e, 0x36, 0x6c, 0xa2,
0xd8, 0x144, 0x1b0, 0x1e6, 0x21c}
@@ -968,17 +968,19 @@ wlan_index_to_data_rate(pmlan_adapter pmadapter, t_u8 index, t_u8 ht_info)
{0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90, 0x1c, 0x39, 0x56, 0x73,
0xad, 0xe7, 0x104, 0x120}
}; /* SG 20M */
-
t_u32 rate = 0;
+
ENTER();
+ if (pmadapter->usr_dev_mcs_support == HT_STREAM_MODE_1X1)
+ mcs_num_supp = 8;
if (ht_info & MBIT(0)) {
if (index == MLAN_RATE_BITMAP_MCS0) {
if (ht_info & MBIT(2))
rate = 0x0D; /* MCS 32 SGI rate */
else
rate = 0x0C; /* MCS 32 LGI rate */
- } else if (index < MCS_NUM_SUPP) {
+ } else if (index < mcs_num_supp) {
if (ht_info & MBIT(1)) {
if (ht_info & MBIT(2))
rate = mcs_rate[1][index]; /* SGI, 40M */
@@ -1184,7 +1186,7 @@ wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter,
}
if (!cfp && channel)
- PRINTM(MERROR, "wlan_get_cfp_by_band_and_channel(): cannot find "
+ PRINTM(MCMND, "wlan_get_cfp_by_band_and_channel(): cannot find "
"cfp by band %d & channel %d\n", band, channel);
LEAVE();
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c b/drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c
index 2b0c77632757..11c158cd997f 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c
@@ -45,6 +45,229 @@ Change Log:
/********************************************************
Local Functions
********************************************************/
+#ifdef STA_SUPPORT
+/**
+ * @brief Internal function used to flush the scan pending queue
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ *
+ * @return N/A
+ */
+void
+wlan_check_scan_queue(IN pmlan_adapter pmadapter)
+{
+ cmd_ctrl_node *pcmd_node = MNULL;
+ t_u16 num = 0;
+
+ if (!
+ (pcmd_node =
+ (cmd_ctrl_node *) util_peek_list(pmadapter->pmoal_handle,
+ &pmadapter->scan_pending_q,
+ pmadapter->callbacks.moal_spin_lock,
+ pmadapter->callbacks.
+ moal_spin_unlock))) {
+ PRINTM(MERROR, "No pending scan command\n");
+ return;
+ }
+ while (pcmd_node != (cmd_ctrl_node *) & pmadapter->scan_pending_q) {
+ num++;
+ pcmd_node = pcmd_node->pnext;
+ }
+ PRINTM(MERROR, "num_pending_scan=%d\n", num);
+}
+#endif
+
+/**
+ * @brief This function will dump the pending commands id
+ *
+ * @param pmadapter A pointer to mlan_adapter
+ *
+ * @return N/A
+ */
+static void
+wlan_dump_pending_commands(pmlan_adapter pmadapter)
+{
+ cmd_ctrl_node *pcmd_node = MNULL;
+ HostCmd_DS_COMMAND *pcmd;
+
+ ENTER();
+
+ if (!
+ (pcmd_node =
+ (cmd_ctrl_node *) util_peek_list(pmadapter->pmoal_handle,
+ &pmadapter->cmd_pending_q,
+ pmadapter->callbacks.moal_spin_lock,
+ pmadapter->callbacks.
+ moal_spin_unlock))) {
+ LEAVE();
+ return;
+ }
+ while (pcmd_node != (cmd_ctrl_node *) & pmadapter->cmd_pending_q) {
+ pcmd =
+ (HostCmd_DS_COMMAND *) (pcmd_node->cmdbuf->pbuf +
+ pcmd_node->cmdbuf->data_offset);
+ PRINTM(MERROR, "pending command id: 0x%x\n",
+ wlan_le16_to_cpu(pcmd->command));
+ pcmd_node = pcmd_node->pnext;
+ }
+#ifdef STA_SUPPORT
+ wlan_check_scan_queue(pmadapter);
+#endif
+ LEAVE();
+ return;
+}
+
+#define REASON_CODE_NO_CMD_NODE 1
+#define REASON_CODE_CMD_TIMEOUT 2
+
+/**
+ * @brief This function dump debug info
+ *
+ * @return N/A
+ */
+t_void
+wlan_dump_info(mlan_adapter * pmadapter, t_u8 reason)
+{
+ cmd_ctrl_node *pcmd_node = MNULL;
+#ifdef DEBUG_LEVEL1
+ t_u32 sec = 0, usec = 0;
+#endif
+ t_u8 i;
+ t_u16 cmd_id, cmd_act;
+ mlan_private *pmpriv = MNULL;
+
+ ENTER();
+
+ PRINTM(MERROR, "------------Dump info-----------\n", reason);
+ switch (reason) {
+ case REASON_CODE_NO_CMD_NODE:
+ pmadapter->dbg.num_no_cmd_node++;
+ PRINTM(MERROR, "No Free command node\n");
+ wlan_dump_pending_commands(pmadapter);
+ break;
+ case REASON_CODE_CMD_TIMEOUT:
+ PRINTM(MERROR, "Commmand Timeout\n");
+ break;
+ default:
+ break;
+ }
+ if (reason != REASON_CODE_CMD_TIMEOUT) {
+ if (!pmadapter->curr_cmd) {
+ PRINTM(MERROR, "CurCmd Empty\n");
+ } else {
+ pcmd_node = pmadapter->curr_cmd;
+ cmd_id = pmadapter->dbg.last_cmd_id[pmadapter->dbg.last_cmd_index];
+ cmd_act =
+ pmadapter->dbg.last_cmd_act[pmadapter->dbg.last_cmd_index];
+ PRINTM_GET_SYS_TIME(MERROR, &sec, &usec);
+ PRINTM(MERROR, "Current cmd id (%lu.%06lu) = 0x%x, act = 0x%x \n",
+ sec, usec, cmd_id, cmd_act);
+ if (pcmd_node->cmdbuf) {
+ t_u8 *pcmd_buf;
+ pcmd_buf =
+ pcmd_node->cmdbuf->pbuf + pcmd_node->cmdbuf->data_offset +
+ INTF_HEADER_LEN;
+ for (i = 0; i < 16; i++) {
+ PRINTM(MERROR, "%02x ", *pcmd_buf++);
+ }
+ PRINTM(MERROR, "\n");
+ }
+ pmpriv = pcmd_node->priv;
+ if (pmpriv) {
+ PRINTM(MERROR, "BSS type = %d BSS role= %d\n", pmpriv->bss_type,
+ pmpriv->bss_role);
+ }
+ }
+ }
+ PRINTM(MERROR, "mlan_processing =%d\n", pmadapter->mlan_processing);
+ PRINTM(MERROR, "more_task_flag = %d\n", pmadapter->more_task_flag);
+ PRINTM(MERROR, "num_cmd_timeout = %d\n", pmadapter->dbg.num_cmd_timeout);
+ PRINTM(MERROR, "last_cmd_index = %d\n", pmadapter->dbg.last_cmd_index);
+ PRINTM(MERROR, "last_cmd_id = ");
+ for (i = 0; i < DBG_CMD_NUM; i++) {
+ PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_id[i]);
+ }
+ PRINTM(MERROR, "\n");
+ PRINTM(MERROR, "last_cmd_act = ");
+ for (i = 0; i < DBG_CMD_NUM; i++) {
+ PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_act[i]);
+ }
+ PRINTM(MERROR, "\n");
+ PRINTM(MERROR, "last_cmd_resp_index = %d\n",
+ pmadapter->dbg.last_cmd_resp_index);
+ PRINTM(MERROR, "last_cmd_resp_id = ");
+ for (i = 0; i < DBG_CMD_NUM; i++) {
+ PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_resp_id[i]);
+ }
+ PRINTM(MERROR, "\n");
+ PRINTM(MERROR, "last_event_index = %d\n", pmadapter->dbg.last_event_index);
+ PRINTM(MERROR, "last_event = ");
+ for (i = 0; i < DBG_CMD_NUM; i++) {
+ PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_event[i]);
+ }
+ PRINTM(MERROR, "\n");
+
+ PRINTM(MERROR, "num_data_h2c_failure = %d\n",
+ pmadapter->dbg.num_tx_host_to_card_failure);
+ PRINTM(MERROR, "num_cmd_h2c_failure = %d\n",
+ pmadapter->dbg.num_cmd_host_to_card_failure);
+ PRINTM(MERROR, "num_data_c2h_failure = %d\n",
+ pmadapter->dbg.num_rx_card_to_host_failure);
+ PRINTM(MERROR, "num_cmdevt_c2h_failure = %d\n",
+ pmadapter->dbg.num_cmdevt_card_to_host_failure);
+ PRINTM(MERROR, "num_int_read_failure = %d\n",
+ pmadapter->dbg.num_int_read_failure);
+ PRINTM(MERROR, "last_int_status = %d\n", pmadapter->dbg.last_int_status);
+ PRINTM(MERROR, "num_no_cmd_node = %d\n", pmadapter->dbg.num_no_cmd_node);
+ PRINTM(MERROR, "num_event_deauth = %d\n", pmadapter->dbg.num_event_deauth);
+ PRINTM(MERROR, "num_event_disassoc = %d\n",
+ pmadapter->dbg.num_event_disassoc);
+ PRINTM(MERROR, "num_event_link_lost = %d\n",
+ pmadapter->dbg.num_event_link_lost);
+ PRINTM(MERROR, "num_cmd_deauth = %d\n", pmadapter->dbg.num_cmd_deauth);
+ PRINTM(MERROR, "num_cmd_assoc_success = %d\n",
+ pmadapter->dbg.num_cmd_assoc_success);
+ PRINTM(MERROR, "num_cmd_assoc_failure = %d\n",
+ pmadapter->dbg.num_cmd_assoc_failure);
+ PRINTM(MERROR, "cmd_resp_received=%d\n", pmadapter->cmd_resp_received);
+ PRINTM(MERROR, "event_received=%d\n", pmadapter->event_received);
+
+ PRINTM(MERROR, "max_tx_buf_size=%d\n", pmadapter->max_tx_buf_size);
+ PRINTM(MERROR, "tx_buf_size=%d\n", pmadapter->tx_buf_size);
+ PRINTM(MERROR, "curr_tx_buf_size=%d\n", pmadapter->curr_tx_buf_size);
+
+ PRINTM(MERROR, "data_sent=%d cmd_sent=%d\n", pmadapter->data_sent,
+ pmadapter->cmd_sent);
+
+ PRINTM(MERROR, "ps_mode=%d ps_state=%d\n", pmadapter->ps_mode,
+ pmadapter->ps_state);
+ PRINTM(MERROR, "wakeup_dev_req=%d wakeup_tries=%d\n",
+ pmadapter->pm_wakeup_card_req, pmadapter->pm_wakeup_fw_try);
+ PRINTM(MERROR, "hs_configured=%d hs_activated=%d\n",
+ pmadapter->is_hs_configured, pmadapter->hs_activated);
+ PRINTM(MERROR, "pps_uapsd_mode=%d sleep_pd=%d\n", pmadapter->pps_uapsd_mode,
+ pmadapter->sleep_period.period);
+ PRINTM(MERROR, "tx_lock_flag = %d\n", pmadapter->tx_lock_flag);
+ PRINTM(MERROR, "scan_processing = %d\n", pmadapter->scan_processing);
+ PRINTM(MERROR, "mp_rd_bitmap=0x%x curr_rd_port=0x%x\n",
+ pmadapter->mp_rd_bitmap, pmadapter->curr_rd_port);
+ PRINTM(MERROR, "mp_wr_bitmap=0x%x curr_wr_port=0x%x\n",
+ pmadapter->mp_wr_bitmap, pmadapter->curr_wr_port);
+ if (reason != REASON_CODE_CMD_TIMEOUT) {
+ if ((pmadapter->dbg.num_no_cmd_node >= 5)
+ || (pmadapter->pm_wakeup_card_req && pmadapter->pm_wakeup_fw_try)
+ ) {
+ if (pmpriv)
+ wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
+ else
+ wlan_recv_event(wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY),
+ MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
+ }
+ }
+ PRINTM(MERROR, "-------- Dump info End---------\n", reason);
+ LEAVE();
+ return;
+}
/**
* @brief This function convert a given character to hex
@@ -107,8 +330,9 @@ wlan_parse_cal_cfg(t_u8 * src, t_size len, t_u8 * dst)
dptr = dst;
while (ptr - src < len) {
- while (*ptr && (wlan_isspace(*ptr) || *ptr == '\t')) {
+ if (*ptr && (wlan_isspace(*ptr) || *ptr == '\t')) {
ptr++;
+ continue;
}
if (wlan_isxdigit(*ptr)) {
@@ -234,6 +458,49 @@ wlan_clean_cmd_node(pmlan_adapter pmadapter, cmd_ctrl_node * pcmd_node)
return;
}
+#ifdef STA_SUPPORT
+/**
+ * @brief This function will return the pointer to the first entry in
+ * pending cmd which matches the given req_id
+ *
+ * @param pmadapter A pointer to mlan_adapter
+ * @param req_id ioctl req_id.
+ *
+ * @return A pointer to first entry match pioctl_req
+ */
+static cmd_ctrl_node *
+wlan_get_pending_ioctl_by_id(pmlan_adapter pmadapter, t_u32 req_id)
+{
+ cmd_ctrl_node *pcmd_node = MNULL;
+ mlan_ioctl_req *pioctl_buf = MNULL;
+
+ ENTER();
+
+ if (!
+ (pcmd_node =
+ (cmd_ctrl_node *) util_peek_list(pmadapter->pmoal_handle,
+ &pmadapter->cmd_pending_q,
+ pmadapter->callbacks.moal_spin_lock,
+ pmadapter->callbacks.
+ moal_spin_unlock))) {
+ LEAVE();
+ return MNULL;
+ }
+ while (pcmd_node != (cmd_ctrl_node *) & pmadapter->cmd_pending_q) {
+ if (pcmd_node->pioctl_buf) {
+ pioctl_buf = (mlan_ioctl_req *) pcmd_node->pioctl_buf;
+ if (pioctl_buf->req_id == req_id) {
+ LEAVE();
+ return pcmd_node;
+ }
+ }
+ pcmd_node = pcmd_node->pnext;
+ }
+ LEAVE();
+ return MNULL;
+}
+#endif
+
/**
* @brief This function will return the pointer to the first entry in
* pending cmd which matches the given pioctl_req
@@ -261,7 +528,7 @@ wlan_get_pending_ioctl_cmd(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
return MNULL;
}
while (pcmd_node != (cmd_ctrl_node *) & pmadapter->cmd_pending_q) {
- if (pcmd_node->pioctl_buf == pioctl_req) {
+ if (pcmd_node->pioctl_buf && (pcmd_node->pioctl_buf == pioctl_req)) {
LEAVE();
return pcmd_node;
}
@@ -271,6 +538,46 @@ wlan_get_pending_ioctl_cmd(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
return MNULL;
}
+/**
+ * @brief This function will return the pointer to the first entry in
+ * pending cmd which matches the given bss_index
+ *
+ * @param pmadapter A pointer to mlan_adapter
+ * @param bss_index bss_index
+ *
+ * @return A pointer to first entry match pioctl_req
+ */
+static cmd_ctrl_node *
+wlan_get_bss_pending_ioctl_cmd(pmlan_adapter pmadapter, t_u32 bss_index)
+{
+ cmd_ctrl_node *pcmd_node = MNULL;
+ mlan_ioctl_req *pioctl_buf = MNULL;
+ ENTER();
+
+ if (!
+ (pcmd_node =
+ (cmd_ctrl_node *) util_peek_list(pmadapter->pmoal_handle,
+ &pmadapter->cmd_pending_q,
+ pmadapter->callbacks.moal_spin_lock,
+ pmadapter->callbacks.
+ moal_spin_unlock))) {
+ LEAVE();
+ return MNULL;
+ }
+ while (pcmd_node != (cmd_ctrl_node *) & pmadapter->cmd_pending_q) {
+ if (pcmd_node->pioctl_buf) {
+ pioctl_buf = (mlan_ioctl_req *) pcmd_node->pioctl_buf;
+ if (pioctl_buf->bss_index == bss_index) {
+ LEAVE();
+ return pcmd_node;
+ }
+ }
+ pcmd_node = pcmd_node->pnext;
+ }
+ LEAVE();
+ return MNULL;
+}
+
/**
* @brief This function handles the command response of host_cmd
*
@@ -345,7 +652,7 @@ wlan_dnld_cmd_to_fw(IN mlan_private * pmpriv, IN cmd_ctrl_node * pcmd_node)
t_u16 cmd_code;
t_u16 cmd_size;
#ifdef DEBUG_LEVEL1
- t_u32 sec, usec;
+ t_u32 sec = 0, usec = 0;
#endif
ENTER();
@@ -447,7 +754,7 @@ wlan_dnld_cmd_to_fw(IN mlan_private * pmpriv, IN cmd_ctrl_node * pcmd_node)
/* Setup the timer after transmit command */
pcb->moal_start_timer(pmadapter->pmoal_handle, pmadapter->pmlan_cmd_timer,
- MFALSE, MRVDRV_TIMER_60S);
+ MFALSE, MRVDRV_TIMER_10S);
pmadapter->cmd_timer_is_set = MTRUE;
@@ -694,7 +1001,7 @@ wlan_process_event(pmlan_adapter pmadapter)
pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event;
t_u32 eventcause = pmadapter->event_cause;
#ifdef DEBUG_LEVEL1
- t_u32 in_ts_sec, in_ts_usec;
+ t_u32 in_ts_sec = 0, in_ts_usec = 0;
#endif
ENTER();
@@ -842,6 +1149,7 @@ wlan_prepare_cmd(IN mlan_private * pmpriv,
if (pcmd_node == MNULL) {
PRINTM(MERROR, "PREP_CMD: No free cmd node\n");
+ wlan_dump_info(pmadapter, REASON_CODE_NO_CMD_NODE);
if (pioctl_req)
pioctl_req->status_code = MLAN_ERROR_NO_MEM;
ret = MLAN_STATUS_FAILURE;
@@ -973,10 +1281,6 @@ wlan_insert_cmd_to_pending_q(IN mlan_adapter * pmadapter,
pcmd =
(HostCmd_DS_COMMAND *) (pcmd_node->cmdbuf->pbuf +
pcmd_node->cmdbuf->data_offset);
- if (pcmd == MNULL) {
- PRINTM(MERROR, "QUEUE_CMD: pcmd is MNULL\n");
- goto done;
- }
command = wlan_le16_to_cpu(pcmd->command);
@@ -1113,7 +1417,7 @@ wlan_process_cmdresp(mlan_adapter * pmadapter)
mlan_ioctl_req *pioctl_buf = MNULL;
mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
#ifdef DEBUG_LEVEL1
- t_u32 sec, usec;
+ t_u32 sec = 0, usec = 0;
#endif
t_u32 i;
@@ -1158,7 +1462,7 @@ wlan_process_cmdresp(mlan_adapter * pmadapter)
cmd_ctrl_node *free_cmd = pmadapter->curr_cmd;
pmadapter->curr_cmd = MNULL;
wlan_release_cmd_lock(pmadapter);
- PRINTM(MERROR, "CMD_RESP: 0x%x been canceled!\n",
+ PRINTM(MCMND, "CMD_RESP: 0x%x been canceled!\n",
wlan_le16_to_cpu(resp->command));
wlan_insert_cmd_to_free_q(pmadapter, free_cmd);
if (pioctl_buf)
@@ -1255,7 +1559,8 @@ wlan_process_cmdresp(mlan_adapter * pmadapter)
if (pioctl_buf && (ret == MLAN_STATUS_SUCCESS))
pioctl_buf->status_code = MLAN_ERROR_NO_ERROR;
- else if (pioctl_buf && (ret == MLAN_STATUS_FAILURE))
+ else if (pioctl_buf && (ret == MLAN_STATUS_FAILURE) &&
+ !pioctl_buf->status_code)
pioctl_buf->status_code = MLAN_ERROR_CMD_RESP_FAIL;
/* Clean up and put current command back to cmd_free_q */
@@ -1267,8 +1572,15 @@ wlan_process_cmdresp(mlan_adapter * pmadapter)
if ((pmadapter->hw_status == WlanHardwareStatusInitializing) &&
(pmadapter->last_init_cmd == cmdresp_no)) {
i = pmpriv->bss_index + 1;
- while (!(pmpriv_next = pmadapter->priv[i]) && i < pmadapter->priv_num)
+ while (i < pmadapter->priv_num && !(pmpriv_next = pmadapter->priv[i]))
i++;
+ if (pmpriv_next && pmpriv_next->bss_virtual) {
+ i = pmpriv_next->bss_index + 1;
+ /** skip virtual interface */
+ while (i < pmadapter->priv_num &&
+ !(pmpriv_next = pmadapter->priv[i]))
+ i++;
+ }
if (!pmpriv_next || i >= pmadapter->priv_num) {
#if defined(STA_SUPPORT)
if (pmadapter->pwarm_reset_ioctl_req) {
@@ -1307,7 +1619,7 @@ wlan_cmd_timeout_func(t_void * function_context)
cmd_ctrl_node *pcmd_node = MNULL;
mlan_ioctl_req *pioctl_buf = MNULL;
#ifdef DEBUG_LEVEL1
- t_u32 sec, usec;
+ t_u32 sec = 0, usec = 0;
#endif
t_u8 i;
mlan_private *pmpriv = MNULL;
@@ -1327,119 +1639,41 @@ wlan_cmd_timeout_func(t_void * function_context)
pioctl_buf->status_code = MLAN_ERROR_CMD_TIMEOUT;
}
- if (pcmd_node) {
- pmadapter->dbg.timeout_cmd_id =
- pmadapter->dbg.last_cmd_id[pmadapter->dbg.last_cmd_index];
- pmadapter->dbg.timeout_cmd_act =
- pmadapter->dbg.last_cmd_act[pmadapter->dbg.last_cmd_index];
- PRINTM_GET_SYS_TIME(MERROR, &sec, &usec);
- PRINTM(MERROR, "Timeout cmd id (%lu.%06lu) = 0x%x, act = 0x%x \n", sec,
- usec, pmadapter->dbg.timeout_cmd_id,
- pmadapter->dbg.timeout_cmd_act);
- if (pcmd_node->cmdbuf) {
- t_u8 *pcmd_buf;
- pcmd_buf =
- pcmd_node->cmdbuf->pbuf + pcmd_node->cmdbuf->data_offset +
- INTF_HEADER_LEN;
- for (i = 0; i < 16; i++) {
- PRINTM(MERROR, "%02x ", *pcmd_buf++);
- }
- PRINTM(MERROR, "\n");
- }
-
- pmpriv = pcmd_node->priv;
- if (pmpriv) {
- PRINTM(MERROR, "BSS type = %d BSS role= %d\n", pmpriv->bss_type,
- pmpriv->bss_role);
- }
-
- PRINTM(MERROR, "num_cmd_timeout = %d\n",
- pmadapter->dbg.num_cmd_timeout);
- PRINTM(MERROR, "last_cmd_index = %d\n", pmadapter->dbg.last_cmd_index);
- PRINTM(MERROR, "last_cmd_id = ");
- for (i = 0; i < DBG_CMD_NUM; i++) {
- PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_id[i]);
- }
- PRINTM(MERROR, "\n");
- PRINTM(MERROR, "last_cmd_act = ");
- for (i = 0; i < DBG_CMD_NUM; i++) {
- PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_act[i]);
- }
- PRINTM(MERROR, "\n");
- PRINTM(MERROR, "last_cmd_resp_index = %d\n",
- pmadapter->dbg.last_cmd_resp_index);
- PRINTM(MERROR, "last_cmd_resp_id = ");
- for (i = 0; i < DBG_CMD_NUM; i++) {
- PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_resp_id[i]);
- }
- PRINTM(MERROR, "\n");
- PRINTM(MERROR, "last_event_index = %d\n",
- pmadapter->dbg.last_event_index);
- PRINTM(MERROR, "last_event = ");
- for (i = 0; i < DBG_CMD_NUM; i++) {
- PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_event[i]);
+ pmadapter->dbg.timeout_cmd_id =
+ pmadapter->dbg.last_cmd_id[pmadapter->dbg.last_cmd_index];
+ pmadapter->dbg.timeout_cmd_act =
+ pmadapter->dbg.last_cmd_act[pmadapter->dbg.last_cmd_index];
+ PRINTM_GET_SYS_TIME(MERROR, &sec, &usec);
+ PRINTM(MERROR, "Timeout cmd id (%lu.%06lu) = 0x%x, act = 0x%x \n", sec,
+ usec, pmadapter->dbg.timeout_cmd_id, pmadapter->dbg.timeout_cmd_act);
+ if (pcmd_node->cmdbuf) {
+ t_u8 *pcmd_buf;
+ pcmd_buf =
+ pcmd_node->cmdbuf->pbuf + pcmd_node->cmdbuf->data_offset +
+ INTF_HEADER_LEN;
+ for (i = 0; i < 16; i++) {
+ PRINTM(MERROR, "%02x ", *pcmd_buf++);
}
PRINTM(MERROR, "\n");
+ }
- PRINTM(MERROR, "num_data_h2c_failure = %d\n",
- pmadapter->dbg.num_tx_host_to_card_failure);
- PRINTM(MERROR, "num_cmd_h2c_failure = %d\n",
- pmadapter->dbg.num_cmd_host_to_card_failure);
- PRINTM(MERROR, "num_data_c2h_failure = %d\n",
- pmadapter->dbg.num_rx_card_to_host_failure);
- PRINTM(MERROR, "num_cmdevt_c2h_failure = %d\n",
- pmadapter->dbg.num_cmdevt_card_to_host_failure);
- PRINTM(MERROR, "num_int_read_failure = %d\n",
- pmadapter->dbg.num_int_read_failure);
- PRINTM(MERROR, "last_int_status = %d\n",
- pmadapter->dbg.last_int_status);
-
- PRINTM(MERROR, "num_event_deauth = %d\n",
- pmadapter->dbg.num_event_deauth);
- PRINTM(MERROR, "num_event_disassoc = %d\n",
- pmadapter->dbg.num_event_disassoc);
- PRINTM(MERROR, "num_event_link_lost = %d\n",
- pmadapter->dbg.num_event_link_lost);
- PRINTM(MERROR, "num_cmd_deauth = %d\n", pmadapter->dbg.num_cmd_deauth);
- PRINTM(MERROR, "num_cmd_assoc_success = %d\n",
- pmadapter->dbg.num_cmd_assoc_success);
- PRINTM(MERROR, "num_cmd_assoc_failure = %d\n",
- pmadapter->dbg.num_cmd_assoc_failure);
- PRINTM(MERROR, "cmd_resp_received=%d\n", pmadapter->cmd_resp_received);
- PRINTM(MERROR, "event_received=%d\n", pmadapter->event_received);
-
- PRINTM(MERROR, "max_tx_buf_size=%d\n", pmadapter->max_tx_buf_size);
- PRINTM(MERROR, "tx_buf_size=%d\n", pmadapter->tx_buf_size);
- PRINTM(MERROR, "curr_tx_buf_size=%d\n", pmadapter->curr_tx_buf_size);
-
- PRINTM(MERROR, "data_sent=%d cmd_sent=%d\n", pmadapter->data_sent,
- pmadapter->cmd_sent);
-
- PRINTM(MERROR, "ps_mode=%d ps_state=%d\n", pmadapter->ps_mode,
- pmadapter->ps_state);
- PRINTM(MERROR, "wakeup_dev_req=%d wakeup_tries=%d\n",
- pmadapter->pm_wakeup_card_req, pmadapter->pm_wakeup_fw_try);
- PRINTM(MERROR, "hs_configured=%d hs_activated=%d\n",
- pmadapter->is_hs_configured, pmadapter->hs_activated);
- PRINTM(MERROR, "pps_uapsd_mode=%d sleep_pd=%d\n",
- pmadapter->pps_uapsd_mode, pmadapter->sleep_period.period);
- PRINTM(MERROR, "tx_lock_flag = %d\n", pmadapter->tx_lock_flag);
- PRINTM(MERROR, "scan_processing = %d\n", pmadapter->scan_processing);
-
- PRINTM(MERROR, "mp_rd_bitmap=0x%x curr_rd_port=0x%x\n",
- pmadapter->mp_rd_bitmap, pmadapter->curr_rd_port);
- PRINTM(MERROR, "mp_wr_bitmap=0x%x curr_wr_port=0x%x\n",
- pmadapter->mp_wr_bitmap, pmadapter->curr_wr_port);
+ pmpriv = pcmd_node->priv;
+ if (pmpriv) {
+ PRINTM(MERROR, "BSS type = %d BSS role= %d\n", pmpriv->bss_type,
+ pmpriv->bss_role);
}
+ wlan_dump_info(pmadapter, REASON_CODE_CMD_TIMEOUT);
+
if (pmadapter->hw_status == WlanHardwareStatusInitializing)
wlan_init_fw_complete(pmadapter);
- else
+ else {
/* Signal MOAL to perform extra handling for debugging */
- if (pmpriv) {
- wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
- } else {
- wlan_recv_event(wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY),
- MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
+ if (pmpriv) {
+ wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
+ } else {
+ wlan_recv_event(wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY),
+ MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
+ }
}
exit:
@@ -1480,6 +1714,63 @@ wlan_flush_scan_queue(IN pmlan_adapter pmadapter)
LEAVE();
}
+
+/**
+ * @brief Cancel pending SCAN ioctl cmd.
+ *
+ * @param pmadapter A pointer to mlan_adapter
+ *
+ * @return N/A
+ */
+t_void
+wlan_cancel_pending_scan_cmd(pmlan_adapter pmadapter)
+{
+ pmlan_callbacks pcb = &pmadapter->callbacks;
+ cmd_ctrl_node *pcmd_node = MNULL;
+ mlan_ioctl_req *pioctl_buf = MNULL;
+ ENTER();
+
+ PRINTM(MIOCTL, "Cancel scan command\n");
+ wlan_request_cmd_lock(pmadapter);
+ if (pmadapter->curr_cmd && pmadapter->curr_cmd->pioctl_buf) {
+ pioctl_buf = (mlan_ioctl_req *) pmadapter->curr_cmd->pioctl_buf;
+ if (pioctl_buf->req_id == MLAN_IOCTL_SCAN) {
+ PRINTM(MIOCTL, "wlan_cancel_scan: current command\n");
+ pcmd_node = pmadapter->curr_cmd;
+ pcmd_node->pioctl_buf = MNULL;
+ pcmd_node->cmd_flag |= CMD_F_CANCELED;
+ pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
+ pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
+ MLAN_STATUS_FAILURE);
+ }
+ }
+ while ((pcmd_node =
+ wlan_get_pending_ioctl_by_id(pmadapter,
+ MLAN_IOCTL_SCAN)) != MNULL) {
+ PRINTM(MIOCTL,
+ "wlan_cancel_scan: find scan command in cmd_pending_q\n");
+ util_unlink_list(pmadapter->pmoal_handle, &pmadapter->cmd_pending_q,
+ (pmlan_linked_list) pcmd_node,
+ pmadapter->callbacks.moal_spin_lock,
+ pmadapter->callbacks.moal_spin_unlock);
+ pioctl_buf = (mlan_ioctl_req *) pcmd_node->pioctl_buf;
+ pcmd_node->pioctl_buf = MNULL;
+ pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
+ pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
+ MLAN_STATUS_FAILURE);
+ wlan_release_cmd_lock(pmadapter);
+ wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+ wlan_request_cmd_lock(pmadapter);
+ }
+ wlan_release_cmd_lock(pmadapter);
+
+ /* IOCTL will be completed, avoid calling IOCTL complete again from EVENT */
+ pmadapter->pext_scan_ioctl_req = MNULL;
+ /* Cancel all pending scan command */
+ wlan_flush_scan_queue(pmadapter);
+ LEAVE();
+ return;
+}
#endif
/**
@@ -1535,6 +1826,78 @@ wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter)
}
/**
+ * @brief Cancel specific bss's pending ioctl cmd.
+ *
+ * @param pmadapter A pointer to mlan_adapter
+ * @param bss_index BSS index
+ *
+ * @return N/A
+ */
+t_void
+wlan_cancel_bss_pending_cmd(pmlan_adapter pmadapter, t_u32 bss_index)
+{
+ pmlan_callbacks pcb = &pmadapter->callbacks;
+ cmd_ctrl_node *pcmd_node = MNULL;
+ mlan_ioctl_req *pioctl_buf = MNULL;
+#ifdef STA_SUPPORT
+ t_u8 flash_scan = MFALSE;
+#endif
+ ENTER();
+
+ PRINTM(MIOCTL, "MOAL Cancel BSS IOCTL: bss_index=%d\n", (int) bss_index);
+ wlan_request_cmd_lock(pmadapter);
+ if (pmadapter->curr_cmd && pmadapter->curr_cmd->pioctl_buf) {
+ pioctl_buf = (mlan_ioctl_req *) pmadapter->curr_cmd->pioctl_buf;
+ if (pioctl_buf->bss_index == bss_index) {
+ pcmd_node = pmadapter->curr_cmd;
+ pcmd_node->pioctl_buf = MNULL;
+ pcmd_node->cmd_flag |= CMD_F_CANCELED;
+#ifdef STA_SUPPORT
+ if (pioctl_buf->req_id == MLAN_IOCTL_SCAN)
+ flash_scan = MTRUE;
+#endif
+ pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
+ pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
+ MLAN_STATUS_FAILURE);
+ }
+ }
+ while ((pcmd_node =
+ wlan_get_bss_pending_ioctl_cmd(pmadapter, bss_index)) != MNULL) {
+ util_unlink_list(pmadapter->pmoal_handle, &pmadapter->cmd_pending_q,
+ (pmlan_linked_list) pcmd_node,
+ pmadapter->callbacks.moal_spin_lock,
+ pmadapter->callbacks.moal_spin_unlock);
+ pioctl_buf = (mlan_ioctl_req *) pcmd_node->pioctl_buf;
+ pcmd_node->pioctl_buf = MNULL;
+#ifdef STA_SUPPORT
+ if (pioctl_buf->req_id == MLAN_IOCTL_SCAN)
+ flash_scan = MTRUE;
+#endif
+ pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
+ pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
+ MLAN_STATUS_FAILURE);
+ wlan_release_cmd_lock(pmadapter);
+ wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+ wlan_request_cmd_lock(pmadapter);
+ }
+ wlan_release_cmd_lock(pmadapter);
+#ifdef STA_SUPPORT
+ if (pmadapter->pext_scan_ioctl_req &&
+ (pmadapter->pext_scan_ioctl_req->bss_index == bss_index))
+ flash_scan = MTRUE;
+ if (flash_scan) {
+ /* IOCTL will be completed, avoid calling IOCTL complete again from
+ EVENT */
+ pmadapter->pext_scan_ioctl_req = MNULL;
+ /* Cancel all pending scan command */
+ wlan_flush_scan_queue(pmadapter);
+ }
+#endif
+ LEAVE();
+ return;
+}
+
+/**
* @brief Cancel pending ioctl cmd.
*
* @param pmadapter A pointer to mlan_adapter
@@ -2196,7 +2559,7 @@ wlan_ret_802_11_tx_rate_query(IN pmlan_private pmpriv,
rate->param.data_rate.rx_ht_bw = MLAN_HT_BW40;
else
rate->param.data_rate.rx_ht_bw = MLAN_HT_BW20;
- if (pmpriv->tx_htinfo & MBIT(2))
+ if (pmpriv->rxpd_htinfo & MBIT(2))
rate->param.data_rate.rx_ht_gi = MLAN_HT_SGI;
else
rate->param.data_rate.rx_ht_gi = MLAN_HT_LGI;
@@ -2231,7 +2594,8 @@ wlan_cmd_tx_rate_cfg(IN pmlan_private pmpriv,
IN HostCmd_DS_COMMAND * cmd,
IN t_u16 cmd_action, IN t_void * pdata_buf)
{
- HostCmd_DS_TX_RATE_CFG *rate_cfg = &cmd->params.tx_rate_cfg;
+ HostCmd_DS_TX_RATE_CFG *rate_cfg =
+ (HostCmd_DS_TX_RATE_CFG *) & (cmd->params.tx_rate_cfg);
MrvlRateScope_t *rate_scope;
MrvlRateDropPattern_t *rate_drop;
t_u16 *pbitmap_rates = (t_u16 *) pdata_buf;
@@ -2301,7 +2665,7 @@ wlan_ret_tx_rate_cfg(IN pmlan_private pmpriv,
HostCmd_DS_TX_RATE_CFG *prate_cfg = MNULL;
MrvlRateScope_t *prate_scope;
MrvlIEtypesHeader_t *head = MNULL;
- t_u16 tlv, tlv_buf_len;
+ t_u16 tlv, tlv_buf_len = 0;
t_u8 *tlv_buf;
t_u32 i;
t_s32 index;
@@ -2313,11 +2677,13 @@ wlan_ret_tx_rate_cfg(IN pmlan_private pmpriv,
LEAVE();
return MLAN_STATUS_FAILURE;
}
- prate_cfg = &resp->params.tx_rate_cfg;
+ prate_cfg = (HostCmd_DS_TX_RATE_CFG *) & (resp->params.tx_rate_cfg);
tlv_buf = (t_u8 *) ((t_u8 *) prate_cfg) + sizeof(HostCmd_DS_TX_RATE_CFG);
- tlv_buf_len = *(t_u16 *) (tlv_buf + sizeof(t_u16));
- tlv_buf_len = wlan_le16_to_cpu(tlv_buf_len);
+ if (tlv_buf) {
+ tlv_buf_len = *(t_u16 *) (tlv_buf + sizeof(t_u16));
+ tlv_buf_len = wlan_le16_to_cpu(tlv_buf_len);
+ }
while (tlv_buf && tlv_buf_len > 0) {
tlv = (*tlv_buf);
@@ -2611,6 +2977,59 @@ wlan_ret_cfg_data(IN pmlan_private pmpriv,
}
/**
+ * @brief This function prepares command of mac_control.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param pcmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action Command action
+ * @param pdata_buf A pointer to command information buffer
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_mac_control(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * pcmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ HostCmd_DS_MAC_CONTROL *pmac = &pcmd->params.mac_ctrl;
+ t_u32 action = *((t_u32 *) pdata_buf);
+
+ ENTER();
+
+ if (cmd_action != HostCmd_ACT_GEN_SET) {
+ PRINTM(MERROR, "wlan_cmd_mac_control(): support SET only.\n");
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
+ }
+
+ pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
+ pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_CONTROL) + S_DS_GEN);
+ pmac->action = wlan_cpu_to_le32(action);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function handles the command response of mac_control
+ *
+ * @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_mac_control(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * resp,
+ IN mlan_ioctl_req * pioctl_buf)
+{
+ ENTER();
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
* @brief This function handles the command response of get_hw_spec
*
* @param pmpriv A pointer to mlan_private structure
@@ -2681,10 +3100,8 @@ wlan_ret_get_hw_spec(IN pmlan_private pmpriv,
PRINTM(MINFO, "GET_HW_SPEC: fw_release_number- 0x%X\n",
wlan_le32_to_cpu(pmadapter->fw_release_number));
- PRINTM(MINFO, "GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
- hw_spec->permanent_addr[0], hw_spec->permanent_addr[1],
- hw_spec->permanent_addr[2], hw_spec->permanent_addr[3],
- hw_spec->permanent_addr[4], hw_spec->permanent_addr[5]);
+ PRINTM(MINFO, "GET_HW_SPEC: Permanent addr- " MACSTR "\n",
+ MAC2STR(hw_spec->permanent_addr));
PRINTM(MINFO, "GET_HW_SPEC: hw_if_version=0x%X version=0x%X\n",
wlan_le16_to_cpu(hw_spec->hw_if_version),
wlan_le16_to_cpu(hw_spec->version));
@@ -2941,7 +3358,6 @@ wlan_ret_wifi_direct_mode(IN pmlan_private pmpriv,
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
- * @param cmd_action the action: GET or SET
* @param pdata_buf A pointer to data buffer
* @return MLAN_STATUS_SUCCESS
*/
@@ -3006,22 +3422,45 @@ wlan_cmd_802_11_rf_antenna(IN pmlan_private pmpriv,
{
HostCmd_DS_802_11_RF_ANTENNA *pantenna = &cmd->params.antenna;
mlan_ds_ant_cfg *ant_cfg = (mlan_ds_ant_cfg *) pdata_buf;
+ typedef struct _HostCmd_DS_802_11_RF_ANTENNA_1X1
+ {
+ /** Action */
+ t_u16 action;
+ /** Antenna or 0xffff (diversity) */
+ t_u16 antenna_mode;
+ } HostCmd_DS_802_11_RF_ANTENNA_1X1;
+ HostCmd_DS_802_11_RF_ANTENNA_1X1 *pantenna_1x1 =
+ (HostCmd_DS_802_11_RF_ANTENNA_1X1 *) & cmd->params.antenna;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_ANTENNA);
- cmd->size =
- wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_ANTENNA) + S_DS_GEN);
+ if (!IS_STREAM_2X2(pmpriv->adapter->feature_control))
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_ANTENNA_1X1) +
+ S_DS_GEN);
+ else
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_ANTENNA) + S_DS_GEN);
if (cmd_action == HostCmd_ACT_GEN_SET) {
- pantenna->action_tx = wlan_cpu_to_le16(HostCmd_ACT_SET_TX);
- pantenna->tx_antenna_mode =
- wlan_cpu_to_le16((t_u16) ant_cfg->tx_antenna);
- pantenna->action_rx = wlan_cpu_to_le16(HostCmd_ACT_SET_RX);
- pantenna->rx_antenna_mode =
- wlan_cpu_to_le16((t_u16) ant_cfg->rx_antenna);
+ if (IS_STREAM_2X2(pmpriv->adapter->feature_control)) {
+ pantenna->action_tx = wlan_cpu_to_le16(HostCmd_ACT_SET_TX);
+ pantenna->tx_antenna_mode =
+ wlan_cpu_to_le16((t_u16) ant_cfg->tx_antenna);
+ pantenna->action_rx = wlan_cpu_to_le16(HostCmd_ACT_SET_RX);
+ pantenna->rx_antenna_mode =
+ wlan_cpu_to_le16((t_u16) ant_cfg->rx_antenna);
+ } else {
+ pantenna_1x1->action = wlan_cpu_to_le16(HostCmd_ACT_SET_BOTH);
+ pantenna_1x1->antenna_mode = wlan_cpu_to_le16(*(t_u16 *) pdata_buf);
+ }
} else {
- pantenna->action_tx = wlan_cpu_to_le16(HostCmd_ACT_GET_TX);
- pantenna->action_rx = wlan_cpu_to_le16(HostCmd_ACT_GET_RX);
+ if (IS_STREAM_2X2(pmpriv->adapter->feature_control)) {
+ pantenna->action_tx = wlan_cpu_to_le16(HostCmd_ACT_GET_TX);
+ pantenna->action_rx = wlan_cpu_to_le16(HostCmd_ACT_GET_RX);
+ } else {
+ pantenna_1x1->action = wlan_cpu_to_le16(HostCmd_ACT_GET_BOTH);
+ }
}
LEAVE();
return MLAN_STATUS_SUCCESS;
@@ -3044,19 +3483,37 @@ wlan_ret_802_11_rf_antenna(IN pmlan_private pmpriv,
HostCmd_DS_802_11_RF_ANTENNA *pantenna = &resp->params.antenna;
t_u16 tx_ant_mode = wlan_le16_to_cpu(pantenna->tx_antenna_mode);
t_u16 rx_ant_mode = wlan_le16_to_cpu(pantenna->rx_antenna_mode);
+ typedef struct _HostCmd_DS_802_11_RF_ANTENNA_1X1
+ {
+ /** Action */
+ t_u16 action;
+ /** Antenna or 0xffff (diversity) */
+ t_u16 antenna_mode;
+ } HostCmd_DS_802_11_RF_ANTENNA_1X1;
+ HostCmd_DS_802_11_RF_ANTENNA_1X1 *pantenna_1x1 =
+ (HostCmd_DS_802_11_RF_ANTENNA_1X1 *) & resp->params.antenna;
+ t_u16 ant_mode = wlan_le16_to_cpu(pantenna_1x1->antenna_mode);
mlan_ds_radio_cfg *radio = MNULL;
ENTER();
- PRINTM(MINFO, "RF_ANT_RESP: Tx action = 0x%x, Tx Mode = 0x%04x"
- " Rx action = 0x%x, Rx Mode = 0x%04x\n",
- wlan_le16_to_cpu(pantenna->action_tx), tx_ant_mode,
- wlan_le16_to_cpu(pantenna->action_rx), rx_ant_mode);
+ if (IS_STREAM_2X2(pmpriv->adapter->feature_control))
+ PRINTM(MINFO, "RF_ANT_RESP: Tx action = 0x%x, Tx Mode = 0x%04x"
+ " Rx action = 0x%x, Rx Mode = 0x%04x\n",
+ wlan_le16_to_cpu(pantenna->action_tx), tx_ant_mode,
+ wlan_le16_to_cpu(pantenna->action_rx), rx_ant_mode);
+ else
+ PRINTM(MINFO, "RF_ANT_RESP: action = 0x%x, Mode = 0x%04x\n",
+ wlan_le16_to_cpu(pantenna_1x1->action), ant_mode);
if (pioctl_buf) {
radio = (mlan_ds_radio_cfg *) pioctl_buf->pbuf;
- radio->param.ant_cfg.tx_antenna = tx_ant_mode;
- radio->param.ant_cfg.rx_antenna = rx_ant_mode;
+ if (IS_STREAM_2X2(pmpriv->adapter->feature_control)) {
+ radio->param.ant_cfg.tx_antenna = tx_ant_mode;
+ radio->param.ant_cfg.rx_antenna = rx_ant_mode;
+ } else {
+ radio->param.antenna = ant_mode;
+ }
}
LEAVE();
@@ -3152,6 +3609,7 @@ wlan_cmd_reg_access(IN HostCmd_DS_COMMAND * cmd,
/**
* @brief This function handles the command response of reg_access
*
+ * @param pmadapter A pointer to mlan_adapter structure
* @param type The type of reg access (MAC, BBP or RF)
* @param resp A pointer to HostCmd_DS_COMMAND
* @param pioctl_buf A pointer to command buffer
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_decl.h b/drivers/net/wireless/sd8797/mlan/mlan_decl.h
index ac24b5e79fc4..28ab785045e3 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_decl.h
+++ b/drivers/net/wireless/sd8797/mlan/mlan_decl.h
@@ -27,11 +27,11 @@ Change log:
#define _MLAN_DECL_H_
/** MLAN release version */
-#define MLAN_RELEASE_VERSION "334"
+#define MLAN_RELEASE_VERSION "394"
/** Re-define generic data types for MLAN/MOAL */
/** Signed char (1-byte) */
-typedef char t_s8;
+typedef signed char t_s8;
/** Unsigned char (1-byte) */
typedef unsigned char t_u8;
/** Signed short (2-bytes) */
@@ -101,6 +101,16 @@ typedef t_s32 t_sval;
/** MLAN FALSE */
#define MFALSE (0)
+#ifndef MACSTR
+/** MAC address security format */
+#define MACSTR "%02x:XX:XX:XX:%02x:%02x"
+#endif
+
+#ifndef MAC2STR
+/** MAC address security print arguments */
+#define MAC2STR(a) (a)[0], (a)[4], (a)[5]
+#endif
+
/** Macros for Data Alignment : size */
#define ALIGN_SZ(p, a) \
(((p) + ((a) - 1)) & ~((a) - 1))
@@ -296,26 +306,26 @@ typedef enum _mlan_error_code
MLAN_ERROR_NO_ERROR = 0,
/** Firmware/device errors below (MSB=0) */
MLAN_ERROR_FW_NOT_READY = 0x00000001,
- MLAN_ERROR_FW_BUSY,
- MLAN_ERROR_FW_CMDRESP,
- MLAN_ERROR_DATA_TX_FAIL,
- MLAN_ERROR_DATA_RX_FAIL,
+ MLAN_ERROR_FW_BUSY = 0x00000002,
+ MLAN_ERROR_FW_CMDRESP = 0x00000003,
+ MLAN_ERROR_DATA_TX_FAIL = 0x00000004,
+ MLAN_ERROR_DATA_RX_FAIL = 0x00000005,
/** Driver errors below (MSB=1) */
MLAN_ERROR_PKT_SIZE_INVALID = 0x80000001,
- MLAN_ERROR_PKT_TIMEOUT,
- MLAN_ERROR_PKT_INVALID,
- MLAN_ERROR_CMD_INVALID,
- MLAN_ERROR_CMD_TIMEOUT,
- MLAN_ERROR_CMD_DNLD_FAIL,
- MLAN_ERROR_CMD_CANCEL,
- MLAN_ERROR_CMD_RESP_FAIL,
- MLAN_ERROR_CMD_ASSOC_FAIL,
- MLAN_ERROR_CMD_SCAN_FAIL,
- MLAN_ERROR_IOCTL_INVALID,
- MLAN_ERROR_IOCTL_FAIL,
- MLAN_ERROR_EVENT_UNKNOWN,
- MLAN_ERROR_INVALID_PARAMETER,
- MLAN_ERROR_NO_MEM,
+ MLAN_ERROR_PKT_TIMEOUT = 0x80000002,
+ MLAN_ERROR_PKT_INVALID = 0x80000003,
+ MLAN_ERROR_CMD_INVALID = 0x80000004,
+ MLAN_ERROR_CMD_TIMEOUT = 0x80000005,
+ MLAN_ERROR_CMD_DNLD_FAIL = 0x80000006,
+ MLAN_ERROR_CMD_CANCEL = 0x80000007,
+ MLAN_ERROR_CMD_RESP_FAIL = 0x80000008,
+ MLAN_ERROR_CMD_ASSOC_FAIL = 0x80000009,
+ MLAN_ERROR_CMD_SCAN_FAIL = 0x8000000A,
+ MLAN_ERROR_IOCTL_INVALID = 0x8000000B,
+ MLAN_ERROR_IOCTL_FAIL = 0x8000000C,
+ MLAN_ERROR_EVENT_UNKNOWN = 0x8000000D,
+ MLAN_ERROR_INVALID_PARAMETER = 0x8000000E,
+ MLAN_ERROR_NO_MEM = 0x8000000F,
/** More to add */
} mlan_error_code;
@@ -365,56 +375,60 @@ typedef enum _mlan_event_id
{
/* Event generated by firmware (MSB=0) */
MLAN_EVENT_ID_FW_UNKNOWN = 0x00000001,
- MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED,
- MLAN_EVENT_ID_FW_ADHOC_LINK_LOST,
- MLAN_EVENT_ID_FW_DISCONNECTED,
- MLAN_EVENT_ID_FW_MIC_ERR_UNI,
- MLAN_EVENT_ID_FW_MIC_ERR_MUL,
- MLAN_EVENT_ID_FW_BCN_RSSI_LOW,
- MLAN_EVENT_ID_FW_BCN_RSSI_HIGH,
- MLAN_EVENT_ID_FW_BCN_SNR_LOW,
- MLAN_EVENT_ID_FW_BCN_SNR_HIGH,
- MLAN_EVENT_ID_FW_MAX_FAIL,
- MLAN_EVENT_ID_FW_DATA_RSSI_LOW,
- MLAN_EVENT_ID_FW_DATA_RSSI_HIGH,
- MLAN_EVENT_ID_FW_DATA_SNR_LOW,
- MLAN_EVENT_ID_FW_DATA_SNR_HIGH,
- MLAN_EVENT_ID_FW_LINK_QUALITY,
- MLAN_EVENT_ID_FW_PORT_RELEASE,
- MLAN_EVENT_ID_FW_PRE_BCN_LOST,
- MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE,
- MLAN_EVENT_ID_FW_HS_WAKEUP,
- MLAN_EVENT_ID_FW_BG_SCAN,
- MLAN_EVENT_ID_FW_WEP_ICV_ERR,
- MLAN_EVENT_ID_FW_STOP_TX,
- MLAN_EVENT_ID_FW_START_TX,
- MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN,
- MLAN_EVENT_ID_FW_RADAR_DETECTED,
- MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY,
- MLAN_EVENT_ID_FW_BW_CHANGED,
+ MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED = 0x00000002,
+ MLAN_EVENT_ID_FW_ADHOC_LINK_LOST = 0x00000003,
+ MLAN_EVENT_ID_FW_DISCONNECTED = 0x00000004,
+ MLAN_EVENT_ID_FW_MIC_ERR_UNI = 0x00000005,
+ MLAN_EVENT_ID_FW_MIC_ERR_MUL = 0x00000006,
+ MLAN_EVENT_ID_FW_BCN_RSSI_LOW = 0x00000007,
+ MLAN_EVENT_ID_FW_BCN_RSSI_HIGH = 0x00000008,
+ MLAN_EVENT_ID_FW_BCN_SNR_LOW = 0x00000009,
+ MLAN_EVENT_ID_FW_BCN_SNR_HIGH = 0x0000000A,
+ MLAN_EVENT_ID_FW_MAX_FAIL = 0x0000000B,
+ MLAN_EVENT_ID_FW_DATA_RSSI_LOW = 0x0000000C,
+ MLAN_EVENT_ID_FW_DATA_RSSI_HIGH = 0x0000000D,
+ MLAN_EVENT_ID_FW_DATA_SNR_LOW = 0x0000000E,
+ MLAN_EVENT_ID_FW_DATA_SNR_HIGH = 0x0000000F,
+ MLAN_EVENT_ID_FW_LINK_QUALITY = 0x00000010,
+ MLAN_EVENT_ID_FW_PORT_RELEASE = 0x00000011,
+ MLAN_EVENT_ID_FW_PRE_BCN_LOST = 0x00000012,
+ MLAN_EVENT_ID_FW_DEBUG_INFO = 0x00000013,
+ MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE = 0x0000001A,
+ MLAN_EVENT_ID_FW_HS_WAKEUP = 0x0000001B,
+ MLAN_EVENT_ID_FW_BG_SCAN = 0x0000001D,
+ MLAN_EVENT_ID_FW_BG_SCAN_STOPPED = 0x0000001E,
+ MLAN_EVENT_ID_FW_WEP_ICV_ERR = 0x00000020,
+ MLAN_EVENT_ID_FW_STOP_TX = 0x00000021,
+ MLAN_EVENT_ID_FW_START_TX = 0x00000022,
+ MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN = 0x00000023,
+ MLAN_EVENT_ID_FW_RADAR_DETECTED = 0x00000024,
+ MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY = 0x00000025,
+ MLAN_EVENT_ID_FW_BW_CHANGED = 0x00000026,
#ifdef WIFI_DIRECT_SUPPORT
- MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED,
+ MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED = 0x0000002B,
#endif
#ifdef UAP_SUPPORT
- MLAN_EVENT_ID_UAP_FW_BSS_START,
- MLAN_EVENT_ID_UAP_FW_BSS_ACTIVE,
- MLAN_EVENT_ID_UAP_FW_BSS_IDLE,
- MLAN_EVENT_ID_UAP_FW_STA_CONNECT,
- MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT,
+ MLAN_EVENT_ID_UAP_FW_BSS_START = 0x0000002C,
+ MLAN_EVENT_ID_UAP_FW_BSS_ACTIVE = 0x0000002D,
+ MLAN_EVENT_ID_UAP_FW_BSS_IDLE = 0x0000002E,
+ MLAN_EVENT_ID_UAP_FW_STA_CONNECT = 0x00000030,
+ MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT = 0x00000031,
#endif
/* Event generated by MLAN driver (MSB=1) */
MLAN_EVENT_ID_DRV_CONNECTED = 0x80000001,
- MLAN_EVENT_ID_DRV_DEFER_HANDLING,
- MLAN_EVENT_ID_DRV_HS_ACTIVATED,
- MLAN_EVENT_ID_DRV_HS_DEACTIVATED,
- MLAN_EVENT_ID_DRV_MGMT_FRAME,
- MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM,
- MLAN_EVENT_ID_DRV_PASSTHRU,
- MLAN_EVENT_ID_DRV_SCAN_REPORT,
- MLAN_EVENT_ID_DRV_MEAS_REPORT,
- MLAN_EVENT_ID_DRV_REPORT_STRING,
- MLAN_EVENT_ID_DRV_DBG_DUMP,
+ MLAN_EVENT_ID_DRV_DEFER_HANDLING = 0x80000002,
+ MLAN_EVENT_ID_DRV_HS_ACTIVATED = 0x80000003,
+ MLAN_EVENT_ID_DRV_HS_DEACTIVATED = 0x80000004,
+ MLAN_EVENT_ID_DRV_MGMT_FRAME = 0x80000005,
+ MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM = 0x80000006,
+ MLAN_EVENT_ID_DRV_PASSTHRU = 0x80000007,
+ MLAN_EVENT_ID_DRV_SCAN_REPORT = 0x80000009,
+ MLAN_EVENT_ID_DRV_MEAS_REPORT = 0x8000000A,
+ MLAN_EVENT_ID_DRV_ASSOC_FAILURE_REPORT = 0x8000000B,
+ MLAN_EVENT_ID_DRV_REPORT_STRING = 0x8000000F,
+ MLAN_EVENT_ID_DRV_DBG_DUMP = 0x80000012,
+ MLAN_EVENT_ID_DRV_BGSCAN_RESULT = 0x80000013,
} mlan_event_id;
/** Data Structures */
@@ -552,6 +566,8 @@ typedef struct _mlan_bss_attr
t_u32 bss_priority;
/** BSS number */
t_u32 bss_num;
+ /** The BSS is virtual */
+ t_u32 bss_virtual;
} mlan_bss_attr, *pmlan_bss_attr;
#ifdef PRAGMA_PACK
@@ -711,6 +727,7 @@ typedef struct _mlan_callbacks
mlan_status(*moal_ioctl_complete) (IN t_void * pmoal_handle,
IN pmlan_ioctl_req pioctl_req,
IN mlan_status status);
+
/** moal_alloc_mlan_buffer */
mlan_status(*moal_alloc_mlan_buffer) (IN t_void * pmoal_handle,
IN t_u32 size,
@@ -738,6 +755,11 @@ typedef struct _mlan_callbacks
IN t_u32 size, IN t_u32 flag, OUT t_u8 ** ppbuf);
/** moal_mfree */
mlan_status(*moal_mfree) (IN t_void * pmoal_handle, IN t_u8 * pbuf);
+ /** moal_vmalloc */
+ mlan_status(*moal_vmalloc) (IN t_void * pmoal_handle,
+ IN t_u32 size, OUT t_u8 ** ppbuf);
+ /** moal_vfree */
+ mlan_status(*moal_vfree) (IN t_void * pmoal_handle, IN t_u8 * pbuf);
/** moal_memset */
t_void *(*moal_memset) (IN t_void * pmoal_handle,
IN t_void * pmem, IN t_u8 byte, IN t_u32 num);
@@ -787,7 +809,7 @@ typedef struct _mlan_callbacks
IN t_void * plock);
/** moal_print */
t_void(*moal_print) (IN t_void * pmoal_handle,
- IN t_u32 level, IN t_s8 * pformat, IN ...);
+ IN t_u32 level, IN char *pformat, IN ...);
/** moal_print_netintf */
t_void(*moal_print_netintf) (IN t_void * pmoal_handle,
IN t_u32 bss_index, IN t_u32 level);
@@ -807,6 +829,14 @@ typedef struct _mlan_callbacks
/** Parameter disabled, override MLAN default setting */
#define MLAN_INIT_PARA_DISABLED 2
+/** Control bit for stream 2X2 */
+#define FEATURE_CTRL_STREAM_2X2 MBIT(6)
+/** Control bit for DFS support */
+#define FEATURE_CTRL_DFS_SUPPORT MBIT(7)
+
+/** Default feature control */
+#define FEATURE_CTRL_DEFAULT 0xffffffff
+
/** mlan_device data structure */
typedef struct _mlan_device
{
@@ -846,6 +876,8 @@ typedef struct _mlan_device
/** 802.11d configuration */
t_u32 cfg_11d;
#endif
+ /** Feature control bitmask */
+ t_u32 feature_control;
} mlan_device, *pmlan_device;
/** MLAN API function prototype */
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_fw.h b/drivers/net/wireless/sd8797/mlan/mlan_fw.h
index 8750844eece8..3e2538231e57 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_fw.h
+++ b/drivers/net/wireless/sd8797/mlan/mlan_fw.h
@@ -146,11 +146,11 @@ typedef enum _KEY_TYPE_ID
/** Key type : WEP */
KEY_TYPE_ID_WEP = 0,
/** Key type : TKIP */
- KEY_TYPE_ID_TKIP,
+ KEY_TYPE_ID_TKIP = 1,
/** Key type : AES */
- KEY_TYPE_ID_AES,
- KEY_TYPE_ID_WAPI,
- KEY_TYPE_ID_AES_CMAC,
+ KEY_TYPE_ID_AES = 2,
+ KEY_TYPE_ID_WAPI = 3,
+ KEY_TYPE_ID_AES_CMAC = 4,
} KEY_TYPE_ID;
/** Key Info flag for multicast key */
@@ -371,6 +371,12 @@ typedef enum _WLAN_802_11_WEP_STATUS
/** TLV type: MAX_MGMT_IE */
#define TLV_TYPE_MAX_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 0xaa) // 0x01aa
+/** TLV type: key param v2 */
+#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 0x9C) // 0x019C
+
+/** TLV type: hs wake hold off */
+#define TLV_TYPE_HS_WAKE_HOLDOFF (PROPRIETARY_TLV_BASE_ID + 0xB6) // 0x01b6
+
/** TLV type : HT Capabilities */
#define TLV_TYPE_HT_CAP (PROPRIETARY_TLV_BASE_ID + 0x4a) // 0x014a
/** TLV type : HT Information */
@@ -606,6 +612,25 @@ typedef enum _WLAN_802_11_WEP_STATUS
/** RadioType : Set secondary channel */
#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4))
+/** ExtCap : Support for TDLS */
+#define ISSUPP_EXTCAP_TDLS(ext_cap) (ext_cap.TDLSSupport)
+/** ExtCap : Set support TDLS */
+#define SET_EXTCAP_TDLS(ext_cap) (ext_cap.TDLSSupport = 1)
+/** ExtCap : Reset support TDLS */
+#define RESET_EXTCAP_TDLS(ext_cap) (ext_cap.TDLSSupport = 0)
+/** ExtCap : Support for Interworking */
+#define ISSUPP_EXTCAP_INTERWORKING(ext_cap) (ext_cap.Interworking)
+/** ExtCap : Set support Interworking */
+#define SET_EXTCAP_INTERWORKING(ext_cap) (ext_cap.Interworking = 1)
+/** ExtCap : Reset support Interworking */
+#define RESET_EXTCAP_INTERWORKING(ext_cap) (ext_cap.Interworking = 0)
+/** ExtCap : Support for Operation Mode Notification */
+#define ISSUPP_EXTCAP_OPERMODENTF(ext_cap) (ext_cap.OperModeNtf)
+/** ExtCap : Set support Operation Mode Notification */
+#define SET_EXTCAP_OPERMODENTF(ext_cap) (ext_cap.OperModeNtf = 1)
+/** ExtCap : Reset support Operation Mode Notification */
+#define RESET_EXTCAP_OPERMODENTF(ext_cap) (ext_cap.OperModeNtf = 0)
+
/** LLC/SNAP header len */
#define LLC_SNAP_LEN 8
@@ -964,12 +989,12 @@ typedef enum _ENH_PS_MODES
/** Buffer Constants */
/** Number of command buffers */
-#define MRVDRV_NUM_OF_CMD_BUFFER 20
+#define MRVDRV_NUM_OF_CMD_BUFFER 30
/** Size of command buffer */
#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024)
/** Maximum number of BSS Descriptors */
-#define MRVDRV_MAX_BSSID_LIST 64
+#define MRVDRV_MAX_BSSID_LIST 128
/** Host command flag in command */
#define CMD_F_HOSTCMD (1 << 0)
@@ -1047,6 +1072,8 @@ typedef enum _ENH_PS_MODES
/** Card Event definition : BG scan report */
#define EVENT_BG_SCAN_REPORT 0x00000018
+/** Card Event definition : BG scan stopped */
+#define EVENT_BG_SCAN_STOPPED 0x00000065
/** Card Event definition : Beacon RSSI low */
#define EVENT_RSSI_LOW 0x00000019
@@ -1120,6 +1147,9 @@ typedef enum _ENH_PS_MODES
/** Event definition: Scan results through event */
#define EVENT_EXT_SCAN_REPORT 0x00000058
+/** Event definition : FW debug information */
+#define EVENT_FW_DEBUG_INFO 0x00000063
+
/** Event definition: RXBA_SYNC */
#define EVENT_RXBA_SYNC 0x00000059
@@ -1213,6 +1243,16 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_Data_t
t_u8 data[1];
} MLAN_PACK_END MrvlIEtypes_Data_t;
+#if defined(STA_SUPPORT)
+/** Pairwise Cipher Suite length */
+#define PAIRWISE_CIPHER_SUITE_LEN 4
+/** AKM Suite length */
+#define AKM_SUITE_LEN 4
+/** MFPC bit in RSN capability */
+#define MFPC_BIT 7
+/** MFPR bit in RSN capability */
+#define MFPR_BIT 6
+#endif
/** Bit mask for TxPD status field for null packet */
#define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01
/** Bit mask for TxPD status field for last packet */
@@ -1225,6 +1265,7 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_Data_t
#define PKT_TYPE_AMSDU 0xE6
/** Packet type: BAR */
#define PKT_TYPE_BAR 0xE7
+
/** Packet type: debugging */
#define PKT_TYPE_DEBUG 0xEF
@@ -1746,38 +1787,112 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_RsnParamSet_t
t_u8 rsn_ie[1];
} MLAN_PACK_END MrvlIEtypes_RsnParamSet_t;
-/** Key_param_set fixed length */
-#define KEYPARAMSET_FIXED_LEN 6
-
+/** Key Info flag for multicast key */
+#define KEY_INFO_MCAST_KEY 0x01
+/** Key Info flag for unicast key */
+#define KEY_INFO_UCAST_KEY 0x02
+/** Key Info flag for enable key */
+#define KEY_INFO_ENABLE_KEY 0x04
+/** Key Info flag for default key */
+#define KEY_INFO_DEFAULT_KEY 0x08
+/** Key Info flag for TX key */
+#define KEY_INFO_TX_KEY 0x10
+/** Key Info flag for RX key */
+#define KEY_INFO_RX_KEY 0x20
+#define KEY_INFO_CMAC_AES_KEY 0x400
+/** PN size for WPA/WPA2 */
+#define WPA_PN_SIZE 8
/** PN size for PMF IGTK */
#define IGTK_PN_SIZE 8
-/** WPA AES IGTK key length */
-#define CMAC_AES_KEY_LEN 16
+/** WAPI KEY size */
+#define WAPI_KEY_SIZE 32
+/** key params fix size */
+#define KEY_PARAMS_FIXED_LEN 10
+/** key index mask */
+#define KEY_INDEX_MASK 0xf
+
+/** wep_param */
+typedef MLAN_PACK_START struct _wep_param_t
+{
+ /** key_len */
+ t_u16 key_len;
+ /** wep key */
+ t_u8 key[MAX_WEP_KEY_SIZE];
+} MLAN_PACK_END wep_param_t;
+
+/** tkip_param */
+typedef MLAN_PACK_START struct _tkip_param
+{
+ /** Rx packet num */
+ t_u8 pn[WPA_PN_SIZE];
+ /** key_len */
+ t_u16 key_len;
+ /** tkip key */
+ t_u8 key[WPA_TKIP_KEY_LEN];
+} MLAN_PACK_END tkip_param;
+
+/** aes_param */
+typedef MLAN_PACK_START struct _aes_param
+{
+ /** Rx packet num */
+ t_u8 pn[WPA_PN_SIZE];
+ /** key_len */
+ t_u16 key_len;
+ /** aes key */
+ t_u8 key[WPA_AES_KEY_LEN];
+} MLAN_PACK_END aes_param;
+
+/** wapi_param */
+typedef MLAN_PACK_START struct _wapi_param
+{
+ /** Rx packet num */
+ t_u8 pn[PN_SIZE];
+ /** key_len */
+ t_u16 key_len;
+ /** wapi key */
+ t_u8 key[WAPI_KEY_SIZE];
+} MLAN_PACK_END wapi_param;
+
/** cmac_aes_param */
-typedef MLAN_PACK_START struct _cmac_param
+typedef MLAN_PACK_START struct _cmac_aes_param
{
/** IGTK pn */
t_u8 ipn[IGTK_PN_SIZE];
+ /** key_len */
+ t_u16 key_len;
/** aes key */
t_u8 key[CMAC_AES_KEY_LEN];
-} MLAN_PACK_END cmac_param;
+} MLAN_PACK_END cmac_aes_param;
/** MrvlIEtype_KeyParamSet_t */
-typedef MLAN_PACK_START struct _MrvlIEtype_KeyParamSet_t
+typedef MLAN_PACK_START struct _MrvlIEtype_KeyParamSetV2_t
{
/** Type ID */
t_u16 type;
/** Length of Payload */
t_u16 length;
- /** Type of Key: WEP=0, TKIP=1, AES=2 WAPI=3 AES_CMAC=4 */
- t_u16 key_type_id;
+ /** mac address */
+ t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH];
+ /** key index */
+ t_u8 key_idx;
+ /** Type of Key: WEP=0, TKIP=1, AES=2, WAPI=3 AES_CMAC=4 */
+ t_u8 key_type;
/** Key Control Info specific to a key_type_id */
t_u16 key_info;
- /** Length of key */
- t_u16 key_len;
- /** Key material of size key_len */
- t_u8 key[50];
-} MLAN_PACK_END MrvlIEtype_KeyParamSet_t;
+ union
+ {
+ /** wep key param */
+ wep_param_t wep;
+ /** tkip key param */
+ tkip_param tkip;
+ /** aes key param */
+ aes_param aes;
+ /** wapi key param */
+ wapi_param wapi;
+ /** IGTK key param */
+ cmac_aes_param cmac_aes;
+ } key_params;
+} MLAN_PACK_END MrvlIEtype_KeyParamSetV2_t;
/** HostCmd_DS_802_11_KEY_MATERIAL */
typedef MLAN_PACK_START struct _HostCmd_DS_802_11_KEY_MATERIAL
@@ -1785,7 +1900,7 @@ typedef MLAN_PACK_START struct _HostCmd_DS_802_11_KEY_MATERIAL
/** Action */
t_u16 action;
/** Key parameter set */
- MrvlIEtype_KeyParamSet_t key_param_set;
+ MrvlIEtype_KeyParamSetV2_t key_param_set;
} MLAN_PACK_END HostCmd_DS_802_11_KEY_MATERIAL;
/** Data structure of WMM QoS information */
@@ -2183,9 +2298,7 @@ typedef MLAN_PACK_START struct _HostCmd_DS_802_11_MAC_ADDRESS
typedef MLAN_PACK_START struct _HostCmd_DS_MAC_CONTROL
{
/** Action */
- t_u16 action;
- /** Reserved field */
- t_u16 reserved;
+ t_u32 action;
} MLAN_PACK_END HostCmd_DS_MAC_CONTROL;
/** HostCmd_DS_CMD_TX_DATA_PAUSE */
@@ -2411,6 +2524,10 @@ typedef MLAN_PACK_START struct _HostCmd_DS_802_11_GET_LOG
t_u32 reserved;
/** Number of WEP icv error for each key */
t_u32 wep_icv_err_cnt[4];
+ /** Beacon received count */
+ t_u32 bcn_rcv_cnt;
+ /** Beacon missed count */
+ t_u32 bcn_miss_cnt;
} MLAN_PACK_END HostCmd_DS_802_11_GET_LOG;
/**_HostCmd_TX_RATE_QUERY */
@@ -3657,6 +3774,15 @@ typedef MLAN_PACK_START struct _HostCmd_DS_HS_WAKEUP_REASON
t_u16 wakeup_reason;
} MLAN_PACK_END HostCmd_DS_HS_WAKEUP_REASON;
+/** MrvlIEtypes_HsWakeHoldoff_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_HsWakeHoldoff_t
+{
+ /** Header */
+ MrvlIEtypesHeader_t header;
+ /** Minimum delay between HsActive and HostWake (in msec) */
+ t_u16 min_wake_holdoff;
+} MLAN_PACK_END MrvlIEtypes_HsWakeHoldoff_t;
+
/** HostCmd_DS_INACTIVITY_TIMEOUT_EXT */
typedef MLAN_PACK_START struct _HostCmd_DS_INACTIVITY_TIMEOUT_EXT
{
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_ieee.h b/drivers/net/wireless/sd8797/mlan/mlan_ieee.h
index 976f1c7013a4..c11c911466e6 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_ieee.h
+++ b/drivers/net/wireless/sd8797/mlan/mlan_ieee.h
@@ -155,6 +155,15 @@ typedef MLAN_PACK_START struct _IEEEtypes_Generic_t
}
MLAN_PACK_END IEEEtypes_Generic_t, *pIEEEtypes_Generic_t;
+/** TLV header */
+typedef MLAN_PACK_START struct _TLV_Generic_t
+{
+ /** Type */
+ t_u16 type;
+ /** Length */
+ t_u16 len;
+} MLAN_PACK_END TLV_Generic_t, *pTLV_Generic_t;
+
/** Capability information mask */
#define CAPINFO_MASK (~(MBIT(15) | MBIT(14) | \
MBIT(12) | MBIT(11) | MBIT(9)))
@@ -305,6 +314,8 @@ typedef t_u16 IEEEtypes_AId_t;
/** IEEEtypes_StatusCode_t */
typedef t_u16 IEEEtypes_StatusCode_t;
+/** Fixed size in assoc_resp */
+#define ASSOC_RESP_FIXED_SIZE 6
/** IEEEtypes_AssocRsp_t */
typedef MLAN_PACK_START struct _IEEEtypes_AssocRsp_t
{
@@ -329,6 +340,20 @@ typedef t_u8 WLAN_802_11_RATES[WLAN_SUPPORTED_RATES];
#define RSN_AKM_8021X 1
/** AKM: PSK */
#define RSN_AKM_PSK 2
+/** AKM: PSK SHA256 */
+#define RSN_AKM_PSK_SHA256 6
+#if defined(STA_SUPPORT)
+/** Pairwise Cipher Suite length */
+#define PAIRWISE_CIPHER_SUITE_LEN 4
+/** AKM Suite length */
+#define AKM_SUITE_LEN 4
+/** MFPC bit in RSN capability */
+#define MFPC_BIT 7
+/** MFPR bit in RSN capability */
+#define MFPR_BIT 6
+/** PMF ORing mask */
+#define PMF_MASK 0x00c0
+#endif
/** wpa_suite_t */
typedef MLAN_PACK_START struct _wpa_suite_t
@@ -800,12 +825,147 @@ typedef struct MLAN_PACK_START _BSSCo2040_t
t_u8 bss_co_2040_value;
} MLAN_PACK_END BSSCo2040_t, *pBSSCo2040_t;
+#ifdef BIG_ENDIAN_SUPPORT
+/** Extended Capabilities Data */
+typedef struct MLAN_PACK_START _ExtCap_t
+{
+ /** Extended Capabilities value */
+ t_u8 rsvdBit63:1; /* bit 63 */
+ t_u8 OperModeNtf:1; /* bit 62 */
+ t_u8 TDLSWildBandwidth:1; /* bit 61 */
+ t_u8 rsvdBit60:1; /* bit 60 */
+ t_u8 rsvdBit59:1; /* bit 59 */
+ t_u8 rsvdBit58:1; /* bit 58 */
+ t_u8 rsvdBit57:1; /* bit 57 */
+ t_u8 rsvdBit56:1; /* bit 56 */
+ t_u8 rsvdBit55:1; /* bit 55 */
+ t_u8 rsvdBit54:1; /* bit 54 */
+ t_u8 rsvdBit53:1; /* bit 53 */
+ t_u8 rsvdBit52:1; /* bit 52 */
+ t_u8 rsvdBit51:1; /* bit 51 */
+ t_u8 rsvdBit50:1; /* bit 50 */
+ t_u8 rsvdBit49:1; /* bit 49 */
+ t_u8 rsvdBit48:1; /* bit 48 */
+ t_u8 rsvdBit47:1; /* bit 47 */
+ t_u8 rsvdBit46:1; /* bit 46 */
+ t_u8 rsvdBit45:1; /* bit 45 */
+ t_u8 rsvdBit44:1; /* bit 44 */
+ t_u8 rsvdBit43:1; /* bit 43 */
+ t_u8 rsvdBit42:1; /* bit 42 */
+ t_u8 rsvdBit41:1; /* bit 41 */
+ t_u8 rsvdBit40:1; /* bit 40 */
+ t_u8 TDLSChlSwitchProhib:1; /* bit 39 */
+ t_u8 TDLSProhibited:1; /* bit 38 */
+ t_u8 TDLSSupport:1; /* bit 37 */
+ t_u8 MSGCF_Capa:1; /* bit 36 */
+ t_u8 Reserved35:1; /* bit 35 */
+ t_u8 SSPN_Interface:1; /* bit 34 */
+ t_u8 EBR:1; /* bit 33 */
+ t_u8 Qos_Map:1; /* bit 32 */
+ t_u8 Interworking:1; /* bit 31 */
+ t_u8 TDLSChannelSwitching:1; /* bit 30 */
+ t_u8 TDLSPeerPSMSupport:1; /* bit 29 */
+ t_u8 TDLSPeerUAPSDSupport:1; /* bit 28 */
+ t_u8 UTC:1; /* bit 27 */
+ t_u8 DMS:1; /* bit 26 */
+ t_u8 SSID_List:1; /* bit 25 */
+ t_u8 ChannelUsage:1; /* bit 24 */
+ t_u8 TimingMeasurement:1; /* bit 23 */
+ t_u8 MultipleBSSID:1; /* bit 22 */
+ t_u8 AC_StationCount:1; /* bit 21 */
+ t_u8 QoSTrafficCap:1; /* bit 20 */
+ t_u8 BSS_Transition:1; /* bit 19 */
+ t_u8 TIM_Broadcast:1; /* bit 18 */
+ t_u8 WNM_Sleep:1; /* bit 17 */
+ t_u8 TFS:1; /* bit 16 */
+ t_u8 GeospatialLocation:1; /* bit 15 */
+ t_u8 CivicLocation:1; /* bit 14 */
+ t_u8 CollocatedIntf:1; /* bit 13 */
+ t_u8 ProxyARPService:1; /* bit 12 */
+ t_u8 FMS:1; /* bit 11 */
+ t_u8 LocationTracking:1; /* bit 10 */
+ t_u8 MulticastDiagnostics:1; /* bit 9 */
+ t_u8 Diagnostics:1; /* bit 8 */
+ t_u8 Event:1; /* bit 7 */
+ t_u8 SPSMP_Support:1; /* bit 6 */
+ t_u8 Reserved5:1; /* bit 5 */
+ t_u8 PSMP_Capable:1; /* bit 4 */
+ t_u8 RejectUnadmFrame:1; /* bit 3 */
+ t_u8 ExtChanSwitching:1; /* bit 2 */
+ t_u8 Reserved1:1; /* bit 1 */
+ t_u8 BSS_CoexistSupport:1; /* bit 0 */
+} MLAN_PACK_END ExtCap_t, *pExtCap_t;
+#else
/** Extended Capabilities Data */
typedef struct MLAN_PACK_START _ExtCap_t
{
/** Extended Capabilities value */
- t_u8 ext_cap_value;
+ t_u8 BSS_CoexistSupport:1; /* bit 0 */
+ t_u8 Reserved1:1; /* bit 1 */
+ t_u8 ExtChanSwitching:1; /* bit 2 */
+ t_u8 RejectUnadmFrame:1; /* bit 3 */
+ t_u8 PSMP_Capable:1; /* bit 4 */
+ t_u8 Reserved5:1; /* bit 5 */
+ t_u8 SPSMP_Support:1; /* bit 6 */
+ t_u8 Event:1; /* bit 7 */
+ t_u8 Diagnostics:1; /* bit 8 */
+ t_u8 MulticastDiagnostics:1; /* bit 9 */
+ t_u8 LocationTracking:1; /* bit 10 */
+ t_u8 FMS:1; /* bit 11 */
+ t_u8 ProxyARPService:1; /* bit 12 */
+ t_u8 CollocatedIntf:1; /* bit 13 */
+ t_u8 CivicLocation:1; /* bit 14 */
+ t_u8 GeospatialLocation:1; /* bit 15 */
+ t_u8 TFS:1; /* bit 16 */
+ t_u8 WNM_Sleep:1; /* bit 17 */
+ t_u8 TIM_Broadcast:1; /* bit 18 */
+ t_u8 BSS_Transition:1; /* bit 19 */
+ t_u8 QoSTrafficCap:1; /* bit 20 */
+ t_u8 AC_StationCount:1; /* bit 21 */
+ t_u8 MultipleBSSID:1; /* bit 22 */
+ t_u8 TimingMeasurement:1; /* bit 23 */
+ t_u8 ChannelUsage:1; /* bit 24 */
+ t_u8 SSID_List:1; /* bit 25 */
+ t_u8 DMS:1; /* bit 26 */
+ t_u8 UTC:1; /* bit 27 */
+ t_u8 TDLSPeerUAPSDSupport:1; /* bit 28 */
+ t_u8 TDLSPeerPSMSupport:1; /* bit 29 */
+ t_u8 TDLSChannelSwitching:1; /* bit 30 */
+ t_u8 Interworking:1; /* bit 31 */
+ t_u8 Qos_Map:1; /* bit 32 */
+ t_u8 EBR:1; /* bit 33 */
+ t_u8 SSPN_Interface:1; /* bit 34 */
+ t_u8 Reserved35:1; /* bit 35 */
+ t_u8 MSGCF_Capa:1; /* bit 36 */
+ t_u8 TDLSSupport:1; /* bit 37 */
+ t_u8 TDLSProhibited:1; /* bit 38 */
+ t_u8 TDLSChlSwitchProhib:1; /* bit 39 */
+ t_u8 rsvdBit40:1; /* bit 40 */
+ t_u8 rsvdBit41:1; /* bit 41 */
+ t_u8 rsvdBit42:1; /* bit 42 */
+ t_u8 rsvdBit43:1; /* bit 43 */
+ t_u8 rsvdBit44:1; /* bit 44 */
+ t_u8 rsvdBit45:1; /* bit 45 */
+ t_u8 rsvdBit46:1; /* bit 46 */
+ t_u8 rsvdBit47:1; /* bit 47 */
+ t_u8 rsvdBit48:1; /* bit 48 */
+ t_u8 rsvdBit49:1; /* bit 49 */
+ t_u8 rsvdBit50:1; /* bit 50 */
+ t_u8 rsvdBit51:1; /* bit 51 */
+ t_u8 rsvdBit52:1; /* bit 52 */
+ t_u8 rsvdBit53:1; /* bit 53 */
+ t_u8 rsvdBit54:1; /* bit 54 */
+ t_u8 rsvdBit55:1; /* bit 55 */
+ t_u8 rsvdBit56:1; /* bit 56 */
+ t_u8 rsvdBit57:1; /* bit 57 */
+ t_u8 rsvdBit58:1; /* bit 58 */
+ t_u8 rsvdBit59:1; /* bit 59 */
+ t_u8 rsvdBit60:1; /* bit 60 */
+ t_u8 TDLSWildBandwidth:1; /* bit 61 */
+ t_u8 OperModeNtf:1; /* bit 62 */
+ t_u8 rsvdBit63:1; /* bit 63 */
} MLAN_PACK_END ExtCap_t, *pExtCap_t;
+#endif
/** Overlapping BSS Scan Parameters Data */
typedef struct MLAN_PACK_START _OverlapBSSScanParam_t
@@ -1149,7 +1309,7 @@ typedef MLAN_PACK_START struct
/** ssid match and RSSI exceeded */
#define BG_SCAN_SSID_RSSI_MATCH 0x0004
/** Maximum number of channels that can be sent in bg scan config */
-#define WLAN_BG_SCAN_CHAN_MAX 32
+#define WLAN_BG_SCAN_CHAN_MAX 38
/**
* Input structure to configure bs scan cmd to firmware
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_init.c b/drivers/net/wireless/sd8797/mlan/mlan_init.c
index 33357e3d75f9..09628b3fc683 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_init.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_init.c
@@ -169,10 +169,15 @@ wlan_allocate_adapter(pmlan_adapter pmadapter)
#ifdef STA_SUPPORT
/* Allocate buffer to store the BSSID list */
buf_size = sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST;
- ret =
- pmadapter->callbacks.moal_malloc(pmadapter->pmoal_handle, buf_size,
- MLAN_MEM_DEF,
- (t_u8 **) & ptemp_scan_table);
+ if (pmadapter->callbacks.moal_vmalloc && pmadapter->callbacks.moal_vfree)
+ ret =
+ pmadapter->callbacks.moal_vmalloc(pmadapter->pmoal_handle, buf_size,
+ (t_u8 **) & ptemp_scan_table);
+ else
+ ret =
+ pmadapter->callbacks.moal_malloc(pmadapter->pmoal_handle, buf_size,
+ MLAN_MEM_DEF,
+ (t_u8 **) & ptemp_scan_table);
if (ret != MLAN_STATUS_SUCCESS || !ptemp_scan_table) {
PRINTM(MERROR, "Failed to allocate scan table\n");
LEAVE();
@@ -281,7 +286,7 @@ wlan_init_priv(pmlan_private priv)
wlan_11d_priv_init(priv);
wlan_11h_priv_init(priv);
-#if defined(UAP_SUPPORT)
+#ifdef UAP_SUPPORT
priv->uap_bss_started = MFALSE;
memset(pmadapter, &priv->uap_state_chan_cb, 0,
sizeof(priv->uap_state_chan_cb));
@@ -320,6 +325,10 @@ wlan_init_priv(pmlan_private priv)
memset(pmadapter, &priv->aes_key, 0, sizeof(priv->aes_key));
priv->wpa_ie_len = 0;
priv->wpa_is_gtk_set = MFALSE;
+#if defined(STA_SUPPORT)
+ priv->pmfcfg.mfpc = 0;
+ priv->pmfcfg.mfpr = 0;
+#endif
priv->sec_info.wapi_enabled = MFALSE;
priv->wapi_ie_len = 0;
priv->sec_info.wapi_key_on = MFALSE;
@@ -336,6 +345,7 @@ wlan_init_priv(pmlan_private priv)
#ifdef STA_SUPPORT
priv->pcurr_bcn_buf = MNULL;
priv->curr_bcn_size = 0;
+ memset(pmadapter, &priv->ext_cap, 0, sizeof(priv->ext_cap));
#endif /* STA_SUPPORT */
for (i = 0; i < MAX_NUM_TID; i++)
@@ -367,7 +377,6 @@ t_void
wlan_init_adapter(pmlan_adapter pmadapter)
{
opt_sleep_confirm_buffer *sleep_cfm_buf = MNULL;
-
ENTER();
sleep_cfm_buf = (opt_sleep_confirm_buffer *) (pmadapter->psleep_cfm->pbuf +
@@ -508,6 +517,7 @@ wlan_init_adapter(pmlan_adapter pmadapter)
pmadapter->hs_cfg.gpio = HOST_SLEEP_DEF_GPIO;
pmadapter->hs_cfg.gap = HOST_SLEEP_DEF_GAP;
pmadapter->hs_activated = MFALSE;
+ pmadapter->min_wake_holdoff = HOST_SLEEP_DEF_WAKE_HOLDOFF;
memset(pmadapter, pmadapter->event_body, 0, sizeof(pmadapter->event_body));
pmadapter->hw_dot_11n_dev_cap = 0;
@@ -526,7 +536,7 @@ wlan_init_adapter(pmlan_adapter pmadapter)
wlan_11h_init(pmadapter);
wlan_wmm_init(pmadapter);
-
+ pmadapter->bypass_pkt_count = 0;
if (pmadapter->psleep_cfm) {
pmadapter->psleep_cfm->buf_type = MLAN_BUF_TYPE_CMD;
pmadapter->psleep_cfm->data_len = sizeof(OPT_Confirm_Sleep);
@@ -642,10 +652,6 @@ wlan_init_lock_list(IN pmlan_adapter pmadapter)
}
}
- /* Initialize bypass_txq */
- util_init_list_head((t_void *) pmadapter->pmoal_handle,
- &pmadapter->bypass_txq, MTRUE,
- pmadapter->callbacks.moal_init_lock);
/* Initialize cmd_free_q */
util_init_list_head((t_void *) pmadapter->pmoal_handle,
&pmadapter->cmd_free_q, MTRUE,
@@ -691,6 +697,10 @@ wlan_init_lock_list(IN pmlan_adapter pmadapter)
util_init_list_head((t_void *) pmadapter->pmoal_handle,
&priv->sta_list, MTRUE,
pmadapter->callbacks.moal_init_lock);
+ /* Initialize bypass_txq */
+ util_init_list_head((t_void *) pmadapter->pmoal_handle,
+ &priv->bypass_txq, MTRUE,
+ pmadapter->callbacks.moal_init_lock);
}
}
@@ -745,9 +755,6 @@ wlan_free_lock_list(IN pmlan_adapter pmadapter)
/* Free lists */
util_free_list_head((t_void *) pmadapter->pmoal_handle,
- &pmadapter->bypass_txq,
- pmadapter->callbacks.moal_free_lock);
- util_free_list_head((t_void *) pmadapter->pmoal_handle,
&pmadapter->cmd_free_q,
pmadapter->callbacks.moal_free_lock);
@@ -770,6 +777,9 @@ wlan_free_lock_list(IN pmlan_adapter pmadapter)
util_free_list_head((t_void *) pmadapter->pmoal_handle,
&priv->sta_list,
priv->adapter->callbacks.moal_free_lock);
+ util_free_list_head((t_void *) pmadapter->pmoal_handle,
+ &priv->bypass_txq,
+ pmadapter->callbacks.moal_free_lock);
for (j = 0; j < MAX_NUM_TID; ++j)
util_free_list_head((t_void *) priv->adapter->pmoal_handle,
@@ -808,7 +818,6 @@ wlan_init_timer(IN pmlan_adapter pmadapter)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
-
ENTER();
if (pcb->
@@ -835,7 +844,6 @@ t_void
wlan_free_timer(IN pmlan_adapter pmadapter)
{
pmlan_callbacks pcb = &pmadapter->callbacks;
-
ENTER();
if (pmadapter->pmlan_cmd_timer)
@@ -917,7 +925,6 @@ t_void
wlan_free_adapter(pmlan_adapter pmadapter)
{
mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
-
ENTER();
if (!pmadapter) {
@@ -940,8 +947,12 @@ wlan_free_adapter(pmlan_adapter pmadapter)
#ifdef STA_SUPPORT
PRINTM(MINFO, "Free ScanTable\n");
if (pmadapter->pscan_table) {
- pcb->moal_mfree(pmadapter->pmoal_handle,
- (t_u8 *) pmadapter->pscan_table);
+ if (pcb->moal_vmalloc && pcb->moal_vfree) {
+ pcb->moal_vfree(pmadapter->pmoal_handle,
+ (t_u8 *) pmadapter->pscan_table);
+ } else
+ pcb->moal_mfree(pmadapter->pmoal_handle,
+ (t_u8 *) pmadapter->pscan_table);
pmadapter->pscan_table = MNULL;
}
if (pmadapter->bcn_buf) {
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_ioctl.h b/drivers/net/wireless/sd8797/mlan/mlan_ioctl.h
index 7cfc344bf0d4..606d161737f9 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_ioctl.h
+++ b/drivers/net/wireless/sd8797/mlan/mlan_ioctl.h
@@ -31,196 +31,204 @@ enum _mlan_ioctl_req_id
{
/* Scan Group */
MLAN_IOCTL_SCAN = 0x00010000,
- MLAN_OID_SCAN_NORMAL,
- MLAN_OID_SCAN_SPECIFIC_SSID,
- MLAN_OID_SCAN_USER_CONFIG,
- MLAN_OID_SCAN_CONFIG,
- MLAN_OID_SCAN_GET_CURRENT_BSS,
- MLAN_OID_SCAN_CANCEL,
- MLAN_OID_SCAN_TABLE_FLUSH,
- MLAN_OID_SCAN_BGSCAN_CONFIG,
+ MLAN_OID_SCAN_NORMAL = 0x00010001,
+ MLAN_OID_SCAN_SPECIFIC_SSID = 0x00010002,
+ MLAN_OID_SCAN_USER_CONFIG = 0x00010003,
+ MLAN_OID_SCAN_CONFIG = 0x00010004,
+ MLAN_OID_SCAN_GET_CURRENT_BSS = 0x00010005,
+ MLAN_OID_SCAN_CANCEL = 0x00010006,
+ MLAN_OID_SCAN_TABLE_FLUSH = 0x0001000A,
+ MLAN_OID_SCAN_BGSCAN_CONFIG = 0x0001000B,
/* BSS Configuration Group */
MLAN_IOCTL_BSS = 0x00020000,
- MLAN_OID_BSS_START,
- MLAN_OID_BSS_STOP,
- MLAN_OID_BSS_MODE,
- MLAN_OID_BSS_CHANNEL,
- MLAN_OID_BSS_CHANNEL_LIST,
- MLAN_OID_BSS_MAC_ADDR,
- MLAN_OID_BSS_MULTICAST_LIST,
- MLAN_OID_BSS_FIND_BSS,
- MLAN_OID_IBSS_BCN_INTERVAL,
- MLAN_OID_IBSS_ATIM_WINDOW,
- MLAN_OID_IBSS_CHANNEL,
+ MLAN_OID_BSS_START = 0x00020001,
+ MLAN_OID_BSS_STOP = 0x00020002,
+ MLAN_OID_BSS_MODE = 0x00020003,
+ MLAN_OID_BSS_CHANNEL = 0x00020004,
+ MLAN_OID_BSS_CHANNEL_LIST = 0x00020005,
+ MLAN_OID_BSS_MAC_ADDR = 0x00020006,
+ MLAN_OID_BSS_MULTICAST_LIST = 0x00020007,
+ MLAN_OID_BSS_FIND_BSS = 0x00020008,
+ MLAN_OID_IBSS_BCN_INTERVAL = 0x00020009,
+ MLAN_OID_IBSS_ATIM_WINDOW = 0x0002000A,
+ MLAN_OID_IBSS_CHANNEL = 0x0002000B,
#ifdef UAP_SUPPORT
- MLAN_OID_UAP_BSS_CONFIG,
- MLAN_OID_UAP_DEAUTH_STA,
- MLAN_OID_UAP_BSS_RESET,
+ MLAN_OID_UAP_BSS_CONFIG = 0x0002000C,
+ MLAN_OID_UAP_DEAUTH_STA = 0x0002000D,
+ MLAN_OID_UAP_BSS_RESET = 0x0002000E,
#endif
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
- MLAN_OID_BSS_ROLE,
+ MLAN_OID_BSS_ROLE = 0x0002000F,
#endif
#ifdef WIFI_DIRECT_SUPPORT
- MLAN_OID_WIFI_DIRECT_MODE,
+ MLAN_OID_WIFI_DIRECT_MODE = 0x00020010,
#endif
#ifdef STA_SUPPORT
- MLAN_OID_BSS_LISTEN_INTERVAL,
+ MLAN_OID_BSS_LISTEN_INTERVAL = 0x00020011,
#endif
+ MLAN_OID_BSS_REMOVE = 0x00020014,
/* Radio Configuration Group */
MLAN_IOCTL_RADIO_CFG = 0x00030000,
- MLAN_OID_RADIO_CTRL,
- MLAN_OID_BAND_CFG,
- MLAN_OID_ANT_CFG,
+ MLAN_OID_RADIO_CTRL = 0x00030001,
+ MLAN_OID_BAND_CFG = 0x00030002,
+ MLAN_OID_ANT_CFG = 0x00030003,
#ifdef WIFI_DIRECT_SUPPORT
- MLAN_OID_REMAIN_CHAN_CFG,
+ MLAN_OID_REMAIN_CHAN_CFG = 0x00030004,
#endif
/* SNMP MIB Group */
MLAN_IOCTL_SNMP_MIB = 0x00040000,
- MLAN_OID_SNMP_MIB_RTS_THRESHOLD,
- MLAN_OID_SNMP_MIB_FRAG_THRESHOLD,
- MLAN_OID_SNMP_MIB_RETRY_COUNT,
+ MLAN_OID_SNMP_MIB_RTS_THRESHOLD = 0x00040001,
+ MLAN_OID_SNMP_MIB_FRAG_THRESHOLD = 0x00040002,
+ MLAN_OID_SNMP_MIB_RETRY_COUNT = 0x00040003,
#if defined(UAP_SUPPORT)
- MLAN_OID_SNMP_MIB_DOT11D,
- MLAN_OID_SNMP_MIB_DOT11H,
+ MLAN_OID_SNMP_MIB_DOT11D = 0x00040004,
+ MLAN_OID_SNMP_MIB_DOT11H = 0x00040005,
#endif
- MLAN_OID_SNMP_MIB_DTIM_PERIOD,
+ MLAN_OID_SNMP_MIB_DTIM_PERIOD = 0x00040006,
/* Status Information Group */
MLAN_IOCTL_GET_INFO = 0x00050000,
- MLAN_OID_GET_STATS,
- MLAN_OID_GET_SIGNAL,
- MLAN_OID_GET_FW_INFO,
- MLAN_OID_GET_VER_EXT,
- MLAN_OID_GET_BSS_INFO,
- MLAN_OID_GET_DEBUG_INFO,
+ MLAN_OID_GET_STATS = 0x00050001,
+ MLAN_OID_GET_SIGNAL = 0x00050002,
+ MLAN_OID_GET_FW_INFO = 0x00050003,
+ MLAN_OID_GET_VER_EXT = 0x00050004,
+ MLAN_OID_GET_BSS_INFO = 0x00050005,
+ MLAN_OID_GET_DEBUG_INFO = 0x00050006,
#ifdef UAP_SUPPORT
- MLAN_OID_UAP_STA_LIST,
+ MLAN_OID_UAP_STA_LIST = 0x00050007,
#endif
/* Security Configuration Group */
MLAN_IOCTL_SEC_CFG = 0x00060000,
- MLAN_OID_SEC_CFG_AUTH_MODE,
- MLAN_OID_SEC_CFG_ENCRYPT_MODE,
- MLAN_OID_SEC_CFG_WPA_ENABLED,
- MLAN_OID_SEC_CFG_ENCRYPT_KEY,
- MLAN_OID_SEC_CFG_PASSPHRASE,
- MLAN_OID_SEC_CFG_EWPA_ENABLED,
- MLAN_OID_SEC_CFG_ESUPP_MODE,
- MLAN_OID_SEC_CFG_WAPI_ENABLED,
- MLAN_OID_SEC_CFG_PORT_CTRL_ENABLED,
+ MLAN_OID_SEC_CFG_AUTH_MODE = 0x00060001,
+ MLAN_OID_SEC_CFG_ENCRYPT_MODE = 0x00060002,
+ MLAN_OID_SEC_CFG_WPA_ENABLED = 0x00060003,
+ MLAN_OID_SEC_CFG_ENCRYPT_KEY = 0x00060004,
+ MLAN_OID_SEC_CFG_PASSPHRASE = 0x00060005,
+ MLAN_OID_SEC_CFG_EWPA_ENABLED = 0x00060006,
+ MLAN_OID_SEC_CFG_ESUPP_MODE = 0x00060007,
+ MLAN_OID_SEC_CFG_WAPI_ENABLED = 0x00060009,
+ MLAN_OID_SEC_CFG_PORT_CTRL_ENABLED = 0x0006000A,
/* Rate Group */
MLAN_IOCTL_RATE = 0x00070000,
- MLAN_OID_RATE_CFG,
- MLAN_OID_GET_DATA_RATE,
- MLAN_OID_SUPPORTED_RATES,
+ MLAN_OID_RATE_CFG = 0x00070001,
+ MLAN_OID_GET_DATA_RATE = 0x00070002,
+ MLAN_OID_SUPPORTED_RATES = 0x00070003,
/* Power Configuration Group */
MLAN_IOCTL_POWER_CFG = 0x00080000,
- MLAN_OID_POWER_CFG,
- MLAN_OID_POWER_CFG_EXT,
+ MLAN_OID_POWER_CFG = 0x00080001,
+ MLAN_OID_POWER_CFG_EXT = 0x00080002,
/* Power Management Configuration Group */
MLAN_IOCTL_PM_CFG = 0x00090000,
- MLAN_OID_PM_CFG_IEEE_PS,
- MLAN_OID_PM_CFG_HS_CFG,
- MLAN_OID_PM_CFG_INACTIVITY_TO,
- MLAN_OID_PM_CFG_DEEP_SLEEP,
- MLAN_OID_PM_CFG_SLEEP_PD,
- MLAN_OID_PM_CFG_PS_CFG,
- MLAN_OID_PM_CFG_SLEEP_PARAMS,
+ MLAN_OID_PM_CFG_IEEE_PS = 0x00090001,
+ MLAN_OID_PM_CFG_HS_CFG = 0x00090002,
+ MLAN_OID_PM_CFG_INACTIVITY_TO = 0x00090003,
+ MLAN_OID_PM_CFG_DEEP_SLEEP = 0x00090004,
+ MLAN_OID_PM_CFG_SLEEP_PD = 0x00090005,
+ MLAN_OID_PM_CFG_PS_CFG = 0x00090006,
+ MLAN_OID_PM_CFG_SLEEP_PARAMS = 0x00090008,
#ifdef UAP_SUPPORT
- MLAN_OID_PM_CFG_PS_MODE,
+ MLAN_OID_PM_CFG_PS_MODE = 0x00090009,
#endif /* UAP_SUPPORT */
- MLAN_OID_PM_INFO,
- MLAN_OID_PM_HS_WAKEUP_REASON,
+ MLAN_OID_PM_INFO = 0x0009000A,
+ MLAN_OID_PM_HS_WAKEUP_REASON = 0x0009000B,
/* WMM Configuration Group */
MLAN_IOCTL_WMM_CFG = 0x000A0000,
- MLAN_OID_WMM_CFG_ENABLE,
- MLAN_OID_WMM_CFG_QOS,
- MLAN_OID_WMM_CFG_ADDTS,
- MLAN_OID_WMM_CFG_DELTS,
- MLAN_OID_WMM_CFG_QUEUE_CONFIG,
- MLAN_OID_WMM_CFG_QUEUE_STATS,
- MLAN_OID_WMM_CFG_QUEUE_STATUS,
- MLAN_OID_WMM_CFG_TS_STATUS,
+ MLAN_OID_WMM_CFG_ENABLE = 0x000A0001,
+ MLAN_OID_WMM_CFG_QOS = 0x000A0002,
+ MLAN_OID_WMM_CFG_ADDTS = 0x000A0003,
+ MLAN_OID_WMM_CFG_DELTS = 0x000A0004,
+ MLAN_OID_WMM_CFG_QUEUE_CONFIG = 0x000A0005,
+ MLAN_OID_WMM_CFG_QUEUE_STATS = 0x000A0006,
+ MLAN_OID_WMM_CFG_QUEUE_STATUS = 0x000A0007,
+ MLAN_OID_WMM_CFG_TS_STATUS = 0x000A0008,
/* WPS Configuration Group */
MLAN_IOCTL_WPS_CFG = 0x000B0000,
- MLAN_OID_WPS_CFG_SESSION,
+ MLAN_OID_WPS_CFG_SESSION = 0x000B0001,
/* 802.11n Configuration Group */
MLAN_IOCTL_11N_CFG = 0x000C0000,
- MLAN_OID_11N_CFG_TX,
- MLAN_OID_11N_HTCAP_CFG,
- MLAN_OID_11N_CFG_ADDBA_REJECT,
- MLAN_OID_11N_CFG_AGGR_PRIO_TBL,
- MLAN_OID_11N_CFG_ADDBA_PARAM,
- MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE,
- MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL,
- MLAN_OID_11N_CFG_SUPPORTED_MCS_SET,
- MLAN_OID_11N_CFG_TX_BF_CAP,
- MLAN_OID_11N_CFG_TX_BF_CFG,
- MLAN_OID_11N_CFG_STREAM_CFG,
- MLAN_OID_11N_CFG_DELBA,
- MLAN_OID_11N_CFG_REJECT_ADDBA_REQ,
+ MLAN_OID_11N_CFG_TX = 0x000C0001,
+ MLAN_OID_11N_HTCAP_CFG = 0x000C0002,
+ MLAN_OID_11N_CFG_ADDBA_REJECT = 0x000C0003,
+ MLAN_OID_11N_CFG_AGGR_PRIO_TBL = 0x000C0004,
+ MLAN_OID_11N_CFG_ADDBA_PARAM = 0x000C0005,
+ MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE = 0x000C0006,
+ MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL = 0x000C0007,
+ MLAN_OID_11N_CFG_SUPPORTED_MCS_SET = 0x000C0008,
+ MLAN_OID_11N_CFG_TX_BF_CAP = 0x000C0009,
+ MLAN_OID_11N_CFG_TX_BF_CFG = 0x000C000A,
+ MLAN_OID_11N_CFG_STREAM_CFG = 0x000C000B,
+ MLAN_OID_11N_CFG_DELBA = 0x000C000C,
+ MLAN_OID_11N_CFG_REJECT_ADDBA_REQ = 0x000C000D,
/* 802.11d Configuration Group */
MLAN_IOCTL_11D_CFG = 0x000D0000,
#ifdef STA_SUPPORT
- MLAN_OID_11D_CFG_ENABLE,
- MLAN_OID_11D_CLR_CHAN_TABLE,
+ MLAN_OID_11D_CFG_ENABLE = 0x000D0001,
+ MLAN_OID_11D_CLR_CHAN_TABLE = 0x000D0002,
#endif /* STA_SUPPORT */
- MLAN_OID_11D_DOMAIN_INFO,
+ MLAN_OID_11D_DOMAIN_INFO = 0x000D0003,
/* Register Memory Access Group */
MLAN_IOCTL_REG_MEM = 0x000E0000,
- MLAN_OID_REG_RW,
- MLAN_OID_EEPROM_RD,
- MLAN_OID_MEM_RW,
+ MLAN_OID_REG_RW = 0x000E0001,
+ MLAN_OID_EEPROM_RD = 0x000E0002,
+ MLAN_OID_MEM_RW = 0x000E0003,
/* Multi-Radio Configuration Group */
MLAN_IOCTL_MFR_CFG = 0x00100000,
/* 802.11h Configuration Group */
MLAN_IOCTL_11H_CFG = 0x00110000,
- MLAN_OID_11H_CHANNEL_CHECK,
- MLAN_OID_11H_LOCAL_POWER_CONSTRAINT,
+ MLAN_OID_11H_CHANNEL_CHECK = 0x00110001,
+ MLAN_OID_11H_LOCAL_POWER_CONSTRAINT = 0x00110002,
#if defined(DFS_TESTING_SUPPORT)
- MLAN_OID_11H_DFS_TESTING,
+ MLAN_OID_11H_DFS_TESTING = 0x00110003,
#endif
/* Miscellaneous Configuration Group */
MLAN_IOCTL_MISC_CFG = 0x00200000,
- MLAN_OID_MISC_GEN_IE,
- MLAN_OID_MISC_REGION,
- MLAN_OID_MISC_WARM_RESET,
+ MLAN_OID_MISC_GEN_IE = 0x00200001,
+ MLAN_OID_MISC_REGION = 0x00200002,
+ MLAN_OID_MISC_WARM_RESET = 0x00200003,
#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
- MLAN_OID_MISC_SDIO_MPA_CTRL,
+ MLAN_OID_MISC_SDIO_MPA_CTRL = 0x00200006,
#endif
- MLAN_OID_MISC_HOST_CMD,
- MLAN_OID_MISC_SYS_CLOCK,
- MLAN_OID_MISC_SOFT_RESET,
- MLAN_OID_MISC_WWS,
- MLAN_OID_MISC_INIT_SHUTDOWN,
- MLAN_OID_MISC_CUSTOM_IE,
- MLAN_OID_MISC_TX_DATAPAUSE,
- MLAN_OID_MISC_IP_ADDR,
- MLAN_OID_MISC_MAC_CONTROL,
- MLAN_OID_MISC_MEF_CFG,
- MLAN_OID_MISC_CFP_CODE,
- MLAN_OID_MISC_COUNTRY_CODE,
- MLAN_OID_MISC_THERMAL,
- MLAN_OID_MISC_RX_MGMT_IND,
- MLAN_OID_MISC_SUBSCRIBE_EVENT,
+ MLAN_OID_MISC_HOST_CMD = 0x00200007,
+ MLAN_OID_MISC_SYS_CLOCK = 0x00200009,
+ MLAN_OID_MISC_SOFT_RESET = 0x0020000A,
+ MLAN_OID_MISC_WWS = 0x0020000B,
+ MLAN_OID_MISC_ASSOC_RSP = 0x0020000C,
+ MLAN_OID_MISC_INIT_SHUTDOWN = 0x0020000D,
+ MLAN_OID_MISC_CUSTOM_IE = 0x0020000F,
+ MLAN_OID_MISC_TX_DATAPAUSE = 0x00200012,
+ MLAN_OID_MISC_IP_ADDR = 0x00200013,
+ MLAN_OID_MISC_MAC_CONTROL = 0x00200014,
+ MLAN_OID_MISC_MEF_CFG = 0x00200015,
+ MLAN_OID_MISC_CFP_CODE = 0x00200016,
+ MLAN_OID_MISC_COUNTRY_CODE = 0x00200017,
+ MLAN_OID_MISC_THERMAL = 0x00200018,
+ MLAN_OID_MISC_RX_MGMT_IND = 0x00200019,
+ MLAN_OID_MISC_SUBSCRIBE_EVENT = 0x0020001A,
#ifdef DEBUG_LEVEL1
- MLAN_OID_MISC_DRVDBG,
+ MLAN_OID_MISC_DRVDBG = 0x0020001B,
+#endif
+ MLAN_OID_MISC_OTP_USER_DATA = 0x0020001D,
+ MLAN_OID_MISC_TXCONTROL = 0x00200020,
+#ifdef STA_SUPPORT
+ MLAN_OID_MISC_EXT_CAP_CFG = 0x00200021,
+#endif
+#if defined(STA_SUPPORT)
+ MLAN_OID_MISC_PMFCFG = 0x00200022,
#endif
- MLAN_OID_MISC_OTP_USER_DATA,
- MLAN_OID_MISC_TXCONTROL,
};
/** Sub command size */
@@ -520,6 +528,8 @@ typedef struct _mlan_ssid_bssid
mlan_802_11_mac_addr bssid;
/** index in BSSID list, start from 1 */
t_u32 idx;
+ /** Receive signal strength in dBm */
+ t_s32 rssi;
} mlan_ssid_bssid;
#ifdef UAP_SUPPORT
@@ -610,6 +620,8 @@ typedef struct _mlan_ssid_bssid
#define KEY_MGMT_PSK 0x02
/** Key_mgmt_eap */
#define KEY_MGMT_EAP 0x01
+/** Key_mgmt_psk_sha256 */
+#define KEY_MGMT_PSK_SHA256 0x100
/** TKIP */
#define CIPHER_TKIP 0x04
@@ -978,6 +990,11 @@ enum _mlan_band_def
#define CHANNEL_BW_40MHZ_ABOVE 1
#define CHANNEL_BW_40MHZ_BELOW 3
+/** RF antenna selection */
+#define RF_ANTENNA_MASK(n) ((1<<(n))-1)
+/** RF antenna auto select */
+#define RF_ANTENNA_AUTO 0xFFFF
+
/** Type definition of mlan_ds_band_cfg for MLAN_OID_BAND_CFG */
typedef struct _mlan_ds_band_cfg
{
@@ -1110,6 +1127,10 @@ typedef struct _mlan_ds_get_stats
t_u32 tx_frame;
/** WEP ICV error count */
t_u32 wep_icv_error[4];
+ /** beacon recv count */
+ t_u32 bcn_rcv_cnt;
+ /** beacon miss count */
+ t_u32 bcn_miss_cnt;
} mlan_ds_get_stats, *pmlan_ds_get_stats;
/** Type definition of mlan_ds_uap_stats for MLAN_OID_GET_STATS */
@@ -1340,7 +1361,7 @@ typedef struct
} tx_ba_stream_tbl;
/** Debug command number */
-#define DBG_CMD_NUM 5
+#define DBG_CMD_NUM 10
/** mlan_debug_info data structure for MLAN_OID_GET_DEBUG_INFO */
typedef struct _mlan_debug_info
@@ -1393,6 +1414,8 @@ typedef struct _mlan_debug_info
t_u8 tx_lock_flag;
/** Corresponds to port_open member of mlan_private */
t_u8 port_open;
+ /** bypass pkt count */
+ t_u16 bypass_pkt_count;
/** Corresponds to scan_processing member of mlan_adapter */
t_u32 scan_processing;
/** Number of host to card command failures */
@@ -1443,7 +1466,8 @@ typedef struct _mlan_debug_info
t_u16 last_event[DBG_CMD_NUM];
/** Last event index */
t_u16 last_event_index;
-
+ /** Number of no free command node */
+ t_u16 num_no_cmd_node;
/** Corresponds to data_sent member of mlan_adapter */
t_u8 data_sent;
/** Corresponds to cmd_sent member of mlan_adapter */
@@ -1716,7 +1740,8 @@ typedef struct _mlan_ds_sec_cfg
enum _mlan_rate_type
{
MLAN_RATE_INDEX,
- MLAN_RATE_VALUE
+ MLAN_RATE_VALUE,
+ MLAN_RATE_BITMAP
};
/** Enumeration for rate format */
@@ -1734,7 +1759,7 @@ typedef struct _mlan_rate_cfg_t
{
/** Fixed rate: 0, auto rate: 1 */
t_u32 is_rate_auto;
- /** Rate type. 0: index; 1: valude */
+ /** Rate type. 0: index; 1: value; 2: bitmap */
t_u32 rate_type;
/** Rate/MCS index or rate value if fixed rate */
t_u32 rate;
@@ -1858,6 +1883,8 @@ typedef struct _mlan_ds_power_cfg
#define HOST_SLEEP_COND_MAC_EVENT MBIT(2)
/** Host sleep config condition: multicast data */
#define HOST_SLEEP_COND_MULTICAST_DATA MBIT(3)
+/** Host sleep config condition: IPV6 packet */
+#define HOST_SLEEP_COND_IPV6_PACKET MBIT(31)
/** Host sleep config conditions: Default */
#define HOST_SLEEP_DEF_COND (HOST_SLEEP_COND_BROADCAST_DATA | HOST_SLEEP_COND_UNICAST_DATA | HOST_SLEEP_COND_MAC_EVENT)
@@ -1865,6 +1892,8 @@ typedef struct _mlan_ds_power_cfg
#define HOST_SLEEP_DEF_GPIO 0xff
/** Host sleep config gap : Default */
#define HOST_SLEEP_DEF_GAP 200
+/** Host sleep config min wake holdoff */
+#define HOST_SLEEP_DEF_WAKE_HOLDOFF 0;
/** Type definition of mlan_ds_hs_cfg for MLAN_OID_PM_CFG_HS_CFG */
typedef struct _mlan_ds_hs_cfg
@@ -2807,6 +2836,18 @@ typedef struct _mlan_ds_misc_sys_clock
t_u16 sys_clk[MLAN_MAX_CLK_NUM];
} mlan_ds_misc_sys_clock;
+/** Maximum response buffer length */
+#define ASSOC_RSP_BUF_SIZE 500
+
+/** Type definition of mlan_ds_misc_assoc_rsp for MLAN_OID_MISC_ASSOC_RSP */
+typedef struct _mlan_ds_misc_assoc_rsp
+{
+ /** Associate response buffer */
+ t_u8 assoc_resp_buf[ASSOC_RSP_BUF_SIZE];
+ /** Response buffer length */
+ t_u32 assoc_resp_len;
+} mlan_ds_misc_assoc_rsp;
+
/** Enumeration for function init/shutdown */
enum _mlan_func_cmd
{
@@ -2827,6 +2868,8 @@ typedef struct _mlan_ds_misc_tx_datapause
#define IPADDR_LEN (16)
/** Max number of ip */
#define MAX_IPADDR (4)
+/** IP address type - NONE*/
+#define IPADDR_TYPE_NONE (0)
/** IP address type - IPv4*/
#define IPADDR_TYPE_IPV4 (1)
/** IP operation remove */
@@ -2887,6 +2930,10 @@ typedef struct _mlan_ds_misc_country_code
t_u8 country_code[COUNTRY_CODE_LEN];
} mlan_ds_misc_country_code;
+/** action for set */
+#define SUBSCRIBE_EVT_ACT_BITWISE_SET 0x0002
+/** action for clear */
+#define SUBSCRIBE_EVT_ACT_BITWISE_CLR 0x0003
/** BITMAP for subscribe event rssi low */
#define SUBSCRIBE_EVT_RSSI_LOW MBIT(0)
/** BITMAP for subscribe event snr low */
@@ -2917,6 +2964,8 @@ typedef struct _mlan_ds_misc_country_code
/** Type definition of mlan_ds_subscribe_evt for MLAN_OID_MISC_CFP_CODE */
typedef struct _mlan_ds_subscribe_evt
{
+ /** evt action */
+ t_u16 evt_action;
/** bitmap for subscribe event */
t_u16 evt_bitmap;
/** Absolute value of RSSI threshold value (dBm) */
@@ -2989,6 +3038,16 @@ typedef struct _mlan_ds_misc_otp_user_data
t_u8 user_data[MAX_OTP_USER_DATA_LEN];
} mlan_ds_misc_otp_user_data;
+#if defined(STA_SUPPORT)
+typedef struct _mlan_ds_misc_pmfcfg
+{
+ /** Management Frame Protection Capable */
+ t_u8 mfpc;
+ /** Management Frame Protection Required */
+ t_u8 mfpr;
+} mlan_ds_misc_pmfcfg;
+#endif
+
/** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */
typedef struct _mlan_ds_misc_cfg
{
@@ -3011,6 +3070,8 @@ typedef struct _mlan_ds_misc_cfg
mlan_ds_misc_sys_clock sys_clock;
/** WWS set/get for MLAN_OID_MISC_WWS */
t_u32 wws_cfg;
+ /** Get associate response for MLAN_OID_MISC_ASSOC_RSP */
+ mlan_ds_misc_assoc_rsp assoc_resp;
/** Function init/shutdown for MLAN_OID_MISC_INIT_SHUTDOWN */
t_u32 func_init_shutdown;
/** Custom IE for MLAN_OID_MISC_CUSTOM_IE */
@@ -3037,9 +3098,15 @@ typedef struct _mlan_ds_misc_cfg
/** Driver debug bit masks */
t_u32 drvdbg;
#endif
+#ifdef STA_SUPPORT
+ t_u8 ext_cap[8];
+#endif
mlan_ds_misc_otp_user_data otp_user_data;
/** Tx control */
t_u32 tx_control;
+#if defined(STA_SUPPORT)
+ mlan_ds_misc_pmfcfg pmfcfg;
+#endif
} param;
} mlan_ds_misc_cfg, *pmlan_ds_misc_cfg;
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_join.c b/drivers/net/wireless/sd8797/mlan/mlan_join.c
index d3b45ed3e2d9..b59c4361bb41 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_join.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_join.c
@@ -287,13 +287,13 @@ wlan_setup_rates_from_bssdesc(IN mlan_private * pmpriv,
pmpriv->adapter->region_code == COUNTRY_CODE_JP_FF)
&& (pbss_desc->phy_param_set.ds_param_set.current_chan == 14)) {
/* Special Case: For Japan, 11G rates on CH14 are not allowed */
- card_rates_size = wlan_get_active_data_rates(pmpriv, pmpriv->bss_mode,
- BAND_B, card_rates);
+ card_rates_size = wlan_get_supported_rates(pmpriv, pmpriv->bss_mode,
+ BAND_B, card_rates);
} else {
/* Get the STA supported rates */
- card_rates_size = wlan_get_active_data_rates(pmpriv, pmpriv->bss_mode,
- pmpriv->config_bands,
- card_rates);
+ card_rates_size = wlan_get_supported_rates(pmpriv, pmpriv->bss_mode,
+ pmpriv->config_bands,
+ card_rates);
}
/* Get the common rates between AP and STA supported rates */
if (wlan_get_common_rates(pmpriv, pout_rates, WLAN_SUPPORTED_RATES,
@@ -409,6 +409,111 @@ wlan_cmd_append_wapi_ie(mlan_private * priv, t_u8 ** ppBuffer)
Global Functions
********************************************************/
/**
+ * @brief This function updates RSN IE in the association request.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ *
+ * @param ptlv_rsn_ie A pointer to rsn_ie TLV
+ */
+void
+wlan_update_rsn_ie(mlan_private * pmpriv,
+ MrvlIEtypes_RsnParamSet_t * ptlv_rsn_ie)
+{
+ t_u16 *prsn_cap;
+ t_u16 *ptr;
+ t_u16 *akm_suite_count_ptr;
+ t_u16 pmf_mask = 0x00;
+ t_u8 *temp;
+ int pairwise_cipher_count = 0;
+ int akm_suite_count = 0;
+ int temp_akm_suite_count = 0;
+ int found = 0;
+ t_u8 sha_256_oui[4] = { 0x00, 0x0f, 0xac, 0x06 };
+ mlan_adapter *pmadapter = pmpriv->adapter;
+
+ pmf_mask =
+ (((pmpriv->pmfcfg.mfpc << MFPC_BIT) | (pmpriv->pmfcfg.
+ mfpr << MFPR_BIT)) |
+ (~PMF_MASK));
+ /* prsn_cap = prsn_ie->rsn_ie + 2 bytes version + 4 bytes
+ group_cipher_suite + 2 bytes pairwise_cipher_count +
+ 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 = *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 = *ptr;
+ akm_suite_count = *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 (!memcmp(pmadapter, temp, sha_256_oui, AKM_SUITE_LEN)) {
+ found = 1;
+ break;
+ }
+ temp += AKM_SUITE_LEN;
+ temp_akm_suite_count--;
+ }
+ if (found) {
+ /* Copy SHA256 as AKM suite */
+ memcpy(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)), sha_256_oui,
+ 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;
+ }
+ }
+ 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;
+ *prsn_cap |= PMF_MASK;
+ *prsn_cap &= pmf_mask;
+}
+
+/**
* @brief This function prepares command of association.
*
* @param pmpriv A pointer to mlan_private structure
@@ -508,7 +613,9 @@ wlan_cmd_802_11_associate(IN mlan_private * pmpriv,
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);
- if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
+ if ((pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
+ || (pmpriv->sec_info.authentication_mode ==
+ MLAN_AUTH_MODE_NETWORKEAP))
pauth_tlv->auth_type =
wlan_cpu_to_le16((t_u16) pmpriv->sec_info.authentication_mode);
else
@@ -608,6 +715,9 @@ wlan_cmd_802_11_associate(IN mlan_private * pmpriv,
memcpy(pmadapter, prsn_ie_tlv->rsn_ie,
&((*(pbss_desc->prsn_ie)).data[0])
, prsn_ie_tlv->header.len);
+ if (pmpriv->pmfcfg.mfpc || pmpriv->pmfcfg.mfpr) {
+ wlan_update_rsn_ie(pmpriv, prsn_ie_tlv);
+ }
} else {
ret = MLAN_STATUS_FAILURE;
goto done;
@@ -763,11 +873,18 @@ wlan_ret_802_11_associate(IN mlan_private * pmpriv,
t_u8 enable_data = MTRUE;
t_u8 event_buf[100];
mlan_event *pevent = (mlan_event *) event_buf;
+ t_u8 cur_mac[MLAN_MAC_ADDR_LENGTH];
+ t_u8 media_connected = pmpriv->media_connected;
+ mlan_adapter *pmadapter = pmpriv->adapter;
ENTER();
passoc_rsp = (IEEEtypes_AssocRsp_t *) & resp->params;
passoc_rsp->status_code = wlan_le16_to_cpu(passoc_rsp->status_code);
+ if (pmpriv->media_connected == MTRUE)
+ memcpy(pmpriv->adapter, cur_mac,
+ pmpriv->curr_bss_params.bss_descriptor.mac_address,
+ MLAN_MAC_ADDR_LENGTH);
HEXDUMP("ASSOC_RESP:", (t_u8 *) & resp->params, (resp->size - S_DS_GEN));
@@ -778,6 +895,19 @@ wlan_ret_802_11_associate(IN mlan_private * pmpriv,
pmpriv->assoc_rsp_size);
if (passoc_rsp->status_code) {
+ if (pmpriv->media_connected == MTRUE) {
+ if (pmpriv->port_ctrl_mode == MTRUE)
+ pmpriv->port_open = pmpriv->prior_port_status;
+ if (!memcmp
+ (pmpriv->adapter, cur_mac,
+ pmpriv->pattempted_bss_desc->mac_address,
+ MLAN_MAC_ADDR_LENGTH))
+ wlan_reset_connect_state(pmpriv, MTRUE);
+ else
+ wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_ASSOC_FAILURE_REPORT,
+ MNULL);
+ } else
+ wlan_reset_connect_state(pmpriv, MTRUE);
pmpriv->adapter->dbg.num_cmd_assoc_failure++;
PRINTM(MERROR, "ASSOC_RESP: Association Failed, "
"status code = %d, error = 0x%x, a_id = 0x%x\n",
@@ -799,7 +929,8 @@ wlan_ret_802_11_associate(IN mlan_private * pmpriv,
/* Set the attempted BSSID Index to current */
pbss_desc = pmpriv->pattempted_bss_desc;
- PRINTM(MINFO, "ASSOC_RESP: %s\n", pbss_desc->ssid.ssid);
+ PRINTM(MCMND, "ASSOC_RESP: %-32s (a_id = 0x%x)\n", pbss_desc->ssid.ssid,
+ wlan_le16_to_cpu(passoc_rsp->a_id));
/* Make a copy of current BSSID descriptor */
memcpy(pmpriv->adapter, &pmpriv->curr_bss_params.bss_descriptor,
@@ -883,7 +1014,24 @@ wlan_ret_802_11_associate(IN mlan_private * pmpriv,
MLAN_MAC_ADDR_LENGTH);
/* Add the ra_list here for infra mode as there will be only 1 ra always */
- wlan_ralist_add(pmpriv, pmpriv->curr_bss_params.bss_descriptor.mac_address);
+ if (media_connected) {
+ /** replace ralist's mac address with new mac address */
+ if (0 ==
+ wlan_ralist_update(pmpriv, cur_mac,
+ pmpriv->curr_bss_params.bss_descriptor.
+ mac_address))
+ wlan_ralist_add(pmpriv,
+ pmpriv->curr_bss_params.bss_descriptor.mac_address);
+ wlan_11n_cleanup_reorder_tbl(pmpriv);
+
+ pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle,
+ pmpriv->wmm.ra_list_spinlock);
+ wlan_11n_deleteall_txbastream_tbl(pmpriv);
+ pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle,
+ pmpriv->wmm.ra_list_spinlock);
+ } else
+ wlan_ralist_add(pmpriv,
+ pmpriv->curr_bss_params.bss_descriptor.mac_address);
wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_CONNECTED, pevent);
@@ -892,7 +1040,8 @@ wlan_ret_802_11_associate(IN mlan_private * pmpriv,
if (!pmpriv->sec_info.wpa_enabled
&& !pmpriv->sec_info.wpa2_enabled
- && !pmpriv->sec_info.ewpa_enabled && !pmpriv->sec_info.wapi_enabled) {
+ && !pmpriv->sec_info.ewpa_enabled
+ && !pmpriv->sec_info.wapi_enabled && !pmpriv->wps.session_enable) {
/* We are in Open/WEP mode, open port immediately */
if (pmpriv->port_ctrl_mode == MTRUE) {
pmpriv->port_open = MTRUE;
@@ -912,7 +1061,8 @@ wlan_ret_802_11_associate(IN mlan_private * pmpriv,
if (ret != MLAN_STATUS_SUCCESS) {
if (passoc_rsp->status_code)
pioctl_req->status_code =
- wlan_le16_to_cpu(passoc_rsp->status_code);
+ (wlan_le16_to_cpu(*(t_u16 *) & passoc_rsp->capability) <<
+ 16) + wlan_le16_to_cpu(passoc_rsp->status_code);
else
pioctl_req->status_code = MLAN_ERROR_CMD_ASSOC_FAIL;
} else {
@@ -949,6 +1099,7 @@ wlan_cmd_802_11_ad_hoc_start(IN mlan_private * pmpriv,
MrvlIEtypes_RsnParamSet_t *prsn_ie_tlv;
MrvlIETypes_HTCap_t *pht_cap;
MrvlIETypes_HTInfo_t *pht_info;
+ t_u32 rx_mcs_supp = 0;
/* wpa ie for WPA_NONE AES */
const t_u8 wpa_ie[24] = { 0xdd, 0x16, 0x00, 0x50, 0xf2, 0x01, 0x01, 0x00,
0x00, 0x50, 0xf2, 0x04, 0x01, 0x00, 0x00, 0x50,
@@ -1209,6 +1360,10 @@ wlan_cmd_802_11_ad_hoc_start(IN mlan_private * pmpriv,
memset(pmadapter, pht_cap, 0, sizeof(MrvlIETypes_HTCap_t));
pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY);
pht_cap->header.len = sizeof(HTCap_t);
+ rx_mcs_supp = GET_RXMCSSUPP(pmadapter->usr_dev_mcs_support);
+ /* Set MCS for 1x1/2x2 */
+ memset(pmadapter, (t_u8 *) pht_cap->ht_cap.supported_mcs_set, 0xff,
+ rx_mcs_supp);
wlan_fill_ht_cap_tlv(pmpriv, pht_cap, pmpriv->curr_bss_params.band);
HEXDUMP("ADHOC_START: HT_CAPABILITIES IE", (t_u8 *) pht_cap,
sizeof(MrvlIETypes_HTCap_t));
@@ -1281,7 +1436,7 @@ wlan_cmd_802_11_ad_hoc_join(IN mlan_private * pmpriv,
t_u32 cmd_append_size = 0;
t_u16 tmp_cap;
t_u32 i, rates_size = 0;
- t_u16 curr_pkt_filter;
+ t_u32 curr_pkt_filter;
t_u8 *pos = (t_u8 *) padhoc_join + sizeof(HostCmd_DS_802_11_AD_HOC_JOIN);
ENTER();
@@ -1336,13 +1491,8 @@ wlan_cmd_802_11_ad_hoc_join(IN mlan_private * pmpriv,
/* Information on BSSID descriptor passed to FW */
PRINTM(MINFO,
- "ADHOC_J_CMD: BSSID = %02x-%02x-%02x-%02x-%02x-%02x, SSID = %s\n",
- padhoc_join->bss_descriptor.bssid[0],
- padhoc_join->bss_descriptor.bssid[1],
- padhoc_join->bss_descriptor.bssid[2],
- padhoc_join->bss_descriptor.bssid[3],
- padhoc_join->bss_descriptor.bssid[4],
- padhoc_join->bss_descriptor.bssid[5],
+ "ADHOC_J_CMD: BSSID = " MACSTR ", SSID = %s\n",
+ MAC2STR(padhoc_join->bss_descriptor.bssid),
padhoc_join->bss_descriptor.ssid);
for (i = 0; i < WLAN_SUPPORTED_RATES && pbss_desc->supported_rates[i]; i++);
@@ -1595,13 +1745,8 @@ wlan_ret_802_11_ad_hoc(IN mlan_private * pmpriv,
}
PRINTM(MINFO, "ADHOC_RESP: Channel = %d\n", pmpriv->adhoc_channel);
- PRINTM(MINFO, "ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
- pmpriv->curr_bss_params.bss_descriptor.mac_address[0],
- pmpriv->curr_bss_params.bss_descriptor.mac_address[1],
- pmpriv->curr_bss_params.bss_descriptor.mac_address[2],
- pmpriv->curr_bss_params.bss_descriptor.mac_address[3],
- pmpriv->curr_bss_params.bss_descriptor.mac_address[4],
- pmpriv->curr_bss_params.bss_descriptor.mac_address[5]);
+ PRINTM(MINFO, "ADHOC_RESP: BSSID = " MACSTR "\n",
+ MAC2STR(pmpriv->curr_bss_params.bss_descriptor.mac_address));
pevent->bss_index = pmpriv->bss_index;
pevent->event_id = MLAN_EVENT_ID_DRV_CONNECTED;
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_main.h b/drivers/net/wireless/sd8797/mlan/mlan_main.h
index 1e29c0464f5f..848137ba283a 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_main.h
+++ b/drivers/net/wireless/sd8797/mlan/mlan_main.h
@@ -30,31 +30,31 @@ Change log:
#ifdef DEBUG_LEVEL1
extern t_void(*print_callback) (IN t_void * pmoal_handle,
- IN t_u32 level, IN t_s8 * pformat, IN ...);
+ IN t_u32 level, IN char *pformat, IN ...);
extern mlan_status(*get_sys_time_callback) (IN t_void * pmoal_handle,
OUT t_u32 * psec,
OUT t_u32 * pusec);
-extern t_u32 drvdbg;
+extern t_u32 mlan_drvdbg;
#ifdef DEBUG_LEVEL2
-#define PRINTM_MINFO(msg...) do {if ((drvdbg & MINFO) && (print_callback)) \
+#define PRINTM_MINFO(msg...) do {if ((mlan_drvdbg & MINFO) && (print_callback)) \
print_callback(MNULL, MINFO, msg);} while(0)
-#define PRINTM_MWARN(msg...) do {if ((drvdbg & MWARN) && (print_callback)) \
+#define PRINTM_MWARN(msg...) do {if ((mlan_drvdbg & MWARN) && (print_callback)) \
print_callback(MNULL, MWARN, msg);} while(0)
-#define PRINTM_MENTRY(msg...) do {if ((drvdbg & MENTRY) && (print_callback)) \
+#define PRINTM_MENTRY(msg...) do {if ((mlan_drvdbg & MENTRY) && (print_callback)) \
print_callback(MNULL, MENTRY, msg);} while(0)
#define PRINTM_GET_SYS_TIME(level, psec, pusec) \
do { \
- if ((level & drvdbg) && (get_sys_time_callback)) \
+ if ((level & mlan_drvdbg) && (get_sys_time_callback)) \
get_sys_time_callback(MNULL, psec, pusec); \
} while (0)
/** Hexdump for level-2 debugging */
#define HEXDUMP(x,y,z) \
do { \
- if ((drvdbg & (MHEX_DUMP | MINFO)) && (print_callback)) \
+ if ((mlan_drvdbg & (MHEX_DUMP | MINFO)) && (print_callback)) \
print_callback(MNULL, MHEX_DUMP | MINFO, x, y, z); \
} while (0)
@@ -66,7 +66,7 @@ do { \
#define PRINTM_GET_SYS_TIME(level, psec, pusec) \
do { \
- if ((level & drvdbg) && (get_sys_time_callback) \
+ if ((level & mlan_drvdbg) && (get_sys_time_callback) \
&& (level != MINFO) && (level != MWARN)) \
get_sys_time_callback(MNULL, psec, pusec); \
} while (0)
@@ -76,39 +76,39 @@ do { \
#endif /* DEBUG_LEVEL2 */
-#define PRINTM_MFW_D(msg...) do {if ((drvdbg & MFW_D) && (print_callback)) \
+#define PRINTM_MFW_D(msg...) do {if ((mlan_drvdbg & MFW_D) && (print_callback)) \
print_callback(MNULL, MFW_D, msg);} while(0)
-#define PRINTM_MCMD_D(msg...) do {if ((drvdbg & MCMD_D) && (print_callback)) \
+#define PRINTM_MCMD_D(msg...) do {if ((mlan_drvdbg & MCMD_D) && (print_callback)) \
print_callback(MNULL, MCMD_D, msg);} while(0)
-#define PRINTM_MDAT_D(msg...) do {if ((drvdbg & MDAT_D) && (print_callback)) \
+#define PRINTM_MDAT_D(msg...) do {if ((mlan_drvdbg & MDAT_D) && (print_callback)) \
print_callback(MNULL, MDAT_D, msg);} while(0)
-#define PRINTM_MIF_D(msg...) do {if ((drvdbg & MIF_D) && (print_callback)) \
+#define PRINTM_MIF_D(msg...) do {if ((mlan_drvdbg & MIF_D) && (print_callback)) \
print_callback(MNULL, MIF_D, msg);} while(0)
-#define PRINTM_MIOCTL(msg...) do {if ((drvdbg & MIOCTL) && (print_callback)) \
+#define PRINTM_MIOCTL(msg...) do {if ((mlan_drvdbg & MIOCTL) && (print_callback)) \
print_callback(MNULL, MIOCTL, msg);} while(0)
-#define PRINTM_MINTR(msg...) do {if ((drvdbg & MINTR) && (print_callback)) \
+#define PRINTM_MINTR(msg...) do {if ((mlan_drvdbg & MINTR) && (print_callback)) \
print_callback(MNULL, MINTR, msg);} while(0)
-#define PRINTM_MEVENT(msg...) do {if ((drvdbg & MEVENT) && (print_callback)) \
+#define PRINTM_MEVENT(msg...) do {if ((mlan_drvdbg & MEVENT) && (print_callback)) \
print_callback(MNULL, MEVENT, msg);} while(0)
-#define PRINTM_MCMND(msg...) do {if ((drvdbg & MCMND) && (print_callback)) \
+#define PRINTM_MCMND(msg...) do {if ((mlan_drvdbg & MCMND) && (print_callback)) \
print_callback(MNULL, MCMND, msg);} while(0)
-#define PRINTM_MDATA(msg...) do {if ((drvdbg & MDATA) && (print_callback)) \
+#define PRINTM_MDATA(msg...) do {if ((mlan_drvdbg & MDATA) && (print_callback)) \
print_callback(MNULL, MDATA, msg);} while(0)
-#define PRINTM_MERROR(msg...) do {if ((drvdbg & MERROR) && (print_callback)) \
+#define PRINTM_MERROR(msg...) do {if ((mlan_drvdbg & MERROR) && (print_callback)) \
print_callback(MNULL, MERROR, msg);} while(0)
-#define PRINTM_MFATAL(msg...) do {if ((drvdbg & MFATAL) && (print_callback)) \
+#define PRINTM_MFATAL(msg...) do {if ((mlan_drvdbg & MFATAL) && (print_callback)) \
print_callback(MNULL, MFATAL, msg);} while(0)
-#define PRINTM_MMSG(msg...) do {if ((drvdbg & MMSG) && (print_callback)) \
+#define PRINTM_MMSG(msg...) do {if ((mlan_drvdbg & MMSG) && (print_callback)) \
print_callback(MNULL, MMSG, msg);} while(0)
-#define PRINTM(level,msg...) PRINTM_##level(msg)
+#define PRINTM(level,msg...) PRINTM_##level((char*)msg)
/** Log debug message */
#ifdef __GNUC__
#define PRINTM_NETINTF(level, pmpriv) \
do { \
- if ((drvdbg & level) && pmpriv \
+ if ((mlan_drvdbg & level) && pmpriv \
&& pmpriv->adapter->callbacks.moal_print_netintf) \
pmpriv->adapter->callbacks.moal_print_netintf( \
pmpriv->adapter->pmoal_handle, \
@@ -122,7 +122,7 @@ do { \
/** Debug hexdump for level-1 debugging */
#define DBG_HEXDUMP(level,x,y,z) \
do { \
- if ((drvdbg & level) && print_callback) \
+ if ((mlan_drvdbg & level) && print_callback) \
print_callback(MNULL, MHEX_DUMP | level, x, y, z); \
} while (0)
@@ -316,7 +316,7 @@ do { \
#define WLAN_UPLD_SIZE (2312)
/** Maximum event buffer size */
-#define MAX_EVENT_SIZE 1024
+#define MAX_EVENT_SIZE 2048
#ifdef STA_SUPPORT
/** Maximum buffer size for ARP filter */
@@ -388,7 +388,7 @@ do { \
#define DEFAULT_BCN_MISS_TIMEOUT 10
/** Maximum buffer space for beacons retrieved from scan responses */
-#define MAX_SCAN_BEACON_BUFFER 16384
+#define MAX_SCAN_BEACON_BUFFER 32768
/** Default buffer space for beacons retrieved from scan responses */
#define DEFAULT_SCAN_BEACON_BUFFER 4096
@@ -425,11 +425,6 @@ do { \
/** If OUI is found */
#define MLAN_OUI_PRESENT 1
-/** RF antenna selection */
-#define RF_ANTENNA_MASK(n) ((1<<(n))-1)
-/** RF antenna auto select */
-#define RF_ANTENNA_AUTO 0xFFFF
-
/** Is cmd_resp, event or data packet received? */
#define IS_CARD_RX_RCVD(adapter) (adapter->cmd_resp_received || \
adapter->event_received || \
@@ -465,7 +460,7 @@ do { \
#define RX_LOW_THRESHOLD 128
/** Debug command number */
-#define DBG_CMD_NUM 5
+#define DBG_CMD_NUM 10
/** Info for debug purpose */
typedef struct _wlan_dbg
@@ -518,6 +513,8 @@ typedef struct _wlan_dbg
t_u16 last_event[DBG_CMD_NUM];
/** Last event index */
t_u16 last_event_index;
+ /** Number of no free command node */
+ t_u16 num_no_cmd_node;
} wlan_dbg;
/** Hardware status codes */
@@ -900,6 +897,8 @@ typedef struct _mlan_private
t_u8 bss_type;
/** BSS role */
t_u8 bss_role;
+ /** BSS virtual flag */
+ t_u8 bss_virtual;
/** BSS Priority */
t_u8 bss_priority;
/** BSS number */
@@ -912,7 +911,7 @@ typedef struct _mlan_private
t_bool media_connected;
/** Current packet filter */
- t_u16 curr_pkt_filter;
+ t_u32 curr_pkt_filter;
/** Infrastructure mode */
t_u32 bss_mode;
@@ -1010,12 +1009,14 @@ typedef struct _mlan_private
wlan_802_11d_state_t state_11d;
/** FSM variable for 11h support */
wlan_11h_interface_state_t intf_state_11h;
-#if defined(UAP_SUPPORT)
+#ifdef UAP_SUPPORT
/** Whether UAP interface has started */
t_bool uap_bss_started;
+ /**UAP operating channel*/
+ t_u8 uap_channel;
/** state variable for UAP Get Info callback */
wlan_uap_get_info_cb_t uap_state_chan_cb;
-#endif
+#endif /* UAP_SUPPORT */
/** Security related */
/** Encryption parameter */
@@ -1032,8 +1033,11 @@ typedef struct _mlan_private
t_u8 wpa_ie_len;
/** GTK set flag */
t_u8 wpa_is_gtk_set;
- /** AES key material */
- HostCmd_DS_802_11_KEY_MATERIAL aes_key;
+ mlan_ds_encrypt_key aes_key;
+#if defined(STA_SUPPORT)
+ /* Mgmt Frame Protection config */
+ mlan_ds_misc_pmfcfg pmfcfg;
+#endif
/** WAPI IE */
t_u8 wapi_ie[256];
/** WAPI IE length */
@@ -1103,10 +1107,15 @@ typedef struct _mlan_private
/** Port open flag state at time of association attempt */
t_u8 prior_port_status;
+ /** Bypass TX queue */
+ mlan_list_head bypass_txq;
/** IP address operation */
t_u32 op_code;
/** IP address */
t_u8 ip_addr[IPADDR_LEN];
+#ifdef STA_SUPPORT
+ ExtCap_t ext_cap;
+#endif
} mlan_private, *pmlan_private;
/** BA stream status */
@@ -1161,6 +1170,8 @@ struct _RxReorderTbl
t_u8 ta[MLAN_MAC_ADDR_LENGTH];
/** Start window */
int start_win;
+ /** last_seq */
+ int last_seq;
/** Window size */
int win_size;
/** Pointer to pointer to RxReorderTbl */
@@ -1170,8 +1181,10 @@ struct _RxReorderTbl
/** BA stream status */
baStatus_e ba_status;
t_u8 amsdu;
- /** no packet drop flag for rx_reorder_tbl */
+ /** no packet drop flag for rx_reorder_tbl */
t_u8 force_no_drop;
+ /** flag for check start win */
+ t_u8 check_start_win;
};
/** BSS priority node */
@@ -1511,6 +1524,8 @@ typedef struct _mlan_adapter
t_void *pmain_proc_lock;
/** mlan_processing */
t_u32 mlan_processing;
+ /** more task flag */
+ t_u32 more_task_flag;
/** Max tx buf size */
t_u16 max_tx_buf_size;
/** Tx buf size */
@@ -1806,9 +1821,11 @@ typedef struct _mlan_adapter
/** ARP filter buffer size */
t_u32 arp_filter_size;
#endif /* STA_SUPPORT */
+ /** Minimum delay between HsActive and HostWake (in msec) */
+ t_u16 min_wake_holdoff;
- /** Bypass TX queue */
- mlan_list_head bypass_txq;
+ /** Bypass TX queue pkt count */
+ t_u16 bypass_pkt_count;
#if defined(STA_SUPPORT)
/** warm-reset IOCTL request buffer pointer */
pmlan_ioctl_req pwarm_reset_ioctl_req;
@@ -1819,9 +1836,16 @@ typedef struct _mlan_adapter
t_u8 *pcal_data;
/** Cal data length */
t_u32 cal_data_len;
+ /** Feature control bitmask */
+ t_u32 feature_control;
} mlan_adapter, *pmlan_adapter;
+/** Check if stream 2X2 enabled */
+#define IS_STREAM_2X2(x) ((x) & FEATURE_CTRL_STREAM_2X2)
+/** Check if DFS support enabled */
+#define IS_DFS_SUPPORT(x) ((x) & FEATURE_CTRL_DFS_SUPPORT)
+
/** Ethernet packet type for EAPOL */
#define MLAN_ETHER_PKT_TYPE_EAPOL (0x888E)
/** Ethernet packet type for WAPI */
@@ -1906,12 +1930,15 @@ t_void wlan_release_cmd_lock(mlan_adapter * pmadapter);
#ifdef STA_SUPPORT
/** Flush the scan pending queue */
t_void wlan_flush_scan_queue(pmlan_adapter pmadapter);
+t_void wlan_cancel_pending_scan_cmd(pmlan_adapter pmadapter);
#endif
/**Cancel pending command */
t_void wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter);
/**Cancel pending ioctl */
t_void wlan_cancel_pending_ioctl(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
+/**Cancel bss pending ioctl */
+t_void wlan_cancel_bss_pending_cmd(pmlan_adapter pmadapter, t_u32 bss_index);
/** Insert command to free queue */
t_void wlan_insert_cmd_to_free_q(IN mlan_adapter * pmadapter,
@@ -1954,7 +1981,7 @@ t_void wlan_clean_txrx(pmlan_private priv);
t_void wlan_add_buf_bypass_txqueue(mlan_adapter * pmadapter,
pmlan_buffer pmbuf);
t_void wlan_process_bypass_tx(mlan_adapter * pmadapter);
-t_void wlan_cleanup_bypass_txq(mlan_adapter * pmadapter);
+t_void wlan_cleanup_bypass_txq(pmlan_private priv);
t_u8 wlan_bypass_tx_list_empty(mlan_adapter * pmadapter);
/** Check if this is the last packet */
@@ -2043,6 +2070,9 @@ mlan_status wlan_ret_remain_on_channel(IN pmlan_private pmpriv,
mlan_status wlan_get_pm_info(IN pmlan_adapter pmadapter,
IN pmlan_ioctl_req pioctl_req);
+mlan_status wlan_bss_ioctl_bss_remove(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req);
+
mlan_status wlan_get_hs_wakeup_reason(IN pmlan_adapter pmadapter,
IN pmlan_ioctl_req pioctl_req);
@@ -2406,7 +2436,7 @@ wlan_is_tx_pause(mlan_private * priv, t_u8 * ra)
return MFALSE;
}
-t_void wlan_updata_ralist_tx_pause(pmlan_private priv, t_u8 * mac,
+t_void wlan_update_ralist_tx_pause(pmlan_private priv, t_u8 * mac,
t_u8 tx_pause);
#ifdef UAP_SUPPORT
@@ -2430,6 +2460,15 @@ mlan_status wlan_ret_get_hw_spec(IN pmlan_private pmpriv,
IN HostCmd_DS_COMMAND * resp,
IN t_void * pioctl_buf);
+mlan_status wlan_misc_ioctl_mac_control(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req);
+mlan_status wlan_cmd_mac_control(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * pcmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf);
+mlan_status wlan_ret_mac_control(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * resp,
+ IN mlan_ioctl_req * pioctl_buf);
+
mlan_status wlan_cmd_802_11_radio_control(IN pmlan_private pmpriv,
IN HostCmd_DS_COMMAND * cmd,
IN t_u16 cmd_action,
@@ -2476,6 +2515,17 @@ mlan_status wlan_set_drvdbg(IN pmlan_adapter pmadapter,
IN pmlan_ioctl_req pioctl_req);
#endif
+#ifdef STA_SUPPORT
+mlan_status wlan_misc_ext_capa_cfg(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req);
+
+t_u32 wlan_is_ext_capa_support(IN mlan_private * pmpriv);
+#endif
+
+#ifdef STA_SUPPORT
+void wlan_add_ext_capa_info_ie(IN mlan_private * pmpriv, OUT t_u8 ** pptlv_out);
+#endif
+
mlan_status wlan_misc_otp_user_data(IN pmlan_adapter pmadapter,
IN pmlan_ioctl_req pioctl_req);
@@ -2535,7 +2585,7 @@ wlan_copy_rates(t_u8 * dest, t_u32 pos, t_u8 * src, int len)
* @return Length of string
*/
static INLINE t_u32
-wlan_strlen(const t_s8 * str)
+wlan_strlen(const char *str)
{
t_u32 i;
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_meas.c b/drivers/net/wireless/sd8797/mlan/mlan_meas.c
index d9da9da20756..19c4131c7bc1 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_meas.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_meas.c
@@ -85,12 +85,8 @@ wlan_meas_dump_meas_req(const HostCmd_DS_MEASUREMENT_REQUEST * pmeas_req)
PRINTM(MINFO, "Meas: Req: ------------------------------\n");
- PRINTM(MINFO, "Meas: Req: mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
- pmeas_req->mac_addr[0],
- pmeas_req->mac_addr[1],
- pmeas_req->mac_addr[2],
- pmeas_req->mac_addr[3],
- pmeas_req->mac_addr[4], pmeas_req->mac_addr[5]);
+ PRINTM(MINFO, "Meas: Req: mac_addr: " MACSTR "\n",
+ MAC2STR(pmeas_req->mac_addr));
PRINTM(MINFO, "Meas: Req: dlgTkn: %d\n", pmeas_req->dialog_token);
PRINTM(MINFO, "Meas: Req: mode: dm[%c] rpt[%c] req[%c]\n",
@@ -136,12 +132,8 @@ wlan_meas_dump_meas_rpt(const HostCmd_DS_MEASUREMENT_REPORT * pmeas_rpt)
ENTER();
PRINTM(MINFO, "Meas: Rpt: ------------------------------\n");
- PRINTM(MINFO, "Meas: Rpt: mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
- pmeas_rpt->mac_addr[0],
- pmeas_rpt->mac_addr[1],
- pmeas_rpt->mac_addr[2],
- pmeas_rpt->mac_addr[3],
- pmeas_rpt->mac_addr[4], pmeas_rpt->mac_addr[5]);
+ PRINTM(MINFO, "Meas: Rpt: mac_addr: " MACSTR "\n",
+ MAC2STR(pmeas_rpt->mac_addr));
PRINTM(MINFO, "Meas: Rpt: dlgTkn: %d\n", pmeas_rpt->dialog_token);
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_misc.c b/drivers/net/wireless/sd8797/mlan/mlan_misc.c
index 6f4073560b31..540147c1837e 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_misc.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_misc.c
@@ -57,6 +57,8 @@ extern t_u8 ac_to_tid[4][2];
#define MLAN_CUSTOM_IE_AUTO_IDX_MASK 0xffff
/** Custom IE mask for delete operation */
#define MLAN_CUSTOM_IE_DELETE_MASK 0
+/** Custom IE mask for create new index */
+#define MLAN_CUSTOM_IE_NEW_MASK 0x8000
/** Custom IE header size */
#define MLAN_CUSTOM_IE_HDR_SIZE (sizeof(custom_ie)-MAX_IE_SIZE)
@@ -129,9 +131,9 @@ wlan_custom_ioctl_get_autoidx(IN pmlan_private pmpriv,
(pmpriv->adapter, pmpriv->mgmt_ie[index].ie_buffer,
ie_data->ie_buffer,
pmpriv->mgmt_ie[index].ie_length)) {
- PRINTM(MERROR,
- "IE with the same mask exists at index %d\n",
- index);
+ PRINTM(MINFO,
+ "IE with the same mask exists at index %d mask=0x%x\n",
+ index, mask);
*idx = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
goto done;
}
@@ -208,6 +210,9 @@ wlan_custom_ioctl_auto_delete(IN pmlan_private pmpriv,
MIN(MAX_IE_SIZE, ie_data->ie_length));
del_len = MIN(MAX_IE_SIZE, ie_data->ie_length);
+ if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == idx)
+ ie_data->ie_index = 0;
+
for (index = 0; index < pmadapter->max_mgmt_ie_index; index++) {
if (MLAN_CUSTOM_IE_AUTO_IDX_MASK != idx)
index = idx;
@@ -228,6 +233,9 @@ wlan_custom_ioctl_auto_delete(IN pmlan_private pmpriv,
memcpy(pmpriv->adapter, &pmpriv->mgmt_ie[index].ie_buffer, ie,
pmpriv->mgmt_ie[index].ie_length - del_len);
pmpriv->mgmt_ie[index].ie_length -= del_len;
+ if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == idx)
+ /* set a bit to indicate caller about update */
+ ie_data->ie_index |= (((t_u16) 1) << index);
insert = MTRUE;
tmp_ie = pmpriv->mgmt_ie[index].ie_buffer;
tmp_len = pmpriv->mgmt_ie[index].ie_length;
@@ -376,8 +384,8 @@ wlan_get_info_debug_info(IN pmlan_adapter pmadapter,
pmpriv->wmm_qosinfo = info->param.debug_info.qos_cfg;
pmadapter->tx_lock_flag = info->param.debug_info.tx_lock_flag;
pmpriv->port_open = info->param.debug_info.port_open;
+ pmadapter->bypass_pkt_count = info->param.debug_info.bypass_pkt_count;
pmadapter->scan_processing = info->param.debug_info.scan_processing;
-
pmadapter->dbg.num_cmd_host_to_card_failure =
info->param.debug_info.num_cmd_host_to_card_failure;
pmadapter->dbg.num_cmd_sleep_cfm_host_to_card_failure =
@@ -423,6 +431,7 @@ wlan_get_info_debug_info(IN pmlan_adapter pmadapter,
sizeof(pmadapter->dbg.last_event));
pmadapter->dbg.last_event_index =
info->param.debug_info.last_event_index;
+ pmadapter->dbg.num_no_cmd_node = info->param.debug_info.num_no_cmd_node;
pmadapter->data_sent = info->param.debug_info.data_sent;
pmadapter->cmd_sent = info->param.debug_info.cmd_sent;
@@ -472,8 +481,8 @@ wlan_get_info_debug_info(IN pmlan_adapter pmadapter,
info->param.debug_info.qos_cfg = pmpriv->wmm_qosinfo;
info->param.debug_info.tx_lock_flag = pmadapter->tx_lock_flag;
info->param.debug_info.port_open = pmpriv->port_open;
+ info->param.debug_info.bypass_pkt_count = pmadapter->bypass_pkt_count;
info->param.debug_info.scan_processing = pmadapter->scan_processing;
-
info->param.debug_info.num_cmd_host_to_card_failure
= pmadapter->dbg.num_cmd_host_to_card_failure;
info->param.debug_info.num_cmd_sleep_cfm_host_to_card_failure
@@ -517,6 +526,7 @@ wlan_get_info_debug_info(IN pmlan_adapter pmadapter,
pmadapter->dbg.last_event, sizeof(pmadapter->dbg.last_event));
info->param.debug_info.last_event_index =
pmadapter->dbg.last_event_index;
+ info->param.debug_info.num_no_cmd_node = pmadapter->dbg.num_no_cmd_node;
info->param.debug_info.mp_rd_bitmap = pmadapter->mp_rd_bitmap;
info->param.debug_info.mp_wr_bitmap = pmadapter->mp_wr_bitmap;
info->param.debug_info.curr_rd_port = pmadapter->curr_rd_port;
@@ -541,6 +551,47 @@ wlan_get_info_debug_info(IN pmlan_adapter pmadapter,
}
/**
+ * @brief Set/Get the MAC control configuration.
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING -- success, otherwise fail
+ */
+mlan_status
+wlan_misc_ioctl_mac_control(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ t_u16 cmd_action = 0;
+
+ ENTER();
+
+ misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+
+ if (pioctl_req->action == MLAN_ACT_GET) {
+ misc->param.mac_ctrl = pmpriv->curr_pkt_filter;
+ } else {
+ pmpriv->curr_pkt_filter = misc->param.mac_ctrl;
+ cmd_action = HostCmd_ACT_GEN_SET;
+
+ /* Send command to firmware */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_MAC_CONTROL,
+ cmd_action, 0,
+ (t_void *) pioctl_req, &misc->param.mac_ctrl);
+
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
+ }
+
+ LEAVE();
+ return ret;
+}
+
+/**
* @brief This function wakes up the card.
*
* @param pmadapter A pointer to mlan_adapter structure
@@ -749,6 +800,8 @@ wlan_free_mlan_buffer(mlan_adapter * pmadapter, pmlan_buffer pmbuf)
ENTER();
if (pcb && pmbuf) {
+ if (pmbuf->flags & MLAN_BUF_FLAG_BRIDGE_BUF)
+ pmadapter->pending_bridge_pkts--;
if (pmbuf->flags & MLAN_BUF_FLAG_MALLOC_BUF)
pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmbuf);
else
@@ -820,6 +873,24 @@ wlan_delay_func(mlan_adapter * pmadapter, t_u32 delay, t_delay_unit u)
return;
}
+/**
+ * @brief BSS remove
+ *
+ * @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_bss_ioctl_bss_remove(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ ENTER();
+ wlan_cancel_bss_pending_cmd(pmadapter, pioctl_req->bss_index);
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
/**
* @brief Set/Get BSS role
@@ -947,7 +1018,8 @@ wlan_misc_ioctl_custom_ie_list(IN pmlan_adapter pmadapter,
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
custom_ie *ie_data = MNULL;
- t_u16 cmd_action = 0, index, mask, i, len, app_data_len, ioctl_len;
+ t_u16 cmd_action = 0, index, mask, i, len, app_data_len;
+ t_s32 ioctl_len;
t_u8 *tmp_ie;
ENTER();
@@ -986,26 +1058,30 @@ wlan_misc_ioctl_custom_ie_list(IN pmlan_adapter pmadapter,
if (ret == MLAN_STATUS_FAILURE) {
goto done;
}
+ index = ie_data->ie_index;
memset(pmadapter, ie_data, 0,
sizeof(custom_ie) * MAX_MGMT_IE_INDEX_TO_FW);
len = 0;
for (i = 0; i < pmadapter->max_mgmt_ie_index; i++) {
- memcpy(pmadapter, (t_u8 *) ie_data + len, &i,
- sizeof(ie_data->ie_index));
- len += sizeof(ie_data->ie_index);
- memcpy(pmadapter, (t_u8 *) ie_data + len,
- &pmpriv->mgmt_ie[i].mgmt_subtype_mask,
- sizeof(ie_data->mgmt_subtype_mask));
- len += sizeof(ie_data->mgmt_subtype_mask);
- memcpy(pmadapter, (t_u8 *) ie_data + len,
- &pmpriv->mgmt_ie[i].ie_length,
- sizeof(ie_data->ie_length));
- len += sizeof(ie_data->ie_length);
- if (pmpriv->mgmt_ie[i].ie_length) {
+ /* Check if index is updated before sending to FW */
+ if (index & ((t_u16) 1) << i) {
+ memcpy(pmadapter, (t_u8 *) ie_data + len, &i,
+ sizeof(ie_data->ie_index));
+ len += sizeof(ie_data->ie_index);
+ memcpy(pmadapter, (t_u8 *) ie_data + len,
+ &pmpriv->mgmt_ie[i].mgmt_subtype_mask,
+ sizeof(ie_data->mgmt_subtype_mask));
+ len += sizeof(ie_data->mgmt_subtype_mask);
memcpy(pmadapter, (t_u8 *) ie_data + len,
- &pmpriv->mgmt_ie[i].ie_buffer,
- pmpriv->mgmt_ie[i].ie_length);
- len += pmpriv->mgmt_ie[i].ie_length;
+ &pmpriv->mgmt_ie[i].ie_length,
+ sizeof(ie_data->ie_length));
+ len += sizeof(ie_data->ie_length);
+ if (pmpriv->mgmt_ie[i].ie_length) {
+ memcpy(pmadapter, (t_u8 *) ie_data + len,
+ &pmpriv->mgmt_ie[i].ie_buffer,
+ pmpriv->mgmt_ie[i].ie_length);
+ len += pmpriv->mgmt_ie[i].ie_length;
+ }
}
}
misc->param.cust_ie.len += len;
@@ -1019,6 +1095,7 @@ wlan_misc_ioctl_custom_ie_list(IN pmlan_adapter pmadapter,
ret = MLAN_STATUS_FAILURE;
goto done;
}
+ mask &= ~MLAN_CUSTOM_IE_NEW_MASK;
if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == index) {
ret = MLAN_STATUS_SUCCESS;
goto done;
@@ -1092,7 +1169,18 @@ wlan_misc_ioctl_custom_ie_list(IN pmlan_adapter pmadapter,
ie_data->ie_buffer, ie_data->ie_length)) {
PRINTM(MIOCTL,
"same custom ie already configured!\n");
- goto done;
+ if (ioctl_len <= 0 && misc->param.cust_ie.len == 0) {
+ goto done;
+ } else {
+ /* remove matching IE from app buffer */
+ app_data_len -=
+ ie_data->ie_length +
+ MLAN_CUSTOM_IE_HDR_SIZE;
+ memmove(pmadapter, (t_u8 *) ie_data,
+ ie_data->ie_buffer + ie_data->ie_length,
+ ioctl_len);
+ continue;
+ }
}
}
memset(pmadapter, &pmpriv->mgmt_ie[index], 0,
@@ -1480,7 +1568,7 @@ wlan_set_drvdbg(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
ENTER();
/* Set driver debug bit masks */
- drvdbg = misc->param.drvdbg;
+ mlan_drvdbg = misc->param.drvdbg;
LEAVE();
return ret;
@@ -1577,10 +1665,8 @@ wlan_process_802dot11_mgmt_pkt(IN mlan_private * priv,
(pmadapter, pieee_pkt_hdr->addr1, priv->curr_addr,
MLAN_MAC_ADDR_LENGTH)) {
PRINTM(MINFO,
- "Dropping mgmt frame for others: type=%d %02x:%02x:%02x:%02x:%02x:%02x\n",
- sub_type, pieee_pkt_hdr->addr1[0], pieee_pkt_hdr->addr1[1],
- pieee_pkt_hdr->addr1[2], pieee_pkt_hdr->addr1[3],
- pieee_pkt_hdr->addr1[4], pieee_pkt_hdr->addr1[5]);
+ "Dropping mgmt frame for others: type=%d " MACSTR "\n",
+ sub_type, MAC2STR(pieee_pkt_hdr->addr1));
LEAVE();
return ret;
}
@@ -1610,6 +1696,90 @@ wlan_process_802dot11_mgmt_pkt(IN mlan_private * priv,
return MLAN_STATUS_SUCCESS;
}
+#ifdef STA_SUPPORT
+/**
+ * @brief Extended capabilities configuration
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
+ */
+mlan_status
+wlan_misc_ext_capa_cfg(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+
+ ENTER();
+
+ if (MLAN_ACT_GET == pioctl_req->action)
+ memcpy(pmpriv->adapter, &misc->param.ext_cap, &pmpriv->ext_cap,
+ sizeof(misc->param.ext_cap));
+ else if (MLAN_ACT_SET == pioctl_req->action) {
+ memcpy(pmpriv->adapter, &pmpriv->ext_cap, &misc->param.ext_cap,
+ sizeof(misc->param.ext_cap));
+ }
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Check whether Extended Capabilities IE support
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ *
+ * @return MTRUE or MFALSE;
+ */
+t_u32
+wlan_is_ext_capa_support(mlan_private * pmpriv)
+{
+ ENTER();
+
+ /* So far there are only three bits are meaningful */
+ if (ISSUPP_EXTCAP_TDLS(pmpriv->ext_cap)
+ || ISSUPP_EXTCAP_INTERWORKING(pmpriv->ext_cap)
+ ) {
+ LEAVE();
+ return MTRUE;
+ } else {
+ LEAVE();
+ return MFALSE;
+ }
+}
+#endif
+
+#ifdef STA_SUPPORT
+/**
+ * @brief Add Extended Capabilities IE
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param pptlv_out A pointer to TLV to fill in
+ *
+ * @return N/A
+ */
+void
+wlan_add_ext_capa_info_ie(IN mlan_private * pmpriv, OUT t_u8 ** pptlv_out)
+{
+ MrvlIETypes_ExtCap_t *pext_cap = MNULL;
+
+ ENTER();
+
+ pext_cap = (MrvlIETypes_ExtCap_t *) * pptlv_out;
+ memset(pmpriv->adapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
+ pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
+ pext_cap->header.len = wlan_cpu_to_le16(sizeof(ExtCap_t));
+ memcpy(pmpriv->adapter, &pext_cap->ext_cap, &pmpriv->ext_cap,
+ sizeof(pmpriv->ext_cap));
+ *pptlv_out += sizeof(MrvlIETypes_ExtCap_t);
+
+ LEAVE();
+}
+#endif
+
/**
* @brief Get OTP user data
*
@@ -1895,42 +2065,64 @@ wlan_radio_ioctl_ant_cfg(IN pmlan_adapter pmadapter,
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_radio_cfg *radio_cfg = MNULL;
t_u16 cmd_action = 0;
- mlan_ds_ant_cfg *ant_cfg;
+ mlan_ds_ant_cfg *ant_cfg = MNULL;
+ t_u16 *ant_cfg_1x1 = MNULL;
ENTER();
radio_cfg = (mlan_ds_radio_cfg *) pioctl_req->pbuf;
- ant_cfg = &radio_cfg->param.ant_cfg;
+ if (IS_STREAM_2X2(pmadapter->feature_control))
+ ant_cfg = &radio_cfg->param.ant_cfg;
if (pioctl_req->action == MLAN_ACT_SET) {
/* User input validation */
- if (!ant_cfg->tx_antenna ||
- ant_cfg->tx_antenna & ~RF_ANTENNA_MASK(pmadapter->
- number_of_antenna)) {
- PRINTM(MERROR, "Invalid antenna setting\n");
- pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
- ret = MLAN_STATUS_FAILURE;
- goto exit;
- }
- if (ant_cfg->rx_antenna) {
- if (ant_cfg->
- rx_antenna & ~RF_ANTENNA_MASK(pmadapter->number_of_antenna)) {
+ if (IS_STREAM_2X2(pmadapter->feature_control)) {
+ if (!ant_cfg->tx_antenna ||
+ ant_cfg->tx_antenna & ~RF_ANTENNA_MASK(pmadapter->
+ number_of_antenna)) {
PRINTM(MERROR, "Invalid antenna setting\n");
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
ret = MLAN_STATUS_FAILURE;
goto exit;
}
- } else
- ant_cfg->rx_antenna = ant_cfg->tx_antenna;
+ if (ant_cfg->rx_antenna) {
+ if (ant_cfg->
+ rx_antenna & ~RF_ANTENNA_MASK(pmadapter->
+ number_of_antenna)) {
+ PRINTM(MERROR, "Invalid antenna setting\n");
+ pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
+ ret = MLAN_STATUS_FAILURE;
+ goto exit;
+ }
+ } else
+ ant_cfg->rx_antenna = ant_cfg->tx_antenna;
+ } else if ((!radio_cfg->param.antenna ||
+ radio_cfg->param.antenna & ~RF_ANTENNA_MASK(pmadapter->
+ number_of_antenna))
+ && (radio_cfg->param.antenna != RF_ANTENNA_AUTO ||
+ pmadapter->number_of_antenna <= 1)) {
+ PRINTM(MERROR, "Invalid antenna setting\n");
+ pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
+ ret = MLAN_STATUS_FAILURE;
+ goto exit;
+ }
cmd_action = HostCmd_ACT_GEN_SET;
} else
cmd_action = HostCmd_ACT_GEN_GET;
+ /* Cast it to t_u16, antenna mode for command HostCmd_CMD_802_11_RF_ANTENNA
+ requires 2 bytes */
+ if (!IS_STREAM_2X2(pmadapter->feature_control))
+ ant_cfg_1x1 = (t_u16 *) & radio_cfg->param.antenna;
+
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv,
HostCmd_CMD_802_11_RF_ANTENNA,
cmd_action,
- 0, (t_void *) pioctl_req, (t_void *) ant_cfg);
+ 0,
+ (t_void *) pioctl_req,
+ (IS_STREAM_2X2(pmadapter->feature_control)) ?
+ (t_void *) ant_cfg : (t_void *) ant_cfg_1x1);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
@@ -1940,6 +2132,78 @@ wlan_radio_ioctl_ant_cfg(IN pmlan_adapter pmadapter,
return ret;
}
+/**
+ * @brief Get rate bitmap
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_get_rate_bitmap(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
+
+ ENTER();
+
+ /* Send request to firmware */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_TX_RATE_CFG,
+ HostCmd_ACT_GEN_GET,
+ 0, (t_void *) pioctl_req, MNULL);
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Set rate bitmap
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_set_rate_bitmap(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_ds_rate *ds_rate = MNULL;
+ mlan_status ret = MLAN_STATUS_FAILURE;
+ mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ t_u16 *bitmap_rates = MNULL;
+
+ ENTER();
+
+ ds_rate = (mlan_ds_rate *) pioctl_req->pbuf;
+ bitmap_rates = ds_rate->param.rate_cfg.bitmap_rates;
+
+ PRINTM(MINFO, "RateBitmap=%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x, "
+ "IsRateAuto=%d, DataRate=%d\n",
+ bitmap_rates[9], bitmap_rates[8],
+ bitmap_rates[7], bitmap_rates[6],
+ bitmap_rates[5], bitmap_rates[4],
+ bitmap_rates[3], bitmap_rates[2],
+ bitmap_rates[1], bitmap_rates[0],
+ pmpriv->is_data_rate_auto, pmpriv->data_rate);
+
+ /* Send request to firmware */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_TX_RATE_CFG,
+ HostCmd_ACT_GEN_SET,
+ 0, (t_void *) pioctl_req, (t_void *) bitmap_rates);
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
+
+ LEAVE();
+ return ret;
+}
+
/**
* @brief Get rate value
*
@@ -2227,7 +2491,12 @@ wlan_rate_ioctl_cfg(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
ENTER();
rate = (mlan_ds_rate *) pioctl_req->pbuf;
- if (rate->param.rate_cfg.rate_type == MLAN_RATE_VALUE) {
+ if (rate->param.rate_cfg.rate_type == MLAN_RATE_BITMAP) {
+ if (pioctl_req->action == MLAN_ACT_GET)
+ status = wlan_rate_ioctl_get_rate_bitmap(pmadapter, pioctl_req);
+ else
+ status = wlan_rate_ioctl_set_rate_bitmap(pmadapter, pioctl_req);
+ } else if (rate->param.rate_cfg.rate_type == MLAN_RATE_VALUE) {
if (pioctl_req->action == MLAN_ACT_GET)
status = wlan_rate_ioctl_get_rate_value(pmadapter, pioctl_req);
else
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_scan.c b/drivers/net/wireless/sd8797/mlan/mlan_scan.c
index 677ac6b0200b..a9cffd6d84d2 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_scan.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_scan.c
@@ -97,19 +97,25 @@ typedef union
/** Cipher suite definition */
enum cipher_suite
{
+ CIPHER_SUITE_WEP40,
CIPHER_SUITE_TKIP,
CIPHER_SUITE_CCMP,
+ CIPHER_SUITE_WEP104,
CIPHER_SUITE_MAX
};
static t_u8 wpa_oui[CIPHER_SUITE_MAX][4] = {
+ {0x00, 0x50, 0xf2, 0x01}, /* WEP40 */
{0x00, 0x50, 0xf2, 0x02}, /* TKIP */
{0x00, 0x50, 0xf2, 0x04}, /* AES */
+ {0x00, 0x50, 0xf2, 0x05}, /* WEP104 */
};
static t_u8 rsn_oui[CIPHER_SUITE_MAX][4] = {
+ {0x00, 0x0f, 0xac, 0x01}, /* WEP40 */
{0x00, 0x0f, 0xac, 0x02}, /* TKIP */
{0x00, 0x0f, 0xac, 0x04}, /* AES */
+ {0x00, 0x0f, 0xac, 0x05}, /* WEP104 */
};
/**
@@ -839,6 +845,7 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv,
MrvlIEtypes_NumProbes_t *pnum_probes_tlv;
MrvlIEtypes_WildCardSsIdParamSet_t *pwildcard_ssid_tlv;
MrvlIEtypes_RatesParamSet_t *prates_tlv;
+
const t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0, 0, 0, 0, 0, 0 };
t_u8 *ptlv_pos;
t_u32 num_probes;
@@ -888,7 +895,6 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv,
/* Set the number of probes to send, use Adapter setting if unset */
num_probes = (puser_scan_in->num_probes ? puser_scan_in->num_probes :
pmadapter->scan_probes);
-
/*
* Set the BSSID filter to the incoming configuration,
* if non-zero. If not set, it will remain disabled (all zeros).
@@ -903,7 +909,7 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv,
ssid_idx++) {
ssid_len =
- wlan_strlen((t_s8 *) puser_scan_in->ssid_list[ssid_idx].ssid);
+ wlan_strlen((char *) puser_scan_in->ssid_list[ssid_idx].ssid);
pwildcard_ssid_tlv
= (MrvlIEtypes_WildCardSsIdParamSet_t *) ptlv_pos;
@@ -1008,6 +1014,8 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv,
pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len);
}
+ if (wlan_is_ext_capa_support(pmpriv))
+ wlan_add_ext_capa_info_ie(pmpriv, &ptlv_pos);
wlan_add_wps_probe_request_ie(pmpriv, &ptlv_pos);
/*
@@ -1271,10 +1279,8 @@ wlan_interpret_bss_desc_with_ie(IN pmlan_adapter pmadapter,
memcpy(pmadapter, pbss_entry->mac_address, pcurrent_ptr,
MLAN_MAC_ADDR_LENGTH);
- PRINTM(MINFO, "InterpretIE: AP MAC Addr-%02x:%02x:%02x:%02x:%02x:%02x\n",
- pbss_entry->mac_address[0], pbss_entry->mac_address[1],
- pbss_entry->mac_address[2], pbss_entry->mac_address[3],
- pbss_entry->mac_address[4], pbss_entry->mac_address[5]);
+ PRINTM(MINFO, "InterpretIE: AP MAC Addr-" MACSTR "\n",
+ MAC2STR(pbss_entry->mac_address));
pcurrent_ptr += MLAN_MAC_ADDR_LENGTH;
bytes_left_for_current_beacon -= MLAN_MAC_ADDR_LENGTH;
@@ -1595,7 +1601,7 @@ wlan_interpret_bss_desc_with_ie(IN pmlan_adapter pmadapter,
(IEEEtypes_OverlapBSSScanParam_t *) pcurrent_ptr;
pbss_entry->overlap_bss_offset =
(t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
- HEXDUMP("InterpretIE: Resp HTCAP_IE",
+ HEXDUMP("InterpretIE: Resp OBSS_IE",
(t_u8 *) pbss_entry->poverlap_bss_scan_param,
(*(pbss_entry->poverlap_bss_scan_param)).ieee_hdr.len +
sizeof(IEEEtypes_Header_t));
@@ -1974,11 +1980,9 @@ wlan_ret_802_11_scan_store_beacon(IN mlan_private * pmpriv,
* No space for new beacon
*/
PRINTM(MCMND, "AppControl: No space beacon (%d): "
- "%02x:%02x:%02x:%02x:%02x:%02x; sz=%03d, left=%03d\n",
+ MACSTR "; sz=%03d, left=%03d\n",
beacon_idx,
- pnew_beacon->mac_address[0], pnew_beacon->mac_address[1],
- pnew_beacon->mac_address[2], pnew_beacon->mac_address[3],
- pnew_beacon->mac_address[4], pnew_beacon->mac_address[5],
+ MAC2STR(pnew_beacon->mac_address),
pnew_beacon->beacon_buf_size,
(pmadapter->bcn_buf_size -
(pmadapter->pbcn_buf_end - pmadapter->bcn_buf)));
@@ -2138,15 +2142,10 @@ wlan_scan_process_results(IN mlan_private * pmpriv)
}
for (i = 0; i < pmadapter->num_in_scan_table; i++)
- PRINTM(MINFO, "Scan:(%02d) %02x:%02x:%02x:%02x:%02x:%02x, "
+ PRINTM(MINFO, "Scan:(%02d) " MACSTR ", "
"RSSI[%03d], SSID[%s]\n",
i,
- pmadapter->pscan_table[i].mac_address[0],
- pmadapter->pscan_table[i].mac_address[1],
- pmadapter->pscan_table[i].mac_address[2],
- pmadapter->pscan_table[i].mac_address[3],
- pmadapter->pscan_table[i].mac_address[4],
- pmadapter->pscan_table[i].mac_address[5],
+ MAC2STR(pmadapter->pscan_table[i].mac_address),
(t_s32) pmadapter->pscan_table[i].rssi,
pmadapter->pscan_table[i].ssid.ssid);
@@ -2473,6 +2472,25 @@ wlan_is_network_compatible(IN mlan_private * pmpriv,
/* Static WEP enabled */
PRINTM(MINFO, "Disable 11n in WEP mode\n");
pbss_desc->disable_11n = MTRUE;
+ /* Reject the following cases: */
+ /* case 1: RSN IE w/o WEP OUI and WPA IE w/o WEP OUI case 2: RSN IE
+ w/o WEP OUI and No WPA IE case 3: WPA IE w/o WEP OUI and No RSN
+ IE * */
+ if (((pbss_desc->prsn_ie) &&
+ ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id == RSN_IE)) ||
+ ((pbss_desc->pwpa_ie) &&
+ ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE))) {
+ if (!is_rsn_oui_present
+ (pmpriv->adapter, pbss_desc, CIPHER_SUITE_WEP40) &&
+ !is_rsn_oui_present(pmpriv->adapter, pbss_desc,
+ CIPHER_SUITE_WEP104) &&
+ !is_wpa_oui_present(pmpriv->adapter, pbss_desc,
+ CIPHER_SUITE_WEP40) &&
+ !is_wpa_oui_present(pmpriv->adapter, pbss_desc,
+ CIPHER_SUITE_WEP104))
+ index = -1;
+ }
+
LEAVE();
return index;
} else if (pmpriv->sec_info.wep_status == Wlan802_11WEPDisabled
@@ -2967,11 +2985,8 @@ wlan_ret_802_11_scan(IN mlan_private * pmpriv,
&pbss_info,
&bytes_left) ==
MLAN_STATUS_SUCCESS) {
- PRINTM(MINFO, "SCAN_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
- bss_new_entry->mac_address[0], bss_new_entry->mac_address[1],
- bss_new_entry->mac_address[2], bss_new_entry->mac_address[3],
- bss_new_entry->mac_address[4],
- bss_new_entry->mac_address[5]);
+ PRINTM(MINFO, "SCAN_RESP: BSSID = " MACSTR "\n",
+ MAC2STR(bss_new_entry->mac_address));
band = BAND_G;
if (pchan_band_tlv) {
@@ -3021,6 +3036,7 @@ wlan_ret_802_11_scan(IN mlan_private * pmpriv,
bss_new_entry->ssid.ssid_len))) {
PRINTM(MINFO, "SCAN_RESP: Duplicate of index: %d\n",
bss_idx);
+
break;
}
/*
@@ -3357,11 +3373,8 @@ wlan_parse_ext_scan_result(IN mlan_private * pmpriv,
&pbss_info,
&bytes_left) ==
MLAN_STATUS_SUCCESS) {
- PRINTM(MINFO, "EXT_SCAN: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
- bss_new_entry->mac_address[0], bss_new_entry->mac_address[1],
- bss_new_entry->mac_address[2], bss_new_entry->mac_address[3],
- bss_new_entry->mac_address[4],
- bss_new_entry->mac_address[5]);
+ PRINTM(MINFO, "EXT_SCAN: BSSID = " MACSTR "\n",
+ MAC2STR(bss_new_entry->mac_address));
band = BAND_G;
/*
@@ -3847,7 +3860,7 @@ wlan_cmd_bgscan_config(IN mlan_private * pmpriv,
&& (*bg_scan_in->ssid_list[ssid_idx].ssid ||
bg_scan_in->ssid_list[ssid_idx].max_len));
ssid_idx++) {
- ssid_len = wlan_strlen((t_s8 *) bg_scan_in->ssid_list[ssid_idx].ssid);
+ ssid_len = wlan_strlen((char *) bg_scan_in->ssid_list[ssid_idx].ssid);
pwildcard_ssid_tlv = (MrvlIEtypes_WildCardSsIdParamSet_t *) tlv;
pwildcard_ssid_tlv->header.type =
wlan_cpu_to_le16(TLV_TYPE_WILDCARDSSID);
@@ -4058,15 +4071,10 @@ wlan_find_ssid_in_list(IN mlan_private * pmpriv,
|| !memcmp(pmadapter, pmadapter->pscan_table[i].mac_address, bssid,
MLAN_MAC_ADDR_LENGTH))) {
- if (((mode == MLAN_BSS_MODE_INFRA) &&
- !wlan_is_band_compatible(pmpriv->config_bands,
- pmadapter->pscan_table[i].bss_band))
- ||
- (wlan_find_cfp_by_band_and_channel
- (pmadapter, (t_u8) pmadapter->pscan_table[i].bss_band,
- (t_u16) pmadapter->pscan_table[i].channel) == MNULL)) {
+ if ((mode == MLAN_BSS_MODE_INFRA) &&
+ !wlan_is_band_compatible(pmpriv->config_bands,
+ pmadapter->pscan_table[i].bss_band))
continue;
- }
switch (mode) {
case MLAN_BSS_MODE_INFRA:
@@ -4142,15 +4150,10 @@ wlan_find_bssid_in_list(IN mlan_private * pmpriv,
if (!memcmp
(pmadapter, pmadapter->pscan_table[i].mac_address, bssid,
MLAN_MAC_ADDR_LENGTH)) {
- if (((mode == MLAN_BSS_MODE_INFRA) &&
- !wlan_is_band_compatible(pmpriv->config_bands,
- pmadapter->pscan_table[i].bss_band))
- ||
- (wlan_find_cfp_by_band_and_channel
- (pmadapter, (t_u8) pmadapter->pscan_table[i].bss_band,
- (t_u16) pmadapter->pscan_table[i].channel) == MNULL)) {
+ if ((mode == MLAN_BSS_MODE_INFRA) &&
+ !wlan_is_band_compatible(pmpriv->config_bands,
+ pmadapter->pscan_table[i].bss_band))
continue;
- }
switch (mode) {
case MLAN_BSS_MODE_INFRA:
case MLAN_BSS_MODE_IBSS:
@@ -4262,11 +4265,8 @@ wlan_find_best_network(IN mlan_private * pmpriv,
}
PRINTM(MINFO, "Best network found = [%s], "
- "[%02x:%02x:%02x:%02x:%02x:%02x]\n",
- preq_ssid_bssid->ssid.ssid,
- preq_ssid_bssid->bssid[0], preq_ssid_bssid->bssid[1],
- preq_ssid_bssid->bssid[2], preq_ssid_bssid->bssid[3],
- preq_ssid_bssid->bssid[4], preq_ssid_bssid->bssid[5]);
+ "[" MACSTR "]\n",
+ preq_ssid_bssid->ssid.ssid, MAC2STR(preq_ssid_bssid->bssid));
done:
LEAVE();
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sdio.c b/drivers/net/wireless/sd8797/mlan/mlan_sdio.c
index 75799af4ae99..b7427c1682c1 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_sdio.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sdio.c
@@ -138,7 +138,7 @@ wlan_write_data_sync(mlan_adapter * pmadapter, mlan_buffer * pmbuf, t_u32 port)
ret);
if (MLAN_STATUS_SUCCESS !=
pcb->moal_write_reg(pmadapter->pmoal_handle,
- HOST_TO_CARD_EVENT_REG, 0x04)) {
+ HOST_TO_CARD_EVENT_REG, HOST_TERM_CMD53)) {
PRINTM(MERROR, "write CFG reg failed\n");
}
ret = MLAN_STATUS_FAILURE;
@@ -588,7 +588,7 @@ wlan_prog_fw_w_helper(IN pmlan_adapter pmadapter, IN pmlan_fw_image pmfw)
i, offset);
if (pcb->
moal_write_reg(pmadapter->pmoal_handle, HOST_TO_CARD_EVENT_REG,
- 0x04) != MLAN_STATUS_SUCCESS) {
+ HOST_TERM_CMD53) != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "write CFG reg failed\n");
}
ret = MLAN_STATUS_FAILURE;
@@ -1186,7 +1186,6 @@ wlan_interrupt(pmlan_adapter pmadapter)
t_u32 sdio_ireg = 0;
ENTER();
-
memset(pmadapter, &mbuf, 0, sizeof(mlan_buffer));
mbuf.pbuf = pmadapter->mp_regs;
mbuf.data_len = MAX_MP_REGS;
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sdio.h b/drivers/net/wireless/sd8797/mlan/mlan_sdio.h
index f77397d66eb4..b5eb87706d96 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_sdio.h
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sdio.h
@@ -27,9 +27,14 @@ Change log:
#define _MLAN_SDIO_H
/** Block mode */
+#ifndef BLOCK_MODE
#define BLOCK_MODE 1
+#endif
+
/** Fixed address mode */
+#ifndef FIXED_ADDRESS
#define FIXED_ADDRESS 0
+#endif
/* Host Control Registers */
/** Host Control Registers : Host to Card Event */
@@ -45,12 +50,14 @@ Change log:
/** Host Control Registers : Host interrupt RSR */
#define HOST_INT_RSR_REG 0x01
+
/** Host Control Registers : Upload host interrupt RSR */
#define UP_LD_HOST_INT_RSR (0x1U)
#define HOST_INT_RSR_MASK 0x3F
/** Host Control Registers : Host interrupt mask */
#define HOST_INT_MASK_REG 0x02
+
/** Host Control Registers : Upload host interrupt mask */
#define UP_LD_HOST_INT_MASK (0x1U)
/** Host Control Registers : Download host interrupt mask */
@@ -62,6 +69,7 @@ Change log:
/** Host Control Registers : Host interrupt status */
#define HOST_INT_STATUS_REG 0x03
+
/** Host Control Registers : Upload host interrupt status */
#define UP_LD_HOST_INT_STATUS (0x1U)
/** Host Control Registers : Download host interrupt status */
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_shim.c b/drivers/net/wireless/sd8797/mlan/mlan_shim.c
index ed7b89d535fb..4d650496039d 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_shim.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_shim.c
@@ -107,7 +107,7 @@ t_void(*assert_callback) (IN t_void * pmoal_handle, IN t_u32 cond) = MNULL;
/** Global moal_print callback */
t_void(*print_callback) (IN t_void * pmoal_handle,
- IN t_u32 level, IN t_s8 * pformat, IN ...) = MNULL;
+ IN t_u32 level, IN char *pformat, IN ...) = MNULL;
/** Global moal_get_system_time callback */
mlan_status(*get_sys_time_callback) (IN t_void * pmoal_handle,
@@ -115,7 +115,7 @@ mlan_status(*get_sys_time_callback) (IN t_void * pmoal_handle,
OUT t_u32 * pusec) = MNULL;
/** Global driver debug mit masks */
-t_u32 drvdbg = DEFAULT_DEBUG_MASK;
+t_u32 mlan_drvdbg = DEFAULT_DEBUG_MASK;
#endif
/********************************************************
@@ -178,15 +178,21 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
MASSERT(pmdevice->callbacks.moal_memmove);
/* Allocate memory for adapter structure */
- if ((pmdevice->callbacks.
- moal_malloc(pmdevice->pmoal_handle, sizeof(mlan_adapter), MLAN_MEM_DEF,
- (t_u8 **) & pmadapter) != MLAN_STATUS_SUCCESS)
- || !pmadapter) {
+ if (pmdevice->callbacks.moal_vmalloc && pmdevice->callbacks.moal_vfree)
+ ret = pmdevice->callbacks.moal_vmalloc(pmdevice->pmoal_handle,
+ sizeof(mlan_adapter),
+ (t_u8 **) & pmadapter);
+ else
+ ret = pmdevice->callbacks.moal_malloc(pmdevice->pmoal_handle,
+ sizeof(mlan_adapter),
+ MLAN_MEM_DEF,
+ (t_u8 **) & pmadapter);
+ if ((ret != MLAN_STATUS_SUCCESS) || !pmadapter) {
ret = MLAN_STATUS_FAILURE;
goto exit_register;
}
- pmdevice->callbacks.moal_memset(pmadapter, pmadapter,
+ pmdevice->callbacks.moal_memset(pmdevice->pmoal_handle, pmadapter,
0, sizeof(mlan_adapter));
pcb = &pmadapter->callbacks;
@@ -203,6 +209,7 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
MASSERT(pcb->moal_recv_packet);
MASSERT(pcb->moal_recv_event);
MASSERT(pcb->moal_ioctl_complete);
+
MASSERT(pcb->moal_write_reg);
MASSERT(pcb->moal_read_reg);
MASSERT(pcb->moal_alloc_mlan_buffer);
@@ -225,6 +232,8 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
/* Save pmoal_handle */
pmadapter->pmoal_handle = pmdevice->pmoal_handle;
+ pmadapter->feature_control = pmdevice->feature_control;
+
if ((pmdevice->int_mode == INT_MODE_GPIO) && (pmdevice->gpio_pin == 0)) {
PRINTM(MERROR, "SDIO_GPIO_INT_CONFIG: Invalid GPIO Pin\n");
ret = MLAN_STATUS_FAILURE;
@@ -238,7 +247,7 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
goto error;
}
#ifdef DEBUG_LEVEL1
- drvdbg = pmdevice->drvdbg;
+ mlan_drvdbg = pmdevice->drvdbg;
#endif
#ifdef MFG_CMD_SUPPORT
@@ -261,7 +270,9 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
#else
pmadapter->init_para.cfg_11d = 0;
#endif
- pmadapter->init_para.dfs_master_radar_det_en = DFS_MASTER_RADAR_DETECT_EN;
+ if (IS_DFS_SUPPORT(pmadapter->feature_control))
+ pmadapter->init_para.dfs_master_radar_det_en =
+ DFS_MASTER_RADAR_DETECT_EN;
pmadapter->init_para.dfs_slave_radar_det_en = DFS_SLAVE_RADAR_DETECT_EN;
pmadapter->priv_num = 0;
@@ -269,12 +280,17 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
pmadapter->priv[i] = MNULL;
if (pmdevice->bss_attr[i].active == MTRUE) {
/* For valid bss_attr, allocate memory for private structure */
- if ((pcb->
- moal_malloc(pmadapter->pmoal_handle, sizeof(mlan_private),
- MLAN_MEM_DEF,
- (t_u8 **) & pmadapter->priv[i]) !=
- MLAN_STATUS_SUCCESS)
- || !pmadapter->priv[i]) {
+ if (pcb->moal_vmalloc && pcb->moal_vfree)
+ ret =
+ pcb->moal_vmalloc(pmadapter->pmoal_handle,
+ sizeof(mlan_private),
+ (t_u8 **) & pmadapter->priv[i]);
+ else
+ ret =
+ pcb->moal_malloc(pmadapter->pmoal_handle,
+ sizeof(mlan_private), MLAN_MEM_DEF,
+ (t_u8 **) & pmadapter->priv[i]);
+ if (ret != MLAN_STATUS_SUCCESS || !pmadapter->priv[i]) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
@@ -296,8 +312,11 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_UAP)
pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_UAP;
#ifdef WIFI_DIRECT_SUPPORT
- else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
+ else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_STA;
+ if (pmdevice->bss_attr[i].bss_virtual)
+ pmadapter->priv[i]->bss_virtual = MTRUE;
+ }
#endif
/* Save bss_index and bss_num */
pmadapter->priv[i]->bss_index = i;
@@ -344,11 +363,19 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
/* Free lock variables */
wlan_free_lock_list(pmadapter);
for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
- if (pmadapter->priv[i])
- pcb->moal_mfree(pmadapter->pmoal_handle,
- (t_u8 *) pmadapter->priv[i]);
+ if (pmadapter->priv[i]) {
+ if (pcb->moal_vmalloc && pcb->moal_vfree)
+ pcb->moal_vfree(pmadapter->pmoal_handle,
+ (t_u8 *) pmadapter->priv[i]);
+ else
+ pcb->moal_mfree(pmadapter->pmoal_handle,
+ (t_u8 *) pmadapter->priv[i]);
+ }
}
- pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter);
+ if (pcb->moal_vmalloc && pcb->moal_vfree)
+ pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter);
+ else
+ pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter);
exit_register:
LEAVE();
@@ -390,13 +417,20 @@ mlan_unregister(IN t_void * pmlan_adapter)
/* Free private structures */
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i]) {
- pcb->moal_mfree(pmadapter->pmoal_handle,
- (t_u8 *) pmadapter->priv[i]);
+ if (pcb->moal_vmalloc && pcb->moal_vfree)
+ pcb->moal_vfree(pmadapter->pmoal_handle,
+ (t_u8 *) pmadapter->priv[i]);
+ else
+ pcb->moal_mfree(pmadapter->pmoal_handle,
+ (t_u8 *) pmadapter->priv[i]);
}
}
/* Free mlan_adapter */
- pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter);
+ if (pcb->moal_vmalloc && pcb->moal_vfree)
+ pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter);
+ else
+ pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *) pmadapter);
LEAVE();
return ret;
@@ -595,22 +629,9 @@ mlan_shutdown_fw(IN t_void * pmlan_adapter)
pcb = &pmadapter->callbacks;
- if (pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->pmlan_lock)
- != MLAN_STATUS_SUCCESS) {
- ret = MLAN_STATUS_FAILURE;
- goto exit_shutdown_fw;
- }
-
- if (pcb->moal_spin_unlock(pmadapter->pmoal_handle, pmadapter->pmlan_lock)
- != MLAN_STATUS_SUCCESS) {
- ret = MLAN_STATUS_FAILURE;
- goto exit_shutdown_fw;
- }
-
/* Notify completion */
ret = wlan_shutdown_fw_complete(pmadapter);
- exit_shutdown_fw:
LEAVE();
return ret;
}
@@ -639,6 +660,7 @@ mlan_main_process(IN t_void * pmlan_adapter)
/* Check if already processing */
if (pmadapter->mlan_processing) {
+ pmadapter->more_task_flag = MTRUE;
pcb->moal_spin_unlock(pmadapter->pmoal_handle,
pmadapter->pmain_proc_lock);
goto exit_main_proc;
@@ -649,6 +671,11 @@ mlan_main_process(IN t_void * pmlan_adapter)
}
process_start:
do {
+ pcb->moal_spin_lock(pmadapter->pmoal_handle,
+ pmadapter->pmain_proc_lock);
+ pmadapter->more_task_flag = MFALSE;
+ pcb->moal_spin_unlock(pmadapter->pmoal_handle,
+ pmadapter->pmain_proc_lock);
/* Is MLAN shutting down or not ready? */
if ((pmadapter->hw_status == WlanHardwareStatusClosing) ||
(pmadapter->hw_status == WlanHardwareStatusNotReady))
@@ -694,7 +721,8 @@ mlan_main_process(IN t_void * pmlan_adapter)
(pmadapter->tx_lock_flag == MTRUE))
break;
- if (pmadapter->scan_processing || pmadapter->data_sent
+ if (pmadapter->scan_processing
+ || pmadapter->data_sent
|| (wlan_bypass_tx_list_empty(pmadapter) &&
wlan_wmm_lists_empty(pmadapter))
|| wlan_11h_radar_detected_tx_blocked(pmadapter)
@@ -751,7 +779,8 @@ mlan_main_process(IN t_void * pmlan_adapter)
}
}
- if (!pmadapter->scan_processing && !pmadapter->data_sent &&
+ if (!pmadapter->scan_processing
+ && !pmadapter->data_sent &&
!wlan_11h_radar_detected_tx_blocked(pmadapter) &&
!wlan_bypass_tx_list_empty(pmadapter)) {
PRINTM(MINFO, "mlan_send_pkt(): deq(bybass_txq)\n");
@@ -764,8 +793,8 @@ mlan_main_process(IN t_void * pmlan_adapter)
}
}
- if (!pmadapter->scan_processing && !pmadapter->data_sent &&
- !wlan_wmm_lists_empty(pmadapter)
+ if (!pmadapter->scan_processing
+ && !pmadapter->data_sent && !wlan_wmm_lists_empty(pmadapter)
&& !wlan_11h_radar_detected_tx_blocked(pmadapter)
) {
wlan_wmm_process_tx(pmadapter);
@@ -795,10 +824,12 @@ mlan_main_process(IN t_void * pmlan_adapter)
} while (MTRUE);
- if ((pmadapter->sdio_ireg) || IS_CARD_RX_RCVD(pmadapter)) {
+ pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->pmain_proc_lock);
+ if (pmadapter->more_task_flag == MTRUE) {
+ pcb->moal_spin_unlock(pmadapter->pmoal_handle,
+ pmadapter->pmain_proc_lock);
goto process_start;
}
- pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->pmain_proc_lock);
pmadapter->mlan_processing = MFALSE;
pcb->moal_spin_unlock(pmadapter->pmoal_handle, pmadapter->pmain_proc_lock);
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c
index 787e5784ed43..52b6bced6009 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c
@@ -86,40 +86,6 @@ wlan_cmd_802_11_rssi_info(IN pmlan_private pmpriv,
}
/**
- * @brief This function prepares command of mac_control.
- *
- * @param pmpriv A pointer to mlan_private structure
- * @param pcmd A pointer to HostCmd_DS_COMMAND structure
- * @param cmd_action Command action
- * @param pdata_buf A pointer to command information buffer
- *
- * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
- */
-static mlan_status
-wlan_cmd_mac_control(IN pmlan_private pmpriv,
- IN HostCmd_DS_COMMAND * pcmd,
- IN t_u16 cmd_action, IN t_void * pdata_buf)
-{
- HostCmd_DS_MAC_CONTROL *pmac = &pcmd->params.mac_ctrl;
- t_u16 action = *((t_u16 *) pdata_buf);
-
- ENTER();
-
- if (cmd_action != HostCmd_ACT_GEN_SET) {
- PRINTM(MERROR, "wlan_cmd_mac_control(): support SET only.\n");
- LEAVE();
- return MLAN_STATUS_FAILURE;
- }
-
- pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
- pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_CONTROL) + S_DS_GEN);
- pmac->action = wlan_cpu_to_le16(action);
-
- LEAVE();
- return MLAN_STATUS_SUCCESS;
-}
-
-/**
* @brief This function prepares command of snmp_mib.
*
* @param pmpriv A pointer to mlan_private structure
@@ -355,6 +321,41 @@ wlan_cmd_802_11_rf_tx_power(IN pmlan_private pmpriv,
return MLAN_STATUS_SUCCESS;
}
+#ifdef WIFI_DIRECT_SUPPORT
+/**
+ * @brief Check if any p2p interface is conencted
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ *
+ * @return MTRUE/MFALSE;
+ */
+static t_u8
+wlan_is_p2p_connected(IN pmlan_adapter pmadapter)
+{
+ int j;
+ pmlan_private priv;
+ ENTER();
+ for (j = 0; j < pmadapter->priv_num; ++j) {
+ if ((priv = pmadapter->priv[j])) {
+ if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
+ if ((priv->bss_role == MLAN_BSS_ROLE_STA) &&
+ (priv->media_connected == MTRUE)) {
+ LEAVE();
+ return MTRUE;
+ }
+ if ((priv->bss_role == MLAN_BSS_ROLE_UAP) &&
+ (priv->uap_bss_started == MTRUE)) {
+ LEAVE();
+ return MTRUE;
+ }
+ }
+ }
+ }
+ LEAVE();
+ return MFALSE;
+}
+#endif
+
/**
* @brief This function prepares command of hs_cfg.
*
@@ -373,6 +374,8 @@ wlan_cmd_802_11_hs_cfg(IN pmlan_private pmpriv,
pmlan_adapter pmadapter = pmpriv->adapter;
HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg = &cmd->params.opt_hs_cfg;
t_u16 hs_activate = MFALSE;
+ t_u8 *tlv = (t_u8 *) phs_cfg + sizeof(HostCmd_DS_802_11_HS_CFG_ENH);
+ MrvlIEtypes_HsWakeHoldoff_t *holdoff_tlv = MNULL;
ENTER();
@@ -391,25 +394,49 @@ wlan_cmd_802_11_hs_cfg(IN pmlan_private pmpriv,
((t_u8 *) phs_cfg) + sizeof(HostCmd_DS_802_11_HS_CFG_ENH),
pmadapter->arp_filter, pmadapter->arp_filter_size);
cmd->size =
- (t_u16) wlan_cpu_to_le16(pmadapter->arp_filter_size +
- sizeof(HostCmd_DS_802_11_HS_CFG_ENH) +
- S_DS_GEN);
+ pmadapter->arp_filter_size + sizeof(HostCmd_DS_802_11_HS_CFG_ENH) +
+ S_DS_GEN;
+ tlv =
+ (t_u8 *) phs_cfg + sizeof(HostCmd_DS_802_11_HS_CFG_ENH) +
+ pmadapter->arp_filter_size;
} else
- cmd->size =
- wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_802_11_HS_CFG_ENH));
+ cmd->size = S_DS_GEN + sizeof(HostCmd_DS_802_11_HS_CFG_ENH);
if (hs_activate) {
+ cmd->size = wlan_cpu_to_le16(cmd->size);
phs_cfg->action = wlan_cpu_to_le16(HS_ACTIVATE);
phs_cfg->params.hs_activate.resp_ctrl = wlan_cpu_to_le16(RESP_NEEDED);
} else {
phs_cfg->action = wlan_cpu_to_le16(HS_CONFIGURE);
- phs_cfg->params.hs_config.conditions =
- wlan_cpu_to_le32(pdata_buf->conditions);
+#ifdef WIFI_DIRECT_SUPPORT
+ if (wlan_is_p2p_connected(pmadapter))
+ phs_cfg->params.hs_config.conditions =
+ wlan_cpu_to_le32(pdata_buf->
+ conditions | HOST_SLEEP_COND_MULTICAST_DATA);
+ else
+#endif
+ phs_cfg->params.hs_config.conditions =
+ wlan_cpu_to_le32(pdata_buf->conditions);
phs_cfg->params.hs_config.gpio = pdata_buf->gpio;
phs_cfg->params.hs_config.gap = pdata_buf->gap;
- PRINTM(MCMND, "HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
+ if (pmadapter->min_wake_holdoff) {
+ cmd->size += sizeof(MrvlIEtypes_HsWakeHoldoff_t);
+ holdoff_tlv = (MrvlIEtypes_HsWakeHoldoff_t *) tlv;
+ holdoff_tlv->header.type =
+ wlan_cpu_to_le16(TLV_TYPE_HS_WAKE_HOLDOFF);
+ holdoff_tlv->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_HsWakeHoldoff_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ holdoff_tlv->min_wake_holdoff =
+ wlan_cpu_to_le16(pmadapter->min_wake_holdoff);
+ PRINTM(MCMND, "min_wake_holdoff=%d\n", pmadapter->min_wake_holdoff);
+ }
+ cmd->size = wlan_cpu_to_le16(cmd->size);
+ PRINTM(MCMND,
+ "HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x holdoff=%d\n",
phs_cfg->params.hs_config.conditions,
- phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap);
+ phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap,
+ pmadapter->min_wake_holdoff);
}
LEAVE();
@@ -578,9 +605,7 @@ wlan_cmd_802_11_deauthenticate(IN pmlan_private pmpriv,
memcpy(pmpriv->adapter, pdeauth->mac_addr, (t_u8 *) pdata_buf,
MLAN_MAC_ADDR_LENGTH);
- PRINTM(MCMND, "Deauth: %02x:%02x:%02x:%02x:%02x:%02x\n",
- pdeauth->mac_addr[0], pdeauth->mac_addr[1], pdeauth->mac_addr[2],
- pdeauth->mac_addr[3], pdeauth->mac_addr[4], pdeauth->mac_addr[5]);
+ PRINTM(MCMND, "Deauth: " MACSTR "\n", MAC2STR(pdeauth->mac_addr));
if (pmpriv->adapter->state_11h.recvd_chanswann_event) {
/** Reason code 36 = Requested from peer station as it is leaving the BSS */
@@ -621,74 +646,6 @@ wlan_cmd_802_11_ad_hoc_stop(IN pmlan_private pmpriv,
}
/**
- * @brief This function sets WEP key(s) to key_param_set TLV(s).
- *
- * @param priv A pointer to mlan_private structure
- * @param key_param_set A pointer to MrvlIEtype_KeyParamSet_t structure
- * @param key_param_len A pointer to the length variable
- *
- * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
- */
-static mlan_status
-wlan_set_keyparamset_wep(mlan_private * priv,
- MrvlIEtype_KeyParamSet_t * key_param_set,
- t_u16 * key_param_len)
-{
- int cur_key_param_len = 0;
- t_u8 i;
- mlan_status ret = MLAN_STATUS_SUCCESS;
-
- ENTER();
-
- /* Multi-key_param_set TLV is supported */
- for (i = 0; i < MRVL_NUM_WEP_KEY; i++) {
- if ((priv->wep_key[i].key_length == WEP_40_BIT_LEN) ||
- (priv->wep_key[i].key_length == WEP_104_BIT_LEN)) {
- key_param_set->type = wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
-/** Key_param_set WEP fixed length */
-#define KEYPARAMSET_WEP_FIXED_LEN 8
- key_param_set->length =
- wlan_cpu_to_le16((t_u16)
- (priv->wep_key[i].key_length +
- KEYPARAMSET_WEP_FIXED_LEN));
- key_param_set->key_type_id = wlan_cpu_to_le16(KEY_TYPE_ID_WEP);
- key_param_set->key_info = wlan_cpu_to_le16
- (KEY_INFO_WEP_ENABLED | KEY_INFO_WEP_UNICAST |
- KEY_INFO_WEP_MCAST);
- key_param_set->key_len =
- (t_u16) wlan_cpu_to_le16(priv->wep_key[i].key_length);
- /* Set WEP key index */
- key_param_set->key[0] = i;
- /* Set default Tx key flag */
- if (i == (priv->wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK))
- key_param_set->key[1] = 1;
- else
- key_param_set->key[1] = 0;
- memmove(priv->adapter, &key_param_set->key[2],
- priv->wep_key[i].key_material, priv->wep_key[i].key_length);
-
- cur_key_param_len = priv->wep_key[i].key_length +
- KEYPARAMSET_WEP_FIXED_LEN + sizeof(MrvlIEtypesHeader_t);
- *key_param_len += (t_u16) cur_key_param_len;
- key_param_set =
- (MrvlIEtype_KeyParamSet_t *) ((t_u8 *) key_param_set +
- cur_key_param_len);
- } else if (!priv->wep_key[i].key_length) {
- continue;
- } else {
- PRINTM(MERROR, "key%d Length = %d is incorrect\n", (i + 1),
- priv->wep_key[i].key_length);
- ret = MLAN_STATUS_FAILURE;
- goto done;
- }
- }
-
- done:
- LEAVE();
- return ret;
-}
-
-/**
* @brief This function prepares command of key_material.
*
* @param pmpriv A pointer to mlan_private structure
@@ -707,186 +664,203 @@ wlan_cmd_802_11_key_material(IN pmlan_private pmpriv,
{
HostCmd_DS_802_11_KEY_MATERIAL *pkey_material = &cmd->params.key_material;
mlan_ds_encrypt_key *pkey = (mlan_ds_encrypt_key *) pdata_buf;
- t_u16 key_param_len = 0;
mlan_status ret = MLAN_STATUS_SUCCESS;
- const t_u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
ENTER();
-
+ if (!pkey) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
pkey_material->action = wlan_cpu_to_le16(cmd_action);
-
if (cmd_action == HostCmd_ACT_GEN_GET) {
- cmd->size =
- wlan_cpu_to_le16(sizeof(pkey_material->action) + S_DS_GEN +
- KEYPARAMSET_FIXED_LEN +
- sizeof(MrvlIEtypesHeader_t));
- memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
- sizeof(MrvlIEtype_KeyParamSet_t));
+ PRINTM(MCMND, "GET Key\n");
+ pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
pkey_material->key_param_set.type =
- wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+ wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
pkey_material->key_param_set.length =
- wlan_cpu_to_le16(KEYPARAMSET_FIXED_LEN);
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.mac_addr,
+ pkey->mac_addr, MLAN_MAC_ADDR_LENGTH);
if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
else
pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
if (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)
- pkey_material->key_param_set.key_info = KEY_INFO_AES_MCAST_IGTK;
+ pkey_material->key_param_set.key_info = KEY_INFO_CMAC_AES_KEY;
pkey_material->key_param_set.key_info =
wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN +
+ sizeof(pkey_material->action));
goto done;
}
-
- if (!pkey) {
- memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
- (MRVL_NUM_WEP_KEY * sizeof(MrvlIEtype_KeyParamSet_t)));
- ret =
- wlan_set_keyparamset_wep(pmpriv, &pkey_material->key_param_set,
- &key_param_len);
+ memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
+ sizeof(MrvlIEtype_KeyParamSetV2_t));
+ if (pkey->key_flags & KEY_FLAG_REMOVE_KEY) {
+ pkey_material->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_REMOVE);
+ pkey_material->key_param_set.type =
+ wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
+ pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
+ pkey_material->key_param_set.key_info =
+ KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY;
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.mac_addr,
+ pkey->mac_addr, MLAN_MAC_ADDR_LENGTH);
cmd->size =
- wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
- S_DS_GEN);
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Remove Key\n");
goto done;
- } else
- memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
- sizeof(MrvlIEtype_KeyParamSet_t));
- if (pkey->is_wapi_key) {
- PRINTM(MINFO, "Set WAPI Key\n");
- pkey_material->key_param_set.key_type_id =
- wlan_cpu_to_le16(KEY_TYPE_ID_WAPI);
- if (cmd_oid == KEY_INFO_ENABLED)
- pkey_material->key_param_set.key_info =
- wlan_cpu_to_le16(KEY_INFO_WAPI_ENABLED);
- else
- pkey_material->key_param_set.key_info =
- !(wlan_cpu_to_le16(KEY_INFO_WAPI_ENABLED));
-
- pkey_material->key_param_set.key[0] = (t_u8) pkey->key_index;
- if (!pmpriv->sec_info.wapi_key_on)
- pkey_material->key_param_set.key[1] = 1;
- else
- pkey_material->key_param_set.key[1] = 0; /* set 0 when re-key */
-
- if (0 != memcmp(pmpriv->adapter, pkey->mac_addr, bc_mac, sizeof(bc_mac))) /* WAPI
- pairwise
- key:
- unicast
- */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_WAPI_UNICAST);
- else { /* WAPI group key: multicast */
+ }
+ pkey_material->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
+ pkey_material->key_param_set.type = wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
+ pkey_material->key_param_set.key_info = KEY_INFO_ENABLE_KEY;
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.mac_addr,
+ pkey->mac_addr, MLAN_MAC_ADDR_LENGTH);
+ if (pkey->key_len <= MAX_WEP_KEY_SIZE) {
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(wep_param_t));
+ pkey_material->key_param_set.key_type = KEY_TYPE_ID_WEP;
+ if (pkey->is_current_wep_key) {
pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_WAPI_MCAST);
- pmpriv->sec_info.wapi_key_on = MTRUE;
+ KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY;
+ if (pkey_material->key_param_set.key_idx ==
+ (pmpriv->wep_key_curr_index & KEY_INDEX_MASK))
+ pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
+ } else {
+ if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
+ pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
+ else
+ pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
+ if (pkey->key_flags & KEY_FLAG_SET_TX_KEY)
+ pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
}
-
- pkey_material->key_param_set.type =
- wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
- pkey_material->key_param_set.key_len = wlan_cpu_to_le16(WAPI_KEY_LEN);
- memcpy(pmpriv->adapter, &pkey_material->key_param_set.key[2],
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
+ pkey_material->key_param_set.key_params.wep.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.key_params.wep.key,
pkey->key_material, pkey->key_len);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(wep_param_t) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set WEP Key\n");
+ goto done;
+ }
+ if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
+ pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
+ else
+ pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
+ if (pkey->key_flags & KEY_FLAG_SET_TX_KEY)
+ pkey_material->key_param_set.key_info |=
+ KEY_INFO_TX_KEY | KEY_INFO_RX_KEY;
+ else
+ pkey_material->key_param_set.key_info |= KEY_INFO_RX_KEY;
+ if (pkey->is_wapi_key) {
+ pkey_material->key_param_set.key_type = KEY_TYPE_ID_WAPI;
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.key_params.wapi.pn,
+ pkey->pn, PN_SIZE);
+ pkey_material->key_param_set.key_params.wapi.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
memcpy(pmpriv->adapter,
- &pkey_material->key_param_set.key[2 + pkey->key_len], pkey->pn,
- PN_SIZE);
+ pkey_material->key_param_set.key_params.wapi.key,
+ pkey->key_material, pkey->key_len);
+ if (!pmpriv->sec_info.wapi_key_on)
+ pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
+ if (pkey->key_flags & KEY_FLAG_GROUP_KEY)
+ pmpriv->sec_info.wapi_key_on = MTRUE;
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
pkey_material->key_param_set.length =
- wlan_cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
-
- key_param_len =
- (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
- sizeof(MrvlIEtypesHeader_t);
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(wapi_param));
cmd->size =
- wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
- S_DS_GEN);
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(wapi_param) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set WAPI Key\n");
goto done;
}
- /* IGTK key length is the same as AES key length */
+ if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) {
+ /* Enable default key for WPA/WPA2 */
+ if (!pmpriv->wpa_is_gtk_set)
+ pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
+ } else {
+ pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
+ /* Enable unicast bit for WPA-NONE/ADHOC_AES */
+ if ((!pmpriv->sec_info.wpa2_enabled) &&
+ (pkey->key_flags & KEY_FLAG_SET_TX_KEY))
+ pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
+ }
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
if (pkey->key_len == WPA_AES_KEY_LEN &&
!(pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
- PRINTM(MCMND, "WPA_AES\n");
- pkey_material->key_param_set.key_type_id =
- wlan_cpu_to_le16(KEY_TYPE_ID_AES);
- if (cmd_oid == KEY_INFO_ENABLED)
- pkey_material->key_param_set.key_info =
- wlan_cpu_to_le16(KEY_INFO_AES_ENABLED);
- else
- pkey_material->key_param_set.key_info =
- !(wlan_cpu_to_le16(KEY_INFO_AES_ENABLED));
-
- if (pkey->key_index & MLAN_KEY_INDEX_UNICAST) /* AES pairwise key:
- unicast */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_AES_UNICAST);
- else { /* AES group key: multicast */
-
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_AES_MCAST);
- }
- } else if ((pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK) &&
- pkey->key_len == WPA_IGTK_KEY_LEN) {
- PRINTM(MCMND, "WPA_AES_CMAC\n");
- pkey_material->key_param_set.key_type_id =
- wlan_cpu_to_le16(KEY_TYPE_ID_AES_CMAC);
- if (cmd_oid == KEY_INFO_ENABLED)
- pkey_material->key_param_set.key_info =
- wlan_cpu_to_le16(KEY_INFO_AES_ENABLED);
- else
- pkey_material->key_param_set.key_info =
- !(wlan_cpu_to_le16(KEY_INFO_AES_ENABLED));
-
+ if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.aes.pn, pkey->pn,
+ SEQ_MAX_SIZE);
+ pkey_material->key_param_set.key_type = KEY_TYPE_ID_AES;
+ pkey_material->key_param_set.key_params.aes.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.key_params.aes.key,
+ pkey->key_material, pkey->key_len);
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(aes_param));
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(aes_param) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set AES Key\n");
+ goto done;
+ }
+ if (pkey->key_len == WPA_IGTK_KEY_LEN &&
+ (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
+ if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.cmac_aes.ipn,
+ pkey->pn, SEQ_MAX_SIZE);
+ pkey_material->key_param_set.key_info &= ~KEY_INFO_MCAST_KEY;
pkey_material->key_param_set.key_info |=
wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
- } else if (pkey->key_len == WPA_TKIP_KEY_LEN) {
- PRINTM(MCMND, "WPA_TKIP\n");
- pkey_material->key_param_set.key_type_id =
- wlan_cpu_to_le16(KEY_TYPE_ID_TKIP);
- pkey_material->key_param_set.key_info =
- wlan_cpu_to_le16(KEY_INFO_TKIP_ENABLED);
-
- if (pkey->key_index & MLAN_KEY_INDEX_UNICAST) /* TKIP pairwise key:
- unicast */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_TKIP_UNICAST);
- else /* TKIP group key: multicast */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_TKIP_MCAST);
+ pkey_material->key_param_set.key_type = KEY_TYPE_ID_AES_CMAC;
+ pkey_material->key_param_set.key_params.cmac_aes.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.cmac_aes.key,
+ pkey->key_material, pkey->key_len);
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(cmac_aes_param));
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(cmac_aes_param) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set CMAC AES Key\n");
+ goto done;
}
-
- if (pkey_material->key_param_set.key_type_id) {
- pkey_material->key_param_set.type =
- wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
- pkey_material->key_param_set.key_len =
- wlan_cpu_to_le16((t_u16) pkey->key_len);
- memcpy(pmpriv->adapter, pkey_material->key_param_set.key,
+ if (pkey->key_len == WPA_TKIP_KEY_LEN) {
+ if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.tkip.pn, pkey->pn,
+ SEQ_MAX_SIZE);
+ pkey_material->key_param_set.key_type = KEY_TYPE_ID_TKIP;
+ pkey_material->key_param_set.key_params.tkip.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.tkip.key,
pkey->key_material, pkey->key_len);
pkey_material->key_param_set.length =
- wlan_cpu_to_le16((t_u16) pkey->key_len + KEYPARAMSET_FIXED_LEN);
- key_param_len =
- (t_u16) (pkey->key_len + KEYPARAMSET_FIXED_LEN) +
- sizeof(MrvlIEtypesHeader_t);
-
- /* key format with pn field is defined in Key Material V1 */
- if (pkey_material->key_param_set.key_type_id ==
- wlan_cpu_to_le16(KEY_TYPE_ID_AES_CMAC)) {
- cmac_param *param;
- param = (cmac_param *) pkey_material->key_param_set.key;
- memcpy(pmpriv->adapter, param->ipn, pkey->pn, SEQ_MAX_SIZE);
- memcpy(pmpriv->adapter, param->key, pkey->key_material,
- pkey->key_len);
-
- pkey_material->key_param_set.key_len =
- wlan_cpu_to_le16((t_u16) sizeof(cmac_param));
- pkey_material->key_param_set.length =
- wlan_cpu_to_le16((t_u16) sizeof(cmac_param) +
- KEYPARAMSET_FIXED_LEN);
- key_param_len =
- (t_u16) (sizeof(cmac_param) + KEYPARAMSET_FIXED_LEN) +
- sizeof(MrvlIEtypesHeader_t);
- }
-
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(tkip_param));
cmd->size =
- wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
- S_DS_GEN);
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(tkip_param) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set TKIP Key\n");
}
done:
LEAVE();
@@ -1024,7 +998,8 @@ wlan_cmd_802_11_supplicant_profile(IN pmlan_private pmpriv,
IN t_u16 cmd_action, IN t_void * pdata_buf)
{
HostCmd_DS_802_11_SUPPLICANT_PROFILE *sup_profile =
- &cmd->params.esupplicant_profile;
+ (HostCmd_DS_802_11_SUPPLICANT_PROFILE *) & (cmd->params.
+ esupplicant_profile);
MrvlIEtypes_EncrProto_t *encr_proto_tlv = MNULL;
MrvlIEtypes_Cipher_t *pcipher_tlv = MNULL;
t_u8 *ptlv_buffer = (t_u8 *) sup_profile->tlv_buf;
@@ -1296,8 +1271,7 @@ wlan_cmd_subscribe_event(IN pmlan_private pmpriv,
cmd_size = sizeof(HostCmd_DS_SUBSCRIBE_EVENT) + S_DS_GEN;
if (cmd_action == HostCmd_ACT_GEN_GET)
goto done;
-#define HostCmd_ACT_BITWISE_SET 0x02
- evt->action = wlan_cpu_to_le16(HostCmd_ACT_BITWISE_SET);
+ evt->action = wlan_cpu_to_le16(sub_evt->evt_action);
evt->event_bitmap = wlan_cpu_to_le16(sub_evt->evt_bitmap);
tlv = (t_u8 *) cmd + cmd_size;
if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_RSSI_LOW) {
@@ -1660,7 +1634,8 @@ wlan_ops_sta_prepare_cmd(IN t_void * priv,
cmd_ptr->params.rx_mgmt_ind.action = wlan_cpu_to_le16(cmd_action);
cmd_ptr->params.rx_mgmt_ind.mgmt_subtype_mask =
wlan_cpu_to_le32((t_u32) (*((t_u32 *) pdata_buf)));
- cmd_ptr->size = wlan_cpu_to_le16(sizeof(t_u32) + S_DS_GEN);
+ cmd_ptr->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_RX_MGMT_IND) + S_DS_GEN);
break;
case HostCmd_CMD_802_11_RF_CHANNEL:
ret =
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c
index 5b9a2508e986..ce9e70efbfe7 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c
@@ -32,7 +32,6 @@ Change log:
#include "mlan_wmm.h"
#include "mlan_11n.h"
#include "mlan_11h.h"
-
#include "mlan_sdio.h"
#include "mlan_meas.h"
@@ -95,6 +94,9 @@ wlan_process_cmdresp_error(mlan_private * pmpriv, HostCmd_DS_COMMAND * resp,
case HostCmd_CMD_MAC_CONTROL:
break;
+ case HostCmd_CMD_802_11_ASSOCIATE:
+ wlan_reset_connect_state(pmpriv, MTRUE);
+ break;
default:
break;
}
@@ -128,6 +130,8 @@ wlan_ret_802_11_rssi_info(IN pmlan_private pmpriv,
HostCmd_DS_802_11_RSSI_INFO_RSP *prssi_info_rsp =
&resp->params.rssi_info_rsp;
mlan_ds_get_info *pget_info = MNULL;
+ BSSDescriptor_t *pbss_desc;
+ t_s32 tbl_idx = 0;
ENTER();
@@ -143,6 +147,16 @@ wlan_ret_802_11_rssi_info(IN pmlan_private pmpriv,
pmpriv->bcn_rssi_avg = wlan_le16_to_cpu(prssi_info_rsp->bcn_rssi_avg);
pmpriv->bcn_nf_avg = wlan_le16_to_cpu(prssi_info_rsp->bcn_nf_avg);
+ /* Get current BSS info */
+ pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
+ tbl_idx =
+ wlan_find_ssid_in_list(pmpriv, &pbss_desc->ssid, pbss_desc->mac_address,
+ pmpriv->bss_mode);
+ if (tbl_idx >= 0) {
+ pbss_desc = &pmpriv->adapter->pscan_table[tbl_idx];
+ pbss_desc->rssi = -pmpriv->bcn_rssi_avg;
+ }
+
/* Need to indicate IOCTL complete */
if (pioctl_buf != MNULL) {
pget_info = (mlan_ds_get_info *) pioctl_buf->pbuf;
@@ -182,25 +196,6 @@ wlan_ret_802_11_rssi_info(IN pmlan_private pmpriv,
}
/**
- * @brief This function handles the command response of mac_control
- *
- * @param pmpriv A pointer to mlan_private structure
- * @param resp A pointer to HostCmd_DS_COMMAND
- * @param pioctl_buf A pointer to mlan_ioctl_req structure
- *
- * @return MLAN_STATUS_SUCCESS
- */
-static mlan_status
-wlan_ret_mac_control(IN pmlan_private pmpriv,
- IN HostCmd_DS_COMMAND * resp,
- IN mlan_ioctl_req * pioctl_buf)
-{
- ENTER();
- LEAVE();
- return MLAN_STATUS_SUCCESS;
-}
-
-/**
* @brief This function handles the command response of snmp_mib
*
* @param pmpriv A pointer to mlan_private structure
@@ -325,6 +320,7 @@ wlan_ret_get_log(IN pmlan_private pmpriv,
mlan_ds_get_info *pget_info = MNULL;
ENTER();
+
if (pioctl_buf) {
pget_info = (mlan_ds_get_info *) pioctl_buf->pbuf;
pget_info->param.stats.mcast_tx_frame =
@@ -355,6 +351,10 @@ wlan_ret_get_log(IN pmlan_private pmpriv,
wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[2]);
pget_info->param.stats.wep_icv_error[3] =
wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[3]);
+ pget_info->param.stats.bcn_rcv_cnt =
+ wlan_le32_to_cpu(pget_log->bcn_rcv_cnt);
+ pget_info->param.stats.bcn_miss_cnt =
+ wlan_le32_to_cpu(pget_log->bcn_miss_cnt);
/* Indicate ioctl complete */
pioctl_buf->data_read_written = sizeof(mlan_ds_get_info);
}
@@ -666,9 +666,7 @@ wlan_ret_802_11_mac_address(IN pmlan_private pmpriv,
memcpy(pmpriv->adapter, pmpriv->curr_addr, pmac_addr->mac_addr,
MLAN_MAC_ADDR_LENGTH);
- PRINTM(MINFO, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
- pmpriv->curr_addr[0], pmpriv->curr_addr[1], pmpriv->curr_addr[2],
- pmpriv->curr_addr[3], pmpriv->curr_addr[4], pmpriv->curr_addr[5]);
+ PRINTM(MINFO, "MAC address: " MACSTR "\n", MAC2STR(pmpriv->curr_addr));
if (pioctl_buf) {
bss = (mlan_ds_bss *) pioctl_buf->pbuf;
memcpy(pmpriv->adapter, &bss->param.mac_addr, pmpriv->curr_addr,
@@ -791,44 +789,66 @@ wlan_ret_802_11_key_material(IN pmlan_private pmpriv,
} else {
if (pioctl_buf &&
(wlan_le16_to_cpu(pkey->key_param_set.type) ==
- TLV_TYPE_KEY_MATERIAL)) {
- PRINTM(MIOCTL, "key_type_id=%d, key_len=%d, key_info=0x%x\n",
- wlan_le16_to_cpu(pkey->key_param_set.key_type_id),
- wlan_le16_to_cpu(pkey->key_param_set.key_len),
- wlan_le16_to_cpu(pkey->key_param_set.key_info));
+ TLV_TYPE_KEY_PARAM_V2)) {
sec = (mlan_ds_sec_cfg *) pioctl_buf->pbuf;
-#define WAPI_KEY_SIZE 32
- switch (wlan_le16_to_cpu(pkey->key_param_set.key_type_id)) {
- case KEY_TYPE_ID_WEP:
- sec->param.encrypt_key.key_index = pkey->key_param_set.key[0];
+ memcpy(pmpriv->adapter, sec->param.encrypt_key.mac_addr,
+ pkey->key_param_set.mac_addr, MLAN_MAC_ADDR_LENGTH);
+ sec->param.encrypt_key.key_index = pkey->key_param_set.key_idx;
+ PRINTM(MIOCTL,
+ "key_type=%d, key_index=%d, key_info=0x%x " MACSTR "\n",
+ pkey->key_param_set.key_type, pkey->key_param_set.key_idx,
+ wlan_le16_to_cpu(pkey->key_param_set.key_info),
+ MAC2STR(sec->param.encrypt_key.mac_addr));
+ switch (pkey->key_param_set.key_type) {
+ case KEY_TYPE_ID_WAPI:
+ sec->param.encrypt_key.is_wapi_key = MTRUE;
sec->param.encrypt_key.key_len =
- wlan_le16_to_cpu(pkey->key_param_set.key_len);
+ wlan_le16_to_cpu(pkey->key_param_set.key_params.wapi.
+ key_len);
memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material,
- &pkey->key_param_set.key[2],
+ pkey->key_param_set.key_params.wapi.key,
sec->param.encrypt_key.key_len);
+ memcpy(pmpriv->adapter, sec->param.encrypt_key.pn,
+ pkey->key_param_set.key_params.wapi.pn, PN_SIZE);
break;
case KEY_TYPE_ID_TKIP:
sec->param.encrypt_key.key_len =
- wlan_le16_to_cpu(pkey->key_param_set.key_len);
+ wlan_le16_to_cpu(pkey->key_param_set.key_params.tkip.
+ key_len);
memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material,
- pkey->key_param_set.key, sec->param.encrypt_key.key_len);
+ pkey->key_param_set.key_params.tkip.key,
+ sec->param.encrypt_key.key_len);
+ memcpy(pmpriv->adapter, sec->param.encrypt_key.pn,
+ pkey->key_param_set.key_params.tkip.pn, WPA_PN_SIZE);
break;
case KEY_TYPE_ID_AES:
- case KEY_TYPE_ID_AES_CMAC:
sec->param.encrypt_key.key_len =
- wlan_le16_to_cpu(pkey->key_param_set.key_len);
+ wlan_le16_to_cpu(pkey->key_param_set.key_params.aes.
+ key_len);
memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material,
- pkey->key_param_set.key, sec->param.encrypt_key.key_len);
+ pkey->key_param_set.key_params.aes.key,
+ sec->param.encrypt_key.key_len);
+ memcpy(pmpriv->adapter, sec->param.encrypt_key.pn,
+ pkey->key_param_set.key_params.aes.pn, WPA_PN_SIZE);
break;
- case KEY_TYPE_ID_WAPI:
- sec->param.encrypt_key.is_wapi_key = MTRUE;
- sec->param.encrypt_key.key_index = pkey->key_param_set.key[0];
- sec->param.encrypt_key.key_len = WAPI_KEY_SIZE;
+ case KEY_TYPE_ID_AES_CMAC:
+ sec->param.encrypt_key.key_len =
+ wlan_le16_to_cpu(pkey->key_param_set.key_params.cmac_aes.
+ key_len);
memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material,
- &pkey->key_param_set.key[2],
+ pkey->key_param_set.key_params.cmac_aes.key,
sec->param.encrypt_key.key_len);
memcpy(pmpriv->adapter, sec->param.encrypt_key.pn,
- &pkey->key_param_set.key[2 + WAPI_KEY_SIZE], PN_SIZE);
+ pkey->key_param_set.key_params.cmac_aes.ipn,
+ IGTK_PN_SIZE);
+ break;
+ case KEY_TYPE_ID_WEP:
+ sec->param.encrypt_key.key_len =
+ wlan_le16_to_cpu(pkey->key_param_set.key_params.wep.
+ key_len);
+ memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material,
+ pkey->key_param_set.key_params.wep.key,
+ sec->param.encrypt_key.key_len);
break;
}
}
@@ -1072,10 +1092,7 @@ wlan_ret_ibss_coalescing_status(IN pmlan_private pmpriv,
return MLAN_STATUS_SUCCESS;
}
- PRINTM(MINFO, "New BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
- pibss_coal_resp->bssid[0], pibss_coal_resp->bssid[1],
- pibss_coal_resp->bssid[2], pibss_coal_resp->bssid[3],
- pibss_coal_resp->bssid[4], pibss_coal_resp->bssid[5]);
+ PRINTM(MINFO, "New BSSID " MACSTR "\n", MAC2STR(pibss_coal_resp->bssid));
/* If rsp has MNULL BSSID, Just return..... No Action */
if (!memcmp
@@ -1338,6 +1355,7 @@ wlan_ret_otp_user_data(IN pmlan_private pmpriv,
/********************************************************
Global Functions
********************************************************/
+
/**
* @brief This function handles the station command response
*
@@ -1357,6 +1375,7 @@ wlan_ops_sta_process_cmdresp(IN t_void * priv,
mlan_private *pmpriv = (mlan_private *) priv;
HostCmd_DS_COMMAND *resp = (HostCmd_DS_COMMAND *) pcmd_buf;
mlan_ioctl_req *pioctl_buf = (mlan_ioctl_req *) pioctl;
+
mlan_adapter *pmadapter = pmpriv->adapter;
int ctr;
@@ -1404,6 +1423,7 @@ wlan_ops_sta_process_cmdresp(IN t_void * priv,
break;
case HostCmd_CMD_802_11_BG_SCAN_QUERY:
ret = wlan_ret_802_11_bgscan_query(pmpriv, resp, pioctl_buf);
+ wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_BGSCAN_RESULT, MNULL);
PRINTM(MINFO, "CMD_RESP: BG_SCAN result is ready!\n");
break;
case HostCmd_CMD_TXPWR_CFG:
@@ -1598,6 +1618,7 @@ wlan_ops_sta_process_cmdresp(IN t_void * priv,
case HostCmd_CMD_REJECT_ADDBA_REQ:
ret = wlan_ret_reject_addba_req(pmpriv, resp, pioctl_buf);
break;
+
default:
PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n",
resp->command);
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_event.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_event.c
index fd408a6efe4b..7fce6e29a6e3 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_sta_event.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_event.c
@@ -82,11 +82,6 @@ wlan_reset_connect_state(pmlan_private priv, t_u8 drv_disconnect)
ENTER();
- if (priv->media_connected != MTRUE) {
- LEAVE();
- return;
- }
-
PRINTM(MINFO, "Handles disconnect event.\n");
if (drv_disconnect) {
@@ -227,11 +222,19 @@ wlan_ops_sta_process_event(IN t_void * priv)
t_u8 event_buf[100];
t_u8 *evt_buf = MNULL;
pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event;
+ t_u16 reason_code;
pmlan_callbacks pcb = &pmadapter->callbacks;
mlan_event *pevent = (mlan_event *) event_buf;
ENTER();
+ /* Event length check */
+ if ((pmbuf->data_len - sizeof(eventcause)) > MAX_EVENT_SIZE) {
+ pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
+ }
+
if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE &&
pmbuf->data_len > sizeof(eventcause))
DBG_HEXDUMP(MEVT_D, "EVENT", pmbuf->pbuf + pmbuf->data_offset,
@@ -249,20 +252,27 @@ wlan_ops_sta_process_event(IN t_void * priv)
break;
case EVENT_DEAUTHENTICATED:
- PRINTM(MEVENT, "EVENT: Deauthenticated\n");
+ reason_code =
+ *(t_u16 *) (pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause));
+ PRINTM(MMSG, "wlan: EVENT: Deauthenticated (reason 0x%x)\n",
+ reason_code);
pmadapter->dbg.num_event_deauth++;
wlan_handle_disconnect_event(pmpriv);
break;
case EVENT_DISASSOCIATED:
- PRINTM(MEVENT, "EVENT: Disassociated\n");
+ reason_code =
+ *(t_u16 *) (pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause));
+ PRINTM(MMSG, "wlan: EVENT: Disassociated (reason 0x%x)\n", reason_code);
pmadapter->dbg.num_event_disassoc++;
wlan_handle_disconnect_event(pmpriv);
break;
case EVENT_LINK_LOST:
- PRINTM(MEVENT, "EVENT: Link lost\n");
+ reason_code =
+ *(t_u16 *) (pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause));
+ PRINTM(MMSG, "wlan: EVENT: Link lost (reason 0x%x)\n", reason_code);
pmadapter->dbg.num_event_link_lost++;
wlan_handle_disconnect_event(pmpriv);
break;
@@ -339,11 +349,34 @@ wlan_ops_sta_process_event(IN t_void * priv)
wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_LOST, MNULL);
break;
+ case EVENT_FW_DEBUG_INFO:
+ /* Allocate memory for event buffer */
+ ret = pcb->moal_malloc(pmadapter->pmoal_handle,
+ MAX_EVENT_SIZE, MLAN_MEM_DEF, &evt_buf);
+ if ((ret == MLAN_STATUS_SUCCESS) && evt_buf) {
+ pevent = (pmlan_event) evt_buf;
+ pevent->bss_index = pmpriv->bss_index;
+ PRINTM(MEVENT, "EVENT: FW Debug Info\n");
+ pevent->event_id = MLAN_EVENT_ID_FW_DEBUG_INFO;
+ pevent->event_len = pmbuf->data_len - sizeof(eventcause);
+ memcpy(pmadapter,
+ (t_u8 *) pevent->event_buf,
+ pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause),
+ pevent->event_len);
+ wlan_recv_event(pmpriv, pevent->event_id, pevent);
+ pcb->moal_mfree(pmadapter->pmoal_handle, evt_buf);
+ }
+ break;
+
case EVENT_BG_SCAN_REPORT:
PRINTM(MEVENT, "EVENT: BGS_REPORT\n");
pmadapter->bgscan_reported = MTRUE;
wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN, MNULL);
break;
+ case EVENT_BG_SCAN_STOPPED:
+ PRINTM(MEVENT, "EVENT: BGS_STOPPED\n");
+ wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN_STOPPED, MNULL);
+ break;
case EVENT_PORT_RELEASE:
PRINTM(MEVENT, "EVENT: PORT RELEASE\n");
@@ -429,7 +462,8 @@ wlan_ops_sta_process_event(IN t_void * priv)
break;
case EVENT_EXT_SCAN_REPORT:
PRINTM(MEVENT, "EVENT: EXT_SCAN Report (%#x)\n", eventcause);
- ret = wlan_handle_event_ext_scan_report(priv, pmbuf);
+ if (pmadapter->pext_scan_ioctl_req)
+ ret = wlan_handle_event_ext_scan_report(priv, pmbuf);
break;
case EVENT_MEAS_REPORT_RDY:
PRINTM(MEVENT, "EVENT: Measurement Report Ready (%#x)\n", eventcause);
@@ -619,6 +653,7 @@ wlan_ops_sta_process_event(IN t_void * priv)
pEvtDat[3]);
}
break;
+
default:
PRINTM(MEVENT, "EVENT: unknown event id: %#x\n", eventcause);
wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_UNKNOWN, MNULL);
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c
index 2c1743025218..47c8e25c99f9 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c
@@ -54,27 +54,15 @@ Change log:
static void
wlan_enable_aes_key(pmlan_private pmpriv)
{
- mlan_ds_encrypt_key encrypt_key;
ENTER();
- if (pmpriv->aes_key.key_param_set.key_len != WPA_AES_KEY_LEN) {
+ if (pmpriv->aes_key.key_len != WPA_AES_KEY_LEN) {
LEAVE();
return;
}
-
- memset(pmpriv->adapter, &encrypt_key, 0, sizeof(mlan_ds_encrypt_key));
- encrypt_key.key_len = WPA_AES_KEY_LEN;
- encrypt_key.key_index = MLAN_KEY_INDEX_UNICAST;
- memcpy(pmpriv->adapter, encrypt_key.key_material,
- pmpriv->aes_key.key_param_set.key, encrypt_key.key_len);
- wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
- HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, MNULL,
- &encrypt_key);
- encrypt_key.key_index &= ~MLAN_KEY_INDEX_UNICAST;
wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
- HostCmd_ACT_GEN_SET,
- KEY_INFO_ENABLED, MNULL, &encrypt_key);
+ HostCmd_ACT_GEN_SET, 0, MNULL, &pmpriv->aes_key);
LEAVE();
return;
@@ -330,6 +318,7 @@ wlan_get_info_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
memcpy(pmadapter, &pget_info->param.fw_info.mac_addr, pmpriv->curr_addr,
MLAN_MAC_ADDR_LENGTH);
pget_info->param.fw_info.fw_bands = pmadapter->fw_bands;
+ pget_info->param.fw_info.region_code = pmadapter->region_code;
pget_info->param.fw_info.hw_dev_mcs_support =
pmadapter->hw_dev_mcs_support;
break;
@@ -832,7 +821,7 @@ static mlan_status
wlan_bss_ioctl_channel(IN pmlan_adapter pmadapter,
IN pmlan_ioctl_req pioctl_req)
{
- mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_private *pmpriv = MNULL;
mlan_ds_bss *bss = MNULL;
mlan_status ret = MLAN_STATUS_SUCCESS;
chan_freq_power_t *cfp = MNULL;
@@ -843,6 +832,7 @@ wlan_bss_ioctl_channel(IN pmlan_adapter pmadapter,
LEAVE();
return MLAN_STATUS_FAILURE;
}
+ pmpriv = pmadapter->priv[pioctl_req->bss_index];
bss = (mlan_ds_bss *) pioctl_req->pbuf;
if (pioctl_req->action == MLAN_ACT_GET) {
cfp = wlan_find_cfp_by_band_and_channel(pmadapter,
@@ -1057,14 +1047,9 @@ wlan_bss_ioctl_start(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
goto start_ssid_done;
} else { /* i >= 0 */
PRINTM(MERROR,
- "SSID not found in scan list: ssid=%s, %02x:%02x:%02x:%02x:%02x:%02x, idx=%d\n",
+ "SSID not found in scan list: ssid=%s, " MACSTR ", idx=%d\n",
bss->param.ssid_bssid.ssid.ssid,
- bss->param.ssid_bssid.bssid[0],
- bss->param.ssid_bssid.bssid[1],
- bss->param.ssid_bssid.bssid[2],
- bss->param.ssid_bssid.bssid[3],
- bss->param.ssid_bssid.bssid[4],
- bss->param.ssid_bssid.bssid[5],
+ MAC2STR(bss->param.ssid_bssid.bssid),
(int) bss->param.ssid_bssid.idx);
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
ret = MLAN_STATUS_FAILURE;
@@ -1234,7 +1219,7 @@ wlan_bss_ioctl_listen_interval(IN pmlan_adapter pmadapter,
return MLAN_STATUS_SUCCESS;
}
-/**
+/*
* @brief Set/Get beacon interval
*
* @param pmadapter A pointer to mlan_adapter structure
@@ -1448,6 +1433,9 @@ wlan_bss_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
case MLAN_OID_BSS_LISTEN_INTERVAL:
status = wlan_bss_ioctl_listen_interval(pmadapter, pioctl_req);
break;
+ case MLAN_OID_BSS_REMOVE:
+ status = wlan_bss_ioctl_bss_remove(pmadapter, pioctl_req);
+ break;
default:
status = MLAN_STATUS_FAILURE;
break;
@@ -2276,317 +2264,6 @@ wlan_pm_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
}
/**
- * @brief Set/Get WMM status
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_SUCCESS --success
- */
-static mlan_status
-wlan_wmm_ioctl_enable(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status ret = MLAN_STATUS_SUCCESS;
- mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_wmm_cfg *wmm = MNULL;
- ENTER();
- wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
- if (pioctl_req->action == MLAN_ACT_GET)
- wmm->param.wmm_enable = (t_u32) pmpriv->wmm_required;
- else
- pmpriv->wmm_required = (t_u8) wmm->param.wmm_enable;
- pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Set/Get WMM QoS configuration
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_SUCCESS --success
- */
-static mlan_status
-wlan_wmm_ioctl_qos(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status ret = MLAN_STATUS_SUCCESS;
- mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_wmm_cfg *wmm = MNULL;
-
- ENTER();
-
- wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
-
- if (pioctl_req->action == MLAN_ACT_GET)
- wmm->param.qos_cfg = pmpriv->wmm_qosinfo;
- else {
- pmpriv->wmm_qosinfo = wmm->param.qos_cfg;
- }
-
- pioctl_req->data_read_written = sizeof(t_u8) + MLAN_SUB_COMMAND_SIZE;
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Request for add a TSPEC
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_PENDING --success, otherwise fail
- */
-static mlan_status
-wlan_wmm_ioctl_addts_req(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status ret = MLAN_STATUS_SUCCESS;
- pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_wmm_cfg *cfg = MNULL;
-
- ENTER();
- cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
-
- /* Send request to firmware */
- ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_ADDTS_REQ,
- 0, 0, (t_void *) pioctl_req,
- (t_void *) & cfg->param.addts);
-
- if (ret == MLAN_STATUS_SUCCESS)
- ret = MLAN_STATUS_PENDING;
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Request for delete a TSPEC
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_PENDING --success, otherwise fail
- */
-static mlan_status
-wlan_wmm_ioctl_delts_req(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status ret = MLAN_STATUS_SUCCESS;
- pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_wmm_cfg *cfg = MNULL;
-
- ENTER();
- cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
-
- /* Send request to firmware */
- ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_DELTS_REQ,
- 0, 0, (t_void *) pioctl_req,
- (t_void *) & cfg->param.delts);
-
- if (ret == MLAN_STATUS_SUCCESS)
- ret = MLAN_STATUS_PENDING;
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Set/Get a specified AC Queue's parameters
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_PENDING --success, otherwise fail
- */
-static mlan_status
-wlan_wmm_ioctl_queue_config(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status ret = MLAN_STATUS_SUCCESS;
- pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_wmm_cfg *cfg = MNULL;
-
- ENTER();
- cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
-
- /* Send request to firmware */
- ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_QUEUE_CONFIG,
- 0, 0, (t_void *) pioctl_req,
- (t_void *) & cfg->param.q_cfg);
-
- if (ret == MLAN_STATUS_SUCCESS)
- ret = MLAN_STATUS_PENDING;
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief To get and start/stop queue stats on a WMM AC
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_PENDING --success, otherwise fail
- */
-static mlan_status
-wlan_wmm_ioctl_queue_stats(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status ret = MLAN_STATUS_SUCCESS;
- pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_wmm_cfg *cfg = MNULL;
-
- ENTER();
- cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
-
- /* Send request to firmware */
- ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_QUEUE_STATS,
- 0, 0, (t_void *) pioctl_req,
- (t_void *) & cfg->param.q_stats);
-
- if (ret == MLAN_STATUS_SUCCESS)
- ret = MLAN_STATUS_PENDING;
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Get the status of the WMM AC queues
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_SUCCESS --success
- */
-static mlan_status
-wlan_wmm_ioctl_queue_status(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status ret = MLAN_STATUS_SUCCESS;
- pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_wmm_cfg *cfg = MNULL;
- mlan_ds_wmm_queue_status *pqstatus = MNULL;
- WmmAcStatus_t *pac_status = MNULL;
- mlan_wmm_ac_e ac_idx;
-
- ENTER();
-
- cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
- pqstatus = (mlan_ds_wmm_queue_status *) & cfg->param.q_status;
-
- for (ac_idx = WMM_AC_BK; ac_idx <= WMM_AC_VO; ac_idx++) {
- pac_status = &pmpriv->wmm.ac_status[ac_idx];
-
- /* Firmware status */
- pqstatus->ac_status[ac_idx].flow_required = pac_status->flow_required;
- pqstatus->ac_status[ac_idx].flow_created = pac_status->flow_created;
- pqstatus->ac_status[ac_idx].disabled = pac_status->disabled;
-
- /* ACM bit reflected in firmware status (redundant) */
- pqstatus->ac_status[ac_idx].wmm_acm = pac_status->flow_required;
- }
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Get the status of the WMM Traffic Streams
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_PENDING --success, otherwise fail
- */
-static mlan_status
-wlan_wmm_ioctl_ts_status(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status ret = MLAN_STATUS_SUCCESS;
- pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_wmm_cfg *cfg = MNULL;
-
- ENTER();
-
- cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
-
- /* Send request to firmware */
- ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_TS_STATUS,
- 0, 0, (t_void *) pioctl_req,
- (t_void *) & cfg->param.ts_status);
-
- if (ret == MLAN_STATUS_SUCCESS)
- ret = MLAN_STATUS_PENDING;
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief WMM configuration handler
- *
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
- *
- * @return MLAN_STATUS_SUCCESS --success, otherwise fail
- */
-static mlan_status
-wlan_wmm_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
-{
- mlan_status status = MLAN_STATUS_SUCCESS;
- mlan_ds_wmm_cfg *wmm = MNULL;
-
- ENTER();
-
- if (pioctl_req->buf_len < sizeof(mlan_ds_wmm_cfg)) {
- PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
- pioctl_req->data_read_written = 0;
- pioctl_req->buf_len_needed = sizeof(mlan_ds_wmm_cfg);
- pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
- LEAVE();
- return MLAN_STATUS_RESOURCE;
- }
- wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
- switch (wmm->sub_command) {
- case MLAN_OID_WMM_CFG_ENABLE:
- status = wlan_wmm_ioctl_enable(pmadapter, pioctl_req);
- break;
- case MLAN_OID_WMM_CFG_QOS:
- status = wlan_wmm_ioctl_qos(pmadapter, pioctl_req);
- break;
- case MLAN_OID_WMM_CFG_ADDTS:
- status = wlan_wmm_ioctl_addts_req(pmadapter, pioctl_req);
- break;
- case MLAN_OID_WMM_CFG_DELTS:
- status = wlan_wmm_ioctl_delts_req(pmadapter, pioctl_req);
- break;
- case MLAN_OID_WMM_CFG_QUEUE_CONFIG:
- status = wlan_wmm_ioctl_queue_config(pmadapter, pioctl_req);
- break;
- case MLAN_OID_WMM_CFG_QUEUE_STATS:
- status = wlan_wmm_ioctl_queue_stats(pmadapter, pioctl_req);
- break;
- case MLAN_OID_WMM_CFG_QUEUE_STATUS:
- status = wlan_wmm_ioctl_queue_status(pmadapter, pioctl_req);
- break;
- case MLAN_OID_WMM_CFG_TS_STATUS:
- status = wlan_wmm_ioctl_ts_status(pmadapter, pioctl_req);
- break;
- default:
- pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
- status = MLAN_STATUS_FAILURE;
- break;
- }
- LEAVE();
- return status;
-}
-
-/**
* @brief Set/Get WPA IE
*
* @param priv A pointer to mlan_private structure
@@ -2763,7 +2440,7 @@ wlan_sec_ioctl_port_ctrl_enable(IN pmlan_adapter pmadapter,
if (pmpriv->port_ctrl_mode == MTRUE) {
pmpriv->port_ctrl_mode = MFALSE;
/* Cleanup the bypass TX queue */
- wlan_cleanup_bypass_txq(pmadapter);
+ wlan_cleanup_bypass_txq(pmpriv);
}
}
}
@@ -2831,6 +2508,30 @@ wlan_sec_ioctl_encrypt_mode(IN pmlan_adapter pmadapter,
}
/**
+ * @brief Get Random charactor
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ *
+ * @return random charactor
+ */
+t_u8
+wlan_get_random_charactor(pmlan_adapter pmadapter)
+{
+ t_u32 sec, usec;
+ t_u8 ch = 0;
+
+ ENTER();
+
+ pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec,
+ &usec);
+ sec = (sec & 0xFFFF) + (sec >> 16);
+ usec = (usec & 0xFFFF) + (usec >> 16);
+ ch = (((sec << 16) + usec) % 26) + 'a';
+ LEAVE();
+ return ch;
+}
+
+/**
* @brief Set/Get WPA status
*
* @param pmadapter A pointer to mlan_adapter structure
@@ -2858,7 +2559,7 @@ wlan_sec_ioctl_wpa_enable(IN pmlan_adapter pmadapter,
}
/** clear adhoc aes flag, when WPA enabled */
pmpriv->adhoc_aes_enabled = MFALSE;
- pmpriv->aes_key.key_param_set.key_len = 0;
+ pmpriv->aes_key.key_len = 0;
}
pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
LEAVE();
@@ -2882,6 +2583,7 @@ wlan_sec_ioctl_set_wep_key(IN pmlan_adapter pmadapter,
mlan_ds_sec_cfg *sec = MNULL;
mrvl_wep_key_t *pwep_key = MNULL;
int index;
+ int i = 0;
ENTER();
@@ -2891,8 +2593,18 @@ wlan_sec_ioctl_set_wep_key(IN pmlan_adapter pmadapter,
sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
if (sec->param.encrypt_key.key_index == MLAN_KEY_INDEX_DEFAULT) {
index = pmpriv->wep_key_curr_index;
+ sec->param.encrypt_key.key_index = index;
} else {
if (sec->param.encrypt_key.key_index >= MRVL_NUM_WEP_KEY) {
+ if ((sec->param.encrypt_key.key_remove == MTRUE) &&
+ (sec->param.encrypt_key.key_index <= 5)) {
+ /* call firmware remove key */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_802_11_KEY_MATERIAL,
+ HostCmd_ACT_GEN_SET,
+ 0, MNULL, &sec->param.encrypt_key);
+ goto exit;
+ }
PRINTM(MERROR, "Key_index is invalid\n");
ret = MLAN_STATUS_FAILURE;
goto exit;
@@ -2907,14 +2619,28 @@ wlan_sec_ioctl_set_wep_key(IN pmlan_adapter pmadapter,
if (sec->param.encrypt_key.key_remove == MTRUE) {
memset(pmadapter, &pmpriv->wep_key[index], 0,
sizeof(mrvl_wep_key_t));
+ /* call firmware remove key */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_802_11_KEY_MATERIAL,
+ HostCmd_ACT_GEN_SET,
+ 0, MNULL, &sec->param.encrypt_key);
+ if (ret)
+ goto exit;
}
} else {
if (sec->param.encrypt_key.key_len) {
if ((sec->param.encrypt_key.key_len != WEP_104_BIT_LEN) &&
(sec->param.encrypt_key.key_len != WEP_40_BIT_LEN)) {
- PRINTM(MERROR, "Invalid wep key len\n");
- ret = MLAN_STATUS_FAILURE;
- goto exit;
+ PRINTM(MERROR, "Invalid wep key len=%d\n",
+ sec->param.encrypt_key.key_len);
+ /* We will use random key to clear the key buffer in FW */
+ if (sec->param.encrypt_key.key_len < WEP_40_BIT_LEN)
+ sec->param.encrypt_key.key_len = WEP_40_BIT_LEN;
+ else
+ sec->param.encrypt_key.key_len = WEP_104_BIT_LEN;
+ for (i = 0; i < sec->param.encrypt_key.key_len; i++)
+ sec->param.encrypt_key.key_material[i] =
+ wlan_get_random_charactor(pmadapter);
}
pwep_key = &pmpriv->wep_key[index];
/* Cleanup */
@@ -2939,6 +2665,13 @@ wlan_sec_ioctl_set_wep_key(IN pmlan_adapter pmadapter,
/* Copy the required key as the current key */
pwep_key = &pmpriv->wep_key[index];
if (!pwep_key->key_length) {
+ if (0
+ || &pmpriv->sec_info.wpa_enabled
+ || &pmpriv->sec_info.wpa2_enabled
+ || &pmpriv->sec_info.wapi_enabled) {
+ ret = MLAN_STATUS_SUCCESS;
+ goto exit;
+ }
PRINTM(MERROR, "Key %d not set,so cannot enable it\n", index);
pioctl_req->status_code = MLAN_ERROR_CMD_RESP_FAIL;
ret = MLAN_STATUS_FAILURE;
@@ -2947,6 +2680,10 @@ wlan_sec_ioctl_set_wep_key(IN pmlan_adapter pmadapter,
pmpriv->wep_key_curr_index = (t_u16) index;
pmpriv->sec_info.wep_status = Wlan802_11WEPEnabled;
}
+ if (sec->param.encrypt_key.key_flags && pwep_key->key_length) {
+ pmpriv->wep_key_curr_index = (t_u16) index;
+ pmpriv->sec_info.wep_status = Wlan802_11WEPEnabled;
+ }
}
if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
pmpriv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
@@ -2962,15 +2699,29 @@ wlan_sec_ioctl_set_wep_key(IN pmlan_adapter pmadapter,
0, MNULL, &pmpriv->curr_pkt_filter);
if (ret)
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;
+ memcpy(pmadapter, sec->param.encrypt_key.key_material,
+ pwep_key->key_material, sec->param.encrypt_key.key_len);
+ }
ret = wlan_prepare_cmd(pmpriv,
HostCmd_CMD_802_11_KEY_MATERIAL,
HostCmd_ACT_GEN_SET,
- 0, (t_void *) pioctl_req, MNULL);
+ 0,
+ (t_void *) pioctl_req, &sec->param.encrypt_key);
} else {
if (pwep_key->key_length) {
+ 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;
+ memcpy(pmadapter, sec->param.encrypt_key.key_material,
+ pwep_key->key_material, sec->param.encrypt_key.key_len);
+ }
ret = wlan_prepare_cmd(pmpriv,
HostCmd_CMD_802_11_KEY_MATERIAL,
- HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
+ HostCmd_ACT_GEN_SET,
+ 0, MNULL, &sec->param.encrypt_key);
if (ret)
goto exit;
}
@@ -3003,8 +2754,6 @@ wlan_sec_ioctl_set_wpa_key(IN pmlan_adapter pmadapter,
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_sec_cfg *sec = MNULL;
- t_u8 broadcast_mac_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- t_u8 remove_key = MFALSE;
ENTER();
@@ -3016,34 +2765,12 @@ wlan_sec_ioctl_set_wpa_key(IN pmlan_adapter pmadapter,
ret = MLAN_STATUS_FAILURE;
goto exit;
}
- if ((pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) &&
- pmpriv->sec_info.wpa_enabled) {
- /*
- * IBSS/WPA-None uses only one key (Group) for both receiving and
- * sending unicast and multicast packets.
- */
- /* Send the key as PTK to firmware */
- sec->param.encrypt_key.key_index = MLAN_KEY_INDEX_UNICAST;
- ret = wlan_prepare_cmd(pmpriv,
- HostCmd_CMD_802_11_KEY_MATERIAL,
- HostCmd_ACT_GEN_SET,
- KEY_INFO_ENABLED,
- MNULL, &sec->param.encrypt_key);
- if (ret)
- goto exit;
-
- /* Send the key as GTK to firmware */
- sec->param.encrypt_key.key_index = ~MLAN_KEY_INDEX_UNICAST;
- }
if (sec->param.encrypt_key.key_len == WPA_AES_KEY_LEN) {
/** back up adhoc AES key */
- memset(pmpriv->adapter, pmpriv->aes_key.key_param_set.key, 0,
- sizeof(pmpriv->aes_key.key_param_set.key));
- pmpriv->aes_key.key_param_set.key_len = sec->param.encrypt_key.key_len;
- memcpy(pmpriv->adapter, pmpriv->aes_key.key_param_set.key,
- sec->param.encrypt_key.key_material,
- pmpriv->aes_key.key_param_set.key_len);
+ memset(pmpriv->adapter, &pmpriv->aes_key, 0, sizeof(pmpriv->aes_key));
+ memcpy(pmpriv->adapter, (t_u8 *) & pmpriv->aes_key,
+ (t_u8 *) & sec->param.encrypt_key, sizeof(pmpriv->aes_key));
}
/** only adhoc aes key_index = MLAN_KEY_INDEX_UNICAST */
@@ -3057,36 +2784,18 @@ wlan_sec_ioctl_set_wpa_key(IN pmlan_adapter pmadapter,
WPA_AES_KEY_LEN)) {
PRINTM(MINFO, "Adhoc AES Enabled.\n");
pmpriv->adhoc_aes_enabled = MTRUE;
- remove_key = MFALSE;
} else {
PRINTM(MINFO, "Adhoc AES Disabled.\n");
pmpriv->adhoc_aes_enabled = MFALSE;
/** clear adhoc AES key */
- remove_key = MTRUE;
- pmpriv->aes_key.key_param_set.key_len = 0;
+ pmpriv->aes_key.key_len = 0;
}
}
- if (memcmp
- (pmadapter, sec->param.encrypt_key.mac_addr, broadcast_mac_addr,
- MLAN_MAC_ADDR_LENGTH))
- sec->param.encrypt_key.key_index = MLAN_KEY_INDEX_UNICAST;
-
- if (remove_key == MTRUE) {
- /* Send request to firmware */
- ret = wlan_prepare_cmd(pmpriv,
- HostCmd_CMD_802_11_KEY_MATERIAL,
- HostCmd_ACT_GEN_SET,
- !(KEY_INFO_ENABLED),
- (t_void *) pioctl_req, &sec->param.encrypt_key);
- } else {
- /* Send request to firmware */
- ret = wlan_prepare_cmd(pmpriv,
- HostCmd_CMD_802_11_KEY_MATERIAL,
- HostCmd_ACT_GEN_SET,
- KEY_INFO_ENABLED,
- (t_void *) pioctl_req, &sec->param.encrypt_key);
- }
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_802_11_KEY_MATERIAL,
+ HostCmd_ACT_GEN_SET,
+ 0, (t_void *) pioctl_req, &sec->param.encrypt_key);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
@@ -3119,11 +2828,11 @@ wlan_sec_ioctl_get_key(IN pmlan_adapter pmadapter,
if ((sec->param.encrypt_key.key_index == MLAN_KEY_INDEX_UNICAST) &&
(sec->param.encrypt_key.key_len == WPA_AES_KEY_LEN)) {
if (pmpriv->adhoc_aes_enabled == MTRUE &&
- (pmpriv->aes_key.key_param_set.key_len == WPA_AES_KEY_LEN)) {
- HEXDUMP("Get ADHOCAES Key", pmpriv->aes_key.key_param_set.key,
+ (pmpriv->aes_key.key_len == WPA_AES_KEY_LEN)) {
+ HEXDUMP("Get ADHOCAES Key", pmpriv->aes_key.key_material,
WPA_AES_KEY_LEN);
memcpy(pmadapter, sec->param.encrypt_key.key_material,
- pmpriv->aes_key.key_param_set.key, WPA_AES_KEY_LEN);
+ pmpriv->aes_key.key_material, WPA_AES_KEY_LEN);
LEAVE();
return ret;
} else {
@@ -3166,13 +2875,12 @@ wlan_sec_ioctl_get_key(IN pmlan_adapter pmadapter,
) {
/* Return WPA enabled */
sec->param.encrypt_key.key_disable = MFALSE;
+
memcpy(pmadapter, sec->param.encrypt_key.key_material,
- pmpriv->aes_key.key_param_set.key, MIN(MLAN_MAX_KEY_LENGTH,
- pmpriv->aes_key.
- key_param_set.
- key_len));
+ pmpriv->aes_key.key_material, MIN(MLAN_MAX_KEY_LENGTH,
+ pmpriv->aes_key.key_len));
sec->param.encrypt_key.key_len =
- MIN(MLAN_MAX_KEY_LENGTH, pmpriv->aes_key.key_param_set.key_len);
+ MIN(MLAN_MAX_KEY_LENGTH, pmpriv->aes_key.key_len);
} else {
sec->param.encrypt_key.key_disable = MTRUE;
}
@@ -3497,6 +3205,7 @@ wlan_set_gen_ie_helper(mlan_private * priv, t_u8 * ie_data_ptr, t_u16 ie_len)
priv->gen_ie_buf_len = 0;
priv->wps.session_enable = MFALSE;
wlan_set_wpa_ie_helper(priv, MNULL, 0);
+ wlan_set_wapi_ie(priv, MNULL, 0);
} else if (!ie_data_ptr) {
/* MNULL check */
ret = MLAN_STATUS_FAILURE;
@@ -3785,6 +3494,8 @@ wlan_wps_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
if (pioctl_req->action == MLAN_ACT_SET) {
if (pwps->param.wps_session == MLAN_WPS_CFG_SESSION_START)
pmpriv->wps.session_enable = MTRUE;
+ else
+ pmpriv->wps.session_enable = MFALSE;
} else {
pwps->param.wps_session = (t_u32) pmpriv->wps.session_enable;
pioctl_req->data_read_written = sizeof(t_u32);
@@ -4285,70 +3996,63 @@ wlan_misc_ioctl_sysclock(IN pmlan_adapter pmadapter,
}
/**
- * @brief Send function softreset command to firmware
+ * @brief Get the associate response
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
- * @return MLAN_STATUS_PENDING --success, otherwise fail
+ * @return MLAN_STATUS_SUCCESS --success
*/
static mlan_status
-wlan_misc_ioctl_soft_reset(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req)
+wlan_misc_ioctl_get_assoc_rsp(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
{
+ mlan_ds_misc_cfg *misc = MNULL;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_status ret = MLAN_STATUS_SUCCESS;
ENTER();
- /* Send command to firmware */
- ret = wlan_prepare_cmd(pmpriv,
- HostCmd_CMD_SOFT_RESET,
- HostCmd_ACT_GEN_SET,
- 0, (t_void *) pioctl_req, MNULL);
- if (ret == MLAN_STATUS_SUCCESS)
- ret = MLAN_STATUS_PENDING;
+ misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+ if ((pioctl_req->action == MLAN_ACT_GET) && pmpriv->assoc_rsp_size) {
+ memcpy(pmadapter, misc->param.assoc_resp.assoc_resp_buf,
+ pmpriv->assoc_rsp_buf, MIN(ASSOC_RSP_BUF_SIZE,
+ pmpriv->assoc_rsp_size));
+ misc->param.assoc_resp.assoc_resp_len =
+ MIN(ASSOC_RSP_BUF_SIZE, pmpriv->assoc_rsp_size);
+
+ /* Reset assoc buffer */
+ pmpriv->assoc_rsp_size = 0;
+ }
+
LEAVE();
return ret;
}
/**
- * @brief Set/Get the MAC control configuration.
+ * @brief Send function softreset command to firmware
*
- * @param pmadapter A pointer to mlan_adapter structure
- * @param pioctl_req A pointer to ioctl request buffer
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
*
- * @return MLAN_STATUS_PENDING -- success, otherwise fail
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
*/
-mlan_status
-wlan_misc_ioctl_mac_control(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req)
+static mlan_status
+wlan_misc_ioctl_soft_reset(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
{
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
- mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
mlan_status ret = MLAN_STATUS_SUCCESS;
- t_u16 cmd_action = 0;
ENTER();
+ /* Send command to firmware */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_SOFT_RESET,
+ HostCmd_ACT_GEN_SET,
+ 0, (t_void *) pioctl_req, MNULL);
- misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
-
- if (pioctl_req->action == MLAN_ACT_GET) {
- misc->param.mac_ctrl = pmpriv->curr_pkt_filter;
- } else {
- pmpriv->curr_pkt_filter = misc->param.mac_ctrl;
- cmd_action = HostCmd_ACT_GEN_SET;
-
- /* Send command to firmware */
- ret = wlan_prepare_cmd(pmpriv,
- HostCmd_CMD_MAC_CONTROL,
- cmd_action, 0,
- (t_void *) pioctl_req, &misc->param.mac_ctrl);
-
- if (ret == MLAN_STATUS_SUCCESS)
- ret = MLAN_STATUS_PENDING;
- }
-
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
@@ -4517,7 +4221,10 @@ wlan_ipaddr_arp_filter(IN pmlan_adapter pmadapter,
return ret;
}
-#define FLTR_BUF_IP_OFFSET 39
+#define FLTR_BUF_IP_OFFSET 24
+#define FLTR_BUF_IP_OFFSET_2_IP_1 9
+#define FLTR_BUF_IP_OFFSET_2_IP_2 26
+
/**
* @brief Enable/Disable Auto ARP resonse
*
@@ -4529,7 +4236,8 @@ wlan_ipaddr_arp_filter(IN pmlan_adapter pmadapter,
*/
mlan_status
wlan_ipaddr_auto_arp_resp(IN pmlan_adapter pmadapter,
- IN pmlan_ioctl_req pioctl_req, IN t_u32 ipv4_addr)
+ IN pmlan_ioctl_req pioctl_req,
+ IN t_u32 * ipv4_addr, IN t_u8 num_ipv4)
{
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_status ret = MLAN_STATUS_SUCCESS;
@@ -4539,13 +4247,20 @@ wlan_ipaddr_auto_arp_resp(IN pmlan_adapter pmadapter,
mlan_ds_misc_cmd *hostcmd;
t_u32 buf_len = 0;
t_u8 *buf, *filter;
- t_u8 fltr_buf[] = { 0x01, 0x10, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x01, 0xff, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x41, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08,
- 0x06, 0x02, 0x02, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x41, 0x44, 0x01, 0x00, 0x00, 0x00, 0x01, 0xc0,
- 0xa8, 0x00, 0x68, 0x04, 0x02, 0x2e, 0x00, 0x00,
- 0x00, 0x01, 0x41, 0x44
+
+ t_u8 fltr_buf[] = { 0x01, 0x10, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x08, 0x06, 0x02, 0x02, 0x14, 0x00, 0x00,
+ 0x00, 0x01, 0x41, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0xc0, 0xa8, 0x01, 0x6d, 0x04, 0x02, 0x2e, 0x00,
+ 0x00, 0x00, 0x01, 0x41, 0x44
+ };
+ t_u8 fltr_buf_2_ip[] = { 0x01, 0x10, 0x33, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0xc0, 0xa8, 0x01, 0x6d, 0x04, 0x02, 0x2e,
+ 0x00, 0x00, 0x00, 0x01, 0x41, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0xc0, 0xa8, 0x02, 0x6d, 0x04, 0x02,
+ 0x2e, 0x00, 0x00, 0x00, 0x01, 0x41, 0x45, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x02, 0x02,
+ 0x14, 0x00, 0x00, 0x00, 0x01, 0x41, 0x44
};
ENTER();
@@ -4582,10 +4297,20 @@ wlan_ipaddr_auto_arp_resp(IN pmlan_adapter pmadapter,
mefcmd->nentries = wlan_cpu_to_le16(1);
buf_len += sizeof(HostCmd_DS_MEF_CFG);
filter = buf + buf_len;
- memcpy(pmpriv->adapter, filter, fltr_buf, sizeof(fltr_buf));
- memcpy(pmpriv->adapter, &filter[FLTR_BUF_IP_OFFSET], &ipv4_addr,
- sizeof(ipv4_addr));
- buf_len += sizeof(fltr_buf);
+ if (num_ipv4 == 1) {
+ memcpy(pmpriv->adapter, filter, fltr_buf, sizeof(fltr_buf));
+ memcpy(pmpriv->adapter, &filter[FLTR_BUF_IP_OFFSET], &ipv4_addr[0],
+ sizeof(t_u32));
+ buf_len += sizeof(fltr_buf);
+ } else if (num_ipv4 >= 2) {
+ memcpy(pmpriv->adapter, filter, fltr_buf_2_ip,
+ sizeof(fltr_buf_2_ip));
+ memcpy(pmpriv->adapter, &filter[FLTR_BUF_IP_OFFSET_2_IP_1],
+ &ipv4_addr[0], sizeof(t_u32));
+ memcpy(pmpriv->adapter, &filter[FLTR_BUF_IP_OFFSET_2_IP_2],
+ &ipv4_addr[1], sizeof(t_u32));
+ buf_len += sizeof(fltr_buf_2_ip);
+ }
}
hostcmd_hdr->size = wlan_cpu_to_le16(buf_len);
hostcmd->len = buf_len;
@@ -4727,7 +4452,8 @@ wlan_misc_ioctl_ipaddr_cfg(IN pmlan_adapter pmadapter,
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
mlan_status ret = MLAN_STATUS_SUCCESS;
- t_u32 ipv4_addr;
+ t_u32 ipv4_addr[MAX_IPADDR];
+ int i = 0;
ENTER();
@@ -4739,26 +4465,30 @@ wlan_misc_ioctl_ipaddr_cfg(IN pmlan_adapter pmadapter,
goto done;
}
/* only one IP is supported in current firmware */
- memcpy(pmadapter, &ipv4_addr, misc->param.ipaddr_cfg.ip_addr[0],
- sizeof(t_u32));
+ for (i = 0; i < misc->param.ipaddr_cfg.ip_addr_num; i++) {
+ memcpy(pmadapter, &ipv4_addr[i], misc->param.ipaddr_cfg.ip_addr[i],
+ sizeof(t_u32));
+ }
if (misc->param.ipaddr_cfg.op_code != MLAN_IPADDR_OP_IP_REMOVE &&
- !ipv4_addr) {
+ !misc->param.ipaddr_cfg.ip_addr_num) {
PRINTM(MERROR, "Invalid IPv4 address\n");
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (misc->param.ipaddr_cfg.op_code & MLAN_IPADDR_OP_ARP_FILTER)
- ret = wlan_ipaddr_arp_filter(pmadapter, pioctl_req, ipv4_addr);
+ ret = wlan_ipaddr_arp_filter(pmadapter, pioctl_req, ipv4_addr[0]);
else if (pmpriv->op_code & MLAN_IPADDR_OP_ARP_FILTER)
ret = wlan_ipaddr_arp_filter(pmadapter, pioctl_req, 0);
if (ret == MLAN_STATUS_FAILURE)
goto done;
if (misc->param.ipaddr_cfg.op_code & MLAN_IPADDR_OP_AUTO_ARP_RESP)
- ret = wlan_ipaddr_auto_arp_resp(pmadapter, pioctl_req, ipv4_addr);
+ ret = wlan_ipaddr_auto_arp_resp(pmadapter, pioctl_req,
+ ipv4_addr,
+ misc->param.ipaddr_cfg.ip_addr_num);
else if (pmpriv->op_code & MLAN_IPADDR_OP_AUTO_ARP_RESP)
- ret = wlan_ipaddr_auto_arp_resp(pmadapter, pioctl_req, 0);
+ ret = wlan_ipaddr_auto_arp_resp(pmadapter, pioctl_req, MNULL, 0);
if (ret == MLAN_STATUS_FAILURE)
goto done;
@@ -4808,19 +4538,6 @@ wlan_misc_ioctl_cfp_code_cfg(IN pmlan_adapter pmadapter,
break;
}
}
- if (!region_bg) {
- for (i = 0; i < MRVDRV_MAX_CFP_CODE_BG; i++) {
- /* Use the CFP code to search for the index */
- if (cfp_code->cfp_code_bg == cfp_code_index_bg[i])
- break;
- }
- if (i >= MRVDRV_MAX_CFP_CODE_BG) {
- PRINTM(MERROR, "CFP Code not identified for BG\n");
- pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
- ret = MLAN_STATUS_FAILURE;
- goto done;
- }
- }
if (!cfp_code->cfp_code_a)
cfp_code->cfp_code_a = pmadapter->cfp_code_a;
for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
@@ -4926,6 +4643,38 @@ wlan_misc_ioctl_country_code(IN pmlan_adapter pmadapter,
return ret;
}
+/**
+ * @brief Configure MFPC and MFPR for management frame protection
+ *
+ * @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_pmfcfg(IN pmlan_adapter pmadapter, IN mlan_ioctl_req * pioctl_req)
+{
+ pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ mlan_ds_misc_cfg *cfg_misc = MNULL;
+ mlan_ds_misc_pmfcfg *pmfcfg;
+
+ cfg_misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+ pmfcfg = &cfg_misc->param.pmfcfg;
+
+ if (pioctl_req->action == MLAN_ACT_SET) {
+ pmpriv->pmfcfg.mfpc = pmfcfg->mfpc;
+ pmpriv->pmfcfg.mfpr = pmfcfg->mfpr;
+ } else {
+ /* GET operation */
+ pmfcfg->mfpc = pmpriv->pmfcfg.mfpc;
+ pmfcfg->mfpr = pmpriv->pmfcfg.mfpr;
+ }
+
+ LEAVE();
+ return ret;
+}
+
/**
* @brief Miscellaneous configuration handler
*
@@ -4942,6 +4691,11 @@ wlan_misc_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
ENTER();
+ if ((pioctl_req == MNULL) || (pioctl_req->pbuf == MNULL)) {
+ PRINTM(MERROR, "Request buffer not found!\n");
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
+ }
if (pioctl_req->buf_len < sizeof(mlan_ds_misc_cfg)) {
PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
pioctl_req->data_read_written = 0;
@@ -4950,11 +4704,6 @@ wlan_misc_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
LEAVE();
return MLAN_STATUS_RESOURCE;
}
- if ((pioctl_req == MNULL) || (pioctl_req->pbuf == MNULL)) {
- PRINTM(MERROR, "Request buffer not found!\n");
- LEAVE();
- return MLAN_STATUS_FAILURE;
- }
misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
switch (misc->sub_command) {
case MLAN_OID_MISC_GEN_IE:
@@ -4980,6 +4729,9 @@ wlan_misc_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
case MLAN_OID_MISC_WWS:
status = wlan_misc_ioctl_wws_cfg(pmadapter, pioctl_req);
break;
+ case MLAN_OID_MISC_ASSOC_RSP:
+ status = wlan_misc_ioctl_get_assoc_rsp(pmadapter, pioctl_req);
+ break;
case MLAN_OID_MISC_INIT_SHUTDOWN:
status = wlan_misc_ioctl_init_shutdown(pmadapter, pioctl_req);
break;
@@ -5024,6 +4776,14 @@ wlan_misc_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
case MLAN_OID_MISC_TXCONTROL:
status = wlan_misc_ioctl_txcontrol(pmadapter, pioctl_req);
break;
+#ifdef STA_SUPPORT
+ case MLAN_OID_MISC_EXT_CAP_CFG:
+ status = wlan_misc_ext_capa_cfg(pmadapter, pioctl_req);
+ break;
+#endif
+ case MLAN_OID_MISC_PMFCFG:
+ status = wlan_misc_pmfcfg(pmadapter, pioctl_req);
+ break;
default:
if (pioctl_req)
pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
@@ -5142,7 +4902,7 @@ wlan_scan_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
status = wlan_set_get_scan_cfg(pmadapter, pioctl_req, MLAN_ACT_SET);
break;
case MLAN_OID_SCAN_CANCEL:
- wlan_flush_scan_queue(pmadapter);
+ wlan_cancel_pending_scan_cmd(pmadapter);
break;
case MLAN_OID_SCAN_TABLE_FLUSH:
status = wlan_flush_scan_table(pmadapter);
@@ -5279,8 +5039,7 @@ wlan_find_bss(mlan_private * pmpriv, pmlan_ioctl_req pioctl_req)
pmpriv->bss_mode);
if (i < 0) {
memcpy(pmadapter, mac, &bss->param.ssid_bssid.bssid, sizeof(mac));
- PRINTM(MERROR, "Can not find bssid %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ PRINTM(MIOCTL, "Can not find bssid " MACSTR "\n", MAC2STR(mac));
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
LEAVE();
return MLAN_STATUS_FAILURE;
@@ -5288,13 +5047,14 @@ wlan_find_bss(mlan_private * pmpriv, pmlan_ioctl_req pioctl_req)
pbss_desc = &pmadapter->pscan_table[i];
memcpy(pmadapter, &bss->param.ssid_bssid.ssid, &pbss_desc->ssid,
sizeof(mlan_802_11_ssid));
+ bss->param.ssid_bssid.rssi = pbss_desc->rssi;
/* index in bss list,start from 1 */
bss->param.ssid_bssid.idx = i + 1;
} else if (bss->param.ssid_bssid.ssid.ssid_len) {
i = wlan_find_ssid_in_list(pmpriv, &bss->param.ssid_bssid.ssid, MNULL,
pmpriv->bss_mode);
if (i < 0) {
- PRINTM(MERROR, "Can not find ssid %s\n",
+ PRINTM(MIOCTL, "Can not find ssid %s\n",
bss->param.ssid_bssid.ssid.ssid);
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
LEAVE();
@@ -5303,6 +5063,7 @@ wlan_find_bss(mlan_private * pmpriv, pmlan_ioctl_req pioctl_req)
pbss_desc = &pmadapter->pscan_table[i];
memcpy(pmadapter, (t_u8 *) & bss->param.ssid_bssid.bssid,
(t_u8 *) & pbss_desc->mac_address, MLAN_MAC_ADDR_LENGTH);
+ bss->param.ssid_bssid.rssi = pbss_desc->rssi;
/* index in bss list, start from 1 */
bss->param.ssid_bssid.idx = i + 1;
} else {
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c
index a357103926f7..b0ff21d88c5a 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c
@@ -100,7 +100,7 @@ wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
if (dbgType == DBG_TYPE_SMALL) {
PRINTM(MFW_D, "\n");
DBG_HEXDUMP(MFW_D, "FWDBG",
- (t_s8 *) ((t_u8 *) & prx_pkt->eth803_hdr +
+ (char *) ((t_u8 *) & prx_pkt->eth803_hdr +
SIZE_OF_DBG_STRUCT), prx_pd->rx_pkt_length);
PRINTM(MFW_D, "FWDBG::\n");
}
@@ -167,8 +167,8 @@ wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));
priv->rxpd_rate = prx_pd->rx_rate;
-
priv->rxpd_htinfo = prx_pd->ht_info;
+
pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
&pmbuf->out_ts_sec,
&pmbuf->out_ts_usec);
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c
index dafd1ac57a98..6191e4edeefc 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c
@@ -212,9 +212,12 @@ wlan_send_null_packet(pmlan_private priv, t_u8 flags)
switch (ret) {
case MLAN_STATUS_RESOURCE:
- pmadapter->data_sent = MTRUE;
- /* Fall through FAILURE handling */
+ wlan_free_mlan_buffer(pmadapter, pmbuf);
+ PRINTM(MERROR, "STA Tx Error: Failed to send NULL packet!\n");
+ pmadapter->dbg.num_tx_host_to_card_failure++;
+ goto done;
case MLAN_STATUS_FAILURE:
+ pmadapter->data_sent = MFALSE;
wlan_free_mlan_buffer(pmadapter, pmbuf);
PRINTM(MERROR, "STA Tx Error: Failed to send NULL packet!\n");
pmadapter->dbg.num_tx_host_to_card_failure++;
@@ -225,6 +228,8 @@ wlan_send_null_packet(pmlan_private priv, t_u8 flags)
pmadapter->tx_lock_flag = MTRUE;
break;
case MLAN_STATUS_PENDING:
+ pmadapter->data_sent = MFALSE;
+ pmadapter->tx_lock_flag = MTRUE;
break;
default:
break;
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_txrx.c b/drivers/net/wireless/sd8797/mlan/mlan_txrx.c
index 9ae74bbad834..57c8ef23d43e 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_txrx.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_txrx.c
@@ -61,10 +61,10 @@ mlan_status
wlan_handle_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
- pmlan_private priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
+ pmlan_private priv = MNULL;
RxPD *prx_pd;
#ifdef DEBUG_LEVEL1
- t_u32 sec, usec;
+ t_u32 sec = 0, usec = 0;
#endif
ENTER();
@@ -103,14 +103,13 @@ wlan_process_tx(pmlan_private priv, pmlan_buffer pmbuf,
pmlan_adapter pmadapter = priv->adapter;
t_u8 *head_ptr = MNULL;
#ifdef DEBUG_LEVEL1
- t_u32 sec, usec;
+ t_u32 sec = 0, usec = 0;
#endif
#ifdef STA_SUPPORT
TxPD *plocal_tx_pd = MNULL;
#endif
ENTER();
-
head_ptr = (t_u8 *) priv->ops.process_txpd(priv, pmbuf);
if (!head_ptr) {
pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
@@ -142,6 +141,7 @@ wlan_process_tx(pmlan_private priv, pmlan_buffer pmbuf,
wlan_write_data_complete(pmadapter, pmbuf, ret);
break;
case MLAN_STATUS_PENDING:
+
pmadapter->data_sent = MFALSE;
DBG_HEXDUMP(MDAT_D, "Tx", head_ptr + INTF_HEADER_LEN,
MIN(pmbuf->data_len + sizeof(TxPD), MAX_DATA_DUMP_LEN));
@@ -193,9 +193,6 @@ wlan_write_data_complete(IN pmlan_adapter pmadapter,
pcb->moal_send_packet_complete(pmadapter->pmoal_handle,
pmbuf, status);
} else {
- if (pmbuf->flags & MLAN_BUF_FLAG_BRIDGE_BUF) {
- pmadapter->pending_bridge_pkts--;
- }
/* pmbuf was allocated by MLAN */
wlan_free_mlan_buffer(pmadapter, pmbuf);
}
@@ -265,16 +262,19 @@ wlan_recv_packet_complete(IN pmlan_adapter pmadapter,
t_void
wlan_add_buf_bypass_txqueue(mlan_adapter * pmadapter, pmlan_buffer pmbuf)
{
+ pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
ENTER();
if (pmbuf->buf_type != MLAN_BUF_TYPE_RAW_DATA) {
pmbuf->buf_type = MLAN_BUF_TYPE_DATA;
}
-
- util_enqueue_list_tail(pmadapter->pmoal_handle, &pmadapter->bypass_txq,
- (pmlan_linked_list) pmbuf,
- pmadapter->callbacks.moal_spin_lock,
- pmadapter->callbacks.moal_spin_unlock);
+ pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle,
+ priv->wmm.ra_list_spinlock);
+ pmadapter->bypass_pkt_count++;
+ util_enqueue_list_tail(pmadapter->pmoal_handle, &priv->bypass_txq,
+ (pmlan_linked_list) pmbuf, MNULL, MNULL);
+ pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle,
+ priv->wmm.ra_list_spinlock);
LEAVE();
}
@@ -288,46 +288,34 @@ wlan_add_buf_bypass_txqueue(mlan_adapter * pmadapter, pmlan_buffer pmbuf)
INLINE t_u8
wlan_bypass_tx_list_empty(mlan_adapter * pmadapter)
{
- t_u8 q_empty = MTRUE;
- pmlan_callbacks pcb = &pmadapter->callbacks;
- ENTER();
-
- q_empty = (util_peek_list(pmadapter->pmoal_handle, &pmadapter->bypass_txq,
- pcb->moal_spin_lock,
- pcb->moal_spin_unlock)) ? MFALSE : MTRUE;
-
- LEAVE();
- return q_empty;
+ return ((pmadapter->bypass_pkt_count) ? MFALSE : MTRUE);
}
/**
* @brief Clean up the By-pass TX queue
*
- * @param pmadapter Pointer to the mlan_adapter driver data struct
+ * @param priv Pointer to the mlan_private data struct
*
* @return N/A
*/
t_void
-wlan_cleanup_bypass_txq(mlan_adapter * pmadapter)
+wlan_cleanup_bypass_txq(mlan_private * priv)
{
pmlan_buffer pmbuf;
+ mlan_adapter *pmadapter = priv->adapter;
ENTER();
-
pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle,
- pmadapter->bypass_txq.plock);
-
+ priv->wmm.ra_list_spinlock);
while ((pmbuf =
(pmlan_buffer) util_peek_list(pmadapter->pmoal_handle,
- &pmadapter->bypass_txq, MNULL,
- MNULL))) {
- util_unlink_list(pmadapter->pmoal_handle, &pmadapter->bypass_txq,
+ &priv->bypass_txq, MNULL, MNULL))) {
+ util_unlink_list(pmadapter->pmoal_handle, &priv->bypass_txq,
(pmlan_linked_list) pmbuf, MNULL, MNULL);
wlan_write_data_complete(pmadapter, pmbuf, MLAN_STATUS_FAILURE);
+ pmadapter->bypass_pkt_count--;
}
-
pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle,
- pmadapter->bypass_txq.plock);
-
+ priv->wmm.ra_list_spinlock);
LEAVE();
}
@@ -344,33 +332,48 @@ wlan_process_bypass_tx(pmlan_adapter pmadapter)
pmlan_buffer pmbuf;
mlan_tx_param tx_param;
mlan_status status = MLAN_STATUS_SUCCESS;
-
+ pmlan_private priv;
+ int j = 0;
ENTER();
-
- if ((pmbuf = (pmlan_buffer) util_dequeue_list(pmadapter->pmoal_handle,
- &pmadapter->bypass_txq,
+ for (j = 0; j < pmadapter->priv_num; ++j) {
+ if ((priv = pmadapter->priv[j])) {
+ if ((pmbuf =
+ (pmlan_buffer) util_dequeue_list(pmadapter->pmoal_handle,
+ &priv->bypass_txq,
pmadapter->callbacks.
moal_spin_lock,
pmadapter->callbacks.
moal_spin_unlock))) {
- PRINTM(MINFO, "Dequeuing bypassed packet %p\n", pmbuf);
- /* XXX: nex_pkt_len ??? */
- tx_param.next_pkt_len = 0;
- status =
- wlan_process_tx(pmadapter->priv[pmbuf->bss_index], pmbuf,
- &tx_param);
-
- if (status == MLAN_STATUS_RESOURCE) {
- /* Queue the packet again so that it will be TX'ed later */
- util_enqueue_list_head(pmadapter->pmoal_handle,
- &pmadapter->bypass_txq,
- (pmlan_linked_list) pmbuf,
- pmadapter->callbacks.moal_spin_lock,
- pmadapter->callbacks.moal_spin_unlock);
+ PRINTM(MINFO, "Dequeuing bypassed packet %p\n", pmbuf);
+ /* XXX: nex_pkt_len ??? */
+ tx_param.next_pkt_len = 0;
+ status =
+ wlan_process_tx(pmadapter->priv[pmbuf->bss_index], pmbuf,
+ &tx_param);
+
+ if (status == MLAN_STATUS_RESOURCE) {
+ /* Queue the packet again so that it will be TX'ed later */
+ util_enqueue_list_head(pmadapter->pmoal_handle,
+ &priv->bypass_txq,
+ (pmlan_linked_list) pmbuf,
+ pmadapter->callbacks.moal_spin_lock,
+ pmadapter->callbacks.
+ moal_spin_unlock);
+ } else {
+ pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle,
+ priv->wmm.
+ ra_list_spinlock);
+ pmadapter->bypass_pkt_count--;
+ pmadapter->callbacks.moal_spin_unlock(pmadapter->
+ pmoal_handle,
+ priv->wmm.
+ ra_list_spinlock);
+ }
+ break;
+ } else {
+ PRINTM(MINFO, "Nothing to send\n");
+ }
}
- } else {
- PRINTM(MINFO, "Nothing to send\n");
}
-
LEAVE();
}
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c b/drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c
index 4801d2e809f5..08f26f039773 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c
@@ -72,6 +72,48 @@ uap_process_cmdresp_error(mlan_private * pmpriv, HostCmd_DS_COMMAND * resp,
return;
}
+/**
+ * @brief This function will return the pointer to station entry in station list
+ * table which matches the give mac address
+ *
+ * @param priv A pointer to mlan_private
+ *
+ * @return A pointer to structure sta_node
+ */
+void
+wlan_notify_station_deauth(mlan_private * priv)
+{
+ sta_node *sta_ptr;
+ t_u8 event_buf[100];
+ mlan_event *pevent = (mlan_event *) event_buf;
+ t_u8 *pbuf;
+
+ ENTER();
+ if (!(sta_ptr = (sta_node *) util_peek_list(priv->adapter->pmoal_handle,
+ &priv->sta_list,
+ priv->adapter->callbacks.
+ moal_spin_lock,
+ priv->adapter->callbacks.
+ moal_spin_unlock))) {
+ LEAVE();
+ return;
+ }
+ while (sta_ptr != (sta_node *) & priv->sta_list) {
+ memset(priv->adapter, event_buf, 0, sizeof(event_buf));
+ pevent->bss_index = priv->bss_index;
+ pevent->event_id = MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT;
+ pevent->event_len = MLAN_MAC_ADDR_LENGTH + 2;
+ pbuf = (t_u8 *) pevent->event_buf;
+ /* reason field set to 0, Unspecified */
+ memcpy(priv->adapter, pbuf + 2, sta_ptr->mac_addr,
+ MLAN_MAC_ADDR_LENGTH);
+ wlan_recv_event(priv, pevent->event_id, pevent);
+ sta_ptr = sta_ptr->pnext;
+ }
+ LEAVE();
+ return;
+}
+
/**
* @brief This function prepares command of hs_cfg.
*
@@ -87,7 +129,10 @@ wlan_uap_cmd_802_11_hs_cfg(IN pmlan_private pmpriv,
IN HostCmd_DS_COMMAND * cmd,
IN t_u16 cmd_action, IN hs_config_param * pdata_buf)
{
- HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg = &cmd->params.opt_hs_cfg;
+ HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg =
+ (HostCmd_DS_802_11_HS_CFG_ENH *) & (cmd->params.opt_hs_cfg);
+ t_u8 *tlv = (t_u8 *) phs_cfg + sizeof(HostCmd_DS_802_11_HS_CFG_ENH);
+ MrvlIEtypes_HsWakeHoldoff_t *holdoff_tlv = MNULL;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
@@ -103,9 +148,25 @@ wlan_uap_cmd_802_11_hs_cfg(IN pmlan_private pmpriv,
wlan_cpu_to_le32(pdata_buf->conditions);
phs_cfg->params.hs_config.gpio = pdata_buf->gpio;
phs_cfg->params.hs_config.gap = pdata_buf->gap;
- PRINTM(MCMND, "HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
+ if (pmpriv->adapter->min_wake_holdoff) {
+ cmd->size =
+ wlan_cpu_to_le16(S_DS_GEN +
+ sizeof(HostCmd_DS_802_11_HS_CFG_ENH) +
+ sizeof(MrvlIEtypes_HsWakeHoldoff_t));
+ holdoff_tlv = (MrvlIEtypes_HsWakeHoldoff_t *) tlv;
+ holdoff_tlv->header.type =
+ wlan_cpu_to_le16(TLV_TYPE_HS_WAKE_HOLDOFF);
+ holdoff_tlv->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_HsWakeHoldoff_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ holdoff_tlv->min_wake_holdoff =
+ wlan_cpu_to_le16(pmpriv->adapter->min_wake_holdoff);
+ }
+ PRINTM(MCMND,
+ "HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x holdoff=%d\n",
phs_cfg->params.hs_config.conditions,
- phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap);
+ phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap,
+ pmpriv->adapter->min_wake_holdoff);
}
LEAVE();
return MLAN_STATUS_SUCCESS;
@@ -208,16 +269,13 @@ wlan_process_tx_pause_event(pmlan_private priv, pmlan_buffer pevent)
}
if (tlv_type == TLV_TYPE_TX_PAUSE) {
tx_pause_tlv = (MrvlIEtypes_tx_pause_t *) tlv;
- PRINTM(MCMND,
- "TxPause: %02x:%02x:%02x:%02x:%02x:%02x pause=%d, pkts=%d\n",
- tx_pause_tlv->peermac[0], tx_pause_tlv->peermac[1],
- tx_pause_tlv->peermac[2], tx_pause_tlv->peermac[3],
- tx_pause_tlv->peermac[4], tx_pause_tlv->peermac[5],
+ PRINTM(MCMND, "TxPause: " MACSTR " pause=%d, pkts=%d\n",
+ MAC2STR(tx_pause_tlv->peermac),
tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt);
if ((sta_ptr = wlan_get_station_entry(priv, tx_pause_tlv->peermac))) {
if (sta_ptr->tx_pause != tx_pause_tlv->tx_pause) {
sta_ptr->tx_pause = tx_pause_tlv->tx_pause;
- wlan_updata_ralist_tx_pause(priv, tx_pause_tlv->peermac,
+ wlan_update_ralist_tx_pause(priv, tx_pause_tlv->peermac,
tx_pause_tlv->tx_pause);
}
}
@@ -879,6 +937,8 @@ wlan_uap_cmd_ap_config(pmlan_private pmpriv,
for (ac = 0; ac < 4; ac++) {
tlv_wmm_parameter->wmm_para.ac_params[ac].aci_aifsn.aifsn =
bss->param.bss_config.wmm_para.ac_params[ac].aci_aifsn.aifsn;
+ tlv_wmm_parameter->wmm_para.ac_params[ac].aci_aifsn.aci =
+ bss->param.bss_config.wmm_para.ac_params[ac].aci_aifsn.aci;
tlv_wmm_parameter->wmm_para.ac_params[ac].ecw.ecw_max =
bss->param.bss_config.wmm_para.ac_params[ac].ecw.ecw_max;
tlv_wmm_parameter->wmm_para.ac_params[ac].ecw.ecw_min =
@@ -1468,6 +1528,8 @@ wlan_uap_ret_cmd_ap_config(IN pmlan_private pmpriv,
for (ac = 0; ac < 4; ac++) {
bss->param.bss_config.wmm_para.ac_params[ac].aci_aifsn.aifsn =
tlv_wmm_parameter->wmm_para.ac_params[ac].aci_aifsn.aifsn;
+ bss->param.bss_config.wmm_para.ac_params[ac].aci_aifsn.aci =
+ tlv_wmm_parameter->wmm_para.ac_params[ac].aci_aifsn.aci;
bss->param.bss_config.wmm_para.ac_params[ac].ecw.ecw_max =
tlv_wmm_parameter->wmm_para.ac_params[ac].ecw.ecw_max;
bss->param.bss_config.wmm_para.ac_params[ac].ecw.ecw_min =
@@ -1928,143 +1990,180 @@ wlan_uap_cmd_key_material(IN pmlan_private pmpriv,
{
HostCmd_DS_802_11_KEY_MATERIAL *pkey_material = &cmd->params.key_material;
mlan_ds_encrypt_key *pkey = (mlan_ds_encrypt_key *) pdata_buf;
- MrvlIEtypes_MacAddr_t *tlv = MNULL;
- const t_u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- t_u16 key_param_len = 0;
mlan_status ret = MLAN_STATUS_SUCCESS;
sta_node *sta_ptr = MNULL;
ENTER();
-
+ if (!pkey) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
pkey_material->action = wlan_cpu_to_le16(cmd_action);
-
if (cmd_action == HostCmd_ACT_GEN_GET) {
cmd->size = wlan_cpu_to_le16(sizeof(pkey_material->action) + S_DS_GEN);
goto done;
}
-
memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
- sizeof(MrvlIEtype_KeyParamSet_t));
- if (pkey->key_len &&
- memcmp(pmpriv->adapter, pkey->mac_addr, bc_mac, sizeof(bc_mac)))
- pmpriv->adapter->scan_block = MFALSE;
+ sizeof(MrvlIEtype_KeyParamSetV2_t));
+ if (pkey->key_flags & KEY_FLAG_REMOVE_KEY) {
+ pkey_material->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_REMOVE);
+ pkey_material->key_param_set.type =
+ wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN);
+ pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
+ pkey_material->key_param_set.key_info =
+ KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY;
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.mac_addr,
+ pkey->mac_addr, MLAN_MAC_ADDR_LENGTH);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Remove Key\n");
+ goto done;
+ }
+ pkey_material->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ pkey_material->key_param_set.key_idx = pkey->key_index & KEY_INDEX_MASK;
+ pkey_material->key_param_set.type = wlan_cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
+ pkey_material->key_param_set.key_info = KEY_INFO_ENABLE_KEY;
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.mac_addr,
+ pkey->mac_addr, MLAN_MAC_ADDR_LENGTH);
+ if (pkey->key_len <= MAX_WEP_KEY_SIZE) {
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(wep_param_t));
+ pkey_material->key_param_set.key_type =
+ wlan_cpu_to_le16(KEY_TYPE_ID_WEP);
+ pkey_material->key_param_set.key_info |=
+ KEY_INFO_MCAST_KEY | KEY_INFO_UCAST_KEY;
+ if (pkey_material->key_param_set.key_idx ==
+ (pmpriv->wep_key_curr_index & KEY_INDEX_MASK))
+ pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
+ pkey_material->key_param_set.key_params.wep.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.key_params.wep.key,
+ pkey->key_material, pkey->key_len);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(wep_param_t) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set WEP Key\n");
+ goto done;
+ }
+ if (pkey->key_flags & KEY_FLAG_GROUP_KEY) {
+ pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY;
+ } else {
+ pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY;
+ }
+ if (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)
+ pkey_material->key_param_set.key_info = KEY_INFO_CMAC_AES_KEY;
+ if (pkey->key_flags & KEY_FLAG_SET_TX_KEY)
+ pkey_material->key_param_set.key_info |=
+ KEY_INFO_TX_KEY | KEY_INFO_RX_KEY;
+ else
+ pkey_material->key_param_set.key_info |= KEY_INFO_TX_KEY;
if (pkey->is_wapi_key) {
- PRINTM(MINFO, "Set WAPI Key\n");
- pkey_material->key_param_set.key_type_id =
+ pkey_material->key_param_set.key_type =
wlan_cpu_to_le16(KEY_TYPE_ID_WAPI);
- if (cmd_oid == KEY_INFO_ENABLED)
- pkey_material->key_param_set.key_info =
- wlan_cpu_to_le16(KEY_INFO_WAPI_ENABLED);
- else
- pkey_material->key_param_set.key_info =
- !(wlan_cpu_to_le16(KEY_INFO_WAPI_ENABLED));
-
- pkey_material->key_param_set.key[0] = pkey->key_index;
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.key_params.wapi.pn,
+ pkey->pn, PN_SIZE);
+ pkey_material->key_param_set.key_params.wapi.key_len =
+ MIN(WAPI_KEY_SIZE, wlan_cpu_to_le16(pkey->key_len));
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.wapi.key,
+ pkey->key_material, MIN(WAPI_KEY_SIZE, pkey->key_len));
if (!pmpriv->sec_info.wapi_key_on)
- pkey_material->key_param_set.key[1] = 1;
- else
- pkey_material->key_param_set.key[1] = 0; /* set 0 when re-key */
-
- if (0 != memcmp(pmpriv->adapter, pkey->mac_addr, bc_mac, sizeof(bc_mac))) { /* WAPI
- pairwise
- key:
- unicast
- */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_WAPI_UNICAST);
+ pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
+ if (pkey->key_flags & KEY_FLAG_GROUP_KEY) {
+ pmpriv->sec_info.wapi_key_on = MTRUE;
+ } else {
+ /* WAPI pairwise key: unicast */
if ((sta_ptr = wlan_add_station_entry(pmpriv, pkey->mac_addr))) {
PRINTM(MCMND, "station: wapi_key_on\n");
sta_ptr->wapi_key_on = MTRUE;
}
- } else { /* WAPI group key: multicast */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_WAPI_MCAST);
- pmpriv->sec_info.wapi_key_on = MTRUE;
}
- pkey_material->key_param_set.type =
- wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
- pkey_material->key_param_set.key_len = wlan_cpu_to_le16(WAPI_KEY_LEN);
- memcpy(pmpriv->adapter, &pkey_material->key_param_set.key[2],
- pkey->key_material, pkey->key_len);
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
pkey_material->key_param_set.length =
- wlan_cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
-
- key_param_len =
- (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
- sizeof(MrvlIEtypesHeader_t);
- tlv =
- (MrvlIEtypes_MacAddr_t *) ((t_u8 *) & pkey_material->key_param_set +
- key_param_len);
- tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_STA_MAC_ADDRESS);
- tlv->header.len = wlan_cpu_to_le16(MLAN_MAC_ADDR_LENGTH);
- memcpy(pmpriv->adapter, tlv->mac, pkey->mac_addr, MLAN_MAC_ADDR_LENGTH);
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(wapi_param));
cmd->size =
- wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
- S_DS_GEN + sizeof(MrvlIEtypes_MacAddr_t));
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(wapi_param) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set WAPI Key\n");
goto done;
}
- if (pkey->key_len == WPA_AES_KEY_LEN) {
- PRINTM(MCMND, "WPA_AES\n");
- pkey_material->key_param_set.key_type_id =
+ pkey_material->key_param_set.key_info |= KEY_INFO_DEFAULT_KEY;
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(pkey_material->key_param_set.key_info);
+ if (pkey->key_len == WPA_AES_KEY_LEN &&
+ !(pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
+ if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.aes.pn, pkey->pn,
+ SEQ_MAX_SIZE);
+ pkey_material->key_param_set.key_type =
wlan_cpu_to_le16(KEY_TYPE_ID_AES);
- if (cmd_oid == KEY_INFO_ENABLED)
- pkey_material->key_param_set.key_info =
- wlan_cpu_to_le16(KEY_INFO_AES_ENABLED);
- else
- pkey_material->key_param_set.key_info =
- !(wlan_cpu_to_le16(KEY_INFO_AES_ENABLED));
-
- if (memcmp(pmpriv->adapter, pkey->mac_addr, bc_mac, sizeof(bc_mac))) /* AES
- pairwise
- key:
- unicast
- */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_AES_UNICAST);
- else /* AES group key: multicast */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_AES_MCAST);
- } else if (pkey->key_len == WPA_TKIP_KEY_LEN) {
- PRINTM(MCMND, "WPA_TKIP\n");
- pkey_material->key_param_set.key_type_id =
- wlan_cpu_to_le16(KEY_TYPE_ID_TKIP);
- pkey_material->key_param_set.key_info =
- wlan_cpu_to_le16(KEY_INFO_TKIP_ENABLED);
-
- if (memcmp(pmpriv->adapter, pkey->mac_addr, bc_mac, sizeof(bc_mac))) /* TKIP
- pairwise
- key:
- unicast
- */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_TKIP_UNICAST);
- else /* TKIP group key: multicast */
- pkey_material->key_param_set.key_info |=
- wlan_cpu_to_le16(KEY_INFO_TKIP_MCAST);
+ pkey_material->key_param_set.key_params.aes.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.key_params.aes.key,
+ pkey->key_material, pkey->key_len);
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(aes_param));
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(aes_param) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set AES Key\n");
+ goto done;
}
-
- if (pkey_material->key_param_set.key_type_id) {
- pkey_material->key_param_set.type =
- wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
- pkey_material->key_param_set.key_len = wlan_cpu_to_le16(pkey->key_len);
- memcpy(pmpriv->adapter, pkey_material->key_param_set.key,
+ if (pkey->key_len == WPA_IGTK_KEY_LEN &&
+ (pkey->key_flags & KEY_FLAG_AES_MCAST_IGTK)) {
+ if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.cmac_aes.ipn,
+ pkey->pn, SEQ_MAX_SIZE);
+ pkey_material->key_param_set.key_info &= ~KEY_INFO_MCAST_KEY;
+ pkey_material->key_param_set.key_info |=
+ wlan_cpu_to_le16(KEY_INFO_AES_MCAST_IGTK);
+ pkey_material->key_param_set.key_type = KEY_TYPE_ID_AES_CMAC;
+ pkey_material->key_param_set.key_params.cmac_aes.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.cmac_aes.key,
pkey->key_material, pkey->key_len);
pkey_material->key_param_set.length =
- wlan_cpu_to_le16((t_u16) pkey->key_len + KEYPARAMSET_FIXED_LEN);
- key_param_len =
- (pkey->key_len + KEYPARAMSET_FIXED_LEN) +
- sizeof(MrvlIEtypesHeader_t);
-
- tlv =
- (MrvlIEtypes_MacAddr_t *) ((t_u8 *) & pkey_material->key_param_set +
- key_param_len);
- tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_STA_MAC_ADDRESS);
- tlv->header.len = wlan_cpu_to_le16(MLAN_MAC_ADDR_LENGTH);
- memcpy(pmpriv->adapter, tlv->mac, pkey->mac_addr, MLAN_MAC_ADDR_LENGTH);
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(cmac_aes_param));
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(cmac_aes_param) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set CMAC AES Key\n");
+ goto done;
+ }
+ if (pkey->key_len == WPA_TKIP_KEY_LEN) {
+ if (pkey->key_flags & (KEY_FLAG_RX_SEQ_VALID | KEY_FLAG_TX_SEQ_VALID))
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.tkip.pn, pkey->pn,
+ SEQ_MAX_SIZE);
+ pkey_material->key_param_set.key_type =
+ wlan_cpu_to_le16(KEY_TYPE_ID_TKIP);
+ pkey_material->key_param_set.key_params.tkip.key_len =
+ wlan_cpu_to_le16(pkey->key_len);
+ memcpy(pmpriv->adapter,
+ pkey_material->key_param_set.key_params.tkip.key,
+ pkey->key_material, pkey->key_len);
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(KEY_PARAMS_FIXED_LEN + sizeof(tkip_param));
cmd->size =
- wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
- S_DS_GEN + sizeof(MrvlIEtypes_MacAddr_t));
+ wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) + S_DS_GEN +
+ KEY_PARAMS_FIXED_LEN + sizeof(tkip_param) +
+ sizeof(pkey_material->action));
+ PRINTM(MCMND, "Set TKIP Key\n");
}
done:
LEAVE();
@@ -2115,80 +2214,6 @@ wlan_uap_ret_sta_list(IN pmlan_private pmpriv,
}
/**
- * @brief This function will search for wps/wpa/rsn/wapi IE
- *
- *
- * @param priv A pointer to mlan_private
- * @param ie_buf A pointer to ie_buf
- * @param ie_len total ie length
- *
- * @return MTRUE/MFALSE
- */
-t_u8
-wlan_check_specific_ie(pmlan_private priv, t_u8 * ie_buf, t_u8 ie_len)
-{
- t_u32 bytes_left = ie_len;
- t_u8 *pcurrent_ptr = ie_buf;
- t_u16 total_ie_len;
- IEEEtypes_ElementId_e element_id;
- t_u8 element_len;
- IEEEtypes_VendorSpecific_t *pvendor_ie;
- const t_u8 wps_oui[4] = { 0x00, 0x50, 0xf2, 0x04 };
- const t_u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
- t_u8 find_wps_ie = 0;
- t_u8 find_sec_ie = 0;
- t_u8 ret = MFALSE;
-
- ENTER();
-
- DBG_HEXDUMP(MCMD_D, "ie", ie_buf, ie_len);
- while (bytes_left >= 2) {
- element_id = (IEEEtypes_ElementId_e) (*((t_u8 *) pcurrent_ptr));
- element_len = *((t_u8 *) pcurrent_ptr + 1);
- total_ie_len = element_len + sizeof(IEEEtypes_Header_t);
- if (bytes_left < total_ie_len) {
- PRINTM(MERROR, "InterpretIE: Error in processing IE, "
- "bytes left < IE length\n");
- break;
- }
- switch (element_id) {
- case WAPI_IE:
- PRINTM(MCMND, "Find WAPI ie\n");
- find_sec_ie = MTRUE;
- break;
- case RSN_IE:
- PRINTM(MCMND, "Find RSN ie\n");
- find_sec_ie = MTRUE;
- break;
- case VENDOR_SPECIFIC_221:
- pvendor_ie = (IEEEtypes_VendorSpecific_t *) pcurrent_ptr;
- if (!memcmp
- (priv->adapter, pvendor_ie->vend_hdr.oui, wpa_oui,
- sizeof(wpa_oui))) {
- PRINTM(MCMND, "Find WPA ie\n");
- find_sec_ie = MTRUE;
- } else
- if (!memcmp
- (priv->adapter, pvendor_ie->vend_hdr.oui, wps_oui,
- sizeof(wps_oui))) {
- PRINTM(MCMND, "Find WPS ie\n");
- find_wps_ie = MTRUE;
- }
- break;
- default:
- break;
- }
- pcurrent_ptr += element_len + 2;
- /* Need to account for IE ID and IE Len */
- bytes_left -= (element_len + 2);
- }
- if (find_sec_ie || find_wps_ie)
- ret = MTRUE;
- LEAVE();
- return ret;
-}
-
-/**
* @brief This function will search for the specific ie
*
*
@@ -2240,8 +2265,6 @@ wlan_check_sta_capability(pmlan_private priv, pmlan_buffer pevent,
assoc_req_ie =
(t_u8 *) tlv + sizeof(MrvlIETypes_MgmtFrameSet_t) +
assoc_ie_len;
- if (wlan_check_specific_ie(priv, assoc_req_ie, ie_len))
- priv->adapter->scan_block = MTRUE;
sta_ptr->is_wmm_enabled =
wlan_is_wmm_ie_present(priv->adapter, assoc_req_ie, ie_len);
PRINTM(MCMND, "STA: is_wmm_enabled=%d\n",
@@ -2295,7 +2318,8 @@ wlan_check_uap_capability(pmlan_private priv, pmlan_buffer pevent)
(MrvlIEtypesHeader_t *) (pevent->pbuf + pevent->data_offset +
BSS_START_EVENT_FIX_SIZE);
const t_u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
- IEEEtypes_WmmParameter_t *pWmmParamIe = MNULL;
+ IEEEtypes_WmmParameter_t WmmParamIe;
+ MrvlIEtypes_channel_band_t *pChanInfo;
priv->wmm_enabled = MFALSE;
priv->pkt_fwd = MFALSE;
priv->is_11n_enabled = MFALSE;
@@ -2325,10 +2349,11 @@ wlan_check_uap_capability(pmlan_private priv, pmlan_buffer pevent)
priv->wmm_enabled = MFALSE;
wlan_wmm_setup_ac_downgrade(priv);
priv->wmm_enabled = MTRUE;
- pWmmParamIe = (IEEEtypes_WmmParameter_t *) ((t_u8 *) tlv + 2);
- pWmmParamIe->vend_hdr.len = (t_u8) tlv_len;
- pWmmParamIe->vend_hdr.element_id = WMM_IE;
- wlan_wmm_setup_queue_priorities(priv, pWmmParamIe);
+ memcpy(priv->adapter, &WmmParamIe, ((t_u8 *) tlv + 2),
+ sizeof(IEEEtypes_WmmParameter_t));
+ WmmParamIe.vend_hdr.len = (t_u8) tlv_len;
+ WmmParamIe.vend_hdr.element_id = WMM_IE;
+ wlan_wmm_setup_queue_priorities(priv, &WmmParamIe);
}
}
if (tlv_type == TLV_TYPE_UAP_PKT_FWD_CTL) {
@@ -2342,6 +2367,14 @@ wlan_check_uap_capability(pmlan_private priv, pmlan_buffer pevent)
priv->pkt_fwd |= PKT_FWD_ENABLE_BIT;
PRINTM(MCMND, "pkt_fwd DRV: 0x%x\n", priv->pkt_fwd);
}
+ if (tlv_type == TLV_TYPE_UAP_CHAN_BAND_CONFIG) {
+ DBG_HEXDUMP(MCMD_D, "chan_band_config tlv", tlv,
+ tlv_len + sizeof(MrvlIEtypesHeader_t));
+ pChanInfo = (MrvlIEtypes_channel_band_t *) tlv;
+ priv->uap_channel = pChanInfo->channel;
+ PRINTM(MCMND, "uap_channel FW: 0x%x\n", priv->uap_channel);
+ }
+
tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
tlv =
(MrvlIEtypesHeader_t *) ((t_u8 *) tlv + tlv_len +
@@ -2555,6 +2588,9 @@ wlan_ops_uap_prepare_cmd(IN t_void * priv,
case HostCmd_CMD_CFG_DATA:
ret = wlan_cmd_cfg_data(pmpriv, cmd_ptr, cmd_action, pdata_buf);
break;
+ case HostCmd_CMD_MAC_CONTROL:
+ ret = wlan_cmd_mac_control(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
case HostCmd_CMD_802_11_SNMP_MIB:
ret = wlan_uap_cmd_snmp_mib(pmpriv, cmd_ptr, cmd_action, cmd_oid,
(pmlan_ioctl_req) pioctl_buf, pdata_buf);
@@ -2633,7 +2669,8 @@ wlan_ops_uap_prepare_cmd(IN t_void * priv,
cmd_ptr->params.rx_mgmt_ind.action = wlan_cpu_to_le16(cmd_action);
cmd_ptr->params.rx_mgmt_ind.mgmt_subtype_mask =
(t_u32) (*((t_u32 *) pdata_buf));
- cmd_ptr->size = wlan_cpu_to_le16(sizeof(t_u32) + S_DS_GEN);
+ cmd_ptr->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_RX_MGMT_IND) + S_DS_GEN);
break;
case HostCmd_CMD_CFG_TX_DATA_PAUSE:
ret = wlan_uap_cmd_txdatapause(pmpriv, cmd_ptr, cmd_action, pdata_buf);
@@ -2676,7 +2713,14 @@ wlan_ops_uap_prepare_cmd(IN t_void * priv,
case HostCmd_CMD_MEM_ACCESS:
ret = wlan_cmd_mem_access(cmd_ptr, cmd_action, pdata_buf);
break;
-
+ case HostCmd_CMD_WMM_QUEUE_CONFIG:
+ ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf);
+ break;
+#if defined(MUTLI_CHAN_SUPPORT)
+ case HostCmd_CMD_MULTI_CHAN_CONFIG:
+ ret = wlan_cmd_multi_chan_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+#endif
default:
PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
if (pioctl_req)
@@ -2733,9 +2777,8 @@ wlan_ops_uap_process_cmdresp(IN t_void * priv,
wlan_11h_radar_detected_callback((t_void *) pmpriv);
break;
case HOST_CMD_APCMD_SYS_RESET:
- ret = wlan_uap_ret_sys_reset(pmpriv, resp, pioctl_buf);
-
pmpriv->uap_bss_started = MFALSE;
+ ret = wlan_uap_ret_sys_reset(pmpriv, resp, pioctl_buf);
wlan_11h_check_update_radar_det_state(pmpriv);
break;
case HOST_CMD_APCMD_SYS_INFO:
@@ -2773,6 +2816,9 @@ wlan_ops_uap_process_cmdresp(IN t_void * priv,
case HostCmd_CMD_CFG_DATA:
ret = wlan_ret_cfg_data(pmpriv, resp, pioctl_buf);
break;
+ case HostCmd_CMD_MAC_CONTROL:
+ ret = wlan_ret_mac_control(pmpriv, resp, pioctl_buf);
+ break;
case HostCmd_CMD_802_11_HS_CFG_ENH:
ret = wlan_ret_802_11_hs_cfg(pmpriv, resp, pioctl_buf);
break;
@@ -2863,7 +2909,9 @@ wlan_ops_uap_process_cmdresp(IN t_void * priv,
case HostCmd_CMD_MEM_ACCESS:
ret = wlan_ret_mem_access(pmpriv, resp, pioctl_buf);
break;
-
+ case HostCmd_CMD_WMM_QUEUE_CONFIG:
+ ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf);
+ break;
default:
PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n",
resp->command);
@@ -2899,6 +2947,13 @@ wlan_ops_uap_process_event(IN t_void * priv)
ENTER();
+ /* Event length check */
+ if ((pmbuf->data_len - sizeof(eventcause)) > MAX_EVENT_SIZE) {
+ pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
+ }
+
/* Allocate memory for event buffer */
ret =
pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE, MLAN_MEM_DEF,
@@ -2933,10 +2988,10 @@ wlan_ops_uap_process_event(IN t_void * priv)
break;
case EVENT_MICRO_AP_BSS_IDLE:
PRINTM(MEVENT, "EVENT: MICRO_AP_BSS_IDLE\n");
- pmadapter->scan_block = MFALSE;
pevent->event_id = MLAN_EVENT_ID_UAP_FW_BSS_IDLE;
pmpriv->media_connected = MFALSE;
wlan_clean_txrx(pmpriv);
+ wlan_notify_station_deauth(pmpriv);
wlan_delete_station_list(pmpriv);
break;
case EVENT_PS_AWAKE:
@@ -2959,11 +3014,12 @@ wlan_ops_uap_process_event(IN t_void * priv)
wlan_check_ps_cond(pmadapter);
break;
case EVENT_MICRO_AP_STA_ASSOC:
- PRINTM(MEVENT, "EVENT: MICRO_AP_STA_ASSOC\n");
wlan_process_sta_assoc_event(pmpriv, pevent, pmbuf);
memcpy(pmadapter, sta_addr, pmadapter->event_body + 2,
MLAN_MAC_ADDR_LENGTH);
sta_ptr = wlan_add_station_entry(pmpriv, sta_addr);
+ PRINTM(MMSG, "wlan: EVENT: MICRO_AP_STA_ASSOC " MACSTR "\n",
+ MAC2STR(sta_addr));
if (pmpriv->is_11n_enabled) {
wlan_check_sta_capability(pmpriv, pmbuf, sta_ptr);
for (i = 0; i < MAX_NUM_TID; i++) {
@@ -2979,8 +3035,6 @@ wlan_ops_uap_process_event(IN t_void * priv)
pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
break;
case EVENT_MICRO_AP_STA_DEAUTH:
- PRINTM(MEVENT, "EVENT: MICRO_AP_STA_DEAUTH\n");
- pmadapter->scan_block = MFALSE;
pevent->event_id = MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT;
pevent->bss_index = pmpriv->bss_index;
pevent->event_len = pmbuf->data_len - 4;
@@ -2990,6 +3044,8 @@ wlan_ops_uap_process_event(IN t_void * priv)
wlan_recv_event(pmpriv, pevent->event_id, pevent);
memcpy(pmadapter, sta_addr, pmadapter->event_body + 2,
MLAN_MAC_ADDR_LENGTH);
+ PRINTM(MMSG, "wlan: EVENT: MICRO_AP_STA_DEAUTH " MACSTR "\n",
+ MAC2STR(sta_addr));
if (pmpriv->is_11n_enabled) {
wlan_cleanup_reorder_tbl(pmpriv, sta_addr);
pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle,
@@ -3097,6 +3153,20 @@ wlan_ops_uap_process_event(IN t_void * priv)
pevent->event_id = MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED;
break;
#endif
+
+ case EVENT_FW_DEBUG_INFO:
+ PRINTM(MERROR, "EVENT: FW Debug Info\n");
+ memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE);
+ pevent->bss_index = pmpriv->bss_index;
+ pevent->event_id = MLAN_EVENT_ID_FW_DEBUG_INFO;
+ pevent->event_len = pmbuf->data_len - sizeof(eventcause);
+ memcpy(pmadapter,
+ (t_u8 *) pevent->event_buf,
+ pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause),
+ pevent->event_len);
+ wlan_recv_event(pmpriv, pevent->event_id, pevent);
+ pevent->event_id = 0; // clear to avoid resending at end of fcn
+ break;
default:
pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
break;
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c b/drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c
index 86b4942dff2f..58c69bdeea55 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c
@@ -682,7 +682,7 @@ wlan_uap_sec_ioctl_set_encrypt_key(IN pmlan_adapter pmadapter,
LEAVE();
return MLAN_STATUS_FAILURE;
}
- if (!sec->param.encrypt_key.key_len) {
+ if (!sec->param.encrypt_key.key_remove && !sec->param.encrypt_key.key_len) {
PRINTM(MCMND, "Skip set key with key_len = 0\n");
LEAVE();
return ret;
@@ -867,11 +867,18 @@ wlan_uap_callback_domain_info(IN t_void * priv)
wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb;
mlan_ds_11d_cfg *cfg11d;
t_u8 band;
+ pmlan_adapter pmadapter = pmpriv->adapter;
+ pmlan_callbacks pcb = &pmadapter->callbacks;
ENTER();
/* clear callback now that we're here */
puap_state_chan_cb->get_chan_callback = MNULL;
+ if (!puap_state_chan_cb->pioctl_req_curr) {
+ PRINTM(MERROR, "pioctl_req_curr is null\n");
+ LEAVE();
+ return ret;
+ }
cfg11d = (mlan_ds_11d_cfg *) puap_state_chan_cb->pioctl_req_curr->pbuf;
band =
(puap_state_chan_cb->band_config & BAND_CONFIG_5GHZ) ? BAND_A : BAND_B;
@@ -881,6 +888,12 @@ wlan_uap_callback_domain_info(IN t_void * priv)
puap_state_chan_cb->pioctl_req_curr);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
+ else {
+ puap_state_chan_cb->pioctl_req_curr->status_code = MLAN_STATUS_FAILURE;
+ pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
+ puap_state_chan_cb->pioctl_req_curr,
+ MLAN_STATUS_FAILURE);
+ }
puap_state_chan_cb->pioctl_req_curr = MNULL; // prevent re-use
LEAVE();
@@ -1248,8 +1261,8 @@ wlan_ops_uap_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req)
mlan_ds_misc_cfg *misc = MNULL;
mlan_ds_sec_cfg *sec = MNULL;
mlan_ds_pm_cfg *pm = MNULL;
- mlan_ds_snmp_mib *snmp = MNULL;
mlan_ds_11d_cfg *cfg11d = MNULL;
+ mlan_ds_snmp_mib *snmp = MNULL;
mlan_ds_11h_cfg *cfg11h = MNULL;
mlan_ds_radio_cfg *radiocfg = MNULL;
mlan_ds_rate *rate = MNULL;
@@ -1281,6 +1294,8 @@ wlan_ops_uap_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req)
else if (bss->sub_command == MLAN_OID_WIFI_DIRECT_MODE)
status = wlan_bss_ioctl_wifi_direct_mode(pmadapter, pioctl_req);
#endif
+ else if (bss->sub_command == MLAN_OID_BSS_REMOVE)
+ status = wlan_bss_ioctl_bss_remove(pmadapter, pioctl_req);
break;
case MLAN_IOCTL_GET_INFO:
pget_info = (mlan_ds_get_info *) pioctl_req->pbuf;
@@ -1329,6 +1344,8 @@ wlan_ops_uap_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req)
#endif
if (misc->sub_command == MLAN_OID_MISC_TXCONTROL)
status = wlan_misc_ioctl_txcontrol(pmadapter, pioctl_req);
+ if (misc->sub_command == MLAN_OID_MISC_MAC_CONTROL)
+ status = wlan_misc_ioctl_mac_control(pmadapter, pioctl_req);
break;
case MLAN_IOCTL_PM_CFG:
pm = (mlan_ds_pm_cfg *) pioctl_req->pbuf;
@@ -1404,6 +1421,9 @@ wlan_ops_uap_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req)
else if (reg_mem->sub_command == MLAN_OID_MEM_RW)
status = wlan_reg_mem_ioctl_mem_rw(pmadapter, pioctl_req);
break;
+ case MLAN_IOCTL_WMM_CFG:
+ status = wlan_wmm_cfg_ioctl(pmadapter, pioctl_req);
+ break;
default:
pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
break;
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c b/drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c
index 746d4547a82d..45c116a4c40a 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c
@@ -354,10 +354,8 @@ wlan_uap_recv_packet(IN mlan_private * priv, IN pmlan_buffer pmbuf)
DBG_HEXDUMP(MDAT_D, "uap_recv_packet", pmbuf->pbuf + pmbuf->data_offset,
MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));
- PRINTM(MDATA, "AMSDU dest %02x:%02x:%02x:%02x:%02x:%02x\n",
- prx_pkt->eth803_hdr.dest_addr[0], prx_pkt->eth803_hdr.dest_addr[1],
- prx_pkt->eth803_hdr.dest_addr[2], prx_pkt->eth803_hdr.dest_addr[3],
- prx_pkt->eth803_hdr.dest_addr[4], prx_pkt->eth803_hdr.dest_addr[5]);
+ PRINTM(MDATA, "AMSDU dest " MACSTR "\n",
+ MAC2STR(prx_pkt->eth803_hdr.dest_addr));
/* don't do packet forwarding in disconnected state */
if ((priv->media_connected == MFALSE) ||
@@ -419,13 +417,8 @@ wlan_uap_recv_packet(IN mlan_private * priv, IN pmlan_buffer pmbuf)
wlan_check_unicast_packet(priv,
prx_pkt->eth803_hdr.dest_addr)) {
/* drop packet */
- PRINTM(MDATA, "Drop AMSDU dest %02x:%02x:%02x:%02x:%02x:%02x\n",
- prx_pkt->eth803_hdr.dest_addr[0],
- prx_pkt->eth803_hdr.dest_addr[1],
- prx_pkt->eth803_hdr.dest_addr[2],
- prx_pkt->eth803_hdr.dest_addr[3],
- prx_pkt->eth803_hdr.dest_addr[4],
- prx_pkt->eth803_hdr.dest_addr[5]);
+ PRINTM(MDATA, "Drop AMSDU dest " MACSTR "\n",
+ MAC2STR(prx_pkt->eth803_hdr.dest_addr));
goto done;
}
}
@@ -469,10 +462,8 @@ wlan_process_uap_rx_packet(IN mlan_private * priv, IN pmlan_buffer pmbuf)
PRINTM(MINFO, "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
pmbuf->data_len, prx_pd->rx_pkt_offset,
pmbuf->data_len - prx_pd->rx_pkt_offset);
- PRINTM(MDATA, "Rx dest %02x:%02x:%02x:%02x:%02x:%02x\n",
- prx_pkt->eth803_hdr.dest_addr[0], prx_pkt->eth803_hdr.dest_addr[1],
- prx_pkt->eth803_hdr.dest_addr[2], prx_pkt->eth803_hdr.dest_addr[3],
- prx_pkt->eth803_hdr.dest_addr[4], prx_pkt->eth803_hdr.dest_addr[5]);
+ PRINTM(MDATA, "Rx dest " MACSTR "\n",
+ MAC2STR(prx_pkt->eth803_hdr.dest_addr));
/* don't do packet forwarding in disconnected state */
/* don't do packet forwarding when packet > 1514 */
@@ -521,18 +512,14 @@ wlan_process_uap_rx_packet(IN mlan_private * priv, IN pmlan_buffer pmbuf)
} else if (MLAN_STATUS_FAILURE ==
wlan_check_unicast_packet(priv,
prx_pkt->eth803_hdr.dest_addr)) {
- PRINTM(MDATA, "Drop Pkts: Rx dest %02x:%02x:%02x:%02x:%02x:%02x\n",
- prx_pkt->eth803_hdr.dest_addr[0],
- prx_pkt->eth803_hdr.dest_addr[1],
- prx_pkt->eth803_hdr.dest_addr[2],
- prx_pkt->eth803_hdr.dest_addr[3],
- prx_pkt->eth803_hdr.dest_addr[4],
- prx_pkt->eth803_hdr.dest_addr[5]);
+ PRINTM(MDATA, "Drop Pkts: Rx dest " MACSTR "\n",
+ MAC2STR(prx_pkt->eth803_hdr.dest_addr));
pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
wlan_free_mlan_buffer(pmadapter, pmbuf);
goto done;
}
}
+
upload:
/* Chop off RxPD */
pmbuf->data_len -= prx_pd->rx_pkt_offset;
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_wmm.c b/drivers/net/wireless/sd8797/mlan/mlan_wmm.c
index daf798265b98..f347a8019227 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_wmm.c
+++ b/drivers/net/wireless/sd8797/mlan/mlan_wmm.c
@@ -571,7 +571,7 @@ wlan_send_wmmac_host_event(pmlan_private priv,
pevent->bss_index = priv->bss_index;
pevent->event_id = MLAN_EVENT_ID_DRV_REPORT_STRING;
- pevent->event_len = wlan_strlen((const t_s8 *) (pevent->event_buf));
+ pevent->event_len = wlan_strlen((const char *) (pevent->event_buf));
wlan_recv_event(priv, MLAN_EVENT_ID_DRV_REPORT_STRING, pevent);
LEAVE();
@@ -702,6 +702,7 @@ wlan_wmm_get_highest_priolist_ptr(pmlan_adapter pmadapter,
if ((bssprio_node = bssprio_node->pnext) == (mlan_bssprio_node *)
& pmadapter->bssprio_tbl[j].bssprio_head)
bssprio_node = bssprio_node->pnext;
+ pmadapter->bssprio_tbl[j].bssprio_cur = bssprio_node;
} while (bssprio_node != bssprio_head);
}
@@ -1033,7 +1034,7 @@ wlan_dequeue_tx_packet(pmlan_adapter pmadapter)
* @return N/A
*/
t_void
-wlan_updata_ralist_tx_pause(pmlan_private priv, t_u8 * mac, t_u8 tx_pause)
+wlan_update_ralist_tx_pause(pmlan_private priv, t_u8 * mac, t_u8 tx_pause)
{
raListTbl *ra_list;
int i;
@@ -1128,9 +1129,7 @@ wlan_clean_txrx(pmlan_private priv)
ENTER();
- if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) {
- wlan_cleanup_bypass_txq(pmadapter);
- }
+ wlan_cleanup_bypass_txq(priv);
wlan_11n_cleanup_reorder_tbl(priv);
@@ -1162,9 +1161,6 @@ wlan_clean_txrx(pmlan_private priv)
MP_TX_AGGR_BUF_RESET(priv->adapter);
#endif
-#ifdef SDIO_MULTI_PORT_RX_AGGR
- MP_RX_AGGR_BUF_RESET(priv->adapter);
-#endif
wlan_wmm_delete_all_ralist(priv);
memcpy(pmadapter, tos_to_tid, ac_to_tid, sizeof(tos_to_tid));
for (i = 0; i < MAX_NUM_TID; i++) {
@@ -1384,15 +1380,8 @@ wlan_wmm_init(pmlan_adapter pmadapter)
if ((priv = pmadapter->priv[j])) {
for (i = 0; i < MAX_NUM_TID; ++i) {
priv->aggr_prio_tbl[i].amsdu = BA_STREAM_NOT_ALLOWED;
-#ifdef WIFI_DIRECT_SUPPORT
- if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
- priv->aggr_prio_tbl[i].ampdu_ap =
- priv->aggr_prio_tbl[i].ampdu_user =
- BA_STREAM_NOT_ALLOWED;
- else
-#endif
- priv->aggr_prio_tbl[i].ampdu_ap =
- priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i];
+ priv->aggr_prio_tbl[i].ampdu_ap =
+ priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i];
priv->wmm.pkts_queued[i] = 0;
priv->wmm.tid_tbl_ptr[i].ra_list_curr = MNULL;
}
@@ -1606,13 +1595,9 @@ wlan_ralist_update(mlan_private * priv, t_u8 * old_ra, t_u8 * new_ra)
ra_list->packet_count = 0;
ra_list->ba_packet_threshold =
wlan_get_random_ba_threshold(priv->adapter);
- PRINTM(MINFO,
- "ralist_update: %p, %d, %02x:%02x:%02x:%02x:%02x:%02x-->"
- "%02x:%02x:%02x:%02x:%02x:%02x\n", ra_list,
- ra_list->is_11n_enabled, ra_list->ra[0], ra_list->ra[1],
- ra_list->ra[2], ra_list->ra[3], ra_list->ra[4],
- ra_list->ra[5], new_ra[0], new_ra[1], new_ra[2], new_ra[3],
- new_ra[4], new_ra[5]);
+ PRINTM(MINFO, "ralist_update: %p, %d, " MACSTR "-->" MACSTR "\n",
+ ra_list, ra_list->is_11n_enabled, MAC2STR(ra_list->ra),
+ MAC2STR(new_ra));
memcpy(priv->adapter, ra_list->ra, new_ra, MLAN_MAC_ADDR_LENGTH);
}
@@ -2065,11 +2050,9 @@ wlan_del_tx_pkts_in_ralist(pmlan_private priv,
&ra_list->buf_head, MNULL,
MNULL))) {
PRINTM(MDATA,
- "Drop pkts: tid=%d tx_pause=%d pkts=%d brd_pkts=%d %02x:%02x:%02x:%02x:%02x:%02x\n",
- tid, ra_list->tx_pause, ra_list->total_pkts,
- pmadapter->pending_bridge_pkts, ra_list->ra[0],
- ra_list->ra[1], ra_list->ra[2], ra_list->ra[3],
- ra_list->ra[4], ra_list->ra[5]);
+ "Drop pkts: tid=%d tx_pause=%d pkts=%d brd_pkts=%d "
+ MACSTR "\n", tid, ra_list->tx_pause, ra_list->total_pkts,
+ pmadapter->pending_bridge_pkts, MAC2STR(ra_list->ra));
wlan_write_data_complete(pmadapter, pmbuf, MLAN_STATUS_FAILURE);
priv->wmm.pkts_queued[tid]--;
priv->num_drop_pkts++;
@@ -2344,70 +2327,6 @@ wlan_ret_wmm_delts_req(IN pmlan_private pmpriv,
}
/**
- * @brief This function prepares the command of WMM_QUEUE_CONFIG
- *
- * @param pmpriv A pointer to mlan_private structure
- * @param cmd A pointer to HostCmd_DS_COMMAND structure
- * @param pdata_buf A pointer to data buffer
- * @return MLAN_STATUS_SUCCESS
- */
-mlan_status
-wlan_cmd_wmm_queue_config(IN pmlan_private pmpriv,
- OUT HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
-{
- mlan_ds_wmm_queue_config *pqcfg = (mlan_ds_wmm_queue_config *) pdata_buf;
- HostCmd_DS_WMM_QUEUE_CONFIG *pcmd_qcfg = &cmd->params.queue_config;
-
- ENTER();
-
- cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_QUEUE_CONFIG);
- cmd->size = wlan_cpu_to_le16(sizeof(pcmd_qcfg->action)
- + sizeof(pcmd_qcfg->access_category)
- + sizeof(pcmd_qcfg->msdu_lifetime_expiry)
- + S_DS_GEN);
- cmd->result = 0;
-
- pcmd_qcfg->action = pqcfg->action;
- pcmd_qcfg->access_category = pqcfg->access_category;
- pcmd_qcfg->msdu_lifetime_expiry =
- wlan_cpu_to_le16(pqcfg->msdu_lifetime_expiry);
-
- LEAVE();
- return MLAN_STATUS_SUCCESS;
-}
-
-/**
- * @brief This function handles the command response of WMM_QUEUE_CONFIG
- *
- * @param pmpriv A pointer to mlan_private structure
- * @param resp A pointer to HostCmd_DS_COMMAND
- * @param pioctl_buf A pointer to mlan_ioctl_req structure
- *
- * @return MLAN_STATUS_SUCCESS
- */
-mlan_status
-wlan_ret_wmm_queue_config(IN pmlan_private pmpriv,
- const IN HostCmd_DS_COMMAND * resp,
- OUT mlan_ioctl_req * pioctl_buf)
-{
- mlan_ds_wmm_cfg *pwmm = MNULL;
- const HostCmd_DS_WMM_QUEUE_CONFIG *presp_qcfg = &resp->params.queue_config;
-
- ENTER();
-
- if (pioctl_buf) {
- pwmm = (mlan_ds_wmm_cfg *) pioctl_buf->pbuf;
- pwmm->param.q_cfg.action = presp_qcfg->action;
- pwmm->param.q_cfg.access_category = presp_qcfg->access_category;
- pwmm->param.q_cfg.msdu_lifetime_expiry =
- wlan_le16_to_cpu(presp_qcfg->msdu_lifetime_expiry);
- }
-
- LEAVE();
- return MLAN_STATUS_SUCCESS;
-}
-
-/**
* @brief This function prepares the command of WMM_QUEUE_STATS
*
* @param pmpriv A pointer to mlan_private structure
@@ -2552,4 +2471,381 @@ wlan_ret_wmm_ts_status(IN pmlan_private pmpriv,
LEAVE();
return MLAN_STATUS_SUCCESS;
}
+
+/**
+ * @brief Set/Get WMM status
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_SUCCESS --success
+ */
+static mlan_status
+wlan_wmm_ioctl_enable(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_wmm_cfg *wmm = MNULL;
+ ENTER();
+ wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+ if (pioctl_req->action == MLAN_ACT_GET)
+ wmm->param.wmm_enable = (t_u32) pmpriv->wmm_required;
+ else
+ pmpriv->wmm_required = (t_u8) wmm->param.wmm_enable;
+ pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Set/Get WMM QoS configuration
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_SUCCESS --success
+ */
+static mlan_status
+wlan_wmm_ioctl_qos(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_wmm_cfg *wmm = MNULL;
+
+ ENTER();
+
+ wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+ if (pioctl_req->action == MLAN_ACT_GET)
+ wmm->param.qos_cfg = pmpriv->wmm_qosinfo;
+ else {
+ pmpriv->wmm_qosinfo = wmm->param.qos_cfg;
+ }
+
+ pioctl_req->data_read_written = sizeof(t_u8) + MLAN_SUB_COMMAND_SIZE;
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Request for add a TSPEC
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_addts_req(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_wmm_cfg *cfg = MNULL;
+
+ ENTER();
+ cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+ /* Send request to firmware */
+ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_ADDTS_REQ,
+ 0, 0, (t_void *) pioctl_req,
+ (t_void *) & cfg->param.addts);
+
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Request for delete a TSPEC
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_delts_req(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_wmm_cfg *cfg = MNULL;
+
+ ENTER();
+ cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+ /* Send request to firmware */
+ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_DELTS_REQ,
+ 0, 0, (t_void *) pioctl_req,
+ (t_void *) & cfg->param.delts);
+
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief To get and start/stop queue stats on a WMM AC
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_queue_stats(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_wmm_cfg *cfg = MNULL;
+
+ ENTER();
+ cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+ /* Send request to firmware */
+ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_QUEUE_STATS,
+ 0, 0, (t_void *) pioctl_req,
+ (t_void *) & cfg->param.q_stats);
+
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Get the status of the WMM AC queues
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_SUCCESS --success
+ */
+static mlan_status
+wlan_wmm_ioctl_queue_status(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_wmm_cfg *cfg = MNULL;
+ mlan_ds_wmm_queue_status *pqstatus = MNULL;
+ WmmAcStatus_t *pac_status = MNULL;
+ mlan_wmm_ac_e ac_idx;
+
+ ENTER();
+
+ cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+ pqstatus = (mlan_ds_wmm_queue_status *) & cfg->param.q_status;
+
+ for (ac_idx = WMM_AC_BK; ac_idx <= WMM_AC_VO; ac_idx++) {
+ pac_status = &pmpriv->wmm.ac_status[ac_idx];
+
+ /* Firmware status */
+ pqstatus->ac_status[ac_idx].flow_required = pac_status->flow_required;
+ pqstatus->ac_status[ac_idx].flow_created = pac_status->flow_created;
+ pqstatus->ac_status[ac_idx].disabled = pac_status->disabled;
+
+ /* ACM bit reflected in firmware status (redundant) */
+ pqstatus->ac_status[ac_idx].wmm_acm = pac_status->flow_required;
+ }
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Get the status of the WMM Traffic Streams
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_ts_status(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_wmm_cfg *cfg = MNULL;
+
+ ENTER();
+
+ cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+ /* Send request to firmware */
+ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_TS_STATUS,
+ 0, 0, (t_void *) pioctl_req,
+ (t_void *) & cfg->param.ts_status);
+
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
+
+ LEAVE();
+ return ret;
+}
#endif /* STA_SUPPORT */
+
+/**
+ * @brief This function prepares the command of WMM_QUEUE_CONFIG
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param pdata_buf A pointer to data buffer
+ * @return MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_cmd_wmm_queue_config(IN pmlan_private pmpriv,
+ OUT HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+ mlan_ds_wmm_queue_config *pqcfg = (mlan_ds_wmm_queue_config *) pdata_buf;
+ HostCmd_DS_WMM_QUEUE_CONFIG *pcmd_qcfg = &cmd->params.queue_config;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_QUEUE_CONFIG);
+ cmd->size = wlan_cpu_to_le16(sizeof(pcmd_qcfg->action)
+ + sizeof(pcmd_qcfg->access_category)
+ + sizeof(pcmd_qcfg->msdu_lifetime_expiry)
+ + S_DS_GEN);
+ cmd->result = 0;
+
+ pcmd_qcfg->action = pqcfg->action;
+ pcmd_qcfg->access_category = pqcfg->access_category;
+ pcmd_qcfg->msdu_lifetime_expiry =
+ wlan_cpu_to_le16(pqcfg->msdu_lifetime_expiry);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function handles the command response of WMM_QUEUE_CONFIG
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param resp A pointer to HostCmd_DS_COMMAND
+ * @param pioctl_buf A pointer to mlan_ioctl_req structure
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_wmm_queue_config(IN pmlan_private pmpriv,
+ const IN HostCmd_DS_COMMAND * resp,
+ OUT mlan_ioctl_req * pioctl_buf)
+{
+ mlan_ds_wmm_cfg *pwmm = MNULL;
+ const HostCmd_DS_WMM_QUEUE_CONFIG *presp_qcfg = &resp->params.queue_config;
+
+ ENTER();
+
+ if (pioctl_buf) {
+ pwmm = (mlan_ds_wmm_cfg *) pioctl_buf->pbuf;
+ pwmm->param.q_cfg.action = presp_qcfg->action;
+ pwmm->param.q_cfg.access_category = presp_qcfg->access_category;
+ pwmm->param.q_cfg.msdu_lifetime_expiry =
+ wlan_le16_to_cpu(presp_qcfg->msdu_lifetime_expiry);
+ }
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief Set/Get a specified AC Queue's parameters
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_queue_config(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
+ mlan_ds_wmm_cfg *cfg = MNULL;
+
+ ENTER();
+ cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+ /* Send request to firmware */
+ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_QUEUE_CONFIG,
+ 0, 0, (t_void *) pioctl_req,
+ (t_void *) & cfg->param.q_cfg);
+
+ if (ret == MLAN_STATUS_SUCCESS)
+ ret = MLAN_STATUS_PENDING;
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief WMM configuration handler
+ *
+ * @param pmadapter A pointer to mlan_adapter structure
+ * @param pioctl_req A pointer to ioctl request buffer
+ *
+ * @return MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+wlan_wmm_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+ mlan_status status = MLAN_STATUS_SUCCESS;
+ mlan_ds_wmm_cfg *wmm = MNULL;
+
+ ENTER();
+
+ if (pioctl_req->buf_len < sizeof(mlan_ds_wmm_cfg)) {
+ PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+ pioctl_req->data_read_written = 0;
+ pioctl_req->buf_len_needed = sizeof(mlan_ds_wmm_cfg);
+ pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
+ LEAVE();
+ return MLAN_STATUS_RESOURCE;
+ }
+ wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+ switch (wmm->sub_command) {
+#ifdef STA_SUPPORT
+ case MLAN_OID_WMM_CFG_ENABLE:
+ status = wlan_wmm_ioctl_enable(pmadapter, pioctl_req);
+ break;
+ case MLAN_OID_WMM_CFG_QOS:
+ status = wlan_wmm_ioctl_qos(pmadapter, pioctl_req);
+ break;
+ case MLAN_OID_WMM_CFG_ADDTS:
+ status = wlan_wmm_ioctl_addts_req(pmadapter, pioctl_req);
+ break;
+ case MLAN_OID_WMM_CFG_DELTS:
+ status = wlan_wmm_ioctl_delts_req(pmadapter, pioctl_req);
+ break;
+ case MLAN_OID_WMM_CFG_QUEUE_STATS:
+ status = wlan_wmm_ioctl_queue_stats(pmadapter, pioctl_req);
+ break;
+ case MLAN_OID_WMM_CFG_QUEUE_STATUS:
+ status = wlan_wmm_ioctl_queue_status(pmadapter, pioctl_req);
+ break;
+ case MLAN_OID_WMM_CFG_TS_STATUS:
+ status = wlan_wmm_ioctl_ts_status(pmadapter, pioctl_req);
+ break;
+#endif
+ case MLAN_OID_WMM_CFG_QUEUE_CONFIG:
+ status = wlan_wmm_ioctl_queue_config(pmadapter, pioctl_req);
+ break;
+ default:
+ pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
+ status = MLAN_STATUS_FAILURE;
+ break;
+ }
+ LEAVE();
+ return status;
+}
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_wmm.h b/drivers/net/wireless/sd8797/mlan/mlan_wmm.h
index 89a2c8f37e49..e36dea734b6d 100644
--- a/drivers/net/wireless/sd8797/mlan/mlan_wmm.h
+++ b/drivers/net/wireless/sd8797/mlan/mlan_wmm.h
@@ -138,10 +138,6 @@ extern mlan_status wlan_cmd_wmm_addts_req(IN pmlan_private pmpriv,
extern mlan_status wlan_cmd_wmm_delts_req(IN pmlan_private pmpriv,
OUT HostCmd_DS_COMMAND * cmd,
IN t_void * pdata_buf);
-/** WMM QUEUE_CONFIG command handler */
-extern mlan_status wlan_cmd_wmm_queue_config(IN pmlan_private pmpriv,
- OUT HostCmd_DS_COMMAND * cmd,
- IN t_void * pdata_buf);
/** WMM QUEUE_STATS command handler */
extern mlan_status wlan_cmd_wmm_queue_stats(IN pmlan_private pmpriv,
OUT HostCmd_DS_COMMAND * cmd,
@@ -165,10 +161,6 @@ extern mlan_status wlan_ret_wmm_addts_req(IN pmlan_private pmpriv,
extern mlan_status wlan_ret_wmm_delts_req(IN pmlan_private pmpriv,
const IN HostCmd_DS_COMMAND * resp,
OUT mlan_ioctl_req * pioctl_buf);
-/** WMM QUEUE_CONFIG command response handler */
-extern mlan_status wlan_ret_wmm_queue_config(IN pmlan_private pmpriv,
- const IN HostCmd_DS_COMMAND * resp,
- OUT mlan_ioctl_req * pioctl_buf);
/** WMM QUEUE_STATS command response handler */
extern mlan_status wlan_ret_wmm_queue_stats(IN pmlan_private pmpriv,
const IN HostCmd_DS_COMMAND * resp,
@@ -179,4 +171,16 @@ extern mlan_status wlan_ret_wmm_ts_status(IN pmlan_private pmpriv,
OUT mlan_ioctl_req * pioctl_buf);
#endif /* STA_SUPPORT */
+/** WMM QUEUE_CONFIG command handler */
+extern mlan_status wlan_cmd_wmm_queue_config(IN pmlan_private pmpriv,
+ OUT HostCmd_DS_COMMAND * cmd,
+ IN t_void * pdata_buf);
+
+/** WMM QUEUE_CONFIG command response handler */
+extern mlan_status wlan_ret_wmm_queue_config(IN pmlan_private pmpriv,
+ const IN HostCmd_DS_COMMAND * resp,
+ OUT mlan_ioctl_req * pioctl_buf);
+
+mlan_status wlan_wmm_cfg_ioctl(IN pmlan_adapter pmadapter,
+ IN pmlan_ioctl_req pioctl_req);
#endif /* !_MLAN_WMM_H_ */
diff --git a/drivers/net/wireless/sd8797/mlinux/mlan_decl.h b/drivers/net/wireless/sd8797/mlinux/mlan_decl.h
index ac24b5e79fc4..28ab785045e3 100644
--- a/drivers/net/wireless/sd8797/mlinux/mlan_decl.h
+++ b/drivers/net/wireless/sd8797/mlinux/mlan_decl.h
@@ -27,11 +27,11 @@ Change log:
#define _MLAN_DECL_H_
/** MLAN release version */
-#define MLAN_RELEASE_VERSION "334"
+#define MLAN_RELEASE_VERSION "394"
/** Re-define generic data types for MLAN/MOAL */
/** Signed char (1-byte) */
-typedef char t_s8;
+typedef signed char t_s8;
/** Unsigned char (1-byte) */
typedef unsigned char t_u8;
/** Signed short (2-bytes) */
@@ -101,6 +101,16 @@ typedef t_s32 t_sval;
/** MLAN FALSE */
#define MFALSE (0)
+#ifndef MACSTR
+/** MAC address security format */
+#define MACSTR "%02x:XX:XX:XX:%02x:%02x"
+#endif
+
+#ifndef MAC2STR
+/** MAC address security print arguments */
+#define MAC2STR(a) (a)[0], (a)[4], (a)[5]
+#endif
+
/** Macros for Data Alignment : size */
#define ALIGN_SZ(p, a) \
(((p) + ((a) - 1)) & ~((a) - 1))
@@ -296,26 +306,26 @@ typedef enum _mlan_error_code
MLAN_ERROR_NO_ERROR = 0,
/** Firmware/device errors below (MSB=0) */
MLAN_ERROR_FW_NOT_READY = 0x00000001,
- MLAN_ERROR_FW_BUSY,
- MLAN_ERROR_FW_CMDRESP,
- MLAN_ERROR_DATA_TX_FAIL,
- MLAN_ERROR_DATA_RX_FAIL,
+ MLAN_ERROR_FW_BUSY = 0x00000002,
+ MLAN_ERROR_FW_CMDRESP = 0x00000003,
+ MLAN_ERROR_DATA_TX_FAIL = 0x00000004,
+ MLAN_ERROR_DATA_RX_FAIL = 0x00000005,
/** Driver errors below (MSB=1) */
MLAN_ERROR_PKT_SIZE_INVALID = 0x80000001,
- MLAN_ERROR_PKT_TIMEOUT,
- MLAN_ERROR_PKT_INVALID,
- MLAN_ERROR_CMD_INVALID,
- MLAN_ERROR_CMD_TIMEOUT,
- MLAN_ERROR_CMD_DNLD_FAIL,
- MLAN_ERROR_CMD_CANCEL,
- MLAN_ERROR_CMD_RESP_FAIL,
- MLAN_ERROR_CMD_ASSOC_FAIL,
- MLAN_ERROR_CMD_SCAN_FAIL,
- MLAN_ERROR_IOCTL_INVALID,
- MLAN_ERROR_IOCTL_FAIL,
- MLAN_ERROR_EVENT_UNKNOWN,
- MLAN_ERROR_INVALID_PARAMETER,
- MLAN_ERROR_NO_MEM,
+ MLAN_ERROR_PKT_TIMEOUT = 0x80000002,
+ MLAN_ERROR_PKT_INVALID = 0x80000003,
+ MLAN_ERROR_CMD_INVALID = 0x80000004,
+ MLAN_ERROR_CMD_TIMEOUT = 0x80000005,
+ MLAN_ERROR_CMD_DNLD_FAIL = 0x80000006,
+ MLAN_ERROR_CMD_CANCEL = 0x80000007,
+ MLAN_ERROR_CMD_RESP_FAIL = 0x80000008,
+ MLAN_ERROR_CMD_ASSOC_FAIL = 0x80000009,
+ MLAN_ERROR_CMD_SCAN_FAIL = 0x8000000A,
+ MLAN_ERROR_IOCTL_INVALID = 0x8000000B,
+ MLAN_ERROR_IOCTL_FAIL = 0x8000000C,
+ MLAN_ERROR_EVENT_UNKNOWN = 0x8000000D,
+ MLAN_ERROR_INVALID_PARAMETER = 0x8000000E,
+ MLAN_ERROR_NO_MEM = 0x8000000F,
/** More to add */
} mlan_error_code;
@@ -365,56 +375,60 @@ typedef enum _mlan_event_id
{
/* Event generated by firmware (MSB=0) */
MLAN_EVENT_ID_FW_UNKNOWN = 0x00000001,
- MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED,
- MLAN_EVENT_ID_FW_ADHOC_LINK_LOST,
- MLAN_EVENT_ID_FW_DISCONNECTED,
- MLAN_EVENT_ID_FW_MIC_ERR_UNI,
- MLAN_EVENT_ID_FW_MIC_ERR_MUL,
- MLAN_EVENT_ID_FW_BCN_RSSI_LOW,
- MLAN_EVENT_ID_FW_BCN_RSSI_HIGH,
- MLAN_EVENT_ID_FW_BCN_SNR_LOW,
- MLAN_EVENT_ID_FW_BCN_SNR_HIGH,
- MLAN_EVENT_ID_FW_MAX_FAIL,
- MLAN_EVENT_ID_FW_DATA_RSSI_LOW,
- MLAN_EVENT_ID_FW_DATA_RSSI_HIGH,
- MLAN_EVENT_ID_FW_DATA_SNR_LOW,
- MLAN_EVENT_ID_FW_DATA_SNR_HIGH,
- MLAN_EVENT_ID_FW_LINK_QUALITY,
- MLAN_EVENT_ID_FW_PORT_RELEASE,
- MLAN_EVENT_ID_FW_PRE_BCN_LOST,
- MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE,
- MLAN_EVENT_ID_FW_HS_WAKEUP,
- MLAN_EVENT_ID_FW_BG_SCAN,
- MLAN_EVENT_ID_FW_WEP_ICV_ERR,
- MLAN_EVENT_ID_FW_STOP_TX,
- MLAN_EVENT_ID_FW_START_TX,
- MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN,
- MLAN_EVENT_ID_FW_RADAR_DETECTED,
- MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY,
- MLAN_EVENT_ID_FW_BW_CHANGED,
+ MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED = 0x00000002,
+ MLAN_EVENT_ID_FW_ADHOC_LINK_LOST = 0x00000003,
+ MLAN_EVENT_ID_FW_DISCONNECTED = 0x00000004,
+ MLAN_EVENT_ID_FW_MIC_ERR_UNI = 0x00000005,
+ MLAN_EVENT_ID_FW_MIC_ERR_MUL = 0x00000006,
+ MLAN_EVENT_ID_FW_BCN_RSSI_LOW = 0x00000007,
+ MLAN_EVENT_ID_FW_BCN_RSSI_HIGH = 0x00000008,
+ MLAN_EVENT_ID_FW_BCN_SNR_LOW = 0x00000009,
+ MLAN_EVENT_ID_FW_BCN_SNR_HIGH = 0x0000000A,
+ MLAN_EVENT_ID_FW_MAX_FAIL = 0x0000000B,
+ MLAN_EVENT_ID_FW_DATA_RSSI_LOW = 0x0000000C,
+ MLAN_EVENT_ID_FW_DATA_RSSI_HIGH = 0x0000000D,
+ MLAN_EVENT_ID_FW_DATA_SNR_LOW = 0x0000000E,
+ MLAN_EVENT_ID_FW_DATA_SNR_HIGH = 0x0000000F,
+ MLAN_EVENT_ID_FW_LINK_QUALITY = 0x00000010,
+ MLAN_EVENT_ID_FW_PORT_RELEASE = 0x00000011,
+ MLAN_EVENT_ID_FW_PRE_BCN_LOST = 0x00000012,
+ MLAN_EVENT_ID_FW_DEBUG_INFO = 0x00000013,
+ MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE = 0x0000001A,
+ MLAN_EVENT_ID_FW_HS_WAKEUP = 0x0000001B,
+ MLAN_EVENT_ID_FW_BG_SCAN = 0x0000001D,
+ MLAN_EVENT_ID_FW_BG_SCAN_STOPPED = 0x0000001E,
+ MLAN_EVENT_ID_FW_WEP_ICV_ERR = 0x00000020,
+ MLAN_EVENT_ID_FW_STOP_TX = 0x00000021,
+ MLAN_EVENT_ID_FW_START_TX = 0x00000022,
+ MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN = 0x00000023,
+ MLAN_EVENT_ID_FW_RADAR_DETECTED = 0x00000024,
+ MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY = 0x00000025,
+ MLAN_EVENT_ID_FW_BW_CHANGED = 0x00000026,
#ifdef WIFI_DIRECT_SUPPORT
- MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED,
+ MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED = 0x0000002B,
#endif
#ifdef UAP_SUPPORT
- MLAN_EVENT_ID_UAP_FW_BSS_START,
- MLAN_EVENT_ID_UAP_FW_BSS_ACTIVE,
- MLAN_EVENT_ID_UAP_FW_BSS_IDLE,
- MLAN_EVENT_ID_UAP_FW_STA_CONNECT,
- MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT,
+ MLAN_EVENT_ID_UAP_FW_BSS_START = 0x0000002C,
+ MLAN_EVENT_ID_UAP_FW_BSS_ACTIVE = 0x0000002D,
+ MLAN_EVENT_ID_UAP_FW_BSS_IDLE = 0x0000002E,
+ MLAN_EVENT_ID_UAP_FW_STA_CONNECT = 0x00000030,
+ MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT = 0x00000031,
#endif
/* Event generated by MLAN driver (MSB=1) */
MLAN_EVENT_ID_DRV_CONNECTED = 0x80000001,
- MLAN_EVENT_ID_DRV_DEFER_HANDLING,
- MLAN_EVENT_ID_DRV_HS_ACTIVATED,
- MLAN_EVENT_ID_DRV_HS_DEACTIVATED,
- MLAN_EVENT_ID_DRV_MGMT_FRAME,
- MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM,
- MLAN_EVENT_ID_DRV_PASSTHRU,
- MLAN_EVENT_ID_DRV_SCAN_REPORT,
- MLAN_EVENT_ID_DRV_MEAS_REPORT,
- MLAN_EVENT_ID_DRV_REPORT_STRING,
- MLAN_EVENT_ID_DRV_DBG_DUMP,
+ MLAN_EVENT_ID_DRV_DEFER_HANDLING = 0x80000002,
+ MLAN_EVENT_ID_DRV_HS_ACTIVATED = 0x80000003,
+ MLAN_EVENT_ID_DRV_HS_DEACTIVATED = 0x80000004,
+ MLAN_EVENT_ID_DRV_MGMT_FRAME = 0x80000005,
+ MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM = 0x80000006,
+ MLAN_EVENT_ID_DRV_PASSTHRU = 0x80000007,
+ MLAN_EVENT_ID_DRV_SCAN_REPORT = 0x80000009,
+ MLAN_EVENT_ID_DRV_MEAS_REPORT = 0x8000000A,
+ MLAN_EVENT_ID_DRV_ASSOC_FAILURE_REPORT = 0x8000000B,
+ MLAN_EVENT_ID_DRV_REPORT_STRING = 0x8000000F,
+ MLAN_EVENT_ID_DRV_DBG_DUMP = 0x80000012,
+ MLAN_EVENT_ID_DRV_BGSCAN_RESULT = 0x80000013,
} mlan_event_id;
/** Data Structures */
@@ -552,6 +566,8 @@ typedef struct _mlan_bss_attr
t_u32 bss_priority;
/** BSS number */
t_u32 bss_num;
+ /** The BSS is virtual */
+ t_u32 bss_virtual;
} mlan_bss_attr, *pmlan_bss_attr;
#ifdef PRAGMA_PACK
@@ -711,6 +727,7 @@ typedef struct _mlan_callbacks
mlan_status(*moal_ioctl_complete) (IN t_void * pmoal_handle,
IN pmlan_ioctl_req pioctl_req,
IN mlan_status status);
+
/** moal_alloc_mlan_buffer */
mlan_status(*moal_alloc_mlan_buffer) (IN t_void * pmoal_handle,
IN t_u32 size,
@@ -738,6 +755,11 @@ typedef struct _mlan_callbacks
IN t_u32 size, IN t_u32 flag, OUT t_u8 ** ppbuf);
/** moal_mfree */
mlan_status(*moal_mfree) (IN t_void * pmoal_handle, IN t_u8 * pbuf);
+ /** moal_vmalloc */
+ mlan_status(*moal_vmalloc) (IN t_void * pmoal_handle,
+ IN t_u32 size, OUT t_u8 ** ppbuf);
+ /** moal_vfree */
+ mlan_status(*moal_vfree) (IN t_void * pmoal_handle, IN t_u8 * pbuf);
/** moal_memset */
t_void *(*moal_memset) (IN t_void * pmoal_handle,
IN t_void * pmem, IN t_u8 byte, IN t_u32 num);
@@ -787,7 +809,7 @@ typedef struct _mlan_callbacks
IN t_void * plock);
/** moal_print */
t_void(*moal_print) (IN t_void * pmoal_handle,
- IN t_u32 level, IN t_s8 * pformat, IN ...);
+ IN t_u32 level, IN char *pformat, IN ...);
/** moal_print_netintf */
t_void(*moal_print_netintf) (IN t_void * pmoal_handle,
IN t_u32 bss_index, IN t_u32 level);
@@ -807,6 +829,14 @@ typedef struct _mlan_callbacks
/** Parameter disabled, override MLAN default setting */
#define MLAN_INIT_PARA_DISABLED 2
+/** Control bit for stream 2X2 */
+#define FEATURE_CTRL_STREAM_2X2 MBIT(6)
+/** Control bit for DFS support */
+#define FEATURE_CTRL_DFS_SUPPORT MBIT(7)
+
+/** Default feature control */
+#define FEATURE_CTRL_DEFAULT 0xffffffff
+
/** mlan_device data structure */
typedef struct _mlan_device
{
@@ -846,6 +876,8 @@ typedef struct _mlan_device
/** 802.11d configuration */
t_u32 cfg_11d;
#endif
+ /** Feature control bitmask */
+ t_u32 feature_control;
} mlan_device, *pmlan_device;
/** MLAN API function prototype */
diff --git a/drivers/net/wireless/sd8797/mlinux/mlan_ieee.h b/drivers/net/wireless/sd8797/mlinux/mlan_ieee.h
index 976f1c7013a4..c11c911466e6 100644
--- a/drivers/net/wireless/sd8797/mlinux/mlan_ieee.h
+++ b/drivers/net/wireless/sd8797/mlinux/mlan_ieee.h
@@ -155,6 +155,15 @@ typedef MLAN_PACK_START struct _IEEEtypes_Generic_t
}
MLAN_PACK_END IEEEtypes_Generic_t, *pIEEEtypes_Generic_t;
+/** TLV header */
+typedef MLAN_PACK_START struct _TLV_Generic_t
+{
+ /** Type */
+ t_u16 type;
+ /** Length */
+ t_u16 len;
+} MLAN_PACK_END TLV_Generic_t, *pTLV_Generic_t;
+
/** Capability information mask */
#define CAPINFO_MASK (~(MBIT(15) | MBIT(14) | \
MBIT(12) | MBIT(11) | MBIT(9)))
@@ -305,6 +314,8 @@ typedef t_u16 IEEEtypes_AId_t;
/** IEEEtypes_StatusCode_t */
typedef t_u16 IEEEtypes_StatusCode_t;
+/** Fixed size in assoc_resp */
+#define ASSOC_RESP_FIXED_SIZE 6
/** IEEEtypes_AssocRsp_t */
typedef MLAN_PACK_START struct _IEEEtypes_AssocRsp_t
{
@@ -329,6 +340,20 @@ typedef t_u8 WLAN_802_11_RATES[WLAN_SUPPORTED_RATES];
#define RSN_AKM_8021X 1
/** AKM: PSK */
#define RSN_AKM_PSK 2
+/** AKM: PSK SHA256 */
+#define RSN_AKM_PSK_SHA256 6
+#if defined(STA_SUPPORT)
+/** Pairwise Cipher Suite length */
+#define PAIRWISE_CIPHER_SUITE_LEN 4
+/** AKM Suite length */
+#define AKM_SUITE_LEN 4
+/** MFPC bit in RSN capability */
+#define MFPC_BIT 7
+/** MFPR bit in RSN capability */
+#define MFPR_BIT 6
+/** PMF ORing mask */
+#define PMF_MASK 0x00c0
+#endif
/** wpa_suite_t */
typedef MLAN_PACK_START struct _wpa_suite_t
@@ -800,12 +825,147 @@ typedef struct MLAN_PACK_START _BSSCo2040_t
t_u8 bss_co_2040_value;
} MLAN_PACK_END BSSCo2040_t, *pBSSCo2040_t;
+#ifdef BIG_ENDIAN_SUPPORT
+/** Extended Capabilities Data */
+typedef struct MLAN_PACK_START _ExtCap_t
+{
+ /** Extended Capabilities value */
+ t_u8 rsvdBit63:1; /* bit 63 */
+ t_u8 OperModeNtf:1; /* bit 62 */
+ t_u8 TDLSWildBandwidth:1; /* bit 61 */
+ t_u8 rsvdBit60:1; /* bit 60 */
+ t_u8 rsvdBit59:1; /* bit 59 */
+ t_u8 rsvdBit58:1; /* bit 58 */
+ t_u8 rsvdBit57:1; /* bit 57 */
+ t_u8 rsvdBit56:1; /* bit 56 */
+ t_u8 rsvdBit55:1; /* bit 55 */
+ t_u8 rsvdBit54:1; /* bit 54 */
+ t_u8 rsvdBit53:1; /* bit 53 */
+ t_u8 rsvdBit52:1; /* bit 52 */
+ t_u8 rsvdBit51:1; /* bit 51 */
+ t_u8 rsvdBit50:1; /* bit 50 */
+ t_u8 rsvdBit49:1; /* bit 49 */
+ t_u8 rsvdBit48:1; /* bit 48 */
+ t_u8 rsvdBit47:1; /* bit 47 */
+ t_u8 rsvdBit46:1; /* bit 46 */
+ t_u8 rsvdBit45:1; /* bit 45 */
+ t_u8 rsvdBit44:1; /* bit 44 */
+ t_u8 rsvdBit43:1; /* bit 43 */
+ t_u8 rsvdBit42:1; /* bit 42 */
+ t_u8 rsvdBit41:1; /* bit 41 */
+ t_u8 rsvdBit40:1; /* bit 40 */
+ t_u8 TDLSChlSwitchProhib:1; /* bit 39 */
+ t_u8 TDLSProhibited:1; /* bit 38 */
+ t_u8 TDLSSupport:1; /* bit 37 */
+ t_u8 MSGCF_Capa:1; /* bit 36 */
+ t_u8 Reserved35:1; /* bit 35 */
+ t_u8 SSPN_Interface:1; /* bit 34 */
+ t_u8 EBR:1; /* bit 33 */
+ t_u8 Qos_Map:1; /* bit 32 */
+ t_u8 Interworking:1; /* bit 31 */
+ t_u8 TDLSChannelSwitching:1; /* bit 30 */
+ t_u8 TDLSPeerPSMSupport:1; /* bit 29 */
+ t_u8 TDLSPeerUAPSDSupport:1; /* bit 28 */
+ t_u8 UTC:1; /* bit 27 */
+ t_u8 DMS:1; /* bit 26 */
+ t_u8 SSID_List:1; /* bit 25 */
+ t_u8 ChannelUsage:1; /* bit 24 */
+ t_u8 TimingMeasurement:1; /* bit 23 */
+ t_u8 MultipleBSSID:1; /* bit 22 */
+ t_u8 AC_StationCount:1; /* bit 21 */
+ t_u8 QoSTrafficCap:1; /* bit 20 */
+ t_u8 BSS_Transition:1; /* bit 19 */
+ t_u8 TIM_Broadcast:1; /* bit 18 */
+ t_u8 WNM_Sleep:1; /* bit 17 */
+ t_u8 TFS:1; /* bit 16 */
+ t_u8 GeospatialLocation:1; /* bit 15 */
+ t_u8 CivicLocation:1; /* bit 14 */
+ t_u8 CollocatedIntf:1; /* bit 13 */
+ t_u8 ProxyARPService:1; /* bit 12 */
+ t_u8 FMS:1; /* bit 11 */
+ t_u8 LocationTracking:1; /* bit 10 */
+ t_u8 MulticastDiagnostics:1; /* bit 9 */
+ t_u8 Diagnostics:1; /* bit 8 */
+ t_u8 Event:1; /* bit 7 */
+ t_u8 SPSMP_Support:1; /* bit 6 */
+ t_u8 Reserved5:1; /* bit 5 */
+ t_u8 PSMP_Capable:1; /* bit 4 */
+ t_u8 RejectUnadmFrame:1; /* bit 3 */
+ t_u8 ExtChanSwitching:1; /* bit 2 */
+ t_u8 Reserved1:1; /* bit 1 */
+ t_u8 BSS_CoexistSupport:1; /* bit 0 */
+} MLAN_PACK_END ExtCap_t, *pExtCap_t;
+#else
/** Extended Capabilities Data */
typedef struct MLAN_PACK_START _ExtCap_t
{
/** Extended Capabilities value */
- t_u8 ext_cap_value;
+ t_u8 BSS_CoexistSupport:1; /* bit 0 */
+ t_u8 Reserved1:1; /* bit 1 */
+ t_u8 ExtChanSwitching:1; /* bit 2 */
+ t_u8 RejectUnadmFrame:1; /* bit 3 */
+ t_u8 PSMP_Capable:1; /* bit 4 */
+ t_u8 Reserved5:1; /* bit 5 */
+ t_u8 SPSMP_Support:1; /* bit 6 */
+ t_u8 Event:1; /* bit 7 */
+ t_u8 Diagnostics:1; /* bit 8 */
+ t_u8 MulticastDiagnostics:1; /* bit 9 */
+ t_u8 LocationTracking:1; /* bit 10 */
+ t_u8 FMS:1; /* bit 11 */
+ t_u8 ProxyARPService:1; /* bit 12 */
+ t_u8 CollocatedIntf:1; /* bit 13 */
+ t_u8 CivicLocation:1; /* bit 14 */
+ t_u8 GeospatialLocation:1; /* bit 15 */
+ t_u8 TFS:1; /* bit 16 */
+ t_u8 WNM_Sleep:1; /* bit 17 */
+ t_u8 TIM_Broadcast:1; /* bit 18 */
+ t_u8 BSS_Transition:1; /* bit 19 */
+ t_u8 QoSTrafficCap:1; /* bit 20 */
+ t_u8 AC_StationCount:1; /* bit 21 */
+ t_u8 MultipleBSSID:1; /* bit 22 */
+ t_u8 TimingMeasurement:1; /* bit 23 */
+ t_u8 ChannelUsage:1; /* bit 24 */
+ t_u8 SSID_List:1; /* bit 25 */
+ t_u8 DMS:1; /* bit 26 */
+ t_u8 UTC:1; /* bit 27 */
+ t_u8 TDLSPeerUAPSDSupport:1; /* bit 28 */
+ t_u8 TDLSPeerPSMSupport:1; /* bit 29 */
+ t_u8 TDLSChannelSwitching:1; /* bit 30 */
+ t_u8 Interworking:1; /* bit 31 */
+ t_u8 Qos_Map:1; /* bit 32 */
+ t_u8 EBR:1; /* bit 33 */
+ t_u8 SSPN_Interface:1; /* bit 34 */
+ t_u8 Reserved35:1; /* bit 35 */
+ t_u8 MSGCF_Capa:1; /* bit 36 */
+ t_u8 TDLSSupport:1; /* bit 37 */
+ t_u8 TDLSProhibited:1; /* bit 38 */
+ t_u8 TDLSChlSwitchProhib:1; /* bit 39 */
+ t_u8 rsvdBit40:1; /* bit 40 */
+ t_u8 rsvdBit41:1; /* bit 41 */
+ t_u8 rsvdBit42:1; /* bit 42 */
+ t_u8 rsvdBit43:1; /* bit 43 */
+ t_u8 rsvdBit44:1; /* bit 44 */
+ t_u8 rsvdBit45:1; /* bit 45 */
+ t_u8 rsvdBit46:1; /* bit 46 */
+ t_u8 rsvdBit47:1; /* bit 47 */
+ t_u8 rsvdBit48:1; /* bit 48 */
+ t_u8 rsvdBit49:1; /* bit 49 */
+ t_u8 rsvdBit50:1; /* bit 50 */
+ t_u8 rsvdBit51:1; /* bit 51 */
+ t_u8 rsvdBit52:1; /* bit 52 */
+ t_u8 rsvdBit53:1; /* bit 53 */
+ t_u8 rsvdBit54:1; /* bit 54 */
+ t_u8 rsvdBit55:1; /* bit 55 */
+ t_u8 rsvdBit56:1; /* bit 56 */
+ t_u8 rsvdBit57:1; /* bit 57 */
+ t_u8 rsvdBit58:1; /* bit 58 */
+ t_u8 rsvdBit59:1; /* bit 59 */
+ t_u8 rsvdBit60:1; /* bit 60 */
+ t_u8 TDLSWildBandwidth:1; /* bit 61 */
+ t_u8 OperModeNtf:1; /* bit 62 */
+ t_u8 rsvdBit63:1; /* bit 63 */
} MLAN_PACK_END ExtCap_t, *pExtCap_t;
+#endif
/** Overlapping BSS Scan Parameters Data */
typedef struct MLAN_PACK_START _OverlapBSSScanParam_t
@@ -1149,7 +1309,7 @@ typedef MLAN_PACK_START struct
/** ssid match and RSSI exceeded */
#define BG_SCAN_SSID_RSSI_MATCH 0x0004
/** Maximum number of channels that can be sent in bg scan config */
-#define WLAN_BG_SCAN_CHAN_MAX 32
+#define WLAN_BG_SCAN_CHAN_MAX 38
/**
* Input structure to configure bs scan cmd to firmware
diff --git a/drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h b/drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h
index 7cfc344bf0d4..606d161737f9 100644
--- a/drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h
+++ b/drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h
@@ -31,196 +31,204 @@ enum _mlan_ioctl_req_id
{
/* Scan Group */
MLAN_IOCTL_SCAN = 0x00010000,
- MLAN_OID_SCAN_NORMAL,
- MLAN_OID_SCAN_SPECIFIC_SSID,
- MLAN_OID_SCAN_USER_CONFIG,
- MLAN_OID_SCAN_CONFIG,
- MLAN_OID_SCAN_GET_CURRENT_BSS,
- MLAN_OID_SCAN_CANCEL,
- MLAN_OID_SCAN_TABLE_FLUSH,
- MLAN_OID_SCAN_BGSCAN_CONFIG,
+ MLAN_OID_SCAN_NORMAL = 0x00010001,
+ MLAN_OID_SCAN_SPECIFIC_SSID = 0x00010002,
+ MLAN_OID_SCAN_USER_CONFIG = 0x00010003,
+ MLAN_OID_SCAN_CONFIG = 0x00010004,
+ MLAN_OID_SCAN_GET_CURRENT_BSS = 0x00010005,
+ MLAN_OID_SCAN_CANCEL = 0x00010006,
+ MLAN_OID_SCAN_TABLE_FLUSH = 0x0001000A,
+ MLAN_OID_SCAN_BGSCAN_CONFIG = 0x0001000B,
/* BSS Configuration Group */
MLAN_IOCTL_BSS = 0x00020000,
- MLAN_OID_BSS_START,
- MLAN_OID_BSS_STOP,
- MLAN_OID_BSS_MODE,
- MLAN_OID_BSS_CHANNEL,
- MLAN_OID_BSS_CHANNEL_LIST,
- MLAN_OID_BSS_MAC_ADDR,
- MLAN_OID_BSS_MULTICAST_LIST,
- MLAN_OID_BSS_FIND_BSS,
- MLAN_OID_IBSS_BCN_INTERVAL,
- MLAN_OID_IBSS_ATIM_WINDOW,
- MLAN_OID_IBSS_CHANNEL,
+ MLAN_OID_BSS_START = 0x00020001,
+ MLAN_OID_BSS_STOP = 0x00020002,
+ MLAN_OID_BSS_MODE = 0x00020003,
+ MLAN_OID_BSS_CHANNEL = 0x00020004,
+ MLAN_OID_BSS_CHANNEL_LIST = 0x00020005,
+ MLAN_OID_BSS_MAC_ADDR = 0x00020006,
+ MLAN_OID_BSS_MULTICAST_LIST = 0x00020007,
+ MLAN_OID_BSS_FIND_BSS = 0x00020008,
+ MLAN_OID_IBSS_BCN_INTERVAL = 0x00020009,
+ MLAN_OID_IBSS_ATIM_WINDOW = 0x0002000A,
+ MLAN_OID_IBSS_CHANNEL = 0x0002000B,
#ifdef UAP_SUPPORT
- MLAN_OID_UAP_BSS_CONFIG,
- MLAN_OID_UAP_DEAUTH_STA,
- MLAN_OID_UAP_BSS_RESET,
+ MLAN_OID_UAP_BSS_CONFIG = 0x0002000C,
+ MLAN_OID_UAP_DEAUTH_STA = 0x0002000D,
+ MLAN_OID_UAP_BSS_RESET = 0x0002000E,
#endif
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
- MLAN_OID_BSS_ROLE,
+ MLAN_OID_BSS_ROLE = 0x0002000F,
#endif
#ifdef WIFI_DIRECT_SUPPORT
- MLAN_OID_WIFI_DIRECT_MODE,
+ MLAN_OID_WIFI_DIRECT_MODE = 0x00020010,
#endif
#ifdef STA_SUPPORT
- MLAN_OID_BSS_LISTEN_INTERVAL,
+ MLAN_OID_BSS_LISTEN_INTERVAL = 0x00020011,
#endif
+ MLAN_OID_BSS_REMOVE = 0x00020014,
/* Radio Configuration Group */
MLAN_IOCTL_RADIO_CFG = 0x00030000,
- MLAN_OID_RADIO_CTRL,
- MLAN_OID_BAND_CFG,
- MLAN_OID_ANT_CFG,
+ MLAN_OID_RADIO_CTRL = 0x00030001,
+ MLAN_OID_BAND_CFG = 0x00030002,
+ MLAN_OID_ANT_CFG = 0x00030003,
#ifdef WIFI_DIRECT_SUPPORT
- MLAN_OID_REMAIN_CHAN_CFG,
+ MLAN_OID_REMAIN_CHAN_CFG = 0x00030004,
#endif
/* SNMP MIB Group */
MLAN_IOCTL_SNMP_MIB = 0x00040000,
- MLAN_OID_SNMP_MIB_RTS_THRESHOLD,
- MLAN_OID_SNMP_MIB_FRAG_THRESHOLD,
- MLAN_OID_SNMP_MIB_RETRY_COUNT,
+ MLAN_OID_SNMP_MIB_RTS_THRESHOLD = 0x00040001,
+ MLAN_OID_SNMP_MIB_FRAG_THRESHOLD = 0x00040002,
+ MLAN_OID_SNMP_MIB_RETRY_COUNT = 0x00040003,
#if defined(UAP_SUPPORT)
- MLAN_OID_SNMP_MIB_DOT11D,
- MLAN_OID_SNMP_MIB_DOT11H,
+ MLAN_OID_SNMP_MIB_DOT11D = 0x00040004,
+ MLAN_OID_SNMP_MIB_DOT11H = 0x00040005,
#endif
- MLAN_OID_SNMP_MIB_DTIM_PERIOD,
+ MLAN_OID_SNMP_MIB_DTIM_PERIOD = 0x00040006,
/* Status Information Group */
MLAN_IOCTL_GET_INFO = 0x00050000,
- MLAN_OID_GET_STATS,
- MLAN_OID_GET_SIGNAL,
- MLAN_OID_GET_FW_INFO,
- MLAN_OID_GET_VER_EXT,
- MLAN_OID_GET_BSS_INFO,
- MLAN_OID_GET_DEBUG_INFO,
+ MLAN_OID_GET_STATS = 0x00050001,
+ MLAN_OID_GET_SIGNAL = 0x00050002,
+ MLAN_OID_GET_FW_INFO = 0x00050003,
+ MLAN_OID_GET_VER_EXT = 0x00050004,
+ MLAN_OID_GET_BSS_INFO = 0x00050005,
+ MLAN_OID_GET_DEBUG_INFO = 0x00050006,
#ifdef UAP_SUPPORT
- MLAN_OID_UAP_STA_LIST,
+ MLAN_OID_UAP_STA_LIST = 0x00050007,
#endif
/* Security Configuration Group */
MLAN_IOCTL_SEC_CFG = 0x00060000,
- MLAN_OID_SEC_CFG_AUTH_MODE,
- MLAN_OID_SEC_CFG_ENCRYPT_MODE,
- MLAN_OID_SEC_CFG_WPA_ENABLED,
- MLAN_OID_SEC_CFG_ENCRYPT_KEY,
- MLAN_OID_SEC_CFG_PASSPHRASE,
- MLAN_OID_SEC_CFG_EWPA_ENABLED,
- MLAN_OID_SEC_CFG_ESUPP_MODE,
- MLAN_OID_SEC_CFG_WAPI_ENABLED,
- MLAN_OID_SEC_CFG_PORT_CTRL_ENABLED,
+ MLAN_OID_SEC_CFG_AUTH_MODE = 0x00060001,
+ MLAN_OID_SEC_CFG_ENCRYPT_MODE = 0x00060002,
+ MLAN_OID_SEC_CFG_WPA_ENABLED = 0x00060003,
+ MLAN_OID_SEC_CFG_ENCRYPT_KEY = 0x00060004,
+ MLAN_OID_SEC_CFG_PASSPHRASE = 0x00060005,
+ MLAN_OID_SEC_CFG_EWPA_ENABLED = 0x00060006,
+ MLAN_OID_SEC_CFG_ESUPP_MODE = 0x00060007,
+ MLAN_OID_SEC_CFG_WAPI_ENABLED = 0x00060009,
+ MLAN_OID_SEC_CFG_PORT_CTRL_ENABLED = 0x0006000A,
/* Rate Group */
MLAN_IOCTL_RATE = 0x00070000,
- MLAN_OID_RATE_CFG,
- MLAN_OID_GET_DATA_RATE,
- MLAN_OID_SUPPORTED_RATES,
+ MLAN_OID_RATE_CFG = 0x00070001,
+ MLAN_OID_GET_DATA_RATE = 0x00070002,
+ MLAN_OID_SUPPORTED_RATES = 0x00070003,
/* Power Configuration Group */
MLAN_IOCTL_POWER_CFG = 0x00080000,
- MLAN_OID_POWER_CFG,
- MLAN_OID_POWER_CFG_EXT,
+ MLAN_OID_POWER_CFG = 0x00080001,
+ MLAN_OID_POWER_CFG_EXT = 0x00080002,
/* Power Management Configuration Group */
MLAN_IOCTL_PM_CFG = 0x00090000,
- MLAN_OID_PM_CFG_IEEE_PS,
- MLAN_OID_PM_CFG_HS_CFG,
- MLAN_OID_PM_CFG_INACTIVITY_TO,
- MLAN_OID_PM_CFG_DEEP_SLEEP,
- MLAN_OID_PM_CFG_SLEEP_PD,
- MLAN_OID_PM_CFG_PS_CFG,
- MLAN_OID_PM_CFG_SLEEP_PARAMS,
+ MLAN_OID_PM_CFG_IEEE_PS = 0x00090001,
+ MLAN_OID_PM_CFG_HS_CFG = 0x00090002,
+ MLAN_OID_PM_CFG_INACTIVITY_TO = 0x00090003,
+ MLAN_OID_PM_CFG_DEEP_SLEEP = 0x00090004,
+ MLAN_OID_PM_CFG_SLEEP_PD = 0x00090005,
+ MLAN_OID_PM_CFG_PS_CFG = 0x00090006,
+ MLAN_OID_PM_CFG_SLEEP_PARAMS = 0x00090008,
#ifdef UAP_SUPPORT
- MLAN_OID_PM_CFG_PS_MODE,
+ MLAN_OID_PM_CFG_PS_MODE = 0x00090009,
#endif /* UAP_SUPPORT */
- MLAN_OID_PM_INFO,
- MLAN_OID_PM_HS_WAKEUP_REASON,
+ MLAN_OID_PM_INFO = 0x0009000A,
+ MLAN_OID_PM_HS_WAKEUP_REASON = 0x0009000B,
/* WMM Configuration Group */
MLAN_IOCTL_WMM_CFG = 0x000A0000,
- MLAN_OID_WMM_CFG_ENABLE,
- MLAN_OID_WMM_CFG_QOS,
- MLAN_OID_WMM_CFG_ADDTS,
- MLAN_OID_WMM_CFG_DELTS,
- MLAN_OID_WMM_CFG_QUEUE_CONFIG,
- MLAN_OID_WMM_CFG_QUEUE_STATS,
- MLAN_OID_WMM_CFG_QUEUE_STATUS,
- MLAN_OID_WMM_CFG_TS_STATUS,
+ MLAN_OID_WMM_CFG_ENABLE = 0x000A0001,
+ MLAN_OID_WMM_CFG_QOS = 0x000A0002,
+ MLAN_OID_WMM_CFG_ADDTS = 0x000A0003,
+ MLAN_OID_WMM_CFG_DELTS = 0x000A0004,
+ MLAN_OID_WMM_CFG_QUEUE_CONFIG = 0x000A0005,
+ MLAN_OID_WMM_CFG_QUEUE_STATS = 0x000A0006,
+ MLAN_OID_WMM_CFG_QUEUE_STATUS = 0x000A0007,
+ MLAN_OID_WMM_CFG_TS_STATUS = 0x000A0008,
/* WPS Configuration Group */
MLAN_IOCTL_WPS_CFG = 0x000B0000,
- MLAN_OID_WPS_CFG_SESSION,
+ MLAN_OID_WPS_CFG_SESSION = 0x000B0001,
/* 802.11n Configuration Group */
MLAN_IOCTL_11N_CFG = 0x000C0000,
- MLAN_OID_11N_CFG_TX,
- MLAN_OID_11N_HTCAP_CFG,
- MLAN_OID_11N_CFG_ADDBA_REJECT,
- MLAN_OID_11N_CFG_AGGR_PRIO_TBL,
- MLAN_OID_11N_CFG_ADDBA_PARAM,
- MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE,
- MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL,
- MLAN_OID_11N_CFG_SUPPORTED_MCS_SET,
- MLAN_OID_11N_CFG_TX_BF_CAP,
- MLAN_OID_11N_CFG_TX_BF_CFG,
- MLAN_OID_11N_CFG_STREAM_CFG,
- MLAN_OID_11N_CFG_DELBA,
- MLAN_OID_11N_CFG_REJECT_ADDBA_REQ,
+ MLAN_OID_11N_CFG_TX = 0x000C0001,
+ MLAN_OID_11N_HTCAP_CFG = 0x000C0002,
+ MLAN_OID_11N_CFG_ADDBA_REJECT = 0x000C0003,
+ MLAN_OID_11N_CFG_AGGR_PRIO_TBL = 0x000C0004,
+ MLAN_OID_11N_CFG_ADDBA_PARAM = 0x000C0005,
+ MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE = 0x000C0006,
+ MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL = 0x000C0007,
+ MLAN_OID_11N_CFG_SUPPORTED_MCS_SET = 0x000C0008,
+ MLAN_OID_11N_CFG_TX_BF_CAP = 0x000C0009,
+ MLAN_OID_11N_CFG_TX_BF_CFG = 0x000C000A,
+ MLAN_OID_11N_CFG_STREAM_CFG = 0x000C000B,
+ MLAN_OID_11N_CFG_DELBA = 0x000C000C,
+ MLAN_OID_11N_CFG_REJECT_ADDBA_REQ = 0x000C000D,
/* 802.11d Configuration Group */
MLAN_IOCTL_11D_CFG = 0x000D0000,
#ifdef STA_SUPPORT
- MLAN_OID_11D_CFG_ENABLE,
- MLAN_OID_11D_CLR_CHAN_TABLE,
+ MLAN_OID_11D_CFG_ENABLE = 0x000D0001,
+ MLAN_OID_11D_CLR_CHAN_TABLE = 0x000D0002,
#endif /* STA_SUPPORT */
- MLAN_OID_11D_DOMAIN_INFO,
+ MLAN_OID_11D_DOMAIN_INFO = 0x000D0003,
/* Register Memory Access Group */
MLAN_IOCTL_REG_MEM = 0x000E0000,
- MLAN_OID_REG_RW,
- MLAN_OID_EEPROM_RD,
- MLAN_OID_MEM_RW,
+ MLAN_OID_REG_RW = 0x000E0001,
+ MLAN_OID_EEPROM_RD = 0x000E0002,
+ MLAN_OID_MEM_RW = 0x000E0003,
/* Multi-Radio Configuration Group */
MLAN_IOCTL_MFR_CFG = 0x00100000,
/* 802.11h Configuration Group */
MLAN_IOCTL_11H_CFG = 0x00110000,
- MLAN_OID_11H_CHANNEL_CHECK,
- MLAN_OID_11H_LOCAL_POWER_CONSTRAINT,
+ MLAN_OID_11H_CHANNEL_CHECK = 0x00110001,
+ MLAN_OID_11H_LOCAL_POWER_CONSTRAINT = 0x00110002,
#if defined(DFS_TESTING_SUPPORT)
- MLAN_OID_11H_DFS_TESTING,
+ MLAN_OID_11H_DFS_TESTING = 0x00110003,
#endif
/* Miscellaneous Configuration Group */
MLAN_IOCTL_MISC_CFG = 0x00200000,
- MLAN_OID_MISC_GEN_IE,
- MLAN_OID_MISC_REGION,
- MLAN_OID_MISC_WARM_RESET,
+ MLAN_OID_MISC_GEN_IE = 0x00200001,
+ MLAN_OID_MISC_REGION = 0x00200002,
+ MLAN_OID_MISC_WARM_RESET = 0x00200003,
#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
- MLAN_OID_MISC_SDIO_MPA_CTRL,
+ MLAN_OID_MISC_SDIO_MPA_CTRL = 0x00200006,
#endif
- MLAN_OID_MISC_HOST_CMD,
- MLAN_OID_MISC_SYS_CLOCK,
- MLAN_OID_MISC_SOFT_RESET,
- MLAN_OID_MISC_WWS,
- MLAN_OID_MISC_INIT_SHUTDOWN,
- MLAN_OID_MISC_CUSTOM_IE,
- MLAN_OID_MISC_TX_DATAPAUSE,
- MLAN_OID_MISC_IP_ADDR,
- MLAN_OID_MISC_MAC_CONTROL,
- MLAN_OID_MISC_MEF_CFG,
- MLAN_OID_MISC_CFP_CODE,
- MLAN_OID_MISC_COUNTRY_CODE,
- MLAN_OID_MISC_THERMAL,
- MLAN_OID_MISC_RX_MGMT_IND,
- MLAN_OID_MISC_SUBSCRIBE_EVENT,
+ MLAN_OID_MISC_HOST_CMD = 0x00200007,
+ MLAN_OID_MISC_SYS_CLOCK = 0x00200009,
+ MLAN_OID_MISC_SOFT_RESET = 0x0020000A,
+ MLAN_OID_MISC_WWS = 0x0020000B,
+ MLAN_OID_MISC_ASSOC_RSP = 0x0020000C,
+ MLAN_OID_MISC_INIT_SHUTDOWN = 0x0020000D,
+ MLAN_OID_MISC_CUSTOM_IE = 0x0020000F,
+ MLAN_OID_MISC_TX_DATAPAUSE = 0x00200012,
+ MLAN_OID_MISC_IP_ADDR = 0x00200013,
+ MLAN_OID_MISC_MAC_CONTROL = 0x00200014,
+ MLAN_OID_MISC_MEF_CFG = 0x00200015,
+ MLAN_OID_MISC_CFP_CODE = 0x00200016,
+ MLAN_OID_MISC_COUNTRY_CODE = 0x00200017,
+ MLAN_OID_MISC_THERMAL = 0x00200018,
+ MLAN_OID_MISC_RX_MGMT_IND = 0x00200019,
+ MLAN_OID_MISC_SUBSCRIBE_EVENT = 0x0020001A,
#ifdef DEBUG_LEVEL1
- MLAN_OID_MISC_DRVDBG,
+ MLAN_OID_MISC_DRVDBG = 0x0020001B,
+#endif
+ MLAN_OID_MISC_OTP_USER_DATA = 0x0020001D,
+ MLAN_OID_MISC_TXCONTROL = 0x00200020,
+#ifdef STA_SUPPORT
+ MLAN_OID_MISC_EXT_CAP_CFG = 0x00200021,
+#endif
+#if defined(STA_SUPPORT)
+ MLAN_OID_MISC_PMFCFG = 0x00200022,
#endif
- MLAN_OID_MISC_OTP_USER_DATA,
- MLAN_OID_MISC_TXCONTROL,
};
/** Sub command size */
@@ -520,6 +528,8 @@ typedef struct _mlan_ssid_bssid
mlan_802_11_mac_addr bssid;
/** index in BSSID list, start from 1 */
t_u32 idx;
+ /** Receive signal strength in dBm */
+ t_s32 rssi;
} mlan_ssid_bssid;
#ifdef UAP_SUPPORT
@@ -610,6 +620,8 @@ typedef struct _mlan_ssid_bssid
#define KEY_MGMT_PSK 0x02
/** Key_mgmt_eap */
#define KEY_MGMT_EAP 0x01
+/** Key_mgmt_psk_sha256 */
+#define KEY_MGMT_PSK_SHA256 0x100
/** TKIP */
#define CIPHER_TKIP 0x04
@@ -978,6 +990,11 @@ enum _mlan_band_def
#define CHANNEL_BW_40MHZ_ABOVE 1
#define CHANNEL_BW_40MHZ_BELOW 3
+/** RF antenna selection */
+#define RF_ANTENNA_MASK(n) ((1<<(n))-1)
+/** RF antenna auto select */
+#define RF_ANTENNA_AUTO 0xFFFF
+
/** Type definition of mlan_ds_band_cfg for MLAN_OID_BAND_CFG */
typedef struct _mlan_ds_band_cfg
{
@@ -1110,6 +1127,10 @@ typedef struct _mlan_ds_get_stats
t_u32 tx_frame;
/** WEP ICV error count */
t_u32 wep_icv_error[4];
+ /** beacon recv count */
+ t_u32 bcn_rcv_cnt;
+ /** beacon miss count */
+ t_u32 bcn_miss_cnt;
} mlan_ds_get_stats, *pmlan_ds_get_stats;
/** Type definition of mlan_ds_uap_stats for MLAN_OID_GET_STATS */
@@ -1340,7 +1361,7 @@ typedef struct
} tx_ba_stream_tbl;
/** Debug command number */
-#define DBG_CMD_NUM 5
+#define DBG_CMD_NUM 10
/** mlan_debug_info data structure for MLAN_OID_GET_DEBUG_INFO */
typedef struct _mlan_debug_info
@@ -1393,6 +1414,8 @@ typedef struct _mlan_debug_info
t_u8 tx_lock_flag;
/** Corresponds to port_open member of mlan_private */
t_u8 port_open;
+ /** bypass pkt count */
+ t_u16 bypass_pkt_count;
/** Corresponds to scan_processing member of mlan_adapter */
t_u32 scan_processing;
/** Number of host to card command failures */
@@ -1443,7 +1466,8 @@ typedef struct _mlan_debug_info
t_u16 last_event[DBG_CMD_NUM];
/** Last event index */
t_u16 last_event_index;
-
+ /** Number of no free command node */
+ t_u16 num_no_cmd_node;
/** Corresponds to data_sent member of mlan_adapter */
t_u8 data_sent;
/** Corresponds to cmd_sent member of mlan_adapter */
@@ -1716,7 +1740,8 @@ typedef struct _mlan_ds_sec_cfg
enum _mlan_rate_type
{
MLAN_RATE_INDEX,
- MLAN_RATE_VALUE
+ MLAN_RATE_VALUE,
+ MLAN_RATE_BITMAP
};
/** Enumeration for rate format */
@@ -1734,7 +1759,7 @@ typedef struct _mlan_rate_cfg_t
{
/** Fixed rate: 0, auto rate: 1 */
t_u32 is_rate_auto;
- /** Rate type. 0: index; 1: valude */
+ /** Rate type. 0: index; 1: value; 2: bitmap */
t_u32 rate_type;
/** Rate/MCS index or rate value if fixed rate */
t_u32 rate;
@@ -1858,6 +1883,8 @@ typedef struct _mlan_ds_power_cfg
#define HOST_SLEEP_COND_MAC_EVENT MBIT(2)
/** Host sleep config condition: multicast data */
#define HOST_SLEEP_COND_MULTICAST_DATA MBIT(3)
+/** Host sleep config condition: IPV6 packet */
+#define HOST_SLEEP_COND_IPV6_PACKET MBIT(31)
/** Host sleep config conditions: Default */
#define HOST_SLEEP_DEF_COND (HOST_SLEEP_COND_BROADCAST_DATA | HOST_SLEEP_COND_UNICAST_DATA | HOST_SLEEP_COND_MAC_EVENT)
@@ -1865,6 +1892,8 @@ typedef struct _mlan_ds_power_cfg
#define HOST_SLEEP_DEF_GPIO 0xff
/** Host sleep config gap : Default */
#define HOST_SLEEP_DEF_GAP 200
+/** Host sleep config min wake holdoff */
+#define HOST_SLEEP_DEF_WAKE_HOLDOFF 0;
/** Type definition of mlan_ds_hs_cfg for MLAN_OID_PM_CFG_HS_CFG */
typedef struct _mlan_ds_hs_cfg
@@ -2807,6 +2836,18 @@ typedef struct _mlan_ds_misc_sys_clock
t_u16 sys_clk[MLAN_MAX_CLK_NUM];
} mlan_ds_misc_sys_clock;
+/** Maximum response buffer length */
+#define ASSOC_RSP_BUF_SIZE 500
+
+/** Type definition of mlan_ds_misc_assoc_rsp for MLAN_OID_MISC_ASSOC_RSP */
+typedef struct _mlan_ds_misc_assoc_rsp
+{
+ /** Associate response buffer */
+ t_u8 assoc_resp_buf[ASSOC_RSP_BUF_SIZE];
+ /** Response buffer length */
+ t_u32 assoc_resp_len;
+} mlan_ds_misc_assoc_rsp;
+
/** Enumeration for function init/shutdown */
enum _mlan_func_cmd
{
@@ -2827,6 +2868,8 @@ typedef struct _mlan_ds_misc_tx_datapause
#define IPADDR_LEN (16)
/** Max number of ip */
#define MAX_IPADDR (4)
+/** IP address type - NONE*/
+#define IPADDR_TYPE_NONE (0)
/** IP address type - IPv4*/
#define IPADDR_TYPE_IPV4 (1)
/** IP operation remove */
@@ -2887,6 +2930,10 @@ typedef struct _mlan_ds_misc_country_code
t_u8 country_code[COUNTRY_CODE_LEN];
} mlan_ds_misc_country_code;
+/** action for set */
+#define SUBSCRIBE_EVT_ACT_BITWISE_SET 0x0002
+/** action for clear */
+#define SUBSCRIBE_EVT_ACT_BITWISE_CLR 0x0003
/** BITMAP for subscribe event rssi low */
#define SUBSCRIBE_EVT_RSSI_LOW MBIT(0)
/** BITMAP for subscribe event snr low */
@@ -2917,6 +2964,8 @@ typedef struct _mlan_ds_misc_country_code
/** Type definition of mlan_ds_subscribe_evt for MLAN_OID_MISC_CFP_CODE */
typedef struct _mlan_ds_subscribe_evt
{
+ /** evt action */
+ t_u16 evt_action;
/** bitmap for subscribe event */
t_u16 evt_bitmap;
/** Absolute value of RSSI threshold value (dBm) */
@@ -2989,6 +3038,16 @@ typedef struct _mlan_ds_misc_otp_user_data
t_u8 user_data[MAX_OTP_USER_DATA_LEN];
} mlan_ds_misc_otp_user_data;
+#if defined(STA_SUPPORT)
+typedef struct _mlan_ds_misc_pmfcfg
+{
+ /** Management Frame Protection Capable */
+ t_u8 mfpc;
+ /** Management Frame Protection Required */
+ t_u8 mfpr;
+} mlan_ds_misc_pmfcfg;
+#endif
+
/** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */
typedef struct _mlan_ds_misc_cfg
{
@@ -3011,6 +3070,8 @@ typedef struct _mlan_ds_misc_cfg
mlan_ds_misc_sys_clock sys_clock;
/** WWS set/get for MLAN_OID_MISC_WWS */
t_u32 wws_cfg;
+ /** Get associate response for MLAN_OID_MISC_ASSOC_RSP */
+ mlan_ds_misc_assoc_rsp assoc_resp;
/** Function init/shutdown for MLAN_OID_MISC_INIT_SHUTDOWN */
t_u32 func_init_shutdown;
/** Custom IE for MLAN_OID_MISC_CUSTOM_IE */
@@ -3037,9 +3098,15 @@ typedef struct _mlan_ds_misc_cfg
/** Driver debug bit masks */
t_u32 drvdbg;
#endif
+#ifdef STA_SUPPORT
+ t_u8 ext_cap[8];
+#endif
mlan_ds_misc_otp_user_data otp_user_data;
/** Tx control */
t_u32 tx_control;
+#if defined(STA_SUPPORT)
+ mlan_ds_misc_pmfcfg pmfcfg;
+#endif
} param;
} mlan_ds_misc_cfg, *pmlan_ds_misc_cfg;
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c b/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c
index b3896efc5567..229e47f04ae5 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c
@@ -137,7 +137,7 @@ const u32 cfg80211_cipher_suites[] = {
WLAN_CIPHER_SUITE_AES_CMAC,
};
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
#ifdef UAP_SUPPORT
/** Network device handlers for uAP */
extern const struct net_device_ops woal_uap_netdev_ops;
@@ -171,7 +171,7 @@ woal_get_wiphy_priv(struct wiphy *wiphy)
/**
* @brief Get the private structure from net device
*
- * @param wiphy A pointer to net_device structure
+ * @param dev A pointer to net_device structure
*
* @return Pointer to moal_private
*/
@@ -182,6 +182,105 @@ woal_get_netdev_priv(struct net_device *dev)
}
/**
+ * @brief Check if any interface is active
+ *
+ * @param handle A pointer to moal_handle
+ *
+ *
+ * @return MTRUE/MFALSE;
+ */
+t_u8
+woal_is_any_interface_active(moal_handle * handle)
+{
+ int i;
+ for (i = 0; i < handle->priv_num; i++) {
+#ifdef STA_SUPPORT
+ if (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA) {
+ if (handle->priv[i]->media_connected == MTRUE)
+ return MTRUE;
+ }
+#endif
+#ifdef UAP_SUPPORT
+ if (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_UAP) {
+ if (handle->priv[i]->bss_started == MTRUE)
+ return MTRUE;
+ }
+#endif
+ }
+ return MFALSE;
+}
+
+/**
+ * @brief Get current frequency of active interface
+ *
+ * @param handle A pointer to moal_handle
+ *
+ * @return channel frequency
+ */
+int
+woal_get_active_intf_freq(moal_handle * handle)
+{
+ int i;
+ for (i = 0; i < handle->priv_num; i++) {
+#ifdef STA_SUPPORT
+ if (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA) {
+ if (handle->priv[i]->media_connected == MTRUE)
+ return ieee80211_channel_to_frequency(handle->priv[i]->channel,
+ (handle->priv[i]->
+ channel <=
+ 14 ? IEEE80211_BAND_2GHZ
+ : IEEE80211_BAND_5GHZ));
+ }
+#endif
+#ifdef UAP_SUPPORT
+ if (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_UAP) {
+ if (handle->priv[i]->bss_started == MTRUE)
+ return ieee80211_channel_to_frequency(handle->priv[i]->channel,
+ (handle->priv[i]->
+ channel <=
+ 14 ? IEEE80211_BAND_2GHZ
+ : IEEE80211_BAND_5GHZ));
+ }
+#endif
+ }
+ return 0;
+}
+
+/**
+ * @brief Convert driver band configuration to IEEE band type
+ *
+ * @param band Driver band configuration
+ *
+ * @return IEEE band type
+ */
+t_u8
+woal_band_cfg_to_ieee_band(t_u32 band)
+{
+ t_u8 ret_radio_type;
+
+ ENTER();
+
+ switch (band) {
+ case BAND_A:
+ case BAND_AN:
+ case BAND_A | BAND_AN:
+ ret_radio_type = IEEE80211_BAND_5GHZ;
+ break;
+ case BAND_B:
+ case BAND_G:
+ case BAND_B | BAND_G:
+ case BAND_GN:
+ case BAND_B | BAND_GN:
+ default:
+ ret_radio_type = IEEE80211_BAND_2GHZ;
+ break;
+ }
+
+ LEAVE();
+ return ret_radio_type;
+}
+
+/**
* @brief Set/Enable encryption key
*
* @param priv A pointer to moal_private structure
@@ -269,25 +368,22 @@ woal_cfg80211_set_key(moal_private * priv, t_u8 is_enable_wep,
seq_len);
}
}
- if (cipher != WLAN_CIPHER_SUITE_WEP40 &&
- cipher != WLAN_CIPHER_SUITE_WEP104) {
- if (addr) {
- memcpy(sec->param.encrypt_key.mac_addr, addr, ETH_ALEN);
- if (0 ==
- memcmp(sec->param.encrypt_key.mac_addr, bcast_addr,
- ETH_ALEN))
- sec->param.encrypt_key.key_flags = KEY_FLAG_GROUP_KEY;
- else
- sec->param.encrypt_key.key_flags = KEY_FLAG_SET_TX_KEY;
- } else {
- memcpy(sec->param.encrypt_key.mac_addr, bcast_addr, ETH_ALEN);
+ if (addr) {
+ memcpy(sec->param.encrypt_key.mac_addr, addr, ETH_ALEN);
+ if (0 ==
+ memcmp(sec->param.encrypt_key.mac_addr, bcast_addr, ETH_ALEN))
sec->param.encrypt_key.key_flags = KEY_FLAG_GROUP_KEY;
- }
- if (seq && seq_len) {
- memcpy(sec->param.encrypt_key.pn, seq, seq_len);
- sec->param.encrypt_key.key_flags |= KEY_FLAG_RX_SEQ_VALID;
- }
+ else
+ sec->param.encrypt_key.key_flags = KEY_FLAG_SET_TX_KEY;
+ } else {
+ memcpy(sec->param.encrypt_key.mac_addr, bcast_addr, ETH_ALEN);
+ sec->param.encrypt_key.key_flags = KEY_FLAG_GROUP_KEY;
}
+ if (seq && seq_len) {
+ memcpy(sec->param.encrypt_key.pn, seq, seq_len);
+ sec->param.encrypt_key.key_flags |= KEY_FLAG_RX_SEQ_VALID;
+ }
+
if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
sec->param.encrypt_key.key_flags |= KEY_FLAG_AES_MCAST_IGTK;
}
@@ -354,8 +450,41 @@ woal_cfg80211_set_wep_keys(moal_private * priv, const t_u8 * key, int key_len,
return ret;
}
-#if defined(WIFI_DIRECT_SUPPORT)
-#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+/**
+ * @brief clear all mgmt ies
+ *
+ * @param priv A pointer to moal private structure
+ * @return N/A
+ */
+void
+woal_clear_all_mgmt_ies(moal_private * priv)
+{
+ t_u16 mask = 0;
+ /* clear BEACON WPS/P2P IE */
+ if (priv->beacon_wps_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK) {
+ PRINTM(MCMND, "Clear BEACON WPS ie\n");
+ woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, NULL, 0, NULL, 0,
+ MGMT_MASK_BEACON_WPS_P2P);
+ }
+ /* clear mgmt frame ies */
+ if (priv->probereq_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)
+ mask |= MGMT_MASK_PROBE_REQ;
+ if (priv->beacon_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)
+ mask |= MGMT_MASK_BEACON;
+ if (priv->proberesp_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)
+ mask |= MGMT_MASK_PROBE_RESP;
+ if (priv->assocresp_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)
+ mask |= MGMT_MASK_ASSOC_RESP;
+ if (mask) {
+ PRINTM(MCMND, "Clear IES: 0x%x 0x%x 0x%x 0x%x\n", priv->beacon_index,
+ priv->probereq_index, priv->proberesp_index,
+ priv->assocresp_index);
+ woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, NULL, 0, NULL, 0,
+ mask);
+ }
+}
+
+#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
/**
* @brief set bss role
*
@@ -365,7 +494,7 @@ woal_cfg80211_set_wep_keys(moal_private * priv, const t_u8 * key, int key_len,
*
* @return 0 -- success, otherwise fail
*/
-static int
+int
woal_cfg80211_bss_role_cfg(moal_private * priv, t_u16 action, t_u8 * bss_role)
{
int ret = 0;
@@ -384,6 +513,10 @@ woal_cfg80211_bss_role_cfg(moal_private * priv, t_u16 action, t_u8 * bss_role)
}
if (action == MLAN_ACT_SET) {
+ /* set back the mac address */
+ woal_request_set_mac_address(priv);
+ /* clear the mgmt ies */
+ woal_clear_all_mgmt_ies(priv);
/* Initialize private structures */
woal_init_priv(priv, MOAL_IOCTL_WAIT);
@@ -396,6 +529,10 @@ woal_cfg80211_bss_role_cfg(moal_private * priv, t_u16 action, t_u8 * bss_role)
LEAVE();
return ret;
}
+#endif
+
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
/**
* @brief initialize p2p client for wpa_supplicant
@@ -544,6 +681,7 @@ woal_cfg80211_deinit_p2p(moal_private * priv)
t_u16 wifi_direct_mode;
t_u8 bss_role;
t_u8 channel_status;
+ moal_private *remain_priv = NULL;
ENTER();
@@ -556,18 +694,33 @@ woal_cfg80211_deinit_p2p(moal_private * priv)
/* cancel previous remain on channel */
if (priv->phandle->remain_on_channel) {
+ remain_priv = priv->phandle->priv[priv->phandle->remain_bss_index];
+ if (!remain_priv) {
+ PRINTM(MERROR, "deinit_p2p: wrong remain_bss_index=%d\n",
+ priv->phandle->remain_bss_index);
+ ret = -EFAULT;
+ goto done;
+ }
if (woal_cfg80211_remain_on_channel_cfg
- (priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0, 0)) {
- PRINTM(MERROR, "Fail to cancel remain on channel\n");
+ (remain_priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0,
+ 0)) {
+ PRINTM(MERROR, "deinit_p2p: Fail to cancel remain on channel\n");
ret = -EFAULT;
goto done;
}
if (priv->phandle->cookie) {
- cfg80211_remain_on_channel_expired(priv->netdev,
- priv->phandle->cookie,
- &priv->phandle->chan,
- priv->phandle->channel_type,
- GFP_ATOMIC);
+ cfg80211_remain_on_channel_expired(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+ remain_priv->netdev,
+#else
+ remain_priv->wdev,
+#endif
+ priv->phandle->cookie,
+ &priv->phandle->chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ priv->phandle->channel_type,
+#endif
+ GFP_ATOMIC);
priv->phandle->cookie = 0;
}
priv->phandle->remain_on_channel = MFALSE;
@@ -625,7 +778,9 @@ woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
mlan_ds_bss *bss = NULL;
mlan_ioctl_req *req = NULL;
+#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
t_u8 bss_role;
+#endif
ENTER();
@@ -633,24 +788,41 @@ woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
PRINTM(MINFO, "Already set to required type\n");
goto done;
}
- PRINTM(MIOCTL, "change virturl intf=%d\n", type);
+ PRINTM(MIOCTL, "%s: change virturl intf=%d\n", dev->name, type);
#if defined(WIFI_DIRECT_SUPPORT)
#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
/** cancel previous remain on channel to avoid firmware hang */
if (priv->phandle->remain_on_channel) {
t_u8 channel_status;
+ moal_private *remain_priv = NULL;
+ remain_priv = priv->phandle->priv[priv->phandle->remain_bss_index];
+ if (!remain_priv) {
+ PRINTM(MERROR, "change_virtual_intf:wrong remain_bss_index=%d\n",
+ priv->phandle->remain_bss_index);
+ ret = -EFAULT;
+ goto done;
+ }
if (woal_cfg80211_remain_on_channel_cfg
- (priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0, 0)) {
- PRINTM(MERROR, "Fail to cancel remain on channel\n");
+ (remain_priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0,
+ 0)) {
+ PRINTM(MERROR,
+ "change_virtual_intf: Fail to cancel remain on channel\n");
ret = -EFAULT;
goto done;
}
if (priv->phandle->cookie) {
- cfg80211_remain_on_channel_expired(priv->netdev,
- priv->phandle->cookie,
- &priv->phandle->chan,
- priv->phandle->channel_type,
- GFP_ATOMIC);
+ cfg80211_remain_on_channel_expired(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+ remain_priv->netdev,
+#else
+ remain_priv->wdev,
+#endif
+ priv->phandle->cookie,
+ &priv->phandle->chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ priv->phandle->channel_type,
+#endif
+ GFP_ATOMIC);
priv->phandle->cookie = 0;
}
priv->phandle->remain_on_channel = MFALSE;
@@ -699,11 +871,14 @@ woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
}
#endif /* KERNEL_VERSION */
#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
+ woal_cfg80211_del_beacon(wiphy, dev);
bss_role = MLAN_BSS_ROLE_STA;
woal_cfg80211_bss_role_cfg(priv, MLAN_ACT_SET, &bss_role);
PRINTM(MIOCTL, "set bss role for STA\n");
}
+#endif
bss->param.bss_mode = MLAN_BSS_MODE_INFRA;
priv->wdev->iftype = NL80211_IFTYPE_STATION;
PRINTM(MINFO, "Setting interface type to managed\n");
@@ -744,11 +919,16 @@ woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
priv->wdev->iftype = NL80211_IFTYPE_P2P_GO;
#endif
#endif
+#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
if (priv->bss_type == MLAN_BSS_TYPE_STA) {
+ if (priv->probereq_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)
+ woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, NULL, 0,
+ NULL, 0, MGMT_MASK_PROBE_REQ);
bss_role = MLAN_BSS_ROLE_UAP;
woal_cfg80211_bss_role_cfg(priv, MLAN_ACT_SET, &bss_role);
PRINTM(MIOCTL, "set bss role for AP\n");
}
+#endif
if (type == NL80211_IFTYPE_AP)
priv->wdev->iftype = NL80211_IFTYPE_AP;
PRINTM(MINFO, "Setting interface type to P2P GO\n");
@@ -794,7 +974,8 @@ woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
int
woal_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
- moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy);
+ moal_private *priv = NULL;
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
#ifdef UAP_CFG80211
#ifdef UAP_SUPPORT
mlan_uap_bss_param sys_cfg;
@@ -806,6 +987,7 @@ woal_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
ENTER();
+ priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
if (rts_thr == MLAN_FRAG_RTS_DISABLED)
rts_thr = MLAN_RTS_MAX_VALUE;
if (frag_thr == MLAN_FRAG_RTS_DISABLED)
@@ -861,6 +1043,7 @@ woal_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
return -EFAULT;
}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) || defined(COMPAT_WIRELESS)
/**
* @brief Request the driver to add a key
*
@@ -873,6 +1056,19 @@ woal_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
*
* @return 0 -- success, otherwise fail
*/
+#else
+/**
+ * @brief Request the driver to add a key
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param netdev A pointer to net_device structure
+ * @param key_index Key index
+ * @param mac_addr MAC address (NULL for group key)
+ * @param params A pointer to key_params structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+#endif
int
woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
t_u8 key_index,
@@ -899,6 +1095,7 @@ woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
return 0;
}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) || defined(COMPAT_WIRELESS)
/**
* @brief Request the driver to delete a key
*
@@ -910,6 +1107,18 @@ woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
*
* @return 0 -- success, otherwise fail
*/
+#else
+/**
+ * @brief Request the driver to delete a key
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param netdev A pointer to net_device structure
+ * @param key_index Key index
+ * @param mac_addr MAC address (NULL for group key)
+ *
+ * @return 0 -- success, otherwise fail
+ */
+#endif
int
woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
t_u8 key_index,
@@ -934,6 +1143,7 @@ woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
return 0;
}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
/**
* @brief Request to enable WEP key to driver
*
@@ -945,6 +1155,17 @@ woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
*
* @return 0 -- success, otherwise fail
*/
+#else
+/**
+ * @brief Request to enable WEP key to driver
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param netdev A pointer to net_device structure
+ * @param key_index Key index
+ *
+ * @return 0 -- success, otherwise fail
+ */
+#endif
int
woal_cfg80211_set_default_key(struct wiphy *wiphy,
struct net_device *netdev, t_u8 key_index
@@ -960,7 +1181,7 @@ woal_cfg80211_set_default_key(struct wiphy *wiphy,
ENTER();
woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
- if (bss_info.wep_status) {
+ if (!bss_info.wep_status) {
LEAVE();
return ret;
}
@@ -974,6 +1195,19 @@ woal_cfg80211_set_default_key(struct wiphy *wiphy,
return ret;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) || defined(COMPAT_WIRELESS)
+/**
+ * @brief Request the driver to change the channel
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param dev A pointer to net_device structure
+ * @param chan A pointer to ieee80211_channel structure
+ * @param channel_type Channel type of nl80211_channel_type
+ *
+ * @return 0 -- success, otherwise fail
+ */
+#else
/**
* @brief Request the driver to change the channel
*
@@ -983,6 +1217,7 @@ woal_cfg80211_set_default_key(struct wiphy *wiphy,
*
* @return 0 -- success, otherwise fail
*/
+#endif
int
woal_cfg80211_set_channel(struct wiphy *wiphy,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) || defined(COMPAT_WIRELESS)
@@ -995,30 +1230,179 @@ woal_cfg80211_set_channel(struct wiphy *wiphy,
moal_private *priv = NULL;
ENTER();
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) || defined(COMPAT_WIRELESS)
if (dev)
priv = woal_get_netdev_priv(dev);
- else
#endif
- priv = (moal_private *) woal_get_wiphy_priv(wiphy);
+#endif
+ if (!priv) {
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
+ if (handle)
+ priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
+ }
+ if (priv) {
#ifdef STA_CFG80211
#ifdef STA_SUPPORT
- if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) {
- if (priv->media_connected == MTRUE) {
- PRINTM(MERROR, "This configuration is valid only when station "
- "is not connected\n");
- LEAVE();
- return -EINVAL;
+ if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) {
+ if (priv->media_connected == MTRUE) {
+ PRINTM(MERROR, "This configuration is valid only when station "
+ "is not connected\n");
+ LEAVE();
+ return -EINVAL;
+ }
+ ret = woal_set_rf_channel(priv, chan, channel_type);
}
- ret = woal_set_rf_channel(priv, chan, channel_type);
+#endif
+#endif
+ priv->channel = ieee80211_frequency_to_channel(chan->center_freq);
}
+ // set monitor channel support
+
+ LEAVE();
+ return ret;
+}
#endif
+
+/**
+ * @brief Request the driver to set the bitrate
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param dev A pointer to net_device structure
+ * @param peer A pointer to peer address
+ * @param mask A pointer to cfg80211_bitrate_mask structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
+ struct net_device *dev,
+ const u8 * peer,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ int ret = 0;
+ mlan_status status = MLAN_STATUS_SUCCESS;
+ moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
+ mlan_bss_info bss_info;
+ enum ieee80211_band band;
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_rate *rate = NULL;
+ mlan_rate_cfg_t *rate_cfg = NULL;
+
+ ENTER();
+
+ if (priv->media_connected == MFALSE) {
+ PRINTM(MERROR, "Can not set data rate in disconnected state\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ status = woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+ if (status)
+ goto done;
+ band = woal_band_cfg_to_ieee_band(bss_info.bss_band);
+
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ rate = (mlan_ds_rate *) req->pbuf;
+ rate_cfg = &rate->param.rate_cfg;
+ rate->sub_command = MLAN_OID_RATE_CFG;
+ req->req_id = MLAN_IOCTL_RATE;
+ req->action = MLAN_ACT_SET;
+ rate_cfg->rate_type = MLAN_RATE_BITMAP;
+
+ /* Fill HR/DSSS rates. */
+ if (band == IEEE80211_BAND_2GHZ)
+ rate_cfg->bitmap_rates[0] = mask->control[band].legacy & 0x000f;
+
+ /* Fill OFDM rates */
+ if (band == IEEE80211_BAND_2GHZ)
+ rate_cfg->bitmap_rates[1] = (mask->control[band].legacy & 0x0ff0) >> 4;
+ else
+ rate_cfg->bitmap_rates[1] = mask->control[band].legacy;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ /* Fill MCS rates */
+ rate_cfg->bitmap_rates[2] = mask->control[band].mcs[0];
+ if (priv->phandle->card_type == CARD_TYPE_SD8797)
+ rate_cfg->bitmap_rates[2] |= mask->control[band].mcs[1] << 8;
#endif
- priv->channel = ieee80211_frequency_to_channel(chan->center_freq);
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ done:
LEAVE();
return ret;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) || defined(COMPAT_WIRELESS)
+/**
+ * @brief Request the driver to set antenna configuration
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param tx_ant Bitmaps of allowed antennas to use for TX
+ * @param rx_ant Bitmaps of allowed antennas to use for RX
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
+{
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
+ moal_private *priv = NULL;
+ mlan_ds_radio_cfg *radio = NULL;
+ mlan_ioctl_req *req = NULL;
+ int ret = 0;
+
+ ENTER();
+
+ if (!handle) {
+ PRINTM(MFATAL, "Unable to get handle\n");
+ ret = -EINVAL;
+ goto done;
+ }
+ priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
+ if (!priv) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ radio = (mlan_ds_radio_cfg *) req->pbuf;
+ radio->sub_command = MLAN_OID_ANT_CFG;
+ req->req_id = MLAN_IOCTL_RADIO_CFG;
+ req->action = MLAN_ACT_SET;
+ radio->param.ant_cfg.tx_antenna = tx_ant;
+ radio->param.ant_cfg.rx_antenna = rx_ant;
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ done:
+ if (req)
+ kfree(req);
+ /* Driver must return -EINVAL to cfg80211 */
+ if (ret)
+ ret = -EINVAL;
+ LEAVE();
+ return ret;
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
/**
* @brief register/unregister mgmt frame forwarding
*
@@ -1033,11 +1417,30 @@ void
woal_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
struct net_device *dev, u16 frame_type,
bool reg)
+#else
+/**
+ * @brief register/unregister mgmt frame forwarding
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param wdev A pointer to wireless_dev structure
+ * @param frame_type Bit mask for mgmt frame type
+ * @param reg Register or unregister
+ *
+ * @return 0 -- success, otherwise fail
+ */
+void
+woal_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
+ struct wireless_dev *wdev, u16 frame_type,
+ bool reg)
+#endif
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct net_device *dev = wdev->netdev;
+#endif
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
mlan_status status = MLAN_STATUS_SUCCESS;
t_u32 mgmt_subtype_mask = 0x0;
- static t_u32 last_mgmt_subtype_mask = 0x0;
+ t_u32 last_mgmt_subtype_mask = priv->mgmt_subtype_mask;
ENTER();
#ifdef UAP_SUPPORT
@@ -1055,8 +1458,8 @@ woal_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
/* clear mgmt_subtype_mask */
mgmt_subtype_mask = last_mgmt_subtype_mask & ~BIT(frame_type >> 4);
}
- PRINTM(MIOCTL, "mgmt_subtype_mask=0x%x last_mgmt_subtype_mask=0x%x\n",
- mgmt_subtype_mask, last_mgmt_subtype_mask);
+ PRINTM(MIOCTL, "%s: mgmt_subtype_mask=0x%x last_mgmt_subtype_mask=0x%x\n",
+ dev->name, mgmt_subtype_mask, last_mgmt_subtype_mask);
if (mgmt_subtype_mask != last_mgmt_subtype_mask) {
last_mgmt_subtype_mask = mgmt_subtype_mask;
@@ -1065,11 +1468,53 @@ woal_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
itself. */
status = woal_reg_rx_mgmt_ind(priv, MLAN_ACT_SET,
&mgmt_subtype_mask, MOAL_NO_WAIT);
+ priv->mgmt_subtype_mask = last_mgmt_subtype_mask;
}
LEAVE();
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
+/**
+ * @brief tx mgmt frame
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param wdev A pointer to wireless_dev structure
+ * @param chan A pointer to ieee80211_channel structure
+ * @param offchan Off channel or not
+ * @param wait Duration to wait
+ * @param buf Frame buffer
+ * @param len Frame length
+ * @param no_cck No CCK check
+ * @param dont_wait_for_ack Do not wait for ACK
+ * @param cookie A pointer to frame cookie
+ *
+ * @return 0 -- success, otherwise fail
+ */
+#else
+/**
+ * @brief tx mgmt frame
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param wdev A pointer to wireless_dev structure
+ * @param chan A pointer to ieee80211_channel structure
+ * @param offchan Off channel or not
+ * @param channel_type Channel type
+ * @param channel_type_valid Is channel type valid or not
+ * @param wait Duration to wait
+ * @param buf Frame buffer
+ * @param len Frame length
+ * @param no_cck No CCK check
+ * @param dont_wait_for_ack Do not wait for ACK
+ * @param cookie A pointer to frame cookie
+ *
+ * @return 0 -- success, otherwise fail
+ */
+#endif
+#else
/**
* @brief tx mgmt frame
*
@@ -1079,19 +1524,66 @@ woal_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
* @param offchan Off channel or not
* @param channel_type Channel type
* @param channel_type_valid Is channel type valid or not
+ * @param wait Duration to wait
* @param buf Frame buffer
* @param len Frame length
+ * @param no_cck No CCK check
+ * @param dont_wait_for_ack Do not wait for ACK
* @param cookie A pointer to frame cookie
*
* @return 0 -- success, otherwise fail
*/
+#endif
+#else
+/**
+ * @brief tx mgmt frame
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param dev A pointer to net_device structure
+ * @param chan A pointer to ieee80211_channel structure
+ * @param offchan Off channel or not
+ * @param channel_type Channel type
+ * @param channel_type_valid Is channel type valid or not
+ * @param wait Duration to wait
+ * @param buf Frame buffer
+ * @param len Frame length
+ * @param no_cck No CCK check
+ * @param cookie A pointer to frame cookie
+ *
+ * @return 0 -- success, otherwise fail
+ */
+#endif
+#else
+/**
+ * @brief tx mgmt frame
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param dev A pointer to net_device structure
+ * @param chan A pointer to ieee80211_channel structure
+ * @param offchan Off channel or not
+ * @param channel_type Channel type
+ * @param channel_type_valid Is channel type valid or not
+ * @param wait Duration to wait
+ * @param buf Frame buffer
+ * @param len Frame length
+ * @param cookie A pointer to frame cookie
+ *
+ * @return 0 -- success, otherwise fail
+ */
+#endif
int
woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
struct net_device *dev,
+#else
+ struct wireless_dev *wdev,
+#endif
struct ieee80211_channel *chan, bool offchan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
enum nl80211_channel_type channel_type,
- bool channel_type_valid, unsigned int wait,
- const u8 * buf, size_t len,
+ bool channel_type_valid,
+#endif
+ unsigned int wait, const u8 * buf, size_t len,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
bool no_cck,
#endif
@@ -1100,6 +1592,9 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
#endif
u64 * cookie)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct net_device *dev = wdev->netdev;
+#endif
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
int ret = 0;
pmlan_buffer pmbuf = NULL;
@@ -1113,6 +1608,7 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
t_u8 channel_status;
t_u32 duration;
+ moal_private *remain_priv = NULL;
#endif
#endif
@@ -1130,7 +1626,8 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
PD/GO negotiation, so we should call remain_on_channel_cfg in order to
receive action frame from peer device */
framectrl = ((const struct ieee80211_mgmt *) buf)->frame_control;
- PRINTM(MIOCTL, "Mgmt: framectrl=0x%x\n", framectrl);
+ PRINTM(MIOCTL, "Mgmt TX %s => framectrl = 0x%x freq = %d\n", dev->name,
+ framectrl, chan->center_freq);
if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) &&
(framectrl == IEEE80211_STYPE_PROBE_RESP)) {
PRINTM(MIOCTL, "Skip send probe_resp in GO/UAP mode\n");
@@ -1140,21 +1637,41 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
if ((priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) &&
(framectrl == IEEE80211_STYPE_ACTION)) {
-#define MGMT_TX_DEFAULT_WAIT_TIME 2000
+ if (priv->phandle->is_go_timer_set) {
+ woal_cancel_timer(&priv->phandle->go_timer);
+ priv->phandle->is_go_timer_set = MFALSE;
+ }
+#define MGMT_TX_DEFAULT_WAIT_TIME 1000
/** cancel previous remain on channel */
if (priv->phandle->remain_on_channel) {
+ remain_priv = priv->phandle->priv[priv->phandle->remain_bss_index];
+ if (!remain_priv) {
+ PRINTM(MERROR, "mgmt_tx:Wrong remain_bss_index=%d\n",
+ priv->phandle->remain_bss_index);
+ ret = -EFAULT;
+ goto done;
+ }
if (woal_cfg80211_remain_on_channel_cfg
- (priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0, 0)) {
- PRINTM(MERROR, "Fail to cancel remain on channel\n");
+ (remain_priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0,
+ 0)) {
+ PRINTM(MERROR, "mgmt_tx:Fail to cancel remain on channel\n");
ret = -EFAULT;
goto done;
}
if (priv->phandle->cookie) {
- cfg80211_remain_on_channel_expired(priv->netdev,
- priv->phandle->cookie,
- &priv->phandle->chan,
- priv->phandle->channel_type,
- GFP_ATOMIC);
+ cfg80211_remain_on_channel_expired(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+ remain_priv->netdev,
+#else
+ remain_priv->wdev,
+#endif
+ priv->phandle->cookie,
+ &priv->phandle->chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ priv->phandle->
+ channel_type,
+#endif
+ GFP_ATOMIC);
priv->phandle->cookie = 0;
}
priv->phandle->remain_on_channel = MFALSE;
@@ -1166,6 +1683,7 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
duration = wait;
if (!wait)
duration = MGMT_TX_DEFAULT_WAIT_TIME;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
if (channel_type_valid)
ret =
woal_cfg80211_remain_on_channel_cfg(priv, MOAL_IOCTL_WAIT,
@@ -1173,6 +1691,7 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
chan, channel_type,
duration);
else
+#endif
ret =
woal_cfg80211_remain_on_channel_cfg(priv, MOAL_IOCTL_WAIT,
MFALSE, &channel_status,
@@ -1183,9 +1702,12 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
goto done;
}
priv->phandle->remain_on_channel = MTRUE;
+ priv->phandle->remain_bss_index = priv->bss_index;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
priv->phandle->channel_type = channel_type;
+#endif
memcpy(&priv->phandle->chan, chan, sizeof(struct ieee80211_channel));
- PRINTM(MIOCTL, "Mgmt Tx: Set remain channel=%d\n",
+ PRINTM(MIOCTL, "%s: Mgmt Tx: Set remain channel=%d\n", dev->name,
ieee80211_frequency_to_channel(chan->center_freq));
}
#endif
@@ -1233,15 +1755,27 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
atomic_inc(&priv->phandle->tx_pending);
queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
- /* delay 20ms to guarantee the packet has been already tx'ed becuase if
- we call cfg80211_mgmt_tx_status() immediately, then wpa_supplicant
- will call cancel_remain_on_channel(), which may affect the mgmt
- frame tx */
- mdelay(20);
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ /* Delay 30ms to guarantee the packet has been already tx'ed, becuase
+ if we call cfg80211_mgmt_tx_status() immediately, then
+ wpa_supplicant will call cancel_remain_on_channel(), which may
+ affect the mgmt frame tx. Meanwhile it is only necessary for P2P
+ action handshake to wait 30ms. */
+ if ((priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) &&
+ (framectrl == IEEE80211_STYPE_ACTION))
+ woal_sched_timeout(30);
+#endif
+#endif
/* Notify the mgmt tx status */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_ATOMIC);
+#else
+ cfg80211_mgmt_tx_status(priv->wdev, *cookie, buf, len, true,
+ GFP_ATOMIC);
+#endif
#endif
break;
case MLAN_STATUS_SUCCESS:
@@ -1287,29 +1821,6 @@ woal_parse_ie_tlv(const t_u8 * ie, int len, t_u8 id)
return NULL;
}
-/**
- * @brief This function returns priv
- * based on mgmt ie index
- *
- * @param handle A pointer to moal_handle
- * @param index mgmt ie index
- *
- * @return Pointer to moal_private
- */
-static moal_private *
-woal_get_priv_by_mgmt_index(moal_handle * handle, t_u16 index)
-{
- int i;
-
- for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) {
- if (handle->priv[i]) {
- if (handle->priv[i]->probereq_index == index)
- return (handle->priv[i]);
- }
- }
- return NULL;
-}
-
/**
* @brief Add custom ie to mgmt frames.
*
@@ -1380,7 +1891,6 @@ woal_cfg80211_custom_ie(moal_private * priv,
pos += len;
custom_ie->len += len;
}
-
ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (ioctl_req == NULL) {
ret = -ENOMEM;
@@ -1450,6 +1960,48 @@ woal_cfg80211_custom_ie(moal_private * priv,
}
/**
+ * @brief Find first P2P ie
+ *
+ * @param ie Pointer to IEs
+ * @param len Total length of ie
+ * @param ie_out Pointer to out IE buf
+ *
+ * @return out IE length
+ */
+static t_u16
+woal_get_first_p2p_ie(const t_u8 * ie, int len, t_u8 * ie_out)
+{
+ int left_len = len;
+ const t_u8 *pos = ie;
+ int length;
+ t_u8 id = 0;
+ t_u16 out_len = 0;
+ IEEEtypes_VendorSpecific_t *pVendorIe = NULL;
+ const u8 p2p_oui[4] = { 0x50, 0x6f, 0x9a, 0x09 };
+
+ while (left_len >= 2) {
+ length = *(pos + 1);
+ id = *pos;
+ if ((length + 2) > left_len)
+ break;
+ if (id == VENDOR_SPECIFIC_221) {
+ pVendorIe = (IEEEtypes_VendorSpecific_t *) pos;
+ if (!memcmp
+ (pVendorIe->vend_hdr.oui, p2p_oui,
+ sizeof(pVendorIe->vend_hdr.oui)) &&
+ pVendorIe->vend_hdr.oui_type == p2p_oui[3]) {
+ memcpy(ie_out + out_len, pos, length + 2);
+ out_len += length + 2;
+ break;
+ }
+ }
+ pos += (length + 2);
+ left_len -= (length + 2);
+ }
+ return out_len;
+}
+
+/**
* @brief Filter specific IE in ie buf
*
* @param ie Pointer to IEs
@@ -1460,7 +2012,7 @@ woal_cfg80211_custom_ie(moal_private * priv,
* @return out IE length
*/
static t_u16
-woal_filter_beacon_ies(const t_u8 * ie, int len, t_u8 * ie_out, t_u8 wps_flag)
+woal_filter_beacon_ies(const t_u8 * ie, int len, t_u8 * ie_out, t_u16 wps_flag)
{
int left_len = len;
const t_u8 *pos = ie;
@@ -1472,6 +2024,7 @@ woal_filter_beacon_ies(const t_u8 * ie, int len, t_u8 * ie_out, t_u8 wps_flag)
const u8 p2p_oui[4] = { 0x50, 0x6f, 0x9a, 0x09 };
const u8 wfd_oui[4] = { 0x50, 0x6f, 0x9a, 0x0a };
const t_u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
+ t_u8 find_p2p_ie = MFALSE;
/* ERP_INFO/EXTENDED_SUPPORT_RATES/HT_CAPABILITY/HT_OPERATION/WMM and
WPS/P2P/WFD IE will be fileter out */
@@ -1489,21 +2042,37 @@ woal_filter_beacon_ies(const t_u8 * ie, int len, t_u8 * ie_out, t_u8 wps_flag)
case VENDOR_SPECIFIC_221:
/* filter out wmm ie */
pVendorIe = (IEEEtypes_VendorSpecific_t *) pos;
- if (!memcmp(pVendorIe->vend_hdr.oui, wmm_oui, sizeof(wmm_oui)))
+ if (!memcmp
+ (pVendorIe->vend_hdr.oui, wmm_oui,
+ sizeof(pVendorIe->vend_hdr.oui)) &&
+ pVendorIe->vend_hdr.oui_type == wmm_oui[3])
+ break;
+ /* filter out wps ie */
+ if ((!memcmp
+ (pVendorIe->vend_hdr.oui, wps_oui,
+ sizeof(pVendorIe->vend_hdr.oui)) &&
+ pVendorIe->vend_hdr.oui_type == wps_oui[3]) &&
+ (wps_flag & IE_MASK_WPS))
break;
- if (wps_flag) {
- /* filter out wps/p2p ie */
- pVendorIe = (IEEEtypes_VendorSpecific_t *) pos;
- if (memcmp(pVendorIe->vend_hdr.oui, wps_oui, sizeof(wps_oui)) &&
- memcmp(pVendorIe->vend_hdr.oui, p2p_oui, sizeof(p2p_oui)) &&
- memcmp(pVendorIe->vend_hdr.oui, wfd_oui, sizeof(wfd_oui))) {
- memcpy(ie_out + out_len, pos, length + 2);
- out_len += length + 2;
+ /* filter out first p2p ie */
+ if ((!memcmp
+ (pVendorIe->vend_hdr.oui, p2p_oui,
+ sizeof(pVendorIe->vend_hdr.oui)) &&
+ pVendorIe->vend_hdr.oui_type == p2p_oui[3])) {
+ if (!find_p2p_ie && (wps_flag & IE_MASK_P2P)) {
+ find_p2p_ie = MTRUE;
+ break;
}
- } else {
- memcpy(ie_out + out_len, pos, length + 2);
- out_len += length + 2;
}
+ /* filter out wfd ie */
+ if ((!memcmp
+ (pVendorIe->vend_hdr.oui, wfd_oui,
+ sizeof(pVendorIe->vend_hdr.oui)) &&
+ pVendorIe->vend_hdr.oui_type == wfd_oui[3]) &&
+ (wps_flag & IE_MASK_WFD))
+ break;
+ memcpy(ie_out + out_len, pos, length + 2);
+ out_len += length + 2;
break;
default:
memcpy(ie_out + out_len, pos, length + 2);
@@ -1516,6 +2085,86 @@ woal_filter_beacon_ies(const t_u8 * ie, int len, t_u8 * ie_out, t_u8 wps_flag)
return out_len;
}
+#ifdef WIFI_DIRECT_SUPPORT
+/**
+ * @brief Check if selected_registrar_on in wps_ie
+ *
+ * @param ie Pointer to IEs
+ * @param len Total length of ie
+ *
+ * @return MTRUE/MFALSE
+ */
+t_u8
+is_selected_registrar_on(const t_u8 * ie, int len)
+{
+#define WPS_IE_FIX_LEN 6
+#define TLV_ID_SELECTED_REGISTRAR 0x1041
+ int left_len = len - WPS_IE_FIX_LEN;
+ TLV_Generic_t *tlv = (TLV_Generic_t *) (ie + WPS_IE_FIX_LEN);
+ u16 tlv_type, tlv_len;
+ u8 *pos = NULL;
+ while (left_len > sizeof(TLV_Generic_t)) {
+ tlv_type = ntohs(tlv->type);
+ tlv_len = ntohs(tlv->len);
+ if (tlv_type == TLV_ID_SELECTED_REGISTRAR) {
+ PRINTM(MIOCTL, "Selected Registrar found !");
+ pos = (u8 *) tlv + sizeof(TLV_Generic_t);
+ if (*pos == 1)
+ return MTRUE;
+ else
+ return MFALSE;
+ }
+ tlv = (TLV_Generic_t *) ((u8 *) tlv + tlv_len + sizeof(TLV_Generic_t));
+ left_len -= tlv_len + sizeof(TLV_Generic_t);
+ }
+ return MFALSE;
+}
+
+/**
+ * @brief Check if selected_registrar_on in ies
+ *
+ * @param ie Pointer to IEs
+ * @param len Total length of ie
+ *
+ *
+ * @return MTRUE/MFALSE
+ */
+static t_u16
+woal_is_selected_registrar_on(const t_u8 * ie, int len)
+{
+ int left_len = len;
+ const t_u8 *pos = ie;
+ int length;
+ t_u8 id = 0;
+ IEEEtypes_VendorSpecific_t *pVendorIe = NULL;
+ const u8 wps_oui[4] = { 0x00, 0x50, 0xf2, 0x04 };
+
+ while (left_len >= 2) {
+ length = *(pos + 1);
+ id = *pos;
+ if ((length + 2) > left_len)
+ break;
+ switch (id) {
+ case VENDOR_SPECIFIC_221:
+ pVendorIe = (IEEEtypes_VendorSpecific_t *) pos;
+ if (!memcmp
+ (pVendorIe->vend_hdr.oui, wps_oui,
+ sizeof(pVendorIe->vend_hdr.oui)) &&
+ pVendorIe->vend_hdr.oui_type == wps_oui[3]) {
+ PRINTM(MIOCTL, "Find WPS ie\n");
+ return is_selected_registrar_on(pos, length + 2);
+ }
+ break;
+ default:
+ break;
+ }
+ pos += (length + 2);
+ left_len -= (length + 2);
+ }
+ return MFALSE;
+}
+#endif
+
/**
* @brief config AP or GO for mgmt frame ies.
*
@@ -1553,14 +2202,11 @@ woal_cfg80211_mgmt_frame_ie(moal_private * priv,
t_u16 proberesp_index = priv->proberesp_index;
t_u16 assocresp_index = priv->assocresp_index;
t_u16 probereq_index = priv->probereq_index;
- moal_private *pmpriv = NULL;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) && !defined(COMPAT_WIRELESS)
t_u16 beacon_wps_index = priv->beacon_wps_index;
-#endif
+ t_u16 proberesp_p2p_index = priv->proberesp_p2p_index;
ENTER();
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) && !defined(COMPAT_WIRELESS)
if (mask & MGMT_MASK_BEACON_WPS_P2P) {
if (!(beacon_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) {
ret = -ENOMEM;
@@ -1568,6 +2214,14 @@ woal_cfg80211_mgmt_frame_ie(moal_private * priv,
}
memset(beacon_ies_data, 0x00, sizeof(custom_ie));
if (beacon_ies && beacon_ies_len) {
+#ifdef WIFI_DIRECT_SUPPORT
+ if (woal_is_selected_registrar_on(beacon_ies, beacon_ies_len)) {
+ PRINTM(MIOCTL, "selected_registrar is on\n");
+ priv->phandle->is_go_timer_set = MTRUE;
+ woal_mod_timer(&priv->phandle->go_timer, MOAL_TIMER_10S);
+ } else
+ PRINTM(MIOCTL, "selected_registrar is off\n");
+#endif
beacon_ies_data->ie_index = beacon_wps_index;
beacon_ies_data->mgmt_subtype_mask = MGMT_MASK_BEACON;
beacon_ies_data->ie_length = beacon_ies_len;
@@ -1590,12 +2244,14 @@ woal_cfg80211_mgmt_frame_ie(moal_private * priv,
proberesp_ies_data, &proberesp_index,
assocresp_ies_data, &assocresp_index,
probereq_ies_data, &probereq_index)) {
+ PRINTM(MERROR, "Fail to set beacon wps IE\n");
ret = -EFAULT;
}
priv->beacon_wps_index = beacon_wps_index;
+ PRINTM(MIOCTL, "beacon_wps_index=0x%x\n", beacon_wps_index);
goto done;
}
-#endif
+
if (mask & MGMT_MASK_BEACON) {
if (!(beacon_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) {
ret = -ENOMEM;
@@ -1634,24 +2290,15 @@ woal_cfg80211_mgmt_frame_ie(moal_private * priv,
if (beacon_ies && beacon_ies_len) {
/* set the beacon ies */
beacon_ies_data->ie_index = beacon_index;
- beacon_ies_data->mgmt_subtype_mask = MGMT_MASK_BEACON;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) && !defined(COMPAT_WIRELESS)
- beacon_ies_data->mgmt_subtype_mask |=
- MGMT_MASK_ASSOC_RESP | MGMT_MASK_PROBE_RESP;
- beacon_ies_data->ie_length =
- woal_filter_beacon_ies(beacon_ies, beacon_ies_len,
- beacon_ies_data->ie_buffer, MTRUE);
-#else
- /* wpa_supplicant 1.x, will pass beacon_ie, probe_resp_ie and
- asso_resp_ie wpa_supplicant 1.0/2.x, will pass beacon_ie,
- prebe_resp_ie Only beacon_ie include RSN/WPA IE, other ies only
- include wps/p2p ie */
- beacon_ies_data->mgmt_subtype_mask |=
+ beacon_ies_data->mgmt_subtype_mask = MGMT_MASK_BEACON |
MGMT_MASK_ASSOC_RESP | MGMT_MASK_PROBE_RESP;
- beacon_ies_data->ie_length =
- woal_filter_beacon_ies(beacon_ies, beacon_ies_len,
- beacon_ies_data->ie_buffer, MFALSE);
-#endif
+ beacon_ies_data->ie_length = woal_filter_beacon_ies(beacon_ies,
+ beacon_ies_len,
+ beacon_ies_data->
+ ie_buffer,
+ IE_MASK_WPS |
+ IE_MASK_WFD |
+ IE_MASK_P2P);
} else {
/* clear the beacon ies */
if (beacon_index > MAX_MGMT_IE_INDEX) {
@@ -1669,20 +2316,54 @@ woal_cfg80211_mgmt_frame_ie(moal_private * priv,
if (proberesp_ies_data) {
memset(proberesp_ies_data, 0x00, sizeof(custom_ie));
if (proberesp_ies && proberesp_ies_len) {
+ /* set the probe response p2p ies */
+ proberesp_ies_data->ie_index = proberesp_p2p_index;
+ proberesp_ies_data->mgmt_subtype_mask = MGMT_MASK_PROBE_RESP;
+ proberesp_ies_data->ie_length = woal_get_first_p2p_ie(proberesp_ies,
+ proberesp_ies_len,
+ proberesp_ies_data->
+ ie_buffer);
+ } else {
+ /* clear the probe response p2p ies */
+ if (proberesp_p2p_index > MAX_MGMT_IE_INDEX) {
+ PRINTM(MERROR,
+ "Invalid proberesp_p2p_index for mgmt frame ie.\n");
+ goto done;
+ }
+ proberesp_ies_data->ie_index = proberesp_p2p_index;
+ proberesp_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK;
+ proberesp_ies_data->ie_length = 0;
+ proberesp_p2p_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
+ }
+ if (MLAN_STATUS_SUCCESS !=
+ woal_cfg80211_custom_ie(priv, NULL, &beacon_index,
+ proberesp_ies_data, &proberesp_p2p_index,
+ NULL, &assocresp_index,
+ NULL, &probereq_index)) {
+ PRINTM(MERROR, "Fail to set proberesp p2p IE\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ priv->proberesp_p2p_index = proberesp_p2p_index;
+ PRINTM(MIOCTL, "proberesp_p2p=0x%x\n", proberesp_p2p_index);
+ memset(proberesp_ies_data, 0x00, sizeof(custom_ie));
+ if (proberesp_ies && proberesp_ies_len) {
/* set the probe response ies */
- // proberesp_ies_data->ie_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
proberesp_ies_data->ie_index = proberesp_index;
proberesp_ies_data->mgmt_subtype_mask = MGMT_MASK_PROBE_RESP;
- proberesp_ies_data->ie_length = proberesp_ies_len;
- pos = proberesp_ies_data->ie_buffer;
- memcpy(pos, proberesp_ies, proberesp_ies_len);
+ if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == proberesp_index)
+ proberesp_ies_data->mgmt_subtype_mask |=
+ MLAN_CUSTOM_IE_NEW_MASK;
+ proberesp_ies_data->ie_length =
+ woal_filter_beacon_ies(proberesp_ies, proberesp_ies_len,
+ proberesp_ies_data->ie_buffer,
+ IE_MASK_P2P);
} else {
/* clear the probe response ies */
if (proberesp_index > MAX_MGMT_IE_INDEX) {
PRINTM(MERROR, "Invalid probe resp index for mgmt frame ie.\n");
goto done;
}
-
proberesp_ies_data->ie_index = proberesp_index;
proberesp_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK;
proberesp_ies_data->ie_length = 0;
@@ -1714,39 +2395,33 @@ woal_cfg80211_mgmt_frame_ie(moal_private * priv,
if (probereq_ies_data) {
memset(probereq_ies_data, 0x00, sizeof(custom_ie));
- if ((probereq_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK) &&
- (priv->probereq_index != probereq_index)) {
- pmpriv = woal_get_priv_by_mgmt_index(priv->phandle, probereq_index);
- if (pmpriv) {
- probereq_ies_data->ie_index = probereq_index;
- probereq_ies_data->mgmt_subtype_mask =
- MLAN_CUSTOM_IE_DELETE_MASK;
- probereq_ies_data->ie_length = 0;
- probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
- pmpriv->probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
- if (MLAN_STATUS_SUCCESS !=
- woal_cfg80211_custom_ie(pmpriv, NULL, &beacon_index,
- NULL, &proberesp_index,
- NULL, &assocresp_index,
- probereq_ies_data,
- &probereq_index)) {
- ret = -EFAULT;
- goto done;
- }
- memset(probereq_ies_data, 0x00, sizeof(custom_ie));
- }
- }
if (probereq_ies && probereq_ies_len) {
/* set the probe req ies */
probereq_ies_data->ie_index = probereq_index;
probereq_ies_data->mgmt_subtype_mask = MGMT_MASK_PROBE_REQ;
- probereq_ies_data->ie_length = probereq_ies_len;
- pos = probereq_ies_data->ie_buffer;
- memcpy(pos, probereq_ies, probereq_ies_len);
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ if (priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT) {
+ /* filter out P2P/WFD ie */
+ probereq_ies_data->ie_length =
+ woal_filter_beacon_ies(probereq_ies, probereq_ies_len,
+ probereq_ies_data->ie_buffer,
+ IE_MASK_P2P | IE_MASK_WFD);
+ } else {
+#endif /* KERNEL_VERSION */
+#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+ probereq_ies_data->ie_length = probereq_ies_len;
+ pos = probereq_ies_data->ie_buffer;
+ memcpy(pos, probereq_ies, probereq_ies_len);
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ }
+#endif /* KERNEL_VERSION */
+#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
} else {
/* clear the probe req ies */
if (probereq_index > MAX_MGMT_IE_INDEX) {
- PRINTM(MERROR, "Invalid probe resp index for mgmt frame ie.\n");
+ PRINTM(MERROR, "Invalid probe req index for mgmt frame ie.\n");
goto done;
}
probereq_ies_data->ie_index = probereq_index;
@@ -1761,6 +2436,7 @@ woal_cfg80211_mgmt_frame_ie(moal_private * priv,
proberesp_ies_data, &proberesp_index,
assocresp_ies_data, &assocresp_index,
probereq_ies_data, &probereq_index)) {
+ PRINTM(MERROR, "Fail to set beacon proberesp assoc probereq IES\n");
ret = -EFAULT;
goto done;
}
@@ -1772,6 +2448,8 @@ woal_cfg80211_mgmt_frame_ie(moal_private * priv,
priv->proberesp_index = proberesp_index;
if (probereq_ies_data)
priv->probereq_index = probereq_index;
+ PRINTM(MIOCTL, "beacon=%x assocresp=%x proberesp=%x probereq=%x\n",
+ beacon_index, assocresp_index, proberesp_index, probereq_index);
done:
if (beacon_ies_data)
kfree(beacon_ies_data);
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h b/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h
index d0b459980384..99fb84dcbc8b 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h
@@ -37,6 +37,7 @@
/* define for custom ie operation */
#define MLAN_CUSTOM_IE_AUTO_IDX_MASK 0xffff
#define MLAN_CUSTOM_IE_DELETE_MASK 0x0
+#define MLAN_CUSTOM_IE_NEW_MASK 0x8000
#define TLV_TYPE_MGMT_IE 0x0169
#define MGMT_MASK_ASSOC_REQ 0x01
#define MGMT_MASK_REASSOC_REQ 0x04
@@ -46,6 +47,9 @@
#define MGMT_MASK_PROBE_RESP 0x20
#define MGMT_MASK_BEACON 0x100
#define MGMT_MASK_BEACON_WPS_P2P 0x8000
+#define IE_MASK_WPS 0x0001
+#define IE_MASK_P2P 0x0002
+#define IE_MASK_WFD 0x0004
/**
* If multiple wiphys are registered e.g. a regular netdev with
@@ -62,6 +66,8 @@ void *woal_get_wiphy_priv(struct wiphy *wiphy);
/* Get the private structure from net device */
void *woal_get_netdev_priv(struct net_device *dev);
+t_u8 woal_band_cfg_to_ieee_band(t_u32 band);
+
int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
struct net_device *dev,
enum nl80211_iftype type,
@@ -83,22 +89,32 @@ int woal_cfg80211_del_key(struct wiphy *wiphy,
#endif
const t_u8 * mac_addr);
+int woal_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
+ struct net_device *dev,
+ const u8 * peer,
+ const struct cfg80211_bitrate_mask *mask);
+
+int woal_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
+
#ifdef STA_CFG80211
#ifdef STA_SUPPORT
int woal_set_rf_channel(moal_private * priv,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type);
mlan_status woal_inform_bss_from_scan_result(moal_private * priv,
- mlan_802_11_ssid * ssid);
+ mlan_ssid_bssid * ssid_bssid,
+ t_u8 wait_option);
#endif
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
int woal_cfg80211_set_channel(struct wiphy *wiphy,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) || defined(COMPAT_WIRELESS)
struct net_device *dev,
#endif
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type);
+#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
int woal_cfg80211_set_default_key(struct wiphy *wiphy,
@@ -110,15 +126,25 @@ int woal_cfg80211_set_default_key(struct wiphy *wiphy,
#endif
void woal_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
- struct net_device *dev, t_u16 frame_type,
- bool reg);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct wireless_dev *wdev,
+#else
+ struct net_device *dev,
+#endif
+ t_u16 frame_type, bool reg);
int woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct wireless_dev *wdev,
+#else
struct net_device *dev,
+#endif
struct ieee80211_channel *chan, bool offchan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
enum nl80211_channel_type channel_type,
- bool channel_type_valid, unsigned int wait,
- const u8 * buf, size_t len,
+ bool channel_type_valid,
+#endif
+ unsigned int wait, const u8 * buf, size_t len,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
bool no_cck,
#endif
@@ -127,10 +153,50 @@ int woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
#endif
u64 * cookie);
+mlan_status woal_register_cfg80211(moal_private * priv);
+
extern struct ieee80211_supported_band cfg80211_band_2ghz;
extern struct ieee80211_supported_band cfg80211_band_5ghz;
extern const u32 cfg80211_cipher_suites[10];
+#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
+int woal_cfg80211_bss_role_cfg(moal_private * priv, t_u16 action,
+ t_u8 * bss_role);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
+struct wireless_dev *woal_cfg80211_add_virtual_intf(struct wiphy *wiphy,
+ const char *name,
+ enum nl80211_iftype type,
+ u32 * flags,
+ struct vif_params *params);
+#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+struct wireless_dev *woal_cfg80211_add_virtual_intf(struct wiphy *wiphy,
+ char *name,
+ enum nl80211_iftype type,
+ u32 * flags,
+ struct vif_params *params);
+#else
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
+struct net_device *woal_cfg80211_add_virtual_intf(struct wiphy *wiphy,
+ char *name,
+ enum nl80211_iftype type,
+ u32 * flags,
+ struct vif_params *params);
+#else
+int woal_cfg80211_add_virtual_intf(struct wiphy *wiphy,
+ char *name, enum nl80211_iftype type,
+ u32 * flags, struct vif_params *params);
+#endif
+#endif
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy,
+ struct wireless_dev *wdev);
+#else
+int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
+#endif
+
#if defined(WIFI_DIRECT_SUPPORT)
/** Define kernel version for wifi direct */
#if !defined(COMPAT_WIRELESS)
@@ -142,6 +208,27 @@ extern const u32 cfg80211_cipher_suites[10];
/** Define for remain on channel duration timer */
#define MAX_REMAIN_ON_CHANNEL_DURATION (1000 * 5)
+int woal_cfg80211_init_p2p_client(moal_private * priv);
+
+int woal_cfg80211_init_p2p_go(moal_private * priv);
+
+int woal_cfg80211_deinit_p2p(moal_private * priv);
+
+int woal_cfg80211_remain_on_channel_cfg(moal_private * priv,
+ t_u8 wait_option, t_u8 remove,
+ t_u8 * status,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type,
+ t_u32 duration);
+int woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 * mac, struct station_info *stainfo);
+
+void woal_remove_virtual_interface(moal_handle * handle);
+
+#endif /* KERNEL_VERSION */
+#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+
+#ifdef UAP_CFG80211
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
int woal_cfg80211_add_beacon(struct wiphy *wiphy,
struct net_device *dev,
@@ -161,26 +248,13 @@ int woal_cfg80211_set_beacon(struct wiphy *wiphy,
#endif
int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev);
-
-int woal_cfg80211_init_p2p_client(moal_private * priv);
-
-int woal_cfg80211_init_p2p_go(moal_private * priv);
-
-int woal_cfg80211_deinit_p2p(moal_private * priv);
-
-int woal_cfg80211_remain_on_channel_cfg(moal_private * priv,
- t_u8 wait_option, t_u8 remove,
- t_u8 * status,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type,
- t_u32 duration);
-int woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
- u8 * mac, struct station_info *stainfo);
-#endif /* KERNEL_VERSION */
-#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+int woal_cfg80211_del_station(struct wiphy *wiphy,
+ struct net_device *dev, u8 * mac_addr);
+#endif
const t_u8 *woal_parse_ie_tlv(const t_u8 * ie, int len, t_u8 id);
+void woal_clear_all_mgmt_ies(moal_private * priv);
int woal_cfg80211_mgmt_frame_ie(moal_private * priv,
const t_u8 * beacon_ies, size_t beacon_ies_len,
const t_u8 * proberesp_ies,
@@ -190,6 +264,12 @@ int woal_cfg80211_mgmt_frame_ie(moal_private * priv,
const t_u8 * probereq_ies,
size_t probereq_ies_len, t_u16 mask);
+t_u8 woal_is_any_interface_active(moal_handle * handle);
+
+int woal_get_active_intf_freq(moal_handle * handle);
+
void woal_cfg80211_setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info,
t_u32 dev_cap, t_u8 * mcs_set);
+int woal_cfg80211_assoc(moal_private * priv, void *sme);
+
#endif /* _MOAL_CFG80211_H_ */
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_debug.c b/drivers/net/wireless/sd8797/mlinux/moal_debug.c
index f731da551e7f..0c19d5effbf8 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_debug.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_debug.c
@@ -100,6 +100,9 @@ static struct debug_data items[] = {
,
{"port_open", item_size(port_open), item_addr(port_open)}
,
+ {"bypass_pkt_count", item_size(bypass_pkt_count),
+ item_addr(bypass_pkt_count)}
+ ,
{"scan_processing", item_size(scan_processing), item_addr(scan_processing)}
,
{"num_tx_timeout", item_size(num_tx_timeout), item_addr(num_tx_timeout)}
@@ -127,6 +130,8 @@ static struct debug_data items[] = {
{"last_event_index", item_size(last_event_index),
item_addr(last_event_index)}
,
+ {"num_no_cmd_node", item_size(num_no_cmd_node), item_addr(num_no_cmd_node)}
+ ,
{"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
item_addr(num_cmd_host_to_card_failure)}
,
@@ -194,6 +199,9 @@ static struct debug_data items[] = {
{"malloc_count", item_handle_size(malloc_count),
item_handle_addr(malloc_count)}
,
+ {"vmalloc_count", item_handle_size(vmalloc_count),
+ item_handle_addr(vmalloc_count)}
+ ,
{"mbufalloc_count", item_handle_size(mbufalloc_count),
item_handle_addr(mbufalloc_count)}
,
@@ -253,6 +261,9 @@ static struct debug_data uap_items[] = {
,
{"tx_pkts_queued", item_size(tx_pkts_queued), item_addr(tx_pkts_queued)}
,
+ {"bypass_pkt_count", item_size(bypass_pkt_count),
+ item_addr(bypass_pkt_count)}
+ ,
{"num_bridge_pkts", item_size(num_bridge_pkts), item_addr(num_bridge_pkts)}
,
{"num_drop_pkts", item_size(num_drop_pkts), item_addr(num_drop_pkts)}
@@ -282,6 +293,8 @@ static struct debug_data uap_items[] = {
{"last_event_index", item_size(last_event_index),
item_addr(last_event_index)}
,
+ {"num_no_cmd_node", item_size(num_no_cmd_node), item_addr(num_no_cmd_node)}
+ ,
{"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
item_addr(num_cmd_host_to_card_failure)}
,
@@ -333,6 +346,9 @@ static struct debug_data uap_items[] = {
{"malloc_count", item_handle_size(malloc_count),
item_handle_addr(malloc_count)}
,
+ {"vmalloc_count", item_handle_size(vmalloc_count),
+ item_handle_addr(vmalloc_count)}
+ ,
{"mbufalloc_count", item_handle_size(mbufalloc_count),
item_handle_addr(mbufalloc_count)}
,
@@ -417,6 +433,11 @@ woal_debug_read(char *page, char **s, off_t off, int cnt, int *eof, void *data)
else
p += sprintf(p, "%s=%d\n", d[i].name, val);
}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+ for (i = 0; i < 4; i++)
+ p += sprintf(p, "wmm_tx_pending[%d]:%d\n", i,
+ atomic_read(&priv->wmm_tx_pending[i]));
+#endif
if (info.tx_tbl_num) {
p += sprintf(p, "Tx BA stream table:\n");
for (i = 0; i < info.tx_tbl_num; i++) {
@@ -490,12 +511,13 @@ woal_debug_write(struct file *f, const char *buf, unsigned long cnt, void *data)
return MLAN_STATUS_FAILURE;
}
- pdata = (char *) kmalloc(cnt, GFP_KERNEL);
+ pdata = (char *) kmalloc(cnt + 1, GFP_KERNEL);
if (pdata == NULL) {
MODULE_PUT;
LEAVE();
return 0;
}
+ memset(pdata, 0, cnt + 1);
if (copy_from_user(pdata, buf, cnt)) {
PRINTM(MERROR, "Copy from user failed\n");
@@ -539,8 +561,9 @@ woal_debug_write(struct file *f, const char *buf, unsigned long cnt, void *data)
kfree(pdata);
#ifdef DEBUG_LEVEL1
- if (last_drvdbg != drvdbg)
+ if (last_drvdbg != drvdbg) {
woal_set_drvdbg(priv, drvdbg);
+ }
#endif
/* Set debug information */
@@ -607,7 +630,7 @@ woal_debug_entry(moal_private * priv)
#endif
priv->items_priv.priv = priv;
- handle_items = 7;
+ handle_items = 8;
#ifdef SDIO_MMC_DEBUG
handle_items += 2;
#endif
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c b/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c
index aab4e5a1a40d..86c7bc73b239 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c
@@ -63,7 +63,7 @@ static t_u8 SupportedAdhocBand[] = {
/********************************************************
Global Variables
********************************************************/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
#ifdef UAP_SUPPORT
/** Network device handlers for uAP */
extern const struct net_device_ops woal_uap_netdev_ops;
@@ -75,6 +75,7 @@ extern const struct net_device_ops woal_netdev_ops;
#endif
extern int cfg80211_wext;
+extern int hw_test;
/********************************************************
Local Functions
********************************************************/
@@ -149,8 +150,7 @@ woal_set_ap_wps_p2p_ie(moal_private * priv, t_u8 * ie, size_t len)
ENTER();
ie_len = len - 2;
- if (ie_len <= 0 || ie_len > MAX_IE_SIZE) {
- // TO DO need handle IE large then 256
+ if (ie_len <= 0) {
PRINTM(MERROR, "IE len error: %d\n", ie_len);
ret = -EFAULT;
goto done;
@@ -867,7 +867,7 @@ woal_priv_delba(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
if (user_data_len > 3 ||
(!(data[0] & (DELBA_TX | DELBA_RX))) ||
- (data[1] != DELBA_ALL_TIDS && !(data[1] >= 0 && data[1] <= 7))) {
+ (data[1] != DELBA_ALL_TIDS && !(data[1] <= 7))) {
/* Incorrect number of arguments */
PRINTM(MERROR, "%d: Invalid arguments\n", __LINE__);
ret = -EINVAL;
@@ -1332,6 +1332,94 @@ woal_setget_priv_txratecfg(moal_private * priv, t_u8 * respbuf,
}
+#ifdef STA_SUPPORT
+/**
+ * @brief Get statistics information
+ *
+ * @param priv A pointer to moal_private structure
+ * @param wait_option Wait option
+ * @param stats A pointer to mlan_ds_get_stats structure
+ *
+ * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, otherwise fail
+ */
+mlan_status
+woal_get_stats_info(moal_private * priv, t_u8 wait_option,
+ mlan_ds_get_stats * stats)
+{
+ int ret = 0;
+ mlan_ds_get_info *info = NULL;
+ mlan_ioctl_req *req = NULL;
+ mlan_status status = MLAN_STATUS_SUCCESS;
+ ENTER();
+
+ /* Allocate an IOCTL request buffer */
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ /* Fill request buffer */
+ info = (mlan_ds_get_info *) req->pbuf;
+ info->sub_command = MLAN_OID_GET_STATS;
+ req->req_id = MLAN_IOCTL_GET_INFO;
+ req->action = MLAN_ACT_GET;
+
+ /* Send IOCTL request to MLAN */
+ status = woal_request_ioctl(priv, req, wait_option);
+ if (status == MLAN_STATUS_SUCCESS) {
+ if (stats)
+ memcpy(stats, &info->param.stats, sizeof(mlan_ds_get_stats));
+#if defined(STA_WEXT) || defined(UAP_WEXT)
+ priv->w_stats.discard.fragment = info->param.stats.fcs_error;
+ priv->w_stats.discard.retries = info->param.stats.retry;
+ priv->w_stats.discard.misc = info->param.stats.ack_failure;
+#endif
+ }
+ done:
+ if (req && (status != MLAN_STATUS_PENDING))
+ kfree(req);
+ LEAVE();
+ return status;
+}
+
+/**
+ * @brief Get wireless stats information
+ *
+ * @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.
+ */
+int
+woal_get_priv_getlog(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ int ret = 0;
+ mlan_ds_get_stats *stats;
+ ENTER();
+
+ if (respbuflen < sizeof(*stats)) {
+ PRINTM(MERROR, "Get log: respbuflen (%d) too small!", (int) respbuflen);
+ ret = -EFAULT;
+ goto done;
+ }
+ stats = (mlan_ds_get_stats *) respbuf;
+ if (MLAN_STATUS_SUCCESS !=
+ woal_get_stats_info(priv, MOAL_IOCTL_WAIT, stats)) {
+ PRINTM(MERROR, "Get log: Failed to get stats info!");
+ ret = -EFAULT;
+ goto done;
+ }
+
+ ret = sizeof(mlan_ds_get_stats);
+
+ done:
+ LEAVE();
+ return ret;
+}
+#endif
+
/**
* @brief Set/Get esupplicant mode configurations
*
@@ -1508,8 +1596,8 @@ woal_setget_priv_passphrase(moal_private * priv, t_u8 * respbuf,
break;
}
sec->param.passphrase.psk_type = MLAN_PSK_PASSPHRASE;
- strncpy(sec->param.passphrase.psk.passphrase.passphrase, end,
- sizeof(sec->param.passphrase.psk.passphrase.passphrase));
+ memcpy(sec->param.passphrase.psk.passphrase.passphrase, end,
+ sizeof(sec->param.passphrase.psk.passphrase.passphrase));
sec->param.passphrase.psk.passphrase.passphrase_len = strlen(end);
PRINTM(MINFO, "passphrase=%s, len=%d\n",
sec->param.passphrase.psk.passphrase.passphrase,
@@ -1581,7 +1669,6 @@ woal_setget_priv_passphrase(moal_private * priv, t_u8 * respbuf,
int
woal_priv_deauth(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
{
- mlan_ioctl_req *req = NULL;
int ret = 0;
t_u8 mac[ETH_ALEN];
@@ -1601,8 +1688,6 @@ woal_priv_deauth(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
}
done:
- if (req)
- kfree(req);
LEAVE();
return ret;
}
@@ -1632,12 +1717,8 @@ woal_priv_ap_deauth(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
memset(&deauth_param, 0, sizeof(mlan_deauth_param));
memcpy(&deauth_param, data_ptr, sizeof(mlan_deauth_param));
- PRINTM(MIOCTL,
- "ioctl deauth station: %02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n",
- deauth_param.mac_addr[0], deauth_param.mac_addr[1],
- deauth_param.mac_addr[2], deauth_param.mac_addr[3],
- deauth_param.mac_addr[4], deauth_param.mac_addr[5],
- deauth_param.reason_code);
+ PRINTM(MIOCTL, "ioctl deauth station: " MACSTR ", reason=%d\n",
+ MAC2STR(deauth_param.mac_addr), deauth_param.reason_code);
ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
if (ioctl_req == NULL) {
@@ -1796,12 +1877,12 @@ woal_priv_bssrole(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
ENTER();
+ memset((char *) data, 0, sizeof(data));
if (strlen(respbuf) == (strlen(CMD_MARVELL) + strlen(PRIV_CMD_BSSROLE))) {
/* GET operation */
user_data_len = 0;
} else {
/* SET operation */
- memset((char *) data, 0, sizeof(data));
parse_arguments(respbuf + strlen(CMD_MARVELL) +
strlen(PRIV_CMD_BSSROLE), data,
sizeof(data) / sizeof(int), &user_data_len);
@@ -2031,6 +2112,76 @@ woal_priv_getscantable(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
LEAVE();
return ret;
}
+
+/**
+ * @brief Extended capabilities configuration
+ *
+ * @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.
+ */
+int
+woal_priv_extcapcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ int ret, header;
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_misc_cfg *cfg = NULL;
+ IEEEtypes_Header_t *ie;
+
+ ENTER();
+
+ if (!respbuf) {
+ LEAVE();
+ return 0;
+ }
+
+ 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_EXT_CAP_CFG;
+ req->req_id = MLAN_IOCTL_MISC_CFG;
+ header = strlen(CMD_MARVELL) + strlen(PRIV_CMD_EXTCAPCFG);
+ if (strlen(respbuf) == header)
+ /* GET operation */
+ req->action = MLAN_ACT_GET;
+ else {
+ /* SET operation */
+ ie = (IEEEtypes_Header_t *) (respbuf + header);
+ if (ie->len > sizeof(ExtCap_t)) {
+ PRINTM(MERROR, "Extended Capability lenth is invalid\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ req->action = MLAN_ACT_SET;
+ memset(&cfg->param.ext_cap, 0, sizeof(ExtCap_t) - ie->len);
+ memcpy(&cfg->param.ext_cap, ie + 1, ie->len);
+ }
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ memset(respbuf, 0, respbuflen);
+ ie = (IEEEtypes_Header_t *) respbuf;
+ ie->element_id = EXT_CAPABILITY;
+ ie->len = sizeof(ExtCap_t);
+ memcpy(ie + 1, &cfg->param.ext_cap, sizeof(ExtCap_t));
+
+ ret = sizeof(ie) + ie->len;
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
#endif
/**
@@ -2124,6 +2275,12 @@ woal_priv_setgetipaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
ENTER();
+ if (priv->bss_type != MLAN_BSS_TYPE_STA) {
+ PRINTM(MIOCTL, "Bss type[%d]: Not STA, ignore it\n", priv->bss_type);
+ ret = sprintf(respbuf, "OK\n") + 1;
+ goto done;
+ }
+
header = strlen(CMD_MARVELL) + strlen(PRIV_CMD_IPADDR);
data_length = strlen(respbuf) - header;
@@ -2209,12 +2366,12 @@ woal_priv_setwpssession(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
ENTER();
+ memset((char *) data, 0, sizeof(data));
if (strlen(respbuf) == (strlen(CMD_MARVELL) + strlen(PRIV_CMD_WPSSESSION))) {
/* GET operation */
user_data_len = 0;
} else {
/* SET operation */
- memset((char *) data, 0, sizeof(data));
parse_arguments(respbuf + strlen(CMD_MARVELL) +
strlen(PRIV_CMD_WPSSESSION), data,
sizeof(data) / sizeof(int), &user_data_len);
@@ -2404,8 +2561,6 @@ woal_priv_setgettcpackenh(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
t_u32 data[1];
int ret = 0;
int user_data_len = 0;
- struct list_head *link = NULL;
- struct tcp_sess *tcp_sess = NULL;
ENTER();
@@ -2438,16 +2593,7 @@ woal_priv_setgettcpackenh(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
PRINTM(MINFO, "Disabling TCP Ack enhancement\n");
priv->enable_tcp_ack_enh = MFALSE;
/* release the tcp sessions if any */
- while (!list_empty(&priv->tcp_sess_queue)) {
- link = priv->tcp_sess_queue.next;
- tcp_sess = list_entry(link, struct tcp_sess, link);
- PRINTM(MINFO,
- "Disable TCP ACK Enh: release a tcp session in dl. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n",
- tcp_sess->src_ip_addr, tcp_sess->src_tcp_port,
- tcp_sess->dst_ip_addr, tcp_sess->dst_tcp_port);
- list_del(link);
- kfree(tcp_sess);
- }
+ woal_flush_tcp_sess_queue(priv);
} else {
PRINTM(MERROR, "Unknown option = %u\n", data[0]);
ret = -EINVAL;
@@ -2530,6 +2676,11 @@ woal_priv_assocessid(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
PRINTM(MINFO, "Requested new SSID = %s\n", (char *) req_ssid.ssid);
memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(mlan_802_11_ssid));
+ if (MTRUE == woal_is_connected(priv, &ssid_bssid)) {
+ PRINTM(MIOCTL, "Already connect to the network\n");
+ ret = sprintf(respbuf, "Has already connected to this ESSID!\n") + 1;
+ goto setessid_ret;
+ }
memcpy(&priv->prev_ssid_bssid.ssid, &req_ssid, sizeof(mlan_802_11_ssid));
/* disconnect before driver assoc */
@@ -2769,6 +2920,7 @@ woal_priv_set_get_drvdbg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
LEAVE();
return ret;
}
+
#endif
/**
@@ -3064,10 +3216,8 @@ woal_priv_set_ap(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
awrq = (struct sockaddr *) &(mwr->u.ap_addr);
- PRINTM(MINFO, "ASSOC: WAP: sa_data: %02x:%02x:%02x:%02x:%02x:%02x\n",
- (t_u8) awrq->sa_data[0], (t_u8) awrq->sa_data[1],
- (t_u8) awrq->sa_data[2], (t_u8) awrq->sa_data[3],
- (t_u8) awrq->sa_data[4], (t_u8) awrq->sa_data[5]);
+ PRINTM(MINFO, "ASSOC: WAP: sa_data: " MACSTR "\n",
+ MAC2STR((t_u8 *) awrq->sa_data));
if (MLAN_STATUS_SUCCESS !=
woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
@@ -3093,8 +3243,6 @@ woal_priv_set_ap(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
if (bss_info.media_connected == MTRUE) {
if (!memcmp(awrq->sa_data, &bss_info.bssid, ETH_ALEN))
goto done;
- /* disconnect before try to assoicate to the new AP */
- woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
}
memcpy(&ssid_bssid.bssid, awrq->sa_data, ETH_ALEN);
}
@@ -3213,6 +3361,12 @@ woal_priv_set_power(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
ENTER();
+ if (hw_test) {
+ PRINTM(MIOCTL, "block set power in hw_test mode\n");
+ LEAVE();
+ return ret;
+ }
+
data_ptr = respbuf + (strlen(CMD_MARVELL) + strlen(PRIV_CMD_SET_POWER));
mwr = (struct mwreq *) data_ptr;
@@ -3308,6 +3462,10 @@ woal_priv_set_essid(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
PRINTM(MINFO, "Requested new SSID = %s\n", (char *) req_ssid.ssid);
memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(mlan_802_11_ssid));
+ if (MTRUE == woal_is_connected(priv, &ssid_bssid)) {
+ PRINTM(MIOCTL, "Already connect to the network\n");
+ goto setessid_ret;
+ }
if (mwr->u.essid.flags != 0xFFFF) {
if (MLAN_STATUS_SUCCESS != woal_find_essid(priv, &ssid_bssid)) {
@@ -3322,8 +3480,6 @@ woal_priv_set_essid(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
}
- /* disconnect before try to associate */
- woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
mode = woal_get_mode(priv, MOAL_IOCTL_WAIT);
if (mode != MW_MODE_ADHOC) {
@@ -3547,6 +3703,63 @@ woal_priv_get_power(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
LEAVE();
return ret;
}
+
+/**
+ * @brief Set/Get power save 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_psmode(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_MARVELL) + strlen(PRIV_CMD_PSMODE);
+
+ if (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;
+ }
+
+ /* Flip the value */
+ data = !data;
+
+ if (MLAN_STATUS_SUCCESS != woal_set_get_power_mgmt(priv, action, &data, 0)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ if (action == MLAN_ACT_SET)
+ data = !data;
+
+ memcpy(respbuf, (t_u8 *) & data, sizeof(data));
+ ret = sizeof(data);
+
+ done:
+ LEAVE();
+ return ret;
+}
#endif /* STA_SUPPORT */
/**
@@ -3737,7 +3950,7 @@ woal_priv_txpowercfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
goto done;
pcfg->param.power_ext.len = user_data_len;
memcpy((t_u8 *) & pcfg->param.power_ext.power_data,
- (t_u8 *) data, sizeof(int) * sizeof(data));
+ (t_u8 *) data, sizeof(data));
}
if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
ret = -EFAULT;
@@ -4522,6 +4735,881 @@ woal_priv_mgmt_frame_passthru_ctrl(moal_private * priv, t_u8 * respbuf,
}
/**
+ * @brief Private IOCTL entry to send an ADDTS TSPEC
+ *
+ * Receive a ADDTS command from the application. The command structure
+ * contains a TSPEC and timeout in milliseconds. The timeout is performed
+ * in the firmware after the ADDTS command frame is sent.
+ *
+ * The TSPEC is received in the API as an opaque block. The firmware will
+ * send the entire data block, including the bytes after the TSPEC. This
+ * is done to allow extra IEs to be packaged with the TSPEC in the ADDTS
+ * action frame.
+ *
+ * The IOCTL structure contains two return fields:
+ * - The firmware command result, which indicates failure and timeouts
+ * - The IEEE Status code which contains the corresponding value from
+ * any ADDTS response frame received.
+ *
+ * In addition, the opaque TSPEC data block passed in is replaced with the
+ * TSPEC received in the ADDTS response frame. In case of failure, the
+ * AP may modify the TSPEC on return and in the case of success, the
+ * medium time is returned as calculated by the AP. Along with the TSPEC,
+ * any IEs that are sent in the ADDTS response are also returned and can be
+ * parsed using the IOCTL length as an indicator of extra elements.
+ *
+ * The return value to the application layer indicates a driver execution
+ * success or failure. A successful return could still indicate a firmware
+ * failure or AP negotiation failure via the commandResult field copied
+ * back to the application.
+ *
+ * @param priv Pointer to the mlan_private driver data struct
+ * @param respbuf A pointer to response buffer
+ * @param respbuflen Available length of response buffer
+ *
+ * @return Number of bytes written if successful else negative value
+ */
+static int
+woal_priv_wmm_addts_req_ioctl(moal_private * priv, t_u8 * respbuf,
+ t_u32 respbuflen)
+{
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_wmm_cfg *cfg = NULL;
+ wlan_ioctl_wmm_addts_req_t addts_ioctl;
+ int ret = 0, header_len = 0, copy_len = sizeof(addts_ioctl);
+ t_u8 *data_ptr;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_ADDTS);
+ data_ptr = respbuf + header_len;
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ req->req_id = MLAN_IOCTL_WMM_CFG;
+ cfg = (mlan_ds_wmm_cfg *) req->pbuf;
+ cfg->sub_command = MLAN_OID_WMM_CFG_ADDTS;
+
+ memset(&addts_ioctl, 0x00, sizeof(addts_ioctl));
+
+ memcpy((t_u8 *) & addts_ioctl, data_ptr, sizeof(addts_ioctl));
+
+ cfg->param.addts.timeout = addts_ioctl.timeout_ms;
+ cfg->param.addts.ie_data_len = (t_u8) addts_ioctl.ie_data_len;
+
+ memcpy(cfg->param.addts.ie_data,
+ addts_ioctl.ie_data, cfg->param.addts.ie_data_len);
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+ addts_ioctl.cmd_result = cfg->param.addts.result;
+ addts_ioctl.ieee_status_code = (t_u8) cfg->param.addts.status_code;
+ addts_ioctl.ie_data_len = cfg->param.addts.ie_data_len;
+
+ memcpy(addts_ioctl.ie_data,
+ cfg->param.addts.ie_data, cfg->param.addts.ie_data_len);
+
+ copy_len = (sizeof(addts_ioctl)
+ - sizeof(addts_ioctl.ie_data)
+ + cfg->param.addts.ie_data_len);
+
+ memcpy(respbuf, (t_u8 *) & addts_ioctl, copy_len);
+ ret = copy_len;
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Private IOCTL entry to send a DELTS TSPEC
+ *
+ * Receive a DELTS command from the application. The command structure
+ * contains a TSPEC and reason code along with space for a command result
+ * to be returned. The information is packaged is sent to the wlan_cmd.c
+ * firmware command prep and send routines for execution in the firmware.
+ *
+ * The reason code is not used for WMM implementations but is indicated in
+ * the 802.11e specification.
+ *
+ * The return value to the application layer indicates a driver execution
+ * success or failure. A successful return could still indicate a firmware
+ * failure via the cmd_result field copied back to the application.
+ *
+ * @param priv Pointer to the mlan_private driver data struct
+ * @param respbuf A pointer to response buffer
+ * @param respbuflen Available length of response buffer
+ *
+ * @return Number of bytes written if successful else negative value
+ */
+static int
+woal_priv_wmm_delts_req_ioctl(moal_private * priv, t_u8 * respbuf,
+ t_u32 respbuflen)
+{
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_wmm_cfg *cfg = NULL;
+ wlan_ioctl_wmm_delts_req_t delts_ioctl;
+ int ret = 0, header_len = 0, copy_len = 0;
+ t_u8 *data_ptr;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_DELTS);
+ data_ptr = respbuf + header_len;
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ req->req_id = MLAN_IOCTL_WMM_CFG;
+ cfg = (mlan_ds_wmm_cfg *) req->pbuf;
+ cfg->sub_command = MLAN_OID_WMM_CFG_DELTS;
+
+ memset(&delts_ioctl, 0x00, sizeof(delts_ioctl));
+
+ if (strlen(respbuf) > header_len) {
+ copy_len = MIN(strlen(data_ptr), sizeof(delts_ioctl));
+ memcpy((t_u8 *) & delts_ioctl, data_ptr, copy_len);
+
+ cfg->param.delts.status_code = (t_u32) delts_ioctl.ieee_reason_code;
+ cfg->param.delts.ie_data_len = (t_u8) delts_ioctl.ie_data_len;
+
+ memcpy(cfg->param.delts.ie_data,
+ delts_ioctl.ie_data, cfg->param.delts.ie_data_len);
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req,
+ MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ /* Return the firmware command result back to the application layer */
+ delts_ioctl.cmd_result = cfg->param.delts.result;
+ copy_len = sizeof(delts_ioctl);
+ memcpy(respbuf, (t_u8 *) & delts_ioctl, copy_len);
+ ret = copy_len;
+ }
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Private IOCTL entry to get/set a specified AC Queue's parameters
+ *
+ * Receive a AC Queue configuration command which is used to get, set, or
+ * default the parameters associated with a specific WMM AC Queue.
+ *
+ * @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_qconfig(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_wmm_cfg *pwmm = NULL;
+ mlan_ds_wmm_queue_config *pqcfg = NULL;
+ wlan_ioctl_wmm_queue_config_t qcfg_ioctl;
+ t_u8 *data_ptr;
+ int ret = 0;
+
+ ENTER();
+
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ req->req_id = MLAN_IOCTL_WMM_CFG;
+ pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
+ pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_CONFIG;
+
+ memset(&qcfg_ioctl, 0x00, sizeof(qcfg_ioctl));
+ pqcfg = (mlan_ds_wmm_queue_config *) & pwmm->param.q_cfg;
+ data_ptr = respbuf + (strlen(CMD_MARVELL) + strlen(PRIV_CMD_QCONFIG));
+
+ memcpy((t_u8 *) & qcfg_ioctl, data_ptr, sizeof(qcfg_ioctl));
+ pqcfg->action = qcfg_ioctl.action;
+ pqcfg->access_category = qcfg_ioctl.access_category;
+ pqcfg->msdu_lifetime_expiry = qcfg_ioctl.msdu_lifetime_expiry;
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+ memset(&qcfg_ioctl, 0x00, sizeof(qcfg_ioctl));
+ qcfg_ioctl.action = pqcfg->action;
+ qcfg_ioctl.access_category = pqcfg->access_category;
+ qcfg_ioctl.msdu_lifetime_expiry = pqcfg->msdu_lifetime_expiry;
+ memcpy(data_ptr, (t_u8 *) & qcfg_ioctl, sizeof(qcfg_ioctl));
+ ret = strlen(CMD_MARVELL) + strlen(PRIV_CMD_QCONFIG) + sizeof(qcfg_ioctl);
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Private IOCTL entry to get the status of the WMM queues
+ *
+ * Return the following information for each WMM AC:
+ * - WMM IE Acm Required
+ * - Firmware Flow Required
+ * - Firmware Flow Established
+ * - Firmware Queue Enabled
+ * - Firmware Delivery Enabled
+ * - Firmware Trigger Enabled
+ *
+ * @param priv Pointer to the moal_private driver data struct
+ * @param respbuf A pointer to response buffer
+ * @param respbuflen Available length of response buffer
+ *
+ * @return Number of bytes written if successful else negative value
+ */
+static int
+woal_priv_wmm_queue_status_ioctl(moal_private * priv, t_u8 * respbuf,
+ t_u32 respbuflen)
+{
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_wmm_cfg *pwmm = NULL;
+ wlan_ioctl_wmm_queue_status_t qstatus_ioctl;
+ int ret = 0, header_len = 0;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_QSTATUS);
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ req->req_id = MLAN_IOCTL_WMM_CFG;
+ pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
+ pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_STATUS;
+
+ if (strlen(respbuf) == header_len) {
+ if (MLAN_STATUS_SUCCESS !=
+ woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ memset(&qstatus_ioctl, 0x00, sizeof(qstatus_ioctl));
+ memcpy((void *) &qstatus_ioctl, (void *) &pwmm->param.q_status,
+ sizeof(qstatus_ioctl));
+ memcpy(respbuf, (t_u8 *) & qstatus_ioctl, sizeof(qstatus_ioctl));
+ ret = sizeof(qstatus_ioctl);
+ }
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Private IOCTL entry to get the status of the WMM Traffic Streams
+ *
+ * @param priv Pointer to the moal_private driver data struct
+ * @param respbuf A pointer to response buffer
+ * @param respbuflen Available length of response buffer
+ *
+ * @return Number of bytes written if successful else negative value
+ */
+static int
+woal_priv_wmm_ts_status_ioctl(moal_private * priv, t_u8 * respbuf,
+ t_u32 respbuflen)
+{
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_wmm_cfg *pwmm = NULL;
+ wlan_ioctl_wmm_ts_status_t ts_status_ioctl;
+ int ret = 0, header_len = 0;
+ t_u8 *data_ptr;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_TS_STATUS);
+ data_ptr = respbuf + header_len;
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ req->req_id = MLAN_IOCTL_WMM_CFG;
+ pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
+ pwmm->sub_command = MLAN_OID_WMM_CFG_TS_STATUS;
+
+ memset(&ts_status_ioctl, 0x00, sizeof(ts_status_ioctl));
+
+ memcpy((t_u8 *) & ts_status_ioctl, data_ptr, sizeof(ts_status_ioctl));
+
+ memset(&pwmm->param.ts_status, 0x00, sizeof(ts_status_ioctl));
+ pwmm->param.ts_status.tid = ts_status_ioctl.tid;
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ memset(&ts_status_ioctl, 0x00, sizeof(ts_status_ioctl));
+ memcpy((void *) &ts_status_ioctl, (void *) &pwmm->param.ts_status,
+ sizeof(ts_status_ioctl));
+ memcpy(respbuf, (t_u8 *) & ts_status_ioctl, sizeof(ts_status_ioctl));
+ ret = sizeof(ts_status_ioctl);
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Set/Get MAC control
+ *
+ * @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.
+ */
+int
+woal_priv_macctrl(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ int data = 0;
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_misc_cfg *cfg = NULL;
+ int ret = 0;
+ int user_data_len = 0, header_len = 0;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_MAC_CTRL);
+ if (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;
+ }
+ 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_MAC_CONTROL;
+ req->req_id = MLAN_IOCTL_MISC_CFG;
+
+ if (user_data_len == 0)
+ req->action = MLAN_ACT_GET;
+ else {
+ cfg->param.mac_ctrl = (t_u32) data;
+ req->action = MLAN_ACT_SET;
+ }
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ memcpy(respbuf, (t_u8 *) & cfg->param.mac_ctrl, sizeof(data));
+ ret = sizeof(data);
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Get connection status
+ *
+ * @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
+ */
+int
+woal_priv_getwap(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ int ret = 0;
+#ifdef STA_SUPPORT
+ mlan_bss_info bss_info;
+#endif
+
+ ENTER();
+
+#ifdef STA_SUPPORT
+ if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) {
+ memset(&bss_info, 0, sizeof(bss_info));
+
+ woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+
+ if (bss_info.media_connected == MTRUE) {
+ memcpy(respbuf, (t_u8 *) & bss_info.bssid, MLAN_MAC_ADDR_LENGTH);
+ } else {
+ memset(respbuf, 0, MLAN_MAC_ADDR_LENGTH);
+ }
+ }
+#endif
+#ifdef UAP_SUPPORT
+ if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
+ if (priv->bss_started) {
+ memcpy(respbuf, priv->current_addr, MLAN_MAC_ADDR_LENGTH);
+ } else {
+ memset(respbuf, 0, MLAN_MAC_ADDR_LENGTH);
+ }
+ }
+#endif
+ ret = MLAN_MAC_ADDR_LENGTH;
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Set/Get Region Code
+ *
+ * @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.
+ */
+int
+woal_priv_region_code(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ int data = 0;
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_misc_cfg *cfg = NULL;
+ int ret = 0;
+ int user_data_len = 0, header_len = 0;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_REGION_CODE);
+ if (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;
+ }
+ 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_REGION;
+ req->req_id = MLAN_IOCTL_MISC_CFG;
+
+ if (user_data_len == 0)
+ req->action = MLAN_ACT_GET;
+ else {
+ cfg->param.region_code = (t_u32) data;
+ req->action = MLAN_ACT_SET;
+ }
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ memcpy(respbuf, (t_u8 *) & cfg->param.region_code, sizeof(data));
+ ret = sizeof(data);
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief Set/Get FW side mac address
+ *
+ * @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
+ */
+int
+woal_priv_fwmacaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ t_u8 data[ETH_ALEN];
+ int ret = 0;
+ int header_len = 0;
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_bss *bss = NULL;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_FWMACADDR);
+
+ /* Allocate an IOCTL request buffer */
+ req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ /* Fill request buffer */
+ bss = (mlan_ds_bss *) req->pbuf;
+ bss->sub_command = MLAN_OID_BSS_MAC_ADDR;
+ req->req_id = MLAN_IOCTL_BSS;
+
+ if (strlen(respbuf) == header_len) {
+ /* GET operation */
+ req->action = MLAN_ACT_GET;
+ } else {
+ /* SET operation */
+ req->action = MLAN_ACT_SET;
+ memset(data, 0, sizeof(data));
+ woal_mac2u8(data, respbuf + header_len);
+ memcpy(bss->param.mac_addr, data, ETH_ALEN);
+ }
+
+ /* Send IOCTL request to MLAN */
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ memcpy(respbuf, bss->param.mac_addr, sizeof(data));
+ ret = sizeof(data);
+ HEXDUMP("FW MAC Addr:", respbuf, ETH_ALEN);
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+#if defined(WIFI_DIRECT_SUPPORT)
+#ifdef STA_CFG80211
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+/**
+ * @brief Set offchannel
+ *
+ * @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
+ */
+int
+woal_priv_offchannel(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ int data[3];
+ int ret = 0;
+ t_u8 status = 1;
+ int user_data_len = 0, header_len = 0;
+
+ ENTER();
+
+ memset(data, 0, sizeof(data));
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_OFFCHANNEL);
+
+ if (header_len == strlen(respbuf)) {
+ /* Query current remain on channel status */
+ if (priv->phandle->remain_on_channel)
+ ret =
+ sprintf(respbuf,
+ "There is pending remain on channel from bss %d\n",
+ priv->phandle->remain_bss_index) + 1;
+ else
+ ret =
+ sprintf(respbuf, "There is no pending remain on channel\n") + 1;
+ goto done;
+ } else
+ parse_arguments(respbuf + header_len, data, sizeof(data) / sizeof(int),
+ &user_data_len);
+
+ if (sizeof(int) * user_data_len > sizeof(data)) {
+ PRINTM(MERROR, "Too many arguments\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (user_data_len >= 1) {
+ if ((data[0] != 0) && (data[0] != 1)) {
+ PRINTM(MERROR, "action (%d) must be either 0 or 1\n", data[0]);
+ ret = -EINVAL;
+ goto done;
+ }
+ }
+ if (user_data_len == 2) {
+ if (data[0] == 1) {
+ PRINTM(MERROR, "channel and duration must both the mentioned\n");
+ ret = -EINVAL;
+ goto done;
+ } else {
+ PRINTM(MWARN,
+ "extra arguments are ignored since action is 'cancel'\n");
+ }
+ }
+ if (user_data_len == 3) {
+ if (data[0] == 1) {
+ if (data[1] < 0) {
+ PRINTM(MERROR, "channel cannot be negative\n");
+ ret = -EINVAL;
+ goto done;
+ }
+ if (data[2] < 0) {
+ PRINTM(MERROR, "duration cannot be negative\n");
+ ret = -EINVAL;
+ goto done;
+ }
+ }
+ }
+
+ if (data[0] == 0) {
+ if (!priv->phandle->remain_on_channel) {
+ ret =
+ sprintf(respbuf,
+ "There is no pending remain on channel to be canceled\n")
+ + 1;
+ goto done;
+ }
+ if (woal_cfg80211_remain_on_channel_cfg
+ (priv, MOAL_IOCTL_WAIT, MTRUE, &status, NULL, 0, 0)) {
+ PRINTM(MERROR, "remain_on_channel: Failed to cancel\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ if (status == MLAN_STATUS_SUCCESS)
+ priv->phandle->remain_on_channel = MFALSE;
+ } else if (data[0] == 1) {
+ if (woal_cfg80211_remain_on_channel_cfg
+ (priv, MOAL_IOCTL_WAIT, MFALSE, &status,
+ ieee80211_get_channel(priv->wdev->wiphy,
+ ieee80211_channel_to_frequency(data[1]
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) || defined(COMPAT_WIRELESS)
+ ,
+ (data[1] <=
+ 14 ?
+ IEEE80211_BAND_2GHZ
+ :
+ IEEE80211_BAND_5GHZ)
+#endif
+ )), 0, (t_u32) data[2])) {
+ PRINTM(MERROR, "remain_on_channel: Failed to start\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ if (status == MLAN_STATUS_SUCCESS) {
+ priv->phandle->remain_on_channel = MTRUE;
+ priv->phandle->remain_bss_index = priv->bss_index;
+ }
+ }
+
+ if (status != MLAN_STATUS_SUCCESS)
+ ret = -EFAULT;
+ else
+ ret = sprintf(respbuf, "OK\n") + 1;
+
+ done:
+ LEAVE();
+ return ret;
+}
+#endif
+#endif
+#endif
+
+#if defined(STA_SUPPORT)
+/**
+ * @brief Make PMF bit required/optional
+ * @param priv Pointer to moal_private structure
+ * @param respbuf Pointer to response buffer
+ * @param resplen Response buffer length
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_priv_set_get_pmfcfg(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen)
+{
+ int data[2] = { 0, 0 };
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_misc_cfg *cfg = NULL;
+ mlan_ds_misc_pmfcfg *pmfcfg;
+ int ret = 0;
+ int user_data_len = 0, header_len = 0;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_PMFCFG);
+ if (strlen(respbuf) == header_len) {
+ /* GET operation */
+ user_data_len = 0;
+ } else {
+ /* SET operation */
+ parse_arguments(respbuf + header_len, data, sizeof(data) / sizeof(int),
+ &user_data_len);
+ }
+
+ if (user_data_len > 2) {
+ PRINTM(MERROR, "Invalid number of arguments\n");
+ ret = -EINVAL;
+ goto done;
+ }
+ 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;
+ pmfcfg = (mlan_ds_misc_pmfcfg *) & cfg->param.pmfcfg;
+ cfg->sub_command = MLAN_OID_MISC_PMFCFG;
+ req->req_id = MLAN_IOCTL_MISC_CFG;
+
+ if (user_data_len == 0)
+ req->action = MLAN_ACT_GET;
+ else {
+ pmfcfg->mfpc = (t_u8) data[0];
+ pmfcfg->mfpr = (t_u8) data[1];
+ req->action = MLAN_ACT_SET;
+ }
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ memcpy(respbuf, (t_u8 *) & cfg->param.pmfcfg, sizeof(mlan_ds_misc_pmfcfg));
+ ret = sizeof(mlan_ds_misc_pmfcfg);
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+#endif
+
+/**
+ * @brief Get/Set inactivity timeout extend
+ * @param priv Pointer to moal_private structure
+ * @param respbuf Pointer to response buffer
+ * @param resplen Response buffer length
+ *
+ * @return Number of bytes written, negative for failure.
+ */
+static int
+woal_priv_inactivity_timeout_ext(moal_private * priv, t_u8 * respbuf,
+ t_u32 respbuflen)
+{
+ int data[4];
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_pm_cfg *pmcfg = NULL;
+ pmlan_ds_inactivity_to inac_to = NULL;
+ int ret = 0;
+ int user_data_len = 0, header_len = 0;
+
+ ENTER();
+
+ header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_INACTIVITYTO);
+ memset(data, 0, sizeof(data));
+ if (strlen(respbuf) == header_len) {
+ /* GET operation */
+ user_data_len = 0;
+ } else {
+ /* SET operation */
+ parse_arguments(respbuf + header_len, data, sizeof(data) / sizeof(int),
+ &user_data_len);
+ }
+
+ if (user_data_len != 0 && user_data_len != 3 && user_data_len != 4) {
+ PRINTM(MERROR, "Invalid number of parameters\n");
+ ret = -EINVAL;
+ goto done;
+ }
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
+ inac_to = &pmcfg->param.inactivity_to;
+ pmcfg->sub_command = MLAN_OID_PM_CFG_INACTIVITY_TO;
+ req->req_id = MLAN_IOCTL_PM_CFG;
+ req->action = MLAN_ACT_GET;
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ if (user_data_len) {
+ inac_to->timeout_unit = data[0];
+ inac_to->unicast_timeout = data[1];
+ inac_to->mcast_timeout = data[2];
+ if (user_data_len == 4)
+ inac_to->ps_entry_timeout = data[3];
+ req->action = MLAN_ACT_SET;
+
+ if (MLAN_STATUS_SUCCESS !=
+ woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
+ }
+ } else {
+ data[0] = inac_to->timeout_unit;
+ data[1] = inac_to->unicast_timeout;
+ data[2] = inac_to->mcast_timeout;
+ data[3] = inac_to->ps_entry_timeout;
+
+ memcpy(respbuf, (t_u8 *) data, sizeof(data));
+ ret = sizeof(data);
+ }
+
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
* @brief Set priv command for Android
* @param dev A pointer to net_device structure
* @param req A pointer to ifreq structure
@@ -4561,7 +5649,8 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
ret = -ENOMEM;
goto done;
}
- if (copy_from_user(buf, priv_cmd.buf, priv_cmd.total_len)) {
+ if (copy_from_user
+ (buf, priv_cmd.buf, MIN((CMD_BUF_LEN - 1), priv_cmd.total_len))) {
ret = -EFAULT;
goto done;
}
@@ -4655,6 +5744,15 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
/* Set/Get tx rate cfg */
len = woal_setget_priv_txratecfg(priv, buf, priv_cmd.total_len);
goto handled;
+#ifdef STA_SUPPORT
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_GETLOG,
+ strlen(PRIV_CMD_GETLOG)) == 0) {
+ /* Get wireless stats information */
+ len = woal_get_priv_getlog(priv, buf, priv_cmd.total_len);
+ goto handled;
+#endif
} else
if (strnicmp
(buf + strlen(CMD_MARVELL), PRIV_CMD_CUSTOMIE,
@@ -4732,6 +5830,13 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
/* Get scan table */
len = woal_priv_getscantable(priv, buf, priv_cmd.total_len);
goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_EXTCAPCFG,
+ strlen(PRIV_CMD_EXTCAPCFG)) == 0) {
+ /* Extended capabilities configure */
+ len = woal_priv_extcapcfg(priv, buf, priv_cmd.total_len);
+ goto handled;
#endif
} else
if (strnicmp
@@ -4881,6 +5986,13 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
/* Get power management parameters */
len = woal_priv_get_power(priv, buf, priv_cmd.total_len);
goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_PSMODE,
+ strlen(PRIV_CMD_PSMODE)) == 0) {
+ /* Set/Get PS mode */
+ len = woal_priv_set_get_psmode(priv, buf, priv_cmd.total_len);
+ goto handled;
#endif
} else
if (strnicmp
@@ -4963,6 +6075,123 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
woal_priv_mgmt_frame_passthru_ctrl(priv, buf,
priv_cmd.total_len);
goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_QCONFIG,
+ strlen(PRIV_CMD_QCONFIG)) == 0) {
+ /* Queue config */
+ len = woal_priv_qconfig(priv, buf, priv_cmd.total_len);
+ goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_ADDTS,
+ strlen(PRIV_CMD_ADDTS)) == 0) {
+ /* Send an ADDTS TSPEC */
+ len = woal_priv_wmm_addts_req_ioctl(priv, buf, priv_cmd.total_len);
+ goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_DELTS,
+ strlen(PRIV_CMD_DELTS)) == 0) {
+ /* Send a DELTS TSPE */
+ len = woal_priv_wmm_delts_req_ioctl(priv, buf, priv_cmd.total_len);
+ goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_QSTATUS,
+ strlen(PRIV_CMD_QSTATUS)) == 0) {
+ /* Get the status of the WMM queues */
+ len =
+ woal_priv_wmm_queue_status_ioctl(priv, buf, priv_cmd.total_len);
+ goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_TS_STATUS,
+ strlen(PRIV_CMD_TS_STATUS)) == 0) {
+ /* Get the status of the WMM Traffic Streams */
+ len = woal_priv_wmm_ts_status_ioctl(priv, buf, priv_cmd.total_len);
+ goto handled;
+#ifdef STA_SUPPORT
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_QOS_CFG,
+ strlen(PRIV_CMD_QOS_CFG)) == 0) {
+ t_u32 action = MLAN_ACT_GET;
+ if (strlen(buf) == strlen(CMD_MARVELL) + strlen(PRIV_CMD_QOS_CFG)) {
+ pdata = buf; /* GET operation */
+ } else {
+ pdata = buf + strlen(CMD_MARVELL) + strlen(PRIV_CMD_QOS_CFG);
+ action = MLAN_ACT_SET; /* SET operation */
+ }
+ if (MLAN_STATUS_SUCCESS != woal_priv_qos_cfg(priv, action, pdata)) {
+ ret = -EFAULT;
+ goto done;
+ }
+ if (action == MLAN_ACT_GET)
+ len = sizeof(t_u8);
+ goto handled;
+#endif
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_MAC_CTRL,
+ strlen(PRIV_CMD_MAC_CTRL)) == 0) {
+ /* MAC CTRL */
+ len = woal_priv_macctrl(priv, buf, priv_cmd.total_len);
+ goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_GETWAP,
+ strlen(PRIV_CMD_GETWAP)) == 0) {
+ /* Get WAP */
+ len = woal_priv_getwap(priv, buf, priv_cmd.total_len);
+ goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_REGION_CODE,
+ strlen(PRIV_CMD_REGION_CODE)) == 0) {
+ /* Region Code */
+ len = woal_priv_region_code(priv, buf, priv_cmd.total_len);
+ goto handled;
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_FWMACADDR,
+ strlen(PRIV_CMD_FWMACADDR)) == 0) {
+ /* Set FW MAC address */
+ len = woal_priv_fwmacaddr(priv, buf, priv_cmd.total_len);
+ goto handled;
+#if defined(WIFI_DIRECT_SUPPORT)
+#ifdef STA_CFG80211
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_OFFCHANNEL,
+ strlen(PRIV_CMD_OFFCHANNEL)) == 0) {
+ if (IS_STA_CFG80211(cfg80211_wext)) {
+ /* Set offchannel */
+ len = woal_priv_offchannel(priv, buf, priv_cmd.total_len);
+ } else
+ len = sprintf(buf, "CFG80211 is not enabled\n") + 1;
+ goto handled;
+#endif
+#endif
+#endif
+#if defined(STA_SUPPORT)
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_PMFCFG,
+ strlen(PRIV_CMD_PMFCFG)) == 0) {
+ /* Configure PMF */
+ len = woal_priv_set_get_pmfcfg(priv, buf, priv_cmd.total_len);
+ goto handled;
+#endif
+ } else
+ if (strnicmp
+ (buf + strlen(CMD_MARVELL), PRIV_CMD_INACTIVITYTO,
+ strlen(PRIV_CMD_INACTIVITYTO)) == 0) {
+ /* Get/Set inactivity timeout extend */
+ len =
+ woal_priv_inactivity_timeout_ext(priv, buf, priv_cmd.total_len);
+ goto handled;
} else {
/* Fall through, after stripping off the custom header */
buf += strlen(CMD_MARVELL);
@@ -4971,7 +6200,8 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
#ifdef STA_SUPPORT
if (strncmp(buf, "RSSILOW-THRESHOLD", strlen("RSSILOW-THRESHOLD")) == 0) {
pdata = buf + strlen("RSSILOW-THRESHOLD") + 1;
- if (MLAN_STATUS_SUCCESS != woal_set_rssi_low_threshold(priv, pdata)) {
+ if (MLAN_STATUS_SUCCESS !=
+ woal_set_rssi_low_threshold(priv, pdata, MOAL_IOCTL_WAIT)) {
ret = -EFAULT;
goto done;
}
@@ -5048,16 +6278,44 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "POWERMODE", strlen("POWERMODE")) == 0) {
pdata = buf + strlen("POWERMODE") + 1;
- if (MLAN_STATUS_SUCCESS != woal_set_powermode(priv, pdata)) {
- ret = -EFAULT;
- goto done;
+ if (!hw_test) {
+ if (MLAN_STATUS_SUCCESS != woal_set_powermode(priv, pdata)) {
+ ret = -EFAULT;
+ goto done;
+ }
+ }
+ len = sprintf(buf, "OK\n") + 1;
+ } else if (strncmp(buf, "SETROAMING", strlen("SETROAMING")) == 0) {
+ pdata = buf + strlen("SETROAMING") + 1;
+#ifdef STA_CFG80211
+ if (*pdata == '1') {
+ priv->roaming_enabled = MTRUE;
+ PRINTM(MIOCTL, "Roaming enabled\n");
+ } else if (*pdata == '0') {
+ priv->roaming_enabled = MFALSE;
+ PRINTM(MIOCTL, "Roaming disabled\n");
}
+#endif
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "COUNTRY", strlen("COUNTRY")) == 0) {
+ if ((strlen(buf) - strlen("COUNTRY") - 1) > COUNTRY_CODE_LEN
+ || (strlen(buf) - strlen("COUNTRY") - 1) <= 0) {
+ PRINTM(MERROR, "Invalid country length\n");
+ ret = -EFAULT;
+ goto done;
+ }
memset(country_code, 0, sizeof(country_code));
memcpy(country_code, buf + strlen("COUNTRY") + 1,
strlen(buf) - strlen("COUNTRY") - 1);
PRINTM(MIOCTL, "Set COUNTRY %s\n", country_code);
+#ifdef STA_CFG80211
+ if (IS_STA_CFG80211(cfg80211_wext)) {
+ PRINTM(MIOCTL, "Notify country code=%s\n", country_code);
+ regulatory_hint(priv->wdev->wiphy, country_code);
+ len = sprintf(buf, "OK\n") + 1;
+ goto done;
+ }
+#endif
if (MLAN_STATUS_SUCCESS != woal_set_region_code(priv, country_code)) {
ret = -EFAULT;
goto done;
@@ -5117,6 +6375,9 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
else if (strncmp(buf, "SETSUSPENDOPT", strlen("SETSUSPENDOPT")) == 0) {
/* it will be done by GUI */
len = sprintf(buf, "OK\n") + 1;
+ } else if (strncmp(buf, "SETSUSPENDMODE", strlen("SETSUSPENDMODE")) == 0) {
+ /* it will be done by GUI */
+ len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) {
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "BTCOEXSCAN-START", strlen("BTCOEXSCAN-START")) ==
@@ -5139,7 +6400,7 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "BGSCAN-STOP", strlen("BGSCAN-STOP")) == 0) {
if (priv->bg_scan_start && !priv->scan_cfg.rssi_threshold) {
- if (MLAN_STATUS_SUCCESS != woal_stop_bg_scan(priv)) {
+ if (MLAN_STATUS_SUCCESS != woal_stop_bg_scan(priv, MOAL_NO_WAIT)) {
ret = -EFAULT;
goto done;
}
@@ -5166,7 +6427,7 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
else if (strncmp(buf, "GET_EVENT", strlen("GET_EVENT")) == 0) {
if (IS_STA_CFG80211(cfg80211_wext)) {
if (priv->last_event & EVENT_BG_SCAN_REPORT)
- woal_inform_bss_from_scan_result(priv, NULL);
+ woal_inform_bss_from_scan_result(priv, NULL, MOAL_IOCTL_WAIT);
}
len = sprintf(buf, "EVENT=%d\n", priv->last_event) + 1;
priv->last_event = 0;
@@ -5190,10 +6451,12 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "QOSINFO", strlen("QOSINFO")) == 0) {
pdata = buf + strlen("QOSINFO") + 1;
- if (MLAN_STATUS_SUCCESS != woal_set_qos_cfg(priv, pdata)) {
+#ifdef STA_SUPPORT
+ if (MLAN_STATUS_SUCCESS != woal_priv_qos_cfg(priv, MLAN_ACT_SET, pdata)) {
ret = -EFAULT;
goto done;
}
+#endif
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "SLEEPPD", strlen("SLEEPPD")) == 0) {
pdata = buf + strlen("SLEEPPD") + 1;
@@ -5209,6 +6472,7 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
"SET_AP_WPS_P2P_IE 2" -- proberesp IE "SET_AP_WPS_P2P_IE 4" --
assocresp IE */
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)
if (MLAN_STATUS_SUCCESS != woal_set_ap_wps_p2p_ie(priv, (t_u8 *) pdata,
priv_cmd.used_len -
strlen
@@ -5218,6 +6482,7 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
goto done;
}
#endif
+#endif
len = sprintf(buf, "OK\n") + 1;
}
#endif
@@ -5258,8 +6523,9 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
ret = -EFAULT;
}
} else {
- PRINTM(MERROR, "%s: the buffer supplied by appl is too small.\n",
- __FUNCTION__);
+ PRINTM(MERROR,
+ "%s: the buffer supplied by appl is too small (supplied: %d, used: %d)\n",
+ __FUNCTION__, priv_cmd.total_len, priv_cmd.used_len);
ret = -EFAULT;
}
} else {
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h b/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h
index 4dbc0f073098..d755b0d72099 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h
@@ -54,6 +54,7 @@ Change log:
#define PRIV_CMD_REJECTADDBAREQ "rejectaddbareq"
#define PRIV_CMD_DATARATE "getdatarate"
#define PRIV_CMD_TXRATECFG "txratecfg"
+#define PRIV_CMD_GETLOG "getlog"
#define PRIV_CMD_ESUPPMODE "esuppmode"
#define PRIV_CMD_PASSPHRASE "passphrase"
#define PRIV_CMD_DEAUTH "deauth"
@@ -70,6 +71,7 @@ Change log:
#ifdef STA_SUPPORT
#define PRIV_CMD_GETSCANTABLE "getscantable"
#define PRIV_CMD_SETUSERSCAN "setuserscan"
+#define PRIV_CMD_EXTCAPCFG "extcapcfg"
#endif
#define PRIV_CMD_DEEPSLEEP "deepsleep"
#define PRIV_CMD_IPADDR "ipaddr"
@@ -98,6 +100,7 @@ Change log:
#define PRIV_CMD_SET_AUTH "setauth"
#define PRIV_CMD_GET_AP "getap"
#define PRIV_CMD_GET_POWER "getpower"
+#define PRIV_CMD_PSMODE "psmode"
#endif
#define PRIV_CMD_WARMRESET "warmreset"
#define PRIV_CMD_TXPOWERCFG "txpowercfg"
@@ -110,6 +113,23 @@ Change log:
#define PRIV_CMD_SDCMD52RW "sdcmd52rw"
#define PRIV_CMD_ARPFILTER "arpfilter"
#define PRIV_CMD_MGMT_FRAME_CTRL "mgmtframectrl"
+#define PRIV_CMD_QCONFIG "qconfig"
+#define PRIV_CMD_ADDTS "addts"
+#define PRIV_CMD_DELTS "delts"
+#define PRIV_CMD_QSTATUS "qstatus"
+#define PRIV_CMD_TS_STATUS "ts_status"
+#define PRIV_CMD_QOS_CFG "qoscfg"
+#define PRIV_CMD_MAC_CTRL "macctrl"
+#define PRIV_CMD_GETWAP "getwap"
+#define PRIV_CMD_REGION_CODE "regioncode"
+#define PRIV_CMD_FWMACADDR "fwmacaddr"
+#if defined(WIFI_DIRECT_SUPPORT)
+#define PRIV_CMD_OFFCHANNEL "offchannel"
+#endif
+#if defined(STA_SUPPORT)
+#define PRIV_CMD_PMFCFG "pmfcfg"
+#endif
+#define PRIV_CMD_INACTIVITYTO "inactivityto"
/** Private command ID for Android default commands */
#define WOAL_ANDROID_DEF_CMD (SIOCDEVPRIVATE + 1)
@@ -163,6 +183,10 @@ typedef struct _android_wifi_priv_cmd
#define MW_MODE_MONITOR 6 /* Passive monitor (listen only) */
#define MW_MODE_MESH 7 /* Mesh (IEEE 802.11s) network */
+#define MW_POWER_TYPE 0xF000 /* Type of parameter */
+#define MW_POWER_PERIOD 0x1000 /* Value is a period/duration of */
+#define MW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */
+
#define MW_AUTH_INDEX 0x0FFF
#define MW_AUTH_FLAGS 0xF000
#define MW_AUTH_WPA_VERSION 0
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_ioctl.c b/drivers/net/wireless/sd8797/mlinux/moal_ioctl.c
index fa288c9ce517..07188725a47b 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_ioctl.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_ioctl.c
@@ -80,13 +80,25 @@ static region_code_mapping_t region_code_mapping[] = {
{"CN ", 0x50}, /* China */
{"JP ", 0xFF}, /* Japan special */
};
+
+/** EEPROM Region code mapping table */
+static region_code_mapping_t hw_region_code_mapping[] = {
+ {"US ", 0x10}, /* US FCC */
+ {"CA ", 0x20}, /* IC Canada */
+ {"KR ", 0x30}, /* Korea */
+ {"CN ", 0x50}, /* China */
+ {"ES ", 0x31}, /* Spain */
+ {"FR ", 0x32}, /* France */
+ {"JP ", 0x40}, /* Japan */
+ {"JP ", 0x41}, /* Japan */
+};
#endif
/********************************************************
Global Variables
********************************************************/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
#ifdef UAP_SUPPORT
/** Network device handlers for uAP */
extern const struct net_device_ops woal_uap_netdev_ops;
@@ -127,6 +139,40 @@ region_string_2_region_code(char *region_string)
LEAVE();
return (region_code_mapping[0].code);
}
+
+/**
+ * @brief This function converts region string to region code
+ *
+ * @param region_code region code
+ *
+ * @return Region string or NULL
+ */
+char *
+region_code_2_string(t_u8 region_code)
+{
+ t_u8 i;
+ t_u8 size = sizeof(hw_region_code_mapping) / sizeof(region_code_mapping_t);
+
+ ENTER();
+ for (i = 0; i < size; i++) {
+ if (hw_region_code_mapping[i].code == region_code) {
+ LEAVE();
+ return hw_region_code_mapping[i].region;
+ }
+ }
+ LEAVE();
+ return NULL;
+}
+
+t_u8
+woal_is_valid_alpha2(char *alpha2)
+{
+ if (!alpha2 || strlen(alpha2) < 2)
+ return MFALSE;
+ if (isalpha(alpha2[0]) && isalpha(alpha2[1]))
+ return MTRUE;
+ return MFALSE;
+}
#endif
/**
@@ -185,9 +231,11 @@ woal_fill_wait_queue(moal_private * priv, wait_queue * wait, t_u8 wait_option)
case MOAL_CMD_WAIT:
wait->wait = &priv->cmd_wait_q;
break;
+#ifdef CONFIG_PROC_FS
case MOAL_PROC_WAIT:
wait->wait = &priv->proc_wait_q;
break;
+#endif
#if defined(STA_WEXT) || defined(UAP_WEXT)
case MOAL_WSTATS_WAIT:
if (IS_STA_OR_UAP_WEXT(cfg80211_wext))
@@ -221,18 +269,21 @@ woal_wait_ioctl_complete(moal_private * priv, mlan_ioctl_req * req,
case MOAL_NO_WAIT:
break;
case MOAL_IOCTL_WAIT:
- wait_event_interruptible(priv->ioctl_wait_q, wait->condition);
+ wait_event_interruptible_exclusive(priv->ioctl_wait_q, wait->condition);
break;
case MOAL_CMD_WAIT:
- wait_event_interruptible(priv->cmd_wait_q, wait->condition);
+ wait_event_interruptible_exclusive(priv->cmd_wait_q, wait->condition);
break;
+#ifdef CONFIG_PROC_FS
case MOAL_PROC_WAIT:
- wait_event_interruptible(priv->proc_wait_q, wait->condition);
+ wait_event_interruptible_exclusive(priv->proc_wait_q, wait->condition);
break;
+#endif
#if defined(STA_WEXT) || defined(UAP_WEXT)
case MOAL_WSTATS_WAIT:
if (IS_STA_OR_UAP_WEXT(cfg80211_wext))
- wait_event_interruptible(priv->w_stats_wait_q, wait->condition);
+ wait_event_interruptible_exclusive(priv->w_stats_wait_q,
+ wait->condition);
break;
#endif
}
@@ -394,7 +445,7 @@ woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req, t_u8 wait_option)
priv->phandle->cac_period == MTRUE) {
t_u32 sub_command;
/* CAC checking period left to complete jiffies */
- unsigned long cac_left_jiffies;
+ long cac_left_jiffies;
sub_command = *(t_u32 *) req->pbuf;
@@ -467,6 +518,7 @@ woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req, t_u8 wait_option)
req->reserved_1 = 0;
/* Call MLAN ioctl handle */
+ atomic_inc(&priv->phandle->ioctl_pending);
spin_lock_irqsave(&priv->phandle->driver_lock, flags);
status = mlan_ioctl(priv->phandle->pmlan_adapter, req);
spin_unlock_irqrestore(&priv->phandle->driver_lock, flags);
@@ -476,7 +528,6 @@ woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req, t_u8 wait_option)
"IOCTL pending: %p id=0x%x, sub_id=0x%x wait_option=%d, action=%d\n",
req, req->req_id, (*(t_u32 *) req->pbuf), wait_option,
(int) req->action);
- atomic_inc(&priv->phandle->ioctl_pending);
/* Status pending, wake up main process */
queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
@@ -494,6 +545,7 @@ woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req, t_u8 wait_option)
req, req->req_id, (*(t_u32 *) req->pbuf), wait_option,
(int) req->action, status);
default:
+ atomic_dec(&priv->phandle->ioctl_pending);
break;
}
@@ -536,11 +588,6 @@ woal_request_set_mac_address(moal_private * priv)
status = woal_request_ioctl(priv, req, MOAL_CMD_WAIT);
if (status == MLAN_STATUS_SUCCESS) {
memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
-#if defined(STA_CFG80211) || defined(UAP_CFG80211)
- if (IS_STA_OR_UAP_CFG80211(cfg80211_wext) && priv->wdev &&
- priv->wdev->wiphy)
- memcpy(priv->wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN);
-#endif
HEXDUMP("priv->MacAddr:", priv->current_addr, ETH_ALEN);
} else {
PRINTM(MERROR, "set mac address failed! status=%d, error_code=0x%x\n",
@@ -673,8 +720,12 @@ woal_bss_start(moal_private * priv, t_u8 wait_option,
ENTER();
- /* Stop the O.S. TX queue if needed */
+ /* Stop the O.S. TX queue When we are roaming */
woal_stop_queue(priv->netdev);
+ if (priv->media_connected == MFALSE) {
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
+ }
/* Allocate an IOCTL request buffer */
req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
@@ -693,7 +744,11 @@ woal_bss_start(moal_private * priv, t_u8 wait_option,
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, wait_option);
-
+#ifdef STA_CFG80211
+#ifdef STA_SUPPORT
+ priv->assoc_status = req->status_code;
+#endif
+#endif
done:
if (req)
kfree(req);
@@ -714,7 +769,6 @@ mlan_status
woal_get_bss_info(moal_private * priv, t_u8 wait_option,
mlan_bss_info * bss_info)
{
- int ret = 0;
mlan_ioctl_req *req = NULL;
mlan_ds_get_info *info = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
@@ -723,7 +777,8 @@ woal_get_bss_info(moal_private * priv, t_u8 wait_option,
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
if (req == NULL) {
- ret = -ENOMEM;
+ PRINTM(MERROR, "Fail to allocate the buffer for get bss_info\n");
+ status = MLAN_STATUS_FAILURE;
goto done;
}
@@ -736,9 +791,8 @@ woal_get_bss_info(moal_private * priv, t_u8 wait_option,
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, wait_option);
if (status == MLAN_STATUS_SUCCESS) {
- if (bss_info) {
+ if (bss_info)
memcpy(bss_info, &info->param.bss_info, sizeof(mlan_bss_info));
- }
}
done:
if (req && (status != MLAN_STATUS_PENDING))
@@ -1076,11 +1130,11 @@ woal_set_get_power_mgmt(moal_private * priv,
pm_cfg->param.ps_mode = 0;
else {
/* Check not support case only (vwrq->disabled == FALSE) */
- if ((power_type & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+ if ((power_type & MW_POWER_TYPE) == MW_POWER_TIMEOUT) {
PRINTM(MERROR, "Setting power timeout is not supported\n");
ret = MLAN_STATUS_FAILURE;
goto done;
- } else if ((power_type & IW_POWER_TYPE) == IW_POWER_PERIOD) {
+ } else if ((power_type & MW_POWER_TYPE) == MW_POWER_PERIOD) {
PRINTM(MERROR, "Setting power period is not supported\n");
ret = MLAN_STATUS_FAILURE;
goto done;
@@ -1199,6 +1253,49 @@ woal_set_get_data_rate(moal_private * priv,
LEAVE();
return ret;
}
+
+/**
+ * @brief Get assoc_resp buffer
+ *
+ * @param priv A pointer to moal_private structure
+ * @param assoc_rsp A pointer to mlan_ds_misc_assoc_rsp structure
+ *
+ * @return MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_get_assoc_rsp(moal_private * priv, mlan_ds_misc_assoc_rsp * assoc_rsp)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ mlan_ds_misc_cfg *misc = NULL;
+ mlan_ioctl_req *req = NULL;
+
+ ENTER();
+
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+ if (req == NULL) {
+ PRINTM(MERROR, "Fail to allocate buffer for get assoc resp\n");
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+
+ req->req_id = MLAN_IOCTL_MISC_CFG;
+ misc = (pmlan_ds_misc_cfg) req->pbuf;
+ misc->sub_command = MLAN_OID_MISC_ASSOC_RSP;
+ req->action = MLAN_ACT_GET;
+
+ if (MLAN_STATUS_SUCCESS == woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ if (assoc_rsp)
+ memcpy(assoc_rsp, &misc->param.assoc_resp,
+ sizeof(mlan_ds_misc_assoc_rsp));
+ } else {
+ ret = MLAN_STATUS_FAILURE;
+ }
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
#endif
/**
@@ -1241,11 +1338,6 @@ woal_request_get_fw_info(moal_private * priv, t_u8 wait_option,
memcpy(priv->current_addr, &info->param.fw_info.mac_addr,
sizeof(mlan_802_11_mac_addr));
memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
-#if defined(STA_CFG80211) || defined(UAP_CFG80211)
- if (IS_STA_OR_UAP_CFG80211(cfg80211_wext) && priv->wdev &&
- priv->wdev->wiphy)
- memcpy(priv->wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN);
-#endif
if (fw_info)
memcpy(fw_info, &info->param.fw_info, sizeof(mlan_fw_info));
DBG_HEXDUMP(MCMD_D, "mac", priv->current_addr, 6);
@@ -1702,6 +1794,7 @@ woal_send_host_packet(struct net_device *dev, struct ifreq *req)
/**
* @brief Set/Get CUSTOM_IE ioctl handler
*
+ * @param priv A pointer to moal_private structure
* @param mask Mask to set or clear from caller
* @param ie IE buffer to set for beacon
* @param ie_len Length of the IE
@@ -1780,7 +1873,6 @@ woal_get_bss_type(struct net_device *dev, struct ifreq *req)
return ret;
}
-#if defined(WIFI_DIRECT_SUPPORT)
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
/**
* @brief Swithces BSS role of interface
@@ -1838,7 +1930,7 @@ woal_bss_role_cfg(moal_private * priv, t_u8 action,
if (*bss_role == MLAN_BSS_ROLE_UAP) {
/* Switch: STA -> uAP */
/* Setup the OS Interface to our functions */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29)
dev->do_ioctl = woal_uap_do_ioctl;
dev->set_multicast_list = woal_uap_set_multicast_list;
#else
@@ -1846,20 +1938,18 @@ woal_bss_role_cfg(moal_private * priv, t_u8 action,
#endif
#ifdef UAP_WEXT
if (IS_UAP_WEXT(cfg80211_wext)) {
-#ifdef WIRELESS_EXT
#if WIRELESS_EXT < 21
dev->get_wireless_stats = woal_get_uap_wireless_stats;
#endif
dev->wireless_handlers =
(struct iw_handler_def *) &woal_uap_handler_def;
-#endif /* WIRELESS_EXT */
init_waitqueue_head(&priv->w_stats_wait_q);
}
#endif /* UAP_WEXT */
} else if (*bss_role == MLAN_BSS_ROLE_STA) {
/* Switch: uAP -> STA */
/* Setup the OS Interface to our functions */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29)
dev->do_ioctl = woal_do_ioctl;
dev->set_multicast_list = woal_set_multicast_list;
#else
@@ -1867,13 +1957,11 @@ woal_bss_role_cfg(moal_private * priv, t_u8 action,
#endif
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext)) {
-#ifdef WIRELESS_EXT
#if WIRELESS_EXT < 21
dev->get_wireless_stats = woal_get_wireless_stats;
#endif
dev->wireless_handlers =
(struct iw_handler_def *) &woal_handler_def;
-#endif
init_waitqueue_head(&priv->w_stats_wait_q);
}
#endif /* STA_WEXT */
@@ -1911,9 +1999,11 @@ woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq)
ret = -EFAULT;
goto done;
}
- if ((bss_role != MLAN_BSS_ROLE_STA &&
- bss_role != MLAN_BSS_ROLE_UAP) ||
- (priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT)) {
+ if ((bss_role != MLAN_BSS_ROLE_STA && bss_role != MLAN_BSS_ROLE_UAP)
+#if defined(WIFI_DIRECT_SUPPORT)
+ || (priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT)
+#endif
+ ) {
PRINTM(MWARN, "Invalid BSS role\n");
ret = -EINVAL;
goto done;
@@ -1942,6 +2032,10 @@ woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq)
}
wrq->u.data.length = 1;
} else {
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+ if (IS_STA_OR_UAP_CFG80211(cfg80211_wext))
+ woal_clear_all_mgmt_ies(priv);
+#endif
/* Initialize private structures */
woal_init_priv(priv, MOAL_IOCTL_WAIT);
@@ -1956,7 +2050,71 @@ woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq)
}
#endif /* STA_WEXT || UAP_WEXT */
#endif /* STA_SUPPORT && UAP_SUPPORT */
-#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+
+/**
+ * @brief Set auto arp resp
+ *
+ * @param handle A pointer to moal_handle structure
+ * @param enable enable/disable
+ *
+ * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, otherwise fail
+ */
+static mlan_status
+woal_set_auto_arp(moal_handle * handle, t_u8 enable)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ int i = 0;
+ moal_private *priv = NULL;
+ mlan_ds_misc_cfg *misc = NULL;
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_misc_ipaddr_cfg ipaddr_cfg;
+
+ ENTER();
+
+ memset(&ipaddr_cfg, 0, sizeof(ipaddr_cfg));
+ for (i = 0; i < handle->priv_num && (priv = handle->priv[i]); i++) {
+ if (priv->ip_addr_type != IPADDR_TYPE_NONE) {
+ memcpy(ipaddr_cfg.ip_addr[ipaddr_cfg.ip_addr_num], priv->ip_addr,
+ IPADDR_LEN);
+ ipaddr_cfg.ip_addr_num++;
+ }
+ }
+ if (ipaddr_cfg.ip_addr_num == 0) {
+ PRINTM(MIOCTL, "No IP addr configured.\n");
+ goto done;
+ }
+
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+ if (req == NULL) {
+ PRINTM(MIOCTL, "IOCTL req allocated failed!\n");
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ misc = (mlan_ds_misc_cfg *) req->pbuf;
+ misc->sub_command = MLAN_OID_MISC_IP_ADDR;
+ req->req_id = MLAN_IOCTL_MISC_CFG;
+ req->action = MLAN_ACT_SET;
+ memcpy(&misc->param.ipaddr_cfg, &ipaddr_cfg, sizeof(ipaddr_cfg));
+ if (enable) {
+ misc->param.ipaddr_cfg.op_code = MLAN_IPADDR_OP_ARP_FILTER |
+ MLAN_IPADDR_OP_AUTO_ARP_RESP;
+ misc->param.ipaddr_cfg.ip_addr_type = IPADDR_TYPE_IPV4;
+ } else {
+ /** remove ip */
+ misc->param.ipaddr_cfg.op_code = MLAN_IPADDR_OP_IP_REMOVE;
+ }
+ ret =
+ woal_request_ioctl(woal_get_priv(handle, MLAN_BSS_ROLE_ANY), req,
+ MOAL_NO_WAIT);
+ if (ret != MLAN_STATUS_SUCCESS && ret != MLAN_STATUS_PENDING) {
+ PRINTM(MIOCTL, "Set auto arp IOCTL failed!\n");
+ }
+ done:
+ if (req && (ret != MLAN_STATUS_PENDING))
+ kfree(req);
+ LEAVE();
+ return ret;
+}
/**
* @brief Get Host Sleep parameters
@@ -2029,6 +2187,9 @@ woal_cancel_hs(moal_private * priv, t_u8 wait_option)
hscfg.is_invoke_hostcmd = MTRUE;
ret = woal_set_get_hs_params(priv, MLAN_ACT_SET, wait_option, &hscfg);
+ /* remove auto arp from FW */
+ woal_set_auto_arp(priv->phandle, MFALSE);
+
LEAVE();
return ret;
}
@@ -2062,9 +2223,45 @@ woal_enable_hs(moal_private * priv)
hs_actived = MTRUE;
goto done;
}
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+ /* cancel pending remain on channel */
+ if (priv->phandle->remain_on_channel) {
+ t_u8 channel_status;
+ moal_private *remain_priv =
+ priv->phandle->priv[priv->phandle->remain_bss_index];
+ if (remain_priv) {
+ woal_cfg80211_remain_on_channel_cfg(remain_priv, MOAL_NO_WAIT,
+ MTRUE, &channel_status, NULL, 0,
+ 0);
+ if (priv->phandle->cookie) {
+ cfg80211_remain_on_channel_expired(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+ remain_priv->netdev,
+#else
+ remain_priv->wdev,
+#endif
+ priv->phandle->cookie,
+ &priv->phandle->chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ priv->phandle->
+ channel_type,
+#endif
+ GFP_ATOMIC);
+ priv->phandle->cookie = 0;
+ }
+ }
+ priv->phandle->remain_on_channel = MFALSE;
+ }
+#endif
+#endif
+
#ifdef STA_SUPPORT
woal_reconfig_bgscan(priv->phandle);
#endif
+
+ /* Set auto arp response configuration to Fw */
+ woal_set_auto_arp(handle, MTRUE);
/* Enable Host Sleep */
handle->hs_activate_wait_q_woken = MFALSE;
memset(&hscfg, 0, sizeof(mlan_ds_hs_cfg));
@@ -2117,6 +2314,7 @@ woal_enable_hs(moal_private * priv)
}
#endif
+#ifdef CONFIG_PROC_FS
/**
* @brief This function send soft_reset command to firmware
*
@@ -2149,6 +2347,7 @@ woal_request_soft_reset(moal_handle * handle)
LEAVE();
return ret;
}
+#endif /* CONFIG_PROC_FS */
/**
* @brief Set wapi enable
@@ -2216,7 +2415,7 @@ woal_get_version(moal_handle * handle, char *version, int max_len)
snprintf(fw_ver, sizeof(fw_ver), "%u.%u.%u.p%u",
ver.c[2], ver.c[1], ver.c[0], ver.c[3]);
- snprintf(version, max_len, driver_version, fw_ver);
+ snprintf(version, max_len, handle->driver_version, fw_ver);
LEAVE();
}
@@ -2817,7 +3016,7 @@ woal_set_remain_channel_ioctl(moal_private * priv, t_u8 wait_option,
sizeof(mlan_ds_remain_chan));
}
done:
- if (req)
+ if (req && (ret != MLAN_STATUS_PENDING))
kfree(req);
LEAVE();
return ret;
@@ -3141,10 +3340,8 @@ woal_find_best_network(moal_private * priv, t_u8 wait_option,
if (ret == MLAN_STATUS_SUCCESS) {
memcpy(ssid_bssid, &bss->param.ssid_bssid, sizeof(mlan_ssid_bssid));
mac = (t_u8 *) & ssid_bssid->bssid;
- PRINTM(MINFO,
- "Find network: ssid=%s, %02x:%02x:%02x:%02x:%02x:%02x, idx=%d\n",
- ssid_bssid->ssid.ssid, mac[0], mac[1], mac[2], mac[3], mac[4],
- mac[5], (int) ssid_bssid->idx);
+ PRINTM(MINFO, "Find network: ssid=%s, " MACSTR ", idx=%d\n",
+ ssid_bssid->ssid.ssid, MAC2STR(mac), (int) ssid_bssid->idx);
}
done:
@@ -3513,11 +3710,54 @@ woal_request_userscan(moal_private * priv,
}
/**
+ * @brief woal_get_scan_config
+ *
+ * @param priv A pointer to moal_private structure
+ * @param scan_cfg A pointer to scan_cfg structure
+ *
+ *
+ * @return MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_get_scan_config(moal_private * priv, mlan_scan_cfg * scan_cfg)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ mlan_ds_scan *scan = NULL;
+ mlan_ioctl_req *req = NULL;
+
+ ENTER();
+
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
+ if (req == NULL) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ scan = (mlan_ds_scan *) req->pbuf;
+ scan->sub_command = MLAN_OID_SCAN_CONFIG;
+ req->req_id = MLAN_IOCTL_SCAN;
+ req->action = MLAN_ACT_GET;
+ memset(&scan->param.scan_cfg, 0, sizeof(mlan_scan_cfg));
+ if (MLAN_STATUS_SUCCESS == woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ if (scan_cfg) {
+ memcpy(scan_cfg, &scan->param.scan_cfg, sizeof(mlan_scan_cfg));
+ }
+ } else {
+ ret = MLAN_STATUS_FAILURE;
+ }
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
* @brief set scan time
*
* @param priv A pointer to moal_private structure
- * @param passive_scan_time passive scan time
- * @param specific_scan_time specific scan time
+ * @param active_scan_time Active scan time
+ * @param passive_scan_time Passive scan time
+ * @param specific_scan_time Specific scan time
*
* @return MLAN_STATUS_SUCCESS -- success, otherwise fail
*/
@@ -3528,9 +3768,15 @@ woal_set_scan_time(moal_private * priv, t_u16 active_scan_time,
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_scan *scan = NULL;
mlan_ioctl_req *req = NULL;
+ mlan_scan_cfg scan_cfg;
ENTER();
+ memset(&scan_cfg, 0, sizeof(scan_cfg));
+ if (MLAN_STATUS_SUCCESS != woal_get_scan_config(priv, &scan_cfg)) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
if (req == NULL) {
ret = MLAN_STATUS_FAILURE;
@@ -3541,9 +3787,13 @@ woal_set_scan_time(moal_private * priv, t_u16 active_scan_time,
req->req_id = MLAN_IOCTL_SCAN;
req->action = MLAN_ACT_SET;
memset(&scan->param.scan_cfg, 0, sizeof(mlan_scan_cfg));
- scan->param.scan_cfg.scan_time.active_scan_time = active_scan_time;
- scan->param.scan_cfg.scan_time.specific_scan_time = specific_scan_time;
- scan->param.scan_cfg.scan_time.passive_scan_time = passive_scan_time;
+ scan_cfg.scan_time.active_scan_time = active_scan_time;
+ scan_cfg.scan_time.specific_scan_time = specific_scan_time;
+ scan_cfg.scan_time.passive_scan_time = passive_scan_time;
+ PRINTM(MIOCTL, "Set specific=%d, active=%d, passive=%d\n",
+ (int) active_scan_time, (int) passive_scan_time,
+ (int) specific_scan_time);
+ memcpy(&scan->param.scan_cfg, &scan_cfg, sizeof(mlan_scan_cfg));
if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
ret = MLAN_STATUS_FAILURE;
done:
@@ -3815,25 +4065,86 @@ woal_set_bg_scan(moal_private * priv, char *buf, int length)
return ret;
}
+#ifdef STA_CFG80211
+/**
+ * @brief set bgscan and new rssi_low_threshold
+ *
+ * @param priv A pointer to moal_private structure
+ * @param set_rssi flag for set rssi_low_threshold
+ *
+ * @return N/A
+ */
+void
+woal_config_bgscan_and_rssi(moal_private * priv, t_u8 set_rssi)
+{
+ char rssi_low[10];
+ mlan_bss_info bss_info;
+ int band = 0;
+
+ ENTER();
+ memset(&bss_info, 0, sizeof(bss_info));
+ woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+ if (!bss_info.media_connected) {
+ PRINTM(MIOCTL, "We already lost connection\n");
+ LEAVE();
+ return;
+ }
+ memset(&priv->scan_cfg, 0, sizeof(priv->scan_cfg));
+ strncpy(priv->scan_cfg.ssid_list[0].ssid, bss_info.ssid.ssid,
+ bss_info.ssid.ssid_len);
+ priv->scan_cfg.ssid_list[0].max_len = 0;
+
+ priv->scan_cfg.report_condition = BG_SCAN_SSID_RSSI_MATCH;
+ priv->scan_cfg.rssi_threshold = priv->rssi_low - RSSI_HYSTERESIS;
+ priv->scan_cfg.repeat_count = DEF_REPEAT_COUNT;
+ priv->scan_cfg.scan_interval = MIN_BGSCAN_INTERVAL;
+ woal_get_band(priv, &band);
+ switch (band) {
+ case WIFI_FREQUENCY_BAND_2GHZ:
+ priv->scan_cfg.chan_list[0].radio_type = 0 | BAND_SPECIFIED;
+ break;
+ case WIFI_FREQUENCY_BAND_5GHZ:
+ priv->scan_cfg.chan_list[0].radio_type = 1 | BAND_SPECIFIED;
+ break;
+ default:
+ break;
+ }
+ priv->scan_cfg.bss_type = MLAN_BSS_MODE_INFRA;
+ priv->scan_cfg.action = BG_SCAN_ACT_SET;
+ priv->scan_cfg.enable = MTRUE;
+ woal_request_bgscan(priv, MOAL_NO_WAIT, &priv->scan_cfg);
+ if (set_rssi &&
+ ((priv->rssi_low + RSSI_HYSTERESIS) <= LOWEST_RSSI_THRESHOLD)) {
+ priv->rssi_low += RSSI_HYSTERESIS;
+ sprintf(rssi_low, "%d", priv->rssi_low);
+ woal_set_rssi_low_threshold(priv, rssi_low, MOAL_NO_WAIT);
+ }
+ LEAVE();
+}
+#endif
+
/**
* @brief stop bg scan
*
* @param priv A pointer to moal_private structure
+ * @param wait_option wait option
*
* @return MLAN_STATUS_SUCCESS -- success, otherwise fail
*/
mlan_status
-woal_stop_bg_scan(moal_private * priv)
+woal_stop_bg_scan(moal_private * priv, t_u8 wait_option)
{
wlan_bgscan_cfg scan_cfg;
+ mlan_status ret = MLAN_STATUS_SUCCESS;
ENTER();
memset(&scan_cfg, 0, sizeof(scan_cfg));
scan_cfg.action = BG_SCAN_ACT_SET;
scan_cfg.enable = MFALSE;
- return woal_request_bgscan(priv, MOAL_IOCTL_WAIT, &scan_cfg);
+ ret = woal_request_bgscan(priv, wait_option, &scan_cfg);
LEAVE();
+ return ret;
}
/**
@@ -3865,12 +4176,13 @@ woal_reconfig_bgscan(moal_handle * handle)
* @brief set rssi low threshold
*
* @param priv A pointer to moal_private structure
- * @param rssi A pointer to low rssi
+ * @param rssi A pointer to low rssi
+ * @param wait_option Wait option
*
* @return MLAN_STATUS_SUCCESS -- success, otherwise fail
*/
mlan_status
-woal_set_rssi_low_threshold(moal_private * priv, char *rssi)
+woal_set_rssi_low_threshold(moal_private * priv, char *rssi, t_u8 wait_option)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ioctl_req *req = NULL;
@@ -3883,19 +4195,20 @@ woal_set_rssi_low_threshold(moal_private * priv, char *rssi)
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
- ret = -ENOMEM;
+ ret = MLAN_STATUS_FAILURE;
goto done;
}
misc = (mlan_ds_misc_cfg *) req->pbuf;
req->req_id = MLAN_IOCTL_MISC_CFG;
misc->sub_command = MLAN_OID_MISC_SUBSCRIBE_EVENT;
req->action = MLAN_ACT_SET;
+ misc->param.subscribe_event.evt_action = SUBSCRIBE_EVT_ACT_BITWISE_SET;
misc->param.subscribe_event.evt_bitmap = SUBSCRIBE_EVT_RSSI_LOW;
misc->param.subscribe_event.evt_bitmap |= SUBSCRIBE_EVT_PRE_BEACON_LOST;
misc->param.subscribe_event.pre_beacon_miss = DEFAULT_PRE_BEACON_MISS;
if (MLAN_STATUS_SUCCESS != woal_atoi(&low_rssi, rssi)) {
- ret = -EFAULT;
+ ret = MLAN_STATUS_FAILURE;
goto done;
}
#ifdef STA_CFG80211
@@ -3903,12 +4216,13 @@ woal_set_rssi_low_threshold(moal_private * priv, char *rssi)
#endif
misc->param.subscribe_event.low_rssi = low_rssi;
misc->param.subscribe_event.low_rssi_freq = 0;
- if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
- ret = -EFAULT;
+ ret = woal_request_ioctl(priv, req, wait_option);
+ if (ret == MLAN_STATUS_FAILURE) {
+ PRINTM(MERROR, "request set rssi_low_threshold fail!\n");
goto done;
}
done:
- if (req)
+ if (req && (ret != MLAN_STATUS_PENDING))
kfree(req);
LEAVE();
return ret;
@@ -3920,11 +4234,12 @@ woal_set_rssi_low_threshold(moal_private * priv, char *rssi)
*
* @param priv A pointer to moal_private structure
* @param event_id event id.
+ * @param wait_option wait option
*
* @return MLAN_STATUS_SUCCESS -- success, otherwise fail
*/
mlan_status
-woal_set_rssi_threshold(moal_private * priv, t_u32 event_id)
+woal_set_rssi_threshold(moal_private * priv, t_u32 event_id, t_u8 wait_option)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ioctl_req *req = NULL;
@@ -3957,20 +4272,22 @@ woal_set_rssi_threshold(moal_private * priv, t_u32 event_id)
req->req_id = MLAN_IOCTL_MISC_CFG;
misc->sub_command = MLAN_OID_MISC_SUBSCRIBE_EVENT;
req->action = MLAN_ACT_SET;
+ if (!event_id && !priv->cqm_rssi_thold && !priv->cqm_rssi_hyst)
+ misc->param.subscribe_event.evt_action = SUBSCRIBE_EVT_ACT_BITWISE_CLR;
+ else
+ misc->param.subscribe_event.evt_action = SUBSCRIBE_EVT_ACT_BITWISE_SET;
misc->param.subscribe_event.evt_bitmap =
SUBSCRIBE_EVT_RSSI_LOW | SUBSCRIBE_EVT_RSSI_HIGH;
misc->param.subscribe_event.low_rssi_freq = 0;
misc->param.subscribe_event.low_rssi = priv->last_rssi_low;
misc->param.subscribe_event.high_rssi_freq = 0;
misc->param.subscribe_event.high_rssi = priv->last_rssi_high;
- PRINTM(MIOCTL, "rssi_low=%d, rssi_high=%d\n", (int) priv->last_rssi_low,
- (int) priv->last_rssi_high);
- if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
- ret = -EFAULT;
- goto done;
- }
+ PRINTM(MIOCTL, "rssi_low=%d, rssi_high=%d action=%d\n",
+ (int) priv->last_rssi_low, (int) priv->last_rssi_high,
+ misc->param.subscribe_event.evt_action);
+ ret = woal_request_ioctl(priv, req, wait_option);
done:
- if (req)
+ if (req && (ret != MLAN_STATUS_PENDING))
kfree(req);
LEAVE();
return ret;
@@ -4023,8 +4340,14 @@ woal_set_scan_type(moal_private * priv, t_u32 scan_type)
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_scan *scan = NULL;
mlan_ioctl_req *req = NULL;
+ mlan_scan_cfg scan_cfg;
ENTER();
+ memset(&scan_cfg, 0, sizeof(scan_cfg));
+ if (MLAN_STATUS_SUCCESS != woal_get_scan_config(priv, &scan_cfg)) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
if (req == NULL) {
@@ -4036,8 +4359,54 @@ woal_set_scan_type(moal_private * priv, t_u32 scan_type)
req->req_id = MLAN_IOCTL_SCAN;
req->action = MLAN_ACT_SET;
memset(&scan->param.scan_cfg, 0, sizeof(mlan_scan_cfg));
- scan->param.scan_cfg.scan_type = scan_type;
+ scan_cfg.scan_type = scan_type;
+ PRINTM(MIOCTL, "Set scan_type=%d\n", (int) scan_type);
+ memcpy(&scan->param.scan_cfg, &scan_cfg, sizeof(mlan_scan_cfg));
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
+ ret = MLAN_STATUS_FAILURE;
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+/**
+ * @brief enable/disable ext_scan
+ *
+ * @param priv A pointer to moal_private structure
+ * @param enable MTRUE -- enable, MFALSE --disable
+ *
+ * @return MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_enable_ext_scan(moal_private * priv, t_u8 enable)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ mlan_ds_scan *scan = NULL;
+ mlan_ioctl_req *req = NULL;
+ mlan_scan_cfg scan_cfg;
+
+ ENTER();
+ memset(&scan_cfg, 0, sizeof(scan_cfg));
+ if (MLAN_STATUS_SUCCESS != woal_get_scan_config(priv, &scan_cfg)) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
+ if (req == NULL) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ scan = (mlan_ds_scan *) req->pbuf;
+ scan->sub_command = MLAN_OID_SCAN_CONFIG;
+ req->req_id = MLAN_IOCTL_SCAN;
+ req->action = MLAN_ACT_SET;
+ memset(&scan->param.scan_cfg, 0, sizeof(mlan_scan_cfg));
+ scan_cfg.ext_scan = enable;
+ PRINTM(MIOCTL, "Set ext_scan=%d\n", (int) enable);
+ memcpy(&scan->param.scan_cfg, &scan_cfg, sizeof(mlan_scan_cfg));
if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
ret = MLAN_STATUS_FAILURE;
done:
@@ -4418,15 +4787,16 @@ woal_remove_rxfilter(moal_private * priv, char *rxfilter)
}
/**
- * @brief Set QoS configuration
+ * @brief Set/Get WMM IE QoS configuration
*
* @param priv A pointer to moal_private structure
+ * @param action Action set or get
* @param qos_cfg A pointer to QoS configuration structure
*
* @return MLAN_STATUS_SUCCESS -- success, otherwise fail
*/
mlan_status
-woal_set_qos_cfg(moal_private * priv, char *qos_cfg)
+woal_priv_qos_cfg(moal_private * priv, t_u32 action, char *qos_cfg)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_wmm_cfg *cfg = NULL;
@@ -4434,11 +4804,16 @@ woal_set_qos_cfg(moal_private * priv, char *qos_cfg)
int qosinfo = 0;
ENTER();
- if (MLAN_STATUS_SUCCESS != woal_atoi(&qosinfo, qos_cfg)) {
+
+ if (qos_cfg == NULL) {
+ PRINTM(MERROR, "QOS info buffer is null\n");
+ return MLAN_STATUS_FAILURE;
+ }
+ if ((action == MLAN_ACT_SET) &&
+ (MLAN_STATUS_SUCCESS != woal_atoi(&qosinfo, qos_cfg))) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
- PRINTM(MIOCTL, "set qosinfo=%d\n", qosinfo);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
if (req == NULL) {
ret = MLAN_STATUS_FAILURE;
@@ -4447,10 +4822,15 @@ woal_set_qos_cfg(moal_private * priv, char *qos_cfg)
cfg = (mlan_ds_wmm_cfg *) req->pbuf;
cfg->sub_command = MLAN_OID_WMM_CFG_QOS;
req->req_id = MLAN_IOCTL_WMM_CFG;
- req->action = MLAN_ACT_SET;
- cfg->param.qos_cfg = (t_u8) qosinfo;
+ req->action = action;
+ if (action == MLAN_ACT_SET) {
+ cfg->param.qos_cfg = (t_u8) qosinfo;
+ PRINTM(MIOCTL, "set qosinfo=%d\n", qosinfo);
+ }
if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
ret = MLAN_STATUS_FAILURE;
+ if (action == MLAN_ACT_GET)
+ *qos_cfg = cfg->param.qos_cfg;
done:
if (req)
kfree(req);
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_main.c b/drivers/net/wireless/sd8797/mlinux/moal_main.c
index 2bc1ba28b5db..293782ef5d69 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_main.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_main.c
@@ -43,8 +43,6 @@ Change log:
#include "moal_uap_cfg80211.h"
#endif
#endif
-#include <linux/platform_device.h>
-#include <linux/wlan_plat.h>
#include "moal_eth_ioctl.h"
#include <linux/if_ether.h>
@@ -68,6 +66,11 @@ char driver_version[] =
#endif
" ";
+/** SD8797 Card */
+#define CARD_SD8797 "SD8797"
+/** SD8782 Card */
+#define CARD_SD8782 "SD8782"
+
/** Firmware name */
char *fw_name = NULL;
int req_fw_nowait = 0;
@@ -113,6 +116,10 @@ char *uap_name = NULL;
int max_wfd_bss = DEF_WIFIDIRECT_BSS;
/** WIFIDIRECT interface name */
char *wfd_name = NULL;
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+/** max VIRTUAL bss */
+int max_vir_bss = DEF_VIRTUAL_BSS;
+#endif
#endif
#ifdef SDIO_SUSPEND_RESUME
@@ -130,19 +137,21 @@ char *cal_data_cfg = NULL;
/** Init config file (MAC address, register etc.) */
char *init_cfg = NULL;
-/** Enable minicard power-up/down */
-int minicard_pwrup = 1;
-/** Pointer to struct with control hooks */
-struct wifi_platform_data *wifi_control_data = NULL;
-
+#if defined(STA_WEXT) || defined(UAP_WEXT)
/** CFG80211 and WEXT mode */
int cfg80211_wext = STA_WEXT_MASK | UAP_WEXT_MASK;
+#else
+/** CFG80211 and WEXT mode */
+int cfg80211_wext = STA_CFG80211_MASK | UAP_CFG80211_MASK;
+#endif
/** Work queue priority */
int wq_sched_prio = 0;
/** Work queue scheduling policy */
int wq_sched_policy = SCHED_NORMAL;
+int hw_test = 0;
+
/** woal_callbacks */
static mlan_callbacks woal_callbacks = {
.moal_get_fw_data = moal_get_fw_data,
@@ -154,12 +163,15 @@ static mlan_callbacks woal_callbacks = {
.moal_ioctl_complete = moal_ioctl_complete,
.moal_alloc_mlan_buffer = moal_alloc_mlan_buffer,
.moal_free_mlan_buffer = moal_free_mlan_buffer,
+
.moal_write_reg = moal_write_reg,
.moal_read_reg = moal_read_reg,
.moal_write_data_sync = moal_write_data_sync,
.moal_read_data_sync = moal_read_data_sync,
.moal_malloc = moal_malloc,
.moal_mfree = moal_mfree,
+ .moal_vmalloc = moal_vmalloc,
+ .moal_vfree = moal_vfree,
.moal_memset = moal_memset,
.moal_memcpy = moal_memcpy,
.moal_memmove = moal_memmove,
@@ -201,10 +213,6 @@ int drv_mode = DRV_MODE_UAP;
/** Semaphore for add/remove card */
struct semaphore AddRemoveCardSem;
/**
- * the maximum number of adapter supported
- **/
-#define MAX_MLAN_ADAPTER 2
-/**
* The global variable of a pointer to moal_handle
* structure variable
**/
@@ -217,6 +225,7 @@ moal_handle *m_handle[MAX_MLAN_ADAPTER];
#define DEFAULT_DEBUG_MASK (MMSG | MFATAL | MERROR)
#endif /* DEBUG_LEVEL2 */
t_u32 drvdbg = DEFAULT_DEBUG_MASK;
+
#endif /* DEBUG_LEVEL1 */
int woal_open(struct net_device *dev);
@@ -224,12 +233,97 @@ int woal_close(struct net_device *dev);
int woal_set_mac_address(struct net_device *dev, void *addr);
void woal_tx_timeout(struct net_device *dev);
struct net_device_stats *woal_get_stats(struct net_device *dev);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
u16 woal_select_queue(struct net_device *dev, struct sk_buff *skb);
#endif
mlan_debug_info info;
+static int woal_netdevice_event(struct notifier_block *nb, unsigned long event,
+ void *ptr);
+static struct notifier_block woal_notifier = {
+ .notifier_call = woal_netdevice_event
+};
+
+/**
+ * @brief This function handle the net interface ipaddr change event
+ *
+ * @param nb pointer to the notifier_block
+ * @param event event type
+ * @param ptr pointer to event struct
+ *
+ * @return NOTIFY_DONE or NOTIFY_OK
+ */
+static int
+woal_netdevice_event(struct notifier_block *nb, unsigned long event, void *ptr)
+{
+ struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
+ struct net_device *ndev;
+ moal_private *priv;
+
+ int ret = NOTIFY_OK;
+#ifdef STA_CFG80211
+ char rssi_low[10];
+#endif
+
+ ENTER();
+
+ ndev = ifa->ifa_dev->dev;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+ if (!ndev || ndev->netdev_ops->ndo_open != woal_open)
+#else
+ if (!ndev || ndev->open != woal_open)
+#endif
+ {
+ PRINTM(MIOCTL, "IP changes not for us, ignore. ndev[%p]\n", ndev);
+ if (ndev)
+ PRINTM(MIOCTL, "changes on %s\n", ndev->name);
+ ret = NOTIFY_DONE;
+ goto done;
+ }
+ priv = (moal_private *) netdev_priv(ndev);
+ if (priv->bss_type != MLAN_BSS_TYPE_STA
+#if defined(WIFI_DIRECT_SUPPORT)
+ && priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT
+#endif
+ ) {
+ PRINTM(MIOCTL, "Bss type [%d] is not STA/P2P, ignore\n",
+ (int) priv->bss_type);
+ ret = NOTIFY_DONE;
+ goto done;
+ }
+
+ switch (event) {
+ case NETDEV_UP:
+ PRINTM(MIOCTL, "[%s]: New ip addr: 0x%08x\n", ndev->name,
+ ifa->ifa_address);
+ /* Save the IP addr now */
+ memcpy(priv->ip_addr, &ifa->ifa_address, sizeof(ifa->ifa_address));
+ priv->ip_addr_type = IPADDR_TYPE_IPV4;
+#ifdef STA_CFG80211
+ if (!hw_test && priv->roaming_enabled) {
+ sprintf(rssi_low, "%d", priv->rssi_low);
+ woal_set_rssi_low_threshold(priv, rssi_low, MOAL_CMD_WAIT);
+ }
+#endif
+ break;
+ case NETDEV_DOWN:
+ PRINTM(MIOCTL, "[%s]: Ip addr removed.\n", ndev->name);
+ priv->ip_addr_type = IPADDR_TYPE_NONE;
+ memset(priv->ip_addr, 0, sizeof(priv->ip_addr));
+ break;
+ default:
+ PRINTM(MIOCTL, "[%s]: Ignore event: %u\n", ndev->name,
+ (unsigned int) event);
+ ret = NOTIFY_DONE;
+ goto done;
+ }
+
+ done:
+ LEAVE();
+ return ret;
+}
+
/**
* @brief This function validates a SSID as being able to be printed
*
@@ -281,6 +375,53 @@ woal_go_timer_func(void *context)
#endif
#endif
+/**
+ * @brief check if we already connect to the AP.
+ * @param priv A pointer to moal_private structure
+ * @param ssid_bssid A pointer to mlan_ssid_bssid structure
+ *
+ * @return MTRUE/MFALSE;
+ */
+int
+woal_is_connected(moal_private * priv, mlan_ssid_bssid * ssid_bssid)
+{
+ mlan_bss_info bss_info;
+ int ret = MFALSE;
+ t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
+ ENTER();
+ memset(&bss_info, 0, sizeof(bss_info));
+ if (MLAN_STATUS_SUCCESS !=
+ woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info))
+ goto done;
+ if (bss_info.media_connected) {
+ if (memcmp(ssid_bssid->bssid, zero_mac, sizeof(zero_mac))) {
+ if (ssid_bssid->ssid.ssid_len) { // compare ssid and bssid
+ if ((ssid_bssid->ssid.ssid_len == bss_info.ssid.ssid_len) &&
+ !memcmp(ssid_bssid->ssid.ssid, bss_info.ssid.ssid,
+ bss_info.ssid.ssid_len) &&
+ !memcmp(ssid_bssid->bssid, bss_info.bssid,
+ MLAN_MAC_ADDR_LENGTH))
+ ret = MTRUE;
+ } else { // compare bssid
+ if (!memcmp
+ (ssid_bssid->bssid, bss_info.bssid, MLAN_MAC_ADDR_LENGTH)) {
+ ret = MTRUE;
+ }
+ }
+ } else { // compare ssid
+ if (ssid_bssid->ssid.ssid_len &&
+ (ssid_bssid->ssid.ssid_len == bss_info.ssid.ssid_len) &&
+ !memcmp(ssid_bssid->ssid.ssid, bss_info.ssid.ssid,
+ bss_info.ssid.ssid_len)) {
+ ret = MTRUE;
+ }
+ }
+ }
+ done:
+ LEAVE();
+ return ret;
+}
+
/**
* @brief Get mode
*
@@ -321,13 +462,13 @@ woal_get_mode(moal_private * priv, t_u8 wait_option)
if (status == MLAN_STATUS_SUCCESS) {
switch (bss->param.bss_mode) {
case MLAN_BSS_MODE_INFRA:
- mode = IW_MODE_INFRA;
+ mode = MW_MODE_INFRA;
break;
case MLAN_BSS_MODE_IBSS:
- mode = IW_MODE_ADHOC;
+ mode = MW_MODE_ADHOC;
break;
default:
- mode = IW_MODE_AUTO;
+ mode = MW_MODE_AUTO;
break;
}
}
@@ -357,6 +498,11 @@ woal_update_drv_tbl(moal_handle * handle, int drv_mode_local)
unsigned int intf_num = 0;
int i = 0, j = 0;
mlan_bss_attr *bss_tbl = NULL;
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+ int last_wfd_index = 0;
+#endif
+#endif
ENTER();
@@ -391,6 +537,9 @@ woal_update_drv_tbl(moal_handle * handle, int drv_mode_local)
max_wfd_bss = DEF_WIFIDIRECT_BSS;
}
intf_num += max_wfd_bss;
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+ intf_num += max_vir_bss;
+#endif
}
#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
@@ -422,6 +571,7 @@ woal_update_drv_tbl(moal_handle * handle, int drv_mode_local)
bss_tbl[i].active = MTRUE;
bss_tbl[i].bss_priority = 0;
bss_tbl[i].bss_num = j;
+ bss_tbl[i].bss_virtual = MFALSE;
i++;
}
}
@@ -437,6 +587,7 @@ woal_update_drv_tbl(moal_handle * handle, int drv_mode_local)
bss_tbl[i].active = MTRUE;
bss_tbl[i].bss_priority = 0;
bss_tbl[i].bss_num = j;
+ bss_tbl[i].bss_virtual = MFALSE;
i++;
}
}
@@ -452,11 +603,31 @@ woal_update_drv_tbl(moal_handle * handle, int drv_mode_local)
bss_tbl[i].active = MTRUE;
bss_tbl[i].bss_priority = 0;
bss_tbl[i].bss_num = j;
+ bss_tbl[i].bss_virtual = MFALSE;
i++;
}
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+ last_wfd_index = j;
+#endif
}
#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+ /** append virtual interface at the end of table */
+ for (j = 0; j < max_vir_bss; j++) {
+ if (i >= intf_num)
+ break;
+ bss_tbl[i].bss_type = MLAN_BSS_TYPE_WIFIDIRECT;
+ bss_tbl[i].frame_type = MLAN_DATA_FRAME_TYPE_ETH_II;
+ bss_tbl[i].active = MTRUE;
+ bss_tbl[i].bss_priority = 0;
+ bss_tbl[i].bss_num = j + last_wfd_index;
+ bss_tbl[i].bss_virtual = MTRUE;
+ i++;
+ }
+#endif
+#endif
/* Clear existing table, if any */
if (handle->drv_mode.bss_attr != NULL) {
kfree(handle->drv_mode.bss_attr);
@@ -471,12 +642,21 @@ woal_update_drv_tbl(moal_handle * handle, int drv_mode_local)
handle->drv_mode.fw_name = fw_name;
} else {
#if defined(UAP_SUPPORT) && defined(STA_SUPPORT)
- handle->drv_mode.fw_name = DEFAULT_AP_STA_FW_NAME;
+ if (handle->card_type == CARD_TYPE_SD8782)
+ handle->drv_mode.fw_name = DEFAULT_AP_STA_FW_NAME_8782;
+ else
+ handle->drv_mode.fw_name = DEFAULT_AP_STA_FW_NAME;
#else
#ifdef UAP_SUPPORT
- handle->drv_mode.fw_name = DEFAULT_AP_FW_NAME;
+ if (handle->card_type == CARD_TYPE_SD8782)
+ handle->drv_mode.fw_name = DEFAULT_AP_FW_NAME_8782;
+ else
+ handle->drv_mode.fw_name = DEFAULT_AP_FW_NAME;
#else
- handle->drv_mode.fw_name = DEFAULT_FW_NAME;
+ if (handle->card_type == CARD_TYPE_SD8782)
+ handle->drv_mode.fw_name = DEFAULT_FW_NAME_8782;
+ else
+ handle->drv_mode.fw_name = DEFAULT_FW_NAME;
#endif /* UAP_SUPPORT */
#endif /* UAP_SUPPORT && STA_SUPPORT */
}
@@ -522,6 +702,13 @@ woal_init_sw(moal_handle * handle)
}
#endif /* STA_SUPPORT */
+ /* Update driver version */
+ if (handle->card_type == CARD_TYPE_SD8782)
+ memcpy(driver_version, CARD_SD8782, strlen(CARD_SD8782));
+ else if (handle->card_type == CARD_TYPE_SD8797)
+ memcpy(driver_version, CARD_SD8797, strlen(CARD_SD8797));
+ memcpy(handle->driver_version, driver_version, strlen(driver_version));
+
if (woal_update_drv_tbl(handle, drv_mode) != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "Could not update driver mode table\n");
LEAVE();
@@ -531,7 +718,7 @@ woal_init_sw(moal_handle * handle)
/* PnP and power profile */
handle->surprise_removed = MFALSE;
init_waitqueue_head(&handle->init_wait_q);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
spin_lock_init(&handle->queue_lock);
#endif
spin_lock_init(&handle->driver_lock);
@@ -577,6 +764,7 @@ woal_init_sw(moal_handle * handle)
woal_initialize_timer(&handle->go_timer, woal_go_timer_func, handle);
handle->is_go_timer_set = MFALSE;
+ handle->remain_on_channel = MFALSE;
#endif
#endif
@@ -612,6 +800,9 @@ woal_init_sw(moal_handle * handle)
device.mpa_rx_cfg = MLAN_INIT_PARA_DISABLED;
#endif
#endif
+ device.feature_control = FEATURE_CTRL_DEFAULT;
+ if (handle->card_type == CARD_TYPE_SD8782)
+ device.feature_control = 0;
for (i = 0; i < handle->drv_mode.intf_num; i++) {
device.bss_attr[i].bss_type = handle->drv_mode.bss_attr[i].bss_type;
@@ -620,6 +811,8 @@ woal_init_sw(moal_handle * handle)
device.bss_attr[i].bss_priority =
handle->drv_mode.bss_attr[i].bss_priority;
device.bss_attr[i].bss_num = handle->drv_mode.bss_attr[i].bss_num;
+ device.bss_attr[i].bss_virtual =
+ handle->drv_mode.bss_attr[i].bss_virtual;
}
memcpy(&device.callbacks, &woal_callbacks, sizeof(mlan_callbacks));
@@ -650,6 +843,15 @@ woal_free_moal_handle(moal_handle * handle)
LEAVE();
return;
}
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+ /* Unregister wiphy device and free */
+ if (handle->wiphy) {
+ wiphy_unregister(handle->wiphy);
+ wiphy_free(handle->wiphy);
+ handle->wiphy = NULL;
+ }
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
if ((handle->nl_sk) && ((handle->nl_sk)->sk_socket)) {
sock_release((handle->nl_sk)->sk_socket);
@@ -846,6 +1048,18 @@ woal_process_init_cfg(moal_handle * handle, t_u8 * data, t_size size)
bss_mac_name, bss_mac_addr);
woal_mac2u8(handle->priv[i]->current_addr,
bss_mac_addr);
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ if (handle->priv[i]->bss_type ==
+ MLAN_BSS_TYPE_WIFIDIRECT) {
+ handle->priv[i]->current_addr[0] |= 0x02;
+ PRINTM(MCMND, "Set WFD device addr: " MACSTR "\n",
+ MAC2STR(handle->priv[i]->current_addr));
+ }
+#endif
+#endif
+#endif
/* Set WLAN MAC addresses */
if (MLAN_STATUS_SUCCESS !=
woal_request_set_mac_address(handle->priv[i])) {
@@ -878,11 +1092,8 @@ woal_process_init_cfg(moal_handle * handle, t_u8 * data, t_size size)
goto done;
}
intf_s = intf_e + 1;
- if (intf_s != NULL)
- intf_e = strchr(intf_s, ',');
- else
- intf_e = NULL;
- if (intf_s != NULL && intf_e != NULL) {
+ intf_e = strchr(intf_s, ',');
+ if (intf_e != NULL) {
if ((intf_e - intf_s) >= MAX_PARAM_LEN) {
PRINTM(MERROR, "Regsier offset is too long %d\n", __LINE__);
goto done;
@@ -895,17 +1106,12 @@ woal_process_init_cfg(moal_handle * handle, t_u8 * data, t_size size)
goto done;
}
intf_s = intf_e + 1;
- if (intf_s != NULL) {
- if ((strlen(intf_s) >= MAX_PARAM_LEN)) {
- PRINTM(MERROR, "Regsier value is too long %d\n", __LINE__);
- goto done;
- }
- /* Copy value */
- strncpy(value, intf_s, sizeof(value));
- } else {
- PRINTM(MERROR, "Wrong config file format %d\n", __LINE__);
+ if ((strlen(intf_s) >= MAX_PARAM_LEN)) {
+ PRINTM(MERROR, "Regsier value is too long %d\n", __LINE__);
goto done;
}
+ /* Copy value */
+ strncpy(value, intf_s, strlen(intf_s));
if (MLAN_STATUS_SUCCESS !=
woal_process_regrdwr(handle, type, offset, value)) {
@@ -990,13 +1196,15 @@ woal_add_card_dpc(moal_handle * handle)
/* Add interfaces */
for (i = 0; i < handle->drv_mode.intf_num; i++) {
+ if (handle->drv_mode.bss_attr[i].bss_virtual)
+ continue;
if (!woal_add_interface
(handle, handle->priv_num, handle->drv_mode.bss_attr[i].bss_type)) {
ret = MLAN_STATUS_FAILURE;
goto err;
}
- handle->priv_num++;
}
+ register_inetaddr_notifier(&woal_notifier);
if (init_cfg) {
if (MLAN_STATUS_SUCCESS != woal_set_user_init_data(handle)) {
PRINTM(MFATAL, "Set user init data and param failed\n");
@@ -1004,10 +1212,10 @@ woal_add_card_dpc(moal_handle * handle)
goto err;
}
}
-
err:
if (ret != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "Failed to add interface\n");
+ unregister_inetaddr_notifier(&woal_notifier);
for (i = 0; i < handle->priv_num; i++)
woal_remove_interface(handle, i);
handle->priv_num = 0;
@@ -1181,29 +1389,9 @@ woal_request_fw(moal_handle * handle)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
int err;
- t_u32 revision_id = 0;
ENTER();
- if (!fw_name) {
-/** Revision ID register */
-#define REV_ID_REG 0x5c
- sdio_claim_host(((struct sdio_mmc_card *) handle->card)->func);
- woal_read_reg(handle, REV_ID_REG, &revision_id);
- sdio_release_host(((struct sdio_mmc_card *) handle->card)->func);
- /* Check revision ID */
- switch (revision_id) {
- case SD8797_A0:
- handle->drv_mode.fw_name = SD8797_A0_FW_NAME;
- break;
- case SD8797_B0:
- handle->drv_mode.fw_name = SD8797_B0_FW_NAME;
- break;
- default:
- break;
- }
- }
-
if (req_fw_nowait) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
if ((err = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
@@ -1346,7 +1534,7 @@ static struct device_type wlan_type = {.name = "wlan", };
#endif
#ifdef STA_SUPPORT
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
/** Network device handlers */
const struct net_device_ops woal_netdev_ops = {
.ndo_open = woal_open,
@@ -1374,13 +1562,13 @@ const struct net_device_ops woal_netdev_ops = {
*
* @return MLAN_STATUS_SUCCESS
*/
-static mlan_status
+mlan_status
woal_init_sta_dev(struct net_device *dev, moal_private * priv)
{
ENTER();
/* Setup the OS Interface to our functions */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29)
dev->open = woal_open;
dev->hard_start_xmit = woal_hard_start_xmit;
dev->stop = woal_close;
@@ -1393,8 +1581,8 @@ woal_init_sta_dev(struct net_device *dev, moal_private * priv)
dev->netdev_ops = &woal_netdev_ops;
#endif
dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT;
- dev->hard_header_len += MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer);
-#ifdef WIRELESS_EXT
+ dev->hard_header_len += MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer)
+ + priv->extra_tx_head_len;
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext)) {
#if WIRELESS_EXT < 21
@@ -1403,13 +1591,14 @@ woal_init_sta_dev(struct net_device *dev, moal_private * priv)
dev->wireless_handlers = (struct iw_handler_def *) &woal_handler_def;
}
#endif
-#endif
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
/* Initialize private structure */
init_waitqueue_head(&priv->ioctl_wait_q);
init_waitqueue_head(&priv->cmd_wait_q);
+#ifdef CONFIG_PROC_FS
init_waitqueue_head(&priv->proc_wait_q);
+#endif
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
init_waitqueue_head(&priv->w_stats_wait_q);
@@ -1421,7 +1610,7 @@ woal_init_sta_dev(struct net_device *dev, moal_private * priv)
#endif /* STA_SUPPORT */
#ifdef UAP_SUPPORT
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
/** Network device handlers */
const struct net_device_ops woal_uap_netdev_ops = {
.ndo_open = woal_open,
@@ -1449,7 +1638,7 @@ const struct net_device_ops woal_uap_netdev_ops = {
*
* @return MLAN_STATUS_SUCCESS
*/
-static mlan_status
+mlan_status
woal_init_uap_dev(struct net_device *dev, moal_private * priv)
{
mlan_status status = MLAN_STATUS_SUCCESS;
@@ -1457,7 +1646,7 @@ woal_init_uap_dev(struct net_device *dev, moal_private * priv)
ENTER();
/* Setup the OS Interface to our functions */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29)
dev->open = woal_open;
dev->hard_start_xmit = woal_hard_start_xmit;
dev->stop = woal_close;
@@ -1470,9 +1659,9 @@ woal_init_uap_dev(struct net_device *dev, moal_private * priv)
dev->netdev_ops = &woal_uap_netdev_ops;
#endif
dev->watchdog_timeo = MRVDRV_DEFAULT_UAP_WATCHDOG_TIMEOUT;
- dev->hard_header_len += MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer);
+ dev->hard_header_len += MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer)
+ + priv->extra_tx_head_len;
#ifdef UAP_WEXT
-#ifdef WIRELESS_EXT
if (IS_UAP_WEXT(cfg80211_wext)) {
#if WIRELESS_EXT < 21
dev->get_wireless_stats = woal_get_uap_wireless_stats;
@@ -1480,14 +1669,15 @@ woal_init_uap_dev(struct net_device *dev, moal_private * priv)
dev->wireless_handlers =
(struct iw_handler_def *) &woal_uap_handler_def;
}
-#endif /* WIRELESS_EXT */
#endif /* UAP_WEXT */
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
/* Initialize private structure */
init_waitqueue_head(&priv->ioctl_wait_q);
init_waitqueue_head(&priv->cmd_wait_q);
+#ifdef CONFIG_PROC_FS
init_waitqueue_head(&priv->proc_wait_q);
+#endif
#ifdef UAP_WEXT
if (IS_UAP_WEXT(cfg80211_wext))
init_waitqueue_head(&priv->w_stats_wait_q);
@@ -1517,7 +1707,7 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type)
ENTER();
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
#define MAX_WMM_QUEUE 4
/* Allocate an Ethernet device */
if (!(dev = alloc_etherdev_mq(sizeof(moal_private), MAX_WMM_QUEUE))) {
@@ -1574,6 +1764,7 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type)
priv->netdev = dev;
priv->bss_index = bss_index;
priv->bss_type = bss_type;
+ priv->extra_tx_head_len = 0;
if (bss_type == MLAN_BSS_TYPE_STA)
priv->bss_role = MLAN_BSS_ROLE_STA;
else if (bss_type == MLAN_BSS_TYPE_UAP)
@@ -1584,6 +1775,7 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type)
#endif
INIT_LIST_HEAD(&priv->tcp_sess_queue);
+ spin_lock_init(&priv->tcp_sess_lock);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
SET_MODULE_OWNER(dev);
@@ -1602,6 +1794,16 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type)
goto error;
}
#endif
+ handle->priv_num++;
+#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+ if (!priv->phandle->wiphy && IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
+ if (woal_register_cfg80211(priv)) {
+ PRINTM(MERROR, "Cannot register with cfg80211\n");
+ goto error;
+ }
+ }
+#endif
+
#ifdef STA_CFG80211
#ifdef STA_SUPPORT
if ((priv->bss_role == MLAN_BSS_ROLE_STA) && IS_STA_CFG80211(cfg80211_wext)) {
@@ -1635,7 +1837,7 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type)
/* Initialize priv structure */
woal_init_priv(priv, MOAL_CMD_WAIT);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
SET_NETDEV_DEV(dev, handle->hotplug_device);
#endif
@@ -1656,6 +1858,18 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type)
if (handle->set_mac_addr) {
memset(priv->current_addr, 0, ETH_ALEN);
memcpy(priv->current_addr, handle->mac_addr, ETH_ALEN);
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
+ priv->current_addr[0] |= 0x02;
+ PRINTM(MCMND, "Set WFD device addr: " MACSTR "\n",
+ MAC2STR(priv->current_addr));
+ }
+#endif
+#endif
+#endif
+
if (MLAN_STATUS_SUCCESS != woal_request_set_mac_address(priv)) {
PRINTM(MERROR, "Set MAC address failed\n");
goto error;
@@ -1672,18 +1886,17 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type)
LEAVE();
return priv;
error:
- if (dev && dev->reg_state == NETREG_REGISTERED)
- unregister_netdev(dev);
+ handle->priv_num = bss_index;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
/* Unregister wiphy device and free */
- if (priv->wdev && IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
- wiphy_unregister(priv->wdev->wiphy);
- wiphy_free(priv->wdev->wiphy);
- /* Free wireless device */
- kfree(priv->wdev);
- priv->wdev = NULL;
+ if (priv) {
+ if (priv->wdev && IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
+ priv->wdev = NULL;
+ }
}
#endif
+ if (dev && dev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(dev);
if (dev)
free_netdev(dev);
LEAVE();
@@ -1723,6 +1936,8 @@ woal_remove_interface(moal_handle * handle, t_u8 bss_index)
}
#endif
}
+ woal_flush_tcp_sess_queue(priv);
+
#ifdef CONFIG_PROC_FS
#ifdef PROC_DEBUG
/* Remove proc debug */
@@ -1745,10 +1960,6 @@ woal_remove_interface(moal_handle * handle, t_u8 bss_index)
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
/* Unregister wiphy device and free */
if (priv->wdev && IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
- wiphy_unregister(priv->wdev->wiphy);
- wiphy_free(priv->wdev->wiphy);
- /* Free wireless device */
- kfree(priv->wdev);
priv->wdev = NULL;
}
#endif
@@ -1825,7 +2036,7 @@ woal_hexval(char chr)
return 0;
}
-#ifdef STA_WEXT
+#ifdef STA_SUPPORT
#endif
/**
@@ -1851,138 +2062,6 @@ woal_terminate_workqueue(moal_handle * handle)
LEAVE();
}
-/* Support for Cardhu wifi gpio toggling */
-/**
- * @brief Sets the card detect state
- *
- * @param on 0: Card will be made undetected
- * 1: Card will be detected
- *
- * @return 0
- */
-static int
-wifi_set_carddetect(int on)
-{
- ENTER();
- PRINTM(MMSG, "%s = %d\n", __FUNCTION__, on);
- if (wifi_control_data && wifi_control_data->set_carddetect) {
- wifi_control_data->set_carddetect(on);
- }
- LEAVE();
- return 0;
-}
-
-/**
- * @brief Sets the power state to On or Off after 'msec' millisecond
- *
- * @param on 0: Card will be powered on
- * 1: Card will be powered off
- * @param msec Delay in millisecond
- *
- * @return 0
- */
-static int
-wifi_set_power(int on, unsigned long msec)
-{
- ENTER();
- PRINTM(MMSG, "%s = %d\n", __FUNCTION__, on);
- if (wifi_control_data && wifi_control_data->set_power) {
- wifi_control_data->set_power(on);
- }
- if (msec)
- mdelay(msec);
- LEAVE();
- return 0;
-}
-
-/**
- * @brief Probes an wifi device
- *
- * @param pdev A pointer to the platform_device structure
- *
- * @return 0
- */
-static int
-wifi_probe(struct platform_device *pdev)
-{
- struct wifi_platform_data *wifi_ctrl =
- (struct wifi_platform_data *) (pdev->dev.platform_data);
-
- ENTER();
-
- wifi_control_data = wifi_ctrl;
- wifi_set_power(1, 0); /* Power On */
- wifi_set_carddetect(1); /* CardDetect (0->1) */
-
- LEAVE();
- return 0;
-}
-
-/**
- * @brief Removes an wifi device
- *
- * @param pdev A pointer to the platform_device structure
- *
- * @return 0
- */
-static int
-wifi_remove(struct platform_device *pdev)
-{
- struct wifi_platform_data *wifi_ctrl =
- (struct wifi_platform_data *) (pdev->dev.platform_data);
-
- ENTER();
-
- wifi_control_data = wifi_ctrl;
- wifi_set_power(0, 0); /* Power Off */
- wifi_set_carddetect(0); /* CardDetect (1->0) */
-
- LEAVE();
- return 0;
-}
-
-static struct platform_driver wifi_device = {
- .probe = wifi_probe,
- .remove = wifi_remove,
- .driver = {
- .name = "mrvl8797_wlan",
- }
-};
-
-/**
- * @brief Adds an wifi device
- * @return 0 --success, otherwise fail
- */
-static int
-wifi_add_dev(void)
-{
- int ret = 0;
-
- ENTER();
-
- if (minicard_pwrup)
- ret = platform_driver_register(&wifi_device);
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Removes an wifi device
- *
- * @return N/A
- */
-static void
-wifi_del_dev(void)
-{
- ENTER();
-
- if (minicard_pwrup)
- platform_driver_unregister(&wifi_device);
-
- LEAVE();
-}
-
/********************************************************
Global Functions
********************************************************/
@@ -2015,6 +2094,17 @@ woal_open(struct net_device *dev)
(priv->media_connected || priv->is_adhoc_link_sensed))
carrier_on = MTRUE;
#endif
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT &&
+ IS_STA_CFG80211(cfg80211_wext)) {
+ priv->phandle->wiphy->interface_modes |= MBIT(NL80211_IFTYPE_P2P_GO) |
+ MBIT(NL80211_IFTYPE_P2P_CLIENT);
+ }
+#endif
+#endif
+#endif
if (carrier_on == MTRUE) {
if (!netif_carrier_ok(priv->netdev))
netif_carrier_on(priv->netdev);
@@ -2043,14 +2133,37 @@ woal_close(struct net_device *dev)
ENTER();
#ifdef STA_SUPPORT
#ifdef STA_CFG80211
+ if (IS_STA_CFG80211(cfg80211_wext) && (priv->bss_type == MLAN_BSS_TYPE_STA))
+ woal_clear_conn_params(priv);
if (IS_STA_CFG80211(cfg80211_wext) && priv->scan_request) {
cfg80211_scan_done(priv->scan_request, MTRUE);
priv->scan_request = NULL;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+ if (IS_STA_CFG80211(cfg80211_wext) && priv->sched_scanning) {
+ woal_stop_bg_scan(priv, MOAL_IOCTL_WAIT);
+ priv->bg_scan_start = MFALSE;
+ priv->bg_scan_reported = MFALSE;
+ cfg80211_sched_scan_stopped(priv->wdev->wiphy);
+ priv->sched_scanning = MFALSE;
+ }
+#endif
+#endif
+#endif
+ if (!priv->bss_virtual)
+ woal_stop_queue(priv->netdev);
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT && !priv->bss_virtual &&
+ IS_STA_CFG80211(cfg80211_wext) && IS_UAP_CFG80211(cfg80211_wext)) {
+ priv->phandle->wiphy->interface_modes &= ~(MBIT(NL80211_IFTYPE_P2P_GO) |
+ MBIT
+ (NL80211_IFTYPE_P2P_CLIENT));
+ }
+#endif
#endif
#endif
- woal_stop_queue(priv->netdev);
-
MODULE_PUT;
LEAVE();
@@ -2082,6 +2195,17 @@ woal_set_mac_address(struct net_device *dev, void *addr)
HEXDUMP("addr:", (t_u8 *) phw_addr->sa_data, ETH_ALEN);
memcpy(priv->current_addr, phw_addr->sa_data, ETH_ALEN);
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
+ priv->current_addr[0] |= 0x02;
+ PRINTM(MCMND, "Set WFD device addr: " MACSTR "\n",
+ MAC2STR(priv->current_addr));
+ }
+#endif
+#endif
+#endif
if (MLAN_STATUS_SUCCESS != woal_request_set_mac_address(priv)) {
PRINTM(MERROR, "Set MAC address failed\n");
/* For failure restore the MAC address */
@@ -2097,6 +2221,66 @@ woal_set_mac_address(struct net_device *dev, void *addr)
}
/**
+ * @brief Check driver status
+ *
+ * @param handle A pointer to moal_handle
+ *
+ * @return MTRUE/MFALSE
+ */
+static t_u8
+woal_check_driver_status(moal_handle * handle)
+{
+ moal_private *priv = NULL;
+ int i = 0;
+ ENTER();
+ priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
+ if (!priv || woal_get_debug_info(priv, MOAL_CMD_WAIT, &info)) {
+ PRINTM(MERROR, "Could not retrieve debug information from MLAN\n");
+ LEAVE();
+ return MTRUE;
+ }
+ if (info.num_cmd_timeout) {
+ PRINTM(MERROR, "num_cmd_timeout = %d\n", info.num_cmd_timeout);
+ PRINTM(MERROR, "Timeout cmd id = 0x%x, act = 0x%x \n",
+ info.timeout_cmd_id, info.timeout_cmd_act);
+ LEAVE();
+ return MTRUE;
+ }
+ if (info.num_no_cmd_node) {
+ PRINTM(MERROR, "num_no_cmd_node = %d\n", info.num_no_cmd_node);
+ LEAVE();
+ return MTRUE;
+ }
+ for (i = 0; i < handle->priv_num; i++) {
+ if ((priv = handle->priv[i])) {
+ if (priv->num_tx_timeout >= NUM_TX_TIMEOUT_THRESHOLD) {
+ PRINTM(MERROR, "num_tx_timeout = %d\n", priv->num_tx_timeout);
+ LEAVE();
+ return MTRUE;
+ }
+ }
+ }
+ if (info.data_sent || info.cmd_sent) {
+ if ((jiffies - handle->last_int_jiffies) > MAX_INT_IDLE_TIME) {
+ PRINTM(MERROR, "data_sent=%d cmd_sent=%d\n", info.data_sent,
+ info.cmd_sent);
+ LEAVE();
+ return MTRUE;
+ }
+ }
+ if (info.pm_wakeup_card_req && info.pm_wakeup_fw_try) {
+ if ((jiffies - handle->last_int_jiffies) > MAX_INT_IDLE_TIME) {
+ PRINTM(MERROR, "wakeup_dev_req=%d wakeup_tries=%d\n",
+ info.pm_wakeup_card_req, info.pm_wakeup_fw_try);
+ LEAVE();
+ return MTRUE;
+ }
+ }
+ LEAVE();
+ return MFALSE;
+}
+
+/**
* @brief Display MLAN debug information
*
* @param priv A pointer to moal_private
@@ -2210,6 +2394,9 @@ woal_tx_timeout(struct net_device *dev)
if (priv->num_tx_timeout == NUM_TX_TIMEOUT_THRESHOLD) {
woal_mlan_debug_info(priv);
woal_moal_debug_info(priv, NULL, MFALSE);
+#if defined(DEBUG_LEVEL1)
+#endif
+
}
LEAVE();
@@ -2229,7 +2416,7 @@ woal_get_stats(struct net_device *dev)
return &priv->stats;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
/**
* @brief This function handles wmm queue select
*
@@ -2270,13 +2457,34 @@ woal_select_queue(struct net_device * dev, struct sk_buff * skb)
#endif
/**
+ * @brief This function flush tcp session queue
+ *
+ * @param priv A pointer to moal_private structure
+ *
+ * @return N/A
+ */
+void
+woal_flush_tcp_sess_queue(moal_private * priv)
+{
+ struct tcp_sess *tcp_sess = NULL, *tmp_node;
+ unsigned long flags;
+ spin_lock_irqsave(&priv->tcp_sess_lock, flags);
+ list_for_each_entry_safe(tcp_sess, tmp_node, &priv->tcp_sess_queue, link) {
+ list_del(&tcp_sess->link);
+ kfree(tcp_sess);
+ }
+ INIT_LIST_HEAD(&priv->tcp_sess_queue);
+ spin_unlock_irqrestore(&priv->tcp_sess_lock, flags);
+}
+
+/**
* @brief This function gets tcp session from the tcp session queue
*
* @param priv A pointer to moal_private structure
* @param src_ip IP address of the device
* @param src_port TCP port of the device
* @param dst_ip IP address of the client
- * @param src_port TCP port of the client
+ * @param dst_port TCP port of the client
*
* @return A pointer to the tcp session data structure, if found.
* Otherwise, null
@@ -2302,50 +2510,6 @@ woal_get_tcp_sess(moal_private * priv,
}
/**
- * @brief This function checks received tcp packet for FIN
- * and release the tcp session if received
- *
- * @param priv A pointer to moal_private structure
- * @param skb A pointer to sk_buff structure
- *
- * @return None
- */
-void
-woal_check_tcp_fin(moal_private * priv, struct sk_buff *skb)
-{
- struct ethhdr *ethh = NULL;
- struct iphdr *iph = NULL;
- struct tcphdr *tcph = NULL;
- struct tcp_sess *tcp_sess = NULL;
-
- ENTER();
-
- ethh = eth_hdr(skb);
- if (ntohs(ethh->h_proto) == ETH_P_IP) {
- iph = (struct iphdr *) ((t_u8 *) ethh + sizeof(struct ethhdr));
- if (iph->protocol == IPPROTO_TCP) {
- tcph = (struct tcphdr *) ((t_u8 *) iph + iph->ihl * 4);
- if (tcph->fin) {
- tcp_sess = woal_get_tcp_sess(priv, iph->daddr,
- tcph->dest, iph->saddr,
- tcph->source);
- if (tcp_sess != NULL) {
- PRINTM(MINFO,
- "TX: release a tcp session in dl. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n",
- iph->daddr, tcph->dest, iph->saddr, tcph->source);
- /* remove the tcp session from the queue */
- list_del(&tcp_sess->link);
- kfree(tcp_sess);
- } else {
- PRINTM(MINFO, "Tx: released TCP session is not found.\n ");
- }
- }
- }
- }
- LEAVE();
-}
-
-/**
* @brief This function process tcp ack packets
*
* @param priv A pointer to moal_private structure
@@ -2368,6 +2532,7 @@ woal_process_tcp_ack(moal_private * priv, mlan_buffer * pmbuf)
t_u8 opt_len = 0;
t_u8 *pos = NULL;
t_u32 win_size = 0;
+ unsigned long flags;
#define TCP_ACK_DELAY 3
#define TCP_ACK_INIT_WARMING_UP 1000 /* initial */
@@ -2378,33 +2543,38 @@ woal_process_tcp_ack(moal_private * priv, mlan_buffer * pmbuf)
/** check the tcp packet */
ethh = (struct ethhdr *) (pmbuf->pbuf + pmbuf->data_offset);
if (ntohs(ethh->h_proto) != ETH_P_IP) {
+ LEAVE();
return 0;
}
iph = (struct iphdr *) ((t_u8 *) ethh + sizeof(struct ethhdr));
if (iph->protocol != IPPROTO_TCP) {
+ LEAVE();
return 0;
}
tcph = (struct tcphdr *) ((t_u8 *) iph + iph->ihl * 4);
+ spin_lock_irqsave(&priv->tcp_sess_lock, flags);
if (tcph->syn & tcph->ack) {
- /* respond to a TCP request. create a tcp session */
- if (!(tcp_sess = kmalloc(sizeof(struct tcp_sess), GFP_ATOMIC))) {
- PRINTM(MERROR, "Fail to allocate tcp_sess.\n");
- return 0;
+ tcp_sess = woal_get_tcp_sess(priv, iph->saddr, tcph->source,
+ iph->daddr, tcph->dest);
+ if (!tcp_sess) {
+ /* respond to a TCP request. create a tcp session */
+ if (!(tcp_sess = kmalloc(sizeof(struct tcp_sess), GFP_ATOMIC))) {
+ PRINTM(MERROR, "Fail to allocate tcp_sess.\n");
+ goto done;
+ }
+ memset(tcp_sess, 0, sizeof(struct tcp_sess));
+ tcp_sess->src_ip_addr = iph->saddr; /* my ip addr */
+ tcp_sess->dst_ip_addr = iph->daddr;
+ tcp_sess->src_tcp_port = tcph->source;
+ tcp_sess->dst_tcp_port = tcph->dest;
+ INIT_LIST_HEAD(&tcp_sess->link);
+ list_add_tail(&tcp_sess->link, &priv->tcp_sess_queue);
+ PRINTM(MINFO,
+ "create a tcp session. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n",
+ iph->saddr, tcph->source, iph->daddr, tcph->dest);
}
- memset(tcp_sess, 0, sizeof(struct tcp_sess));
- tcp_sess->src_ip_addr = iph->saddr; /* my ip addr */
- tcp_sess->dst_ip_addr = iph->daddr;
- tcp_sess->src_tcp_port = tcph->source;
- tcp_sess->dst_tcp_port = tcph->dest;
tcp_sess->start_cnt = TCP_ACK_INIT_WARMING_UP;
-
- INIT_LIST_HEAD(&tcp_sess->link);
- list_add_tail(&tcp_sess->link, &priv->tcp_sess_queue);
- PRINTM(MINFO,
- "create a tcp session. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n",
- iph->saddr, tcph->source, iph->daddr, tcph->dest);
-
/* parse tcp options for the window scale */
len = (tcph->doff * 4) - sizeof(struct tcphdr);
pos = (t_u8 *) (tcph + 1);
@@ -2440,12 +2610,12 @@ woal_process_tcp_ack(moal_private * priv, mlan_buffer * pmbuf)
tcp_sess = woal_get_tcp_sess(priv, iph->saddr, tcph->source,
iph->daddr, tcph->dest);
if (tcp_sess == NULL) {
- return 0;
+ goto done;
}
/** do not drop the ack packets initially */
if (tcp_sess->start_cnt) {
tcp_sess->start_cnt--;
- return 0;
+ goto done;
}
/* check the window size. */
@@ -2475,7 +2645,6 @@ woal_process_tcp_ack(moal_private * priv, mlan_buffer * pmbuf)
ack_seq = tcp_sess->ack_seq;
tcp_sess->ack_seq = ntohl(tcph->ack_seq);
tcp_sess->ack_cnt = 0;
- ret = 0;
}
}
} else if (tcph->fin) {
@@ -2492,6 +2661,8 @@ woal_process_tcp_ack(moal_private * priv, mlan_buffer * pmbuf)
PRINTM(MINFO, "released TCP session is not found.\n ");
}
}
+ done:
+ spin_unlock_irqrestore(&priv->tcp_sess_lock, flags);
LEAVE();
return ret;
}
@@ -2511,6 +2682,10 @@ woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
mlan_buffer *pmbuf = NULL;
mlan_status status;
struct sk_buff *new_skb = NULL;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+ t_u32 index = 0;
+ t_u32 tid = 0;
+#endif
ENTER();
@@ -2530,15 +2705,14 @@ woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
priv->stats.tx_dropped++;
goto done;
}
- if (skb->cloned ||
- (skb_headroom(skb) <
- (MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer)))) {
+ if (skb->cloned || (skb_headroom(skb) < (MLAN_MIN_DATA_HEADER_LEN +
+ sizeof(mlan_buffer) +
+ priv->extra_tx_head_len))) {
PRINTM(MWARN, "Tx: Insufficient skb headroom %d\n", skb_headroom(skb));
/* Insufficient skb headroom - allocate a new skb */
- new_skb =
- skb_realloc_headroom(skb,
- MLAN_MIN_DATA_HEADER_LEN +
- sizeof(mlan_buffer));
+ new_skb = skb_realloc_headroom(skb, MLAN_MIN_DATA_HEADER_LEN +
+ sizeof(mlan_buffer) +
+ priv->extra_tx_head_len);
if (unlikely(!new_skb)) {
PRINTM(MERROR, "Tx: Cannot allocate skb\n");
dev_kfree_skb_any(skb);
@@ -2557,16 +2731,30 @@ woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (priv->enable_tcp_ack_enh == MTRUE) {
if (woal_process_tcp_ack(priv, pmbuf)) {
/* the ack packet has been dropped */
+ priv->stats.tx_dropped++;
+
goto done;
}
}
-
status = mlan_send_packet(priv->phandle->pmlan_adapter, pmbuf);
switch (status) {
case MLAN_STATUS_PENDING:
atomic_inc(&priv->phandle->tx_pending);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+ tid = pmbuf->priority;
+ index =
+ mlan_select_wmm_queue(priv->phandle->pmlan_adapter, priv->bss_index,
+ tid);
+ atomic_inc(&priv->wmm_tx_pending[index]);
+ if (atomic_read(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) {
+ struct netdev_queue *txq = netdev_get_tx_queue(priv->netdev, index);
+ netif_tx_stop_queue(txq);
+ PRINTM(MINFO, "Stop Kernel Queue : %d\n", index);
+ }
+#else
if (atomic_read(&priv->phandle->tx_pending) >= MAX_TX_PENDING)
woal_stop_queue(priv->netdev);
+#endif /* #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) */
queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
break;
case MLAN_STATUS_SUCCESS:
@@ -2795,8 +2983,6 @@ woal_set_multicast_list(struct net_device *dev)
void
woal_init_priv(moal_private * priv, t_u8 wait_option)
{
- struct list_head *link = NULL;
- struct tcp_sess *tcp_sess = NULL;
ENTER();
#ifdef STA_SUPPORT
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) {
@@ -2814,27 +3000,11 @@ woal_init_priv(moal_private * priv, t_u8 wait_option)
priv->reassoc_on = MFALSE;
priv->set_asynced_essid_flag = MFALSE;
#endif
-#ifdef STA_CFG80211
- if (IS_STA_CFG80211(cfg80211_wext)) {
- if (priv->bss_type == MLAN_BSS_TYPE_STA
-#if defined(WIFI_DIRECT_SUPPORT)
-#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
- || priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT
-#endif
-#endif
- )
- woal_cfg80211_sta_init_wiphy(priv, wait_option);
- }
-#endif
}
#endif /* STA_SUPPORT */
#ifdef UAP_SUPPORT
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
priv->bss_started = MFALSE;
-#ifdef UAP_CFG80211
- if (IS_UAP_CFG80211(cfg80211_wext))
- woal_cfg80211_uap_init_wiphy(priv, wait_option);
-#endif
}
#endif
priv->media_connected = MFALSE;
@@ -2844,34 +3014,42 @@ woal_init_priv(moal_private * priv, t_u8 wait_option)
priv->beacon_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
priv->proberesp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
priv->assocresp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) && !defined(COMPAT_WIRELESS)
priv->beacon_wps_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
-#endif
+ priv->proberesp_p2p_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
#endif
#ifdef STA_SUPPORT
#endif
priv->enable_tcp_ack_enh = MTRUE;
- while (!list_empty(&priv->tcp_sess_queue)) {
- link = priv->tcp_sess_queue.next;
- tcp_sess = list_entry(link, struct tcp_sess, link);
- PRINTM(MINFO,
- "warm reset: release a tcp session in dl. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n",
- tcp_sess->src_ip_addr, tcp_sess->src_tcp_port,
- tcp_sess->dst_ip_addr, tcp_sess->dst_tcp_port);
- list_del(link);
- kfree(tcp_sess);
- }
woal_request_get_fw_info(priv, wait_option, NULL);
+
#if defined(WIFI_DIRECT_SUPPORT)
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
- if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
- priv->current_addr[0] |= 0x02;
- woal_request_set_mac_address(priv);
- memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
- }
+#ifdef MFG_CMD_SUPPORT
+ if (mfg_mode != MLAN_INIT_PARA_ENABLED)
+#endif
+ if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
+ if (priv->bss_virtual) {
+ if (priv->pa_netdev) {
+ memcpy(priv->current_addr, priv->pa_netdev->dev_addr,
+ ETH_ALEN);
+ priv->current_addr[4] ^= 0x80;
+ woal_request_set_mac_address(priv);
+ memcpy(priv->netdev->dev_addr, priv->current_addr,
+ ETH_ALEN);
+ PRINTM(MCMND, "Set WFD interface addr: " MACSTR "\n",
+ MAC2STR(priv->current_addr));
+ }
+ } else {
+ priv->current_addr[0] |= 0x02;
+ woal_request_set_mac_address(priv);
+ memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
+ PRINTM(MCMND, "Set WFD device addr: " MACSTR "\n",
+ MAC2STR(priv->current_addr));
+ }
+ }
#endif
#endif
#endif
@@ -3027,6 +3205,13 @@ woal_alloc_mlan_buffer(moal_handle * handle, int size)
struct sk_buff *skb;
ENTER();
+
+ if (size <= 0) {
+ PRINTM(MERROR, "Buffer size must be positive\n");
+ LEAVE();
+ return NULL;
+ }
+
if (!(pmbuf = kmalloc(sizeof(mlan_buffer), GFP_ATOMIC))) {
PRINTM(MERROR, "%s: Fail to alloc mlan buffer\n", __FUNCTION__);
LEAVE();
@@ -3104,8 +3289,8 @@ woal_free_mlan_buffer(moal_handle * handle, pmlan_buffer pmbuf)
return;
}
-#ifdef STA_WEXT
-#endif
+#ifdef STA_SUPPORT
+#endif /* STA_SUPPORT */
/**
* @brief This function handles events generated by firmware
@@ -3122,9 +3307,11 @@ woal_broadcast_event(moal_private * priv, t_u8 * payload, t_u32 len)
struct sk_buff *skb = NULL;
struct nlmsghdr *nlh = NULL;
moal_handle *handle = priv->phandle;
+ struct net_device *netdev = priv->netdev;
struct sock *sk = handle->nl_sk;
ENTER();
+ len += 1; /* space for the '\0' character at the end */
/* interface name to be prepended to event */
if ((len + IFNAMSIZ) > NL_MAX_PAYLOAD
#ifdef WIFI_DIRECT_SUPPORT
@@ -3163,11 +3350,15 @@ woal_broadcast_event(moal_private * priv, t_u8 * payload, t_u32 len)
/* Data */
skb_put(skb, nlh->nlmsg_len);
- memcpy(NLMSG_DATA(nlh), priv->netdev->name, IFNAMSIZ);
+ memcpy(NLMSG_DATA(nlh), netdev->name, IFNAMSIZ);
memcpy(((t_u8 *) (NLMSG_DATA(nlh))) + IFNAMSIZ, payload, len);
/* From Kernel */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
NETLINK_CB(skb).pid = 0;
+#else
+ NETLINK_CB(skb).portid = 0;
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
/* Multicast message */
@@ -3182,7 +3373,11 @@ woal_broadcast_event(moal_private * priv, t_u8 * payload, t_u32 len)
#endif
/* Send message */
- netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_ATOMIC);
+ ret = netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_ATOMIC);
+ if (ret) {
+ PRINTM(MWARN, "netlink_broadcast failed: ret=%d\n", ret);
+ goto done;
+ }
ret = MLAN_STATUS_SUCCESS;
} else {
@@ -3251,6 +3446,16 @@ woal_reassociation_thread(void *data)
PRINTM(MEVENT, "Reassoc: Thread waking up...\n");
reassoc_timer_req = MFALSE;
+#ifdef STA_CFG80211
+ for (i = 0; i < handle->priv_num && (priv = handle->priv[i]); i++) {
+ if (priv->roaming_required) {
+ priv->roaming_required = MFALSE;
+ PRINTM(MEVENT, "Try to roaming......\n");
+ woal_start_roaming(priv);
+ break;
+ }
+ }
+#endif
for (i = 0; i < handle->priv_num && (priv = handle->priv[i]); i++) {
@@ -3326,6 +3531,12 @@ woal_reassociation_thread(void *data)
status = woal_find_best_network(priv, MOAL_CMD_WAIT, &ssid_bssid);
+ /** The find AP without ssid, we need re-search */
+ if (status == MLAN_STATUS_SUCCESS && !ssid_bssid.ssid.ssid_len) {
+ PRINTM(MINFO, "Reassoc: Skip AP without ssid\n");
+ status = MLAN_STATUS_FAILURE;
+ }
+
if (priv->set_asynced_essid_flag != MTRUE &&
MLAN_STATUS_SUCCESS != status) {
PRINTM(MINFO, "Reassoc: AP not found in scan list\n");
@@ -3405,7 +3616,7 @@ woal_reassociation_thread(void *data)
if (reassoc_timer_req == MTRUE) {
handle->is_reassoc_timer_set = MTRUE;
- if (priv->set_asynced_essid_flag == MTRUE) {
+ if (priv && (priv->set_asynced_essid_flag == MTRUE)) {
PRINTM(MERROR,
"Set Async ESSID: No AP found or assoc failed. \n");
priv->set_asynced_essid_flag = MFALSE;
@@ -3416,7 +3627,9 @@ woal_reassociation_thread(void *data)
woal_mod_timer(&handle->reassoc_timer, timer_val);
}
} else {
- priv->set_asynced_essid_flag = MFALSE;
+ if (priv) {
+ priv->set_asynced_essid_flag = MFALSE;
+ }
}
}
woal_deactivate_thread(pmoal_thread);
@@ -3471,6 +3684,7 @@ woal_send_disconnect_to_system(moal_private * priv)
woal_stop_queue(priv->netdev);
if (netif_carrier_ok(priv->netdev))
netif_carrier_off(priv->netdev);
+ woal_flush_tcp_sess_queue(priv);
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext)) {
memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
@@ -3480,10 +3694,10 @@ woal_send_disconnect_to_system(moal_private * priv)
#endif
#ifdef STA_CFG80211
if (IS_STA_CFG80211(cfg80211_wext)) {
- if (!priv->cfg_disconnect &&
+ if (!priv->cfg_disconnect && !priv->cfg_connect &&
priv->wdev && priv->wdev->iftype != NL80211_IFTYPE_ADHOC) {
- PRINTM(MINFO, "Successfully disconnected from %pM:"
- " Reason code %d\n", priv->cfg_bssid,
+ PRINTM(MMSG, "wlan: Disconnected from " MACSTR ":"
+ " Reason code %d\n", MAC2STR(priv->cfg_bssid),
WLAN_REASON_DEAUTH_LEAVING);
/* This function must be called only when disconnect issued by the
FW, i.e. disconnected by AP. For IBSS mode this call is not
@@ -3493,12 +3707,16 @@ woal_send_disconnect_to_system(moal_private * priv)
GFP_KERNEL);
}
priv->cfg_disconnect = 0;
+ if (!woal_is_any_interface_active(priv->phandle))
+ woal_set_scan_time(priv, ACTIVE_SCAN_CHAN_TIME,
+ PASSIVE_SCAN_CHAN_TIME, SPECIFIC_SCAN_CHAN_TIME);
}
#endif /* STA_CFG80211 */
memset(event_buf, 0, sizeof(event_buf));
custom_len = strlen(CUS_EVT_AP_CONNECTED);
- strncpy(event_buf, CUS_EVT_AP_CONNECTED, custom_len);
+ strncpy(event_buf, CUS_EVT_AP_CONNECTED,
+ MIN((sizeof(event_buf) - 1), custom_len));
woal_broadcast_event(priv, event_buf, custom_len + ETH_ALEN);
LEAVE();
}
@@ -3591,7 +3809,7 @@ woal_moal_debug_info(moal_private * priv, moal_handle * handle, u8 flag)
{
moal_handle *phandle = NULL;
char buf[MLAN_MAX_VER_STR_LEN];
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
int i = 0;
#endif
@@ -3615,6 +3833,18 @@ woal_moal_debug_info(moal_private * priv, moal_handle * handle, u8 flag)
PRINTM(MERROR, "ioctl_pending = %d\n",
atomic_read(&phandle->ioctl_pending));
PRINTM(MERROR, "tx_pending = %d\n", atomic_read(&phandle->tx_pending));
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+ if (priv) {
+ PRINTM(MERROR, "wmm_tx_pending[0] = %d\n",
+ atomic_read(&priv->wmm_tx_pending[0]));
+ PRINTM(MERROR, "wmm_tx_pending[1] = %d\n",
+ atomic_read(&priv->wmm_tx_pending[1]));
+ PRINTM(MERROR, "wmm_tx_pending[2] = %d\n",
+ atomic_read(&priv->wmm_tx_pending[2]));
+ PRINTM(MERROR, "wmm_tx_pending[3] = %d\n",
+ atomic_read(&priv->wmm_tx_pending[3]));
+ }
+#endif
PRINTM(MERROR, "rx_pending = %d\n", atomic_read(&phandle->rx_pending));
PRINTM(MERROR, "lock_count = %d\n", atomic_read(&phandle->lock_count));
PRINTM(MERROR, "malloc_count = %d\n", atomic_read(&phandle->malloc_count));
@@ -3631,11 +3861,11 @@ woal_moal_debug_info(moal_private * priv, moal_handle * handle, u8 flag)
MFALSE) ? "Disconnected" : "Connected"));
PRINTM(MERROR, "carrier %s\n",
((netif_carrier_ok(priv->netdev)) ? "on" : "off"));
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
for (i = 0; i < (priv->netdev->num_tx_queues); i++) {
PRINTM(MERROR, "tx queue %d: %s\n", i,
((netif_tx_queue_stopped
- (netdev_get_tx_queue(priv->netdev, 0))) ? "stopped" :
+ (netdev_get_tx_queue(priv->netdev, i))) ? "stopped" :
"started"));
}
#else
@@ -3722,8 +3952,16 @@ woal_interrupt(moal_handle * handle)
LEAVE();
return;
}
+ handle->last_int_jiffies = jiffies;
/* call mlan_interrupt to read int status */
mlan_interrupt(handle->pmlan_adapter);
+#ifdef SDIO_SUSPEND_RESUME
+ if (handle->is_suspended) {
+ PRINTM(MINTR, "Receive interrupt in hs_suspended\n");
+ LEAVE();
+ return;
+ }
+#endif
handle->main_state = MOAL_START_MAIN_PROCESS;
/* Call MLAN main process */
mlan_main_process(handle->pmlan_adapter);
@@ -3746,6 +3984,11 @@ woal_add_card(void *card)
mlan_status status = MLAN_STATUS_SUCCESS;
int netlink_num = NETLINK_MARVELL;
int index = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct netlink_kernel_cfg cfg = {
+ .groups = NL_MULTICAST_GROUP,
+ };
+#endif
ENTER();
@@ -3785,7 +4028,11 @@ woal_add_card(void *card)
}
}
+ /* Update card type */
+ woal_sdio_update_card_type(handle, card);
+
((struct sdio_mmc_card *) card)->handle = handle;
+
#ifdef STA_SUPPORT
handle->scan_pending_on_block = MFALSE;
MOAL_INIT_SEMAPHORE(&handle->async_sem);
@@ -3811,9 +4058,18 @@ woal_add_card(void *card)
netlink_kernel_create(netlink_num, NL_MULTICAST_GROUP, NULL, NULL,
THIS_MODULE);
#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
handle->nl_sk =
netlink_kernel_create(&init_net, netlink_num, NL_MULTICAST_GROUP,
NULL, NULL, THIS_MODULE);
+#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
+ handle->nl_sk =
+ netlink_kernel_create(&init_net, netlink_num, THIS_MODULE, &cfg);
+#else
+ handle->nl_sk = netlink_kernel_create(&init_net, netlink_num, &cfg);
+#endif
+#endif
#endif
#endif
#endif
@@ -3871,6 +4127,15 @@ woal_add_card(void *card)
return handle;
err_init_fw:
+ if ((handle->hardware_status == HardwareStatusFwReady) ||
+ (handle->hardware_status == HardwareStatusReady)) {
+ PRINTM(MINFO, "shutdown mlan\n");
+ handle->init_wait_q_woken = MFALSE;
+ status = mlan_shutdown_fw(handle->pmlan_adapter);
+ if (status == MLAN_STATUS_PENDING)
+ wait_event_interruptible(handle->init_wait_q,
+ handle->init_wait_q_woken);
+ }
/* Unregister device */
PRINTM(MINFO, "unregister device\n");
woal_unregister_dev(handle);
@@ -3887,15 +4152,6 @@ woal_add_card(void *card)
#endif /* REASSOCIATION */
woal_terminate_workqueue(handle);
err_kmalloc:
- if ((handle->hardware_status == HardwareStatusFwReady) ||
- (handle->hardware_status == HardwareStatusReady)) {
- PRINTM(MINFO, "shutdown mlan\n");
- handle->init_wait_q_woken = MFALSE;
- status = mlan_shutdown_fw(handle->pmlan_adapter);
- if (status == MLAN_STATUS_PENDING)
- wait_event_interruptible(handle->init_wait_q,
- handle->init_wait_q_woken);
- }
woal_free_moal_handle(handle);
if (index < MAX_MLAN_ADAPTER) {
m_handle[index] = NULL;
@@ -3967,7 +4223,15 @@ woal_remove_card(void *card)
atomic_read(&handle->tx_pending),
atomic_read(&handle->ioctl_pending));
}
-
+ unregister_inetaddr_notifier(&woal_notifier);
+#if defined(WIFI_DIRECT_SUPPORT)
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ /* Remove virtual interface */
+ woal_remove_virtual_interface(handle);
+#endif
+#endif
+#endif
/* Remove interface */
for (i = 0; i < handle->priv_num; i++)
woal_remove_interface(handle, i);
@@ -4020,6 +4284,7 @@ woal_remove_card(void *card)
return MLAN_STATUS_SUCCESS;
}
+#ifdef CONFIG_PROC_FS
/**
* @brief This function switch the drv_mode
*
@@ -4072,6 +4337,8 @@ woal_switch_drv_mode(moal_handle * handle, t_u32 mode)
atomic_read(&handle->ioctl_pending));
}
+ unregister_inetaddr_notifier(&woal_notifier);
+
/* Remove interface */
for (i = 0; i < handle->priv_num; i++)
woal_remove_interface(handle, i);
@@ -4111,6 +4378,7 @@ woal_switch_drv_mode(moal_handle * handle, t_u32 mode)
LEAVE();
return status;
}
+#endif
/**
* @brief This function initializes module.
@@ -4125,6 +4393,7 @@ woal_init_module(void)
ENTER();
+ PRINTM(MMSG, "wlan: Loading MWLAN driver\n");
/* Init the wlan_private pointer array first */
for (index = 0; index < MAX_MLAN_ADAPTER; index++) {
m_handle[index] = NULL;
@@ -4132,10 +4401,12 @@ woal_init_module(void)
/* Init mutex */
MOAL_INIT_SEMAPHORE(&AddRemoveCardSem);
- wifi_add_dev();
-
/* Register with bus */
ret = woal_bus_register();
+ if (ret == MLAN_STATUS_SUCCESS)
+ PRINTM(MMSG, "wlan: Driver loaded successfully\n");
+ else
+ PRINTM(MMSG, "wlan: Driver loading failed\n");
LEAVE();
return ret;
@@ -4155,6 +4426,7 @@ woal_cleanup_module(void)
ENTER();
+ PRINTM(MMSG, "wlan: Unloading MWLAN driver\n");
if (MOAL_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
goto exit_sem_err;
for (index = 0; index < MAX_MLAN_ADAPTER; index++) {
@@ -4163,13 +4435,15 @@ woal_cleanup_module(void)
continue;
if (!handle->priv_num)
goto exit;
+ if (MTRUE == woal_check_driver_status(handle))
+ goto exit;
#ifdef SDIO_SUSPEND_RESUME
#ifdef MMC_PM_KEEP_POWER
if (handle->is_suspended == MTRUE) {
woal_sdio_resume(&(((struct sdio_mmc_card *) handle->card)->func)->
dev);
}
-#endif
+#endif /* MMC_PM_KEEP_POWER */
#endif /* SDIO_SUSPEND_RESUME */
for (i = 0; i < handle->priv_num; i++) {
@@ -4179,10 +4453,23 @@ woal_cleanup_module(void)
woal_disconnect(handle->priv[i], MOAL_CMD_WAIT, NULL);
#ifdef STA_CFG80211
if (IS_STA_CFG80211(cfg80211_wext) &&
+ (handle->priv[i]->bss_type == MLAN_BSS_TYPE_STA))
+ woal_clear_conn_params(handle->priv[i]);
+ if (IS_STA_CFG80211(cfg80211_wext) &&
handle->priv[i]->scan_request) {
cfg80211_scan_done(handle->priv[i]->scan_request, MTRUE);
handle->priv[i]->scan_request = NULL;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+ if (IS_STA_CFG80211(cfg80211_wext) &&
+ handle->priv[i]->sched_scanning) {
+ woal_stop_bg_scan(handle->priv[i], MOAL_IOCTL_WAIT);
+ handle->priv[i]->bg_scan_start = MFALSE;
+ handle->priv[i]->bg_scan_reported = MFALSE;
+ cfg80211_sched_scan_stopped(handle->priv[i]->wdev->wiphy);
+ handle->priv[i]->sched_scanning = MFALSE;
+ }
+#endif
#endif
}
#endif
@@ -4195,10 +4482,7 @@ woal_cleanup_module(void)
}
#endif
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
- if (handle->priv[i]->probereq_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)
- woal_cfg80211_mgmt_frame_ie(handle->priv[i], NULL, 0, NULL, 0,
- NULL, 0, NULL, 0,
- MGMT_MASK_PROBE_REQ);
+ woal_clear_all_mgmt_ies(handle->priv[i]);
#endif
}
@@ -4220,14 +4504,39 @@ woal_cleanup_module(void)
exit_sem_err:
/* Unregister from bus */
woal_bus_unregister();
- wifi_del_dev();
+ PRINTM(MMSG, "wlan: Driver unloaded\n");
LEAVE();
}
+#ifndef MODULE
+#ifdef MFG_CMD_SUPPORT
+/**
+ * @brief This function handle the mfg_mode from kernel boot command
+ *
+ * @param str buffer for mfg_mode
+ * @return N/A
+ */
+static int __init
+mfg_mode_setup(char *str)
+{
+ int val = -1;
+ get_option(&str, &val);
+ if (val > 0)
+ mfg_mode = 1;
+ PRINTM(MMSG, "mfg_mode=%d\n", mfg_mode);
+ return 1;
+}
+
+__setup("mfg_mode=", mfg_mode_setup);
+#endif
+#endif
+
module_init(woal_init_module);
module_exit(woal_cleanup_module);
+module_param(hw_test, int, 0);
+MODULE_PARM_DESC(hw_test, "0: Disable hardware test; 1: Enable hardware test");
module_param(fw_name, charp, 0);
MODULE_PARM_DESC(fw_name, "Firmware name");
module_param(req_fw_nowait, int, 0);
@@ -4263,6 +4572,10 @@ module_param(max_wfd_bss, int, 0);
MODULE_PARM_DESC(max_wfd_bss, "Number of WIFIDIRECT interfaces (1)");
module_param(wfd_name, charp, 0);
MODULE_PARM_DESC(wfd_name, "WIFIDIRECT interface name");
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+module_param(max_vir_bss, int, 0);
+MODULE_PARM_DESC(max_vir_bss, "Number of Virtual interfaces (0)");
+#endif
#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
#ifdef DEBUG_LEVEL1
module_param(drvdbg, uint, 0);
@@ -4289,9 +4602,6 @@ module_param(init_cfg, charp, 0);
MODULE_PARM_DESC(init_cfg, "Init config file name");
module_param(cal_data_cfg, charp, 0);
MODULE_PARM_DESC(cal_data_cfg, "Calibration data file name");
-module_param(minicard_pwrup, int, 1);
-MODULE_PARM_DESC(minicard_pwrup,
- "1: Driver load clears PDn/Rst, unload sets (default); 0: Don't do this.");
module_param(cfg80211_wext, int, 0);
MODULE_PARM_DESC(cfg80211_wext,
#ifdef STA_WEXT
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_main.h b/drivers/net/wireless/sd8797/mlinux/moal_main.h
index de70eef66179..76a95e36a7ba 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_main.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_main.h
@@ -51,6 +51,7 @@ Change log:
#include <linux/vmalloc.h>
#include <linux/ptrace.h>
#include <linux/string.h>
+#include <linux/irqreturn.h>
#include <linux/list.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
@@ -85,19 +86,20 @@ Change log:
#include <net/sock.h>
#include <net/arp.h>
#include <linux/rtnetlink.h>
+#include <linux/inetdevice.h>
#include <linux/firmware.h>
#include "mlan.h"
#include "moal_shim.h"
/* Wireless header */
-#include <linux/wireless.h>
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#include <net/lib80211.h>
#include <net/cfg80211.h>
#include <net/ieee80211_radiotap.h>
#endif
#if defined(STA_WEXT) || defined(UAP_WEXT)
+#include <linux/wireless.h>
#include <net/iw_handler.h>
#include "moal_wext.h"
#endif
@@ -139,7 +141,9 @@ enum
MOAL_NO_WAIT,
MOAL_IOCTL_WAIT,
MOAL_CMD_WAIT,
+#ifdef CONFIG_PROC_FS
MOAL_PROC_WAIT,
+#endif
MOAL_WSTATS_WAIT
};
@@ -500,7 +504,7 @@ in4_pton(const char *src, int srclen, u8 * dst, int delim, const char **end)
#define REQUEST_FW_TIMEOUT 30
/** Default watchdog timeout */
-#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
+#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (10 * HZ)
#ifdef UAP_SUPPORT
/** Default watchdog timeout
@@ -518,9 +522,68 @@ in4_pton(const char *src, int srclen, u8 * dst, int delim, const char **end)
/** AP connected event */
#define CUS_EVT_AP_CONNECTED "EVENT=AP_CONNECTED"
-/** Port release event */
-#ifndef CUS_EVT_PORT_RELEASE
-#define CUS_EVT_PORT_RELEASE "EVENT=PORT_RELEASE"
+/** Custom event : BW changed */
+#define CUS_EVT_BW_CHANGED "EVENT=BW_CHANGED"
+/** Custom event : OBSS scan parameter */
+#define CUS_EVT_OBSS_SCAN_PARAM "EVENT=OBSS_SCAN_PARAM"
+
+/** Custom event : AdHoc link sensed */
+#define CUS_EVT_ADHOC_LINK_SENSED "EVENT=ADHOC_LINK_SENSED"
+/** Custom event : AdHoc link lost */
+#define CUS_EVT_ADHOC_LINK_LOST "EVENT=ADHOC_LINK_LOST"
+/** Custom event : MIC failure, unicast */
+#define CUS_EVT_MLME_MIC_ERR_UNI "MLME-MICHAELMICFAILURE.indication unicast "
+/** Custom event : MIC failure, multicast */
+#define CUS_EVT_MLME_MIC_ERR_MUL "MLME-MICHAELMICFAILURE.indication multicast "
+/** Custom event : Beacon RSSI low */
+#define CUS_EVT_BEACON_RSSI_LOW "EVENT=BEACON_RSSI_LOW"
+/** Custom event : Beacon SNR low */
+#define CUS_EVT_BEACON_SNR_LOW "EVENT=BEACON_SNR_LOW"
+/** Custom event : Beacon RSSI high */
+#define CUS_EVT_BEACON_RSSI_HIGH "EVENT=BEACON_RSSI_HIGH"
+/** Custom event : Beacon SNR high */
+#define CUS_EVT_BEACON_SNR_HIGH "EVENT=BEACON_SNR_HIGH"
+/** Custom event : Max fail */
+#define CUS_EVT_MAX_FAIL "EVENT=MAX_FAIL"
+/** Custom event : Data RSSI low */
+#define CUS_EVT_DATA_RSSI_LOW "EVENT=DATA_RSSI_LOW"
+/** Custom event : Data SNR low */
+#define CUS_EVT_DATA_SNR_LOW "EVENT=DATA_SNR_LOW"
+/** Custom event : Data RSSI high */
+#define CUS_EVT_DATA_RSSI_HIGH "EVENT=DATA_RSSI_HIGH"
+/** Custom event : Data SNR high */
+#define CUS_EVT_DATA_SNR_HIGH "EVENT=DATA_SNR_HIGH"
+/** Custom event : Link Quality */
+#define CUS_EVT_LINK_QUALITY "EVENT=LINK_QUALITY"
+/** Custom event : Port Release */
+#define CUS_EVT_PORT_RELEASE "EVENT=PORT_RELEASE"
+/** Custom event : Pre-Beacon Lost */
+#define CUS_EVT_PRE_BEACON_LOST "EVENT=PRE_BEACON_LOST"
+
+/** Custom event : Deep Sleep awake */
+#define CUS_EVT_DEEP_SLEEP_AWAKE "EVENT=DS_AWAKE"
+
+/** Custom event : Host Sleep activated */
+#define CUS_EVT_HS_ACTIVATED "HS_ACTIVATED "
+/** Custom event : Host Sleep deactivated */
+#define CUS_EVT_HS_DEACTIVATED "HS_DEACTIVATED "
+/** Custom event : Host Sleep wakeup */
+#define CUS_EVT_HS_WAKEUP "HS_WAKEUP"
+
+/** Custom event : WEP ICV error */
+#define CUS_EVT_WEP_ICV_ERR "EVENT=WEP_ICV_ERR"
+
+/** Custom event : Channel Switch Announcment */
+#define CUS_EVT_CHANNEL_SWITCH_ANN "EVENT=CHANNEL_SWITCH_ANN"
+
+/** Custom indiciation message sent to the application layer for WMM changes */
+#define WMM_CONFIG_CHANGE_INDICATION "WMM_CONFIG_CHANGE.indication"
+
+#ifdef UAP_SUPPORT
+/** Custom event : STA connected */
+#define CUS_EVT_STA_CONNECTED "EVENT=STA_CONNECTED"
+/** Custom event : STA disconnected */
+#define CUS_EVT_STA_DISCONNECTED "EVENT=STA_DISCONNECTED"
#endif
/** 10 seconds */
@@ -530,6 +593,21 @@ in4_pton(const char *src, int srclen, u8 * dst, int delim, const char **end)
/** 1 second */
#define MOAL_TIMER_1S 1000
+/** passive scan time */
+#define PASSIVE_SCAN_CHAN_TIME 110
+/** active scan time */
+#define ACTIVE_SCAN_CHAN_TIME 110
+/** specific scan time */
+#define SPECIFIC_SCAN_CHAN_TIME 110
+/** passive scan time */
+#define INIT_PASSIVE_SCAN_CHAN_TIME 80
+/** active scan time */
+#define INIT_ACTIVE_SCAN_CHAN_TIME 80
+/** specific scan time */
+#define INIT_SPECIFIC_SCAN_CHAN_TIME 80
+/** specific scan time after connected */
+#define MIN_SPECIFIC_SCAN_CHAN_TIME 40
+
/** Default value of re-assoc timer */
#define REASSOC_TIMER_DEFAULT 500
@@ -636,8 +714,19 @@ typedef struct _wait_queue
#define MAX_WIFIDIRECT_BSS 1
/** Default WIFIDIRECT BSS */
#define DEF_WIFIDIRECT_BSS 1
+#if defined(STA_CFG80211) && defined(UAP_CFG80211)
+#define DEF_VIRTUAL_BSS 0
+#endif
#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+/** max interrupt idle time 3 sceond */
+#define MAX_INT_IDLE_TIME 3*HZ
+
+/**
+ * the maximum number of adapter supported
+ **/
+#define MAX_MLAN_ADAPTER 2
+
typedef struct _moal_drv_mode
{
/** driver mode */
@@ -710,6 +799,8 @@ struct _moal_private
t_u8 bss_type;
/** BSS role */
t_u8 bss_role;
+ /** bss virtual flag */
+ t_u8 bss_virtual;
/** MAC address information */
t_u8 current_addr[ETH_ALEN];
/** Media connection status */
@@ -718,25 +809,51 @@ struct _moal_private
/** uAP started or not */
BOOLEAN bss_started;
#endif
+ /** IP addr type */
+ t_u32 ip_addr_type;
+ /** IP addr */
+ t_u8 ip_addr[IPADDR_LEN];
#ifdef STA_SUPPORT
/** scan type */
t_u8 scan_type;
/** bg_scan_start */
t_u8 bg_scan_start;
- /** bg_scan reported */
+ /** bg_scan reported */
t_u8 bg_scan_reported;
- /** bg_scan config */
+ /** bg_scan config */
wlan_bgscan_cfg scan_cfg;
+ /** sched scaning flag */
+ t_u8 sched_scanning;
+#ifdef STA_CFG80211
+ /** roaming enabled flag */
+ t_u8 roaming_enabled;
+ /** rssi low threshold */
+ int rssi_low;
+ /** channel for connect */
+ struct ieee80211_channel conn_chan;
+ /** bssid for connect */
+ t_u8 conn_bssid[ETH_ALEN];
+ /** ssid for connect */
+ t_u8 conn_ssid[MLAN_MAX_SSID_LENGTH];
+ /** key data */
+ t_u8 conn_wep_key[MAX_WEP_KEY_SIZE];
+ /** connection param */
+ struct cfg80211_connect_params sme_current;
+ /** roaming required flag */
+ t_u8 roaming_required;
+#endif
#endif
/** Net device pointer */
struct net_device *netdev;
/** Net device statistics structure */
struct net_device_stats stats;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
- /** Country code for regulatory domain */
- t_u8 country_code[COUNTRY_CODE_LEN];
/** Wireless device pointer */
struct wireless_dev *wdev;
+ /** Wireless device */
+ struct wireless_dev w_dev;
+ /** Net device pointer */
+ struct net_device *pa_netdev;
/** channel parameter for UAP/GO */
t_u16 channel;
/** cipher */
@@ -751,15 +868,17 @@ struct _moal_private
t_u16 beacon_index;
/** proberesp ie index */
t_u16 proberesp_index;
+ /** proberesp_p2p_index */
+ t_u16 proberesp_p2p_index;
/** assocresp ie index */
t_u16 assocresp_index;
/** probereq index for mgmt ie */
t_u16 probereq_index;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) && !defined(COMPAT_WIRELESS)
+ /** mgmt_subtype_mask */
+ t_u32 mgmt_subtype_mask;
/** beacon wps index for mgmt ie */
t_u16 beacon_wps_index;
#endif
-#endif
#ifdef STA_CFG80211
#ifdef STA_SUPPORT
/** CFG80211 scan request description */
@@ -768,6 +887,10 @@ struct _moal_private
t_u8 cfg_bssid[ETH_ALEN];
/** Disconnect request from CFG80211 */
bool cfg_disconnect;
+ /** connect request from CFG80211 */
+ bool cfg_connect;
+ /** assoc status */
+ t_u32 assoc_status;
/** rssi_threshold */
s32 cqm_rssi_thold;
/** rssi hysteresis */
@@ -790,7 +913,7 @@ struct _moal_private
/** Proc entry */
struct proc_dir_entry *proc_entry;
/** Proc entry name */
- t_s8 proc_entry_name[IFNAMSIZ];
+ char proc_entry_name[IFNAMSIZ];
/** PROC wait queue */
wait_queue_head_t proc_wait_q __ATTRIB_ALIGN__;
#endif /* CONFIG_PROC_FS */
@@ -851,6 +974,13 @@ struct _moal_private
struct list_head tcp_sess_queue;
/** TCP Ack enhance flag */
t_u8 enable_tcp_ack_enh;
+ /** TCP session spin lock */
+ spinlock_t tcp_sess_lock;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+ atomic_t wmm_tx_pending[4];
+#endif
+ /** per interface extra headroom */
+ t_u16 extra_tx_head_len;
};
/** Handle data structure for MOAL */
@@ -916,6 +1046,8 @@ struct _moal_handle
atomic_t lock_count;
/** Malloc count */
atomic_t malloc_count;
+ /** vmalloc count */
+ atomic_t vmalloc_count;
/** mlan buffer alloc count */
atomic_t mbufalloc_count;
#if defined(SDIO_SUSPEND_RESUME)
@@ -938,18 +1070,30 @@ struct _moal_handle
/** Bitmap for re-association on/off */
t_u8 reassoc_on;
#endif /* REASSOCIATION */
+ t_u32 last_int_jiffies;
/** Driver workqueue */
struct workqueue_struct *workqueue;
/** main work */
struct work_struct main_work;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
+ struct wiphy *wiphy;
+ /** Country code for regulatory domain */
+ t_u8 country_code[COUNTRY_CODE_LEN];
+ /** band */
+ enum ieee80211_band band;
+ /** first scan done flag */
+ t_u8 first_scan_done;
#ifdef WIFI_DIRECT_SUPPORT
/** remain on channel flag */
t_u8 remain_on_channel;
+ /** bss index for remain on channel */
+ t_u8 remain_bss_index;
/** ieee802_11_channel */
struct ieee80211_channel chan;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
/** channel type */
enum nl80211_channel_type channel_type;
+#endif
/** cookie */
t_u64 cookie;
/** GO timer set flag */
@@ -957,6 +1101,10 @@ struct _moal_handle
/** GO timer */
moal_drv_timer go_timer __ATTRIB_ALIGN__;
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)|| defined(COMPAT_WIRELESS)
+ /** cfg80211_suspend status */
+ t_u8 cfg80211_suspend;
+#endif
#endif
/** Read SDIO registers for debugging */
t_u32 sdio_reg_dbg;
@@ -1002,12 +1150,16 @@ struct _moal_handle
t_u8 cmd52_reg;
/** cmd52 value */
t_u8 cmd52_val;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
/** spinlock to stop_queue/wake_queue*/
spinlock_t queue_lock;
#endif
/** Driver spin lock */
spinlock_t driver_lock;
+ /** Card type */
+ t_u16 card_type;
+ /** Card specific driver version */
+ t_s8 driver_version[MLAN_MAX_VER_STR_LEN];
};
/**
@@ -1039,7 +1191,7 @@ woal_set_trans_start(struct net_device *dev)
static inline void
woal_start_queue(struct net_device *dev)
{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29)
netif_start_queue(dev);
#else
netif_tx_start_all_queues(dev);
@@ -1056,7 +1208,7 @@ woal_start_queue(struct net_device *dev)
static inline void
woal_stop_queue(struct net_device *dev)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
unsigned long flags;
moal_private *priv = (moal_private *) netdev_priv(dev);
spin_lock_irqsave(&priv->phandle->queue_lock, flags);
@@ -1081,7 +1233,7 @@ woal_stop_queue(struct net_device *dev)
static inline void
woal_wake_queue(struct net_device *dev)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
unsigned long flags;
moal_private *priv = (moal_private *) netdev_priv(dev);
spin_lock_irqsave(&priv->phandle->queue_lock, flags);
@@ -1094,38 +1246,57 @@ woal_wake_queue(struct net_device *dev)
#endif
}
-/** Max number of char in custom event - use multiple of them if needed */
-#define IW_CUSTOM_MAX 256 /* In bytes */
-
/** Debug Macro definition*/
#ifdef DEBUG_LEVEL1
extern t_u32 drvdbg;
+#define LOG_CTRL(level) (0)
+
#ifdef DEBUG_LEVEL2
-#define PRINTM_MINFO(msg...) do {if (drvdbg & MINFO) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MWARN(msg...) do {if (drvdbg & MWARN) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MENTRY(msg...) do {if (drvdbg & MENTRY) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MINFO(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MINFO) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MWARN(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MWARN) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MENTRY(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MENTRY) printk(KERN_DEBUG msg);} while(0)
#else
-#define PRINTM_MINFO(msg...) do {} while (0)
-#define PRINTM_MWARN(msg...) do {} while (0)
-#define PRINTM_MENTRY(msg...) do {} while (0)
+#define PRINTM_MINFO(level,msg...) do {} while (0)
+#define PRINTM_MWARN(level,msg...) do {} while (0)
+#define PRINTM_MENTRY(level,msg...) do {} while (0)
#endif /* DEBUG_LEVEL2 */
-#define PRINTM_MFW_D(msg...) do {if (drvdbg & MFW_D) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MCMD_D(msg...) do {if (drvdbg & MCMD_D) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MDAT_D(msg...) do {if (drvdbg & MDAT_D) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MIF_D(msg...) do {if (drvdbg & MIF_D) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MFW_D(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MFW_D) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MCMD_D(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MCMD_D) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MDAT_D(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MDAT_D) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MIF_D(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MIF_D) printk(KERN_DEBUG msg);} while(0)
+
+#define PRINTM_MIOCTL(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MIOCTL) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MINTR(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MINTR) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MEVENT(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MEVENT) printk(msg);} while(0)
+#define PRINTM_MCMND(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MCMND) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MDATA(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MDATA) printk(KERN_DEBUG msg);} while(0)
+#define PRINTM_MERROR(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MERROR) printk(KERN_ERR msg);} while(0)
+#define PRINTM_MFATAL(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MFATAL) printk(KERN_ERR msg);} while(0)
+#define PRINTM_MMSG(level,msg...) do {woal_print(level,msg); \
+ if (drvdbg & MMSG) printk(KERN_ALERT msg);} while(0)
-#define PRINTM_MIOCTL(msg...) do {if (drvdbg & MIOCTL) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MINTR(msg...) do {if (drvdbg & MINTR) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MEVENT(msg...) do {if (drvdbg & MEVENT) printk(msg);} while(0)
-#define PRINTM_MCMND(msg...) do {if (drvdbg & MCMND) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MDATA(msg...) do {if (drvdbg & MDATA) printk(KERN_DEBUG msg);} while(0)
-#define PRINTM_MERROR(msg...) do {if (drvdbg & MERROR) printk(KERN_ERR msg);} while(0)
-#define PRINTM_MFATAL(msg...) do {if (drvdbg & MFATAL) printk(KERN_ERR msg);} while(0)
-#define PRINTM_MMSG(msg...) do {if (drvdbg & MMSG) printk(KERN_ALERT msg);} while(0)
+static inline void
+woal_print(t_u32 level, char *fmt, ...)
+{
+}
-#define PRINTM(level,msg...) PRINTM_##level(msg)
+#define PRINTM(level,msg...) PRINTM_##level(level,msg)
#else
@@ -1154,34 +1325,43 @@ do { \
#define MAX_DUMP_PER_LINE 16
static inline void
-hexdump(char *prompt, t_u8 * buf, int len)
+hexdump(t_u32 level, char *prompt, t_u8 * buf, int len)
{
int i;
char dbgdumpbuf[DBG_DUMP_BUF_LEN];
char *ptr = dbgdumpbuf;
- printk(KERN_DEBUG "%s:\n", prompt);
+ if (drvdbg & level)
+ printk(KERN_DEBUG "%s:\n", prompt);
for (i = 1; i <= len; i++) {
ptr += snprintf(ptr, 4, "%02x ", *buf);
buf++;
if (i % MAX_DUMP_PER_LINE == 0) {
*ptr = 0;
- printk(KERN_DEBUG "%s\n", dbgdumpbuf);
+ if (drvdbg & level)
+ printk(KERN_DEBUG "%s\n", dbgdumpbuf);
ptr = dbgdumpbuf;
}
}
if (len % MAX_DUMP_PER_LINE) {
*ptr = 0;
- printk(KERN_DEBUG "%s\n", dbgdumpbuf);
+ if (drvdbg & level)
+ printk(KERN_DEBUG "%s\n", dbgdumpbuf);
}
}
-#define DBG_HEXDUMP_MERROR(x,y,z) do {if (drvdbg & MERROR) hexdump(x,y,z);} while(0)
-#define DBG_HEXDUMP_MCMD_D(x,y,z) do {if (drvdbg & MCMD_D) hexdump(x,y,z);} while(0)
-#define DBG_HEXDUMP_MDAT_D(x,y,z) do {if (drvdbg & MDAT_D) hexdump(x,y,z);} while(0)
-#define DBG_HEXDUMP_MIF_D(x,y,z) do {if (drvdbg & MIF_D) hexdump(x,y,z);} while(0)
-#define DBG_HEXDUMP_MEVT_D(x,y,z) do {if (drvdbg & MEVT_D) hexdump(x,y,z);} while(0)
-#define DBG_HEXDUMP_MFW_D(x,y,z) do {if (drvdbg & MFW_D) hexdump(x,y,z);} while(0)
+#define DBG_HEXDUMP_MERROR(x,y,z) do {if ((drvdbg & MERROR) || \
+ LOG_CTRL(MERROR)) hexdump(MERROR,x,y,z);} while(0)
+#define DBG_HEXDUMP_MCMD_D(x,y,z) do {if ((drvdbg & MCMD_D) || \
+ LOG_CTRL(MCMD_D)) hexdump(MCMD_D,x,y,z);} while(0)
+#define DBG_HEXDUMP_MDAT_D(x,y,z) do {if ((drvdbg & MDAT_D) || \
+ LOG_CTRL(MDAT_D)) hexdump(MDAT_D,x,y,z);} while(0)
+#define DBG_HEXDUMP_MIF_D(x,y,z) do {if ((drvdbg & MIF_D) || \
+ LOG_CTRL(MIF_D)) hexdump(MIF_D,x,y,z);} while(0)
+#define DBG_HEXDUMP_MEVT_D(x,y,z) do {if ((drvdbg & MEVT_D) || \
+ LOG_CTRL(MEVT_D)) hexdump(MEVT_D,x,y,z);} while(0)
+#define DBG_HEXDUMP_MFW_D(x,y,z) do {if ((drvdbg & MFW_D) || \
+ LOG_CTRL(MFW_D)) hexdump(MFW_D,x,y,z);} while(0)
#define DBG_HEXDUMP(level,x,y,z) DBG_HEXDUMP_##level(x,y,z)
#else
@@ -1190,7 +1370,8 @@ hexdump(char *prompt, t_u8 * buf, int len)
#endif
#ifdef DEBUG_LEVEL2
-#define HEXDUMP(x,y,z) do {if (drvdbg & MINFO) hexdump(x,y,z);} while(0)
+#define HEXDUMP(x,y,z) do {if ((drvdbg & MINFO) || \
+ LOG_CTRL(MINFO)) hexdump(MINFO,x,y,z);} while(0)
#else
/** Do nothing since debugging is not turned on */
#define HEXDUMP(x,y,z) do {} while (0)
@@ -1248,6 +1429,30 @@ woal_get_priv(moal_handle * handle, mlan_bss_role bss_role)
return NULL;
}
+/**
+ * @brief This function returns first available priv
+ * based on the BSS type
+ *
+ * @param handle A pointer to moal_handle
+ * @param bss_type BSS type or MLAN_BSS_TYPE_ANY
+ *
+ * @return Pointer to moal_private
+ */
+static inline moal_private *
+woal_get_priv_bss_type(moal_handle * handle, mlan_bss_type bss_type)
+{
+ int i;
+
+ for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) {
+ if (handle->priv[i]) {
+ if (bss_type == MLAN_BSS_TYPE_ANY ||
+ handle->priv[i]->bss_type == bss_type)
+ return (handle->priv[i]);
+ }
+ }
+ return NULL;
+}
+
/** Max line length allowed in init config file */
#define MAX_LINE_LEN 256
/** Max MAC address string length allowed */
@@ -1282,6 +1487,11 @@ typedef struct _HostCmd_DS_802_11_CFG_DATA
t_u8 data[1];
} __ATTRIB_PACK__ HostCmd_DS_802_11_CFG_DATA;
+/** SD8797 card type */
+#define CARD_TYPE_SD8797 0x01
+/** SD8782 card type */
+#define CARD_TYPE_SD8782 0x02
+
/** combo scan header */
#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
/** combo scan header size */
@@ -1300,6 +1510,19 @@ typedef struct _HostCmd_DS_802_11_CFG_DATA
#define WEXT_BGSCAN_INTERVAL_SECTION 'T'
/** BGSCAN REPEAT SECTION */
#define WEXT_BGSCAN_REPEAT_SECTION 'E'
+/** Min BGSCAN interval 30 second */
+#define MIN_BGSCAN_INTERVAL 30000
+/** default repeat count */
+#define DEF_REPEAT_COUNT 6
+
+/** default rssi low threshold */
+#define DEFAULT_RSSI_LOW_THRESHOLD 70
+/** RSSI HYSTERSIS */
+#define RSSI_HYSTERESIS 6
+/** lowest rssi threshold */
+#define LOWEST_RSSI_THRESHOLD 82
+/** delta rssi */
+#define DELTA_RSSI 10
/** NL80211 scan configuration header */
#define NL80211_SCANCFG_HEADER "SCAN-CFG "
@@ -1356,14 +1579,14 @@ mlan_status woal_remove_card(void *card);
/** broadcast event */
mlan_status woal_broadcast_event(moal_private * priv, t_u8 * payload,
t_u32 len);
+#ifdef CONFIG_PROC_FS
/** switch driver mode */
mlan_status woal_switch_drv_mode(moal_handle * handle, t_u32 mode);
+#endif
/** Interrupt handler */
void woal_interrupt(moal_handle * handle);
-#ifdef STA_WEXT
-#endif
/** Get version */
void woal_get_version(moal_handle * handle, char *version, int maxlen);
/** Get Driver Version */
@@ -1388,7 +1611,9 @@ void woal_request_set_multicast_list(moal_private * priv,
/** Request IOCTL action */
mlan_status woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req,
t_u8 wait_option);
+#ifdef CONFIG_PROC_FS
mlan_status woal_request_soft_reset(moal_handle * handle);
+#endif
#ifdef PROC_DEBUG
/** Get debug information */
mlan_status woal_get_debug_info(moal_private * priv, t_u8 wait_option,
@@ -1432,19 +1657,23 @@ void woal_send_disconnect_to_system(moal_private * priv);
void woal_send_mic_error_event(moal_private * priv, t_u32 event);
void woal_ioctl_get_bss_resp(moal_private * priv, mlan_ds_bss * bss);
void woal_ioctl_get_info_resp(moal_private * priv, mlan_ds_get_info * info);
+mlan_status woal_get_assoc_rsp(moal_private * priv,
+ mlan_ds_misc_assoc_rsp * assoc_rsp);
/** Get signal information */
mlan_status woal_get_signal_info(moal_private * priv, t_u8 wait_option,
mlan_ds_get_signal * signal);
/** Get mode */
t_u32 woal_get_mode(moal_private * priv, t_u8 wait_option);
+char *region_code_2_string(t_u8 region_code);
+t_u8 woal_is_valid_alpha2(char *alpha2);
+/** Get statistics information */
+mlan_status woal_get_stats_info(moal_private * priv, t_u8 wait_option,
+ mlan_ds_get_stats * stats);
#ifdef STA_WEXT
/** Get data rates */
mlan_status woal_get_data_rates(moal_private * priv, t_u8 wait_option,
moal_802_11_rates * m_rates);
-void woal_send_iwevcustom_event(moal_private * priv, t_s8 * str);
-/** Get statistics information */
-mlan_status woal_get_stats_info(moal_private * priv, t_u8 wait_option,
- mlan_ds_get_stats * stats);
+void woal_send_iwevcustom_event(moal_private * priv, char *str);
/** Get channel list */
mlan_status woal_get_channel_list(moal_private * priv, t_u8 wait_option,
mlan_chan_list * chanlist);
@@ -1528,7 +1757,6 @@ int woal_get_bss_type(struct net_device *dev, struct ifreq *req);
#if defined(STA_WEXT) || defined(UAP_WEXT)
int woal_host_command(moal_private * priv, struct iwreq *wrq);
#endif
-#if defined(WIFI_DIRECT_SUPPORT)
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
mlan_status woal_bss_role_cfg(moal_private * priv, t_u8 action,
t_u8 wait_option, t_u8 * bss_role);
@@ -1539,7 +1767,6 @@ void woal_go_timer_func(void *context);
int woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq);
#endif
#endif
-#endif
#if defined(WIFI_DIRECT_SUPPORT) || defined(UAP_SUPPORT)
/** hostcmd ioctl for uap, wifidirect */
int woal_hostcmd_ioctl(struct net_device *dev, struct ifreq *req);
@@ -1574,6 +1801,8 @@ void woal_debug_remove(moal_private * priv);
/** check pm info */
mlan_status woal_get_pm_info(moal_private * priv, mlan_ds_ps_info * pm_info);
+/** get mlan debug info */
+void woal_mlan_debug_info(moal_private * priv);
#ifdef REASSOCIATION
int woal_reassociation_thread(void *data);
@@ -1583,12 +1812,17 @@ void woal_reassoc_timer_func(void *context);
t_void woal_main_work_queue(struct work_struct *work);
int woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
+#ifdef STA_SUPPORT
+mlan_status woal_init_sta_dev(struct net_device *dev, moal_private * priv);
+#endif
+#ifdef UAP_SUPPORT
+mlan_status woal_init_uap_dev(struct net_device *dev, moal_private * priv);
+#endif
moal_private *woal_add_interface(moal_handle * handle, t_u8 bss_num,
t_u8 bss_type);
void woal_remove_interface(moal_handle * handle, t_u8 bss_index);
void woal_set_multicast_list(struct net_device *dev);
mlan_status woal_request_fw(moal_handle * handle);
-
int woal_11h_channel_check_ioctl(moal_private * priv);
void woal_cancel_cac_block(moal_private * priv);
void woal_moal_debug_info(moal_private * priv, moal_handle * handle, u8 flag);
@@ -1596,6 +1830,7 @@ void woal_moal_debug_info(moal_private * priv, moal_handle * handle, u8 flag);
#ifdef STA_SUPPORT
mlan_status woal_get_powermode(moal_private * priv, int *powermode);
mlan_status woal_set_scan_type(moal_private * priv, t_u32 scan_type);
+mlan_status woal_enable_ext_scan(moal_private * priv, t_u8 enable);
mlan_status woal_set_powermode(moal_private * priv, char *powermode);
int woal_find_essid(moal_private * priv, mlan_ssid_bssid * ssid_bssid);
mlan_status woal_do_scan(moal_private * priv, wlan_user_scan_cfg * scan_cfg);
@@ -1607,30 +1842,38 @@ mlan_status woal_get_band(moal_private * priv, int *band);
mlan_status woal_set_band(moal_private * priv, char *pband);
mlan_status woal_add_rxfilter(moal_private * priv, char *rxfilter);
mlan_status woal_remove_rxfilter(moal_private * priv, char *rxfilter);
-mlan_status woal_set_qos_cfg(moal_private * priv, char *qos_cfg);
+mlan_status woal_priv_qos_cfg(moal_private * priv, t_u32 action, char *qos_cfg);
int woal_set_sleeppd(moal_private * priv, char *psleeppd);
int woal_set_scan_cfg(moal_private * priv, char *buf, int length);
/* EVENT: BCN_RSSI_LOW */
#define EVENT_BCN_RSSI_LOW 0x0001
/* EVENT: PRE_BCN_LOST */
#define EVENT_PRE_BCN_LOST 0x0002
-mlan_status woal_set_rssi_low_threshold(moal_private * priv, char *rssi);
-mlan_status woal_set_rssi_threshold(moal_private * priv, t_u32 event_id);
+mlan_status woal_set_rssi_low_threshold(moal_private * priv, char *rssi,
+ t_u8 wait_option);
+mlan_status woal_set_rssi_threshold(moal_private * priv, t_u32 event_id,
+ t_u8 wait_option);
/* EVENT: BG_SCAN_REPORT */
#define EVENT_BG_SCAN_REPORT 0x0004
mlan_status woal_set_bg_scan(moal_private * priv, char *buf, int length);
-mlan_status woal_stop_bg_scan(moal_private * priv);
+mlan_status woal_stop_bg_scan(moal_private * priv, t_u8 wait_option);
void woal_reconfig_bgscan(moal_handle * handle);
+#ifdef STA_CFG80211
+void woal_config_bgscan_and_rssi(moal_private * priv, t_u8 set_rssi);
+void woal_save_conn_params(moal_private * priv,
+ struct cfg80211_connect_params *sme);
+void woal_clear_conn_params(moal_private * priv);
+void woal_start_roaming(moal_private * priv);
+#endif
+mlan_status woal_request_bgscan(moal_private * priv, t_u8 wait_option,
+ wlan_bgscan_cfg * scan_cfg);
#endif
-struct tcp_sess *woal_get_tcp_sess(moal_private * priv,
- t_u32 src_ip, t_u16 src_port,
- t_u32 dst_ip, t_u16 dst_port);
-void woal_check_tcp_fin(moal_private * priv, struct sk_buff *skb);
-
+void woal_flush_tcp_sess_queue(moal_private * priv);
void wlan_scan_create_brief_table_entry(t_u8 ** ppbuffer,
BSSDescriptor_t * pbss_desc);
int wlan_get_scan_table_ret_entry(BSSDescriptor_t * pbss_desc, t_u8 ** ppbuffer,
int *pspace_left);
BOOLEAN woal_ssid_valid(mlan_802_11_ssid * pssid);
+int woal_is_connected(moal_private * priv, mlan_ssid_bssid * ssid_bssid);
#endif /* _MOAL_MAIN_H */
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_priv.c b/drivers/net/wireless/sd8797/mlinux/moal_priv.c
index fd866346ee63..559da684299c 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_priv.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_priv.c
@@ -27,9 +27,6 @@ Change log:
#include "moal_main.h"
#include "moal_sdio.h"
-#if defined(STA_CFG80211) && defined(UAP_CFG80211)
-#include "moal_cfg80211.h"
-#endif
#include "moal_eth_ioctl.h"
/********************************************************
@@ -63,6 +60,97 @@ extern int cfg80211_wext;
Local Functions
********************************************************/
+/**
+ * @brief Associated to a specific indexed entry in the ScanTable
+ *
+ * @param priv A pointer to moal_private structure
+ * @param req A pointer to ifreq structure
+ *
+ * @return 0 --success, otherwise fail
+ */
+static int
+woal_associate_ssid_bssid(moal_private * priv, struct iwreq *wrq)
+{
+ mlan_ssid_bssid ssid_bssid;
+#ifdef REASSOCIATION
+ mlan_bss_info bss_info;
+#endif
+ char buf[64];
+ t_u8 buflen;
+ t_u8 mac_idx;
+ t_u8 i;
+
+ ENTER();
+
+ mac_idx = 0;
+ buflen = MIN(wrq->u.data.length, (sizeof(buf) - 1));
+ memset(buf, 0, sizeof(buf));
+
+ if (buflen < (3 * ETH_ALEN) + 2) {
+ PRINTM(MERROR, "Associate: Insufficient length in IOCTL input\n");
+
+ /* buffer should be at least 3 characters per BSSID octet "00:" ** plus
+ a space separater and at least 1 char in the SSID */
+ LEAVE();
+ return -EINVAL;
+ }
+
+ if (copy_from_user(buf, wrq->u.data.pointer, buflen) != 0) {
+ /* copy_from_user failed */
+ PRINTM(MERROR, "Associate: copy from user failed\n");
+ LEAVE();
+ return -EINVAL;
+ }
+
+ for (i = 0; (i < buflen) && (buf[i] == ' '); i++) {
+ /* Skip white space */
+ }
+
+ /* Copy/Convert the BSSID */
+ for (; (i < buflen) && (mac_idx < ETH_ALEN) && (buf[i] != ' '); i++) {
+ if (buf[i] == ':') {
+ mac_idx++;
+ } else {
+ ssid_bssid.bssid[mac_idx] = (t_u8) woal_atox(buf + i);
+
+ while ((isxdigit(buf[i + 1]) && (i < buflen))) {
+ /* Skip entire hex value */
+ i++;
+ }
+ }
+ }
+
+ /* Skip one space between the BSSID and start of the SSID */
+ i++;
+
+ /* Copy the SSID */
+ ssid_bssid.ssid.ssid_len = buflen - i - 1;
+ memcpy(ssid_bssid.ssid.ssid, buf + i, sizeof(ssid_bssid.ssid.ssid));
+
+ PRINTM(MCMND, "iwpriv assoc: AP=[" MACSTR "], ssid(%d)=[%s]\n",
+ MAC2STR(ssid_bssid.bssid),
+ (int) ssid_bssid.ssid.ssid_len, ssid_bssid.ssid.ssid);
+
+ if (MLAN_STATUS_SUCCESS != woal_bss_start(priv,
+ MOAL_IOCTL_WAIT, &ssid_bssid)) {
+ LEAVE();
+ return -EFAULT;
+ }
+#ifdef REASSOCIATION
+ memset(&bss_info, 0x00, sizeof(bss_info));
+ if (MLAN_STATUS_SUCCESS == woal_get_bss_info(priv,
+ MOAL_IOCTL_WAIT, &bss_info)) {
+ memcpy(&priv->prev_ssid_bssid.ssid,
+ &bss_info.ssid, sizeof(mlan_802_11_ssid));
+ memcpy(&priv->prev_ssid_bssid.bssid,
+ &bss_info.bssid, MLAN_MAC_ADDR_LENGTH);
+ }
+#endif /* REASSOCIATION */
+
+ LEAVE();
+ return 0;
+}
+
/**
* @brief Copy Rates
*
@@ -369,15 +457,18 @@ static int
woal_deep_sleep_ioctl(moal_private * priv, struct iwreq *wrq)
{
int ret = 0;
+ int user_data_len;
t_u32 deep_sleep = DEEP_SLEEP_OFF;
t_u32 data[2];
+ int copy_len;
t_u16 idletime = DEEP_SLEEP_IDLE_TIME;
ENTER();
- if (wrq->u.data.length == 1 || wrq->u.data.length == 2) {
- if (copy_from_user
- (&data, wrq->u.data.pointer, wrq->u.data.length * sizeof(int))) {
+ user_data_len = wrq->u.data.length;
+ copy_len = MIN(sizeof(data), sizeof(int) * user_data_len);
+ if (user_data_len == 1 || user_data_len == 2) {
+ if (copy_from_user(&data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
LEAVE();
return -EFAULT;
@@ -392,7 +483,7 @@ woal_deep_sleep_ioctl(moal_private * priv, struct iwreq *wrq)
}
} else if (deep_sleep == DEEP_SLEEP_ON) {
PRINTM(MINFO, "Enter Deep Sleep Mode\n");
- if (wrq->u.data.length == 2)
+ if (user_data_len == 2)
idletime = data[1];
else
idletime = 0;
@@ -406,8 +497,8 @@ woal_deep_sleep_ioctl(moal_private * priv, struct iwreq *wrq)
LEAVE();
return -EINVAL;
}
- } else if (wrq->u.data.length > 2) {
- PRINTM(MERROR, "Invalid number of arguments %d\n", wrq->u.data.length);
+ } else if (user_data_len > 2) {
+ PRINTM(MERROR, "Invalid number of arguments %d\n", user_data_len);
LEAVE();
return -EINVAL;
} else { /* Display Deep Sleep settings */
@@ -445,7 +536,7 @@ woal_deep_sleep_ioctl(moal_private * priv, struct iwreq *wrq)
static int
woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
{
- int data[2];
+ int data[2], copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
int ret = 0;
@@ -468,13 +559,13 @@ woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
cfg_11n->sub_command = MLAN_OID_11N_HTCAP_CFG;
req->req_id = MLAN_IOCTL_11N_CFG;
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
if (data_length == 0) {
/* Get 11n tx parameters from MLAN */
req->action = MLAN_ACT_GET;
cfg_11n->param.htcap_cfg.misc_cfg = BAND_SELECT_BG;
} else {
- if (copy_from_user
- (data, wrq->u.data.pointer, data_length * sizeof(int))) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -547,18 +638,20 @@ woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
static int
woal_11n_amsdu_aggr_ctrl(moal_private * priv, struct iwreq *wrq)
{
- int data[2];
+ int data[2], copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
int ret = 0;
+ int data_length = wrq->u.data.length;
ENTER();
- if ((wrq->u.data.length != 0) && (wrq->u.data.length != 1)) {
+ if ((data_length != 0) && (data_length != 1)) {
PRINTM(MERROR, "Invalid number of arguments\n");
ret = -EINVAL;
goto done;
}
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
if (req == NULL) {
ret = -ENOMEM;
@@ -569,12 +662,11 @@ woal_11n_amsdu_aggr_ctrl(moal_private * priv, struct iwreq *wrq)
cfg_11n->sub_command = MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL;
req->req_id = MLAN_IOCTL_11N_CFG;
- if (wrq->u.data.length == 0) {
+ if (data_length == 0) {
/* Get 11n tx parameters from MLAN */
req->action = MLAN_ACT_GET;
- } else if (wrq->u.data.length == 1) {
- if (copy_from_user(data, wrq->u.data.pointer,
- wrq->u.data.length * sizeof(int))) {
+ } else if (data_length == 1) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -614,7 +706,7 @@ woal_11n_amsdu_aggr_ctrl(moal_private * priv, struct iwreq *wrq)
static int
woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
{
- int data[2];
+ int data[2], copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
int ret = 0;
@@ -627,6 +719,7 @@ woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
ret = -EINVAL;
goto done;
}
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
if (req == NULL) {
ret = -ENOMEM;
@@ -637,13 +730,12 @@ woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
cfg_11n->sub_command = MLAN_OID_11N_CFG_TX;
req->req_id = MLAN_IOCTL_11N_CFG;
- if (wrq->u.data.length == 0) {
+ if (data_length == 0) {
/* Get 11n tx parameters from MLAN */
req->action = MLAN_ACT_GET;
cfg_11n->param.tx_cfg.misc_cfg = BAND_SELECT_BG;
} else {
- if (copy_from_user
- (data, wrq->u.data.pointer, data_length * sizeof(int))) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -714,10 +806,11 @@ woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
static int
woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
{
- int data[MAX_NUM_TID * 2], i, j;
+ int data[MAX_NUM_TID * 2], i, j, copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
int ret = 0;
+ int data_length = wrq->u.data.length;
ENTER();
@@ -725,6 +818,7 @@ woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
LEAVE();
return -EINVAL;
}
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
if (req == NULL) {
@@ -735,7 +829,7 @@ woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
cfg_11n->sub_command = MLAN_OID_11N_CFG_AGGR_PRIO_TBL;
req->req_id = MLAN_IOCTL_11N_CFG;
- if (wrq->u.data.length == 0) {
+ if (data_length == 0) {
/* Get aggr priority table from MLAN */
req->action = MLAN_ACT_GET;
if (MLAN_STATUS_SUCCESS !=
@@ -755,14 +849,13 @@ woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
ret = -EFAULT;
goto error;
}
- } else if (wrq->u.data.length == 16) {
- if (copy_from_user(data, wrq->u.data.pointer,
- sizeof(int) * wrq->u.data.length)) {
+ } else if (data_length == 16) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto error;
}
- for (i = 0, j = 0; i < (wrq->u.data.length); i = i + 2, ++j) {
+ for (i = 0, j = 0; i < (data_length); i = i + 2, ++j) {
if ((data[i] > 7 && data[i] != 0xff) ||
(data[i + 1] > 7 && data[i + 1] != 0xff)) {
PRINTM(MERROR, "Invalid priority, valid value 0-7 or 0xff.\n");
@@ -805,12 +898,13 @@ woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
static int
woal_addba_reject(moal_private * priv, struct iwreq *wrq)
{
- int data[MAX_NUM_TID], ret = 0, i;
+ int data[MAX_NUM_TID], ret = 0, i, copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
-
+ int data_length = wrq->u.data.length;
ENTER();
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
if (req == NULL) {
LEAVE();
@@ -820,7 +914,7 @@ woal_addba_reject(moal_private * priv, struct iwreq *wrq)
cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_REJECT;
req->req_id = MLAN_IOCTL_11N_CFG;
- if (wrq->u.data.length == 0) {
+ if (data_length == 0) {
PRINTM(MERROR, "Addba reject moal\n");
/* Get aggr priority table from MLAN */
req->action = MLAN_ACT_GET;
@@ -841,14 +935,13 @@ woal_addba_reject(moal_private * priv, struct iwreq *wrq)
ret = -EFAULT;
goto error;
}
- } else if (wrq->u.data.length == 8) {
- if (copy_from_user(data, wrq->u.data.pointer,
- sizeof(int) * wrq->u.data.length)) {
+ } else if (data_length == 8) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto error;
}
- for (i = 0; i < (wrq->u.data.length); ++i) {
+ for (i = 0; i < (data_length); ++i) {
if (data[i] != 0 && data[i] != 1) {
PRINTM(MERROR, "addba reject only takes argument as 0 or 1\n");
ret = -EFAULT;
@@ -888,12 +981,14 @@ woal_addba_reject(moal_private * priv, struct iwreq *wrq)
static int
woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
{
- int data[5], ret = 0;
+ int data[5], ret = 0, copy_len;
mlan_ioctl_req *req = NULL;
mlan_ds_11n_cfg *cfg_11n = NULL;
+ int data_length = wrq->u.data.length;
ENTER();
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
if (req == NULL) {
LEAVE();
@@ -903,7 +998,7 @@ woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_PARAM;
req->req_id = MLAN_IOCTL_11N_CFG;
- if (wrq->u.data.length == 0) {
+ if (data_length == 0) {
/* Get Add BA parameters from MLAN */
req->action = MLAN_ACT_GET;
if (MLAN_STATUS_SUCCESS !=
@@ -926,9 +1021,8 @@ woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
ret = -EFAULT;
goto error;
}
- } else if (wrq->u.data.length == 5) {
- if (copy_from_user
- (data, wrq->u.data.pointer, wrq->u.data.length * sizeof(int))) {
+ } else if (data_length == 5) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto error;
@@ -1043,7 +1137,7 @@ woal_txbuf_cfg(moal_private * priv, struct iwreq *wrq)
static int
woal_hs_cfg(moal_private * priv, struct iwreq *wrq, BOOLEAN invoke_hostcmd)
{
- int data[3];
+ int data[3], copy_len;
int ret = 0;
mlan_ds_hs_cfg hscfg;
t_u16 action;
@@ -1054,14 +1148,14 @@ woal_hs_cfg(moal_private * priv, struct iwreq *wrq, BOOLEAN invoke_hostcmd)
memset(data, 0, sizeof(data));
memset(&hscfg, 0, sizeof(mlan_ds_hs_cfg));
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
if (data_length == 0) {
action = MLAN_ACT_GET;
} else {
action = MLAN_ACT_SET;
if (data_length >= 1 && data_length <= 3) {
- if (copy_from_user
- (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -1171,7 +1265,7 @@ woal_hs_setpara(moal_private * priv, struct iwreq *wrq)
static int
woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
{
- int data[4];
+ int data[4], copy_len;
int ret = 0;
mlan_ioctl_req *req = NULL;
mlan_ds_pm_cfg *pmcfg = NULL;
@@ -1180,6 +1274,7 @@ woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
ENTER();
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
memset(data, 0, sizeof(data));
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
if (req == NULL) {
@@ -1201,8 +1296,7 @@ woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
req->action = MLAN_ACT_GET;
if (data_length) {
- if (copy_from_user
- (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -1253,7 +1347,7 @@ woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
static int
woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
{
- int data[64];
+ int data[64], copy_len;
int ret = 0;
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *cfg = NULL;
@@ -1263,6 +1357,7 @@ woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
ENTER();
memset(data, 0, sizeof(data));
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
@@ -1278,8 +1373,7 @@ woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
req->action = MLAN_ACT_GET;
else if (data_length <= MLAN_MAX_CLK_NUM) {
req->action = MLAN_ACT_SET;
- if (copy_from_user
- (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -1371,7 +1465,7 @@ woal_band_cfg(moal_private * priv, struct iwreq *wrq)
int ret = 0;
unsigned int i;
int data[4];
- int user_data_len = wrq->u.data.length;
+ int user_data_len = wrq->u.data.length, copy_len;
t_u32 infra_band = 0;
t_u32 adhoc_band = 0;
t_u32 adhoc_channel = 0;
@@ -1394,6 +1488,7 @@ woal_band_cfg(moal_private * priv, struct iwreq *wrq)
}
}
+ copy_len = MIN(sizeof(data), sizeof(int) * user_data_len);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
if (req == NULL) {
ret = -ENOMEM;
@@ -1429,8 +1524,7 @@ woal_band_cfg(moal_private * priv, struct iwreq *wrq)
goto error;
}
} else {
- if (copy_from_user
- (data, wrq->u.data.pointer, sizeof(int) * user_data_len)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto error;
@@ -1517,7 +1611,7 @@ woal_band_cfg(moal_private * priv, struct iwreq *wrq)
static int
woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
{
- int data[3];
+ int data[3], copy_len;
int ret = 0;
mlan_ioctl_req *req = NULL;
mlan_ds_reg_mem *reg = NULL;
@@ -1526,6 +1620,7 @@ woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
ENTER();
memset(data, 0, sizeof(data));
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
if (req == NULL) {
@@ -1545,7 +1640,7 @@ woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
ret = -EINVAL;
goto done;
}
- if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -1588,7 +1683,7 @@ woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
static int
woal_read_eeprom(moal_private * priv, struct iwreq *wrq)
{
- int data[2];
+ int data[2], copy_len;
int ret = 0;
mlan_ioctl_req *req = NULL;
mlan_ds_reg_mem *reg = NULL;
@@ -1597,6 +1692,7 @@ woal_read_eeprom(moal_private * priv, struct iwreq *wrq)
ENTER();
memset(data, 0, sizeof(data));
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
if (req == NULL) {
@@ -1614,7 +1710,7 @@ woal_read_eeprom(moal_private * priv, struct iwreq *wrq)
ret = -EINVAL;
goto done;
}
- if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -1661,11 +1757,12 @@ woal_mem_read_write(moal_private * priv, struct iwreq *wrq)
int ret = 0;
mlan_ioctl_req *req = NULL;
mlan_ds_reg_mem *reg_mem = NULL;
- int data_length = wrq->u.data.length;
+ int data_length = wrq->u.data.length, copy_len;
ENTER();
memset(data, 0, sizeof(data));
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
if (req == NULL) {
@@ -1687,7 +1784,7 @@ woal_mem_read_write(moal_private * priv, struct iwreq *wrq)
ret = -EINVAL;
goto done;
}
- if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -1770,7 +1867,9 @@ woal_get_log(moal_private * priv, struct iwreq *wrq)
"wepicverrcnt-1 %u\n"
"wepicverrcnt-2 %u\n"
"wepicverrcnt-3 %u\n"
- "wepicverrcnt-4 %u\n",
+ "wepicverrcnt-4 %u\n"
+ "beacon_rcnt %u\n"
+ "beacon_mcnt %u\n",
stats.mcast_tx_frame,
stats.failed,
stats.retry,
@@ -1785,7 +1884,8 @@ woal_get_log(moal_private * priv, struct iwreq *wrq)
stats.tx_frame,
stats.wep_icv_error[0],
stats.wep_icv_error[1],
- stats.wep_icv_error[2], stats.wep_icv_error[3]);
+ stats.wep_icv_error[2],
+ stats.wep_icv_error[3], stats.bcn_rcv_cnt, stats.bcn_miss_cnt);
wrq->u.data.length = strlen(buf) + 1;
if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
PRINTM(MERROR, "Copy to user failed\n");
@@ -1846,7 +1946,7 @@ woal_deauth(moal_private * priv, struct iwreq *wrq)
static int
woal_tx_power_cfg(moal_private * priv, struct iwreq *wrq)
{
- int data[5], user_data_len;
+ int data[5], user_data_len, copy_len;
int ret = 0;
mlan_bss_info bss_info;
mlan_ds_power_cfg *pcfg = NULL;
@@ -1858,6 +1958,7 @@ woal_tx_power_cfg(moal_private * priv, struct iwreq *wrq)
memset(data, 0, sizeof(data));
user_data_len = wrq->u.data.length;
+ copy_len = MIN(sizeof(data), sizeof(int) * user_data_len);
if (user_data_len) {
if (sizeof(int) * user_data_len > sizeof(data)) {
@@ -1865,8 +1966,7 @@ woal_tx_power_cfg(moal_private * priv, struct iwreq *wrq)
ret = -EINVAL;
goto done;
}
- if (copy_from_user
- (data, wrq->u.data.pointer, sizeof(int) * user_data_len)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -2381,12 +2481,13 @@ woal_set_get_radio(moal_private * priv, struct iwreq *wrq)
static int
woal_drv_dbg(moal_private * priv, struct iwreq *wrq)
{
- int data[4];
+ int data[4], copy_len;
int ret = 0;
-
+ int data_length = wrq->u.data.length;
ENTER();
- if (!wrq->u.data.length) {
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
+ if (!data_length) {
data[0] = drvdbg;
/* Return the current driver debug bit masks */
if (copy_to_user(wrq->u.data.pointer, data, sizeof(int))) {
@@ -2395,10 +2496,9 @@ woal_drv_dbg(moal_private * priv, struct iwreq *wrq)
goto drvdbgexit;
}
wrq->u.data.length = 1;
- } else if (wrq->u.data.length < 3) {
+ } else if (data_length < 3) {
/* Get the driver debug bit masks from user */
- if (copy_from_user
- (data, wrq->u.data.pointer, sizeof(int) * wrq->u.data.length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto drvdbgexit;
@@ -2637,7 +2737,8 @@ woal_sleep_params_ioctl(moal_private * priv, struct iwreq *wrq)
mlan_ioctl_req *req = NULL;
mlan_ds_pm_cfg *pm = NULL;
mlan_ds_sleep_params *psleep_params = NULL;
- int data[6] = { 0 }, i;
+ int data[6] = { 0 }, i, copy_len;
+ int data_length = wrq->u.data.length;
#ifdef DEBUG_LEVEL1
char err_str[][35] = { {"sleep clock error in ppm"},
{"wakeup offset in usec"},
@@ -2648,6 +2749,7 @@ woal_sleep_params_ioctl(moal_private * priv, struct iwreq *wrq)
ENTER();
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
if (req == NULL) {
LEAVE();
@@ -2659,11 +2761,10 @@ woal_sleep_params_ioctl(moal_private * priv, struct iwreq *wrq)
req->req_id = MLAN_IOCTL_PM_CFG;
psleep_params = (pmlan_ds_sleep_params) & pm->param.sleep_params;
- if (wrq->u.data.length == 0) {
+ if (data_length == 0) {
req->action = MLAN_ACT_GET;
- } else if (wrq->u.data.length == 6) {
- if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) *
- wrq->u.data.length)) {
+ } else if (data_length == 6) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
/* copy_from_user failed */
PRINTM(MERROR, "S_PARAMS: copy from user failed\n");
LEAVE();
@@ -3264,28 +3365,30 @@ static int
woal_passphrase(moal_private * priv, struct iwreq *wrq)
{
t_u16 len = 0;
- static char buf[256];
+ char buf[256];
char *begin, *end, *opt;
int ret = 0, action = -1, i;
mlan_ds_sec_cfg *sec = NULL;
mlan_ioctl_req *req = NULL;
t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
t_u8 *mac = NULL;
+ int data_length = wrq->u.data.length, copy_len;
ENTER();
- if (!wrq->u.data.length || wrq->u.data.length >= sizeof(buf)) {
+ if (!data_length || data_length >= sizeof(buf)) {
PRINTM(MERROR, "Argument missing or too long for setpassphrase\n");
ret = -EINVAL;
goto done;
}
+ memset(buf, 0, sizeof(buf));
+ copy_len = data_length;
- if (copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length)) {
+ if (copy_from_user(buf, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
}
- buf[wrq->u.data.length] = '\0';
/* Parse the buf to get the cmd_action */
begin = buf;
@@ -3347,8 +3450,8 @@ woal_passphrase(moal_private * priv, struct iwreq *wrq)
break;
}
sec->param.passphrase.psk_type = MLAN_PSK_PASSPHRASE;
- strncpy(sec->param.passphrase.psk.passphrase.passphrase, end,
- sizeof(sec->param.passphrase.psk.passphrase.passphrase));
+ memcpy(sec->param.passphrase.psk.passphrase.passphrase, end,
+ sizeof(sec->param.passphrase.psk.passphrase.passphrase));
sec->param.passphrase.psk.passphrase.passphrase_len = strlen(end);
PRINTM(MINFO, "passphrase=%s, len=%d\n",
sec->param.passphrase.psk.passphrase.passphrase,
@@ -3483,11 +3586,12 @@ woal_adhoc_aes_ioctl(moal_private * priv, struct iwreq *wrq)
mlan_ds_sec_cfg *sec = NULL;
mlan_ioctl_req *req = NULL;
t_u8 bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
+ int data_length = wrq->u.data.length, copy_len;
ENTER();
memset(key_ascii, 0x00, sizeof(key_ascii));
memset(key_hex, 0x00, sizeof(key_hex));
+ memset(buf, 0x00, sizeof(buf));
/* Get current BSS information */
memset(&bss_info, 0, sizeof(bss_info));
@@ -3504,21 +3608,21 @@ woal_adhoc_aes_ioctl(moal_private * priv, struct iwreq *wrq)
ret = -ENOMEM;
goto done;
}
+ copy_len = data_length;
- if (wrq->u.data.length) {
- if (wrq->u.data.length >= sizeof(buf)) {
+ if (data_length) {
+ if (data_length >= sizeof(buf)) {
PRINTM(MERROR, "Too many arguments\n");
ret = -EINVAL;
goto done;
}
- if (copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length)) {
+ if (copy_from_user(buf, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
}
- buf[wrq->u.data.length] = '\0';
- if (wrq->u.data.length == 1) {
+ if (data_length == 1) {
/* Get Adhoc AES Key */
req->req_id = MLAN_IOCTL_SEC_CFG;
req->action = MLAN_ACT_GET;
@@ -3541,7 +3645,7 @@ woal_adhoc_aes_ioctl(moal_private * priv, struct iwreq *wrq)
tmp = key_ascii;
for (i = 0; i < sizeof(key_hex); i++)
tmp += sprintf((char *) tmp, "%02x", key_hex[i]);
- } else if (wrq->u.data.length >= 2) {
+ } else if (data_length >= 2) {
/* Parse the buf to get the cmd_action */
action = woal_atox(&buf[0]);
if (action < 1 || action > 2) {
@@ -3575,7 +3679,7 @@ woal_adhoc_aes_ioctl(moal_private * priv, struct iwreq *wrq)
ret = -EFAULT;
goto done;
}
- } else if (action == 2) {
+ } else {
/* Clear Adhoc AES Key */
sec->param.encrypt_key.key_len = AES_KEY_LEN;
sec->param.encrypt_key.key_index = MLAN_KEY_INDEX_UNICAST;
@@ -3590,10 +3694,6 @@ woal_adhoc_aes_ioctl(moal_private * priv, struct iwreq *wrq)
ret = -EFAULT;
goto done;
}
- } else {
- PRINTM(MERROR, "Invalid argument\n");
- ret = -EINVAL;
- goto done;
}
}
@@ -3630,9 +3730,12 @@ woal_arp_filter(moal_private * priv, struct iwreq *wrq)
int ret = 0;
mlan_ds_misc_cfg *misc = NULL;
mlan_ioctl_req *req = NULL;
+ int data_length = wrq->u.data.length, copy_len;
ENTER();
+ copy_len =
+ MIN(sizeof(misc->param.gen_ie.ie_data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = -ENOMEM;
@@ -3643,11 +3746,11 @@ woal_arp_filter(moal_private * priv, struct iwreq *wrq)
req->req_id = MLAN_IOCTL_MISC_CFG;
req->action = MLAN_ACT_SET;
misc->param.gen_ie.type = MLAN_IE_TYPE_ARP_FILTER;
- misc->param.gen_ie.len = wrq->u.data.length;
+ misc->param.gen_ie.len = data_length;
/* get the whole command from user */
if (copy_from_user
- (misc->param.gen_ie.ie_data, wrq->u.data.pointer, wrq->u.data.length)) {
+ (misc->param.gen_ie.ie_data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -3693,7 +3796,7 @@ woal_set_get_ip_addr(moal_private * priv, struct iwreq *wrq)
ioctl_req->action = MLAN_ACT_GET;
} else {
if (copy_from_user(buf, wrq->u.data.pointer,
- MIN(IPADDR_MAX_BUF - 1, wrq->u.data.length))) {
+ MIN(IPADDR_MAX_BUF - 1, data_length))) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -3709,7 +3812,7 @@ woal_set_get_ip_addr(moal_private * priv, struct iwreq *wrq)
ioctl_req->action = MLAN_ACT_SET;
/* only one IP is supported in current firmware */
memset(misc->param.ipaddr_cfg.ip_addr[0], 0, IPADDR_LEN);
- in4_pton(&buf[2], MIN((IPADDR_MAX_BUF - 3), (wrq->u.data.length - 2)),
+ in4_pton(&buf[2], MIN((IPADDR_MAX_BUF - 3), (data_length - 2)),
misc->param.ipaddr_cfg.ip_addr[0], ' ', NULL);
/* only one IP is supported in current firmware */
misc->param.ipaddr_cfg.ip_addr_num = 1;
@@ -4538,7 +4641,7 @@ woal_cmd53rdwr_ioctl(moal_private * priv, struct iwreq *wrq)
pattern_len = wrq->u.data.length - 11;
if (pattern_len > total_len)
pattern_len = total_len;
- memset(data, 0, sizeof(data));
+ memset(data, 0, WOAL_2K_BYTES);
/* Copy/duplicate the pattern to data buffer */
for (pos = 0; pos < total_len; pos++)
@@ -4573,7 +4676,7 @@ woal_cmd53rdwr_ioctl(moal_private * priv, struct iwreq *wrq)
static int
woal_do_sdio_mpa_ctrl(moal_private * priv, struct iwreq *wrq)
{
- int data[6], data_length = wrq->u.data.length;
+ int data[6], data_length = wrq->u.data.length, copy_len;
int ret = 0;
mlan_ds_misc_cfg *misc = NULL;
mlan_ioctl_req *req = NULL;
@@ -4585,6 +4688,7 @@ woal_do_sdio_mpa_ctrl(moal_private * priv, struct iwreq *wrq)
ret = -EINVAL;
goto done;
}
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
@@ -4627,13 +4731,10 @@ woal_do_sdio_mpa_ctrl(moal_private * priv, struct iwreq *wrq)
goto done;
}
- if (sizeof(data) >= sizeof(int) * data_length) {
- if (copy_from_user(data, wrq->u.data.pointer,
- sizeof(int) * data_length)) {
- PRINTM(MINFO, "Copy from user failed\n");
- ret = -EFAULT;
- goto done;
- }
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
+ PRINTM(MINFO, "Copy from user failed\n");
+ ret = -EFAULT;
+ goto done;
}
switch (data_length) {
@@ -4690,17 +4791,19 @@ woal_set_get_scan_cfg(moal_private * priv, struct iwreq *wrq)
{
int ret = 0;
int arg_len = 7;
- int data[arg_len];
+ int data[arg_len], copy_len;
mlan_ds_scan *scan = NULL;
mlan_ioctl_req *req = NULL;
+ int data_length = wrq->u.data.length;
ENTER();
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
- if (wrq->u.data.length > arg_len) {
+ if (data_length > arg_len) {
ret = -EINVAL;
goto done;
}
@@ -4708,9 +4811,9 @@ woal_set_get_scan_cfg(moal_private * priv, struct iwreq *wrq)
scan->sub_command = MLAN_OID_SCAN_CONFIG;
req->req_id = MLAN_IOCTL_SCAN;
memset(data, 0, sizeof(data));
- if (wrq->u.data.length) {
- if (copy_from_user
- (data, wrq->u.data.pointer, (wrq->u.data.length * sizeof(int)))) {
+
+ if (data_length) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -4750,7 +4853,7 @@ woal_set_get_scan_cfg(moal_private * priv, struct iwreq *wrq)
ret = -EFAULT;
goto done;
}
- if (!wrq->u.data.length) {
+ if (!data_length) {
memcpy(data, &scan->param.scan_cfg, sizeof(data));
if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
ret = -EFAULT;
@@ -4776,24 +4879,26 @@ woal_set_get_scan_cfg(moal_private * priv, struct iwreq *wrq)
static int
woal_set_get_ps_cfg(moal_private * priv, struct iwreq *wrq)
{
- int data[7], ret = 0;
+ int data[7], copy_len, ret = 0;
mlan_ds_pm_cfg *pm_cfg = NULL;
mlan_ioctl_req *req = NULL;
int allowed = 3;
int i = 3;
+ int data_length = wrq->u.data.length;
ENTER();
allowed++; /* For ad-hoc awake period parameter */
allowed++; /* For beacon missing timeout parameter */
allowed += 2; /* For delay to PS and PS mode parameters */
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
- if (wrq->u.data.length > allowed) {
+ if (data_length > allowed) {
ret = -EINVAL;
goto done;
}
@@ -4801,9 +4906,9 @@ woal_set_get_ps_cfg(moal_private * priv, struct iwreq *wrq)
pm_cfg->sub_command = MLAN_OID_PM_CFG_PS_CFG;
req->req_id = MLAN_IOCTL_PM_CFG;
memset(data, 0, sizeof(data));
- if (wrq->u.data.length) {
- if (copy_from_user
- (data, wrq->u.data.pointer, (wrq->u.data.length * sizeof(int)))) {
+
+ if (data_length) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -4844,7 +4949,7 @@ woal_set_get_ps_cfg(moal_private * priv, struct iwreq *wrq)
goto done;
}
i++;
- if (wrq->u.data.length < allowed - 1)
+ if (data_length < allowed - 1)
data[i] = DELAY_TO_PS_UNCHANGED;
else if ((data[i] < MIN_DELAY_TO_PS) || (data[i] > MAX_DELAY_TO_PS)) {
PRINTM(MERROR, "Invalid argument for delay to PS\n");
@@ -5542,10 +5647,11 @@ woal_dfs_testing(moal_private * priv, struct iwreq *wrq)
mlan_ioctl_req *req = NULL;
mlan_ds_11h_cfg *ds_11hcfg = NULL;
int ret = 0;
- int data[4];
+ int data[4], copy_len;
int data_length = wrq->u.data.length;
ENTER();
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg));
if (req == NULL) {
@@ -5561,8 +5667,7 @@ woal_dfs_testing(moal_private * priv, struct iwreq *wrq)
if (!data_length) {
req->action = MLAN_ACT_GET;
} else if (data_length == 4) {
- if (copy_from_user
- (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -5701,7 +5806,7 @@ static int
woal_cfp_code(moal_private * priv, struct iwreq *wrq)
{
int ret = 0;
- int data[2];
+ int data[2], copy_len;
int data_length = wrq->u.data.length;
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *misc_cfg = NULL;
@@ -5714,6 +5819,7 @@ woal_cfp_code(moal_private * priv, struct iwreq *wrq)
ret = -EINVAL;
goto done;
}
+ copy_len = MIN(sizeof(data), sizeof(int) * data_length);
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
@@ -5731,8 +5837,7 @@ woal_cfp_code(moal_private * priv, struct iwreq *wrq)
if (!data_length) {
req->action = MLAN_ACT_GET;
} else {
- if (copy_from_user
- (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+ if (copy_from_user(data, wrq->u.data.pointer, copy_len)) {
PRINTM(MERROR, "Copy from user failed\n");
ret = -EFAULT;
goto done;
@@ -6065,6 +6170,9 @@ woal_wext_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
case WOAL_ADHOC_AES:
ret = woal_adhoc_aes_ioctl(priv, wrq);
break;
+ case WOAL_ASSOCIATE:
+ ret = woal_associate_ssid_bssid(priv, wrq);
+ break;
case WOAL_WMM_QUEUE_STATUS:
ret = woal_wmm_queue_status_ioctl(priv, wrq);
break;
@@ -6203,54 +6311,6 @@ woal_wext_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
}
/**
- * @brief Get statistics information
- *
- * @param priv A pointer to moal_private structure
- * @param wait_option Wait option
- * @param stats A pointer to mlan_ds_get_stats structure
- *
- * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, otherwise fail
- */
-mlan_status
-woal_get_stats_info(moal_private * priv, t_u8 wait_option,
- mlan_ds_get_stats * stats)
-{
- int ret = 0;
- mlan_ds_get_info *info = NULL;
- mlan_ioctl_req *req = NULL;
- mlan_status status = MLAN_STATUS_SUCCESS;
- ENTER();
-
- /* Allocate an IOCTL request buffer */
- req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
- if (req == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- /* Fill request buffer */
- info = (mlan_ds_get_info *) req->pbuf;
- info->sub_command = MLAN_OID_GET_STATS;
- req->req_id = MLAN_IOCTL_GET_INFO;
- req->action = MLAN_ACT_GET;
-
- /* Send IOCTL request to MLAN */
- status = woal_request_ioctl(priv, req, wait_option);
- if (status == MLAN_STATUS_SUCCESS) {
- if (stats)
- memcpy(stats, &info->param.stats, sizeof(mlan_ds_get_stats));
- priv->w_stats.discard.fragment = info->param.stats.fcs_error;
- priv->w_stats.discard.retries = info->param.stats.retry;
- priv->w_stats.discard.misc = info->param.stats.ack_failure;
- }
- done:
- if (req && (status != MLAN_STATUS_PENDING))
- kfree(req);
- LEAVE();
- return status;
-}
-
-/**
* @brief Get data rates
*
* @param priv A pointer to moal_private structure
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_priv.h b/drivers/net/wireless/sd8797/mlinux/moal_priv.h
index 1c24f30502f6..494a2cae7837 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_priv.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_priv.h
@@ -179,6 +179,7 @@ Change log:
#define WOAL_PASSPHRASE 1
/** Private command to get/set Ad-Hoc AES */
#define WOAL_ADHOC_AES 2
+#define WOAL_ASSOCIATE 3
/** Private command ID to get WMM queue status */
#define WOAL_WMM_QUEUE_STATUS 4
/** Private command ID to get Traffic stream status */
@@ -570,6 +571,11 @@ static const struct iw_priv_args woal_private_args[] = {
IW_PRIV_TYPE_CHAR | 256,
"adhocaes"},
{
+ WOAL_ASSOCIATE,
+ IW_PRIV_TYPE_CHAR | 256,
+ IW_PRIV_TYPE_CHAR | 256,
+ "associate"},
+ {
WOAL_WMM_QUEUE_STATUS,
IW_PRIV_TYPE_CHAR | 256,
IW_PRIV_TYPE_CHAR | 256,
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_proc.c b/drivers/net/wireless/sd8797/mlinux/moal_proc.c
index 356fc79b9bed..5d43583fc1cd 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_proc.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_proc.c
@@ -95,7 +95,7 @@ woal_info_proc_read(char *page, char **start, off_t offset,
int mc_count = netdev_mc_count(netdev);
#endif /* < 2.6.35 */
#else
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
int i = 0;
#endif /* >= 2.6.29 */
#endif
@@ -199,7 +199,7 @@ woal_info_proc_read(char *page, char **start, off_t offset,
p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
p += sprintf(p, "carrier %s\n",
((netif_carrier_ok(priv->netdev)) ? "on" : "off"));
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
for (i = 0; i < netdev->num_tx_queues; i++) {
p += sprintf(p, "tx queue %d: %s\n", i,
((netif_tx_queue_stopped(netdev_get_tx_queue(netdev, 0))) ?
@@ -268,7 +268,8 @@ parse_cmd52_string(const char __user * buffer, size_t len, int *func, int *reg,
string = (char *) kmalloc(CMD52_STR_LEN, GFP_KERNEL);
memset(string, 0, CMD52_STR_LEN);
- memcpy(string, buffer + strlen("sdcmd52rw="), len - strlen("sdcmd52rw="));
+ memcpy(string, buffer + strlen("sdcmd52rw="),
+ MIN((CMD52_STR_LEN - 1), (len - strlen("sdcmd52rw="))));
string = strstrip(string);
*func = -1;
@@ -316,6 +317,8 @@ woal_config_write(struct file *f, const char *buf, unsigned long cnt,
t_u32 config_data = 0;
moal_handle *handle = (moal_handle *) data;
int func, reg, val;
+ int copy_len;
+ moal_private *priv = NULL;
ENTER();
if (!MODULE_GET) {
@@ -329,7 +332,8 @@ woal_config_write(struct file *f, const char *buf, unsigned long cnt,
return (int) cnt;
}
memset(databuf, 0, sizeof(databuf));
- if (copy_from_user(databuf, buf, cnt)) {
+ copy_len = MIN((sizeof(databuf) - 1), cnt);
+ if (copy_from_user(databuf, buf, copy_len)) {
MODULE_PUT;
LEAVE();
return 0;
@@ -359,6 +363,14 @@ woal_config_write(struct file *f, const char *buf, unsigned long cnt,
parse_cmd52_string(databuf, (size_t) cnt, &func, &reg, &val);
woal_sdio_read_write_cmd52(handle, func, reg, val);
}
+ if (!strncmp(databuf, "debug_dump", strlen("debug_dump"))) {
+ priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
+ if (priv) {
+ woal_mlan_debug_info(priv);
+ woal_moal_debug_info(priv, NULL, MFALSE);
+ }
+ }
+
MODULE_PUT;
LEAVE();
return (int) cnt;
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_sdio.h b/drivers/net/wireless/sd8797/mlinux/moal_sdio.h
index 5a5bc2c3718c..e4560f9dd8ca 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_sdio.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_sdio.h
@@ -49,17 +49,11 @@ Change log:
#define FIXED_ADDRESS 0
#endif
-/** SD8797 chip revision ID */
-#define SD8797_A0 0x00
-#define SD8797_B0 0x10
-
-#define SD8797_A0_FW_NAME "mrvl/sd8797_uapsta_a0.bin"
-#define SD8797_B0_FW_NAME "mrvl/sd8797_uapsta.bin"
-
#ifdef STA_SUPPORT
/** Default firmware name */
#define DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin"
+#define DEFAULT_FW_NAME_8782 "mrvl/sd8782_uapsta.bin"
#ifndef DEFAULT_FW_NAME
#define DEFAULT_FW_NAME ""
@@ -70,6 +64,7 @@ Change log:
/** Default firmware name */
#define DEFAULT_AP_FW_NAME "mrvl/sd8797_uapsta.bin"
+#define DEFAULT_AP_FW_NAME_8782 "mrvl/sd8782_uapsta.bin"
#ifndef DEFAULT_AP_FW_NAME
#define DEFAULT_AP_FW_NAME ""
@@ -79,6 +74,7 @@ Change log:
/** Default firmaware name */
#define DEFAULT_AP_STA_FW_NAME "mrvl/sd8797_uapsta.bin"
+#define DEFAULT_AP_STA_FW_NAME_8782 "mrvl/sd8782_uapsta.bin"
#ifndef DEFAULT_AP_STA_FW_NAME
#define DEFAULT_AP_STA_FW_NAME ""
@@ -87,6 +83,8 @@ Change log:
/********************************************************
Global Functions
********************************************************/
+/** Function to update the SDIO card type */
+t_void woal_sdio_update_card_type(moal_handle * handle, t_void * card);
/** Function to write register */
mlan_status woal_write_reg(moal_handle * handle, t_u32 reg, t_u32 data);
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c b/drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c
index ad42fdefa9d5..3dce9bf07e75 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c
@@ -47,10 +47,13 @@ extern int pm_keep_power;
/** Device ID for SD8797 */
#define SD_DEVICE_ID_8797 (0x9129)
+/** Device ID for SD8782 */
+#define SD_DEVICE_ID_8782 (0x9121)
/** WLAN IDs */
static const struct sdio_device_id wlan_ids[] = {
{SDIO_DEVICE(MARVELL_VENDOR_ID, SD_DEVICE_ID_8797)},
+ {SDIO_DEVICE(MARVELL_VENDOR_ID, SD_DEVICE_ID_8782)},
{},
};
@@ -75,7 +78,7 @@ static struct sdio_driver REFDATA wlan_sdio = {
.id_table = wlan_ids,
.probe = woal_sdio_probe,
.remove = woal_sdio_remove,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
.drv = {
.owner = THIS_MODULE,
#ifdef SDIO_SUSPEND_RESUME
@@ -107,36 +110,49 @@ void
woal_dump_sdio_reg(moal_handle * handle)
{
int ret = 0;
- t_u8 data;
- data =
- sdio_f0_readb(((struct sdio_mmc_card *) handle->card)->func, 0x05,
- &ret);
- PRINTM(MMSG, "fun0: reg 0x05=0x%x ret=%d\n", data, ret);
- data =
- sdio_f0_readb(((struct sdio_mmc_card *) handle->card)->func, 0x04,
- &ret);
- PRINTM(MMSG, "fun0: reg 0x04=0x%x ret=%d\n", data, ret);
- data =
- sdio_readb(((struct sdio_mmc_card *) handle->card)->func, 0x03, &ret);
- PRINTM(MMSG, "fun1: reg 0x03=0x%x ret=%d\n", data, ret);
- data =
- sdio_readb(((struct sdio_mmc_card *) handle->card)->func, 0x04, &ret);
- PRINTM(MMSG, "fun1: reg 0x04=0x%x ret=%d\n", data, ret);
- data =
- sdio_readb(((struct sdio_mmc_card *) handle->card)->func, 0x05, &ret);
- PRINTM(MMSG, "fun1: reg 0x05=0x%x ret=%d\n", data, ret);
- data =
- sdio_readb(((struct sdio_mmc_card *) handle->card)->func, 0x60, &ret);
- PRINTM(MMSG, "fun1: reg 0x60=0x%x ret=%d\n", data, ret);
- data =
- sdio_readb(((struct sdio_mmc_card *) handle->card)->func, 0x61, &ret);
- PRINTM(MMSG, "fun1: reg 0x61=0x%x ret=%d\n", data, ret);
+ t_u8 data, i, len;
+ int fun0_reg[] = { 0x05, 0x04 };
+ int fun1_reg[] = { 0x03, 0x04, 0x05, 0x60, 0x61 };
+
+ len = sizeof(fun0_reg) / sizeof(fun0_reg[0]);
+ for (i = 0; i < len; i++) {
+ data = sdio_f0_readb(((struct sdio_mmc_card *) handle->card)->func,
+ fun0_reg[i], &ret);
+ PRINTM(MMSG, "fun0: reg 0x%02x=0x%02x ret=%d\n", fun0_reg[i], data,
+ ret);
+ }
+
+ len = sizeof(fun1_reg) / sizeof(fun1_reg[0]);
+ for (i = 0; i < len; i++) {
+ data = sdio_readb(((struct sdio_mmc_card *) handle->card)->func,
+ fun1_reg[i], &ret);
+ PRINTM(MMSG, "fun1: reg 0x%02x=0x%02x ret=%d\n", fun1_reg[i], data,
+ ret);
+ }
return;
}
/********************************************************
Global Functions
********************************************************/
+/** @brief This function updates the SDIO card types
+ *
+ * @param handle A Pointer to the moal_handle structure
+ * @param card A Pointer to card
+ *
+ * @return N/A
+ */
+t_void
+woal_sdio_update_card_type(moal_handle * handle, t_void * card)
+{
+ struct sdio_mmc_card *cardp = (struct sdio_mmc_card *) card;
+
+ /* Update card type */
+ if (cardp->func->device == SD_DEVICE_ID_8797)
+ handle->card_type = CARD_TYPE_SD8797;
+ else if (cardp->func->device == SD_DEVICE_ID_8782)
+ handle->card_type = CARD_TYPE_SD8782;
+}
/**
* @brief This function handles the interrupt.
@@ -182,7 +198,7 @@ woal_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
ENTER();
- PRINTM(MINFO, "vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
+ PRINTM(MMSG, "vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
func->vendor, func->device, func->class, func->num);
card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
@@ -292,24 +308,18 @@ woal_sdio_suspend(struct device *dev)
ENTER();
PRINTM(MCMND, "<--- Enter woal_sdio_suspend --->\n");
- if (func) {
- pm_flags = sdio_get_host_pm_caps(func);
- PRINTM(MCMND, "%s: suspend: PM flags = 0x%x\n", sdio_func_id(func),
- pm_flags);
- if (!(pm_flags & MMC_PM_KEEP_POWER)) {
- PRINTM(MERROR, "%s: cannot remain alive while host is suspended\n",
- sdio_func_id(func));
- LEAVE();
- return -ENOSYS;
- }
- cardp = sdio_get_drvdata(func);
- if (!cardp || !cardp->handle) {
- PRINTM(MERROR, "Card or moal_handle structure is not valid\n");
- LEAVE();
- return MLAN_STATUS_SUCCESS;
- }
- } else {
- PRINTM(MERROR, "sdio_func is not specified\n");
+ pm_flags = sdio_get_host_pm_caps(func);
+ PRINTM(MCMND, "%s: suspend: PM flags = 0x%x\n", sdio_func_id(func),
+ pm_flags);
+ if (!(pm_flags & MMC_PM_KEEP_POWER)) {
+ PRINTM(MERROR, "%s: cannot remain alive while host is suspended\n",
+ sdio_func_id(func));
+ LEAVE();
+ return -ENOSYS;
+ }
+ cardp = sdio_get_drvdata(func);
+ if (!cardp || !cardp->handle) {
+ PRINTM(MERROR, "Card or moal_handle structure is not valid\n");
LEAVE();
return MLAN_STATUS_SUCCESS;
}
@@ -355,6 +365,9 @@ woal_sdio_suspend(struct device *dev)
#endif
} else {
PRINTM(MMSG, "HS not actived, suspend fail!");
+ handle->suspend_fail = MTRUE;
+ for (i = 0; i < handle->priv_num; i++)
+ netif_device_attach(handle->priv[i]->netdev);
ret = -EBUSY;
goto done;
}
@@ -384,18 +397,12 @@ woal_sdio_resume(struct device *dev)
ENTER();
PRINTM(MCMND, "<--- Enter woal_sdio_resume --->\n");
- if (func) {
- pm_flags = sdio_get_host_pm_caps(func);
- PRINTM(MCMND, "%s: resume: PM flags = 0x%x\n", sdio_func_id(func),
- pm_flags);
- cardp = sdio_get_drvdata(func);
- if (!cardp || !cardp->handle) {
- PRINTM(MERROR, "Card or moal_handle structure is not valid\n");
- LEAVE();
- return MLAN_STATUS_SUCCESS;
- }
- } else {
- PRINTM(MERROR, "sdio_func is not specified\n");
+ pm_flags = sdio_get_host_pm_caps(func);
+ PRINTM(MCMND, "%s: resume: PM flags = 0x%x\n", sdio_func_id(func),
+ pm_flags);
+ cardp = sdio_get_drvdata(func);
+ if (!cardp || !cardp->handle) {
+ PRINTM(MERROR, "Card or moal_handle structure is not valid\n");
LEAVE();
return MLAN_STATUS_SUCCESS;
}
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_shim.c b/drivers/net/wireless/sd8797/mlinux/moal_shim.c
index efdcaacd2031..08c9a12f00d6 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_shim.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_shim.c
@@ -50,6 +50,7 @@ typedef struct _moal_lock
********************************************************/
extern int cfg80211_wext;
+extern int hw_test;
/********************************************************
Local Functions
********************************************************/
@@ -72,7 +73,9 @@ moal_malloc(IN t_void * pmoal_handle,
IN t_u32 size, IN t_u32 flag, OUT t_u8 ** ppbuf)
{
moal_handle *handle = (moal_handle *) pmoal_handle;
- t_u32 mem_flag = GFP_ATOMIC; /* Default type: GFP_ATOMIC */
+ t_u32 mem_flag = (in_interrupt() || irqs_disabled() ||
+ !write_can_lock(&dev_base_lock)) ? GFP_ATOMIC :
+ GFP_KERNEL;
if (flag & MLAN_MEM_DMA)
mem_flag |= GFP_DMA;
@@ -107,6 +110,50 @@ moal_mfree(IN t_void * pmoal_handle, IN t_u8 * pbuf)
return MLAN_STATUS_SUCCESS;
}
+/**
+ * @brief Alloc a vitual-address-continuous buffer
+ *
+ * @param pmoal_handle Pointer to the MOAL context
+ * @param size The size of the buffer to be allocated
+ * @param ppbuf Pointer to a buffer location to store buffer pointer allocated
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_vmalloc(IN t_void * pmoal_handle, IN t_u32 size, OUT t_u8 ** ppbuf)
+{
+ moal_handle *handle = (moal_handle *) pmoal_handle;
+
+ if (!(*ppbuf = vmalloc(size))) {
+ PRINTM(MERROR, "%s: vmalloc (%d bytes) failed!", __FUNCTION__,
+ (int) size);
+ return MLAN_STATUS_FAILURE;
+ }
+ atomic_inc(&handle->vmalloc_count);
+
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief Free a buffer allocated by vmalloc
+ *
+ * @param pmoal_handle Pointer to the MOAL context
+ * @param pbuf Pointer to the buffer to be freed
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_vfree(IN t_void * pmoal_handle, IN t_u8 * pbuf)
+{
+ moal_handle *handle = (moal_handle *) pmoal_handle;
+
+ if (!pbuf)
+ return MLAN_STATUS_FAILURE;
+ vfree(pbuf);
+ atomic_dec(&handle->vmalloc_count);
+ return MLAN_STATUS_SUCCESS;
+}
+
/**
* @brief Fill memory with constant byte
*
@@ -527,7 +574,7 @@ moal_ioctl_complete(IN t_void * pmoal_handle,
(pioctl_req->action == MLAN_ACT_GET))
woal_process_ioctl_resp(priv, pioctl_req);
if (status != MLAN_STATUS_SUCCESS)
- PRINTM(MERROR,
+ PRINTM(MIOCTL,
"IOCTL failed: id=0x%x, action=%d, status_code=0x%x\n",
pioctl_req->req_id, (int) pioctl_req->action,
pioctl_req->status_code);
@@ -589,7 +636,11 @@ moal_send_packet_complete(IN t_void * pmoal_handle,
moal_private *priv = NULL;
moal_handle *handle = (moal_handle *) pmoal_handle;
struct sk_buff *skb = NULL;
- int i;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+ t_u32 tid = 0;
+ t_u32 index = 0;
+#endif
+
ENTER();
if (pmbuf && pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) {
woal_free_mlan_buffer(handle, pmbuf);
@@ -609,7 +660,24 @@ moal_send_packet_complete(IN t_void * pmoal_handle,
} else {
priv->stats.tx_errors++;
}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+ tid = pmbuf->priority;
+ index =
+ mlan_select_wmm_queue(priv->phandle->pmlan_adapter,
+ priv->bss_index, tid);
+ atomic_dec(&handle->tx_pending);
+ if (atomic_dec_return(&priv->wmm_tx_pending[index]) <
+ LOW_TX_PENDING) {
+ struct netdev_queue *txq =
+ netdev_get_tx_queue(priv->netdev, index);
+ if (netif_tx_queue_stopped(txq)) {
+ netif_tx_wake_queue(txq);
+ PRINTM(MINFO, "Wakeup Kernel Queue:%d\n", index);
+ }
+ }
+#else /* #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) */
if (atomic_dec_return(&handle->tx_pending) < LOW_TX_PENDING) {
+ int i;
for (i = 0; i < handle->priv_num; i++) {
#ifdef STA_SUPPORT
if ((GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA)
@@ -626,6 +694,7 @@ moal_send_packet_complete(IN t_void * pmoal_handle,
#endif
}
}
+#endif /* #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) */
}
}
if (skb)
@@ -745,10 +814,6 @@ moal_recv_packet(IN t_void * pmoal_handle, IN pmlan_buffer pmbuf)
skb->protocol = eth_type_trans(skb, priv->netdev);
skb->ip_summed = CHECKSUM_NONE;
- if (priv->enable_tcp_ack_enh == MTRUE) {
- woal_check_tcp_fin(priv, skb);
- }
-
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
if (in_interrupt())
@@ -777,7 +842,7 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
int custom_len = 0;
#endif
moal_private *priv = NULL;
-#if defined(STA_WEXT) || defined(UAP_SUPPORT)
+#if defined(STA_SUPPORT) || defined(UAP_SUPPORT)
moal_private *pmpriv = NULL;
#endif
#if defined(STA_WEXT) || defined(UAP_WEXT)
@@ -790,6 +855,7 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
#if defined(SDIO_SUSPEND_RESUME)
mlan_ds_ps_info pm_info;
#endif
+
ENTER();
PRINTM(MEVENT, "event id:0x%x\n", pmevent->event_id);
@@ -798,6 +864,10 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
PRINTM(MERROR, "%s: priv is null\n", __FUNCTION__);
goto done;
}
+ if (priv->netdev == NULL) {
+ PRINTM(MERROR, "%s: netdev is null\n", __FUNCTION__);
+ goto done;
+ }
switch (pmevent->event_id) {
#ifdef STA_SUPPORT
case MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED:
@@ -809,6 +879,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_ADHOC_LINK_SENSED);
#endif
+ woal_broadcast_event(priv, CUS_EVT_ADHOC_LINK_SENSED,
+ strlen(CUS_EVT_ADHOC_LINK_SENSED));
break;
case MLAN_EVENT_ID_FW_ADHOC_LINK_LOST:
@@ -820,6 +892,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_ADHOC_LINK_LOST);
#endif
+ woal_broadcast_event(priv, CUS_EVT_ADHOC_LINK_LOST,
+ strlen(CUS_EVT_ADHOC_LINK_LOST));
break;
case MLAN_EVENT_ID_DRV_CONNECTED:
@@ -832,13 +906,17 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
}
#endif
#ifdef STA_CFG80211
- if (IS_STA_CFG80211(cfg80211_wext))
+ if (IS_STA_CFG80211(cfg80211_wext)) {
memcpy(priv->cfg_bssid, pmevent->event_buf, ETH_ALEN);
+ woal_set_scan_time(priv, ACTIVE_SCAN_CHAN_TIME,
+ PASSIVE_SCAN_CHAN_TIME,
+ MIN_SPECIFIC_SCAN_CHAN_TIME);
+ }
#endif
custom_len = strlen(CUS_EVT_AP_CONNECTED);
memmove(pmevent->event_buf + custom_len, pmevent->event_buf,
pmevent->event_len);
- strncpy(pmevent->event_buf, CUS_EVT_AP_CONNECTED, custom_len);
+ memcpy(pmevent->event_buf, CUS_EVT_AP_CONNECTED, custom_len);
pmevent->event_len += custom_len;
woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len);
priv->media_connected = MTRUE;
@@ -863,12 +941,18 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
#endif
#ifdef STA_CFG80211
if (IS_STA_CFG80211(cfg80211_wext)) {
- woal_inform_bss_from_scan_result(priv, NULL);
+ woal_inform_bss_from_scan_result(priv, NULL, MOAL_NO_WAIT);
PRINTM(MINFO, "Reporting scan results\n");
if (priv->scan_request) {
cfg80211_scan_done(priv->scan_request, MFALSE);
priv->scan_request = NULL;
}
+ if (!priv->phandle->first_scan_done) {
+ priv->phandle->first_scan_done = MTRUE;
+ woal_set_scan_time(priv, ACTIVE_SCAN_CHAN_TIME,
+ PASSIVE_SCAN_CHAN_TIME,
+ SPECIFIC_SCAN_CHAN_TIME);
+ }
}
#endif /* STA_CFG80211 */
@@ -879,15 +963,18 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
break;
case MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM:
+ memmove((pmevent->event_buf + strlen(CUS_EVT_OBSS_SCAN_PARAM) + 1),
+ pmevent->event_buf, pmevent->event_len);
+ memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_OBSS_SCAN_PARAM,
+ strlen(CUS_EVT_OBSS_SCAN_PARAM));
+ pmevent->event_buf[strlen(CUS_EVT_OBSS_SCAN_PARAM)] = 0;
+ woal_broadcast_event(priv, pmevent->event_buf,
+ pmevent->event_len +
+ strlen(CUS_EVT_OBSS_SCAN_PARAM));
+
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext)) {
memset(&wrqu, 0, sizeof(union iwreq_data));
- memmove((pmevent->event_buf + strlen(CUS_EVT_OBSS_SCAN_PARAM) + 1),
- pmevent->event_buf, pmevent->event_len);
- memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_OBSS_SCAN_PARAM,
- strlen(CUS_EVT_OBSS_SCAN_PARAM));
- pmevent->event_buf[strlen(CUS_EVT_OBSS_SCAN_PARAM)] = 0;
-
wrqu.data.pointer = pmevent->event_buf;
wrqu.data.length =
pmevent->event_len + strlen(CUS_EVT_OBSS_SCAN_PARAM) + 1;
@@ -897,15 +984,17 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
#endif
break;
case MLAN_EVENT_ID_FW_BW_CHANGED:
+ memmove((pmevent->event_buf + strlen(CUS_EVT_BW_CHANGED) + 1),
+ pmevent->event_buf, pmevent->event_len);
+ memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_BW_CHANGED,
+ strlen(CUS_EVT_BW_CHANGED));
+ pmevent->event_buf[strlen(CUS_EVT_BW_CHANGED)] = 0;
+ woal_broadcast_event(priv, pmevent->event_buf,
+ pmevent->event_len + strlen(CUS_EVT_BW_CHANGED));
+
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext)) {
memset(&wrqu, 0, sizeof(union iwreq_data));
- memmove((pmevent->event_buf + strlen(CUS_EVT_BW_CHANGED) + 1),
- pmevent->event_buf, pmevent->event_len);
- memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_BW_CHANGED,
- strlen(CUS_EVT_BW_CHANGED));
- pmevent->event_buf[strlen(CUS_EVT_BW_CHANGED)] = 0;
-
wrqu.data.pointer = pmevent->event_buf;
wrqu.data.length =
pmevent->event_len + strlen(CUS_EVT_BW_CHANGED) + 1;
@@ -954,6 +1043,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
GFP_KERNEL);
}
#endif
+ woal_broadcast_event(priv, CUS_EVT_MLME_MIC_ERR_UNI,
+ strlen(CUS_EVT_MLME_MIC_ERR_UNI));
break;
case MLAN_EVENT_ID_FW_MIC_ERR_MUL:
#ifdef STA_WEXT
@@ -972,6 +1063,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
GFP_KERNEL);
}
#endif
+ woal_broadcast_event(priv, CUS_EVT_MLME_MIC_ERR_MUL,
+ strlen(CUS_EVT_MLME_MIC_ERR_MUL));
break;
case MLAN_EVENT_ID_FW_BCN_RSSI_LOW:
#ifdef STA_WEXT
@@ -986,9 +1079,12 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
GFP_KERNEL);
priv->last_event |= EVENT_BCN_RSSI_LOW;
#endif
- woal_set_rssi_threshold(priv, MLAN_EVENT_ID_FW_BCN_RSSI_LOW);
+ if (!hw_test && priv->roaming_enabled)
+ woal_config_bgscan_and_rssi(priv, MTRUE);
}
#endif
+ woal_broadcast_event(priv, CUS_EVT_BEACON_RSSI_LOW,
+ strlen(CUS_EVT_BEACON_RSSI_LOW));
break;
case MLAN_EVENT_ID_FW_BCN_RSSI_HIGH:
#ifdef STA_WEXT
@@ -1003,58 +1099,76 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
GFP_KERNEL);
#endif
- woal_set_rssi_threshold(priv, MLAN_EVENT_ID_FW_BCN_RSSI_HIGH);
+ woal_set_rssi_threshold(priv, MLAN_EVENT_ID_FW_BCN_RSSI_HIGH,
+ MOAL_NO_WAIT);
}
}
#endif
+ woal_broadcast_event(priv, CUS_EVT_BEACON_RSSI_HIGH,
+ strlen(CUS_EVT_BEACON_RSSI_HIGH));
break;
case MLAN_EVENT_ID_FW_BCN_SNR_LOW:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_BEACON_SNR_LOW);
#endif
+ woal_broadcast_event(priv, CUS_EVT_BEACON_SNR_LOW,
+ strlen(CUS_EVT_BEACON_SNR_LOW));
break;
case MLAN_EVENT_ID_FW_BCN_SNR_HIGH:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_BEACON_SNR_HIGH);
#endif
+ woal_broadcast_event(priv, CUS_EVT_BEACON_SNR_HIGH,
+ strlen(CUS_EVT_BEACON_SNR_HIGH));
break;
case MLAN_EVENT_ID_FW_MAX_FAIL:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_MAX_FAIL);
#endif
+ woal_broadcast_event(priv, CUS_EVT_MAX_FAIL, strlen(CUS_EVT_MAX_FAIL));
break;
case MLAN_EVENT_ID_FW_DATA_RSSI_LOW:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_DATA_RSSI_LOW);
#endif
+ woal_broadcast_event(priv, CUS_EVT_DATA_RSSI_LOW,
+ strlen(CUS_EVT_DATA_RSSI_LOW));
break;
case MLAN_EVENT_ID_FW_DATA_SNR_LOW:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_DATA_SNR_LOW);
#endif
+ woal_broadcast_event(priv, CUS_EVT_DATA_SNR_LOW,
+ strlen(CUS_EVT_DATA_SNR_LOW));
break;
case MLAN_EVENT_ID_FW_DATA_RSSI_HIGH:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_DATA_RSSI_HIGH);
#endif
+ woal_broadcast_event(priv, CUS_EVT_DATA_RSSI_HIGH,
+ strlen(CUS_EVT_DATA_RSSI_HIGH));
break;
case MLAN_EVENT_ID_FW_DATA_SNR_HIGH:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_DATA_SNR_HIGH);
#endif
+ woal_broadcast_event(priv, CUS_EVT_DATA_SNR_HIGH,
+ strlen(CUS_EVT_DATA_SNR_HIGH));
break;
case MLAN_EVENT_ID_FW_LINK_QUALITY:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_LINK_QUALITY);
#endif
+ woal_broadcast_event(priv, CUS_EVT_LINK_QUALITY,
+ strlen(CUS_EVT_LINK_QUALITY));
break;
case MLAN_EVENT_ID_FW_PORT_RELEASE:
#ifdef STA_WEXT
@@ -1078,19 +1192,29 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
0, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
if (bss)
cfg80211_unlink_bss(priv->wdev->wiphy, bss);
- cfg80211_cqm_rssi_notify(priv->netdev,
- NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
- GFP_KERNEL);
+ if (!hw_test && priv->roaming_enabled)
+ woal_config_bgscan_and_rssi(priv, MFALSE);
priv->last_event |= EVENT_PRE_BCN_LOST;
}
#endif
#endif
+ woal_broadcast_event(priv, CUS_EVT_PRE_BEACON_LOST,
+ strlen(CUS_EVT_PRE_BEACON_LOST));
+ break;
+ case MLAN_EVENT_ID_FW_DEBUG_INFO:
+#ifdef STA_WEXT
+ if (IS_STA_WEXT(cfg80211_wext))
+ woal_send_iwevcustom_event(priv, pmevent->event_buf);
+#endif
+ woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len);
break;
case MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, WMM_CONFIG_CHANGE_INDICATION);
#endif
+ woal_broadcast_event(priv, WMM_CONFIG_CHANGE_INDICATION,
+ strlen(WMM_CONFIG_CHANGE_INDICATION));
break;
case MLAN_EVENT_ID_DRV_REPORT_STRING:
@@ -1099,6 +1223,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, pmevent->event_buf);
#endif
+ woal_broadcast_event(priv, pmevent->event_buf,
+ strlen(pmevent->event_buf));
break;
case MLAN_EVENT_ID_FW_WEP_ICV_ERR:
DBG_HEXDUMP(MCMD_D, "WEP ICV error", pmevent->event_buf,
@@ -1107,6 +1233,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_WEP_ICV_ERR);
#endif
+ woal_broadcast_event(priv, CUS_EVT_WEP_ICV_ERR,
+ strlen(CUS_EVT_WEP_ICV_ERR));
break;
case MLAN_EVENT_ID_DRV_DEFER_HANDLING:
@@ -1114,6 +1242,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
break;
case MLAN_EVENT_ID_DRV_DBG_DUMP:
woal_moal_debug_info(priv, NULL, MFALSE);
+#if defined(DEBUG_LEVEL1)
+#endif
break;
case MLAN_EVENT_ID_FW_BG_SCAN:
if (priv->media_connected == MTRUE)
@@ -1128,21 +1258,54 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
#ifdef STA_CFG80211
if (IS_STA_CFG80211(cfg80211_wext)) {
priv->last_event |= EVENT_BG_SCAN_REPORT;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS)
- if (priv->mrvl_rssi_low) {
- cfg80211_cqm_rssi_notify(priv->netdev,
- NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
- GFP_KERNEL);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+ if (priv->sched_scanning && !priv->phandle->cfg80211_suspend) {
+ mlan_scan_resp scan_resp;
+ woal_get_scan_table(priv, MOAL_NO_WAIT, &scan_resp);
+ PRINTM(MIOCTL, "Trigger mlan get bgscan result\n");
+ }
+#endif
+ if (!hw_test && priv->roaming_enabled) {
+ priv->roaming_required = MTRUE;
+ wake_up_interruptible(&priv->phandle->reassoc_thread.wait_q);
+ }
+ }
+#endif
+ break;
+ case MLAN_EVENT_ID_FW_BG_SCAN_STOPPED:
+#ifdef STA_CFG80211
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+ if (IS_STA_CFG80211(cfg80211_wext)) {
+ if (priv->sched_scanning) {
+ cfg80211_sched_scan_stopped(priv->wdev->wiphy);
+ PRINTM(MEVENT, "Sched_Scan stopped\n");
+ priv->sched_scanning = MFALSE;
}
+ }
#endif
+#endif
+ break;
+ case MLAN_EVENT_ID_DRV_BGSCAN_RESULT:
+#ifdef STA_CFG80211
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+ if (IS_STA_CFG80211(cfg80211_wext)) {
+ if (priv->sched_scanning && !priv->phandle->cfg80211_suspend) {
+ woal_inform_bss_from_scan_result(priv, NULL, MOAL_NO_WAIT);
+ cfg80211_sched_scan_results(priv->wdev->wiphy);
+ priv->last_event = 0;
+ PRINTM(MEVENT, "Reporting Sched_Scan results\n");
+ }
}
#endif
+#endif
break;
case MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN:
#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext))
woal_send_iwevcustom_event(priv, CUS_EVT_CHANNEL_SWITCH_ANN);
#endif
+ woal_broadcast_event(priv, CUS_EVT_CHANNEL_SWITCH_ANN,
+ strlen(CUS_EVT_CHANNEL_SWITCH_ANN));
break;
#endif /* STA_SUPPORT */
case MLAN_EVENT_ID_FW_STOP_TX:
@@ -1158,15 +1321,19 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
case MLAN_EVENT_ID_FW_HS_WAKEUP:
/* simulate HSCFG_CANCEL command */
woal_cancel_hs(priv, MOAL_NO_WAIT);
-#ifdef STA_WEXT
#ifdef STA_SUPPORT
+#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext) && (pmpriv = woal_get_priv((moal_handle
*)
pmoal_handle,
MLAN_BSS_ROLE_STA)))
woal_send_iwevcustom_event(pmpriv, CUS_EVT_HS_WAKEUP);
-#endif /* STA_SUPPORT */
#endif /* STA_WEXT */
+ if ((pmpriv =
+ woal_get_priv((moal_handle *) pmoal_handle, MLAN_BSS_ROLE_STA)))
+ woal_broadcast_event(pmpriv, CUS_EVT_HS_WAKEUP,
+ strlen(CUS_EVT_HS_WAKEUP));
+#endif /* STA_SUPPORT */
#ifdef UAP_SUPPORT
if ((pmpriv =
woal_get_priv((moal_handle *) pmoal_handle, MLAN_BSS_ROLE_UAP))) {
@@ -1177,8 +1344,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
#endif /* UAP_SUPPORT */
break;
case MLAN_EVENT_ID_DRV_HS_ACTIVATED:
-#ifdef STA_WEXT
#ifdef STA_SUPPORT
+#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext) && (pmpriv = woal_get_priv((moal_handle
*)
pmoal_handle,
@@ -1186,8 +1353,12 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
{
woal_send_iwevcustom_event(pmpriv, CUS_EVT_HS_ACTIVATED);
}
-#endif /* STA_SUPPORT */
#endif /* STA_WEXT */
+ if ((pmpriv =
+ woal_get_priv((moal_handle *) pmoal_handle, MLAN_BSS_ROLE_STA)))
+ woal_broadcast_event(pmpriv, CUS_EVT_HS_ACTIVATED,
+ strlen(CUS_EVT_HS_ACTIVATED));
+#endif /* STA_SUPPORT */
#if defined(UAP_SUPPORT)
if ((pmpriv =
woal_get_priv((moal_handle *) pmoal_handle, MLAN_BSS_ROLE_UAP))) {
@@ -1211,8 +1382,8 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
#endif
break;
case MLAN_EVENT_ID_DRV_HS_DEACTIVATED:
-#ifdef STA_WEXT
#ifdef STA_SUPPORT
+#ifdef STA_WEXT
if (IS_STA_WEXT(cfg80211_wext) && (pmpriv = woal_get_priv((moal_handle
*)
pmoal_handle,
@@ -1220,8 +1391,12 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
{
woal_send_iwevcustom_event(pmpriv, CUS_EVT_HS_DEACTIVATED);
}
-#endif
-#endif
+#endif /* STA_WEXT */
+ if ((pmpriv =
+ woal_get_priv((moal_handle *) pmoal_handle, MLAN_BSS_ROLE_STA)))
+ woal_broadcast_event(pmpriv, CUS_EVT_HS_DEACTIVATED,
+ strlen(CUS_EVT_HS_DEACTIVATED));
+#endif /* STA_SUPPORT */
#if defined(UAP_SUPPORT)
if ((pmpriv =
woal_get_priv((moal_handle *) pmoal_handle, MLAN_BSS_ROLE_UAP))) {
@@ -1237,9 +1412,24 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
#ifdef UAP_SUPPORT
case MLAN_EVENT_ID_UAP_FW_BSS_START:
priv->bss_started = MTRUE;
+ if (!netif_carrier_ok(priv->netdev))
+ netif_carrier_on(priv->netdev);
+ woal_start_queue(priv->netdev);
memcpy(priv->current_addr, pmevent->event_buf + 6, ETH_ALEN);
memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len);
+#ifdef STA_SUPPORT
+#ifdef STA_CFG80211
+ if (IS_STA_CFG80211(cfg80211_wext)) {
+ if ((pmpriv =
+ woal_get_priv((moal_handle *) pmoal_handle,
+ MLAN_BSS_ROLE_STA)))
+ woal_set_scan_time(pmpriv, ACTIVE_SCAN_CHAN_TIME,
+ PASSIVE_SCAN_CHAN_TIME,
+ MIN_SPECIFIC_SCAN_CHAN_TIME);
+ }
+#endif
+#endif
break;
case MLAN_EVENT_ID_UAP_FW_BSS_ACTIVE:
priv->media_connected = MTRUE;
@@ -1250,24 +1440,29 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
break;
case MLAN_EVENT_ID_UAP_FW_BSS_IDLE:
priv->media_connected = MFALSE;
- woal_stop_queue(priv->netdev);
- if (netif_carrier_ok(priv->netdev))
- netif_carrier_off(priv->netdev);
woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len);
break;
#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
case MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED:
if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
- PRINTM(MEVENT, "FW_REMAIN_ON_CH0ANNEL_EXPIRED cookie = %#llx\n",
+ PRINTM(MEVENT, "FW_REMAIN_ON_CHANNEL_EXPIRED cookie = %#llx\n",
priv->phandle->cookie);
priv->phandle->remain_on_channel = MFALSE;
if (priv->phandle->cookie) {
- cfg80211_remain_on_channel_expired(priv->netdev,
- priv->phandle->cookie,
- &priv->phandle->chan,
- priv->phandle->channel_type,
- GFP_ATOMIC);
+ cfg80211_remain_on_channel_expired(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+ priv->netdev,
+#else
+ priv->wdev,
+#endif
+ priv->phandle->cookie,
+ &priv->phandle->chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ priv->phandle->
+ channel_type,
+#endif
+ GFP_ATOMIC);
priv->phandle->cookie = 0;
}
}
@@ -1285,7 +1480,10 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
/* copy the station mac address */
memset(addr, 0xFF, ETH_ALEN);
memcpy(addr, pmevent->event_buf, ETH_ALEN);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) || defined(COMPAT_WIRELESS)
+ /** these field add in kernel 3.2, but some kernel do have the pacth to
+ * support it,like T3T and pxa978T 3.0.31 JB, these patch are
+ * needed to support wpa_supplicant 2.x */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31) || defined(COMPAT_WIRELESS)
if (pmevent->event_len > ETH_ALEN) {
/* set station info filled flag */
sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
@@ -1301,14 +1499,17 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
(t_u8 *) addr, &sinfo, GFP_KERNEL);
}
#endif /* UAP_CFG80211 */
+ memmove((pmevent->event_buf + strlen(CUS_EVT_STA_CONNECTED) + 1),
+ pmevent->event_buf, pmevent->event_len);
+ memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_STA_CONNECTED,
+ strlen(CUS_EVT_STA_CONNECTED));
+ pmevent->event_buf[strlen(CUS_EVT_STA_CONNECTED)] = 0;
+ woal_broadcast_event(priv, pmevent->event_buf,
+ pmevent->event_len +
+ strlen(CUS_EVT_STA_CONNECTED));
#ifdef UAP_WEXT
if (IS_UAP_WEXT(cfg80211_wext)) {
memset(&wrqu, 0, sizeof(union iwreq_data));
- memmove((pmevent->event_buf + strlen(CUS_EVT_STA_CONNECTED) + 1),
- pmevent->event_buf, pmevent->event_len);
- memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_STA_CONNECTED,
- strlen(CUS_EVT_STA_CONNECTED));
- pmevent->event_buf[strlen(CUS_EVT_STA_CONNECTED)] = 0;
wrqu.data.pointer = pmevent->event_buf;
if ((pmevent->event_len + strlen(CUS_EVT_STA_CONNECTED) + 1) >
IW_CUSTOM_MAX)
@@ -1332,15 +1533,18 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
#endif /* KERNEL_VERSION */
}
#endif /* UAP_CFG80211 */
+ memmove((pmevent->event_buf + strlen(CUS_EVT_STA_DISCONNECTED) + 1),
+ pmevent->event_buf, pmevent->event_len);
+ memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_STA_DISCONNECTED,
+ strlen(CUS_EVT_STA_DISCONNECTED));
+ pmevent->event_buf[strlen(CUS_EVT_STA_DISCONNECTED)] = 0;
+ woal_broadcast_event(priv, pmevent->event_buf,
+ pmevent->event_len +
+ strlen(CUS_EVT_STA_DISCONNECTED));
+
#ifdef UAP_WEXT
if (IS_UAP_WEXT(cfg80211_wext)) {
memset(&wrqu, 0, sizeof(union iwreq_data));
- memmove((pmevent->event_buf + strlen(CUS_EVT_STA_DISCONNECTED) + 1),
- pmevent->event_buf, pmevent->event_len);
- memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_STA_DISCONNECTED,
- strlen(CUS_EVT_STA_DISCONNECTED));
- pmevent->event_buf[strlen(CUS_EVT_STA_DISCONNECTED)] = 0;
-
wrqu.data.pointer = pmevent->event_buf;
wrqu.data.length =
pmevent->event_len + strlen(CUS_EVT_STA_DISCONNECTED) + 1;
@@ -1363,6 +1567,19 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
/* frmctl + durationid + addr1 + addr2 + addr3 + seqctl */
#define PACKET_ADDR4_POS (2 + 2 + 6 + 6 + 6 + 2)
t_u8 *pkt;
+ int freq =
+ priv->phandle->remain_on_channel ? priv->phandle->chan.
+ center_freq : woal_get_active_intf_freq(priv->phandle);
+
+ if (!freq) {
+ if (!priv->phandle->chan.center_freq) {
+ PRINTM(MERROR,
+ "Skip to report mgmt packet to cfg80211\n");
+ break;
+ }
+ freq = priv->phandle->chan.center_freq;
+ }
+
pkt = ((t_u8 *) pmevent->event_buf + sizeof(pmevent->event_id));
/* move addr4 */
@@ -1370,18 +1587,31 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
pkt + PACKET_ADDR4_POS + ETH_ALEN,
pmevent->event_len - sizeof(pmevent->event_id)
- PACKET_ADDR4_POS - ETH_ALEN);
+ PRINTM(MIOCTL,
+ "Mgmt RX %s <= framectrl = 0x%x freq = %d roc = %d\n",
+ priv->netdev->name,
+ ((struct ieee80211_mgmt *) pkt)->frame_control, freq,
+ priv->phandle->remain_on_channel);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
- cfg80211_rx_mgmt(priv->netdev, priv->phandle->chan.center_freq,
- 0, ((const t_u8 *) pmevent->event_buf)
- + sizeof(pmevent->event_id),
- pmevent->event_len - sizeof(pmevent->event_id)
- - MLAN_MAC_ADDR_LENGTH, GFP_ATOMIC);
+ cfg80211_rx_mgmt(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ priv->wdev,
#else
- cfg80211_rx_mgmt(priv->netdev, priv->phandle->chan.center_freq,
- 0, ((const t_u8 *) pmevent->event_buf)
- + sizeof(pmevent->event_id),
- pmevent->event_len - sizeof(pmevent->event_id)
- - MLAN_MAC_ADDR_LENGTH, GFP_ATOMIC);
+ priv->netdev,
+#endif
+ freq, 0,
+ ((const t_u8 *) pmevent->event_buf) +
+ sizeof(pmevent->event_id),
+ pmevent->event_len -
+ sizeof(pmevent->event_id) -
+ MLAN_MAC_ADDR_LENGTH, GFP_ATOMIC);
+#else
+ cfg80211_rx_mgmt(priv->netdev, freq,
+ ((const t_u8 *) pmevent->event_buf) +
+ sizeof(pmevent->event_id),
+ pmevent->event_len -
+ sizeof(pmevent->event_id) -
+ MLAN_MAC_ADDR_LENGTH, GFP_ATOMIC);
#endif
}
#endif /* KERNEL_VERSION */
@@ -1393,6 +1623,19 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
case MLAN_EVENT_ID_DRV_PASSTHRU:
woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len);
break;
+ case MLAN_EVENT_ID_DRV_ASSOC_FAILURE_REPORT:
+ PRINTM(MINFO, "Assoc result\n");
+
+ if (priv->media_connected) {
+ PRINTM(MINFO, "Assoc_Rpt: Media Connected\n");
+ if (!netif_carrier_ok(priv->netdev)) {
+ PRINTM(MINFO, "Assoc_Rpt: Carrier On\n");
+ netif_carrier_on(priv->netdev);
+ }
+ PRINTM(MINFO, "Assoc_Rpt: Queue Start\n");
+ woal_wake_queue(priv->netdev);
+ }
+ break;
case MLAN_EVENT_ID_DRV_MEAS_REPORT:
/* We have received measurement report, wakeup measurement wait queue */
PRINTM(MINFO, "Measurement Report\n");
@@ -1437,6 +1680,7 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
PRINTM(MMSG, "BSS START Complete!\n");
}
}
+
default:
break;
}
@@ -1455,7 +1699,7 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
* @return N/A
*/
t_void
-moal_print(IN t_void * pmoal_handle, IN t_u32 level, IN t_s8 * pformat, IN ...)
+moal_print(IN t_void * pmoal_handle, IN t_u32 level, IN char *pformat, IN ...)
{
#ifdef DEBUG_LEVEL1
va_list args;
@@ -1489,9 +1733,11 @@ moal_print(IN t_void * pmoal_handle, IN t_u32 level, IN t_s8 * pformat, IN ...)
DBG_HEXDUMP(MEVT_D, (char *) pformat, buf, len);
}
} else {
- va_start(args, pformat);
- vprintk(pformat, args);
- va_end(args);
+ if (drvdbg & level) {
+ va_start(args, pformat);
+ vprintk(pformat, args);
+ va_end(args);
+ }
}
#endif /* DEBUG_LEVEL1 */
}
@@ -1511,10 +1757,12 @@ moal_print_netintf(IN t_void * pmoal_handle, IN t_u32 bss_index, IN t_u32 level)
#ifdef DEBUG_LEVEL1
moal_handle *phandle = (moal_handle *) pmoal_handle;
- if (phandle && (drvdbg & level)) {
+ if (phandle) {
if ((bss_index < MLAN_MAX_BSS_NUM) && phandle->priv[bss_index] &&
- phandle->priv[bss_index]->netdev)
- printk("%s: ", phandle->priv[bss_index]->netdev->name);
+ phandle->priv[bss_index]->netdev) {
+ if (drvdbg & level)
+ printk("%s: ", phandle->priv[bss_index]->netdev->name);
+ }
}
#endif /* DEBUG_LEVEL1 */
}
@@ -1530,6 +1778,7 @@ moal_print_netintf(IN t_void * pmoal_handle, IN t_u32 bss_index, IN t_u32 level)
t_void
moal_assert(IN t_void * pmoal_handle, IN t_u32 cond)
{
- if (!cond)
+ if (!cond) {
panic("Assert failed: Panic!");
+ }
}
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_shim.h b/drivers/net/wireless/sd8797/mlinux/moal_shim.h
index ee50a2105f0f..76be517d9858 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_shim.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_shim.h
@@ -43,6 +43,7 @@ mlan_status moal_free_mlan_buffer(IN t_void * pmoal_handle,
mlan_status moal_send_packet_complete(IN t_void * pmoal_handle,
IN pmlan_buffer pmbuf,
IN mlan_status status);
+
/** moal_write_reg */
mlan_status moal_write_reg(IN t_void * pmoal_handle,
IN t_u32 reg, IN t_u32 data);
@@ -60,6 +61,9 @@ mlan_status moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent);
mlan_status moal_malloc(IN t_void * pmoal_handle,
IN t_u32 size, IN t_u32 flag, OUT t_u8 ** ppbuf);
mlan_status moal_mfree(IN t_void * pmoal_handle, IN t_u8 * pbuf);
+mlan_status moal_vmalloc(IN t_void * pmoal_handle,
+ IN t_u32 size, OUT t_u8 ** ppbuf);
+mlan_status moal_vfree(IN t_void * pmoal_handle, IN t_u8 * pbuf);
t_void *moal_memset(IN t_void * pmoal_handle,
IN t_void * pmem, IN t_u8 byte, IN t_u32 num);
t_void *moal_memcpy(IN t_void * pmoal_handle,
@@ -77,7 +81,7 @@ mlan_status moal_init_lock(IN t_void * pmoal_handle, OUT t_void ** pplock);
mlan_status moal_free_lock(IN t_void * pmoal_handle, IN t_void * plock);
mlan_status moal_spin_lock(IN t_void * pmoal_handle, IN t_void * plock);
mlan_status moal_spin_unlock(IN t_void * pmoal_handle, IN t_void * plock);
-t_void moal_print(IN t_void * pmoal_handle, IN t_u32 level, IN t_s8 * pformat,
+t_void moal_print(IN t_void * pmoal_handle, IN t_u32 level, IN char *pformat,
IN ...);
t_void moal_print_netintf(IN t_void * pmoal_handle, IN t_u32 bss_index,
IN t_u32 level);
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c b/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c
index 51027a98aff7..7e28dec0dd38 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c
@@ -21,11 +21,25 @@
#include "moal_cfg80211.h"
#include "moal_sta_cfg80211.h"
-static int woal_cfg80211_reg_notifier(struct wiphy *wiphy,
- struct regulatory_request *request);
+#include "moal_eth_ioctl.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+static void
+#else
+static int
+#endif
+
+
+woal_cfg80211_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+static int woal_cfg80211_scan(struct wiphy *wiphy,
+ struct cfg80211_scan_request *request);
+#else
static int woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request);
+#endif
static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme);
@@ -41,6 +55,10 @@ static int woal_cfg80211_dump_station(struct wiphy *wiphy,
struct net_device *dev, int idx,
t_u8 * mac, struct station_info *sinfo);
+static int woal_cfg80211_dump_survey(struct wiphy *wiphy,
+ struct net_device *dev, int idx,
+ struct survey_info *survey);
+
static int woal_cfg80211_set_power_mgmt(struct wiphy *wiphy,
struct net_device *dev, bool enabled,
int timeout);
@@ -51,6 +69,9 @@ static int woal_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
#endif
static int woal_cfg80211_set_tx_power(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
+ struct wireless_dev *wdev,
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) && !defined(COMPAT_WIRELESS)
enum tx_power_setting type,
#else
@@ -68,34 +89,61 @@ static int woal_cfg80211_leave_ibss(struct wiphy *wiphy,
#if defined(WIFI_DIRECT_SUPPORT)
#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
static int woal_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct wireless_dev *wdev,
+#else
struct net_device *dev,
+#endif
u64 cookie);
-void woal_cfg80211_remain_on_channel_done(void *context);
-
static int woal_cfg80211_remain_on_channel(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct wireless_dev *wdev,
+#else
struct net_device *dev,
+#endif
struct ieee80211_channel *chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
enum nl80211_channel_type
- channel_type, unsigned int duration,
- u64 * cookie);
+ channel_type,
+#endif
+ unsigned int duration, u64 * cookie);
static int woal_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct wireless_dev *wdev,
+#else
struct net_device *dev,
+#endif
u64 cookie);
#endif /* KERNEL_VERSION */
#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
-/** cfg80211 STA operations */
-static struct cfg80211_ops woal_cfg80211_sta_ops = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+int woal_cfg80211_sched_scan_start(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_sched_scan_request *request);
+int woal_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev);
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)|| defined(COMPAT_WIRELESS)
+int woal_cfg80211_resume(struct wiphy *wiphy);
+int woal_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
+#endif
+
+/** cfg80211 operations */
+static struct cfg80211_ops woal_cfg80211_ops = {
.change_virtual_intf = woal_cfg80211_change_virtual_intf,
.scan = woal_cfg80211_scan,
.connect = woal_cfg80211_connect,
.disconnect = woal_cfg80211_disconnect,
.get_station = woal_cfg80211_get_station,
.dump_station = woal_cfg80211_dump_station,
+ .dump_survey = woal_cfg80211_dump_survey,
.set_wiphy_params = woal_cfg80211_set_wiphy_params,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
.set_channel = woal_cfg80211_set_channel,
+#endif
.join_ibss = woal_cfg80211_join_ibss,
.leave_ibss = woal_cfg80211_leave_ibss,
.add_key = woal_cfg80211_add_key,
@@ -103,10 +151,24 @@ static struct cfg80211_ops woal_cfg80211_sta_ops = {
.set_default_key = woal_cfg80211_set_default_key,
.set_power_mgmt = woal_cfg80211_set_power_mgmt,
.set_tx_power = woal_cfg80211_set_tx_power,
+ .set_bitrate_mask = woal_cfg80211_set_bitrate_mask,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+ .sched_scan_start = woal_cfg80211_sched_scan_start,
+ .sched_scan_stop = woal_cfg80211_sched_scan_stop,
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)|| defined(COMPAT_WIRELESS)
+ .suspend = woal_cfg80211_suspend,
+ .resume = woal_cfg80211_resume,
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) || defined(COMPAT_WIRELESS)
+ .set_antenna = woal_cfg80211_set_antenna,
+#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS)
.set_cqm_rssi_config = woal_cfg80211_set_cqm_rssi_config,
#endif
#ifdef UAP_CFG80211
+ .add_virtual_intf = woal_cfg80211_add_virtual_intf,
+ .del_virtual_intf = woal_cfg80211_del_virtual_intf,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
.start_ap = woal_cfg80211_add_beacon,
.change_beacon = woal_cfg80211_set_beacon,
@@ -116,53 +178,32 @@ static struct cfg80211_ops woal_cfg80211_sta_ops = {
.set_beacon = woal_cfg80211_set_beacon,
.del_beacon = woal_cfg80211_del_beacon,
#endif
+ .del_station = woal_cfg80211_del_station,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
.mgmt_frame_register = woal_cfg80211_mgmt_frame_register,
.mgmt_tx = woal_cfg80211_mgmt_tx,
#endif
-#endif
-};
-
#if defined(WIFI_DIRECT_SUPPORT)
#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
-/** cfg80211 Wifi Direct operations */
-static struct cfg80211_ops woal_cfg80211_wifi_direct_ops = {
- .change_virtual_intf = woal_cfg80211_change_virtual_intf,
- .scan = woal_cfg80211_scan,
- .connect = woal_cfg80211_connect,
- .disconnect = woal_cfg80211_disconnect,
- .get_station = woal_cfg80211_get_station,
- .dump_station = woal_cfg80211_dump_station,
- .set_wiphy_params = woal_cfg80211_set_wiphy_params,
- .set_channel = woal_cfg80211_set_channel,
- .add_key = woal_cfg80211_add_key,
- .del_key = woal_cfg80211_del_key,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
- .start_ap = woal_cfg80211_add_beacon,
- .change_beacon = woal_cfg80211_set_beacon,
- .stop_ap = woal_cfg80211_del_beacon,
-#else
- .add_beacon = woal_cfg80211_add_beacon,
- .set_beacon = woal_cfg80211_set_beacon,
- .del_beacon = woal_cfg80211_del_beacon,
-#endif
- .mgmt_frame_register = woal_cfg80211_mgmt_frame_register,
- .mgmt_tx = woal_cfg80211_mgmt_tx,
.mgmt_tx_cancel_wait = woal_cfg80211_mgmt_tx_cancel_wait,
.remain_on_channel = woal_cfg80211_remain_on_channel,
.cancel_remain_on_channel = woal_cfg80211_cancel_remain_on_channel,
- .set_default_key = woal_cfg80211_set_default_key,
- .set_power_mgmt = woal_cfg80211_set_power_mgmt,
- .set_tx_power = woal_cfg80211_set_tx_power,
+#endif
+#endif
+#endif
};
-#endif /* KERNEL_VERSION */
-#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+
+/** Region code mapping */
+typedef struct _region_code_t
+{
+ /** Region */
+ t_u8 region[COUNTRY_CODE_LEN];
+} region_code_t;
/********************************************************
Local Variables
********************************************************/
-#if defined(WIFI_DIRECT_SUPPORT)
-#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
static const struct ieee80211_txrx_stypes
ieee80211_mgmt_stypes[NUM_NL80211_IFTYPES] = {
[NL80211_IFTYPE_ADHOC] = {
@@ -189,6 +230,8 @@ static const struct ieee80211_txrx_stypes
.tx = 0x0000,
.rx = 0x0000,
},
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
[NL80211_IFTYPE_P2P_CLIENT] = {
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
@@ -197,8 +240,7 @@ static const struct ieee80211_txrx_stypes
},
[NL80211_IFTYPE_P2P_GO] = {
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- // BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
- 0,
+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
@@ -207,6 +249,8 @@ static const struct ieee80211_txrx_stypes
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
BIT(IEEE80211_STYPE_ACTION >> 4),
},
+#endif
+#endif
[NL80211_IFTYPE_MESH_POINT] = {
.tx = 0x0000,
.rx = 0x0000,
@@ -214,7 +258,11 @@ static const struct ieee80211_txrx_stypes
};
#endif
-#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+
+extern moal_handle *m_handle[];
+extern int hw_test;
+/** Region alpha2 string */
+char *reg_alpha2 = NULL;
/********************************************************
Global Variables
@@ -223,6 +271,38 @@ static const struct ieee80211_txrx_stypes
/********************************************************
Local Functions
********************************************************/
+
+/**
+ * @brief This function check cfg80211 special region code.
+ *
+ * @param region_string Region string
+ *
+ * @return MTRUE/MFALSE
+ */
+t_u8
+is_cfg80211_special_region_code(char *region_string)
+{
+ t_u8 i;
+ t_u8 size = 0;
+ region_code_t cfg80211_special_region_code[] =
+ { {"00 "}, {"99 "}, {"98 "}, {"97 "} };
+
+ size = sizeof(cfg80211_special_region_code) / sizeof(region_code_t);
+
+ for (i = 0; i < COUNTRY_CODE_LEN && region_string[i]; i++) {
+ region_string[i] = toupper(region_string[i]);
+ }
+
+ for (i = 0; i < size; i++) {
+ if (!memcmp(region_string,
+ cfg80211_special_region_code[i].region, COUNTRY_CODE_LEN)) {
+ PRINTM(MIOCTL, "special region code=%s\n", region_string);
+ return MTRUE;
+ }
+ }
+ return MFALSE;
+}
+
/**
* @brief Get the encryption mode from cipher
*
@@ -240,7 +320,7 @@ woal_cfg80211_get_encryption_mode(t_u32 cipher, int *wpa_enabled)
*wpa_enabled = 0;
switch (cipher) {
- case IW_AUTH_CIPHER_NONE:
+ case MW_AUTH_CIPHER_NONE:
encrypt_mode = MLAN_ENCRYPTION_MODE_NONE;
break;
case WLAN_CIPHER_SUITE_WEP40:
@@ -266,6 +346,36 @@ woal_cfg80211_get_encryption_mode(t_u32 cipher, int *wpa_enabled)
}
/**
+ * @brief get associate failure status code
+ *
+ * @param priv Pointer to the moal_private driver data struct
+ *
+ * @return IEEE status code
+ */
+static int
+woal_get_assoc_status(moal_private * priv)
+{
+ int ret = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ t_u16 status = (t_u16) (priv->assoc_status & 0xffff);
+ t_u16 cap = (t_u16) (priv->assoc_status >> 16);
+
+ switch (cap) {
+ case 0xfffd:
+ case 0xfffe:
+ ret = status;
+ break;
+ case 0xfffc:
+ ret = WLAN_STATUS_AUTH_TIMEOUT;
+ break;
+ default:
+ break;
+ }
+ PRINTM(MCMND, "Assoc fail: status=%d, cap=0x%x, IEEE status=%d\n", status,
+ cap, ret);
+ return ret;
+}
+
+/**
* @brief Check the pairwise or group cipher for
* WEP enabled or not
*
@@ -364,40 +474,6 @@ woal_channel_to_nl80211_channel_type(int channel_type)
}
/**
- * @brief Convert driver band configuration to IEEE band type
- *
- * @param band Driver band configuration
- *
- * @return IEEE band type
- */
-t_u8
-woal_band_cfg_to_ieee_band(t_u32 band)
-{
- t_u8 ret_radio_type;
-
- ENTER();
-
- switch (band) {
- case BAND_A:
- case BAND_AN:
- case BAND_A | BAND_AN:
- ret_radio_type = IEEE80211_BAND_5GHZ;
- break;
- case BAND_B:
- case BAND_G:
- case BAND_B | BAND_G:
- case BAND_GN:
- case BAND_B | BAND_GN:
- default:
- ret_radio_type = IEEE80211_BAND_2GHZ;
- break;
- }
-
- LEAVE();
- return ret_radio_type;
-}
-
-/**
* @brief Convert NL80211 interface type to MLAN_BSS_MODE_*
*
* @param iftype Interface type of NL80211
@@ -508,7 +584,10 @@ woal_cfg80211_assoc_ies_cfg(moal_private * priv, t_u8 * ie, int ie_len)
break;
case VENDOR_SPECIFIC_221:
pvendor_ie = (IEEEtypes_VendorSpecific_t *) pcurrent_ptr;
- if (!memcmp(pvendor_ie->vend_hdr.oui, wps_oui, sizeof(wps_oui))) {
+ if (!memcmp
+ (pvendor_ie->vend_hdr.oui, wps_oui,
+ sizeof(pvendor_ie->vend_hdr.oui)) &&
+ (pvendor_ie->vend_hdr.oui_type == wps_oui[3])) {
PRINTM(MIOCTL, "Enable WPS session\n");
woal_wps_cfg(priv, MTRUE);
}
@@ -561,7 +640,6 @@ woal_send_domain_info_cmd_fw(moal_private * priv)
t_u8 first_chan = 0, next_chan = 0, max_pwr = 0;
t_u8 i, flag = 0;
mlan_ds_11d_cfg *cfg_11d = NULL;
- mlan_ds_radio_cfg *radio_cfg = NULL;
mlan_ioctl_req *req = NULL;
ENTER();
@@ -571,31 +649,22 @@ woal_send_domain_info_cmd_fw(moal_private * priv)
ret = MLAN_STATUS_FAILURE;
goto done;
}
-
- /* Allocate an IOCTL request buffer */
- req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
- if (req == NULL) {
+ band = priv->phandle->band;
+ if (!priv->wdev->wiphy->bands[band]) {
+ PRINTM(MERROR, "11D: setting domain info in FW failed band=%d", band);
ret = MLAN_STATUS_FAILURE;
goto done;
}
- radio_cfg = (mlan_ds_radio_cfg *) req->pbuf;
- radio_cfg->sub_command = MLAN_OID_BAND_CFG;
- req->req_id = MLAN_IOCTL_RADIO_CFG;
- req->action = MLAN_ACT_GET;
- if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
- ret = MLAN_STATUS_FAILURE;
- goto done;
- }
- band = woal_band_cfg_to_ieee_band(radio_cfg->param.band_cfg.config_bands);
- if (!priv->wdev->wiphy->bands[band]) {
- PRINTM(MERROR, "11D: setting domain info in FW failed");
- ret = MLAN_STATUS_FAILURE;
+ if (MTRUE == is_cfg80211_special_region_code(priv->phandle->country_code)) {
+ PRINTM(MIOCTL,
+ "skip region code config, cfg80211 special region code: %s\n",
+ priv->phandle->country_code);
goto done;
}
- kfree(req);
- req = NULL;
-
+ PRINTM(MIOCTL, "Send domain info: country=%c%c band=%d\n",
+ priv->phandle->country_code[0], priv->phandle->country_code[1],
+ band);
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg));
if (req == NULL) {
@@ -608,8 +677,8 @@ woal_send_domain_info_cmd_fw(moal_private * priv)
req->action = MLAN_ACT_SET;
/* Set country code */
- cfg_11d->param.domain_info.country_code[0] = priv->country_code[0];
- cfg_11d->param.domain_info.country_code[1] = priv->country_code[1];
+ cfg_11d->param.domain_info.country_code[0] = priv->phandle->country_code[0];
+ cfg_11d->param.domain_info.country_code[1] = priv->phandle->country_code[1];
cfg_11d->param.domain_info.country_code[2] = ' ';
cfg_11d->param.domain_info.band = band;
@@ -711,29 +780,27 @@ woal_set_rf_channel(moal_private * priv,
ret = -EFAULT;
goto done;
}
- if (chan) {
- req->action = MLAN_ACT_SET;
- /* Set appropriate bands */
- if (chan->band == IEEE80211_BAND_2GHZ)
- config_bands = BAND_B | BAND_G | BAND_GN;
- else
- config_bands = BAND_AN | BAND_A;
- if (mode == MLAN_BSS_MODE_IBSS) {
- radio_cfg->param.band_cfg.adhoc_start_band = config_bands;
- radio_cfg->param.band_cfg.adhoc_channel =
- ieee80211_frequency_to_channel(chan->center_freq);
- }
- /* Set channel offset */
- radio_cfg->param.band_cfg.sec_chan_offset =
- woal_cfg80211_channel_type_to_channel(channel_type);
+ req->action = MLAN_ACT_SET;
+ priv->phandle->band = chan->band;
+ /* Set appropriate bands */
+ if (chan->band == IEEE80211_BAND_2GHZ)
+ config_bands = BAND_B | BAND_G | BAND_GN;
+ else
+ config_bands = BAND_AN | BAND_A;
+ if (mode == MLAN_BSS_MODE_IBSS) {
+ radio_cfg->param.band_cfg.adhoc_start_band = config_bands;
+ radio_cfg->param.band_cfg.adhoc_channel =
+ ieee80211_frequency_to_channel(chan->center_freq);
+ }
+ /* Set channel offset */
+ radio_cfg->param.band_cfg.sec_chan_offset =
+ woal_cfg80211_channel_type_to_channel(channel_type);
- if (MLAN_STATUS_SUCCESS !=
- woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
- ret = -EFAULT;
- goto done;
- }
- woal_send_domain_info_cmd_fw(priv);
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = -EFAULT;
+ goto done;
}
+ woal_send_domain_info_cmd_fw(priv);
PRINTM(MINFO,
"Setting band %d, channel bandwidth %d and mode = %d channel=%d\n",
@@ -869,13 +936,15 @@ woal_cfg80211_set_auth(moal_private * priv, int encrypt_mode, int wpa_enabled)
* - WPA IE
* - RSN IE
*
- * @param priv A pointer to moal_private structure
- * @param ssid A pointer to mlan_802_11_ssid structure
+ * @param priv A pointer to moal_private structure
+ * @param ssid_bssid A pointer to A pointer to mlan_ssid_bssid structure
+ * @param wait_option wait_option
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status
-woal_inform_bss_from_scan_result(moal_private * priv, mlan_802_11_ssid * ssid)
+woal_inform_bss_from_scan_result(moal_private * priv,
+ mlan_ssid_bssid * ssid_bssid, t_u8 wait_option)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
struct ieee80211_channel *chan;
@@ -893,8 +962,7 @@ woal_inform_bss_from_scan_result(moal_private * priv, mlan_802_11_ssid * ssid)
memset(&scan_resp, 0, sizeof(scan_resp));
if (MLAN_STATUS_SUCCESS != woal_get_scan_table(priv,
- MOAL_IOCTL_WAIT,
- &scan_resp)) {
+ wait_option, &scan_resp)) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
@@ -902,15 +970,19 @@ woal_inform_bss_from_scan_result(moal_private * priv, mlan_802_11_ssid * ssid)
if (scan_resp.num_in_scan_table) {
scan_table = (BSSDescriptor_t *) scan_resp.pscan_table;
for (i = 0; i < scan_resp.num_in_scan_table; i++) {
- if (ssid) {
+ if (ssid_bssid) {
/* Inform specific BSS only */
- if (memcmp(ssid->ssid, scan_table[i].ssid.ssid, ssid->ssid_len))
+ if (memcmp(ssid_bssid->ssid.ssid, scan_table[i].ssid.ssid,
+ ssid_bssid->ssid.ssid_len) ||
+ memcmp(ssid_bssid->bssid, scan_table[i].mac_address,
+ ETH_ALEN))
continue;
}
if (!scan_table[i].freq) {
- PRINTM(MERROR, "Invalid channel number %d\n",
- (int) scan_table[i].channel);
- continue;
+ scan_table[i].freq =
+ ieee80211_channel_to_frequency((int) scan_table[i].channel,
+ woal_band_cfg_to_ieee_band
+ (scan_table[i].bss_band));
}
chan = ieee80211_get_channel(priv->wdev->wiphy, scan_table[i].freq);
if (!chan) {
@@ -932,8 +1004,14 @@ woal_inform_bss_from_scan_result(moal_private * priv, mlan_802_11_ssid * ssid)
-RSSI_DBM_TO_MDM(scan_table[i].rssi),
GFP_KERNEL);
if (pub) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
pub->len_information_elements = pub->len_beacon_ies;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+ cfg80211_put_bss(priv->wdev->wiphy, pub);
+#else
cfg80211_put_bss(pub);
+#endif
}
}
}
@@ -1007,13 +1085,98 @@ woal_cfg80211_inform_ibss_bss(moal_private * priv,
beacon_interval, ie_buf, ie_len,
signal.bcn_rssi_avg, GFP_KERNEL);
if (bss)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+ cfg80211_put_bss(priv->wdev->wiphy, bss);
+#else
cfg80211_put_bss(bss);
+#endif
done:
LEAVE();
return ret;
}
/**
+ * @brief Process country IE before assoicate
+ *
+ * @param priv A pointer to moal_private structure
+ * @param bss A pointer to cfg80211_bss structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+static int
+woal_process_country_ie(moal_private * priv, struct cfg80211_bss *bss)
+{
+ u8 *country_ie, country_ie_len;
+ int ret = 0;
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_11d_cfg *cfg_11d = NULL;
+
+ ENTER();
+ country_ie = (u8 *) ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
+ if (!country_ie) {
+ PRINTM(MIOCTL, "No country IE found!\n");
+ woal_send_domain_info_cmd_fw(priv);
+ LEAVE();
+ return 0;
+ }
+
+ country_ie_len = country_ie[1];
+ if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) {
+ PRINTM(MIOCTL, "Wrong Country IE length!\n");
+ woal_send_domain_info_cmd_fw(priv);
+ LEAVE();
+ return 0;
+ }
+ PRINTM(MIOCTL, "Find bss country IE: %c%c band=%d\n", country_ie[2],
+ country_ie[3], priv->phandle->band);
+ priv->phandle->country_code[0] = country_ie[2];
+ priv->phandle->country_code[1] = country_ie[3];
+ priv->phandle->country_code[2] = ' ';
+ if (MLAN_STATUS_SUCCESS !=
+ woal_set_region_code(priv, priv->phandle->country_code))
+ PRINTM(MERROR, "Set country code failed!\n");
+
+ /* Allocate an IOCTL request buffer */
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg));
+ if (req == NULL) {
+ PRINTM(MERROR, "Fail to allocate mlan_ds_11d_cfg buffer\n");
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+
+ cfg_11d = (mlan_ds_11d_cfg *) req->pbuf;
+ cfg_11d->sub_command = MLAN_OID_11D_DOMAIN_INFO;
+ req->req_id = MLAN_IOCTL_11D_CFG;
+ req->action = MLAN_ACT_SET;
+
+ /* Set country code */
+ cfg_11d->param.domain_info.country_code[0] = priv->phandle->country_code[0];
+ cfg_11d->param.domain_info.country_code[1] = priv->phandle->country_code[1];
+ cfg_11d->param.domain_info.country_code[2] = ' ';
+
+ /** IEEE80211_BAND_2GHZ or IEEE80211_BAND_5GHZ */
+ cfg_11d->param.domain_info.band = priv->phandle->band;
+
+ country_ie_len -= IEEE80211_COUNTRY_STRING_LEN;
+ cfg_11d->param.domain_info.no_of_sub_band =
+ country_ie_len / sizeof(struct ieee80211_country_ie_triplet);
+ memcpy((u8 *) cfg_11d->param.domain_info.sub_band,
+ &country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len);
+
+ /* Send domain info command to FW */
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = MLAN_STATUS_FAILURE;
+ PRINTM(MERROR, "11D: Error setting domain info in FW\n");
+ goto done;
+ }
+ done:
+ if (req)
+ kfree(req);
+ LEAVE();
+ return ret;
+}
+
+/**
* @brief Request the driver for (re)association
*
* @param priv A pointer to moal_private structure
@@ -1021,7 +1184,7 @@ woal_cfg80211_inform_ibss_bss(moal_private * priv,
*
* @return 0 -- success, otherwise fail
*/
-static int
+int
woal_cfg80211_assoc(moal_private * priv, void *sme)
{
struct cfg80211_ibss_params *ibss_param = NULL;
@@ -1042,6 +1205,7 @@ woal_cfg80211_assoc(moal_private * priv, void *sme)
struct ieee80211_channel *channel = NULL;
t_u16 beacon_interval = 0;
bool privacy;
+ struct cfg80211_bss *bss = NULL;
ENTER();
@@ -1052,29 +1216,46 @@ woal_cfg80211_assoc(moal_private * priv, void *sme)
ssid = ibss_param->ssid;
ssid_len = ibss_param->ssid_len;
bssid = ibss_param->bssid;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
channel = ibss_param->channel;
+#else
+ channel = ibss_param->chandef.chan;
+#endif
+ if (channel)
+ priv->phandle->band = channel->band;
if (ibss_param->ie_len)
ie = ibss_param->ie;
ie_len = ibss_param->ie_len;
beacon_interval = ibss_param->beacon_interval;
privacy = ibss_param->privacy;
+
} else {
conn_param = (struct cfg80211_connect_params *) sme;
ssid = conn_param->ssid;
ssid_len = conn_param->ssid_len;
bssid = conn_param->bssid;
channel = conn_param->channel;
+ if (channel)
+ priv->phandle->band = channel->band;
if (conn_param->ie_len)
ie = conn_param->ie;
ie_len = conn_param->ie_len;
privacy = conn_param->privacy;
+ bss =
+ cfg80211_get_bss(priv->wdev->wiphy, channel, bssid, ssid, ssid_len,
+ WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+ if (bss) {
+ woal_process_country_ie(priv, bss);
+ cfg80211_put_bss(bss);
+ } else
+ woal_send_domain_info_cmd_fw(priv);
}
memset(&req_ssid, 0, sizeof(mlan_802_11_ssid));
memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));
req_ssid.ssid_len = ssid_len;
- if (ssid_len > IW_ESSID_MAX_SIZE) {
+ if (ssid_len > MW_ESSID_MAX_SIZE) {
PRINTM(MERROR, "Invalid SSID - aborting\n");
ret = -EINVAL;
goto done;
@@ -1264,7 +1445,8 @@ woal_cfg80211_assoc(moal_private * priv, void *sme)
}
/* Disconnect before try to associate */
- woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
+ if (mode == MLAN_BSS_MODE_IBSS)
+ woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
if (mode != MLAN_BSS_MODE_IBSS) {
if (MLAN_STATUS_SUCCESS !=
@@ -1275,7 +1457,8 @@ woal_cfg80211_assoc(moal_private * priv, void *sme)
/* Inform the BSS information to kernel, otherwise kernel will give a
panic after successful assoc */
if (MLAN_STATUS_SUCCESS !=
- woal_inform_bss_from_scan_result(priv, &req_ssid)) {
+ woal_inform_bss_from_scan_result(priv, &ssid_bssid,
+ MOAL_IOCTL_WAIT)) {
ret = -EFAULT;
goto done;
}
@@ -1284,8 +1467,8 @@ woal_cfg80211_assoc(moal_private * priv, void *sme)
/* Adhoc start, Check the channel command */
woal_11h_channel_check_ioctl(priv);
- PRINTM(MINFO, "Trying to associate to %s and bssid %pM\n",
- (char *) req_ssid.ssid, ssid_bssid.bssid);
+ PRINTM(MINFO, "Trying to associate to %s and bssid " MACSTR "\n",
+ (char *) req_ssid.ssid, MAC2STR(ssid_bssid.bssid));
/* Zero SSID implies use BSSID to connect */
if (bssid)
@@ -1311,9 +1494,15 @@ woal_cfg80211_assoc(moal_private * priv, void *sme)
done:
if (ret) {
+ /* clear the encryption mode */
+ woal_cfg80211_set_auth(priv, MLAN_ENCRYPTION_MODE_NONE, MFALSE);
/* clear IE */
ie_len = 0;
- woal_set_get_gen_ie(priv, MLAN_ACT_SET, NULL, &ie_len);
+ if (MLAN_STATUS_SUCCESS !=
+ woal_set_get_gen_ie(priv, MLAN_ACT_SET, NULL, &ie_len)) {
+ PRINTM(MERROR, "Could not clear RSN IE\n");
+ ret = -EFAULT;
+ }
}
if (req)
kfree(req);
@@ -1388,6 +1577,9 @@ woal_cfg80211_dump_station_info(moal_private * priv, struct station_info *sinfo)
mlan_ds_get_signal signal;
mlan_ioctl_req *req = NULL;
mlan_ds_rate *rate = NULL;
+ t_u16 Rates[12] =
+ { 0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60,
+ 0x6c };
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) || defined(COMPAT_WIRELESS)
mlan_bss_info bss_info;
t_u8 dtim_period = 0;
@@ -1420,14 +1612,20 @@ woal_cfg80211_dump_station_info(moal_private * priv, struct station_info *sinfo)
ret = MLAN_STATUS_FAILURE;
goto done;
}
- sinfo->txrate.flags = RATE_INFO_FLAGS_MCS;
- if (rate->param.data_rate.tx_ht_bw == MLAN_HT_BW40) {
- sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
- }
- if (rate->param.data_rate.tx_ht_gi == MLAN_HT_SGI) {
- sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ if (rate->param.data_rate.tx_data_rate >= MLAN_RATE_INDEX_MCS0) {
+ sinfo->txrate.flags = RATE_INFO_FLAGS_MCS;
+ if (rate->param.data_rate.tx_ht_bw == MLAN_HT_BW40) {
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ }
+ if (rate->param.data_rate.tx_ht_gi == MLAN_HT_SGI) {
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ }
+ sinfo->txrate.mcs =
+ rate->param.data_rate.tx_data_rate - MLAN_RATE_INDEX_MCS0;
+ } else {
+ /* Bit rate is in 500 kb/s units. Convert it to 100kb/s units */
+ sinfo->txrate.legacy = Rates[rate->param.data_rate.tx_data_rate] * 5;
}
- sinfo->txrate.mcs = rate->param.data_rate.tx_data_rate;
sinfo->rx_bytes = priv->stats.rx_bytes;
sinfo->tx_bytes = priv->stats.tx_bytes;
sinfo->rx_packets = priv->stats.rx_packets;
@@ -1476,52 +1674,85 @@ woal_cfg80211_dump_station_info(moal_private * priv, struct station_info *sinfo)
*
* @return 0
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+static void
+#else
static int
+#endif
woal_cfg80211_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
{
- moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy);
+ moal_private *priv = NULL;
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
int ret = 0;
+#endif
ENTER();
+ priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
if (!priv) {
PRINTM(MFATAL, "Unable to get priv in %s()\n", __FUNCTION__);
LEAVE();
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
return -EINVAL;
+#else
+ return;
+#endif
}
- PRINTM(MINFO, "cfg80211 regulatory domain callback "
+ PRINTM(MIOCTL, "cfg80211 regulatory domain callback "
"%c%c\n", request->alpha2[0], request->alpha2[1]);
-
- if (MLAN_STATUS_SUCCESS != woal_set_region_code(priv, request->alpha2))
+ if (MTRUE == is_cfg80211_special_region_code(request->alpha2)) {
+ PRINTM(MIOCTL, "Skip configure special region code\n");
+ LEAVE();
+ return ret;
+ }
+ handle->country_code[0] = request->alpha2[0];
+ handle->country_code[1] = request->alpha2[1];
+ handle->country_code[2] = ' ';
+ if (MLAN_STATUS_SUCCESS != woal_set_region_code(priv, handle->country_code))
PRINTM(MERROR, "Set country code failed!\n");
- memcpy(priv->country_code, request->alpha2, COUNTRY_CODE_LEN);
-
switch (request->initiator) {
case NL80211_REGDOM_SET_BY_DRIVER:
- PRINTM(MINFO, "Regulatory domain BY_DRIVER\n");
+ PRINTM(MIOCTL, "Regulatory domain BY_DRIVER\n");
break;
case NL80211_REGDOM_SET_BY_CORE:
- PRINTM(MINFO, "Regulatory domain BY_CORE\n");
+ PRINTM(MIOCTL, "Regulatory domain BY_CORE\n");
break;
case NL80211_REGDOM_SET_BY_USER:
- PRINTM(MINFO, "Regulatory domain BY_USER\n");
+ PRINTM(MIOCTL, "Regulatory domain BY_USER\n");
break;
/* TODO: apply driver specific changes in channel flags based on the
request initiator if necessory. * */
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
- PRINTM(MINFO, "Regulatory domain BY_COUNTRY_IE\n");
+ PRINTM(MIOCTL, "Regulatory domain BY_COUNTRY_IE\n");
break;
}
-
- if (MLAN_STATUS_SUCCESS != woal_send_domain_info_cmd_fw(priv))
- ret = -EFAULT;
-
+ if (priv->wdev && priv->wdev->wiphy &&
+ (request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE))
+ woal_send_domain_info_cmd_fw(priv);
LEAVE();
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
return ret;
+#endif
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+/**
+ * @brief Request the driver to do a scan. Always returning
+ * zero meaning that the scan request is given to driver,
+ * and will be valid until passed to cfg80211_scan_done().
+ * To inform scan results, call cfg80211_inform_bss().
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param request A pointer to cfg80211_scan_request structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+static int
+woal_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
+#else
/**
* @brief Request the driver to do a scan. Always returning
* zero meaning that the scan request is given to driver,
@@ -1537,7 +1768,11 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy,
static int
woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request)
+#endif
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct net_device *dev = request->wdev->netdev;
+#endif
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
wlan_user_scan_cfg scan_req;
mlan_bss_info bss_info;
@@ -1547,28 +1782,35 @@ woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
ENTER();
PRINTM(MINFO, "Received scan request on %s\n", dev->name);
-#if defined(WIFI_DIRECT_SUPPORT)
-#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+#ifdef UAP_CFG80211
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
LEAVE();
cfg80211_scan_done(request, MTRUE);
return 0;
}
#endif
-#endif
+
if (priv->phandle->scan_pending_on_block == MTRUE) {
PRINTM(MINFO, "scan already in processing...\n");
LEAVE();
return -EBUSY;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+ if (priv->last_event & EVENT_BG_SCAN_REPORT) {
+ PRINTM(MINFO, "block scan while pending BGSCAN result\n");
+ priv->last_event = 0;
+ cfg80211_scan_done(request, MTRUE);
+ LEAVE();
+ return 0;
+ }
+#endif
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#ifdef WIFI_DIRECT_SUPPORT
- if (priv->phandle->remain_on_channel || priv->phandle->is_go_timer_set) {
- PRINTM(MINFO, "block scan ... remain_on_channel=%d go_timer=%d\n",
- priv->phandle->remain_on_channel,
- priv->phandle->is_go_timer_set);
+ if (priv->phandle->is_go_timer_set) {
+ PRINTM(MINFO, "block scan in go timer....\n");
+ cfg80211_scan_done(request, MTRUE);
LEAVE();
- return -EBUSY;
+ return 0;
}
#endif
#endif
@@ -1602,23 +1844,32 @@ woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT &&
priv->scan_request->n_ssids) {
- if (!memcmp(scan_req.ssid_list[i - 1].ssid, "DIRECT-", 7)) {
- /* Enable wildcard ssid scan */
- memcpy(scan_req.ssid_list[i].ssid, "DIRECT-*", 8);
- scan_req.ssid_list[i].max_len = 0xff;
+ if (!memcmp(scan_req.ssid_list[0].ssid, "DIRECT-", 7)) {
+ scan_req.ssid_list[0].max_len = 0xfe;
}
}
#endif
#endif
- for (i = 0; i < priv->scan_request->n_channels; i++) {
+ for (i = 0;
+ i < MIN(WLAN_USER_SCAN_CHAN_MAX, priv->scan_request->n_channels);
+ i++) {
chan = priv->scan_request->channels[i];
scan_req.chan_list[i].chan_number = chan->hw_value;
scan_req.chan_list[i].radio_type = chan->band;
- if (chan->flags & IEEE80211_CHAN_DISABLED)
+ if (chan->flags & (IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_RADAR))
scan_req.chan_list[i].scan_type = MLAN_SCAN_TYPE_PASSIVE;
else
scan_req.chan_list[i].scan_type = MLAN_SCAN_TYPE_ACTIVE;
scan_req.chan_list[i].scan_time = 0;
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT &&
+ priv->scan_request->n_ssids) {
+ if (!memcmp(scan_req.ssid_list[0].ssid, "DIRECT-", 7))
+ scan_req.chan_list[i].scan_time = MIN_SPECIFIC_SCAN_CHAN_TIME;
+ }
+#endif
+#endif
}
if (priv->scan_request->ie && priv->scan_request->ie_len) {
if (MLAN_STATUS_SUCCESS !=
@@ -1627,14 +1878,15 @@ woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
(t_u8 *) priv->scan_request->ie,
priv->scan_request->ie_len,
MGMT_MASK_PROBE_REQ)) {
- PRINTM(MERROR, "Fail to set mgmt frame IE\n");
+ PRINTM(MERROR, "Fail to set scan request IE\n");
ret = -EFAULT;
goto done;
}
} else {
/** Clear SCAN IE in Firmware */
- woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, NULL, 0, NULL, 0,
- MGMT_MASK_PROBE_REQ);
+ if (priv->probereq_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)
+ woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, NULL, 0, NULL,
+ 0, MGMT_MASK_PROBE_REQ);
}
if (MLAN_STATUS_SUCCESS != woal_do_scan(priv, &scan_req)) {
PRINTM(MERROR, "woal_do_scan fails!\n");
@@ -1642,8 +1894,10 @@ woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
goto done;
}
done:
- if (ret)
+ if (ret) {
+ cfg80211_scan_done(request, MTRUE);
priv->scan_request = NULL;
+ }
LEAVE();
return ret;
}
@@ -1664,11 +1918,18 @@ woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
{
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
int ret = 0;
+ mlan_bss_info bss_info;
+ mlan_ssid_bssid ssid_bssid;
ENTER();
PRINTM(MINFO, "Received association request on %s\n", dev->name);
-
+#ifdef UAP_CFG80211
+ if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
+ LEAVE();
+ return 0;
+ }
+#endif
if (priv->wdev->iftype != NL80211_IFTYPE_STATION
#if defined(WIFI_DIRECT_SUPPORT)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
@@ -1681,6 +1942,24 @@ woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
LEAVE();
return -EINVAL;
}
+
+ memset(&ssid_bssid, 0, sizeof(ssid_bssid));
+ memcpy(&ssid_bssid.ssid.ssid, sme->ssid, sme->ssid_len);
+ ssid_bssid.ssid.ssid_len = sme->ssid_len;
+ if (sme->bssid)
+ memcpy(&ssid_bssid.bssid, sme->bssid, ETH_ALEN);
+ if (MTRUE == woal_is_connected(priv, &ssid_bssid)) {
+ /* Inform the BSS information to kernel, otherwise * kernel will give a
+ panic after successful assoc */
+ woal_inform_bss_from_scan_result(priv, &ssid_bssid, MOAL_IOCTL_WAIT);
+ cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
+ NULL, 0, WLAN_STATUS_SUCCESS, GFP_KERNEL);
+ PRINTM(MMSG, "wlan: already connected to bssid " MACSTR "\n",
+ MAC2STR(priv->cfg_bssid));
+ LEAVE();
+ return 0;
+ }
+
/** cancel pending scan */
woal_cancel_scan(priv, MOAL_IOCTL_WAIT);
#if defined(WIFI_DIRECT_SUPPORT)
@@ -1704,28 +1983,38 @@ woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
#endif
#endif
+ priv->cfg_connect = MTRUE;
if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE)
woal_set_scan_type(priv, MLAN_SCAN_TYPE_ACTIVE);
+ priv->assoc_status = 0;
ret = woal_cfg80211_assoc(priv, (void *) sme);
if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE)
woal_set_scan_type(priv, MLAN_SCAN_TYPE_PASSIVE);
-
+ priv->cfg_connect = MFALSE;
if (!ret) {
cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
NULL, 0, WLAN_STATUS_SUCCESS, GFP_KERNEL);
- PRINTM(MINFO, "Associated to bssid %pM successfully\n",
- priv->cfg_bssid);
+ PRINTM(MMSG, "wlan: Connected to bssid " MACSTR " successfully\n",
+ MAC2STR(priv->cfg_bssid));
+ priv->rssi_low = DEFAULT_RSSI_LOW_THRESHOLD;
+ if (priv->bss_type == MLAN_BSS_TYPE_STA)
+ woal_save_conn_params(priv, sme);
+ memset(&bss_info, 0, sizeof(bss_info));
+ woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+ priv->channel = bss_info.bss_chan;
+
} else {
- PRINTM(MINFO, "Association to bssid %pM failed\n", priv->cfg_bssid);
+ PRINTM(MINFO, "wlan: Failed to connect to bssid " MACSTR "\n",
+ MAC2STR(priv->cfg_bssid));
cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
- NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE,
+ NULL, 0, woal_get_assoc_status(priv),
GFP_KERNEL);
memset(priv->cfg_bssid, 0, ETH_ALEN);
}
LEAVE();
- return ret;
+ return 0;
}
/**
@@ -1745,7 +2034,12 @@ woal_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
ENTER();
PRINTM(MINFO, "Received disassociation request on %s\n", dev->name);
-
+#ifdef UAP_CFG80211
+ if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
+ LEAVE();
+ return 0;
+ }
+#endif
if (priv->cfg_disconnect) {
PRINTM(MERROR, "Disassociation already in progress\n");
LEAVE();
@@ -1765,10 +2059,13 @@ woal_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
return -EFAULT;
}
- PRINTM(MINFO, "Successfully disconnected from %pM: Reason code %d\n",
- priv->cfg_bssid, reason_code);
+ PRINTM(MINFO, "Successfully disconnected from " MACSTR ": Reason code %d\n",
+ MAC2STR(priv->cfg_bssid), reason_code);
memset(priv->cfg_bssid, 0, ETH_ALEN);
+ if (priv->bss_type == MLAN_BSS_TYPE_STA)
+ woal_clear_conn_params(priv);
+ priv->channel = 0;
LEAVE();
return 0;
@@ -1862,6 +2159,59 @@ woal_cfg80211_dump_station(struct wiphy *wiphy,
}
/**
+ * @brief Request the driver to dump survey info
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param dev A pointer to net_device structure
+ * @param idx Station index
+ * @param survey A pointer to survey_info structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+static int
+woal_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
+ int idx, struct survey_info *survey)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
+ mlan_bss_info bss_info;
+ enum ieee80211_band band;
+ ENTER();
+#ifdef UAP_CFG80211
+ if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
+ LEAVE();
+ return -EFAULT;
+ }
+#endif
+ if (!priv->media_connected || idx != 0) {
+ PRINTM(MINFO, "cfg80211: Media not connected or"
+ " not for this station!\n");
+ LEAVE();
+ return -ENOENT;
+ }
+
+ memset(&bss_info, 0, sizeof(bss_info));
+ if (MLAN_STATUS_SUCCESS !=
+ woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
+ ret = -EFAULT;
+ goto done;
+ }
+ band = woal_band_cfg_to_ieee_band(bss_info.bss_band);
+ survey->channel =
+ ieee80211_get_channel(wiphy,
+ ieee80211_channel_to_frequency(bss_info.bss_chan,
+ band));
+
+ if (bss_info.bcn_nf_last) {
+ survey->filled = SURVEY_INFO_NOISE_DBM;
+ survey->noise = bss_info.bcn_nf_last;
+ }
+ done:
+ LEAVE();
+ return ret;
+}
+
+/**
* @brief Request the driver to Join the specified
* IBSS (or create if necessary)
*
@@ -1892,7 +2242,7 @@ woal_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
if (!ret) {
cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
PRINTM(MINFO, "Joined/created adhoc network with bssid"
- " %pM successfully\n", priv->cfg_bssid);
+ MACSTR " successfully\n", MAC2STR(priv->cfg_bssid));
} else {
PRINTM(MINFO, "Failed creating/joining adhoc network\n");
memset(priv->cfg_bssid, 0, ETH_ALEN);
@@ -1930,7 +2280,7 @@ woal_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
priv->cfg_disconnect = 1;
- PRINTM(MINFO, "Leaving from IBSS %pM\n", priv->cfg_bssid);
+ PRINTM(MINFO, "Leaving from IBSS " MACSTR "\n", MAC2STR(priv->cfg_bssid));
if (woal_disconnect(priv, MOAL_IOCTL_WAIT, priv->cfg_bssid) !=
MLAN_STATUS_SUCCESS) {
LEAVE();
@@ -1962,7 +2312,11 @@ woal_cfg80211_set_power_mgmt(struct wiphy *wiphy,
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
ENTER();
-
+ if (hw_test) {
+ PRINTM(MIOCTL, "block set power in hw_test mode\n");
+ LEAVE();
+ return ret;
+ }
if (enabled)
disabled = 0;
else
@@ -1988,6 +2342,9 @@ woal_cfg80211_set_power_mgmt(struct wiphy *wiphy,
*/
static int
woal_cfg80211_set_tx_power(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
+ struct wireless_dev *wdev,
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) && !defined(COMPAT_WIRELESS)
enum tx_power_setting type,
#else
@@ -1996,11 +2353,13 @@ woal_cfg80211_set_tx_power(struct wiphy *wiphy,
int dbm)
{
int ret = 0;
- moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy);
+ moal_private *priv = NULL;
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
mlan_power_cfg_t power_cfg;
ENTER();
+ priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
if (!priv) {
PRINTM(MFATAL, "Unable to get priv in %s()\n", __FUNCTION__);
LEAVE();
@@ -2042,7 +2401,7 @@ woal_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
PRINTM(MIOCTL, "rssi_thold=%d rssi_hyst=%d\n",
(int) rssi_thold, (int) rssi_hyst);
- woal_set_rssi_threshold(priv, 0);
+ woal_set_rssi_threshold(priv, 0, MOAL_IOCTL_WAIT);
LEAVE();
return 0;
}
@@ -2075,10 +2434,20 @@ woal_cfg80211_remain_on_channel_cfg(moal_private * priv,
int ret = 0;
ENTER();
+
+ if (!status || (!chan && !remove)) {
+ LEAVE();
+ return -EFAULT;
+ }
memset(&chan_cfg, 0, sizeof(mlan_ds_remain_chan));
if (remove) {
chan_cfg.remove = MTRUE;
} else {
+ if (priv->phandle->is_go_timer_set) {
+ PRINTM(MINFO, "block remain on channel while go timer is on\n");
+ LEAVE();
+ return -EBUSY;
+ }
if (chan->band == IEEE80211_BAND_2GHZ)
chan_cfg.bandcfg = 0;
else if (chan->band == IEEE80211_BAND_5GHZ)
@@ -2108,6 +2477,20 @@ woal_cfg80211_remain_on_channel_cfg(moal_private * priv,
return ret;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+/**
+ * @brief tx mgmt frame
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param wdev A pointer to wireless_dev structure
+ * @param cookie A pointer to frame cookie
+ *
+ * @return 0 -- success, otherwise fail
+ */
+static int
+woal_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+ struct wireless_dev *wdev, u64 cookie)
+#else
/**
* @brief tx mgmt frame
*
@@ -2120,27 +2503,46 @@ woal_cfg80211_remain_on_channel_cfg(moal_private * priv,
static int
woal_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
struct net_device *dev, u64 cookie)
+#endif
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct net_device *dev = wdev->netdev;
+#endif
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
int ret = 0;
t_u8 status = 1;
+ moal_private *remain_priv = NULL;
ENTER();
if (priv->phandle->remain_on_channel) {
- if (woal_cfg80211_remain_on_channel_cfg(priv,
- MOAL_IOCTL_WAIT, MTRUE, &status,
- NULL, 0, 0)) {
- PRINTM(MERROR, "Fail to cancel remain on channel\n");
+ remain_priv = priv->phandle->priv[priv->phandle->remain_bss_index];
+ if (!remain_priv) {
+ PRINTM(MERROR, "mgmt_tx_cancel_wait: Wrong remain_bss_index=%d\n",
+ priv->phandle->remain_bss_index);
+ ret = -EFAULT;
+ goto done;
+ }
+ if (woal_cfg80211_remain_on_channel_cfg
+ (remain_priv, MOAL_IOCTL_WAIT, MTRUE, &status, NULL, 0, 0)) {
+ PRINTM(MERROR,
+ "mgmt_tx_cancel_wait: Fail to cancel remain on channel\n");
ret = -EFAULT;
goto done;
}
if (priv->phandle->cookie) {
- cfg80211_remain_on_channel_expired(priv->netdev,
- priv->phandle->cookie,
- &priv->phandle->chan,
- priv->phandle->channel_type,
- GFP_ATOMIC);
+ cfg80211_remain_on_channel_expired(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+ remain_priv->netdev,
+#else
+ remain_priv->wdev,
+#endif
+ priv->phandle->cookie,
+ &priv->phandle->chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ priv->phandle->channel_type,
+#endif
+ GFP_ATOMIC);
priv->phandle->cookie = 0;
}
priv->phandle->remain_on_channel = MFALSE;
@@ -2151,6 +2553,28 @@ woal_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
return ret;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+/**
+ * @brief Make chip remain on channel
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param wdev A pointer to wireless_dev structure
+ * @param chan A pointer to ieee80211_channel structure
+ * @param channel_type Channel type
+ * @param duration Duration for timer
+ * @param cookie A pointer to timer cookie
+ *
+ * @return 0 -- success, otherwise fail
+ */
+static int
+woal_cfg80211_remain_on_channel(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct ieee80211_channel *chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ enum nl80211_channel_type channel_type,
+#endif
+ unsigned int duration, u64 * cookie)
+#else
/**
* @brief Make chip remain on channel
*
@@ -2169,10 +2593,15 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type,
unsigned int duration, u64 * cookie)
+#endif
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct net_device *dev = wdev->netdev;
+#endif
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
int ret = 0;
t_u8 status = 1;
+ moal_private *remain_priv = NULL;
ENTER();
@@ -2183,10 +2612,17 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy,
}
/** cancel previous remain on channel */
if (priv->phandle->remain_on_channel) {
- if (woal_cfg80211_remain_on_channel_cfg(priv,
- MOAL_IOCTL_WAIT, MTRUE, &status,
- NULL, 0, 0)) {
- PRINTM(MERROR, "Fail to cancel remain on channel\n");
+ remain_priv = priv->phandle->priv[priv->phandle->remain_bss_index];
+ if (!remain_priv) {
+ PRINTM(MERROR, "remain_on_channel: Wrong remain_bss_index=%d\n",
+ priv->phandle->remain_bss_index);
+ ret = -EFAULT;
+ goto done;
+ }
+ if (woal_cfg80211_remain_on_channel_cfg
+ (remain_priv, MOAL_IOCTL_WAIT, MTRUE, &status, NULL, 0, 0)) {
+ PRINTM(MERROR,
+ "remain_on_channel: Fail to cancel remain on channel\n");
ret = -EFAULT;
goto done;
}
@@ -2197,7 +2633,12 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy,
woal_cancel_scan(priv, MOAL_IOCTL_WAIT);
if (MLAN_STATUS_SUCCESS !=
woal_cfg80211_remain_on_channel_cfg(priv, MOAL_IOCTL_WAIT,
- MFALSE, &status, chan, channel_type,
+ MFALSE, &status, chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ channel_type,
+#else
+ 0,
+#endif
(t_u32) duration)) {
ret = -EFAULT;
goto done;
@@ -2208,13 +2649,25 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy,
/* we need update the value cookie */
*cookie = (u64) random32() | 1;
priv->phandle->remain_on_channel = MTRUE;
+ priv->phandle->remain_bss_index = priv->bss_index;
priv->phandle->cookie = *cookie;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
priv->phandle->channel_type = channel_type;
+#endif
memcpy(&priv->phandle->chan, chan, sizeof(struct ieee80211_channel));
- cfg80211_ready_on_channel(dev, *cookie, chan,
- channel_type, duration, GFP_KERNEL);
- PRINTM(MIOCTL, "Set remain on Channel: channel=%d cookie = %#llx\n",
- ieee80211_frequency_to_channel(chan->center_freq),
+ cfg80211_ready_on_channel(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+ dev,
+#else
+ priv->wdev,
+#endif
+ *cookie, chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ channel_type,
+#endif
+ duration, GFP_KERNEL);
+ PRINTM(MIOCTL, "%s: Set remain on Channel: channel=%d cookie = %#llx\n",
+ dev->name, ieee80211_frequency_to_channel(chan->center_freq),
priv->phandle->cookie);
}
done:
@@ -2222,6 +2675,20 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy,
return ret;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+/**
+ * @brief Cancel remain on channel
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param wdev A pointer to wireless_dev structure
+ * @param cookie A pointer to timer cookie
+ *
+ * @return 0 -- success, otherwise fail
+ */
+static int
+woal_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
+ struct wireless_dev *wdev, u64 cookie)
+#else
/**
* @brief Cancel remain on channel
*
@@ -2234,17 +2701,29 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy,
static int
woal_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
struct net_device *dev, u64 cookie)
+#endif
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct net_device *dev = wdev->netdev;
+#endif
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
+ moal_private *remain_priv = NULL;
int ret = 0;
t_u8 status = 1;
ENTER();
PRINTM(MIOCTL, "Cancel remain on Channel: cookie = %#llx\n", cookie);
- if (woal_cfg80211_remain_on_channel_cfg(priv,
- MOAL_IOCTL_WAIT, MTRUE, &status,
- NULL, 0, 0)) {
- PRINTM(MERROR, "Fail to cancel remain on channel\n");
+ remain_priv = priv->phandle->priv[priv->phandle->remain_bss_index];
+ if (!remain_priv) {
+ PRINTM(MERROR, "cancel_remain_on_channel: Wrong remain_bss_index=%d\n",
+ priv->phandle->remain_bss_index);
+ ret = -EFAULT;
+ goto done;
+ }
+ if (woal_cfg80211_remain_on_channel_cfg
+ (remain_priv, MOAL_IOCTL_WAIT, MTRUE, &status, NULL, 0, 0)) {
+ PRINTM(MERROR,
+ "cancel_remain_on_channel: Fail to cancel remain on channel\n");
ret = -EFAULT;
goto done;
}
@@ -2259,6 +2738,397 @@ woal_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
#endif /* KERNEL_VERSION */
#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+/**
+ * @brief start sched scan
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param dev A pointer to net_device structure
+ * @param request A pointer to struct cfg80211_sched_scan_request
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_sched_scan_start(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_sched_scan_request *request)
+{
+ struct ieee80211_channel *chan = NULL;
+ int i = 0;
+ int ret = 0;
+ moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
+ struct cfg80211_ssid *ssid = NULL;
+ ENTER();
+#ifdef UAP_CFG80211
+ if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
+ LEAVE();
+ return -EFAULT;
+ }
+#endif
+
+ memset(&priv->scan_cfg, 0, sizeof(priv->scan_cfg));
+ if ((!request || !request->n_ssids || !request->n_match_sets)) {
+ PRINTM(MERROR, "Invalid sched_scan req parameter\n");
+ LEAVE();
+ return -EINVAL;
+ }
+ PRINTM(MIOCTL,
+ "%s sched scan: n_ssids=%d n_match_sets=%d n_channels=%d interval=%d ie_len=%d\n",
+ priv->netdev->name, request->n_ssids, request->n_match_sets,
+ request->n_channels, request->interval, request->ie_len);
+ /** cancel pending scan */
+ woal_cancel_scan(priv, MOAL_IOCTL_WAIT);
+ for (i = 0; i < request->n_match_sets; i++) {
+ ssid = &request->match_sets[i].ssid;
+ strncpy(priv->scan_cfg.ssid_list[i].ssid, ssid->ssid, ssid->ssid_len);
+ priv->scan_cfg.ssid_list[i].max_len = 0;
+ PRINTM(MIOCTL, "sched scan: ssid=%s\n", ssid->ssid);
+ }
+ for (i = 0; i < MIN(WLAN_BG_SCAN_CHAN_MAX, request->n_channels); i++) {
+ chan = request->channels[i];
+ priv->scan_cfg.chan_list[i].chan_number = chan->hw_value;
+ priv->scan_cfg.chan_list[i].radio_type = chan->band;
+ if (chan->flags & (IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_RADAR))
+ priv->scan_cfg.chan_list[i].scan_type = MLAN_SCAN_TYPE_PASSIVE;
+ else
+ priv->scan_cfg.chan_list[i].scan_type = MLAN_SCAN_TYPE_ACTIVE;
+ priv->scan_cfg.chan_list[i].scan_time = 0;
+ }
+
+ /** set scan request IES */
+ if (request->ie && request->ie_len) {
+ if (MLAN_STATUS_SUCCESS !=
+ woal_cfg80211_mgmt_frame_ie(priv, NULL, 0,
+ NULL, 0, NULL, 0,
+ (t_u8 *) request->ie, request->ie_len,
+ MGMT_MASK_PROBE_REQ)) {
+ PRINTM(MERROR, "Fail to set sched scan IE\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ } else {
+ /** Clear SCAN IE in Firmware */
+ if (priv->probereq_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)
+ woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, NULL, 0, NULL,
+ 0, MGMT_MASK_PROBE_REQ);
+ }
+
+ /* Interval between scan cycles in milliseconds,supplicant set to 10 second
+ */
+ /* We want to use 30 second for per scan cycle */
+ priv->scan_cfg.scan_interval = MIN_BGSCAN_INTERVAL;
+ if (request->interval > MIN_BGSCAN_INTERVAL)
+ priv->scan_cfg.scan_interval = request->interval;
+
+ priv->scan_cfg.repeat_count = DEF_REPEAT_COUNT;
+ priv->scan_cfg.report_condition = BG_SCAN_SSID_MATCH;
+ priv->scan_cfg.bss_type = MLAN_BSS_MODE_INFRA;
+ priv->scan_cfg.action = BG_SCAN_ACT_SET;
+ priv->scan_cfg.enable = MTRUE;
+
+ if (MLAN_STATUS_SUCCESS ==
+ woal_request_bgscan(priv, MOAL_IOCTL_WAIT, &priv->scan_cfg)) {
+ priv->sched_scanning = MTRUE;
+ priv->bg_scan_start = MTRUE;
+ priv->bg_scan_reported = MFALSE;
+ } else
+ ret = -EFAULT;
+ done:
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief stop sched scan
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param dev A pointer to net_device structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
+{
+ moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
+ ENTER();
+ PRINTM(MIOCTL, "sched scan stop\n");
+ priv->sched_scanning = MFALSE;
+ woal_stop_bg_scan(priv, MOAL_NO_WAIT);
+ priv->bg_scan_start = MFALSE;
+ priv->bg_scan_reported = MFALSE;
+ LEAVE();
+ return 0;
+}
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+/**
+ * @brief cfg80211_resume handler
+ *
+ * @param wiphy A pointer to wiphy structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_resume(struct wiphy *wiphy)
+{
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
+ int i;
+ for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) {
+ if (handle->priv[i] &&
+ (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA)) {
+ if ((handle->priv[i]->last_event & EVENT_BG_SCAN_REPORT) &&
+ handle->priv[i]->sched_scanning) {
+ woal_inform_bss_from_scan_result(handle->priv[i], NULL,
+ MOAL_CMD_WAIT);
+ cfg80211_sched_scan_results(handle->priv[i]->wdev->wiphy);
+ handle->priv[i]->last_event = 0;
+ PRINTM(MIOCTL, "Report sched scan result in cfg80211 resume\n");
+ }
+ }
+ }
+ handle->cfg80211_suspend = MFALSE;
+ PRINTM(MIOCTL, "woal_cfg80211_resume\n");
+ return 0;
+}
+
+/**
+ * @brief cfg80211_suspend handler
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param wow A pointer to cfg80211_wowlan
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
+{
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
+ int i;
+ for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) {
+ if (handle->priv[i] &&
+ (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA)) {
+ if (handle->priv[i]->scan_request) {
+ PRINTM(MIOCTL,
+ "Cancel pending scan in woal_cfg80211_suspend\n");
+ woal_cancel_scan(handle->priv[i], MOAL_IOCTL_WAIT);
+ }
+ handle->priv[i]->last_event = 0;
+ }
+ }
+ PRINTM(MIOCTL, "woal_cfg80211_suspended\n");
+ handle->cfg80211_suspend = MTRUE;
+ return 0;
+}
+#endif
+
+/**
+ * @brief Save connect parameters for roaming
+ *
+ * @param priv A pointer to moal_private
+ * @param sme A pointer to cfg80211_connect_params structure
+ */
+void
+woal_save_conn_params(moal_private * priv, struct cfg80211_connect_params *sme)
+{
+ ENTER();
+ memcpy(&priv->sme_current, sme, sizeof(struct cfg80211_connect_params));
+ if (sme->channel) {
+ priv->sme_current.channel = &priv->conn_chan;
+ memcpy(priv->sme_current.channel, sme->channel,
+ sizeof(struct ieee80211_channel));
+ }
+ if (sme->bssid) {
+ priv->sme_current.bssid = priv->conn_bssid;
+ memcpy(priv->sme_current.bssid, sme->bssid, MLAN_MAC_ADDR_LENGTH);
+ }
+ if (sme->ssid && sme->ssid_len) {
+ priv->sme_current.ssid = priv->conn_ssid;
+ memset(priv->conn_ssid, 0, MLAN_MAX_SSID_LENGTH);
+ memcpy(priv->sme_current.ssid, sme->ssid, sme->ssid_len);
+ }
+ if (sme->ie && sme->ie_len) {
+ priv->sme_current.ie = kzalloc(sme->ie_len, GFP_KERNEL);
+ memcpy(priv->sme_current.ie, sme->ie, sme->ie_len);
+ }
+ if (sme->key && sme->key_len && (sme->key_len <= MAX_WEP_KEY_SIZE)) {
+ priv->sme_current.key = priv->conn_wep_key;
+ memcpy((t_u8 *) priv->sme_current.key, sme->key, sme->key_len);
+ }
+}
+
+/**
+ * @brief clear connect parameters for ing
+ *
+ * @param priv A pointer to moal_private
+ */
+void
+woal_clear_conn_params(moal_private * priv)
+{
+ ENTER();
+ if (priv->sme_current.ie_len && priv->sme_current.ie)
+ kfree(priv->sme_current.ie);
+ memset(&priv->sme_current, 0, sizeof(struct cfg80211_connect_params));
+ priv->roaming_required = MFALSE;
+ LEAVE();
+}
+
+/**
+ * @brief Start roaming: driver handle roaming
+ *
+ * @param priv A pointer to moal_private structure
+ *
+ * @return N/A
+ */
+void
+woal_start_roaming(moal_private * priv)
+{
+ mlan_ds_get_signal signal;
+ mlan_ssid_bssid ssid_bssid;
+ char rssi_low[10];
+ int ret = 0;
+ mlan_ds_misc_assoc_rsp assoc_rsp;
+ IEEEtypes_AssocRsp_t *passoc_rsp = NULL;
+
+ ENTER();
+ if (priv->last_event & EVENT_BG_SCAN_REPORT) {
+ woal_inform_bss_from_scan_result(priv, NULL, MOAL_CMD_WAIT);
+ PRINTM(MIOCTL, "Report bgscan result\n");
+ }
+ if (priv->media_connected == MFALSE || !priv->sme_current.ssid_len) {
+ PRINTM(MIOCTL, "Not connected, ignore roaming\n");
+ LEAVE();
+ return;
+ }
+
+ /* Get signal information from the firmware */
+ memset(&signal, 0, sizeof(mlan_ds_get_signal));
+ if (MLAN_STATUS_SUCCESS !=
+ woal_get_signal_info(priv, MOAL_CMD_WAIT, &signal)) {
+ PRINTM(MERROR, "Error getting signal information\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));
+ ssid_bssid.ssid.ssid_len = priv->sme_current.ssid_len;
+ memcpy(ssid_bssid.ssid.ssid, priv->sme_current.ssid,
+ priv->sme_current.ssid_len);
+ if (MLAN_STATUS_SUCCESS !=
+ woal_find_best_network(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) {
+ PRINTM(MIOCTL, "Can not find better network\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ /* check if we found different AP */
+ if (!memcmp(&ssid_bssid.bssid, priv->cfg_bssid, MLAN_MAC_ADDR_LENGTH)) {
+ PRINTM(MIOCTL, "This is the same AP, no roaming\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ PRINTM(MIOCTL, "Find AP: bssid=" MACSTR ", signal=%d\n",
+ MAC2STR(ssid_bssid.bssid), ssid_bssid.rssi);
+ /* check signal */
+ if (!(priv->last_event & EVENT_PRE_BCN_LOST)) {
+ if ((abs(signal.bcn_rssi_avg) - abs(ssid_bssid.rssi)) < DELTA_RSSI) {
+ PRINTM(MERROR, "New AP's signal is not good too.\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ }
+ /* start roaming to new AP */
+ priv->sme_current.bssid = priv->conn_bssid;
+ memcpy(priv->sme_current.bssid, &ssid_bssid.bssid, MLAN_MAC_ADDR_LENGTH);
+ ret = woal_cfg80211_assoc(priv, (void *) &priv->sme_current);
+ if (!ret) {
+ woal_inform_bss_from_scan_result(priv, NULL, MOAL_CMD_WAIT);
+ memset(&assoc_rsp, 0, sizeof(mlan_ds_misc_assoc_rsp));
+ woal_get_assoc_rsp(priv, &assoc_rsp);
+ passoc_rsp = (IEEEtypes_AssocRsp_t *) assoc_rsp.assoc_resp_buf;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) || defined(COMPAT_WIRELESS)
+ cfg80211_roamed(priv->netdev, NULL, priv->cfg_bssid,
+ priv->sme_current.ie, priv->sme_current.ie_len,
+ passoc_rsp->ie_buffer,
+ assoc_rsp.assoc_resp_len - ASSOC_RESP_FIXED_SIZE,
+ GFP_KERNEL);
+#else
+ cfg80211_roamed(priv->netdev, priv->cfg_bssid, priv->sme_current.ie,
+ priv->sme_current.ie_len, passoc_rsp->ie_buffer,
+ assoc_rsp.assoc_resp_len - ASSOC_RESP_FIXED_SIZE,
+ GFP_KERNEL);
+#endif
+ PRINTM(MIOCTL, "Roamed to bssid " MACSTR " successfully\n",
+ MAC2STR(priv->cfg_bssid));
+ } else {
+ PRINTM(MIOCTL, "Roaming to bssid " MACSTR " failed\n",
+ MAC2STR(ssid_bssid.bssid));
+ }
+ done:
+ /* config rssi low threshold again */
+ priv->last_event = 0;
+ priv->rssi_low = DEFAULT_RSSI_LOW_THRESHOLD;
+ sprintf(rssi_low, "%d", priv->rssi_low);
+ woal_set_rssi_low_threshold(priv, rssi_low, MOAL_CMD_WAIT);
+ LEAVE();
+ return;
+}
+
+/**
+ * @brief Register the device with cfg80211
+ *
+ * @param dev A pointer to net_device structure
+ * @param bss_type BSS type
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_register_sta_cfg80211(struct net_device * dev, t_u8 bss_type)
+{
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ moal_private *priv = (moal_private *) netdev_priv(dev);
+ struct wireless_dev *wdev = NULL;
+ int disabled = 0;
+
+ ENTER();
+
+ wdev = (struct wireless_dev *) &priv->w_dev;
+ memset(wdev, 0, sizeof(struct wireless_dev));
+ wdev->wiphy = priv->phandle->wiphy;
+ if (!wdev->wiphy) {
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
+ }
+ if (bss_type == MLAN_BSS_TYPE_STA) {
+ wdev->iftype = NL80211_IFTYPE_STATION;
+ priv->roaming_enabled = MFALSE;
+ priv->roaming_required = MFALSE;
+ }
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ if (bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
+ wdev->iftype = NL80211_IFTYPE_STATION;
+#endif
+#endif
+
+ dev_net_set(dev, wiphy_net(wdev->wiphy));
+ dev->ieee80211_ptr = wdev;
+ SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
+ priv->wdev = wdev;
+ /* Get IEEE power save mode */
+ if (MLAN_STATUS_SUCCESS ==
+ woal_set_get_power_mgmt(priv, MLAN_ACT_GET, &disabled, 0)) {
+ /* Save the IEEE power save mode to wiphy, because after * warmreset
+ wiphy power save should be updated instead * of using the last saved
+ configuration */
+ if (disabled)
+ priv->wdev->ps = MFALSE;
+ else
+ priv->wdev->ps = MTRUE;
+ }
+ woal_send_domain_info_cmd_fw(priv);
+ LEAVE();
+ return ret;
+}
+
/**
* @brief Initialize the wiphy
*
@@ -2268,28 +3138,26 @@ woal_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status
-woal_cfg80211_sta_init_wiphy(moal_private * priv, t_u8 wait_option)
+woal_cfg80211_init_wiphy(moal_private * priv, t_u8 wait_option)
{
- int retry_count, rts_thr, frag_thr, disabled;
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ int retry_count, rts_thr, frag_thr;
struct wiphy *wiphy = NULL;
mlan_ioctl_req *req = NULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) || defined(COMPAT_WIRELESS)
+ mlan_ds_radio_cfg *radio = NULL;
+#endif
mlan_ds_11n_cfg *cfg_11n = NULL;
t_u32 hw_dev_cap;
ENTER();
- if (priv->wdev)
- wiphy = priv->wdev->wiphy;
- else {
- PRINTM(MERROR, "Invalid parameter when init wiphy.\n");
- goto done;
- }
-
+ wiphy = priv->phandle->wiphy;
/* Get 11n tx parameters from MLAN */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
if (req == NULL) {
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
}
cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
cfg_11n->sub_command = MLAN_OID_11N_HTCAP_CFG;
@@ -2298,9 +3166,8 @@ woal_cfg80211_sta_init_wiphy(moal_private * priv, t_u8 wait_option)
cfg_11n->param.htcap_cfg.hw_cap_req = MTRUE;
if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
- kfree(req);
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
}
hw_dev_cap = cfg_11n->param.htcap_cfg.htcap;
@@ -2311,9 +3178,8 @@ woal_cfg80211_sta_init_wiphy(moal_private * priv, t_u8 wait_option)
req->action = MLAN_ACT_GET;
if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
- kfree(req);
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
}
/* Initialize parameters for 2GHz and 5GHz bands */
@@ -2327,21 +3193,43 @@ woal_cfg80211_sta_init_wiphy(moal_private * priv, t_u8 wait_option)
if (req)
kfree(req);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) || defined(COMPAT_WIRELESS)
+ /* Get antenna modes */
+ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
+ if (req == NULL) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ radio = (mlan_ds_radio_cfg *) req->pbuf;
+ radio->sub_command = MLAN_OID_ANT_CFG;
+ req->req_id = MLAN_IOCTL_RADIO_CFG;
+ req->action = MLAN_ACT_GET;
+
+ if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+
+ /* Set available antennas to wiphy */
+ wiphy->available_antennas_tx = radio->param.ant_cfg.tx_antenna;
+ wiphy->available_antennas_rx = radio->param.ant_cfg.rx_antenna;
+#endif /* LINUX_VERSION_CODE */
+
/* Set retry limit count to wiphy */
if (MLAN_STATUS_SUCCESS !=
woal_set_get_retry(priv, MLAN_ACT_GET, wait_option, &retry_count)) {
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
}
wiphy->retry_long = (t_u8) retry_count;
wiphy->retry_short = (t_u8) retry_count;
wiphy->max_scan_ie_len = MAX_IE_SIZE;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
+ wiphy->mgmt_stypes = ieee80211_mgmt_stypes;
+#endif
#if defined(WIFI_DIRECT_SUPPORT)
#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
- /* we should add mgmt_stypes for both STA & Wifi Direct, while only
- initialize duration_timer for Wifi Direct */
- wiphy->mgmt_stypes = ieee80211_mgmt_stypes;
wiphy->max_remain_on_channel_duration = MAX_REMAIN_ON_CHANNEL_DURATION;
#endif /* KERNEL_VERSION */
#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */
@@ -2349,8 +3237,8 @@ woal_cfg80211_sta_init_wiphy(moal_private * priv, t_u8 wait_option)
/* Set RTS threshold to wiphy */
if (MLAN_STATUS_SUCCESS !=
woal_set_get_rts(priv, MLAN_ACT_GET, wait_option, &rts_thr)) {
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
}
if (rts_thr < MLAN_RTS_MIN_VALUE || rts_thr > MLAN_RTS_MAX_VALUE)
rts_thr = MLAN_FRAG_RTS_DISABLED;
@@ -2359,169 +3247,138 @@ woal_cfg80211_sta_init_wiphy(moal_private * priv, t_u8 wait_option)
/* Set fragment threshold to wiphy */
if (MLAN_STATUS_SUCCESS !=
woal_set_get_frag(priv, MLAN_ACT_GET, wait_option, &frag_thr)) {
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
}
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;
- /* Get IEEE power save mode */
- if (MLAN_STATUS_SUCCESS != woal_set_get_power_mgmt(priv,
- MLAN_ACT_GET, &disabled,
- 0)) {
- LEAVE();
- return MLAN_STATUS_FAILURE;
- }
- /* Save the IEEE power save mode to wiphy, because after warmreset wiphy
- power save should be updated instead of using the last saved
- configuration */
- if (disabled)
- priv->wdev->ps = MFALSE;
- else
- priv->wdev->ps = MTRUE;
-
done:
LEAVE();
- return MLAN_STATUS_SUCCESS;
+ if (req)
+ kfree(req);
+ return ret;
}
-/**
- * @brief Register the device with cfg80211
+/*
+ * This function registers the device with CFG802.11 subsystem.
*
- * @param dev A pointer to net_device structure
- * @param bss_type BSS type
+ * @param priv A pointer to moal_private
*
- * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status
-woal_register_sta_cfg80211(struct net_device * dev, t_u8 bss_type)
+woal_register_cfg80211(moal_private * priv)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
- moal_private *priv = (moal_private *) netdev_priv(dev);
+ struct wiphy *wiphy;
void *wdev_priv = NULL;
- struct wireless_dev *wdev = NULL;
mlan_fw_info fw_info;
+ char *country = NULL;
+ int index = 0;
ENTER();
- /* Allocate wireless device */
- wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
- if (!wdev) {
- PRINTM(MERROR, "Could not allocate wireless device\n");
- ret = MLAN_STATUS_FAILURE;
- goto err_wdev;
- }
-
- if (bss_type == MLAN_BSS_TYPE_STA)
- /* Allocate wiphy */
- wdev->wiphy = wiphy_new(&woal_cfg80211_sta_ops, sizeof(moal_private *));
-#if defined(WIFI_DIRECT_SUPPORT)
-#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
- else if (bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
- /* Allocate wiphy */
- wdev->wiphy =
- wiphy_new(&woal_cfg80211_wifi_direct_ops, sizeof(moal_private *));
-#endif
-#endif
- else {
- PRINTM(MERROR, "Unexpected bss_type when register cfg80211\n");
- ret = MLAN_STATUS_FAILURE;
- goto err_wdev;
- }
-
- if (!wdev->wiphy) {
+ wiphy = wiphy_new(&woal_cfg80211_ops, sizeof(moal_handle *));
+ if (!wiphy) {
PRINTM(MERROR, "Could not allocate wiphy device\n");
ret = MLAN_STATUS_FAILURE;
- goto err_wdev;
+ goto err_wiphy;
}
- if (bss_type == MLAN_BSS_TYPE_STA) {
- wdev->iftype = NL80211_IFTYPE_STATION;
- wdev->wiphy->interface_modes =
-#ifdef UAP_CFG80211
- MBIT(NL80211_IFTYPE_AP) |
-#endif /* UAP_CFG80211 */
- MBIT(NL80211_IFTYPE_STATION) | MBIT(NL80211_IFTYPE_ADHOC);
- wdev->wiphy->max_scan_ssids = 10;
- }
-#if defined(WIFI_DIRECT_SUPPORT)
-#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
- if (bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
- wdev->iftype = NL80211_IFTYPE_STATION;
- wdev->wiphy->interface_modes = MBIT(NL80211_IFTYPE_STATION) |
- MBIT(NL80211_IFTYPE_P2P_GO) |
- MBIT(NL80211_IFTYPE_P2P_CLIENT) |
- MBIT(NL80211_IFTYPE_ADHOC) | MBIT(NL80211_IFTYPE_AP) | 0;
- wdev->wiphy->max_scan_ssids = 10;
- }
-#endif
-#endif
-
- /* Set phy name like net device name */
- dev_set_name(&wdev->wiphy->dev, dev->name);
+ wiphy->max_scan_ssids = MRVDRV_MAX_SSID_LIST_LENGTH;
+ wiphy->max_scan_ie_len = MAX_IE_SIZE;
+ wiphy->interface_modes = 0;
+ wiphy->interface_modes =
+ MBIT(NL80211_IFTYPE_STATION) | MBIT(NL80211_IFTYPE_ADHOC) |
+ MBIT(NL80211_IFTYPE_AP);
/* Make this wiphy known to this driver only */
- wdev->wiphy->privid = mrvl_wiphy_privid;
-
+ wiphy->privid = mrvl_wiphy_privid;
/* Supported bands */
- wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &cfg80211_band_2ghz;
- if (MLAN_STATUS_SUCCESS ==
- woal_request_get_fw_info(priv, MOAL_CMD_WAIT, &fw_info)) {
- if (fw_info.fw_bands & BAND_A)
- wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &cfg80211_band_5ghz;
- }
-#define PASSIVE_SCAN_CHAN_TIME 130
-#define ACTIVE_SCAN_CHAN_TIME 130
-#define SPECIFIC_SCAN_CHAN_TIME 40
- woal_set_scan_time(priv, ACTIVE_SCAN_CHAN_TIME, PASSIVE_SCAN_CHAN_TIME,
- SPECIFIC_SCAN_CHAN_TIME);
- /* Initialize cipher suits */
- wdev->wiphy->cipher_suites = cfg80211_cipher_suites;
- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cfg80211_cipher_suites);
+ wiphy->bands[IEEE80211_BAND_2GHZ] = &cfg80211_band_2ghz;
+
+ woal_request_get_fw_info(priv, MOAL_CMD_WAIT, &fw_info);
+ if (fw_info.fw_bands & BAND_A) {
+ wiphy->bands[IEEE80211_BAND_5GHZ] = &cfg80211_band_5ghz;
+ /** reduce scan time from 110ms to 80ms */
+ woal_set_scan_time(priv, INIT_ACTIVE_SCAN_CHAN_TIME,
+ INIT_PASSIVE_SCAN_CHAN_TIME,
+ INIT_SPECIFIC_SCAN_CHAN_TIME);
+ } else
+ woal_set_scan_time(priv, ACTIVE_SCAN_CHAN_TIME, PASSIVE_SCAN_CHAN_TIME,
+ SPECIFIC_SCAN_CHAN_TIME);
+ woal_enable_ext_scan(priv, MTRUE);
+ priv->phandle->band = IEEE80211_BAND_2GHZ;
- wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+ /* Initialize cipher suits */
+ wiphy->cipher_suites = cfg80211_cipher_suites;
+ wiphy->n_cipher_suites = ARRAY_SIZE(cfg80211_cipher_suites);
- /* We are using custom domains */
- wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+ memcpy(wiphy->perm_addr, priv->current_addr, ETH_ALEN);
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
- wdev->wiphy->reg_notifier = woal_cfg80211_reg_notifier;
+ wiphy->flags = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
+ wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_OFFCHAN_TX;
+ wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
+#endif
+#ifdef ANDROID_KERNEL
+ wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+ wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+ wiphy->max_sched_scan_ssids = MRVDRV_MAX_SSID_LIST_LENGTH;
+ wiphy->max_sched_scan_ie_len = MAX_IE_SIZE;
+ wiphy->max_match_sets = MRVDRV_MAX_SSID_LIST_LENGTH;
+#endif
- /* Set moal_private pointer in wiphy_priv */
- wdev_priv = wiphy_priv(wdev->wiphy);
+ wiphy->reg_notifier = woal_cfg80211_reg_notifier;
- *(unsigned long *) wdev_priv = (unsigned long) priv;
+ /* Set struct moal_handle pointer in wiphy_priv */
+ wdev_priv = wiphy_priv(wiphy);
+ *(unsigned long *) wdev_priv = (unsigned long) priv->phandle;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) || defined(COMPAT_WIRELESS)
- set_wiphy_dev(wdev->wiphy, (struct device *) priv->phandle->hotplug_device);
+ set_wiphy_dev(wiphy, (struct device *) priv->phandle->hotplug_device);
#endif
-
- if (wiphy_register(wdev->wiphy) < 0) {
+ /* Set phy name */
+ for (index = 0; index < MAX_MLAN_ADAPTER; index++) {
+ if (m_handle[index] == priv->phandle) {
+ dev_set_name(&wiphy->dev, "mwiphy%d", index);
+ break;
+ }
+ }
+ if (wiphy_register(wiphy) < 0) {
PRINTM(MERROR, "Wiphy device registration failed!\n");
ret = MLAN_STATUS_FAILURE;
- goto err_wdev;
+ goto err_wiphy;
}
-
- dev_net_set(dev, wiphy_net(wdev->wiphy));
- dev->ieee80211_ptr = wdev;
- SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
- priv->wdev = wdev;
-
- if (ret != MLAN_STATUS_SUCCESS) {
- PRINTM(MERROR, "Wiphy device registration failed!\n");
+ /** we will try driver parameter first */
+ if (reg_alpha2 && woal_is_valid_alpha2(reg_alpha2)) {
+ PRINTM(MIOCTL, "Notify reg_alpha2 %c%c\n", reg_alpha2[0],
+ reg_alpha2[1]);
+ regulatory_hint(wiphy, reg_alpha2);
} else {
- PRINTM(MINFO, "Successfully registered wiphy device\n");
- LEAVE();
- return ret;
+ country = region_code_2_string(fw_info.region_code);
+ if (country) {
+ PRINTM(MIOCTL, "Notify hw region code=%d %c%c\n",
+ fw_info.region_code, country[0], country[1]);
+ regulatory_hint(wiphy, country);
+ } else
+ PRINTM(MERROR, "hw region code=%d not supported\n",
+ fw_info.region_code);
}
- wiphy_unregister(wdev->wiphy);
- err_wdev:
- dev->ieee80211_ptr = NULL;
- if (wdev) {
- if (wdev->wiphy)
- wiphy_free(wdev->wiphy);
- kfree(wdev);
- }
+ priv->phandle->wiphy = wiphy;
+ woal_cfg80211_init_wiphy(priv, MOAL_CMD_WAIT);
+
+ return ret;
+ err_wiphy:
+ if (wiphy)
+ wiphy_free(wiphy);
LEAVE();
return ret;
}
+
+module_param(reg_alpha2, charp, 0);
+MODULE_PARM_DESC(reg_alpha2, "Regulatory alpha2");
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.h b/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.h
index a83957c5c031..4de8b90db7db 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.h
@@ -26,7 +26,6 @@
#define RSSI_DBM_TO_MDM(x) ((x) * 100)
mlan_status woal_register_sta_cfg80211(struct net_device *dev, t_u8 bss_type);
-mlan_status woal_cfg80211_sta_init_wiphy(moal_private * priv, t_u8 wait_option);
mlan_status
woal_cfg80211_set_key(moal_private * priv, t_u8 is_enable_wep,
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_uap.c b/drivers/net/wireless/sd8797/mlinux/moal_uap.c
index 170f31a1bfbf..ddac122f6948 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_uap.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_uap.c
@@ -1302,14 +1302,14 @@ woal_uap_ioctl(struct net_device *dev, struct ifreq *req)
case UAP_SNMP_MIB:
ret = woal_uap_snmp_mib(dev, req);
break;
- case UAP_DOMAIN_INFO:
- ret = woal_uap_domain_info(dev, req);
- break;
#ifdef DFS_TESTING_SUPPORT
case UAP_DFS_TESTING:
ret = woal_uap_dfs_testing(dev, req);
break;
#endif
+ case UAP_DOMAIN_INFO:
+ ret = woal_uap_domain_info(dev, req);
+ break;
case UAP_TX_BF_CFG:
ret = woal_uap_tx_bf_cfg(dev, req);
break;
@@ -1367,12 +1367,8 @@ woal_uap_sta_deauth_ioctl(struct net_device *dev, struct ifreq *req)
goto done;
}
- PRINTM(MIOCTL,
- "ioctl deauth station: %02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n",
- deauth_param.mac_addr[0], deauth_param.mac_addr[1],
- deauth_param.mac_addr[2], deauth_param.mac_addr[3],
- deauth_param.mac_addr[4], deauth_param.mac_addr[5],
- deauth_param.reason_code);
+ PRINTM(MIOCTL, "ioctl deauth station: " MACSTR ", reason=%d\n",
+ MAC2STR(deauth_param.mac_addr), deauth_param.reason_code);
ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
if (ioctl_req == NULL) {
@@ -2083,12 +2079,12 @@ woal_uap_set_11n_status(mlan_uap_bss_param * sys_cfg, t_u8 action)
* @return 0 --success, otherwise fail
*/
int
-woal_uap_ap_cfg_parse_data(mlan_uap_bss_param * ap_cfg, t_s8 * buf)
+woal_uap_ap_cfg_parse_data(mlan_uap_bss_param * ap_cfg, char *buf)
{
int ret = 0, atoi_ret;
int set_sec = 0, set_key = 0, set_chan = 0;
int set_preamble = 0, set_scb = 0, set_ssid = 0;
- t_s8 *begin = buf, *value = NULL, *opt = NULL;
+ char *begin = buf, *value = NULL, *opt = NULL;
ENTER();
@@ -2282,7 +2278,7 @@ int
woal_uap_set_ap_cfg(moal_private * priv, t_u8 * data, int len)
{
int ret = 0;
- static t_s8 buf[MAX_BUF_LEN];
+ static char buf[MAX_BUF_LEN];
mlan_uap_bss_param sys_config;
int restart = 0;
@@ -2296,7 +2292,7 @@ woal_uap_set_ap_cfg(moal_private * priv, t_u8 * data, int len)
}
memset(buf, 0, MAX_BUF_LEN);
- memcpy(buf, data, len);
+ memcpy(buf, data, MIN(len, (sizeof(buf) - 1)));
/* Initialize the uap bss values which are uploaded from firmware */
woal_uap_get_bss_param(priv, &sys_config, MOAL_IOCTL_WAIT);
@@ -2412,9 +2408,13 @@ woal_uap_bss_ctrl(moal_private * priv, t_u8 wait_option, int data)
goto done;
}
- if (data == UAP_BSS_STOP || data == UAP_BSS_RESET)
+ if (data == UAP_BSS_STOP || data == UAP_BSS_RESET) {
priv->bss_started = MFALSE;
-
+ woal_stop_queue(priv->netdev);
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
+ woal_flush_tcp_sess_queue(priv);
+ }
done:
if (req)
kfree(req);
@@ -2503,6 +2503,7 @@ woal_uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
return ret;
}
+#ifdef CONFIG_PROC_FS
/**
* @brief Get version
*
@@ -2536,7 +2537,7 @@ woal_uap_get_version(moal_private * priv, char *version, int max_len)
if (status == MLAN_STATUS_SUCCESS) {
PRINTM(MINFO, "MOAL UAP VERSION: %s\n",
info->param.ver_ext.version_str);
- snprintf(version, max_len, driver_version,
+ snprintf(version, max_len, priv->phandle->driver_version,
info->param.ver_ext.version_str);
}
@@ -2546,6 +2547,7 @@ woal_uap_get_version(moal_private * priv, char *version, int max_len)
LEAVE();
return;
}
+#endif
/**
* @brief Get uap statistics
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_uap.h b/drivers/net/wireless/sd8797/mlinux/moal_uap.h
index b617e0aaf728..62d628a074c6 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_uap.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_uap.h
@@ -343,6 +343,25 @@ typedef struct _snmp_mib_para
/** Oid for 802.11H enable/disable */
#define OID_80211H_ENABLE 0x000a
+#ifdef DFS_TESTING_SUPPORT
+/** dfs_testing parameters */
+typedef struct _dfs_testing_param
+{
+ /** subcmd */
+ t_u32 subcmd;
+ /** Set/Get */
+ t_u32 action;
+ /** user CAC period (msec) */
+ t_u16 usr_cac_period;
+ /** user NOP period (sec) */
+ t_u16 usr_nop_period;
+ /** don't change channel on radar */
+ t_u8 no_chan_change;
+ /** fixed channel to change to on radar */
+ t_u8 fixed_new_chan;
+} dfs_testing_para;
+#endif
+
/** domain_info parameters */
typedef struct _domain_info_param
{
@@ -363,29 +382,12 @@ typedef struct _domain_info_param
#define MAX_DOMAIN_TLV_LEN (TLV_HEADER_LEN + COUNTRY_CODE_LEN \
+ (SUB_BAND_LEN * MAX_SUB_BANDS))
-#ifdef DFS_TESTING_SUPPORT
-/** dfs_testing parameters */
-typedef struct _dfs_testing_param
-{
- /** subcmd */
- t_u32 subcmd;
- /** Set/Get */
- t_u32 action;
- /** user CAC period (msec) */
- t_u16 usr_cac_period;
- /** user NOP period (sec) */
- t_u16 usr_nop_period;
- /** don't change channel on radar */
- t_u8 no_chan_change;
- /** fixed channel to change to on radar */
- t_u8 fixed_new_chan;
-} dfs_testing_para;
-#endif
-
void woal_uap_set_multicast_list(struct net_device *dev);
int woal_uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd);
int woal_uap_bss_ctrl(moal_private * priv, t_u8 wait_option, int data);
+#ifdef CONFIG_PROC_FS
void woal_uap_get_version(moal_private * priv, char *version, int max_len);
+#endif
mlan_status woal_uap_get_stats(moal_private * priv, t_u8 wait_option,
mlan_ds_uap_stats * ustats);
#if defined(UAP_WEXT) || defined(UAP_CFG80211)
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c b/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c
index f7907edffc73..917123f6978b 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c
@@ -21,118 +21,6 @@
#include "moal_cfg80211.h"
#include "moal_uap_cfg80211.h"
-
-/* these 3 function will be called in woal_cfg80211_wifi_direct_ops */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
-int woal_cfg80211_add_beacon(struct wiphy *wiphy,
- struct net_device *dev,
- struct cfg80211_ap_settings *params);
-
-int woal_cfg80211_set_beacon(struct wiphy *wiphy,
- struct net_device *dev,
- struct cfg80211_beacon_data *params);
-#else
-int woal_cfg80211_add_beacon(struct wiphy *wiphy,
- struct net_device *dev,
- struct beacon_parameters *params);
-
-int woal_cfg80211_set_beacon(struct wiphy *wiphy,
- struct net_device *dev,
- struct beacon_parameters *params);
-#endif
-
-int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev);
-
-static int woal_uap_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_scan_request *request);
-
-static int woal_uap_cfg80211_connect(struct wiphy *wiphy,
- struct net_device *dev,
- struct cfg80211_connect_params *sme);
-
-static int woal_uap_cfg80211_disconnect(struct wiphy *wiphy,
- struct net_device *dev,
- t_u16 reason_code);
-
-int woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
- u8 * mac, struct station_info *stainfo);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
-static const struct ieee80211_txrx_stypes
- ieee80211_uap_mgmt_stypes[NUM_NL80211_IFTYPES] = {
- [NL80211_IFTYPE_ADHOC] = {
- .tx = 0x0000,
- .rx = 0x0000,
- },
- [NL80211_IFTYPE_STATION] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4),
- },
- [NL80211_IFTYPE_AP] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
- BIT(IEEE80211_STYPE_DISASSOC >> 4) |
- BIT(IEEE80211_STYPE_AUTH >> 4) |
- BIT(IEEE80211_STYPE_DEAUTH >> 4) |
- BIT(IEEE80211_STYPE_ACTION >> 4),
- },
- [NL80211_IFTYPE_AP_VLAN] = {
- .tx = 0x0000,
- .rx = 0x0000,
- },
- [NL80211_IFTYPE_P2P_CLIENT] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
- },
- [NL80211_IFTYPE_P2P_GO] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- // BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
- 0,
- .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
- BIT(IEEE80211_STYPE_DISASSOC >> 4) |
- BIT(IEEE80211_STYPE_AUTH >> 4) |
- BIT(IEEE80211_STYPE_DEAUTH >> 4) |
- BIT(IEEE80211_STYPE_ACTION >> 4),
- },
- [NL80211_IFTYPE_MESH_POINT] = {
- .tx = 0x0000,
- .rx = 0x0000,
- },
-};
-#endif
-
-/** cfg80211 uAP operations */
-static struct cfg80211_ops woal_cfg80211_uap_ops = {
- .set_channel = woal_cfg80211_set_channel,
- .scan = woal_uap_cfg80211_scan,
- .connect = woal_uap_cfg80211_connect,
- .disconnect = woal_uap_cfg80211_disconnect,
- .set_wiphy_params = woal_cfg80211_set_wiphy_params,
- .change_virtual_intf = woal_cfg80211_change_virtual_intf,
- .add_key = woal_cfg80211_add_key,
- .del_key = woal_cfg80211_del_key,
- .set_default_key = woal_cfg80211_set_default_key,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
- .start_ap = woal_cfg80211_add_beacon,
- .change_beacon = woal_cfg80211_set_beacon,
- .stop_ap = woal_cfg80211_del_beacon,
-#else
- .add_beacon = woal_cfg80211_add_beacon,
- .set_beacon = woal_cfg80211_set_beacon,
- .del_beacon = woal_cfg80211_del_beacon,
-#endif
- .get_station = woal_uap_cfg80211_get_station,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
- .mgmt_frame_register = woal_cfg80211_mgmt_frame_register,
- .mgmt_tx = woal_cfg80211_mgmt_tx,
-#endif
-};
-
/********************************************************
Local Variables
********************************************************/
@@ -149,7 +37,6 @@ static struct cfg80211_ops woal_cfg80211_uap_ops = {
Global Functions
********************************************************/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) && !defined(COMPAT_WIRELESS)
/**
* @brief Verify RSN IE
*
@@ -170,6 +57,7 @@ woal_check_rsn_ie(IEEEtypes_Rsn_t * rsn_ie, mlan_uap_bss_param * sys_config)
return MFALSE;
sys_config->wpa_cfg.group_cipher = 0;
sys_config->wpa_cfg.pairwise_cipher_wpa2 = 0;
+ sys_config->key_mgmt = 0;
/* check the group cipher */
switch (rsn_ie->group_cipher.type) {
case WPA_CIPHER_TKIP:
@@ -204,14 +92,16 @@ woal_check_rsn_ie(IEEEtypes_Rsn_t * rsn_ie, mlan_uap_bss_param * sys_config)
if (left <
(sizeof(wpa_suite_auth_key_mgmt_t) + (count - 1) * sizeof(wpa_suite)))
return MFALSE;
-
for (i = 0; i < count; i++) {
switch (key_mgmt->list[i].type) {
case RSN_AKM_8021X:
- sys_config->key_mgmt = KEY_MGMT_EAP;
+ sys_config->key_mgmt |= KEY_MGMT_EAP;
break;
case RSN_AKM_PSK:
- sys_config->key_mgmt = KEY_MGMT_PSK;
+ sys_config->key_mgmt |= KEY_MGMT_PSK;
+ break;
+ case RSN_AKM_PSK_SHA256:
+ sys_config->key_mgmt |= KEY_MGMT_PSK_SHA256;
break;
}
}
@@ -293,10 +183,10 @@ woal_check_wpa_ie(IEEEtypes_Wpa_t * wpa_ie, mlan_uap_bss_param * sys_config)
* @return MTRUE/MFALSE
*/
static t_u8
-woal_find_wpa_ies(t_u8 * ie, int len, mlan_uap_bss_param * sys_config)
+woal_find_wpa_ies(const t_u8 * ie, int len, mlan_uap_bss_param * sys_config)
{
int bytes_left = len;
- t_u8 *pcurrent_ptr = ie;
+ const t_u8 *pcurrent_ptr = ie;
t_u16 total_ie_len;
t_u8 element_len;
t_u8 wpa2 = 0;
@@ -323,10 +213,14 @@ woal_find_wpa_ies(t_u8 * ie, int len, mlan_uap_bss_param * sys_config)
break;
case VENDOR_SPECIFIC_221:
pvendor_ie = (IEEEtypes_VendorSpecific_t *) pcurrent_ptr;
- if (!memcmp(pvendor_ie->vend_hdr.oui, wpa_oui, sizeof(wpa_oui)))
+ if (!memcmp
+ (pvendor_ie->vend_hdr.oui, wpa_oui,
+ sizeof(pvendor_ie->vend_hdr.oui)) &&
+ (pvendor_ie->vend_hdr.oui_type == wpa_oui[3])) {
wpa =
woal_check_wpa_ie((IEEEtypes_Wpa_t *) pcurrent_ptr,
sys_config);
+ }
break;
default:
break;
@@ -347,7 +241,6 @@ woal_find_wpa_ies(t_u8 * ie, int len, mlan_uap_bss_param * sys_config)
}
return ret;
}
-#endif
/** secondary channel is below */
#define SECOND_CHANNEL_BELOW 0x30
@@ -475,6 +368,8 @@ woal_cfg80211_beacon_config(moal_private * priv,
/* Setting the default values */
sys_config.channel = 6;
sys_config.preamble_type = 0;
+ sys_config.mgmt_ie_passthru_mask = priv->mgmt_subtype_mask;
+ memcpy(sys_config.mac_addr, priv->current_addr, ETH_ALEN);
if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
@@ -530,11 +425,18 @@ woal_cfg80211_beacon_config(moal_private * priv,
sys_config.auth_mode = MLAN_AUTH_MODE_SHARED;
else
sys_config.auth_mode = MLAN_AUTH_MODE_OPEN;
-
+ if (params->crypto.n_akm_suites) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ woal_find_wpa_ies(params->beacon.tail, (int) params->beacon.tail_len,
+ &sys_config);
+#else
+ woal_find_wpa_ies(params->tail, params->tail_len, &sys_config);
+#endif
+ }
for (i = 0; i < params->crypto.n_akm_suites; i++) {
switch (params->crypto.akm_suites[i]) {
case WLAN_AKM_SUITE_8021X:
- sys_config.key_mgmt = KEY_MGMT_EAP;
+ sys_config.key_mgmt |= KEY_MGMT_EAP;
if ((params->crypto.wpa_versions & NL80211_WPA_VERSION_1) &&
(params->crypto.wpa_versions & NL80211_WPA_VERSION_2))
sys_config.protocol = PROTOCOL_WPA | PROTOCOL_WPA2;
@@ -544,7 +446,7 @@ woal_cfg80211_beacon_config(moal_private * priv,
sys_config.protocol = PROTOCOL_WPA;
break;
case WLAN_AKM_SUITE_PSK:
- sys_config.key_mgmt = KEY_MGMT_PSK;
+ sys_config.key_mgmt |= KEY_MGMT_PSK;
if ((params->crypto.wpa_versions & NL80211_WPA_VERSION_1) &&
(params->crypto.wpa_versions & NL80211_WPA_VERSION_2))
sys_config.protocol = PROTOCOL_WPA | PROTOCOL_WPA2;
@@ -647,8 +549,8 @@ woal_cfg80211_beacon_config(moal_private * priv,
if (capab_info & WLAN_CAPABILITY_PRIVACY) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
if (MFALSE ==
- woal_find_wpa_ies(params->beacon.tail, params->beacon.tail_len,
- &sys_config))
+ woal_find_wpa_ies(params->beacon.tail,
+ (int) params->beacon.tail_len, &sys_config))
#else
if (MFALSE ==
woal_find_wpa_ies(params->tail, params->tail_len, &sys_config))
@@ -683,34 +585,485 @@ woal_cfg80211_beacon_config(moal_private * priv,
return ret;
}
-static int
-woal_uap_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_scan_request *request)
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+/**
+ * @brief Callback function for virtual interface
+ * setup
+ *
+ * @param dev A pointer to structure net_device
+ *
+ * @return N/A
+ */
+static void
+woal_virt_if_setup(struct net_device *dev)
+{
+ ENTER();
+ ether_setup(dev);
+ dev->destructor = free_netdev;
+ LEAVE();
+}
+
+/**
+ * @brief This function adds a new interface. It will
+ * allocate, initialize and register the device.
+ *
+ * @param handle A pointer to moal_handle structure
+ * @param bss_index BSS index number
+ * @param bss_type BSS type
+ *
+ * @return A pointer to the new priv structure
+ */
+moal_private *
+woal_alloc_virt_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
+ const
+#endif
+ char *name)
{
+ struct net_device *dev = NULL;
+ moal_private *priv = NULL;
ENTER();
- cfg80211_scan_done(request, MTRUE);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
+#ifndef MAX_WMM_QUEUE
+#define MAX_WMM_QUEUE 4
+#endif
+ /* Allocate an Ethernet device */
+ if (!
+ (dev =
+ alloc_netdev_mq(sizeof(moal_private), name, woal_virt_if_setup,
+ MAX_WMM_QUEUE))) {
+#else
+ if (!(dev = alloc_netdev(sizeof(moal_private), name, woal_virt_if_setup))) {
+#endif
+ PRINTM(MFATAL, "Init virtual ethernet device failed\n");
+ goto error;
+ }
+ /* Allocate device name */
+ if ((dev_alloc_name(dev, name) < 0)) {
+ PRINTM(MERROR, "Could not allocate device name\n");
+ goto error;
+ }
+
+ priv = (moal_private *) netdev_priv(dev);
+ /* Save the priv to handle */
+ handle->priv[bss_index] = priv;
+
+ /* Use the same handle structure */
+ priv->phandle = handle;
+ priv->netdev = dev;
+ priv->bss_index = bss_index;
+ priv->bss_type = bss_type;
+ priv->bss_role = MLAN_BSS_ROLE_STA;
+ INIT_LIST_HEAD(&priv->tcp_sess_queue);
+ spin_lock_init(&priv->tcp_sess_lock);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ SET_MODULE_OWNER(dev);
+#endif
+
+ PRINTM(MCMND, "Alloc virtual interface%s\n", dev->name);
+
+ LEAVE();
+ return priv;
+ error:
+ if (dev)
+ free_netdev(dev);
LEAVE();
- return 0;
+ return NULL;
}
-static int
-woal_uap_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_connect_params *sme)
+/**
+ * @brief Request the driver to add a virtual interface
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param name Virtual interface name
+ * @param type Virtual interface type
+ * @param flags Flags for the virtual interface
+ * @param params A pointer to vif_params structure
+ * @param new_dev new net_device to return
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_add_virt_if(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
+ const
+#endif
+ char *name, enum nl80211_iftype type, u32 * flags,
+ struct vif_params *params,
+ struct net_device **new_dev)
{
+ int ret = 0;
+ struct net_device *ndev = NULL;
+ moal_private *priv, *new_priv;
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
+ struct wireless_dev *wdev = NULL;
+
ENTER();
+ ASSERT_RTNL();
+ priv =
+ (moal_private *) woal_get_priv_bss_type(handle,
+ MLAN_BSS_TYPE_WIFIDIRECT);
+ if (priv->phandle->drv_mode.intf_num == priv->phandle->priv_num) {
+ PRINTM(MERROR, "max virtual interface limit reached\n");
+ LEAVE();
+ return -ENOMEM;
+ }
+ if ((type != NL80211_IFTYPE_P2P_CLIENT) && (type != NL80211_IFTYPE_P2P_GO)) {
+ PRINTM(MERROR, "Invalid iftype: %d\n", type);
+ LEAVE();
+ return -EINVAL;
+ }
+
+ handle = priv->phandle;
+ /* Cancel previous scan req */
+ woal_cancel_scan(priv, MOAL_IOCTL_WAIT);
+ new_priv =
+ woal_alloc_virt_interface(handle, handle->priv_num,
+ MLAN_BSS_TYPE_WIFIDIRECT, name);
+ if (!new_priv) {
+ PRINTM(MERROR, "Add virtual interface fail.");
+ LEAVE();
+ return -EFAULT;
+ }
+ handle->priv_num++;
+
+ wdev = (struct wireless_dev *) &new_priv->w_dev;
+ memset(wdev, 0, sizeof(struct wireless_dev));
+ ndev = new_priv->netdev;
+ SET_NETDEV_DEV(ndev, wiphy_dev(wiphy));
+ ndev->ieee80211_ptr = wdev;
+ wdev->iftype = type;
+ wdev->wiphy = wiphy;
+ new_priv->wdev = wdev;
+ new_priv->bss_virtual = MTRUE;
+ new_priv->pa_netdev = priv->netdev;
+
+ woal_init_sta_dev(ndev, new_priv);
+
+ /* Initialize priv structure */
+ woal_init_priv(new_priv, MOAL_CMD_WAIT);
+ /** Init to GO/CLIENT mode */
+ if (type == NL80211_IFTYPE_P2P_CLIENT)
+ woal_cfg80211_init_p2p_client(new_priv);
+ else if (type == NL80211_IFTYPE_P2P_GO)
+ woal_cfg80211_init_p2p_go(new_priv);
+ ret = register_netdevice(ndev);
+ if (ret) {
+ handle->priv[new_priv->bss_index] = NULL;
+ handle->priv_num--;
+ free_netdev(ndev);
+ ndev = NULL;
+ PRINTM(MFATAL, "register net_device failed, ret=%d\n", ret);
+ goto done;
+ }
+ netif_carrier_off(ndev);
+ woal_stop_queue(ndev);
+ if (new_dev)
+ *new_dev = ndev;
+ done:
+ if (ret) {
+ if (ndev && ndev->reg_state == NETREG_REGISTERED)
+ unregister_netdevice(ndev);
+ }
LEAVE();
- return 0;
+ return ret;
}
-static int
-woal_uap_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
- t_u16 reason_code)
+/**
+ * @brief Notify mlan BSS will be removed.
+ *
+ * @param priv A pointer to moal_private structure
+ *
+ * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, otherwise fail
+ */
+mlan_status
+woal_bss_remove(moal_private * priv)
+{
+ mlan_ioctl_req *req = NULL;
+ mlan_ds_bss *bss = NULL;
+ mlan_status status;
+
+ ENTER();
+
+ /* Allocate an IOCTL request buffer */
+ req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+ if (req == NULL) {
+ status = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+
+ /* Fill request buffer */
+ bss = (mlan_ds_bss *) req->pbuf;
+ bss->sub_command = MLAN_OID_BSS_REMOVE;
+ req->req_id = MLAN_IOCTL_BSS;
+ req->action = MLAN_ACT_SET;
+ /* Send IOCTL request to MLAN */
+ status = woal_request_ioctl(priv, req, MOAL_CMD_WAIT);
+
+ done:
+ if (req && (status != MLAN_STATUS_PENDING))
+ kfree(req);
+ LEAVE();
+ return status;
+}
+
+/**
+ * @brief This function removes an virtual interface.
+ *
+ * @param wiphy A pointer to the wiphy structure
+ * @param dev A pointer to the net_device structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_del_virt_if(struct wiphy *wiphy, struct net_device *dev)
+{
+ int ret = 0;
+ int i = 0;
+ moal_private *priv = NULL;
+ moal_private *vir_priv = NULL;
+ moal_private *remain_priv = NULL;
+ moal_handle *handle = (moal_handle *) woal_get_wiphy_priv(wiphy);
+
+ priv =
+ (moal_private *) woal_get_priv_bss_type(handle,
+ MLAN_BSS_TYPE_WIFIDIRECT);
+ for (i = 0; i < priv->phandle->priv_num; i++) {
+ if ((vir_priv = priv->phandle->priv[i])) {
+ if (vir_priv->netdev == dev) {
+ PRINTM(MIOCTL, "Find virtual interface, index=%d\n", i);
+ break;
+ }
+ }
+ }
+ if (vir_priv && vir_priv->netdev == dev) {
+ woal_stop_queue(dev);
+ netif_carrier_off(dev);
+ netif_device_detach(dev);
+ woal_cancel_scan(vir_priv, MOAL_IOCTL_WAIT);
+ /* cancel previous remain on channel to avoid firmware hang */
+ if (priv->phandle->remain_on_channel) {
+ t_u8 channel_status;
+ remain_priv = priv->phandle->priv[priv->phandle->remain_bss_index];
+ if (remain_priv) {
+ if (woal_cfg80211_remain_on_channel_cfg
+ (remain_priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL,
+ 0, 0))
+ PRINTM(MERROR,
+ "del_virt_if: Fail to cancel remain on channel\n");
+
+ if (priv->phandle->cookie) {
+ cfg80211_remain_on_channel_expired(
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+ remain_priv->netdev,
+#else
+ remain_priv->wdev,
+#endif
+ priv->phandle->cookie,
+ &priv->phandle->chan,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
+ priv->phandle->
+ channel_type,
+#endif
+ GFP_ATOMIC);
+ priv->phandle->cookie = 0;
+ }
+ priv->phandle->remain_on_channel = MFALSE;
+ }
+ }
+
+ woal_clear_all_mgmt_ies(vir_priv);
+ woal_cfg80211_deinit_p2p(vir_priv);
+ woal_bss_remove(vir_priv);
+ /* Last reference is our one */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+ PRINTM(MINFO, "refcnt = %d\n", atomic_read(&dev->refcnt));
+#else
+ PRINTM(MINFO, "refcnt = %d\n", netdev_refcnt_read(dev));
+#endif
+ PRINTM(MINFO, "netdev_finish_unregister: %s\n", dev->name);
+ /* Clear the priv in handle */
+ vir_priv->phandle->priv[vir_priv->bss_index] = NULL;
+ priv->phandle->priv_num--;
+ if (dev->reg_state == NETREG_REGISTERED)
+ unregister_netdevice(dev);
+ }
+ return ret;
+}
+
+/**
+ * @brief This function removes an virtual interface.
+ *
+ * @param handle A pointer to the moal_handle structure
+ *
+ * @return N/A
+ */
+void
+woal_remove_virtual_interface(moal_handle * handle)
{
+ moal_private *priv = NULL;
+ int vir_intf = 0;
+ int i = 0;
ENTER();
+ rtnl_lock();
+ for (i = 0; i < handle->priv_num; i++) {
+ if ((priv = handle->priv[i])) {
+ if (priv->bss_virtual) {
+ PRINTM(MCMND, "Remove virtual interface %s\n",
+ priv->netdev->name);
+ netif_device_detach(priv->netdev);
+ if (priv->netdev->reg_state == NETREG_REGISTERED)
+ unregister_netdevice(priv->netdev);
+ handle->priv[i] = NULL;
+ vir_intf++;
+ }
+ }
+ }
+ rtnl_unlock();
+ handle->priv_num -= vir_intf;
LEAVE();
- return 0;
+}
+#endif
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
+/**
+ * @brief Request the driver to add a virtual interface
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param name Virtual interface name
+ * @param type Virtual interface type
+ * @param flags Flags for the virtual interface
+ * @param params A pointer to vif_params structure
+ *
+ * @return A pointer to net_device -- success, otherwise null
+ */
+struct net_device *
+woal_cfg80211_add_virtual_intf(struct wiphy *wiphy,
+ char *name, enum nl80211_iftype type,
+ u32 * flags, struct vif_params *params)
+#else
+/**
+ * @brief Request the driver to add a virtual interface
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param name Virtual interface name
+ * @param type Virtual interface type
+ * @param flags Flags for the virtual interface
+ * @param params A pointer to vif_params structure
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_add_virtual_intf(struct wiphy *wiphy,
+ char *name, enum nl80211_iftype type,
+ u32 * flags, struct vif_params *params)
+#endif
+#else
+/**
+ * @brief Request the driver to add a virtual interface
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param name Virtual interface name
+ * @param type Virtual interface type
+ * @param flags Flags for the virtual interface
+ * @param params A pointer to vif_params structure
+ *
+ * @return A pointer to wireless_dev -- success, otherwise null
+ */
+struct wireless_dev *
+woal_cfg80211_add_virtual_intf(struct wiphy *wiphy,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
+ const
+#endif
+ char *name, enum nl80211_iftype type,
+ u32 * flags, struct vif_params *params)
+#endif
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
+ struct net_device *ndev = NULL;
+#endif
+ int ret = 0;
+
+ ENTER();
+ PRINTM(MIOCTL, "add virtual intf: %d name: %s\n", type, name);
+ switch (type) {
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_P2P_GO:
+ ret =
+ woal_cfg80211_add_virt_if(wiphy, name, type, flags, params, &ndev);
+ break;
+#endif
+#endif
+ default:
+ PRINTM(MWARN, "Not supported if type: %d\n", type);
+ ret = -EFAULT;
+ break;
+ }
+ LEAVE();
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
+ if (ret)
+ return NULL;
+ else
+ return ndev;
+#else
+ return ret;
+#endif
+#else
+ if (ret)
+ return NULL;
+ else
+ return (ndev->ieee80211_ptr);
+#endif
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
+/**
+ * @brief Request the driver to del a virtual interface
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param dev The pointer to net_device
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
+#else
+/**
+ * @brief Request the driver to del a virtual interface
+ *
+ * @param wiphy A pointer to wiphy structure
+ * @param wdev The pointer to wireless_dev
+ *
+ * @return 0 -- success, otherwise fail
+ */
+int
+woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
+#endif
+{
+ int ret = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ struct net_device *dev = wdev->netdev;
+#endif
+ ENTER();
+
+ PRINTM(MIOCTL, "del virtual intf %s\n", dev->name);
+ ASSERT_RTNL();
+#if defined(WIFI_DIRECT_SUPPORT)
+#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
+ ret = woal_cfg80211_del_virt_if(wiphy, dev);
+#endif
+#endif
+ LEAVE();
+ return ret;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
@@ -748,12 +1101,16 @@ woal_cfg80211_add_beacon(struct wiphy *wiphy,
ENTER();
- PRINTM(MIOCTL, "add beacon\n");
+ PRINTM(MMSG, "wlan: Starting AP\n");
#ifdef STA_CFG80211
/*** cancel pending scan */
woal_cancel_scan(priv, MOAL_IOCTL_WAIT);
#endif
if (params != NULL) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ priv->channel =
+ ieee80211_frequency_to_channel(params->channel->center_freq);
+#endif
/* bss config */
if (MLAN_STATUS_SUCCESS != woal_cfg80211_beacon_config(priv, params)) {
ret = -EFAULT;
@@ -806,6 +1163,41 @@ woal_cfg80211_add_beacon(struct wiphy *wiphy,
goto done;
}
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ if (params->beacon.beacon_ies && params->beacon.beacon_ies_len) {
+ if (MLAN_STATUS_SUCCESS != woal_cfg80211_mgmt_frame_ie(priv,
+ params->beacon.
+ beacon_ies,
+ params->beacon.
+ beacon_ies_len,
+ NULL, 0, NULL, 0,
+ NULL, 0,
+ MGMT_MASK_BEACON_WPS_P2P))
+ {
+ PRINTM(MERROR, "Failed to set beacon wps/p2p ie\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ }
+#else
+ if (params->beacon_ies && params->beacon_ies_len) {
+ if (MLAN_STATUS_SUCCESS != woal_cfg80211_mgmt_frame_ie(priv,
+ params->
+ beacon_ies,
+ params->
+ beacon_ies_len,
+ NULL, 0, NULL, 0,
+ NULL, 0,
+ MGMT_MASK_BEACON_WPS_P2P))
+ {
+ PRINTM(MERROR, "Failed to set beacon wps/p2p ie\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ }
+#endif
+#endif
/* if the bss is stopped, then start it */
if (priv->bss_started == MFALSE) {
@@ -816,6 +1208,7 @@ woal_cfg80211_add_beacon(struct wiphy *wiphy,
}
}
+ PRINTM(MMSG, "wlan: AP started\n");
done:
LEAVE();
return ret;
@@ -868,7 +1261,7 @@ woal_cfg80211_set_beacon(struct wiphy *wiphy,
}
}
#else
- if (params->beacon_ies && params->beacon_ies_len) {
+ if (params->tail && params->tail_len) {
if (MLAN_STATUS_SUCCESS !=
woal_cfg80211_mgmt_frame_ie(priv, params->tail,
params->tail_len, NULL, 0, NULL, 0,
@@ -877,7 +1270,22 @@ woal_cfg80211_set_beacon(struct wiphy *wiphy,
goto done;
}
}
-
+ if (params->beacon_ies && params->beacon_ies_len) {
+ if (MLAN_STATUS_SUCCESS != woal_cfg80211_mgmt_frame_ie(priv,
+ params->
+ beacon_ies,
+ params->
+ beacon_ies_len,
+ NULL, 0,
+ NULL, 0,
+ NULL, 0,
+ MGMT_MASK_BEACON_WPS_P2P))
+ {
+ PRINTM(MERROR, "Failed to set beacon wps/p2p ie\n");
+ ret = -EFAULT;
+ goto done;
+ }
+ }
if (params->proberesp_ies && params->proberesp_ies_len) {
if (MLAN_STATUS_SUCCESS !=
woal_cfg80211_mgmt_frame_ie(priv, NULL, 0,
@@ -888,7 +1296,6 @@ woal_cfg80211_set_beacon(struct wiphy *wiphy,
goto done;
}
}
-
if (params->assocresp_ies && params->assocresp_ies_len) {
if (MLAN_STATUS_SUCCESS !=
woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0,
@@ -920,10 +1327,13 @@ woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
{
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
int ret = 0;
+#ifdef STA_SUPPORT
+ moal_private *pmpriv = NULL;
+#endif
ENTER();
- PRINTM(MIOCTL, "del beacon\n");
+ PRINTM(MMSG, "wlan: Stoping AP\n");
/* if the bss is still running, then stop it */
if (priv->bss_started == MTRUE) {
if (MLAN_STATUS_SUCCESS !=
@@ -936,45 +1346,89 @@ woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
ret = -EFAULT;
goto done;
}
+ /* Set WLAN MAC addresses */
+ if (MLAN_STATUS_SUCCESS != woal_request_set_mac_address(priv)) {
+ PRINTM(MERROR, "Set MAC address failed\n");
+ ret = -EFAULT;
+ goto done;
+ }
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) && !defined(COMPAT_WIRELESS)
- /* clear BEACON WPS/P2P IE */
- if (MLAN_STATUS_SUCCESS !=
- woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, NULL, 0, NULL, 0,
- MGMT_MASK_BEACON_WPS_P2P)) {
- ret = -EFAULT;
- goto done;
+ woal_clear_all_mgmt_ies(priv);
+
+#ifdef STA_SUPPORT
+ if (!woal_is_any_interface_active(priv->phandle)) {
+ if ((pmpriv =
+ woal_get_priv((moal_handle *) priv->phandle, MLAN_BSS_ROLE_STA))) {
+ woal_set_scan_time(pmpriv, ACTIVE_SCAN_CHAN_TIME,
+ PASSIVE_SCAN_CHAN_TIME, SPECIFIC_SCAN_CHAN_TIME);
+ }
}
#endif
- /* clear mgmt frame ies */
+
+ priv->cipher = 0;
+ priv->key_len = 0;
+ priv->channel = 0;
+ PRINTM(MMSG, "wlan: AP stopped\n");
+ done:
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief send deauth to station
+ *
+ * @param A pointer to moal_private
+ * @param mac A pointer to station mac address
+ *
+ * @return 0 -- success, otherwise fail
+ */
+static int
+woal_deauth_station(moal_private * priv, u8 * mac_addr)
+{
+ mlan_ioctl_req *ioctl_req = NULL;
+ mlan_ds_bss *bss = NULL;
+ int ret = 0;
+
+ ENTER();
+
+ ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+ if (ioctl_req == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ bss = (mlan_ds_bss *) ioctl_req->pbuf;
+ bss->sub_command = MLAN_OID_UAP_DEAUTH_STA;
+ ioctl_req->req_id = MLAN_IOCTL_BSS;
+ ioctl_req->action = MLAN_ACT_SET;
+
+ memcpy(bss->param.deauth_param.mac_addr, mac_addr, MLAN_MAC_ADDR_LENGTH);
+#define REASON_CODE_DEAUTH_LEAVING 3
+ bss->param.deauth_param.reason_code = REASON_CODE_DEAUTH_LEAVING;
if (MLAN_STATUS_SUCCESS !=
- woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, NULL, 0, NULL, 0,
- MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP |
- MGMT_MASK_ASSOC_RESP)) {
+ woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
ret = -EFAULT;
goto done;
}
- priv->cipher = 0;
- priv->key_len = 0;
done:
+ if (ioctl_req)
+ kfree(ioctl_req);
LEAVE();
return ret;
}
/**
- * @brief Get station info
+ * @brief del station
*
* @param wiphy A pointer to wiphy structure
* @param dev A pointer to net_device structure
* @param mac A pointer to station mac address
- * @param stainfo A pointer to station_info structure
*
* @return 0 -- success, otherwise fail
*/
int
-woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
- u8 * mac, struct station_info *stainfo)
+woal_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 * mac_addr)
{
moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
int ret = -EFAULT;
@@ -986,9 +1440,17 @@ woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
if (priv->media_connected == MFALSE) {
PRINTM(MINFO, "cfg80211: Media not connected!\n");
LEAVE();
- return -ENOENT;
+ return 0;
}
+ if (mac_addr) {
+ PRINTM(MIOCTL, "del station: " MACSTR "\n", MAC2STR(mac_addr));
+ ret = woal_deauth_station(priv, mac_addr);
+ woal_sched_timeout(100);
+ LEAVE();
+ return ret;
+ }
+ PRINTM(MIOCTL, "del all station\n");
/* Allocate an IOCTL request buffer */
ioctl_req =
(mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
@@ -1006,116 +1468,83 @@ woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
goto done;
}
+ if (!info->param.sta_list.sta_count)
+ goto done;
for (i = 0; i < info->param.sta_list.sta_count; i++) {
- if (!memcmp(info->param.sta_list.info[i].mac_address, mac, ETH_ALEN)) {
- PRINTM(MIOCTL,
- "Get station: %02x:%02x:%02x:%02x:%02x:%02x RSSI=%d\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
- (int) info->param.sta_list.info[i].rssi);
- stainfo->filled = STATION_INFO_INACTIVE_TIME | STATION_INFO_SIGNAL;
- stainfo->inactive_time = 0;
- stainfo->signal = info->param.sta_list.info[i].rssi;
- ret = 0;
- break;
- }
+ PRINTM(MIOCTL, "deauth station " MACSTR "\n",
+ MAC2STR(info->param.sta_list.info[i].mac_address));
+ ret =
+ woal_deauth_station(priv, info->param.sta_list.info[i].mac_address);
}
+ woal_sched_timeout(100);
done:
if (ioctl_req)
kfree(ioctl_req);
LEAVE();
return ret;
+
}
/**
- * @brief Initialize the uAP wiphy
+ * @brief Get station info
*
- * @param priv A pointer to moal_private structure
- * @param wait_option Wait option
+ * @param wiphy A pointer to wiphy structure
+ * @param dev A pointer to net_device structure
+ * @param mac A pointer to station mac address
+ * @param stainfo A pointer to station_info structure
*
- * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ * @return 0 -- success, otherwise fail
*/
-mlan_status
-woal_cfg80211_uap_init_wiphy(moal_private * priv, t_u8 wait_option)
+int
+woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 * mac, struct station_info *stainfo)
{
- struct wiphy *wiphy;
- mlan_uap_bss_param ap_cfg;
- mlan_ioctl_req *req = NULL;
- mlan_ds_11n_cfg *cfg_11n = NULL;
- t_u32 hw_dev_cap;
+ moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
+ int ret = -EFAULT;
+ int i = 0;
+ mlan_ds_get_info *info = NULL;
+ mlan_ioctl_req *ioctl_req = NULL;
ENTER();
-
- if (priv->wdev)
- wiphy = priv->wdev->wiphy;
- else {
- PRINTM(MERROR, "Invalid parameter when init wiphy.\n");
- LEAVE();
- return MLAN_STATUS_FAILURE;
- }
- if (MLAN_STATUS_SUCCESS != woal_set_get_sys_config(priv,
- MLAN_ACT_GET,
- wait_option, &ap_cfg)) {
- LEAVE();
- return MLAN_STATUS_FAILURE;
- }
-
- /* Get 11n tx parameters from MLAN */
- req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
- if (req == NULL) {
+ if (priv->media_connected == MFALSE) {
+ PRINTM(MINFO, "cfg80211: Media not connected!\n");
LEAVE();
- return MLAN_STATUS_FAILURE;
+ return -ENOENT;
}
- cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
- cfg_11n->sub_command = MLAN_OID_11N_HTCAP_CFG;
- req->req_id = MLAN_IOCTL_11N_CFG;
- req->action = MLAN_ACT_GET;
- cfg_11n->param.htcap_cfg.hw_cap_req = MTRUE;
- if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
- kfree(req);
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ /* Allocate an IOCTL request buffer */
+ ioctl_req =
+ (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+ if (ioctl_req == NULL) {
+ ret = -ENOMEM;
+ goto done;
}
- hw_dev_cap = cfg_11n->param.htcap_cfg.htcap;
- /* Get supported MCS sets */
- memset(req->pbuf, 0, sizeof(mlan_ds_11n_cfg));
- cfg_11n->sub_command = MLAN_OID_11N_CFG_SUPPORTED_MCS_SET;
- req->req_id = MLAN_IOCTL_11N_CFG;
- req->action = MLAN_ACT_GET;
+ info = (mlan_ds_get_info *) ioctl_req->pbuf;
+ info->sub_command = MLAN_OID_UAP_STA_LIST;
+ ioctl_req->req_id = MLAN_IOCTL_GET_INFO;
+ ioctl_req->action = MLAN_ACT_GET;
- if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
- kfree(req);
- LEAVE();
- return MLAN_STATUS_FAILURE;
+ if (MLAN_STATUS_SUCCESS !=
+ woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
+ goto done;
}
-
- /* Initialize parameters for 2GHz and 5GHz bands */
- woal_cfg80211_setup_ht_cap(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap,
- hw_dev_cap, cfg_11n->param.supported_mcs_set);
- /* For 2.4G band only card, this shouldn't be set */
- if (wiphy->bands[IEEE80211_BAND_5GHZ])
- woal_cfg80211_setup_ht_cap(&wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap,
- hw_dev_cap,
- cfg_11n->param.supported_mcs_set);
- if (req)
- kfree(req);
-
- /* Set retry limit count to wiphy */
- wiphy->retry_long = (t_u8) ap_cfg.retry_limit;
- wiphy->retry_short = (t_u8) ap_cfg.retry_limit;
- wiphy->max_scan_ie_len = MAX_IE_SIZE;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
- wiphy->mgmt_stypes = ieee80211_uap_mgmt_stypes;
-#endif
- /* Set RTS threshold to wiphy */
- wiphy->rts_threshold = (t_u32) ap_cfg.rts_threshold;
-
- /* Set fragment threshold to wiphy */
- wiphy->frag_threshold = (t_u32) ap_cfg.frag_threshold;
-
+ for (i = 0; i < info->param.sta_list.sta_count; i++) {
+ if (!memcmp(info->param.sta_list.info[i].mac_address, mac, ETH_ALEN)) {
+ PRINTM(MIOCTL, "Get station: " MACSTR " RSSI=%d\n", MAC2STR(mac),
+ (int) info->param.sta_list.info[i].rssi);
+ stainfo->filled = STATION_INFO_INACTIVE_TIME | STATION_INFO_SIGNAL;
+ stainfo->inactive_time = 0;
+ stainfo->signal = info->param.sta_list.info[i].rssi;
+ ret = 0;
+ break;
+ }
+ }
+ done:
+ if (ioctl_req)
+ kfree(ioctl_req);
LEAVE();
- return MLAN_STATUS_SUCCESS;
+ return ret;
}
/**
@@ -1131,91 +1560,26 @@ woal_register_uap_cfg80211(struct net_device * dev, t_u8 bss_type)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
moal_private *priv = (moal_private *) netdev_priv(dev);
- void *wdev_priv = NULL;
struct wireless_dev *wdev = NULL;
- mlan_fw_info fw_info;
ENTER();
- /* Allocate wireless device */
- wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
- if (!wdev) {
- PRINTM(MERROR, "Could not allocate wireless device\n");
- ret = MLAN_STATUS_FAILURE;
- goto err_wdev;
- }
+ wdev = (struct wireless_dev *) &priv->w_dev;
+ memset(wdev, 0, sizeof(struct wireless_dev));
- /* Allocate wiphy */
- wdev->wiphy = wiphy_new(&woal_cfg80211_uap_ops, sizeof(moal_private *));
+ wdev->wiphy = priv->phandle->wiphy;
if (!wdev->wiphy) {
- PRINTM(MERROR, "Could not allocate wiphy device\n");
- ret = MLAN_STATUS_FAILURE;
- goto err_wdev;
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
}
- if (bss_type == MLAN_BSS_TYPE_UAP) {
- dev_set_name(&wdev->wiphy->dev, dev->name);
+ if (bss_type == MLAN_BSS_TYPE_UAP)
wdev->iftype = NL80211_IFTYPE_AP;
- wdev->wiphy->interface_modes =
- MBIT(NL80211_IFTYPE_AP) | MBIT(NL80211_IFTYPE_STATION) | 0;
- wdev->wiphy->max_scan_ssids = 10;
- }
-
- /* Make this wiphy known to this driver only */
- wdev->wiphy->privid = mrvl_wiphy_privid;
-
- /* Supported bands */
- wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &cfg80211_band_2ghz;
- if (MLAN_STATUS_SUCCESS ==
- woal_request_get_fw_info(priv, MOAL_CMD_WAIT, &fw_info)) {
- if (fw_info.fw_bands & BAND_A)
- wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &cfg80211_band_5ghz;
- }
-
- /* Initialize cipher suits */
- wdev->wiphy->cipher_suites = cfg80211_cipher_suites;
- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cfg80211_cipher_suites);
-
- wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-
- /* We are using custom domains */
- wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
-
- wdev->wiphy->reg_notifier = NULL; // TODO: woal_cfg80211_reg_notifier;
-
- /* Set moal_private pointer in wiphy_priv */
- wdev_priv = wiphy_priv(wdev->wiphy);
-
- *(unsigned long *) wdev_priv = (unsigned long) priv;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) || defined(COMPAT_WIRELESS)
- set_wiphy_dev(wdev->wiphy, (struct device *) priv->phandle->hotplug_device);
-#endif
-
- if (wiphy_register(wdev->wiphy) < 0) {
- PRINTM(MERROR, "Wiphy device registration failed!\n");
- ret = MLAN_STATUS_FAILURE;
- goto err_wdev;
- }
dev_net_set(dev, wiphy_net(wdev->wiphy));
dev->ieee80211_ptr = wdev;
SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
priv->wdev = wdev;
- if (ret != MLAN_STATUS_SUCCESS) {
- PRINTM(MERROR, "Wiphy device registration failed!\n");
- } else {
- PRINTM(MINFO, "Successfully registered wiphy device\n");
- LEAVE();
- return ret;
- }
-
- wiphy_unregister(wdev->wiphy);
- err_wdev:
- dev->ieee80211_ptr = NULL;
- if (wdev && wdev->wiphy)
- wiphy_free(wdev->wiphy);
- kfree(wdev);
LEAVE();
return ret;
}
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.h b/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.h
index 74c6f1a4e59b..9af1030367e0 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.h
@@ -25,6 +25,5 @@
#include "moal_uap.h"
mlan_status woal_register_uap_cfg80211(struct net_device *dev, t_u8 bss_type);
-mlan_status woal_cfg80211_uap_init_wiphy(moal_private * priv, t_u8 wait_option);
#endif /* _MOAL_UAP_CFG80211_H_ */
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_uap_wext.c b/drivers/net/wireless/sd8797/mlinux/moal_uap_wext.c
index 96322fc39522..a4f0e53bc063 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_uap_wext.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_uap_wext.c
@@ -255,10 +255,8 @@ woal_set_wap(struct net_device *dev, struct iw_request_info *info,
goto done;
}
- PRINTM(MINFO, "ASSOC: WAP: uAP bss : %02x:%02x:%02x:%02x:%02x:%02x\n",
- (t_u8) awrq->sa_data[0], (t_u8) awrq->sa_data[1],
- (t_u8) awrq->sa_data[2], (t_u8) awrq->sa_data[3],
- (t_u8) awrq->sa_data[4], (t_u8) awrq->sa_data[5]);
+ PRINTM(MINFO, "ASSOC: WAP: uAP bss : " MACSTR "\n",
+ MAC2STR((t_u8 *) awrq->sa_data));
/*
* Using this ioctl to start/stop the BSS, return if bss
@@ -481,7 +479,7 @@ woal_set_encode(struct net_device *dev, struct iw_request_info *info,
/* Check index */
key_index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- if (key_index > 3) {
+ if ((key_index > 3) || (key_index < 0)) {
PRINTM(MERROR, "Key index #%d out of range\n", key_index);
ret = -EINVAL;
goto done;
@@ -516,16 +514,14 @@ woal_set_encode(struct net_device *dev, struct iw_request_info *info,
sys_cfg->wep_cfg.key2.key_index = 2;
sys_cfg->wep_cfg.key3.key_index = 3;
- if (key_index >= 0 && key_index <= 3) {
- if (key_index == 0)
- pkey = &sys_cfg->wep_cfg.key0;
- else if (key_index == 1)
- pkey = &sys_cfg->wep_cfg.key1;
- else if (key_index == 2)
- pkey = &sys_cfg->wep_cfg.key2;
- else if (key_index == 3)
- pkey = &sys_cfg->wep_cfg.key3;
- }
+ if (key_index == 0)
+ pkey = &sys_cfg->wep_cfg.key0;
+ else if (key_index == 1)
+ pkey = &sys_cfg->wep_cfg.key1;
+ else if (key_index == 2)
+ pkey = &sys_cfg->wep_cfg.key2;
+ else if (key_index == 3)
+ pkey = &sys_cfg->wep_cfg.key3;
if (!(dwrq->flags & IW_ENCODE_NOKEY) && dwrq->length) {
if (dwrq->length > MAX_WEP_KEY_SIZE) {
@@ -533,18 +529,6 @@ woal_set_encode(struct net_device *dev, struct iw_request_info *info,
ret = -E2BIG;
goto done;
}
- if (key_index < 0) {
- /* Get current default key index */
- if (ap_cfg->wep_cfg.key0.is_default)
- pkey = &sys_cfg->wep_cfg.key0;
- if (ap_cfg->wep_cfg.key1.is_default)
- pkey = &sys_cfg->wep_cfg.key1;
- if (ap_cfg->wep_cfg.key2.is_default)
- pkey = &sys_cfg->wep_cfg.key2;
- if (ap_cfg->wep_cfg.key3.is_default)
- pkey = &sys_cfg->wep_cfg.key3;
- }
-
sys_cfg->protocol = PROTOCOL_STATIC_WEP;
memcpy(pkey->key, extra, dwrq->length);
/* Set the length */
@@ -881,7 +865,7 @@ woal_set_encode_ext(struct net_device *dev,
ENTER();
key_index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- if (key_index < 0 || key_index > 3) {
+ if (key_index < 0 || key_index > 5) {
ret = -EINVAL;
goto done;
}
@@ -915,10 +899,12 @@ woal_set_encode_ext(struct net_device *dev,
pwep_key = &sys_cfg.wep_cfg.key3;
break;
}
- pwep_key->key_index = key_index;
- pwep_key->is_default = MTRUE;
- pwep_key->length = ext->key_len;
- memcpy(pwep_key->key, pkey_material, ext->key_len);
+ if (pwep_key) {
+ pwep_key->key_index = key_index;
+ pwep_key->is_default = MTRUE;
+ pwep_key->length = ext->key_len;
+ memcpy(pwep_key->key, pkey_material, ext->key_len);
+ }
} else {
/* Set GTK/PTK key */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
@@ -949,16 +935,14 @@ woal_set_encode_ext(struct net_device *dev,
SEQ_MAX_SIZE);
}
PRINTM(MIOCTL,
- "set uap wpa key key_index=%d, key_len=%d key_flags=0x%x %02x:%02x:%02x:%02x:%02x:%02x\n",
- key_index, ext->key_len, sec->param.encrypt_key.key_flags,
- sec->param.encrypt_key.mac_addr[0],
- sec->param.encrypt_key.mac_addr[1],
- sec->param.encrypt_key.mac_addr[2],
- sec->param.encrypt_key.mac_addr[3],
- sec->param.encrypt_key.mac_addr[4],
- sec->param.encrypt_key.mac_addr[5]);
+ "set uap wpa key key_index=%d, key_len=%d key_flags=0x%x " MACSTR
+ "\n", key_index, ext->key_len, sec->param.encrypt_key.key_flags,
+ MAC2STR(sec->param.encrypt_key.mac_addr));
DBG_HEXDUMP(MCMD_D, "uap wpa key", pkey_material, ext->key_len);
+#define IW_ENCODE_ALG_AES_CMAC 5
+ if (ext->alg == IW_ENCODE_ALG_AES_CMAC)
+ sec->param.encrypt_key.key_flags |= KEY_FLAG_AES_MCAST_IGTK;
if (MLAN_STATUS_SUCCESS !=
woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
ret = -EFAULT;
@@ -1033,9 +1017,8 @@ woal_set_mlme(struct net_device *dev,
memset(sta_addr, 0, ETH_ALEN);
if ((mlme->cmd == IW_MLME_DEAUTH) || (mlme->cmd == IW_MLME_DISASSOC)) {
memcpy(sta_addr, (t_u8 *) mlme->addr.sa_data, ETH_ALEN);
- PRINTM(MIOCTL, "Deauth station: %02x:%02x:%02x:%02x:%02x:%02x, "
- "reason=%d\n", sta_addr[0], sta_addr[1], sta_addr[2],
- sta_addr[3], sta_addr[4], sta_addr[5], mlme->reason_code);
+ PRINTM(MIOCTL, "Deauth station: " MACSTR ", "
+ "reason=%d\n", MAC2STR(sta_addr), mlme->reason_code);
/* FIXME: For flushing all stations we need to use zero MAC, but right
now the FW does not support this. So, manually delete each one
@@ -1073,8 +1056,8 @@ woal_set_mlme(struct net_device *dev,
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
if (req == NULL) {
- LEAVE();
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto done;
}
bss = (mlan_ds_bss *) req->pbuf;
bss->sub_command = MLAN_OID_UAP_DEAUTH_STA;
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_wext.c b/drivers/net/wireless/sd8797/mlinux/moal_wext.c
index f327c53a9506..073639625f28 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_wext.c
+++ b/drivers/net/wireless/sd8797/mlinux/moal_wext.c
@@ -42,7 +42,7 @@ Change log:
/********************************************************
Global Variables
********************************************************/
-
+extern int hw_test;
/********************************************************
Local Functions
********************************************************/
@@ -321,9 +321,9 @@ woal_get_freq(struct net_device *dev, struct iw_request_info *info,
ret = -EFAULT;
goto done;
}
- fwrq->m = (long) bss->param.bss_chan.freq * 100000;
+ fwrq->m = (long) bss->param.bss_chan.freq;
fwrq->i = (long) bss->param.bss_chan.channel;
- fwrq->e = 1;
+ fwrq->e = 6;
fwrq->flags = IW_FREQ_FIXED;
done:
if (req)
@@ -456,10 +456,8 @@ woal_set_wap(struct net_device *dev, struct iw_request_info *info,
goto done;
}
- PRINTM(MINFO, "ASSOC: WAP: sa_data: %02x:%02x:%02x:%02x:%02x:%02x\n",
- (t_u8) awrq->sa_data[0], (t_u8) awrq->sa_data[1],
- (t_u8) awrq->sa_data[2], (t_u8) awrq->sa_data[3],
- (t_u8) awrq->sa_data[4], (t_u8) awrq->sa_data[5]);
+ PRINTM(MINFO, "ASSOC: WAP: sa_data: " MACSTR "\n",
+ MAC2STR((t_u8 *) awrq->sa_data));
if (MLAN_STATUS_SUCCESS !=
woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
@@ -485,8 +483,6 @@ woal_set_wap(struct net_device *dev, struct iw_request_info *info,
if (bss_info.media_connected == MTRUE) {
if (!memcmp(awrq->sa_data, &bss_info.bssid, ETH_ALEN))
goto done;
- /* disconnect before try to assoicate to the new AP */
- woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
}
memcpy(&ssid_bssid.bssid, awrq->sa_data, ETH_ALEN);
}
@@ -698,6 +694,11 @@ woal_set_power(struct net_device *dev, struct iw_request_info *info,
ENTER();
+ if (hw_test) {
+ PRINTM(MIOCTL, "block set power in hw_test mode\n");
+ LEAVE();
+ return ret;
+ }
disabled = vwrq->disabled;
if (MLAN_STATUS_SUCCESS != woal_set_get_power_mgmt(priv,
@@ -1409,14 +1410,9 @@ woal_set_encode_ext(struct net_device *dev,
sec->param.encrypt_key.key_remove = MTRUE;
sec->param.encrypt_key.key_index = key_index;
sec->param.encrypt_key.key_flags = KEY_FLAG_REMOVE_KEY;
- PRINTM(MIOCTL,
- "Remove key key_index=%d, dwrq->flags=0x%x %02x:%02x:%02x:%02x:%02x:%02x\n",
- key_index, dwrq->flags, sec->param.encrypt_key.mac_addr[0],
- sec->param.encrypt_key.mac_addr[1],
- sec->param.encrypt_key.mac_addr[2],
- sec->param.encrypt_key.mac_addr[3],
- sec->param.encrypt_key.mac_addr[4],
- sec->param.encrypt_key.mac_addr[5]);
+ PRINTM(MIOCTL, "Remove key key_index=%d, dwrq->flags=0x%x " MACSTR "\n",
+ key_index, dwrq->flags,
+ MAC2STR(sec->param.encrypt_key.mac_addr));
} else if (ext->key_len <= MAX_WEP_KEY_SIZE) {
/* Set WEP key */
sec->param.encrypt_key.key_index = key_index;
@@ -1444,14 +1440,9 @@ woal_set_encode_ext(struct net_device *dev,
memcpy(sec->param.encrypt_key.key_material, pkey_material,
ext->key_len);
PRINTM(MIOCTL,
- "set wpa key key_index=%d, key_len=%d key_flags=0x%x %02x:%02x:%02x:%02x:%02x:%02x\n",
- key_index, ext->key_len, sec->param.encrypt_key.key_flags,
- sec->param.encrypt_key.mac_addr[0],
- sec->param.encrypt_key.mac_addr[1],
- sec->param.encrypt_key.mac_addr[2],
- sec->param.encrypt_key.mac_addr[3],
- sec->param.encrypt_key.mac_addr[4],
- sec->param.encrypt_key.mac_addr[5]);
+ "set wpa key key_index=%d, key_len=%d key_flags=0x%x " MACSTR
+ "\n", key_index, ext->key_len, sec->param.encrypt_key.key_flags,
+ MAC2STR(sec->param.encrypt_key.mac_addr));
DBG_HEXDUMP(MCMD_D, "wpa key", pkey_material, ext->key_len);
#define IW_ENCODE_ALG_AES_CMAC 5
if (ext->alg == IW_ENCODE_ALG_AES_CMAC)
@@ -1979,7 +1970,8 @@ woal_set_priv(struct net_device *dev, struct iw_request_info *info,
PRINTM(MIOCTL, "SIOCSIWPRIV requst = %s\n", buf);
if (strncmp(buf, "RSSILOW-THRESHOLD", strlen("RSSILOW-THRESHOLD")) == 0) {
pdata = buf + strlen("RSSILOW-THRESHOLD") + 1;
- if (MLAN_STATUS_SUCCESS != woal_set_rssi_low_threshold(priv, pdata)) {
+ if (MLAN_STATUS_SUCCESS !=
+ woal_set_rssi_low_threshold(priv, pdata, MOAL_IOCTL_WAIT)) {
ret = -EFAULT;
goto done;
}
@@ -2045,9 +2037,11 @@ woal_set_priv(struct net_device *dev, struct iw_request_info *info,
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "POWERMODE", strlen("POWERMODE")) == 0) {
pdata = buf + strlen("POWERMODE") + 1;
- if (MLAN_STATUS_SUCCESS != woal_set_powermode(priv, pdata)) {
- ret = -EFAULT;
- goto done;
+ if (!hw_test) {
+ if (MLAN_STATUS_SUCCESS != woal_set_powermode(priv, pdata)) {
+ ret = -EFAULT;
+ goto done;
+ }
}
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "COUNTRY", strlen("COUNTRY")) == 0) {
@@ -2106,7 +2100,7 @@ woal_set_priv(struct net_device *dev, struct iw_request_info *info,
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "BGSCAN-STOP", strlen("BGSCAN-STOP")) == 0) {
if (priv->bg_scan_start && !priv->scan_cfg.rssi_threshold) {
- if (MLAN_STATUS_SUCCESS != woal_stop_bg_scan(priv)) {
+ if (MLAN_STATUS_SUCCESS != woal_stop_bg_scan(priv, MOAL_IOCTL_WAIT)) {
ret = -EFAULT;
goto done;
}
@@ -2144,7 +2138,7 @@ woal_set_priv(struct net_device *dev, struct iw_request_info *info,
len = sprintf(buf, "OK\n") + 1;
} else if (strncmp(buf, "QOSINFO", strlen("QOSINFO")) == 0) {
pdata = buf + strlen("QOSINFO") + 1;
- if (MLAN_STATUS_SUCCESS != woal_set_qos_cfg(priv, pdata)) {
+ if (MLAN_STATUS_SUCCESS != woal_priv_qos_cfg(priv, MLAN_ACT_SET, pdata)) {
ret = -EFAULT;
goto done;
}
@@ -2334,6 +2328,10 @@ woal_set_essid(struct net_device *dev, struct iw_request_info *info,
PRINTM(MINFO, "Requested new SSID = %s\n", (char *) req_ssid.ssid);
memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(mlan_802_11_ssid));
+ if (MTRUE == woal_is_connected(priv, &ssid_bssid)) {
+ PRINTM(MIOCTL, "Already connect to the network\n");
+ goto setessid_ret;
+ }
if (dwrq->flags != 0xFFFF) {
if (MLAN_STATUS_SUCCESS != woal_find_essid(priv, &ssid_bssid)) {
@@ -2348,9 +2346,10 @@ woal_set_essid(struct net_device *dev, struct iw_request_info *info,
}
- /* disconnect before try to associate */
- woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
mode = woal_get_mode(priv, MOAL_IOCTL_WAIT);
+ if (mode == IW_MODE_ADHOC)
+ /* disconnect before try to associate */
+ woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
if (mode != IW_MODE_ADHOC) {
if (MLAN_STATUS_SUCCESS !=
@@ -2523,7 +2522,7 @@ woal_get_scan(struct net_device *dev, struct iw_request_info *info,
break;
}
if (!scan_table[i].freq) {
- PRINTM(MERROR, "Invalid channel number %d\n",
+ PRINTM(MWARN, "Invalid channel number %d\n",
(int) scan_table[i].channel);
continue;
}
@@ -2555,7 +2554,7 @@ woal_get_scan(struct net_device *dev, struct iw_request_info *info,
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev =
IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe,
- (t_s8 *) scan_table[i].ssid.ssid);
+ (char *) scan_table[i].ssid.ssid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -2572,8 +2571,8 @@ woal_get_scan(struct net_device *dev, struct iw_request_info *info,
/* Frequency */
iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = (long) scan_table[i].freq * 100000;
- iwe.u.freq.e = 1;
+ iwe.u.freq.m = (long) scan_table[i].freq;
+ iwe.u.freq.e = 6;
iwe.u.freq.flags = IW_FREQ_FIXED;
iwe.len = IW_EV_FREQ_LEN;
current_ev =
@@ -2865,7 +2864,7 @@ static const iw_handler woal_private_handler[] = {
* @return N/A
*/
void
-woal_send_iwevcustom_event(moal_private * priv, t_s8 * str)
+woal_send_iwevcustom_event(moal_private * priv, char *str)
{
union iwreq_data iwrq;
char buf[IW_CUSTOM_MAX];
@@ -3009,10 +3008,12 @@ woal_get_wireless_stats(struct net_device *dev)
/* Send RSSI command to get beacon RSSI/NF, valid only if associated */
if (priv->media_connected == MTRUE) {
- woal_get_signal_info(priv, wait_option, NULL);
- priv->w_stats.qual.qual = woal_rssi_to_quality((t_s16)
- (priv->w_stats.qual.
- level - 0x100));
+ if (MLAN_STATUS_SUCCESS ==
+ woal_get_signal_info(priv, wait_option, NULL)) {
+ priv->w_stats.qual.qual =
+ woal_rssi_to_quality((t_s16)
+ (priv->w_stats.qual.level - 0x100));
+ }
}
#if WIRELESS_EXT > 18
priv->w_stats.qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM);
diff --git a/drivers/net/wireless/sd8797/mlinux/moal_wext.h b/drivers/net/wireless/sd8797/mlinux/moal_wext.h
index cf1ebc4beccf..5a69c25eeb5e 100644
--- a/drivers/net/wireless/sd8797/mlinux/moal_wext.h
+++ b/drivers/net/wireless/sd8797/mlinux/moal_wext.h
@@ -27,70 +27,6 @@ Change log:
#ifndef _WOAL_WEXT_H_
#define _WOAL_WEXT_H_
-/** Custom event : AdHoc link sensed */
-#define CUS_EVT_ADHOC_LINK_SENSED "EVENT=ADHOC_LINK_SENSED"
-/** Custom event : AdHoc link lost */
-#define CUS_EVT_ADHOC_LINK_LOST "EVENT=ADHOC_LINK_LOST"
-/** Custom event : MIC failure, unicast */
-#define CUS_EVT_MLME_MIC_ERR_UNI "MLME-MICHAELMICFAILURE.indication unicast "
-/** Custom event : MIC failure, multicast */
-#define CUS_EVT_MLME_MIC_ERR_MUL "MLME-MICHAELMICFAILURE.indication multicast "
-/** Custom event : Beacon RSSI low */
-#define CUS_EVT_BEACON_RSSI_LOW "EVENT=BEACON_RSSI_LOW"
-/** Custom event : Beacon SNR low */
-#define CUS_EVT_BEACON_SNR_LOW "EVENT=BEACON_SNR_LOW"
-/** Custom event : Beacon RSSI high */
-#define CUS_EVT_BEACON_RSSI_HIGH "EVENT=BEACON_RSSI_HIGH"
-/** Custom event : Beacon SNR high */
-#define CUS_EVT_BEACON_SNR_HIGH "EVENT=BEACON_SNR_HIGH"
-/** Custom event : Max fail */
-#define CUS_EVT_MAX_FAIL "EVENT=MAX_FAIL"
-/** Custom event : Data RSSI low */
-#define CUS_EVT_DATA_RSSI_LOW "EVENT=DATA_RSSI_LOW"
-/** Custom event : Data SNR low */
-#define CUS_EVT_DATA_SNR_LOW "EVENT=DATA_SNR_LOW"
-/** Custom event : Data RSSI high */
-#define CUS_EVT_DATA_RSSI_HIGH "EVENT=DATA_RSSI_HIGH"
-/** Custom event : Data SNR high */
-#define CUS_EVT_DATA_SNR_HIGH "EVENT=DATA_SNR_HIGH"
-/** Custom event : Link Quality */
-#define CUS_EVT_LINK_QUALITY "EVENT=LINK_QUALITY"
-/** Custom event : Port Release */
-#define CUS_EVT_PORT_RELEASE "EVENT=PORT_RELEASE"
-/** Custom event : Pre-Beacon Lost */
-#define CUS_EVT_PRE_BEACON_LOST "EVENT=PRE_BEACON_LOST"
-
-/** Custom event : Deep Sleep awake */
-#define CUS_EVT_DEEP_SLEEP_AWAKE "EVENT=DS_AWAKE"
-
-/** Custom event : Host Sleep activated */
-#define CUS_EVT_HS_ACTIVATED "HS_ACTIVATED "
-/** Custom event : Host Sleep deactivated */
-#define CUS_EVT_HS_DEACTIVATED "HS_DEACTIVATED "
-/** Custom event : Host Sleep wakeup */
-#define CUS_EVT_HS_WAKEUP "HS_WAKEUP"
-
-/** Custom event : WEP ICV error */
-#define CUS_EVT_WEP_ICV_ERR "EVENT=WEP_ICV_ERR"
-
-/** Custom event : Channel Switch Announcment */
-#define CUS_EVT_CHANNEL_SWITCH_ANN "EVENT=CHANNEL_SWITCH_ANN"
-
-/** Custom event : BW changed */
-#define CUS_EVT_BW_CHANGED "EVENT=BW_CHANGED"
-/** Custom event : OBSS scan parameter */
-#define CUS_EVT_OBSS_SCAN_PARAM "EVENT=OBSS_SCAN_PARAM"
-/** Custom indiciation message sent to the application layer for WMM changes */
-#define WMM_CONFIG_CHANGE_INDICATION "WMM_CONFIG_CHANGE.indication"
-
-#ifdef UAP_SUPPORT
-#ifdef UAP_WEXT
-/** Custom event : STA connected */
-#define CUS_EVT_STA_CONNECTED "EVENT=STA_CONNECTED"
-/** Custom event : STA disconnected */
-#define CUS_EVT_STA_DISCONNECTED "EVENT=STA_DISCONNECTED"
-#endif
-#endif
/** NF value for default scan */
#define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96)