summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-08-20 06:08:08 -0600
committerLinux Build Service Account <lnxbuild@localhost>2016-08-20 06:08:08 -0600
commitf2a58117fced98819db0e88932e7d0daba154de6 (patch)
tree015486ad2ee59c837fe4599fa3e242d77c554e5e
parent74c7f0da5cae60b0499f842105e44f4f1a7c1c0c (diff)
parent2807f3d22e432eb66d11ec755850a24e6ce5f88a (diff)
Promotion of wlan-cld3.driver.lnx.1.1-00081.
CRs Change ID Subject -------------------------------------------------------------------------------------------------------------- 1036775 I5f424a043535b0fdcc7886ba062b34fbc2e6dca0 qcacld-3.0: Print correct no.of channels 971886 I16ab508f74068f7ca1452c97c6105a1ae6e38ef0 qcacld-3.0: free the memory for ch_list while unloading 1050754 Ic0489f7fca3519964b12aa5f272bd66a4d02115c qcacld-3.0: Provide sequence control information to user 688141 Iea866eec216ff827b53869454df616934852120a Release 5.1.0.23N 1019037 I3c83991f56be34412f3f10adf58bd991ecb536ca qcacld-3.0: Dump header info for first data packet after 932749 I328855decbad20dbd88b48022e466e4f78f5d722 qcacld-3.0: Fix to encrypt broadcast frames 971505 I1c9b183c460e1401bd1ee2631489c57778ec665b qcacld-3.0: Avoid race condition in antenna switch opera 688141 I5d82962af91661bd6ab69a36784180e032e99211 Release 5.1.0.23L 1033224 Ida2e20fe08af3c6ed426822a71db1fd6854a0bea qcacld-3.0: Delete PMF Sta from previous vdev 1026370 I23ab8fe0f05245b38cf4b37e93da8fd99d4c1f68 qcacld-3.0: Changes to support different rx data path 1038593 I2ea9ae2aa5c6f1bbec65b724de35a0071ea26804 qcacld-3.0: Change print type from %d to %u for unsigned 1017824 Iede759dfabdc971309f3d1f68411d241f415b422 qcacld-3.0: Remove 11P channels from channel list in PNO 1051920 I849317c699ffca1e057c4e59747e08535baca381 qcacld-3.0: Fix host debug message flooding for unicast 1044060 I7a6aa92351e0140b78c9d7b95f2a6cca45f8e387 qcacld-3.0: Add ndp_ctx NULL check in error scenario 1055093 If1e23ed41987a1f8b40cfae6504f6b69f8a06932 qcacld-3.0: Disable suspend/resume unit test framework i 1042027 Ia165e2f8611830f26c6e466f74bb5e32fc8822e8 qcacld-3.0: Validate the memory allocation for the bpf p 1042048 Idbb69bcbef6cb54df334c30419dc0f7015466f28 qcacld-3.0: Fix potential NULL dereference in ol_txrx_ip 688141 I5d684de1663405265674bbbf42d8ebeb604853fb Release 5.1.0.23M 1022454 Id2ea9b08bdcbc62b1d96d983d19bcf71becc9c42 qcacld-3.0: Parse tx packets only once in tx datapath 975402 I399204261fa3d8515146c590630a3bb663ee801c qcacld-3.0: Move scan_results_available from bucket comp 1046753 I42c0a16ec00c560b1cec1f355db3e15cd15adee5 qcacld-3.0: Update pld_soc_info structure 1050754 I16ca3013147c549acc1b0758c268af717166ac57 qcacld-3.0: Fix incorrect compilation flag termination 994435 If0367e0a7910d7ee460709fc8ae25ecc6de3485d qcacld-3.0: add NULL check and drop rx indication for a 1052652 Ie22800e07bbeef65c43f9171de828533b982a06b qcacld-3.0: Ensure MAS commands to be made PDEV specific 945566 Ie7bf202c47d0282019730448096d91c7dc888e34 qcacld-3.0: Don't return max connection error before doi 688141 I5dda077d8a1160e20b91077856dc7be7a89c9543 Release 5.1.0.23Q 1048793 I9a8f2035b590a90415fbc5a0a6608c48bbd5b2e5 qcacld-3.0: Update wma_get_channels as per the latest dr 985226 I29e15d51ec306071fc9f5ff7e3565c75814944e8 qcacld-3.0: Send WLAN off event to WLS at the end of WLA 1056957 I0364d8a58f272f3646b913063f6484c83c2b7985 qcacld-3.0: Remove platform stub files 688141 I2972bfd1d092b01c9d819afe64c6a14bbaab0de9 Release 5.1.0.23J 688141 I384e3faaaff18c51d750542f45ab1a1f3cd7ca96 Release 5.1.0.23R 1043939 I1578aa5322af50f0ae43248c48a2f754ea081970 qcacld-3.0: Dump more WoW wakeup packet info 1019037 I4f39d93e8aeb243ec3df5cc1a916aec0a1aa4819 qcacld-3.0: Dump header info for first mgmt. packet afte 688141 I5db783be1a0d9568d335588cee0b49a82734721a Release 5.1.0.23O 688141 I1af1099fb2be6547036ffc2d60d841d4b4e51af6 Release 5.1.0.23K 1017887 I63b6f413964cc53f2f25496fef40f99c4244293a qcacld-3.0: Don't populate TDLS IE's in extended capabil 1003326 I4ae24a1813ac5d4738022b2f15a93736c2f05978 qcacld-3.0: Fix to remove 11P channels from channel list 1047382 I602d399e1ef34077b5d7bfc867fb60678ed8612c qcacld-3.0: Changes to update mac_id in packetlog 1047259 Icd293993e84ab4daa98430db231b8b73e082cd29 qcacld-3.0: Provide PLD API for getting IRQ number 1055033 Ia110916f5d657db6970f988dab5c3be55074c3bf qcacld-3.0: Add INI item to control BPF feature configur 1047629 I4ecc901558bc526c99f8b9bdb9442a4d288b313c qcacld-3.0: Add feature of auto-generate mac address 688141 Ie16a5163c716d5bd9fc0ee211ab206079218d6c4 Release 5.1.0.23P 1023457 Ic521c23b4001f15a382e9435413cdafca0c8b49f qcacld-3.0: Add argument to ol_tx_queue_free for vdev or 960456 Ib37ce7cef5b3ce9d9ee4ebdc5ea9bcadaad7b695 qcacld-3.0: Enhance EXTSCAN feature 1053626 I8ccc7172df9d89aaa09ad924ced7f8ed5a6ace13 qcacld-3.0: Remove duplicate OBSS start scan request 1045912 Ie10a8ccd3cc16d48fa509ece997f9098fce52c55 qcacld-3.0: Allocate memory for wlan_mac.bin Change-Id: I3b1490073155b10efa275671d6ccc97e1b6d01bf CRs-Fixed: 1038593, 1044060, 945566, 1017824, 1003326, 960456, 1022454, 1042048, 1052652, 1050754, 1045912, 1046753, 1048793, 1056957, 1047382, 1042027, 1019037, 932749, 1033224, 971886, 971505, 1036775, 688141, 1017887, 1053626, 1026370, 1043939, 994435, 985226, 1051920, 1055033, 975402, 1047629, 1055093, 1047259, 1023457
-rw-r--r--Kbuild11
-rw-r--r--core/cds/inc/cds_concurrency.h4
-rw-r--r--core/cds/inc/cds_sched.h2
-rw-r--r--core/cds/src/cds_api.c3
-rw-r--r--core/cds/src/cds_concurrency.c299
-rw-r--r--core/dp/txrx/ol_rx.c31
-rw-r--r--core/dp/txrx/ol_rx_reorder.c8
-rw-r--r--core/dp/txrx/ol_tx.c6
-rw-r--r--core/dp/txrx/ol_tx_classify.c6
-rw-r--r--core/dp/txrx/ol_tx_queue.c14
-rw-r--r--core/dp/txrx/ol_tx_queue.h10
-rw-r--r--core/dp/txrx/ol_txrx.c23
-rw-r--r--core/dp/txrx/ol_txrx.h1
-rw-r--r--core/dp/txrx/ol_txrx_types.h7
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h91
-rw-r--r--core/hdd/inc/wlan_hdd_main.h5
-rw-r--r--core/hdd/inc/wlan_hdd_tdls.h12
-rw-r--r--core/hdd/inc/wlan_hdd_tx_rx.h11
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c135
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c47
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.h56
-rw-r--r--core/hdd/src/wlan_hdd_ext_scan.c64
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c23
-rw-r--r--core/hdd/src/wlan_hdd_ioctl.c11
-rw-r--r--core/hdd/src/wlan_hdd_ipa.c9
-rw-r--r--core/hdd/src/wlan_hdd_lro.c2
-rw-r--r--core/hdd/src/wlan_hdd_main.c92
-rw-r--r--core/hdd/src/wlan_hdd_nan_datapath.c5
-rw-r--r--core/hdd/src/wlan_hdd_p2p.c4
-rw-r--r--core/hdd/src/wlan_hdd_power.c4
-rw-r--r--core/hdd/src/wlan_hdd_scan.c42
-rw-r--r--core/hdd/src/wlan_hdd_softap_tx_rx.c13
-rw-r--r--core/hdd/src/wlan_hdd_tdls.c39
-rw-r--r--core/hdd/src/wlan_hdd_tx_rx.c181
-rw-r--r--core/mac/inc/qwlan_version.h4
-rw-r--r--core/mac/inc/sir_api.h43
-rw-r--r--core/mac/src/include/sir_params.h1
-rw-r--r--core/mac/src/pe/lim/lim_process_assoc_req_frame.c9
-rw-r--r--core/mac/src/pe/lim/lim_process_auth_frame.c2
-rw-r--r--core/mac/src/pe/lim/lim_scan_result_utils.c5
-rw-r--r--core/mac/src/pe/sch/sch_beacon_gen.c8
-rw-r--r--core/pld/inc/pld_common.h17
-rw-r--r--core/pld/src/pld_common.c24
-rw-r--r--core/pld/src/pld_snoc.c12
-rw-r--r--core/pld/src/pld_snoc.h5
-rw-r--r--core/sme/inc/csr_api.h13
-rw-r--r--core/sme/inc/sme_api.h2
-rw-r--r--core/sme/src/common/sme_api.c44
-rw-r--r--core/sme/src/csr/csr_api_roam.c45
-rw-r--r--core/utils/nlink/inc/wlan_nlink_common.h26
-rw-r--r--core/utils/pktlog/include/pktlog_ac_i.h7
-rw-r--r--core/utils/pktlog/pktlog_internal.c72
-rw-r--r--core/wma/inc/wma.h30
-rw-r--r--core/wma/inc/wma_types.h1
-rw-r--r--core/wma/src/wma_data.c17
-rw-r--r--core/wma/src/wma_features.c500
-rw-r--r--core/wma/src/wma_main.c24
-rw-r--r--core/wma/src/wma_mgmt.c5
-rw-r--r--core/wma/src/wma_scan_roam.c48
-rw-r--r--uapi/linux/pktlog_ac_fmt.h17
60 files changed, 1846 insertions, 406 deletions
diff --git a/Kbuild b/Kbuild
index 9edbedd42457..e9909d190d1e 100644
--- a/Kbuild
+++ b/Kbuild
@@ -794,8 +794,6 @@ HTC_OBJS := $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc.o \
########### HIF ###########
HIF_DIR := hif
HIF_CE_DIR := $(HIF_DIR)/src/ce
-HIF_CNSS_STUB_DIR := $(HIF_DIR)/src/icnss_stub
-
HIF_DISPATCHER_DIR := $(HIF_DIR)/src/dispatcher
@@ -809,9 +807,7 @@ HIF_SDIO_NATIVE_SRC_DIR := $(HIF_SDIO_NATIVE_DIR)/src
HIF_INC := -I$(WLAN_COMMON_INC)/$(HIF_DIR)/inc \
-I$(WLAN_COMMON_INC)/$(HIF_DIR)/src \
- -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR) \
- -I$(WLAN_COMMON_INC)/$(HIF_CNSS_STUB_DIR)
-
+ -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR)
ifeq ($(CONFIG_HIF_PCI), 1)
HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
@@ -851,10 +847,6 @@ HIF_SDIO_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_sdio_send.o \
HIF_SDIO_NATIVE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/hif.o \
$(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/hif_scatter.o
-ifneq ($(CONFIG_ICNSS), y)
-HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_CNSS_STUB_DIR)/icnss_stub.o
-endif
-
ifeq ($(CONFIG_WLAN_NAPI), y)
HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_napi.o
endif
@@ -1249,7 +1241,6 @@ endif
ifeq ($(CONFIG_HIF_SNOC), 1)
CDEFINES += -DHIF_SNOC
-CDEFINES += -DWLAN_SUSPEND_RESUME_TEST
endif
#Enable High Latency related Flags
diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h
index e04698a8749e..bb992eff76f9 100644
--- a/core/cds/inc/cds_concurrency.h
+++ b/core/cds/inc/cds_concurrency.h
@@ -774,6 +774,10 @@ QDF_STATUS cds_register_sap_restart_channel_switch_cb(
void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t));
QDF_STATUS cds_deregister_sap_restart_channel_switch_cb(void);
#endif
+QDF_STATUS cds_get_mac_id_by_session_id(uint8_t session_id, uint8_t *mac_id);
+QDF_STATUS cds_get_mcc_session_id_on_mac(uint8_t mac_id, uint8_t session_id,
+ uint8_t *mcc_session_id);
+uint8_t cds_get_mcc_operating_channel(uint8_t session_id);
QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode,
uint8_t *pcl_ch, uint32_t *len,
uint8_t *weight_list, uint32_t weight_len);
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index 0a269007a4fc..dfed8a8ccc15 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -310,6 +310,8 @@ typedef struct _cds_context_type {
void (*sme_get_nss_for_vdev)(void*, enum tQDF_ADAPTER_MODE,
uint8_t *, uint8_t *);
+ void (*ol_txrx_update_mac_id)(uint8_t , uint8_t);
+
/* This list is not sessionized. This mandatory channel list would be
* as per OEMs preference as per the regulatory/other considerations.
* So, this would remain same for all the interfaces.
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index c9d66cbd636f..998853eec11b 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -307,7 +307,6 @@ QDF_STATUS cds_open(void)
}
/*Open the WMA module */
-
qdf_status = wma_open(gp_cds_context,
hdd_update_tgt_cfg,
hdd_dfs_indicate_radar, cds_cfg);
@@ -379,6 +378,8 @@ QDF_STATUS cds_open(void)
goto err_sme_close;
}
+ gp_cds_context->ol_txrx_update_mac_id = ol_txrx_update_mac_id;
+
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
"%s: CDS successfully Opened", __func__);
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index 24bd5278ffe3..c8781fc0a37a 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -2129,6 +2129,14 @@ static void cds_update_conc_list(uint32_t conn_index,
uint32_t vdev_id,
bool in_use)
{
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return;
+ }
+
if (conn_index >= MAX_NUMBER_OF_CONC_CONNECTIONS) {
cds_err("Number of connections exceeded conn_index: %d",
conn_index);
@@ -2144,6 +2152,9 @@ static void cds_update_conc_list(uint32_t conn_index,
conc_connection_list[conn_index].in_use = in_use;
cds_dump_connection_status_info();
+ if (cds_ctx->ol_txrx_update_mac_id)
+ cds_ctx->ol_txrx_update_mac_id(vdev_id, mac);
+
}
/**
@@ -7273,8 +7284,7 @@ int32_t cds_set_mcc_p2p_quota(hdd_adapter_t *hostapd_adapater,
uint32_t set_value)
{
uint8_t first_adapter_operating_channel = 0;
- uint8_t second_adapter_opertaing_channel = 0;
- hdd_adapter_t *sta_adapter = NULL;
+ uint8_t second_adapter_operating_channel = 0;
int32_t ret = 0; /* success */
uint32_t concurrent_state = cds_get_concurrency_mode();
@@ -7313,63 +7323,32 @@ int32_t cds_set_mcc_p2p_quota(hdd_adapter_t *hostapd_adapater,
*/
set_value = set_value | first_adapter_operating_channel;
/* Find out the 2nd MCC adapter and its operating channel */
- if (hostapd_adapater->device_mode == QDF_STA_MODE) {
- /*
- * iwpriv cmd was issued on wlan0;
- * get p2p0 vdev channel
- */
- if ((concurrent_state & QDF_P2P_CLIENT_MASK) != 0) {
- /* The 2nd MCC vdev is P2P client */
- sta_adapter = hdd_get_adapter(
- hostapd_adapater->pHddCtx,
- QDF_P2P_CLIENT_MODE);
- } else {
- /* The 2nd MCC vdev is P2P GO */
- sta_adapter = hdd_get_adapter(
- hostapd_adapater->pHddCtx,
- QDF_P2P_GO_MODE);
- }
- } else {
- /*
- * iwpriv cmd was issued on p2p0;
- * get wlan0 vdev channel
- */
- sta_adapter = hdd_get_adapter(hostapd_adapater->pHddCtx,
- QDF_STA_MODE);
- }
- if (sta_adapter != NULL) {
- second_adapter_opertaing_channel =
- hdd_get_operating_channel
- (
- sta_adapter->pHddCtx,
- sta_adapter->device_mode
- );
- cds_info("2nd vdev channel No. is:%d",
- second_adapter_opertaing_channel);
-
- if (second_adapter_opertaing_channel == 0 ||
- first_adapter_operating_channel == 0) {
- cds_err("Invalid channel");
- return -EINVAL;
- }
- /*
- * Now move the time quota and channel number of the
- * 1st adapter to bits 23-16 and bits 15-8 of the bit
- * vector, respectively.
- */
- set_value = set_value << 8;
- /*
- * Store the channel number for 2nd MCC vdev at bits
- * 7-0 of set_value
- */
- set_value = set_value |
- second_adapter_opertaing_channel;
- ret = wma_cli_set_command(hostapd_adapater->sessionId,
- WMA_VDEV_MCC_SET_TIME_QUOTA,
- set_value, VDEV_CMD);
- } else {
- cds_err("NULL adapter handle. Exit");
+ second_adapter_operating_channel =
+ cds_get_mcc_operating_channel(
+ hostapd_adapater->sessionId);
+
+ cds_info("2nd vdev channel No. is:%d",
+ second_adapter_operating_channel);
+
+ if (second_adapter_operating_channel == 0 ||
+ first_adapter_operating_channel == 0) {
+ cds_err("Invalid channel");
+ return -EINVAL;
}
+ /*
+ * Now move the time quota and channel number of the
+ * 1st adapter to bits 23-16 and bits 15-8 of the bit
+ * vector, respectively.
+ */
+ set_value = set_value << 8;
+ /*
+ * Store the channel number for 2nd MCC vdev at bits
+ * 7-0 of set_value
+ */
+ set_value = set_value | second_adapter_operating_channel;
+ ret = wma_cli_set_command(hostapd_adapater->sessionId,
+ WMA_VDEV_MCC_SET_TIME_QUOTA,
+ set_value, VDEV_CMD);
} else {
cds_info("MCC is not active. Exit w/o setting latency");
}
@@ -7423,9 +7402,8 @@ int32_t cds_go_set_mcc_p2p_quota(hdd_adapter_t *hostapd_adapter,
uint32_t set_value)
{
uint8_t first_adapter_operating_channel = 0;
- uint8_t second_adapter_opertaing_channel = 0;
+ uint8_t second_adapter_operating_channel = 0;
uint32_t concurrent_state = 0;
- hdd_adapter_t *sta_adapter = NULL;
int32_t ret = 0; /* success */
/*
@@ -7464,66 +7442,36 @@ int32_t cds_go_set_mcc_p2p_quota(hdd_adapter_t *hostapd_adapter,
* the lower 8-bits of bit vector.
*/
set_value = set_value | first_adapter_operating_channel;
- if (hostapd_adapter->device_mode ==
- QDF_STA_MODE) {
- /* iwpriv cmd issued on wlan0; get p2p0 vdev chan */
- if ((concurrent_state & QDF_P2P_CLIENT_MASK) != 0) {
- /* The 2nd MCC vdev is P2P client */
- sta_adapter = hdd_get_adapter
- (
- hostapd_adapter->pHddCtx,
- QDF_P2P_CLIENT_MODE
- );
- } else {
- /* The 2nd MCC vdev is P2P GO */
- sta_adapter = hdd_get_adapter
- (
- hostapd_adapter->pHddCtx,
- QDF_P2P_GO_MODE
- );
- }
- } else {
- /* iwpriv cmd issued on p2p0; get channel for wlan0 */
- sta_adapter = hdd_get_adapter
- (
- hostapd_adapter->pHddCtx,
- QDF_STA_MODE
- );
- }
- if (sta_adapter != NULL) {
- second_adapter_opertaing_channel =
- hdd_get_operating_channel
- (
- sta_adapter->pHddCtx,
- sta_adapter->device_mode
- );
- cds_info("2nd vdev channel No. is:%d",
- second_adapter_opertaing_channel);
-
- if (second_adapter_opertaing_channel == 0 ||
- first_adapter_operating_channel == 0) {
- cds_err("Invalid channel");
- return -EINVAL;
- }
- /*
- * Move the time quota and operating channel number
- * for the first adapter to bits 23-16 & bits 15-8
- * of set_value vector, respectively.
- */
- set_value = set_value << 8;
- /*
- * Store the channel number for 2nd MCC vdev at bits
- * 7-0 of set_value vector as per the bit format above.
- */
- set_value = set_value |
- second_adapter_opertaing_channel;
- ret = wma_cli_set_command(hostapd_adapter->sessionId,
- WMA_VDEV_MCC_SET_TIME_QUOTA,
- set_value, VDEV_CMD);
- } else {
- cds_err("NULL adapter handle. Exit");
+ /* Find out the 2nd MCC adapter and its operating channel */
+ second_adapter_operating_channel =
+ cds_get_mcc_operating_channel(
+ hostapd_adapter->sessionId);
+
+ cds_info("2nd vdev channel No. is:%d",
+ second_adapter_operating_channel);
+
+ if (second_adapter_operating_channel == 0 ||
+ first_adapter_operating_channel == 0) {
+ cds_err("Invalid channel");
+ return -EINVAL;
}
+
+ /*
+ * Move the time quota and operating channel number
+ * for the first adapter to bits 23-16 & bits 15-8
+ * of set_value vector, respectively.
+ */
+ set_value = set_value << 8;
+ /*
+ * Store the channel number for 2nd MCC vdev at bits
+ * 7-0 of set_value vector as per the bit format above.
+ */
+ set_value = set_value |
+ second_adapter_operating_channel;
+ ret = wma_cli_set_command(hostapd_adapter->sessionId,
+ WMA_VDEV_MCC_SET_TIME_QUOTA,
+ set_value, VDEV_CMD);
} else {
cds_info("MCC is not active. Exit w/o setting latency");
}
@@ -8939,6 +8887,121 @@ void cds_dump_connection_status_info(void)
}
/**
+ * cds_get_mac_id_by_session_id() - Get MAC ID for a given session ID
+ * @session_id: Session ID
+ * @mac_id: Pointer to the MAC ID
+ *
+ * Gets the MAC ID for a given session ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cds_get_mac_id_by_session_id(uint8_t session_id, uint8_t *mac_id)
+{
+ cds_context_type *cds_ctx;
+ uint32_t i;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
+ for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+ if ((conc_connection_list[i].vdev_id == session_id) &&
+ (conc_connection_list[i].in_use)) {
+ *mac_id = conc_connection_list[i].mac;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ return QDF_STATUS_SUCCESS;
+ }
+ }
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * cds_get_mcc_session_id_on_mac() - Get MCC session's ID
+ * @mac_id: MAC ID on which MCC session needs to be found
+ * @session_id: Session with which MCC combination needs to be found
+ * @mcc_session_id: Pointer to the MCC session ID
+ *
+ * Get the session ID of the MCC interface
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cds_get_mcc_session_id_on_mac(uint8_t mac_id, uint8_t session_id,
+ uint8_t *mcc_session_id)
+{
+ cds_context_type *cds_ctx;
+ uint32_t i;
+ uint8_t chan = conc_connection_list[session_id].chan;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
+ for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+ if (conc_connection_list[i].mac != mac_id)
+ continue;
+ if (conc_connection_list[i].vdev_id == session_id)
+ continue;
+ /* Inter band or intra band MCC */
+ if ((conc_connection_list[i].chan != chan) &&
+ (conc_connection_list[i].in_use)) {
+ *mcc_session_id = conc_connection_list[i].vdev_id;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ return QDF_STATUS_SUCCESS;
+ }
+ }
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * cds_get_mcc_operating_channel() - Get the MCC channel
+ * @session_id: Session ID with which MCC is being done
+ *
+ * Gets the MCC channel for a given session ID.
+ *
+ * Return: '0' (INVALID_CHANNEL_ID) or valid channel number
+ */
+uint8_t cds_get_mcc_operating_channel(uint8_t session_id)
+{
+ uint8_t mac_id, mcc_session_id;
+ QDF_STATUS status;
+ uint8_t chan;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return INVALID_CHANNEL_ID;
+ }
+
+ status = cds_get_mac_id_by_session_id(session_id, &mac_id);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ hdd_err("failed to get MAC ID");
+ return INVALID_CHANNEL_ID;
+ }
+
+ status = cds_get_mcc_session_id_on_mac(mac_id, session_id,
+ &mcc_session_id);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ hdd_err("failed to get MCC session ID");
+ return INVALID_CHANNEL_ID;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
+ chan = conc_connection_list[mcc_session_id].chan;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+
+ return chan;
+}
+
+/**
* cds_set_do_hw_mode_change_flag() - Set flag to indicate hw mode change
* @flag: Indicate if hw mode change is required or not
*
diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c
index db52497615f8..d201313ac259 100644
--- a/core/dp/txrx/ol_rx.c
+++ b/core/dp/txrx/ol_rx.c
@@ -64,6 +64,27 @@
void ol_rx_data_process(struct ol_txrx_peer_t *peer,
qdf_nbuf_t rx_buf_list);
+/**
+ * ol_rx_send_pktlog_event() - send rx packetlog event
+ * @pdev: pdev handle
+ * @peer: peer handle
+ * @msdu: skb list
+ *
+ * Return: none
+ */
+void ol_rx_send_pktlog_event(struct ol_txrx_pdev_t *pdev,
+ struct ol_txrx_peer_t *peer, qdf_nbuf_t msdu)
+{
+ struct ol_rx_remote_data data;
+
+ data.msdu = msdu;
+ if (peer)
+ data.mac_id = peer->vdev->mac_id;
+ else
+ data.mac_id = 0;
+
+ wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, pdev, &data);
+}
#ifdef HTT_RX_RESTORE
@@ -508,8 +529,7 @@ ol_rx_indication_handler(ol_txrx_pdev_handle pdev,
/* Pktlog */
#ifdef WDI_EVENT_ENABLE
- wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE,
- pdev, head_msdu);
+ ol_rx_send_pktlog_event(pdev, peer, head_msdu);
#endif
if (msdu_chaining) {
@@ -586,9 +606,8 @@ ol_rx_indication_handler(ol_txrx_pdev_handle pdev,
#ifdef WDI_EVENT_ENABLE
if (status != htt_rx_status_ctrl_mgmt_null) {
/* Pktlog */
- wdi_event_handler(
- WDI_EVENT_RX_DESC_REMOTE, pdev,
- msdu);
+ ol_rx_send_pktlog_event(pdev,
+ peer, head_msdu);
}
#endif
if (status == htt_rx_status_err_inv_peer) {
@@ -1332,7 +1351,7 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
/* Pktlog */
#ifdef WDI_EVENT_ENABLE
- wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, pdev, head_msdu);
+ ol_rx_send_pktlog_event(pdev, peer, head_msdu);
#endif
/* if this is an offload indication, peer id is carried in the
diff --git a/core/dp/txrx/ol_rx_reorder.c b/core/dp/txrx/ol_rx_reorder.c
index 971126004faf..2572ccdc34d0 100644
--- a/core/dp/txrx/ol_rx_reorder.c
+++ b/core/dp/txrx/ol_rx_reorder.c
@@ -82,7 +82,6 @@ static char g_log2ceil[] = {
/*---*/
/* reorder array elements are known to be non-NULL */
-#define OL_RX_REORDER_PTR_CHECK(ptr) /* no-op */
#define OL_RX_REORDER_LIST_APPEND(head_msdu, tail_msdu, rx_reorder_array_elem) \
do { \
if (tail_msdu) { \
@@ -262,15 +261,14 @@ ol_rx_reorder_release(struct ol_txrx_vdev_t *vdev,
head_msdu = rx_reorder_array_elem->head;
tail_msdu = rx_reorder_array_elem->tail;
rx_reorder_array_elem->head = rx_reorder_array_elem->tail = NULL;
- OL_RX_REORDER_PTR_CHECK(head_msdu) {
+ if (head_msdu)
OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid], 1);
- }
idx = (idx_start + 1);
OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask);
while (idx != idx_end) {
rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx];
- OL_RX_REORDER_PTR_CHECK(rx_reorder_array_elem->head) {
+ if (rx_reorder_array_elem->head) {
OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid],
1);
OL_RX_REORDER_LIST_APPEND(head_msdu, tail_msdu,
@@ -282,7 +280,7 @@ ol_rx_reorder_release(struct ol_txrx_vdev_t *vdev,
idx++;
OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask);
}
- OL_RX_REORDER_PTR_CHECK(head_msdu) {
+ if (head_msdu) {
uint16_t seq_num;
htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev;
diff --git a/core/dp/txrx/ol_tx.c b/core/dp/txrx/ol_tx.c
index b2bcbfdaf072..a898f0087d94 100644
--- a/core/dp/txrx/ol_tx.c
+++ b/core/dp/txrx/ol_tx.c
@@ -1215,8 +1215,10 @@ struct ol_tx_desc_t *ol_tx_hl_desc_alloc(struct ol_txrx_pdev_t *pdev,
TXRX_HL_TX_DESC_HI_PRIO_RESERVED) {
tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, msdu_info);
} else if (qdf_nbuf_is_ipv4_pkt(msdu) == true) {
- if ((qdf_nbuf_is_ipv4_dhcp_pkt(msdu) == true) ||
- (qdf_nbuf_is_ipv4_eapol_pkt(msdu) == true)) {
+ if ((QDF_NBUF_CB_GET_PACKET_TYPE(msdu) ==
+ QDF_NBUF_CB_PACKET_TYPE_DHCP) ||
+ (QDF_NBUF_CB_GET_PACKET_TYPE(msdu) ==
+ QDF_NBUF_CB_PACKET_TYPE_EAPOL)) {
tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, msdu_info);
TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
"Provided tx descriptor from reserve pool for DHCP/EAPOL\n");
diff --git a/core/dp/txrx/ol_tx_classify.c b/core/dp/txrx/ol_tx_classify.c
index 1cf50a625e33..b45d24863918 100644
--- a/core/dp/txrx/ol_tx_classify.c
+++ b/core/dp/txrx/ol_tx_classify.c
@@ -428,7 +428,8 @@ ol_tx_classify(
OL_TXRX_PEER_SECURITY_MULTICAST].sec_type
!= htt_sec_type_wapi) &&
(qdf_nbuf_is_ipv4_pkt(tx_nbuf) == true)) {
- if (true == qdf_nbuf_is_ipv4_dhcp_pkt(
+ if (QDF_NBUF_CB_PACKET_TYPE_DHCP ==
+ QDF_NBUF_CB_GET_PACKET_TYPE(
tx_nbuf)) {
/* DHCP frame to go with
* voice priority
@@ -561,7 +562,8 @@ ol_tx_classify(
OL_TXRX_PEER_SECURITY_UNICAST].sec_type
!= htt_sec_type_wapi) &&
(qdf_nbuf_is_ipv4_pkt(tx_nbuf) == true)) {
- if (true == qdf_nbuf_is_ipv4_dhcp_pkt(tx_nbuf))
+ if (QDF_NBUF_CB_PACKET_TYPE_DHCP ==
+ QDF_NBUF_CB_GET_PACKET_TYPE(tx_nbuf))
/* DHCP frame to go with voice priority */
tid = TX_DHCP_TID;
}
diff --git a/core/dp/txrx/ol_tx_queue.c b/core/dp/txrx/ol_tx_queue.c
index b9f348699e1c..7cf2fdfb1aad 100644
--- a/core/dp/txrx/ol_tx_queue.c
+++ b/core/dp/txrx/ol_tx_queue.c
@@ -80,7 +80,7 @@ ol_tx_queue_vdev_flush(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev)
/* flush VDEV TX queues */
for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
txq = &vdev->txqs[i];
- ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS));
+ ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS), false);
}
/* flush PEER TX queues */
do {
@@ -109,7 +109,7 @@ ol_tx_queue_vdev_flush(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev)
for (j = 0; j < OL_TX_NUM_TIDS; j++) {
txq = &peers[i]->txqs[j];
if (txq->frms)
- ol_tx_queue_free(pdev, txq, j);
+ ol_tx_queue_free(pdev, txq, j, true);
}
TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
"%s: Delete Peer %p\n", __func__, peer);
@@ -316,7 +316,7 @@ void
ol_tx_queue_free(
struct ol_txrx_pdev_t *pdev,
struct ol_tx_frms_queue_t *txq,
- int tid)
+ int tid, bool is_peer_txq)
{
int frms = 0, bytes = 0;
struct ol_tx_desc_t *tx_desc;
@@ -339,9 +339,9 @@ ol_tx_queue_free(
txq->frms--;
tx_desc = TAILQ_NEXT(tx_desc, tx_desc_list_elem);
}
- ol_tx_queue_log_free(pdev, txq, tid, frms, bytes);
+ ol_tx_queue_log_free(pdev, txq, tid, frms, bytes, is_peer_txq);
txq->bytes -= bytes;
- ol_tx_queue_log_free(pdev, txq, tid, frms, bytes);
+ ol_tx_queue_log_free(pdev, txq, tid, frms, bytes, is_peer_txq);
txq->flag = ol_tx_queue_empty;
/* txq->head gets reset during the TAILQ_CONCAT call */
TAILQ_CONCAT(&tx_tmp_list, &txq->head, tx_desc_list_elem);
@@ -1503,7 +1503,7 @@ void
ol_tx_queue_log_free(
struct ol_txrx_pdev_t *pdev,
struct ol_tx_frms_queue_t *txq,
- int tid, int frms, int bytes)
+ int tid, int frms, int bytes, bool is_peer_txq)
{
u_int16_t peer_id;
struct ol_tx_log_queue_add_t *log_elem;
@@ -1516,7 +1516,7 @@ ol_tx_queue_log_free(
return;
}
- if (tid < OL_TX_NUM_TIDS) {
+ if ((tid < OL_TX_NUM_TIDS) && is_peer_txq) {
struct ol_txrx_peer_t *peer;
struct ol_tx_frms_queue_t *txq_base;
diff --git a/core/dp/txrx/ol_tx_queue.h b/core/dp/txrx/ol_tx_queue.h
index 56ff9e7d6f68..d3e3080c5d8b 100644
--- a/core/dp/txrx/ol_tx_queue.h
+++ b/core/dp/txrx/ol_tx_queue.h
@@ -76,6 +76,7 @@ ol_tx_queue_log_dequeue(struct ol_txrx_pdev_t *pdev,
* @tid: tid value
* @frms: number of frames for which logs need to be freed
* @bytes: number of bytes
+ * @is_peer_txq - peer queue or not
*
*
* Return: None
@@ -83,7 +84,7 @@ ol_tx_queue_log_dequeue(struct ol_txrx_pdev_t *pdev,
void
ol_tx_queue_log_free(struct ol_txrx_pdev_t *pdev,
struct ol_tx_frms_queue_t *txq,
- int tid, int frms, int bytes);
+ int tid, int frms, int bytes, bool is_peer_txq);
#else
@@ -105,7 +106,7 @@ ol_tx_queue_log_dequeue(struct ol_txrx_pdev_t *pdev,
static inline void
ol_tx_queue_log_free(struct ol_txrx_pdev_t *pdev,
struct ol_tx_frms_queue_t *txq,
- int tid, int frms, int bytes)
+ int tid, int frms, int bytes, bool is_peer_txq)
{
return;
}
@@ -171,12 +172,13 @@ ol_tx_dequeue(
* @param pdev - the physical device object, which stores the txqs
* @param txq - which tx queue to free frames from
* @param tid - the extended TID that the queue belongs to
+ * @param is_peer_txq - peer queue or not
*/
void
ol_tx_queue_free(
struct ol_txrx_pdev_t *pdev,
struct ol_tx_frms_queue_t *txq,
- int tid);
+ int tid, bool is_peer_txq);
/**
* @brief - discard pending tx frames from the tx queue
@@ -224,7 +226,7 @@ static inline void
ol_tx_queue_free(
struct ol_txrx_pdev_t *pdev,
struct ol_tx_frms_queue_t *txq,
- int tid)
+ int tid, bool is_peer_txq)
{
return;
}
diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c
index 4411edfed623..435f3a98e50f 100644
--- a/core/dp/txrx/ol_txrx.c
+++ b/core/dp/txrx/ol_txrx.c
@@ -848,7 +848,7 @@ ol_txrx_vdev_tx_queue_free(struct ol_txrx_vdev_t *vdev)
for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
txq = &vdev->txqs[i];
- ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS));
+ ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS), false);
}
}
@@ -902,7 +902,7 @@ ol_txrx_peer_tx_queue_free(struct ol_txrx_pdev_t *pdev,
for (i = 0; i < OL_TX_NUM_TIDS; i++) {
txq = &peer->txqs[i];
- ol_tx_queue_free(pdev, txq, i);
+ ol_tx_queue_free(pdev, txq, i, true);
}
}
#else
@@ -3783,6 +3783,25 @@ void ol_vdev_rx_set_intrabss_fwd(ol_txrx_vdev_handle vdev, bool val)
vdev->disable_intrabss_fwd = val;
}
+/**
+ * ol_txrx_update_mac_id() - update mac_id for vdev
+ * @vdev_id: vdev id
+ * @mac_id: mac id
+ *
+ * Return: none
+ */
+void ol_txrx_update_mac_id(uint8_t vdev_id, uint8_t mac_id)
+{
+ ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+ if (NULL == vdev) {
+ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+ "%s: Invalid vdev_id %d", __func__, vdev_id);
+ return;
+ }
+ vdev->mac_id = mac_id;
+}
+
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
/**
diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h
index e02647e09144..e4d463db0e9c 100644
--- a/core/dp/txrx/ol_txrx.h
+++ b/core/dp/txrx/ol_txrx.h
@@ -133,4 +133,5 @@ ol_txrx_vdev_handle ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id);
void htt_pkt_log_init(struct ol_txrx_pdev_t *handle, void *scn);
QDF_STATUS ol_txrx_set_wisa_mode(ol_txrx_vdev_handle vdev,
bool enable);
+void ol_txrx_update_mac_id(uint8_t vdev_id, uint8_t mac_id);
#endif /* _OL_TXRX__H_ */
diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h
index 78e16c2414d8..ea1ccc6a3875 100644
--- a/core/dp/txrx/ol_txrx_types.h
+++ b/core/dp/txrx/ol_txrx_types.h
@@ -1060,6 +1060,7 @@ struct ol_txrx_vdev_t {
uint64_t fwd_tx_packets;
uint64_t fwd_rx_packets;
bool is_wisa_mode_enable;
+ uint8_t mac_id;
};
struct ol_rx_reorder_array_elem_t {
@@ -1253,4 +1254,10 @@ struct ol_error_info {
struct ol_mic_error_info mic_err;
} u;
};
+
+struct ol_rx_remote_data {
+ qdf_nbuf_t msdu;
+ uint8_t mac_id;
+};
+
#endif /* _OL_TXRX_TYPES__H_ */
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index b5107787bd7d..8db4b79d4fa8 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -48,6 +48,10 @@
#define FW_MODULE_LOG_LEVEL_STRING_LENGTH (255)
+#define CFG_ENABLE_RX_THREAD (1 << 0)
+#define CFG_ENABLE_RPS (1 << 1)
+#define CFG_ENABLE_NAPI (1 << 2)
+
#ifdef DHCP_SERVER_OFFLOAD
#define IPADDR_NUM_ENTRIES (4)
#define IPADDR_STRING_LENGTH (16)
@@ -2318,12 +2322,6 @@ typedef enum {
#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX (0xFF)
#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0x0F)
-/* This will be used only for debugging purpose, will be removed after sometime */
-#define CFG_ENABLE_RX_THREAD "gEnableRxThread"
-#define CFG_ENABLE_RX_THREAD_MIN (0)
-#define CFG_ENABLE_RX_THREAD_MAX (1)
-#define CFG_ENABLE_RX_THREAD_DEFAULT (1)
-
/* SAR Thermal limit values for 2g and 5g */
#define CFG_SET_TXPOWER_LIMIT2G_NAME "TxPower2g"
@@ -2831,6 +2829,15 @@ typedef enum {
#endif
/*
+ * 0: Disable BPF packet filter
+ * 1: Enable BPF packet filter
+ */
+#define CFG_BPF_PACKET_FILTER_OFFLOAD "gBpfFilterEnable"
+#define CFG_BPF_PACKET_FILTER_OFFLOAD_MIN (0)
+#define CFG_BPF_PACKET_FILTER_OFFLOAD_MAX (1)
+#define CFG_BPF_PACKET_FILTER_OFFLOAD_DEFAULT (1)
+
+/*
* 0: disable the cck tx chain mask (default)
* 1: enable the cck tx chain mask
*/
@@ -2915,11 +2922,6 @@ enum dot11p_mode {
#define CFG_DOT11P_MODE_MIN (WLAN_HDD_11P_DISABLED)
#define CFG_DOT11P_MODE_MAX (WLAN_HDD_11P_CONCURRENT)
-#define CFG_NAPI_NAME "gEnableNAPI"
-#define CFG_NAPI_MIN (0)
-#define CFG_NAPI_MAX (1)
-#define CFG_NAPI_DEFAULT (0)
-
#ifdef FEATURE_WLAN_EXTSCAN
#define CFG_EXTSCAN_PASSIVE_MAX_CHANNEL_TIME_NAME "gExtScanPassiveMaxChannelTime"
#define CFG_EXTSCAN_PASSIVE_MAX_CHANNEL_TIME_MIN (0)
@@ -3408,6 +3410,66 @@ enum dot11p_mode {
#define CFG_SUB_20_CHANNEL_WIDTH_MIN (WLAN_SUB_20_CH_WIDTH_NONE)
#define CFG_SUB_20_CHANNEL_WIDTH_MAX (WLAN_SUB_20_CH_WIDTH_10)
#define CFG_SUB_20_CHANNEL_WIDTH_DEFAULT (WLAN_SUB_20_CH_WIDTH_NONE)
+
+/*
+ * This parameter determines that which defered method will be use in rx path
+ * If no bits are set then rx path processing will happen in tasklet context.
+ * Bit 0: rx_thread enable
+ * Bit 1: RPS enable
+ * Bit 2: NAPI enable
+ */
+#define CFG_RX_MODE_NAME "rx_mode"
+#define CFG_RX_MODE_MIN (0)
+#define CFG_RX_MODE_MAX (CFG_ENABLE_RX_THREAD | CFG_ENABLE_RPS | \
+ CFG_ENABLE_NAPI)
+#ifdef MDM_PLATFORM
+#define CFG_RX_MODE_DEFAULT (0)
+#else
+#define CFG_RX_MODE_DEFAULT (CFG_ENABLE_RX_THREAD | CFG_ENABLE_NAPI)
+#endif
+
+/* List of RPS CPU maps for different rx queues registered by WLAN driver
+ * Ref - Kernel/Documentation/networking/scaling.txt
+ * RPS CPU map for a particular RX queue, selects CPU(s) for bottom half
+ * processing of RX packets. For example, for a system with 4 CPUs,
+ * 0xe: Use CPU1 - CPU3 and donot use CPU0.
+ * 0x0: RPS is disabled, packets are processed on the interrupting CPU.
+.*
+ * WLAN driver registers NUM_TX_QUEUES queues for tx and rx each during
+ * alloc_netdev_mq. Hence, we need to have a cpu mask for each of the rx queues.
+ *
+ * For example, if the NUM_TX_QUEUES is 4, a sample WLAN ini entry may look like
+ * rpsRxQueueCpuMapList=a b c d
+ * For a 4 CPU system (CPU0 - CPU3), this implies:
+ * 0xa - (1010) use CPU1, CPU3 for rx queue 0
+ * 0xb - (1011) use CPU0, CPU1 and CPU3 for rx queue 1
+ * 0xc - (1100) use CPU2, CPU3 for rx queue 2
+ * 0xd - (1101) use CPU0, CPU2 and CPU3 for rx queue 3
+
+ * In practice, we may want to avoid the cores which are heavily loaded.
+ */
+
+/* Name of the ini file entry to specify RPS map for different RX queus */
+#define CFG_RPS_RX_QUEUE_CPU_MAP_LIST_NAME "rpsRxQueueCpuMapList"
+
+/* Default value of rpsRxQueueCpuMapList. Different platforms may have
+ * different configurations for NUM_TX_QUEUES and # of cpus, and will need to
+ * configure an appropriate value via ini file. Setting default value to 'e' to
+ * avoid use of CPU0 (since its heavily used by other system processes) by rx
+ * queue 0, which is currently being used for rx packet processing.
+ */
+#define CFG_RPS_RX_QUEUE_CPU_MAP_LIST_DEFAULT "e"
+
+/* Maximum length of string used to hold a list of cpu maps for various rx
+ * queues. Considering a 16 core system with 5 rx queues, a RPS CPU map
+ * list may look like -
+ * rpsRxQueueCpuMapList = ffff ffff ffff ffff ffff
+ * (all 5 rx queues can be processed on all 16 cores)
+ * max string len = 24 + 1(for '\0'). Considering 30 to be on safe side.
+ */
+#define CFG_RPS_RX_QUEUE_CPU_MAP_LIST_LEN 30
+
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -3847,7 +3909,6 @@ struct hdd_config {
uint32_t TxPower2g;
uint32_t TxPower5g;
uint32_t gEnableDebugLog;
- uint8_t enableRxThread;
bool fDfsPhyerrFilterOffload;
uint8_t gSapPreferredChanLocation;
uint8_t gDisableDfsJapanW53;
@@ -3992,15 +4053,15 @@ struct hdd_config {
bool tso_enable;
bool lro_enable;
bool active_mode_offload;
+ bool bpf_packet_filter_enable;
uint32_t fine_time_meas_cap;
uint8_t max_scan_count;
#ifdef WLAN_FEATURE_FASTPATH
bool fastpath_enable;
#endif
uint8_t dot11p_mode;
-#ifdef FEATURE_NAPI
- bool napi_enable;
-#endif
+ uint8_t rx_mode;
+ uint8_t cpu_map_list[CFG_RPS_RX_QUEUE_CPU_MAP_LIST_LEN];
#ifdef FEATURE_WLAN_EXTSCAN
uint32_t extscan_passive_max_chn_time;
uint32_t extscan_passive_min_chn_time;
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 52ef85032526..b42f2fa81528 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1298,6 +1298,8 @@ struct hdd_context_s {
bool enable_tdls_connection_tracker;
uint8_t tdls_external_peer_count;
bool tdls_nss_switch_in_progress;
+ bool tdls_nss_teardown_complete;
+ enum tdls_nss_transition_type tdls_nss_transition_mode;
int32_t tdls_teardown_peers_cnt;
struct tdls_set_state_info set_state_info;
#endif
@@ -1462,6 +1464,9 @@ struct hdd_context_s {
qdf_mc_timer_t iface_change_timer;
/* Interface change lock */
struct mutex iface_change_lock;
+ bool rps;
+ bool enableRxThread;
+ bool napi_enable;
};
/*---------------------------------------------------------------------------
diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h
index 4273d722ea36..0985d1af6e05 100644
--- a/core/hdd/inc/wlan_hdd_tdls.h
+++ b/core/hdd/inc/wlan_hdd_tdls.h
@@ -145,6 +145,18 @@ enum tdls_spatial_streams {
};
/**
+ * enum tdls_nss_transition_type - TDLS NSS transition states
+ * @TDLS_NSS_TRANSITION_UNKNOWN: default state
+ * @TDLS_NSS_TRANSITION_2x2_to_1x1: transition from 2x2 to 1x1 stream
+ * @TDLS_NSS_TRANSITION_1x1_to_2x2: transition from 1x1 to 2x2 stream
+ */
+enum tdls_nss_transition_type {
+ TDLS_NSS_TRANSITION_UNKNOWN = 0,
+ TDLS_NSS_TRANSITION_2x2_to_1x1,
+ TDLS_NSS_TRANSITION_1x1_to_2x2,
+};
+
+/**
* enum tTDLSCapType - tdls capability type
*
* @eTDLS_CAP_NOT_SUPPORTED: tdls not supported
diff --git a/core/hdd/inc/wlan_hdd_tx_rx.h b/core/hdd/inc/wlan_hdd_tx_rx.h
index 5d193cee68af..406b35344b24 100644
--- a/core/hdd/inc/wlan_hdd_tx_rx.h
+++ b/core/hdd/inc/wlan_hdd_tx_rx.h
@@ -113,4 +113,15 @@ const char *hdd_action_type_to_string(enum netif_action_type action);
void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
enum netif_action_type action, enum netif_reason_type reason);
int hdd_set_mon_rx_cb(struct net_device *dev);
+void hdd_send_rps_ind(hdd_adapter_t *adapter);
+void wlan_hdd_classify_pkt(struct sk_buff *skb);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void hdd_event_eapol_log(struct sk_buff *skb, enum qdf_proto_dir dir);
+#else
+static inline
+void hdd_event_eapol_log(struct sk_buff *skb, enum qdf_proto_dir dir)
+{}
+#endif
+
#endif /* end #if !defined(WLAN_HDD_TX_RX_H) */
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index b7d6ba15f2fa..6b38770d723c 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -2870,13 +2870,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN,
CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX),
- REG_VARIABLE(CFG_ENABLE_RX_THREAD, WLAN_PARAM_Integer,
- struct hdd_config, enableRxThread,
- VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
- CFG_ENABLE_RX_THREAD_DEFAULT,
- CFG_ENABLE_RX_THREAD_MIN,
- CFG_ENABLE_RX_THREAD_MAX),
-
REG_VARIABLE(CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME,
WLAN_PARAM_Integer,
struct hdd_config, fDfsPhyerrFilterOffload,
@@ -3532,6 +3525,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_LRO_ENABLED_MIN,
CFG_LRO_ENABLED_MAX),
+ REG_VARIABLE(CFG_BPF_PACKET_FILTER_OFFLOAD, WLAN_PARAM_Integer,
+ struct hdd_config, bpf_packet_filter_enable,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_BPF_PACKET_FILTER_OFFLOAD_DEFAULT,
+ CFG_BPF_PACKET_FILTER_OFFLOAD_MIN,
+ CFG_BPF_PACKET_FILTER_OFFLOAD_MAX),
+
REG_VARIABLE(CFG_ACTIVE_MODE_OFFLOAD, WLAN_PARAM_Integer,
struct hdd_config, active_mode_offload,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -3568,15 +3568,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_DOT11P_MODE_MIN,
CFG_DOT11P_MODE_MAX),
-#ifdef FEATURE_NAPI
- REG_VARIABLE(CFG_NAPI_NAME, WLAN_PARAM_Integer,
- struct hdd_config, napi_enable,
- VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
- CFG_NAPI_DEFAULT,
- CFG_NAPI_MIN,
- CFG_NAPI_MAX),
-#endif /* FEATURE_NAPI */
-
#ifdef FEATURE_WLAN_EXTSCAN
REG_VARIABLE(CFG_EXTSCAN_PASSIVE_MAX_CHANNEL_TIME_NAME,
WLAN_PARAM_Integer,
@@ -3989,6 +3980,19 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ADAPT_DWELL_WIFI_THRESH_MIN,
CFG_ADAPT_DWELL_WIFI_THRESH_MAX),
+ REG_VARIABLE(CFG_RX_MODE_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, rx_mode,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_RX_MODE_DEFAULT,
+ CFG_RX_MODE_MIN,
+ CFG_RX_MODE_MAX),
+
+ REG_VARIABLE_STRING(CFG_RPS_RX_QUEUE_CPU_MAP_LIST_NAME,
+ WLAN_PARAM_String,
+ struct hdd_config, cpu_map_list,
+ VAR_FLAGS_OPTIONAL,
+ (void *)CFG_RPS_RX_QUEUE_CPU_MAP_LIST_DEFAULT),
+
REG_VARIABLE(CFG_INTERFACE_CHANGE_WAIT_NAME, WLAN_PARAM_Integer,
struct hdd_config, iface_change_wait_time,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
@@ -5520,14 +5524,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
"Name = [max_scan_count] value = [%d]",
pHddCtx->config->max_scan_count);
-#ifdef FEATURE_NAPI_DEBUG
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
- "Name = [%s] value = [%d]",
- CFG_ENABLE_RX_THREAD, pHddCtx->config->enableRxThread);
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
"Name = [%s] value = [%d]",
- CFG_NAPI_NAME, pHddCtx->config->napi_enable);
-#endif
+ CFG_RX_MODE_NAME, pHddCtx->config->rx_mode);
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_HIGH,
"Name = [%s] Value = [%u]",
CFG_CE_CLASSIFY_ENABLE_NAME,
@@ -5676,6 +5675,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
hdd_info("Name = [%s] Value = [%s]",
CFG_RM_CAPABILITY_NAME,
pHddCtx->config->rm_capability);
+ hdd_info("Name = [%s] Value = [%d]",
+ CFG_BPF_PACKET_FILTER_OFFLOAD,
+ pHddCtx->config->bpf_packet_filter_enable);
}
@@ -5693,6 +5695,7 @@ QDF_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx)
int status, i = 0;
const struct firmware *fw = NULL;
char *line, *buffer = NULL;
+ char *temp = NULL;
char *name, *value;
tCfgIniEntry macTable[QDF_MAX_CONCURRENCY_PERSONA];
tSirMacAddr customMacAddr;
@@ -5714,7 +5717,17 @@ QDF_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx)
goto config_exit;
}
- buffer = (char *)fw->data;
+ hdd_debug("wlan_mac.bin size %zu", fw->size);
+
+ temp = qdf_mem_malloc(fw->size);
+
+ if (temp == NULL) {
+ hdd_err("fail to alloc memory");
+ qdf_status = QDF_STATUS_E_NOMEM;
+ goto config_exit;
+ }
+ buffer = temp;
+ qdf_mem_copy(buffer, fw->data, fw->size);
/* data format:
* Intf0MacAddress=00AA00BB00CC
@@ -5769,6 +5782,7 @@ QDF_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx)
sme_set_custom_mac_addr(customMacAddr);
config_exit:
+ qdf_mem_free(temp);
release_firmware(fw);
return qdf_status;
}
@@ -5834,6 +5848,30 @@ static void hdd_override_all_ps(hdd_context_t *hdd_ctx)
}
/**
+ * hdd_set_rx_mode_value() - set rx_mode values
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void hdd_set_rx_mode_value(hdd_context_t *hdd_ctx)
+{
+ if (hdd_ctx->config->rx_mode & CFG_ENABLE_RX_THREAD &&
+ hdd_ctx->config->rx_mode & CFG_ENABLE_RPS) {
+ hdd_err("rx_mode wrong configuration. Make it default");
+ hdd_ctx->config->rx_mode = CFG_RX_MODE_DEFAULT;
+ }
+
+ if (hdd_ctx->config->rx_mode & CFG_ENABLE_RX_THREAD)
+ hdd_ctx->enableRxThread = true;
+
+ if (hdd_ctx->config->rx_mode & CFG_ENABLE_RPS)
+ hdd_ctx->rps = true;
+
+ if (hdd_ctx->config->rx_mode & CFG_ENABLE_NAPI)
+ hdd_ctx->napi_enable = true;
+}
+
+/**
* hdd_parse_config_ini() - parse the ini configuration file
* @pHddCtx: the pointer to hdd context
*
@@ -5931,10 +5969,11 @@ QDF_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx)
/* Loop through the registry table and apply all these configs */
qdf_status = hdd_apply_cfg_ini(pHddCtx, cfgIniTable, i);
+ hdd_set_rx_mode_value(pHddCtx);
#ifdef FEATURE_NAPI
if (QDF_STATUS_SUCCESS == qdf_status)
hdd_napi_event(NAPI_EVT_INI_FILE,
- (void *)pHddCtx->config->napi_enable);
+ (void *)pHddCtx->napi_enable);
#endif /* FEATURE_NAPI */
if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
hdd_override_all_ps(pHddCtx);
@@ -6115,6 +6154,54 @@ QDF_STATUS hdd_string_to_u8_array(char *str, uint8_t *array,
}
/**
+ * hdd_hex_string_to_u16_array() - convert a hex string to a uint16 array
+ * @str: input string
+ * @int_array: pointer to input array of type uint16
+ * @len: pointer to number of elements which the function adds to the array
+ * @int_array_max_len: maximum number of elements in input uint16 array
+ *
+ * This function is used to convert a space separated hex string to an array of
+ * uint16_t. For example, an input string str = "a b c d" would be converted to
+ * a unint16 array, int_array = {0xa, 0xb, 0xc, 0xd}, *len = 4.
+ * This assumes that input value int_array_max_len >= 4.
+ *
+ * Return: QDF_STATUS_SUCCESS - if the conversion is successful
+ * non zero value - if the conversion is a failure
+ */
+QDF_STATUS hdd_hex_string_to_u16_array(char *str,
+ uint16_t *int_array, uint8_t *len, uint8_t int_array_max_len)
+{
+ char *s = str;
+ uint32_t val = 0;
+
+ if (str == NULL || int_array == NULL || len == NULL)
+ return QDF_STATUS_E_INVAL;
+
+ hdd_err("str %p intArray %p intArrayMaxLen %d",
+ s, int_array, int_array_max_len);
+
+ *len = 0;
+
+ while ((s != NULL) && (*len < int_array_max_len)) {
+ /*
+ * Increment length only if sscanf successfully extracted one
+ * element. Any other return value means error. Ignore it.
+ */
+ if (sscanf(s, "%x", &val) == 1) {
+ int_array[*len] = (uint16_t) val;
+ hdd_debug("s %p val %x intArray[%d]=0x%x",
+ s, val, *len, int_array[*len]);
+ *len += 1;
+ }
+ s = strpbrk(s, " ");
+ if (s)
+ s++;
+ }
+ return QDF_STATUS_SUCCESS;
+}
+
+
+/**
* hdd_update_config_dat() - scan the string and convery to u8 array
* @str: the pointer to the string
* @intArray: the pointer of buffer to store the u8 value
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index a0f24319c70e..5bcf100a23c2 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -6084,6 +6084,7 @@ static int hdd_set_reset_bpf_offload(hdd_context_t *hdd_ctx,
struct sir_bpf_set_offload *bpf_set_offload;
QDF_STATUS status;
int prog_len;
+ int ret = 0;
ENTER();
@@ -6097,6 +6098,7 @@ static int hdd_set_reset_bpf_offload(hdd_context_t *hdd_ctx,
/* Parse and fetch bpf packet size */
if (!tb[BPF_PACKET_SIZE]) {
hdd_err("attr bpf packet size failed");
+ ret = -EINVAL;
goto fail;
}
bpf_set_offload->total_length = nla_get_u32(tb[BPF_PACKET_SIZE]);
@@ -6109,11 +6111,19 @@ static int hdd_set_reset_bpf_offload(hdd_context_t *hdd_ctx,
/* Parse and fetch bpf program */
if (!tb[BPF_PROGRAM]) {
hdd_err("attr bpf program failed");
+ ret = -EINVAL;
goto fail;
}
prog_len = nla_len(tb[BPF_PROGRAM]);
bpf_set_offload->program = qdf_mem_malloc(sizeof(uint8_t) * prog_len);
+
+ if (bpf_set_offload->program == NULL) {
+ hdd_err("qdf_mem_malloc failed for bpf offload program");
+ ret = -ENOMEM;
+ goto fail;
+ }
+
bpf_set_offload->current_length = prog_len;
nla_memcpy(bpf_set_offload->program, tb[BPF_PROGRAM], prog_len);
bpf_set_offload->session_id = session_id;
@@ -6121,6 +6131,7 @@ static int hdd_set_reset_bpf_offload(hdd_context_t *hdd_ctx,
/* Parse and fetch filter Id */
if (!tb[BPF_FILTER_ID]) {
hdd_err("attr filter id failed");
+ ret = -EINVAL;
goto fail;
}
bpf_set_offload->filter_id = nla_get_u32(tb[BPF_FILTER_ID]);
@@ -6128,6 +6139,7 @@ static int hdd_set_reset_bpf_offload(hdd_context_t *hdd_ctx,
/* Parse and fetch current offset */
if (!tb[BPF_CURRENT_OFFSET]) {
hdd_err("attr current offset failed");
+ ret = -EINVAL;
goto fail;
}
bpf_set_offload->current_offset = nla_get_u32(tb[BPF_CURRENT_OFFSET]);
@@ -6144,19 +6156,16 @@ post_sme:
status = sme_set_bpf_instructions(hdd_ctx->hHal, bpf_set_offload);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("sme_set_bpf_instructions failed(err=%d)", status);
+ ret = -EINVAL;
goto fail;
}
EXIT();
- if (bpf_set_offload->current_length)
- qdf_mem_free(bpf_set_offload->program);
- qdf_mem_free(bpf_set_offload);
- return 0;
fail:
if (bpf_set_offload->current_length)
qdf_mem_free(bpf_set_offload->program);
qdf_mem_free(bpf_set_offload);
- return -EINVAL;
+ return ret;
}
/**
@@ -6191,7 +6200,7 @@ __wlan_hdd_cfg80211_bpf_offload(struct wiphy *wiphy,
}
if (!hdd_ctx->bpf_enabled) {
- hdd_err("BPF offload is not supported by firmware");
+ hdd_err("BPF offload is not supported/enabled");
return -ENOTSUPP;
}
@@ -9242,6 +9251,11 @@ static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
pAPCtx->wepKey[key_index].keyDirection =
eSIR_TX_DEFAULT;
+ hdd_info("key index passed for sme_roam_set_default_key_index %d",
+ key_index);
+ sme_roam_set_default_key_index(
+ WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId, key_index);
}
}
@@ -9419,6 +9433,8 @@ wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter,
qie_age->tsf_delta = bss_desc->tsf_delta;
memcpy(&qie_age->beacon_tsf, bss_desc->timeStamp,
sizeof(qie_age->beacon_tsf));
+ memcpy(&qie_age->seq_ctrl, &bss_desc->seq_ctrl,
+ sizeof(qie_age->seq_ctrl));
#endif
memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
@@ -11046,6 +11062,16 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
if (true == wlan_hdd_reassoc_bssid_hint(pAdapter, req, &status))
return status;
+ wlan_hdd_disable_roaming(pAdapter);
+
+ /* Try disconnecting if already in connected state */
+ status = wlan_hdd_try_disconnect(pAdapter);
+ if (0 > status) {
+ hdd_err("Failed to disconnect the existing connection");
+ return -EALREADY;
+ }
+
+ /* Check for max concurrent connections after doing disconnect if any */
if (req->channel) {
if (!cds_allow_concurrency(
cds_convert_device_mode_to_qdf_type(
@@ -11063,15 +11089,6 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
}
}
- wlan_hdd_disable_roaming(pAdapter);
-
- /*Try disconnecting if already in connected state */
- status = wlan_hdd_try_disconnect(pAdapter);
- if (0 > status) {
- hdd_err("Failed to disconnect the existing connection");
- return -EALREADY;
- }
-
/*initialise security parameters */
status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
index 57bb546278ab..1bd642d9d583 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -89,27 +89,6 @@
#define QCOM_VENDOR_IE_AGE_TYPE 0x100
#define QCOM_VENDOR_IE_AGE_LEN (sizeof(qcom_ie_age) - 2)
-#ifdef FEATURE_WLAN_TDLS
-#define WLAN_IS_TDLS_SETUP_ACTION(action) \
- ((SIR_MAC_TDLS_SETUP_REQ <= action) && \
- (SIR_MAC_TDLS_SETUP_CNF >= action))
-#if !defined (TDLS_MGMT_VERSION2)
-#define TDLS_MGMT_VERSION2 0
-#endif
-#endif
-
-#define MAX_CHANNEL (NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS)
-#define MAX_SCAN_SSID 10
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) \
- || defined(BACKPORTED_CHANNEL_SWITCH_PRESENT)
-#define CHANNEL_SWITCH_SUPPORTED
-#endif
-
-#if defined(CFG80211_DEL_STA_V2) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) || defined(WITH_BACKPORTS)
-#define USE_CFG80211_DEL_STA_V2
-#endif
-
/**
* typedef struct qcom_ie_age - age ie
*
@@ -122,6 +101,7 @@
* @age: Age
* @tsf_delta: tsf delta from FW
* @beacon_tsf: original beacon TSF
+ * @seq_ctrl: sequence control field
*/
typedef struct {
u8 element_id;
@@ -133,9 +113,31 @@ typedef struct {
u32 age;
u32 tsf_delta;
u64 beacon_tsf;
+ u16 seq_ctrl;
} __attribute__ ((packed)) qcom_ie_age;
#endif
+#ifdef FEATURE_WLAN_TDLS
+#define WLAN_IS_TDLS_SETUP_ACTION(action) \
+ ((SIR_MAC_TDLS_SETUP_REQ <= action) && \
+ (SIR_MAC_TDLS_SETUP_CNF >= action))
+#if !defined (TDLS_MGMT_VERSION2)
+#define TDLS_MGMT_VERSION2 0
+#endif
+#endif
+
+#define MAX_CHANNEL (NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS)
+#define MAX_SCAN_SSID 10
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) \
+ || defined(BACKPORTED_CHANNEL_SWITCH_PRESENT)
+#define CHANNEL_SWITCH_SUPPORTED
+#endif
+
+#if defined(CFG80211_DEL_STA_V2) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) || defined(WITH_BACKPORTS)
+#define USE_CFG80211_DEL_STA_V2
+#endif
+
/**
* enum eDFS_CAC_STATUS: CAC status
*
@@ -931,10 +933,9 @@ enum qca_wlan_vendor_attr {
* @QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD:
* Unsigned 32-bit value. If max_period is non zero or different than
* period, then this bucket is an exponential backoff bucket.
- * @QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT:
+ * @QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE:
* Unsigned 32-bit value. For exponential back off bucket,
- * number of scans performed at a given period and until the
- * exponent is applied.
+ * number of scans to performed for a given period.
* @QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT:
* Unsigned 8-bit value; in number of scans, wake up AP after these
* many scans.
@@ -1010,7 +1011,7 @@ enum qca_wlan_vendor_attr_extscan_config_params {
QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE,
QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD,
- QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT,
+ QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE,
QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT,
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS,
@@ -1130,6 +1131,10 @@ enum qca_wlan_vendor_attr_extscan_config_params {
* Unsigned 32bit value; Max number of epno networks by ssid
* @QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID:
* Unsigned 32bit value; Max number of whitelisted ssids
+ * @QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED:
+ * Unsigned 32bit value, Bit mask of all buckets scanned in the
+ * current EXTSCAN CYCLE. For e.g. If fw scan is going to scan
+ * following buckets 0, 1, 2 in current cycle then it will be (0x111)
* @QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_AFTER_LAST: After last
* @QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_MAX: Max value
*/
@@ -1250,6 +1255,7 @@ enum qca_wlan_vendor_attr_extscan_results {
/* Use attr QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE
* to indicate number of results.
*/
+ QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED,
/* keep last */
QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_AFTER_LAST,
diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c
index 36a521165437..6d99b958331d 100644
--- a/core/hdd/src/wlan_hdd_ext_scan.c
+++ b/core/hdd/src/wlan_hdd_ext_scan.c
@@ -46,6 +46,7 @@
* @ignore_cached_results: Flag to ignore cached results or not
* @context_lock: Spinlock to serialize all context accesses
* @capability_response: Ext scan capability response data from target
+ * @buckets_scanned: bitmask of buckets scanned in extscan cycle
*/
struct hdd_ext_scan_context {
uint32_t request_id;
@@ -54,6 +55,7 @@ struct hdd_ext_scan_context {
struct completion response_event;
spinlock_t context_lock;
struct ext_scan_capabilities_response capability_response;
+ uint32_t buckets_scanned;
};
static struct hdd_ext_scan_context ext_scan_context;
@@ -314,6 +316,7 @@ wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
#define EXTSCAN_CACHED_NL_FIXED_TLV \
((sizeof(data->request_id) + NLA_HDRLEN) + \
(sizeof(data->num_scan_ids) + NLA_HDRLEN) + \
+ (sizeof(data->buckets_scanned) + NLA_HDRLEN)+ \
(sizeof(data->more_data) + NLA_HDRLEN))
#define EXTSCAN_CACHED_NL_SCAN_ID_TLV \
((sizeof(result->scan_id) + NLA_HDRLEN) + \
@@ -365,8 +368,9 @@ wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
goto fail;
}
- hdd_notice("Req Id %u Num_scan_ids %u More Data %u",
- data->request_id, data->num_scan_ids, data->more_data);
+ hdd_notice("Req Id %u Num_scan_ids %u More Data %u buckets_scanned %u",
+ data->request_id, data->num_scan_ids, data->more_data,
+ data->buckets_scanned);
result = &data->result[0];
for (i = 0; i < data->num_scan_ids; i++) {
@@ -450,6 +454,9 @@ wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
result->flags) ||
nla_put_u32(skb,
+ QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED,
+ data->buckets_scanned) ||
+ nla_put_u32(skb,
QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE,
result->num_results)) {
hdd_err("put fail");
@@ -774,6 +781,7 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
hdd_context_t *pHddCtx = (hdd_context_t *) ctx;
struct sk_buff *skb = NULL;
struct timespec ts;
+ struct hdd_ext_scan_context *context;
int flags = cds_get_gfp_flags();
@@ -878,6 +886,17 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
goto nla_put_failure;
}
+ context = &ext_scan_context;
+ spin_lock(&context->context_lock);
+ if (nla_put_u32(skb,
+ QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED,
+ context->buckets_scanned)) {
+ spin_unlock(&context->context_lock);
+ hdd_notice("Failed to include buckets_scanned");
+ goto nla_put_failure;
+ }
+ spin_unlock(&context->context_lock);
+
cfg80211_vendor_event(skb, flags);
EXIT();
return;
@@ -966,6 +985,7 @@ wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
hdd_context_t *pHddCtx = (hdd_context_t *) ctx;
struct sk_buff *skb = NULL;
int flags = cds_get_gfp_flags();
+ struct hdd_ext_scan_context *context;
ENTER();
@@ -973,6 +993,7 @@ wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
return;
if (!pData) {
hdd_err("pData is null");
+ EXIT();
return;
}
@@ -985,19 +1006,34 @@ wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
if (!skb) {
hdd_err("cfg80211_vendor_event_alloc failed");
+ EXIT();
return;
}
- hdd_notice("Req Id %u Scan event type %u Scan event status %u",
- pData->requestId, pData->scanEventType, pData->status);
+
+ hdd_notice("Request Id %u Scan event type %u Scan event status %u buckets scanned %u",
+ pData->requestId, pData->scanEventType, pData->status,
+ pData->buckets_scanned);
+
+ context = &ext_scan_context;
+ spin_lock(&context->context_lock);
+ if (pData->scanEventType == WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT) {
+ context->buckets_scanned = 0;
+ pData->scanEventType = WIFI_EXTSCAN_RESULTS_AVAILABLE;
+ spin_unlock(&context->context_lock);
+ } else if (pData->scanEventType == WIFI_EXTSCAN_CYCLE_STARTED_EVENT) {
+ context->buckets_scanned = pData->buckets_scanned;
+ /* No need to report to user space */
+ spin_unlock(&context->context_lock);
+ goto nla_put_failure;
+ } else {
+ spin_unlock(&context->context_lock);
+ }
if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
pData->requestId) ||
nla_put_u8(skb,
QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
- pData->scanEventType) ||
- nla_put_u32(skb,
- QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
- pData->status)) {
+ pData->scanEventType)) {
hdd_err("nla put fail");
goto nla_put_failure;
}
@@ -1008,6 +1044,7 @@ wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
nla_put_failure:
kfree_skb(skb);
+ EXIT();
return;
}
@@ -2771,14 +2808,14 @@ static int hdd_extscan_start_fill_bucket_channel_spec(
hdd_notice("max period %u",
req_msg->buckets[bkt_index].max_period);
- /* Parse and fetch exponent */
- if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
- hdd_err("attr exponent failed");
+ /* Parse and fetch base */
+ if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE]) {
+ hdd_err("attr base failed");
return -EINVAL;
}
req_msg->buckets[bkt_index].exponent = nla_get_u32(
- bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
- hdd_notice("exponent %u",
+ bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE]);
+ hdd_notice("base %u",
req_msg->buckets[bkt_index].exponent);
/* Parse and fetch step count */
@@ -3241,6 +3278,7 @@ __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
spin_lock(&context->context_lock);
INIT_COMPLETION(context->response_event);
context->request_id = request_id = pReqMsg->requestId;
+ context->buckets_scanned = 0;
spin_unlock(&context->context_lock);
status = sme_ext_scan_start(pHddCtx->hHal, pReqMsg);
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index c4bcf59df5a7..d7c8aa302e13 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -8126,11 +8126,6 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
TRACE_CODE_HDD_CFG80211_STOP_AP,
pAdapter->sessionId, pAdapter->device_mode));
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- ret = wlan_hdd_validate_context(pHddCtx);
- if (0 != ret)
- return ret;
-
if (!(pAdapter->device_mode == QDF_SAP_MODE ||
pAdapter->device_mode == QDF_P2P_GO_MODE)) {
return -EOPNOTSUPP;
@@ -8140,6 +8135,24 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
hdd_device_mode_to_string(pAdapter->device_mode),
pAdapter->device_mode);
+ pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ ret = wlan_hdd_validate_context(pHddCtx);
+ if (0 != ret) {
+ if (cds_is_driver_unloading()) {
+ /*
+ * Unloading the driver so free the memory for ch_list,
+ * otherwise it will result in memory leak
+ */
+ if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list) {
+ qdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.
+ acs_cfg.ch_list);
+ pAdapter->sessionCtx.ap.sapConfig.acs_cfg.
+ ch_list = NULL;
+ }
+ }
+ return ret;
+ }
+
status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
staAdapter = pAdapterNode->pAdapter;
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
index 5ca71152c474..f5240d10fcda 100644
--- a/core/hdd/src/wlan_hdd_ioctl.c
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -6691,6 +6691,17 @@ static int drv_cmd_set_antenna_mode(hdd_adapter_t *adapter,
hdd_ctx->current_antenna_mode);
ret = 0;
exit:
+#ifdef FEATURE_WLAN_TDLS
+ /* Reset tdls NSS flags */
+ if (hdd_ctx->tdls_nss_switch_in_progress &&
+ hdd_ctx->tdls_nss_teardown_complete) {
+ hdd_ctx->tdls_nss_switch_in_progress = false;
+ hdd_ctx->tdls_nss_teardown_complete = false;
+ }
+ hdd_info("tdls_nss_switch_in_progress: %d tdls_nss_teardown_complete: %d",
+ hdd_ctx->tdls_nss_switch_in_progress,
+ hdd_ctx->tdls_nss_teardown_complete);
+#endif
hdd_info("Set antenna status: %d current mode: %d",
ret, hdd_ctx->current_antenna_mode);
return ret;
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index 5f9f30ab14f2..87ae722f5726 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -3991,10 +3991,16 @@ QDF_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
struct hdd_ipa_priv *hdd_ipa = NULL;
int ret, i;
struct hdd_ipa_iface_context *iface_context = NULL;
+ struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
if (!hdd_ipa_is_enabled(hdd_ctx))
return QDF_STATUS_SUCCESS;
+ if (!pdev) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_FATAL, "pdev is NULL");
+ goto fail_return;
+ }
+
hdd_ipa = qdf_mem_malloc(sizeof(*hdd_ipa));
if (!hdd_ipa) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_FATAL, "hdd_ipa allocation failed");
@@ -4005,8 +4011,7 @@ QDF_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
ghdd_ipa = hdd_ipa;
hdd_ipa->hdd_ctx = hdd_ctx;
hdd_ipa->num_iface = 0;
- ol_txrx_ipa_uc_get_resource(cds_get_context(QDF_MODULE_ID_TXRX),
- &hdd_ipa->ipa_resource);
+ ol_txrx_ipa_uc_get_resource(pdev, &hdd_ipa->ipa_resource);
if ((0 == hdd_ipa->ipa_resource.ce_sr_base_paddr) ||
(0 == hdd_ipa->ipa_resource.tx_comp_ring_base_paddr) ||
(0 == hdd_ipa->ipa_resource.rx_rdy_ring_base_paddr) ||
diff --git a/core/hdd/src/wlan_hdd_lro.c b/core/hdd/src/wlan_hdd_lro.c
index 88bde8882a90..d80681ef67f3 100644
--- a/core/hdd/src/wlan_hdd_lro.c
+++ b/core/hdd/src/wlan_hdd_lro.c
@@ -562,7 +562,7 @@ int hdd_lro_enable(hdd_context_t *hdd_ctx,
hdd_lro_desc_info_init(hdd_lro);
hdd_lro->lro_mgr->dev = adapter->dev;
- if (hdd_ctx->config->enableRxThread)
+ if (hdd_ctx->enableRxThread)
hdd_lro->lro_mgr->features = LRO_F_NI;
if (hdd_napi_enabled(HDD_NAPI_ANY))
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index caf39aae25f0..30e2c6b35d86 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -77,6 +77,7 @@
#ifdef MSM_PLATFORM
#include <soc/qcom/subsystem_restart.h>
#endif
+#include <soc/qcom/socinfo.h>
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_softap_tx_rx.h>
#include "cfg_api.h"
@@ -199,6 +200,28 @@ void wlan_hdd_auto_shutdown_cb(void);
#endif
/**
+ * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
+ * @hdd_ctx: pointer to hdd_context_t
+ *
+ * Return: none
+ */
+void hdd_set_rps_cpu_mask(hdd_context_t *hdd_ctx)
+{
+ hdd_adapter_t *adapter;
+ hdd_adapter_list_node_t *adapter_node, *next;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
+ while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
+ adapter = adapter_node->pAdapter;
+ if (NULL != adapter)
+ hdd_send_rps_ind(adapter);
+ status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
+ adapter_node = next;
+ }
+}
+
+/**
* wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
* @vdev_id: vdev_id
* @action: action type
@@ -1342,6 +1365,38 @@ static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx,
}
+/**
+ * hdd_generate_macaddr_auto() - Auto-generate mac address
+ * @hdd_ctx: Pointer to the HDD context
+ *
+ * Auto-generate mac address using device serial number.
+ * Keep the first 3 bytes of OUI as before and replace
+ * the last 3 bytes with the lower 3 bytes of serial number.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+static int hdd_generate_macaddr_auto(hdd_context_t *hdd_ctx)
+{
+ unsigned int serialno = 0;
+ struct qdf_mac_addr mac_addr = {
+ {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
+ };
+
+ serialno = socinfo_get_serial_number();
+ if (serialno == 0)
+ return -EINVAL;
+
+ serialno &= 0x00ffffff;
+
+ mac_addr.bytes[3] = (serialno >> 16) & 0xff;
+ mac_addr.bytes[4] = (serialno >> 8) & 0xff;
+ mac_addr.bytes[5] = serialno & 0xff;
+
+ hdd_update_macaddr(hdd_ctx->config, mac_addr);
+ return 0;
+}
+
void hdd_update_tgt_cfg(void *context, void *param)
{
hdd_context_t *hdd_ctx = (hdd_context_t *) context;
@@ -1389,11 +1444,22 @@ void hdd_update_tgt_cfg(void *context, void *param)
if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
} else {
- hddLog(QDF_TRACE_LEVEL_ERROR,
- FL(
- "Invalid MAC passed from target, using MAC from ini file"
- MAC_ADDRESS_STR),
- MAC_ADDR_ARRAY(hdd_ctx->config->intfMacAddr[0].bytes));
+ static struct qdf_mac_addr default_mac_addr = {
+ {0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
+ };
+ if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
+ &default_mac_addr)) {
+ if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
+ hdd_err("Fail to auto-generate MAC, using MAC from ini file "
+ MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(hdd_ctx->config->
+ intfMacAddr[0].bytes));
+ } else {
+ hdd_err("Invalid MAC passed from target, using MAC from ini file "
+ MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(hdd_ctx->config->
+ intfMacAddr[0].bytes));
+ }
}
hdd_ctx->target_fw_version = cfg->target_fw_version;
@@ -1426,7 +1492,10 @@ void hdd_update_tgt_cfg(void *context, void *param)
hdd_info("Init current antenna mode: %d",
hdd_ctx->current_antenna_mode);
- hdd_ctx->bpf_enabled = cfg->bpf_enabled;
+ hdd_info("Target BPF %d Host BPF %d",
+ cfg->bpf_enabled, hdd_ctx->config->bpf_packet_filter_enable);
+ hdd_ctx->bpf_enabled = (cfg->bpf_enabled &&
+ hdd_ctx->config->bpf_packet_filter_enable);
/* Configure NAN datapath features */
hdd_nan_datapath_target_config(hdd_ctx, cfg);
}
@@ -4501,6 +4570,8 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
wiphy_unregister(wiphy);
wlan_hdd_cfg80211_deinit(wiphy);
+ wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
+
hdd_exit_netlink_services(hdd_ctx);
mutex_destroy(&hdd_ctx->iface_change_lock);
hdd_context_destroy(hdd_ctx);
@@ -4522,10 +4593,6 @@ void __hdd_wlan_exit(void)
/* Check IPA HW Pipe shutdown */
hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
-#ifdef WLAN_FEATURE_LPSS
- wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
-#endif
-
memdump_deinit();
/* Do all the cleanup before deregistering the driver */
@@ -6525,7 +6592,7 @@ int hdd_update_cds_config(hdd_context_t *hdd_ctx)
cds_cfg->ip_tcp_udp_checksum_offload =
hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
- cds_cfg->enable_rxthread = hdd_ctx->config->enableRxThread;
+ cds_cfg->enable_rxthread = hdd_ctx->enableRxThread;
cds_cfg->ce_classify_enabled =
hdd_ctx->config->ce_classify_enabled;
cds_cfg->tx_chain_mask_cck = hdd_ctx->config->tx_chain_mask_cck;
@@ -7428,6 +7495,8 @@ int hdd_wlan_startup(struct device *dev)
hdd_ctx->target_hw_version,
hdd_ctx->target_hw_name);
+ if (hdd_ctx->rps)
+ hdd_set_rps_cpu_mask(hdd_ctx);
ret = hdd_register_notifiers(hdd_ctx);
if (ret)
@@ -7883,6 +7952,7 @@ void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
case WLAN_SVC_WLAN_TP_IND:
case WLAN_SVC_WLAN_TP_TX_IND:
+ case WLAN_SVC_RPS_ENABLE_IND:
ani_hdr->length = len;
nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
diff --git a/core/hdd/src/wlan_hdd_nan_datapath.c b/core/hdd/src/wlan_hdd_nan_datapath.c
index 8bec901f9715..6279e5a47959 100644
--- a/core/hdd/src/wlan_hdd_nan_datapath.c
+++ b/core/hdd/src/wlan_hdd_nan_datapath.c
@@ -1594,6 +1594,11 @@ static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
continue;
}
ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
+ if (!ndp_ctx) {
+ hdd_err("ndp_ctx is NULL for vdev id: %d",
+ end_ind->ndp_map[i].vdev_id);
+ continue;
+ }
idx = hdd_get_peer_idx(sta_ctx,
&end_ind->ndp_map[i].peer_ndi_mac_addr);
if (idx == INVALID_PEER_IDX) {
diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c
index cc995252ac41..a71f3549acc5 100644
--- a/core/hdd/src/wlan_hdd_p2p.c
+++ b/core/hdd/src/wlan_hdd_p2p.c
@@ -2047,6 +2047,10 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
__func__);
return ERR_PTR(-ENOSPC);
}
+
+ if (pHddCtx->rps)
+ hdd_send_rps_ind(pAdapter);
+
EXIT();
return pAdapter->dev->ieee80211_ptr;
}
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index a1df43603409..9c50fbbf7101 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -1305,8 +1305,6 @@ QDF_STATUS hdd_wlan_shutdown(void)
hdd_alert("WLAN driver shutting down!");
- wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
-
/* If SSR never completes, then do kernel panic. */
hdd_ssr_timer_init();
hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
@@ -1352,6 +1350,8 @@ QDF_STATUS hdd_wlan_shutdown(void)
wlansap_global_deinit();
hdd_wlan_stop_modules(pHddCtx, true);
+ wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
+
hdd_alert("WLAN driver shutdown complete");
return QDF_STATUS_SUCCESS;
}
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
index f5767944e6db..b053817ca89a 100644
--- a/core/hdd/src/wlan_hdd_scan.c
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -48,6 +48,7 @@
#include "wlan_hdd_scan.h"
#include "cds_concurrency.h"
#include "wma_api.h"
+#include "cds_utils.h"
#define MAX_RATES 12
#define HDD_WAKE_LOCK_SCAN_DURATION (5 * 1000) /* in msec */
@@ -1263,6 +1264,7 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
uint8_t *pP2pIe = NULL;
hdd_adapter_t *con_sap_adapter;
uint16_t con_dfs_ch;
+ uint8_t num_chan = 0;
ENTER();
@@ -1430,8 +1432,6 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
request->n_channels = MAX_CHANNEL;
}
- hdd_notice("No of Scan Channels: %d", request->n_channels);
-
if (request->n_channels) {
char chList[(request->n_channels * 5) + 1];
int len;
@@ -1442,14 +1442,23 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
goto free_mem;
}
for (i = 0, len = 0; i < request->n_channels; i++) {
- channelList[i] = request->channels[i]->hw_value;
+ if (cds_is_dsrc_channel(cds_chan_to_freq(
+ request->channels[i]->hw_value)))
+ continue;
+ channelList[num_chan] = request->channels[i]->hw_value;
len += snprintf(chList + len, 5, "%d ", channelList[i]);
+ num_chan++;
}
-
hdd_notice("Channel-List: %s", chList);
-
+ hdd_notice("No. of Scan Channels: %d", num_chan);
}
- scan_req.ChannelInfo.numOfChannels = request->n_channels;
+ if (!num_chan) {
+ hdd_err("Received zero non-dsrc channels");
+ status = -EINVAL;
+ goto free_mem;
+ }
+
+ scan_req.ChannelInfo.numOfChannels = num_chan;
scan_req.ChannelInfo.ChannelList = channelList;
/* set requestType to full scan */
@@ -2136,13 +2145,16 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
num_ignore_dfs_ch++;
break;
}
-
- valid_ch[num_ch++] =
- request->channels[i]->hw_value;
- len +=
- snprintf(chList + len, 5, "%d ",
- request->channels[i]->
- hw_value);
+ if (!cds_is_dsrc_channel(
+ cds_chan_to_freq(
+ request->channels[i]->hw_value))) {
+ valid_ch[num_ch++] = request->
+ channels[i]->hw_value;
+ len += snprintf(chList + len,
+ 5, "%d ",
+ request->channels[i]->
+ hw_value);
+ }
break;
}
}
@@ -2152,8 +2164,8 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
/* If all channels are DFS and dropped,
* then ignore the PNO request
*/
- if (num_ignore_dfs_ch == request->n_channels) {
- hdd_notice("All requested channels are DFS channels");
+ if (!num_ch) {
+ hdd_notice("Channel list empty due to filtering of DSRC,DFS channels");
ret = -EINVAL;
goto error;
}
diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c
index be1edf2fac2f..f893aab74863 100644
--- a/core/hdd/src/wlan_hdd_softap_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -251,10 +251,12 @@ int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop_pkt;
}
+ wlan_hdd_classify_pkt(skb);
+
pDestMacAddress = (struct qdf_mac_addr *) skb->data;
- if (qdf_is_macaddr_broadcast(pDestMacAddress) ||
- qdf_is_macaddr_group(pDestMacAddress)) {
+ if (QDF_NBUF_CB_GET_IS_BCAST(skb) ||
+ QDF_NBUF_CB_GET_IS_MCAST(skb)) {
/* The BC/MC station ID is assigned during BSS
* starting phase. SAP will return the station ID
* used for BC/MC traffic.
@@ -324,8 +326,7 @@ int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
pAdapter->stats.tx_bytes += skb->len;
++pAdapter->stats.tx_packets;
- /* Zero out skb's context buffer for the driver to use */
- qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+ hdd_event_eapol_log(skb, QDF_TX);
qdf_dp_trace_log_pkt(pAdapter->sessionId, skb, QDF_TX);
QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
QDF_NBUF_UPDATE_TX_PKT_COUNT(skb, QDF_NBUF_TX_PKT_HDD);
@@ -593,6 +594,7 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
++pAdapter->stats.rx_packets;
pAdapter->stats.rx_bytes += skb->len;
+ hdd_event_eapol_log(skb, QDF_RX);
DPTRACE(qdf_dp_trace(rxBuf,
QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD,
qdf_nbuf_data_addr(rxBuf),
@@ -609,7 +611,8 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
* it to stack
*/
qdf_net_buf_debug_release_skb(rxBuf);
- if (hdd_napi_enabled(HDD_NAPI_ANY) && !pHddCtx->config->enableRxThread)
+ if (hdd_napi_enabled(HDD_NAPI_ANY) &&
+ !pHddCtx->enableRxThread)
rxstat = netif_receive_skb(skb);
else
rxstat = netif_rx_ni(skb);
diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c
index 6ba82a47259b..915cbafb6e9a 100644
--- a/core/hdd/src/wlan_hdd_tdls.c
+++ b/core/hdd/src/wlan_hdd_tdls.c
@@ -654,6 +654,8 @@ void hdd_tdls_context_init(hdd_context_t *hdd_ctx)
hdd_ctx->tdls_external_peer_count = 0;
hdd_ctx->set_state_info.set_state_cnt = 0;
hdd_ctx->set_state_info.vdev_id = 0;
+ hdd_ctx->tdls_nss_teardown_complete = false;
+ hdd_ctx->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_UNKNOWN;
/* This flag will set be true, only when device operates in
* standalone STA mode
@@ -4082,8 +4084,24 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
mutex_lock(&pHddCtx->tdls_lock);
if (pHddCtx->tdls_teardown_peers_cnt != 0)
pHddCtx->tdls_teardown_peers_cnt--;
- if (pHddCtx->tdls_teardown_peers_cnt == 0)
- pHddCtx->tdls_nss_switch_in_progress = false;
+ if (pHddCtx->tdls_teardown_peers_cnt == 0) {
+ if (pHddCtx->tdls_nss_transition_mode ==
+ TDLS_NSS_TRANSITION_1x1_to_2x2) {
+ /* TDLS NSS switch is fully completed, so
+ * reset the flags.
+ */
+ hdd_info("TDLS NSS switch is fully completed");
+ pHddCtx->tdls_nss_switch_in_progress = false;
+ pHddCtx->tdls_nss_teardown_complete = false;
+ } else {
+ /* TDLS NSS switch is not yet completed, but
+ * tdls teardown is completed for all the
+ * peers.
+ */
+ hdd_info("TDLS teardown is completed and NSS switch still in progress");
+ pHddCtx->tdls_nss_teardown_complete = true;
+ }
+ }
mutex_unlock(&pHddCtx->tdls_lock);
}
@@ -5829,11 +5847,16 @@ static int wlan_hdd_tdls_teardown_links(hdd_context_t *hddctx,
hdd_info("TDLS peers to be torn down = %d",
hddctx->tdls_teardown_peers_cnt);
/* Antenna switch 2x2 to 1x1 */
- if (mode == HDD_ANTENNA_MODE_1X1)
+ if (mode == HDD_ANTENNA_MODE_1X1) {
+ hddctx->tdls_nss_transition_mode =
+ TDLS_NSS_TRANSITION_2x2_to_1x1;
ret = -EAGAIN;
- else
+ } else {
/* Antenna switch 1x1 to 2x2 */
+ hddctx->tdls_nss_transition_mode =
+ TDLS_NSS_TRANSITION_1x1_to_2x2;
ret = 0;
+ }
hdd_info("TDLS teardown for antenna switch operation starts");
}
mutex_unlock(&hddctx->tdls_lock);
@@ -5858,8 +5881,12 @@ int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx,
/* Check whether TDLS antenna switch is in progress */
if (hdd_ctx->tdls_nss_switch_in_progress) {
- hdd_err("TDLS antenna switch is in progress");
- return -EAGAIN;
+ if (hdd_ctx->tdls_nss_teardown_complete == false) {
+ hdd_err("TDLS antenna switch is in progress");
+ return -EAGAIN;
+ } else {
+ goto tdls_ant_sw_done;
+ }
}
/* Check whether TDLS is connected or not */
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index 03d259a21a3e..5c4d503489a5 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -265,36 +265,80 @@ void hdd_get_tx_resource(hdd_adapter_t *adapter,
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
-
/**
- * wlan_hdd_is_eapol_or_wai() - Check if frame is EAPOL or WAPI
- * @skb: skb data
- *
- * This function checks if the frame is EAPOL or WAPI.
- * single routine call will check for both types, thus avoiding
- * data path performance penalty.
- *
- * Return: true (1) if packet is EAPOL or WAPI
+ * qdf_event_eapol_log() - send event to wlan diag
+ * @skb: skb ptr
+ * @dir: direction
+ * @eapol_key_info: eapol key info
*
+ * Return: None
*/
-static bool wlan_hdd_is_eapol_or_wai(struct sk_buff *skb)
+void hdd_event_eapol_log(struct sk_buff *skb, enum qdf_proto_dir dir)
{
- uint16_t ether_type;
+ int16_t eapol_key_info;
- if (!skb) {
- hdd_err(FL("skb is NULL"));
- return false;
- }
+ WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct host_event_wlan_eapol);
+
+ if ((dir == QDF_TX &&
+ (QDF_NBUF_CB_PACKET_TYPE_EAPOL !=
+ QDF_NBUF_CB_GET_PACKET_TYPE(skb))))
+ return;
+ else if (!qdf_nbuf_is_ipv4_eapol_pkt(skb))
+ return;
- ether_type = (uint16_t)(*(uint16_t *)
- (skb->data + HDD_ETHERTYPE_802_1_X_FRAME_OFFSET));
+ eapol_key_info = (uint16_t)(*(uint16_t *)
+ (skb->data + EAPOL_KEY_INFO_OFFSET));
+
+ wlan_diag_event.event_sub_type =
+ (dir == QDF_TX ?
+ WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED :
+ WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
+ wlan_diag_event.eapol_packet_type = (uint8_t)(*(uint8_t *)
+ (skb->data + EAPOL_PACKET_TYPE_OFFSET));
+ wlan_diag_event.eapol_key_info = eapol_key_info;
+ wlan_diag_event.eapol_rate = 0;
+ qdf_mem_copy(wlan_diag_event.dest_addr,
+ (skb->data + QDF_NBUF_DEST_MAC_OFFSET),
+ sizeof(wlan_diag_event.dest_addr));
+ qdf_mem_copy(wlan_diag_event.src_addr,
+ (skb->data + QDF_NBUF_SRC_MAC_OFFSET),
+ sizeof(wlan_diag_event.src_addr));
+
+ WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL);
+}
- if (ether_type == QDF_SWAP_U16(HDD_ETHERTYPE_802_1_X) ||
- ether_type == QDF_SWAP_U16(HDD_ETHERTYPE_WAI))
- return true;
- /* No error msg handled since this will happen often */
- return false;
+/**
+ * wlan_hdd_classify_pkt() - classify packet
+ * @skb - sk buff
+ *
+ * Return: none
+ */
+void wlan_hdd_classify_pkt(struct sk_buff *skb)
+{
+ struct ethhdr *eh = (struct ethhdr *)skb->data;
+
+ qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+
+ /* check destination mac address is broadcast/multicast */
+ if (is_broadcast_ether_addr((uint8_t *)eh))
+ QDF_NBUF_CB_GET_IS_BCAST(skb) = true;
+ else if (is_multicast_ether_addr((uint8_t *)eh))
+ QDF_NBUF_CB_GET_IS_MCAST(skb) = true;
+
+ if (qdf_nbuf_is_ipv4_arp_pkt(skb))
+ QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+ QDF_NBUF_CB_PACKET_TYPE_ARP;
+ else if (qdf_nbuf_is_ipv4_dhcp_pkt(skb))
+ QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+ QDF_NBUF_CB_PACKET_TYPE_DHCP;
+ else if (qdf_nbuf_is_ipv4_eapol_pkt(skb))
+ QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+ QDF_NBUF_CB_PACKET_TYPE_EAPOL;
+ else if (qdf_nbuf_is_ipv4_wapi_pkt(skb))
+ QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+ QDF_NBUF_CB_PACKET_TYPE_WAPI;
+
}
/**
@@ -309,19 +353,19 @@ static bool wlan_hdd_is_eapol_or_wai(struct sk_buff *skb)
* Returns: None
*/
static void hdd_get_transmit_sta_id(hdd_adapter_t *adapter,
- struct qdf_mac_addr *dst_addr, uint8_t *station_id)
+ struct sk_buff *skb, uint8_t *station_id)
{
bool mcbc_addr = false;
hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ struct qdf_mac_addr *dst_addr = NULL;
+ dst_addr = (struct qdf_mac_addr *)skb->data;
hdd_get_peer_sta_id(sta_ctx, dst_addr, station_id);
if (*station_id == HDD_WLAN_INVALID_STA_ID) {
- if (qdf_is_macaddr_broadcast(dst_addr) ||
- qdf_is_macaddr_group(dst_addr)) {
+ if (QDF_NBUF_CB_GET_IS_BCAST(skb) ||
+ QDF_NBUF_CB_GET_IS_MCAST(skb)) {
hdd_info("Received MC/BC packet for transmission");
mcbc_addr = true;
- } else {
- hdd_err("UC frame with invalid destination address");
}
}
@@ -364,9 +408,8 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
sme_QosWmmUpType up;
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
bool granted;
- uint8_t STAId = WLAN_MAX_STA_COUNT;
+ uint8_t STAId;
hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
- struct qdf_mac_addr *pDestMacAddress = NULL;
#ifdef QCA_PKT_PROTO_TRACE
uint8_t proto_type = 0;
#endif /* QCA_PKT_PROTO_TRACE */
@@ -386,10 +429,11 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop_pkt;
}
- pDestMacAddress = (struct qdf_mac_addr *)skb->data;
+ wlan_hdd_classify_pkt(skb);
+
STAId = HDD_WLAN_INVALID_STA_ID;
- hdd_get_transmit_sta_id(pAdapter, pDestMacAddress, &STAId);
+ hdd_get_transmit_sta_id(pAdapter, skb, &STAId);
if (STAId >= WLAN_MAX_STA_COUNT) {
hddLog(LOGE, "Invalid station id, transmit operation suspended");
goto drop_pkt;
@@ -438,7 +482,10 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
likely(pAdapter->hddWmmStatus.wmmAcStatus[ac].
wmmAcAccessAllowed)) ||
((pHddStaCtx->conn_info.uIsAuthenticated == false) &&
- wlan_hdd_is_eapol_or_wai(skb))) {
+ (QDF_NBUF_CB_PACKET_TYPE_EAPOL ==
+ QDF_NBUF_CB_GET_PACKET_TYPE(skb) ||
+ QDF_NBUF_CB_PACKET_TYPE_WAPI ==
+ QDF_NBUF_CB_GET_PACKET_TYPE(skb)))) {
granted = true;
} else {
status = hdd_wmm_acquire_access(pAdapter, ac, &granted);
@@ -502,8 +549,7 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
++pAdapter->stats.tx_packets;
- /* Zero out skb's context buffer for the driver to use */
- qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+ hdd_event_eapol_log(skb, QDF_TX);
qdf_dp_trace_log_pkt(pAdapter->sessionId, skb, QDF_TX);
QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
QDF_NBUF_UPDATE_TX_PKT_COUNT(skb, QDF_NBUF_TX_PKT_HDD);
@@ -866,6 +912,7 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
return QDF_STATUS_SUCCESS;
}
+ hdd_event_eapol_log(skb, QDF_RX);
DPTRACE(qdf_dp_trace(rxBuf,
QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD,
qdf_nbuf_data_addr(rxBuf),
@@ -893,7 +940,7 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
if (HDD_LRO_NO_RX ==
hdd_lro_rx(pHddCtx, pAdapter, skb)) {
if (hdd_napi_enabled(HDD_NAPI_ANY) &&
- !pHddCtx->config->enableRxThread)
+ !pHddCtx->enableRxThread)
rxstat = netif_receive_skb(skb);
else
rxstat = netif_rx_ni(skb);
@@ -1236,3 +1283,67 @@ exit:
ret = qdf_status_to_os_return(qdf_status);
return ret;
}
+
+/**
+ * hdd_send_rps_ind() - send rps indication to daemon
+ * @adapter: adapter context
+ *
+ * If RPS feature enabled by INI, send RPS enable indication to daemon
+ * Indication contents is the name of interface to find correct sysfs node
+ * Should send all available interfaces
+ *
+ * Return: none
+ */
+void hdd_send_rps_ind(hdd_adapter_t *adapter)
+{
+ int i;
+ uint8_t cpu_map_list_len = 0;
+ hdd_context_t *hdd_ctxt = NULL;
+ struct wlan_rps_data rps_data;
+
+ if (!adapter) {
+ hdd_err("adapter is NULL");
+ return;
+ }
+
+ hdd_ctxt = WLAN_HDD_GET_CTX(adapter);
+ rps_data.num_queues = NUM_TX_QUEUES;
+
+ hdd_info("cpu_map_list '%s'", hdd_ctxt->config->cpu_map_list);
+
+ /* in case no cpu map list is provided, simply return */
+ if (!strlen(hdd_ctxt->config->cpu_map_list)) {
+ hdd_err("no cpu map list found");
+ goto err;
+ }
+
+ if (QDF_STATUS_SUCCESS !=
+ hdd_hex_string_to_u16_array(hdd_ctxt->config->cpu_map_list,
+ rps_data.cpu_map_list,
+ &cpu_map_list_len,
+ WLAN_SVC_IFACE_NUM_QUEUES)) {
+ hdd_err("invalid cpu map list");
+ goto err;
+ }
+
+ rps_data.num_queues =
+ (cpu_map_list_len < rps_data.num_queues) ?
+ cpu_map_list_len : rps_data.num_queues;
+
+ for (i = 0; i < rps_data.num_queues; i++) {
+ hdd_info("cpu_map_list[%d] = 0x%x",
+ i, rps_data.cpu_map_list[i]);
+ }
+
+ strlcpy(rps_data.ifname, adapter->dev->name,
+ sizeof(rps_data.ifname));
+ wlan_hdd_send_svc_nlink_msg(WLAN_SVC_RPS_ENABLE_IND,
+ &rps_data, sizeof(rps_data));
+
+err:
+ hdd_err("Wrong RPS configuration. enabling rx_thread");
+ hdd_ctxt->rps = false;
+ hdd_ctxt->enableRxThread = true;
+}
+
+
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
index 89588faf43d7..18a4a7d42f95 100644
--- a/core/mac/inc/qwlan_version.h
+++ b/core/mac/inc/qwlan_version.h
@@ -41,9 +41,9 @@
#define QWLAN_VERSION_MAJOR 5
#define QWLAN_VERSION_MINOR 1
#define QWLAN_VERSION_PATCH 0
-#define QWLAN_VERSION_EXTRA "I"
+#define QWLAN_VERSION_EXTRA "R"
#define QWLAN_VERSION_BUILD 23
-#define QWLAN_VERSIONSTR "5.1.0.23I"
+#define QWLAN_VERSIONSTR "5.1.0.23R"
#endif /* QWLAN_VERSION_H */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 2aa2318bdf8e..c4b7daf8a2cd 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -733,8 +733,7 @@ typedef struct sSirBssDescription {
uint8_t fProbeRsp;
/* Actual channel the beacon/probe response was received on */
uint8_t rx_channel;
- uint8_t reservedPadding2;
- uint8_t reservedPadding3;
+ tSirMacSeqCtl seq_ctrl;
uint32_t WscIeLen;
uint8_t WscIeProbeRsp[WSCIE_PROBE_RSP_LEN];
uint8_t reservedPadding4;
@@ -4208,11 +4207,38 @@ typedef enum {
WIFI_BAND_MAX
} tWifiBand;
-/* wifi scan related events */
-typedef enum {
- WIFI_SCAN_BUFFER_FULL,
- WIFI_SCAN_COMPLETE,
-} tWifiScanEventType;
+/**
+ * enum wifi_extscan_event_type - extscan event type
+ * @WIFI_EXTSCAN_RESULTS_AVAILABLE: reported when REPORT_EVENTS_EACH_SCAN is set
+ * and a scan cycle completes. WIFI_SCAN_THRESHOLD_NUM_SCANS or
+ * WIFI_SCAN_THRESHOLD_PERCENT can be reported instead if the
+ * reason for the event is available; however, at most one of
+ * these events should be reported per scan.
+ * @WIFI_EXTSCAN_THRESHOLD_NUM_SCANS: can be reported when
+ * REPORT_EVENTS_EACH_SCAN is not set and
+ * report_threshold_num_scans is reached.
+ * @WIFI_EXTSCAN_THRESHOLD_PERCENT: can be reported when REPORT_EVENTS_EACH_SCAN
+ * is not set and report_threshold_percent is reached.
+ * @WIFI_SCAN_DISABLED: reported when currently executing gscans are disabled
+ * start_gscan will need to be called again in order to continue
+ * scanning.
+ * @WIFI_EXTSCAN_BUCKET_STARTED_EVENT: Bucket started event
+ * This event is consumed in driver only.
+ * @WIFI_EXTSCAN_CYCLE_STARTED_EVENT: Cycle started event.
+ * This event is consumed in driver only.
+ * @WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT: Cycle complete event. This event
+ * triggers @WIFI_EXTSCAN_RESULTS_AVAILABLE to the user space.
+ */
+enum wifi_extscan_event_type {
+ WIFI_EXTSCAN_RESULTS_AVAILABLE,
+ WIFI_EXTSCAN_THRESHOLD_NUM_SCANS,
+ WIFI_EXTSCAN_THRESHOLD_PERCENT,
+ WIFI_SCAN_DISABLED,
+
+ WIFI_EXTSCAN_BUCKET_STARTED_EVENT = 0x10,
+ WIFI_EXTSCAN_CYCLE_STARTED_EVENT,
+ WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT,
+};
/**
* enum extscan_configuration_flags - extscan config flags
@@ -4381,12 +4407,14 @@ typedef struct {
* @more_data: 0 - for last fragment
* 1 - still more fragment(s) coming
* @num_scan_ids: number of scan ids
+ * @buckets_scanned: bitmask of buckets scanned in current extscan cycle
* @result: wifi scan result
*/
struct extscan_cached_scan_results {
uint32_t request_id;
bool more_data;
uint32_t num_scan_ids;
+ uint32_t buckets_scanned;
struct extscan_cached_scan_result *result;
};
@@ -4655,6 +4683,7 @@ typedef struct {
uint32_t requestId;
uint32_t status;
uint8_t scanEventType;
+ uint32_t buckets_scanned;
} tSirExtScanOnScanEventIndParams, *tpSirExtScanOnScanEventIndParams;
/**
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index cde2bd73a830..650c2aab942e 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -628,6 +628,7 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_NDP_INDICATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 355)
#define SIR_HAL_NDP_CONFIRM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 356)
#define SIR_HAL_NDP_END_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 357)
+#define SIR_HAL_UPDATE_WEP_DEFAULT_KEY (SIR_HAL_ITC_MSG_TYPES_BEGIN + 358)
#define SIR_HAL_POWER_DBG_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 347)
diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
index ee6c33841b00..85d6346bd05f 100644
--- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
+++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
@@ -137,6 +137,7 @@ static void lim_convert_supported_channels(tpAniSirGlobal mac_ctx,
* lim_check_sta_in_pe_entries() - checks if sta exists in any dph tables.
* @mac_ctx: Pointer to Global MAC structure
* @hdr: A pointer to the MAC header
+ * @sessionid - session id for which session is initiated
*
* This function is called by lim_process_assoc_req_frame() to check if STA
* entry already exists in any of the PE entries of the AP. If it exists, deauth
@@ -145,7 +146,8 @@ static void lim_convert_supported_channels(tpAniSirGlobal mac_ctx,
*
* Return: void
*/
-void lim_check_sta_in_pe_entries(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr)
+void lim_check_sta_in_pe_entries(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+ uint16_t sessionid)
{
uint8_t i;
uint16_t assoc_id = 0;
@@ -161,7 +163,8 @@ void lim_check_sta_in_pe_entries(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr)
&assoc_id, &session->dph.dphHashTable);
if (sta_ds
#ifdef WLAN_FEATURE_11W
- && !sta_ds->rmfEnabled
+ && (!sta_ds->rmfEnabled ||
+ (sessionid != session->peSessionId))
#endif
) {
lim_log(mac_ctx, LOGE,
@@ -1778,7 +1781,7 @@ void lim_process_assoc_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
return;
}
- lim_check_sta_in_pe_entries(mac_ctx, hdr);
+ lim_check_sta_in_pe_entries(mac_ctx, hdr, session->peSessionId);
/* Get pointer to Re/Association Request frame body */
frm_body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c
index b996942bd40b..149091f11d0a 100644
--- a/core/mac/src/pe/lim/lim_process_auth_frame.c
+++ b/core/mac/src/pe/lim/lim_process_auth_frame.c
@@ -357,7 +357,7 @@ static void lim_process_auth_frame_type1(tpAniSirGlobal mac_ctx,
* received but ACK lost at STA side, in this case 2nd
* auth frame is already in transmission queue
*/
- lim_log(mac_ctx, LOGE,
+ lim_log(mac_ctx, LOGW,
FL("STA is initiating Auth after ACK lost"));
return;
}
diff --git a/core/mac/src/pe/lim/lim_scan_result_utils.c b/core/mac/src/pe/lim/lim_scan_result_utils.c
index af0e93e5b1ac..65796e0f270e 100644
--- a/core/mac/src/pe/lim/lim_scan_result_utils.c
+++ b/core/mac/src/pe/lim/lim_scan_result_utils.c
@@ -179,6 +179,7 @@ lim_collect_bss_description(tpAniSirGlobal pMac,
pBssDescr->nReceivedTime = (uint32_t) qdf_mc_timer_get_system_ticks();
pBssDescr->tsf_delta = WMA_GET_RX_TSF_DELTA(pRxPacketInfo);
+ pBssDescr->seq_ctrl = pHdr->seqControl;
lim_log(pMac, LOG1,
FL("BSSID: "MAC_ADDRESS_STR " tsf_delta = %u ReceivedTime = %u ssid = %s"),
@@ -186,6 +187,10 @@ lim_collect_bss_description(tpAniSirGlobal pMac,
pBssDescr->nReceivedTime,
((pBPR->ssidPresent) ? (char *)pBPR->ssId.ssId : ""));
+ lim_log(pMac, LOG1, FL("Seq Ctrl: Frag Num: %d, Seq Num: LO:%02x HI:%02x"),
+ pBssDescr->seq_ctrl.fragNum, pBssDescr->seq_ctrl.seqNumLo,
+ pBssDescr->seq_ctrl.seqNumHi);
+
if (fScanning) {
rrm_get_start_tsf(pMac, pBssDescr->startTSF);
pBssDescr->parentTSF = WMA_GET_RX_TIMESTAMP(pRxPacketInfo);
diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c
index 3acbb7d18027..415bdaf358ee 100644
--- a/core/mac/src/pe/sch/sch_beacon_gen.c
+++ b/core/mac/src/pe/sch/sch_beacon_gen.c
@@ -395,8 +395,9 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
populate_dot11f_operating_mode(mac_ctx,
&bcn_2->OperatingMode, session);
}
- populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &bcn_2->ExtCap,
- session);
+ if (session->limSystemRole != eLIM_STA_IN_IBSS_ROLE)
+ populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &bcn_2->ExtCap,
+ session);
populate_dot11f_ext_supp_rates(mac_ctx,
POPULATE_DOT11F_RATES_OPERATIONAL,
&bcn_2->ExtSuppRates, session);
@@ -498,7 +499,8 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
sch_log(mac_ctx, LOG1, FL("extcap not extracted"));
}
/* merge extcap IE */
- if (extcap_present)
+ if (extcap_present &&
+ session->limSystemRole != eLIM_STA_IN_IBSS_ROLE)
lim_merge_extcap_struct(&bcn_2->ExtCap,
&extracted_extcap);
diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h
index 0e680504755c..345f69b06aa3 100644
--- a/core/pld/inc/pld_common.h
+++ b/core/pld/inc/pld_common.h
@@ -251,18 +251,30 @@ enum pld_driver_mode {
PLD_OFF
};
+#define PLD_MAX_TIMESTAMP_LEN 32
+
/**
* struct pld_soc_info - SOC information
* @v_addr: virtual address of preallocated memory
* @p_addr: physical address of preallcoated memory
- * @version: version number
+ * @chip_id: chip ID
+ * @chip_family: chip family
+ * @board_id: board ID
+ * @soc_id: SOC ID
+ * @fw_version: FW version
+ * @fw_build_timestamp: FW build timestamp
*
* pld_soc_info is used to store WLAN SOC information.
*/
struct pld_soc_info {
void __iomem *v_addr;
phys_addr_t p_addr;
- u32 version;
+ u32 chip_id;
+ u32 chip_family;
+ u32 board_id;
+ u32 soc_id;
+ u32 fw_version;
+ char fw_build_timestamp[PLD_MAX_TIMESTAMP_LEN + 1];
};
/**
@@ -364,6 +376,7 @@ void pld_enable_irq(struct device *dev, unsigned int ce_id);
void pld_disable_irq(struct device *dev, unsigned int ce_id);
int pld_get_soc_info(struct device *dev, struct pld_soc_info *info);
int pld_get_ce_id(struct device *dev, int irq);
+int pld_get_irq(struct device *dev, int ce_id);
void pld_lock_pm_sem(struct device *dev);
void pld_release_pm_sem(struct device *dev);
int pld_power_on(struct device *dev);
diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c
index 29458eb7853d..0aa3017bbd90 100644
--- a/core/pld/src/pld_common.c
+++ b/core/pld/src/pld_common.c
@@ -1272,6 +1272,30 @@ int pld_get_ce_id(struct device *dev, int irq)
}
/**
+ * pld_get_irq() - Get IRQ number for given CE ID
+ * @dev: device
+ * @ce_id: CE ID
+ *
+ * Return: IRQ number
+ */
+int pld_get_irq(struct device *dev, int ce_id)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_SNOC:
+ ret = pld_snoc_get_irq(ce_id);
+ break;
+ case PLD_BUS_TYPE_PCIE:
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
* pld_lock_pm_sem() - Lock PM semaphore
* @dev: device
*
diff --git a/core/pld/src/pld_snoc.c b/core/pld/src/pld_snoc.c
index 22297b4e7944..bfbedb056c12 100644
--- a/core/pld/src/pld_snoc.c
+++ b/core/pld/src/pld_snoc.c
@@ -381,4 +381,16 @@ int pld_snoc_power_off(struct device *dev)
{
return icnss_power_off(dev);
}
+
+/**
+ * pld_snoc_get_irq() - Get IRQ number for given CE ID
+ * @ce_id: CE ID
+ *
+ * Return: IRQ number
+ */
+int pld_snoc_get_irq(int ce_id)
+{
+ return icnss_get_irq(ce_id);
+}
+
#endif
diff --git a/core/pld/src/pld_snoc.h b/core/pld/src/pld_snoc.h
index 75f3f1036f37..ca1ce1d91cd6 100644
--- a/core/pld/src/pld_snoc.h
+++ b/core/pld/src/pld_snoc.h
@@ -83,6 +83,10 @@ static inline int pld_snoc_power_off(struct device *dev)
{
return 0;
}
+static inline int pld_snoc_get_irq(int ce_id)
+{
+ return 0;
+}
#else
int pld_snoc_register_driver(void);
void pld_snoc_unregister_driver(void);
@@ -99,6 +103,7 @@ void pld_snoc_disable_irq(unsigned int ce_id);
int pld_snoc_get_ce_id(int irq);
int pld_snoc_power_on(struct device *dev);
int pld_snoc_power_off(struct device *dev);
+int pld_snoc_get_irq(int ce_id);
#endif
#endif
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 8cfbff20ba66..bbef6cad952f 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -1599,6 +1599,19 @@ struct tagCsrDelStaParams {
uint8_t subtype;
};
+/**
+ * struct wep_update_default_key_idx: wep default key index structure
+ * @session_id: session ID for the connection session
+ * @default_idx: default key index for wep
+ *
+ * structure includes sesssion id for connection and default key
+ * index used for wep
+ */
+struct wep_update_default_key_idx {
+ uint8_t session_id;
+ uint8_t default_idx;
+};
+
/*
* NOTE: p2 is the second context pass in for the caller
* NOTE: what if callback is called before requester gets the scanId??
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 366f52a1e754..d906cdeba772 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -1154,4 +1154,6 @@ QDF_STATUS sme_process_mac_pwr_dbg_cmd(tHalHandle hal, uint32_t session_id,
void sme_get_vdev_type_nss(tHalHandle hal, enum tQDF_ADAPTER_MODE dev_mode,
uint8_t *nss_2g, uint8_t *nss_5g);
+QDF_STATUS sme_roam_set_default_key_index(tHalHandle hal, uint8_t session_id,
+ uint8_t default_idx);
#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 47c3a85c4104..a9e35d20e8c1 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -5096,6 +5096,50 @@ QDF_STATUS sme_roam_set_key(tHalHandle hal, uint8_t session_id,
return status;
}
+/**
+ * sme_roam_set_default_key_index - To set default wep key idx
+ * @hal: pointer to hal handler
+ * @session_id: session id
+ * @default_idx: default wep key index
+ *
+ * This function prepares a message and post to WMA to set wep default
+ * key index
+ *
+ * Return: Success:QDF_STATUS_SUCCESS Failure: Error value
+ */
+QDF_STATUS sme_roam_set_default_key_index(tHalHandle hal, uint8_t session_id,
+ uint8_t default_idx)
+{
+ cds_msg_t msg;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ struct wep_update_default_key_idx *update_key;
+
+ update_key = qdf_mem_malloc(sizeof(*update_key));
+ if (!update_key) {
+ sms_log(mac_ctx, LOGE,
+ FL("Failed to allocate memory for update key"));
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ update_key->session_id = session_id;
+ update_key->default_idx = default_idx;
+
+ msg.type = WMA_UPDATE_WEP_DEFAULT_KEY;
+ msg.reserved = 0;
+ msg.bodyptr = (void *)update_key;
+
+ if (QDF_STATUS_SUCCESS !=
+ cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
+ sms_log(mac_ctx, LOGE,
+ FL("Failed to post WMA_UPDATE_WEP_DEFAULT_KEY to WMA"));
+ qdf_mem_free(update_key);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+
/* ---------------------------------------------------------------------------
\fn sme_get_rssi
\brief a wrapper function that client calls to register a callback to get
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index b29c7c05349c..3a06d55dcf2a 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -11063,32 +11063,33 @@ csr_roam_chk_lnk_set_ctx_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
pMsg->length = sizeof(uint8_t);
pMsg->seesionId = sessionId;
status = cds_send_mb_message_to_mac(pMsg);
+ /*
+ * OBSS SCAN Indication will be sent to Firmware
+ * to start OBSS Scan
+ */
+ if (CSR_IS_CHANNEL_24GHZ(
+ session->connectedProfile.operationChannel)
+ && (session->connectState ==
+ eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)
+ && session->pCurRoamProfile
+ && ((QDF_P2P_CLIENT_MODE ==
+ session->pCurRoamProfile->csrPersona)
+ || (QDF_STA_MODE ==
+ session->pCurRoamProfile->csrPersona))) {
+ struct sme_obss_ht40_scanind_msg *msg;
+ msg = qdf_mem_malloc(sizeof(
+ struct sme_obss_ht40_scanind_msg));
+ msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND;
+ msg->length =
+ sizeof(struct sme_obss_ht40_scanind_msg);
+ qdf_copy_macaddr(&msg->mac_addr,
+ &session->connectedProfile.bssid);
+ status = cds_send_mb_message_to_mac(msg);
+ }
result = eCSR_ROAM_RESULT_AUTHENTICATED;
} else {
result = eCSR_ROAM_RESULT_NONE;
}
- /*
- * OBSS SCAN Indication will be sent to Firmware
- * to start OBSS Scan
- */
- if (CSR_IS_CHANNEL_24GHZ(
- session->connectedProfile.operationChannel)
- && (session->connectState ==
- eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)
- && session->pCurRoamProfile
- && ((QDF_P2P_CLIENT_MODE ==
- session->pCurRoamProfile->csrPersona)
- || (QDF_STA_MODE ==
- session->pCurRoamProfile->csrPersona))) {
- struct sme_obss_ht40_scanind_msg *msg;
- msg = qdf_mem_malloc(sizeof(
- struct sme_obss_ht40_scanind_msg));
- msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND;
- msg->length = sizeof(struct sme_obss_ht40_scanind_msg);
- qdf_copy_macaddr(&msg->mac_addr,
- &session->connectedProfile.bssid);
- status = cds_send_mb_message_to_mac(msg);
- }
roam_info_ptr = &roam_info;
} else {
result = eCSR_ROAM_RESULT_FAILURE;
diff --git a/core/utils/nlink/inc/wlan_nlink_common.h b/core/utils/nlink/inc/wlan_nlink_common.h
index f714d1bd6aa7..9165af0d03d2 100644
--- a/core/utils/nlink/inc/wlan_nlink_common.h
+++ b/core/utils/nlink/inc/wlan_nlink_common.h
@@ -38,6 +38,8 @@
#define WLAN_NLINK_COMMON_H__
#include <linux/netlink.h>
+#include <linux/if.h>
+
/*---------------------------------------------------------------------------
* External Functions
@@ -79,6 +81,7 @@
#define WLAN_SVC_WLAN_VERSION_IND 0x107
#define WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND 0x108
#define WLAN_SVC_WLAN_TP_IND 0x109
+#define WLAN_SVC_RPS_ENABLE_IND 0x10A
#define WLAN_SVC_WLAN_TP_TX_IND 0x10B
#define WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND 0x10C
#define WLAN_SVC_MAX_SSID_LEN 32
@@ -143,6 +146,29 @@ struct wlan_dfs_info {
uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN];
};
+/*
+ * Maximim number of queues supported by WLAN driver. Setting an upper
+ * limit. Actual number of queues may be smaller than this value.
+ */
+#define WLAN_SVC_IFACE_NUM_QUEUES 6
+
+/**
+ * struct wlan_rps_data - structure to send RPS info to cnss-daemon
+ * @ifname: interface name for which the RPS data belongs to
+ * @num_queues: number of rx queues for which RPS data is being sent
+ * @cpu_map_list: array of cpu maps for different rx queues supported by
+ * the wlan driver
+ *
+ * The structure specifies the format of data exchanged between wlan
+ * driver and cnss-daemon. On receipt of the data, cnss-daemon is expected
+ * to apply the 'cpu_map' for each rx queue belonging to the interface 'ifname'
+ */
+struct wlan_rps_data {
+ char ifname[IFNAMSIZ];
+ uint16_t num_queues;
+ uint16_t cpu_map_list[WLAN_SVC_IFACE_NUM_QUEUES];
+};
+
/**
* enum wlan_tp_level - indicates wlan throughput level
* @WLAN_SVC_TP_NONE: used for initialization
diff --git a/core/utils/pktlog/include/pktlog_ac_i.h b/core/utils/pktlog/include/pktlog_ac_i.h
index 7dbf443a6990..5c4e9d6a9265 100644
--- a/core/utils/pktlog/include/pktlog_ac_i.h
+++ b/core/utils/pktlog/include/pktlog_ac_i.h
@@ -43,7 +43,12 @@ struct ath_pktlog_arg {
struct ath_pktlog_info *pl_info;
uint32_t flags;
uint16_t missed_cnt;
+#ifdef HELIUMPLUS
+ uint8_t log_type;
+ uint8_t macId;
+#else
uint16_t log_type;
+#endif
size_t log_size;
uint16_t timestamp;
#ifdef HELIUMPLUS
@@ -59,7 +64,7 @@ char *pktlog_getbuf(struct ol_pktlog_dev_t *pl_dev,
A_STATUS process_tx_info(struct ol_txrx_pdev_t *pdev, void *data);
A_STATUS process_rx_info(void *pdev, void *data);
-A_STATUS process_rx_info_remote(void *pdev, qdf_nbuf_t amsdu);
+A_STATUS process_rx_info_remote(void *pdev, void *data);
A_STATUS process_rate_find(void *pdev, void *data);
A_STATUS process_rate_update(void *pdev, void *data);
diff --git a/core/utils/pktlog/pktlog_internal.c b/core/utils/pktlog/pktlog_internal.c
index 5d7083610323..0519d17e0836 100644
--- a/core/utils/pktlog/pktlog_internal.c
+++ b/core/utils/pktlog/pktlog_internal.c
@@ -69,6 +69,9 @@ void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg)
uint16_t log_type;
size_t log_size;
uint32_t flags;
+#ifdef HELIUMPLUS
+ uint8_t mac_id;
+#endif
if (!plarg) {
printk("Invalid parg in %s\n", __func__);
@@ -76,7 +79,12 @@ void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg)
}
pl_info = plarg->pl_info;
+#ifdef HELIUMPLUS
+ mac_id = plarg->macId;
log_type = plarg->log_type;
+#else
+ log_type = plarg->log_type;
+#endif
log_size = plarg->log_size;
log_buf = pl_info->buf;
flags = plarg->flags;
@@ -100,8 +108,14 @@ void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg)
}
log_hdr = (struct ath_pktlog_hdr *)(log_buf->log_data + cur_wr_offset);
- log_hdr->log_type = log_type;
+
log_hdr->flags = flags;
+#ifdef HELIUMPLUS
+ log_hdr->macId = mac_id;
+ log_hdr->log_type = log_type;
+#else
+ log_hdr->log_type = log_type;
+#endif
log_hdr->size = (uint16_t) log_size;
log_hdr->missed_cnt = plarg->missed_cnt;
log_hdr->timestamp = plarg->timestamp;
@@ -167,7 +181,12 @@ char *pktlog_getbuf(struct ol_pktlog_dev_t *pl_dev,
uint8_t flags = 0;
plarg.pl_info = pl_info;
+#ifdef HELIUMPLUS
+ plarg.macId = pl_hdr->macId;
+ plarg.log_type = pl_hdr->log_type;
+#else
plarg.log_type = pl_hdr->log_type;
+#endif
plarg.log_size = log_size;
plarg.flags = pl_hdr->flags;
plarg.missed_cnt = pl_hdr->missed_cnt;
@@ -379,9 +398,18 @@ A_STATUS process_tx_info(struct ol_txrx_pdev_t *txrx_pdev, void *data)
pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
+#ifdef HELIUMPLUS
+ pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
+ ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
+ ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+ pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
+ ATH_PKTLOG_HDR_MAC_ID_MASK) >>
+ ATH_PKTLOG_HDR_MAC_ID_SHIFT;
+#else
pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+#endif
pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
@@ -501,7 +529,7 @@ A_STATUS process_tx_info(struct ol_txrx_pdev_t *txrx_pdev, void *data)
return A_OK;
}
-A_STATUS process_rx_info_remote(void *pdev, qdf_nbuf_t amsdu)
+A_STATUS process_rx_info_remote(void *pdev, void *data)
{
struct ol_pktlog_dev_t *pl_dev;
struct ath_pktlog_info *pl_info;
@@ -509,19 +537,20 @@ A_STATUS process_rx_info_remote(void *pdev, qdf_nbuf_t amsdu)
struct ath_pktlog_hdr pl_hdr;
struct ath_pktlog_rx_info rxstat_log;
size_t log_size;
+ struct ol_rx_remote_data *r_data = (struct ol_rx_remote_data *)data;
qdf_nbuf_t msdu;
if (!pdev) {
printk("Invalid pdev in %s\n", __func__);
return A_ERROR;
}
- if (!amsdu) {
+ if (!r_data) {
printk("Invalid data in %s\n", __func__);
return A_ERROR;
}
pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev;
pl_info = pl_dev->pl_info;
- msdu = amsdu;
+ msdu = r_data->msdu;
while (msdu) {
rx_desc =
@@ -535,7 +564,12 @@ A_STATUS process_rx_info_remote(void *pdev, qdf_nbuf_t amsdu)
*/
pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
pl_hdr.missed_cnt = 0;
+#if defined(HELIUMPLUS)
+ pl_hdr.macId = r_data->mac_id;
+ pl_hdr.log_type = PKTLOG_TYPE_RX_STAT;
+#else
pl_hdr.log_type = PKTLOG_TYPE_RX_STAT;
+#endif
pl_hdr.size = sizeof(*rx_desc) -
sizeof(struct htt_host_fw_desc_base);
#if defined(HELIUMPLUS)
@@ -576,9 +610,19 @@ A_STATUS process_rx_info(void *pdev, void *data)
pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
+#ifdef HELIUMPLUS
pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+ pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
+ ATH_PKTLOG_HDR_MAC_ID_MASK) >>
+ ATH_PKTLOG_HDR_MAC_ID_SHIFT;
+#else
+ pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
+ ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
+ ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+#endif
+
pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
@@ -627,9 +671,19 @@ A_STATUS process_rate_find(void *pdev, void *data)
pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
+#ifdef HELIUMPLUS
pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+ pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
+ ATH_PKTLOG_HDR_MAC_ID_MASK) >>
+ ATH_PKTLOG_HDR_MAC_ID_SHIFT;
+#else
+ pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
+ ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
+ ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+#endif
+
pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
@@ -674,9 +728,19 @@ A_STATUS process_rate_update(void *pdev, void *data)
pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
+#ifdef HELIUMPLUS
pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+ pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
+ ATH_PKTLOG_HDR_MAC_ID_MASK) >>
+ ATH_PKTLOG_HDR_MAC_ID_SHIFT;
+#else
+ pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
+ ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
+ ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+#endif
+
pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index 3895465b921f..1665af613c16 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -166,6 +166,34 @@
#define WMA_MCAST_IPV4_MAC_ADDR (0x01)
#define WMA_MCAST_IPV6_MAC_ADDR (0x33)
+#define WMA_IS_EAPOL_GET_MIN_LEN 14
+#define WMA_EAPOL_SUBTYPE_GET_MIN_LEN 21
+#define WMA_EAPOL_INFO_GET_MIN_LEN 23
+#define WMA_IS_DHCP_GET_MIN_LEN 38
+#define WMA_DHCP_SUBTYPE_GET_MIN_LEN 0x11D
+#define WMA_DHCP_INFO_GET_MIN_LEN 50
+#define WMA_IS_ARP_GET_MIN_LEN 14
+#define WMA_ARP_SUBTYPE_GET_MIN_LEN 22
+#define WMA_IPV4_PROTO_GET_MIN_LEN 24
+#define WMA_IPV4_PKT_INFO_GET_MIN_LEN 42
+#define WMA_ICMP_SUBTYPE_GET_MIN_LEN 35
+#define WMA_IPV6_PROTO_GET_MIN_LEN 21
+#define WMA_IPV6_PKT_INFO_GET_MIN_LEN 62
+#define WMA_ICMPV6_SUBTYPE_GET_MIN_LEN 55
+
+/**
+ * ds_mode: distribution system mode
+ * @IEEE80211_NO_DS: NO DS at either side
+ * @IEEE80211_TO_DS: DS at receiver side
+ * @IEEE80211_FROM_DS: DS at sender side
+ * @IEEE80211_DS_TO_DS: DS at both sender and revceiver side
+ */
+enum ds_mode {
+ IEEE80211_NO_DS,
+ IEEE80211_TO_DS,
+ IEEE80211_FROM_DS,
+ IEEE80211_DS_TO_DS
+};
/* Roaming default values
* All time and period values are in milliseconds.
@@ -864,6 +892,7 @@ typedef struct {
* @rx_streams: number of rx streams can be used by the vdev
* @chain_mask: chain mask can be used by the vdev
* @mac_id: the mac on which vdev is on
+ * @wep_default_key_idx: wep default index for group key
*
* It stores parameters per vdev in wma.
*/
@@ -940,6 +969,7 @@ struct wma_txrx_node {
uint8_t nss_2g;
uint8_t nss_5g;
bool p2p_lo_in_progress;
+ uint8_t wep_default_key_idx;
};
#if defined(QCA_WIFI_FTM)
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index 7bb5ecaa9a26..a49ad83552f3 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -471,6 +471,7 @@
#define WDA_BPF_SET_INSTRUCTIONS_REQ SIR_HAL_BPF_SET_INSTRUCTIONS_REQ
#define WMA_SET_PDEV_IE_REQ SIR_HAL_SET_PDEV_IE_REQ
+#define WMA_UPDATE_WEP_DEFAULT_KEY SIR_HAL_UPDATE_WEP_DEFAULT_KEY
/* Bit 6 will be used to control BD rate for Management frames */
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c
index 10ddf1dae559..a0ef65830b2b 100644
--- a/core/wma/src/wma_data.c
+++ b/core/wma/src/wma_data.c
@@ -1013,14 +1013,17 @@ QDF_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(uint32_t
return QDF_STATUS_E_FAULT;
}
- /* In WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID fw cannot
- * determine the PDEV on its own, Host needs to specify the PDEV
- * ID in the command.
+ /*
+ * Since there could be up to two instances of OCS in FW (one per MAC),
+ * FW provides the option of enabling and disabling MAS on a per MAC
+ * basis. But, Host does not have enable/disable option for individual
+ * MACs. So, FW agreed for the Host to send down a 'pdev id' of 0.
+ * When 'pdev id' of 0 is used, FW treats this as a SOC level command
+ * and applies the same value to both MACs. Irrespective of the value
+ * of 'WMI_SERVICE_DEPRECATED_REPLACE', the pdev id needs to be '0'
+ * (SOC level) for WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID
*/
- if (wma->wlan_resource_config.use_pdev_id)
- pdev_id = WMA_MAC_TO_PDEV_MAP(0);
- else
- pdev_id = WMI_PDEV_ID_SOC;
+ pdev_id = WMI_PDEV_ID_SOC;
return wmi_unified_set_enable_disable_mcc_adaptive_scheduler_cmd(
wma->wmi_handle, mcc_adaptive_scheduler, pdev_id);
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 89185a0b3ab5..f2c8a87ad3a2 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -33,6 +33,7 @@
/* Header files */
+#include "cds_ieee80211_common.h" /* ieee80211_frame */
#include "wma.h"
#include "wma_api.h"
#include "cds_api.h"
@@ -2348,6 +2349,14 @@ static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason)
return "WOW_REASON_NAN_EVENT";
case WOW_REASON_OEM_RESPONSE_EVENT:
return "WOW_OEM_RESPONSE_EVENT";
+ case WOW_REASON_ASSOC_RES_RECV:
+ return "ASSOC_RES_RECV";
+ case WOW_REASON_REASSOC_REQ_RECV:
+ return "REASSOC_REQ_RECV";
+ case WOW_REASON_REASSOC_RES_RECV:
+ return "REASSOC_RES_RECV";
+ case WOW_REASON_ACTION_FRAME_RECV:
+ return "ACTION_FRAME_RECV";
}
return "unknown";
}
@@ -2617,6 +2626,431 @@ static bool tlv_check_required(int32_t reason)
}
/**
+ * wma_pkt_proto_subtype_to_string() - to convert proto subtype
+ * of data packet to string.
+ * @proto_subtype: proto subtype for data packet
+ *
+ * This function returns the string for the proto subtype of
+ * data packet.
+ *
+ * Return: string for proto subtype for data packet
+ */
+const char *
+wma_pkt_proto_subtype_to_string(enum qdf_proto_subtype proto_subtype)
+{
+ switch (proto_subtype) {
+ case QDF_PROTO_EAPOL_M1:
+ return "EAPOL M1";
+ case QDF_PROTO_EAPOL_M2:
+ return "EAPOL M2";
+ case QDF_PROTO_EAPOL_M3:
+ return "EAPOL M3";
+ case QDF_PROTO_EAPOL_M4:
+ return "EAPOL M4";
+ case QDF_PROTO_DHCP_DISCOVER:
+ return "DHCP DISCOVER";
+ case QDF_PROTO_DHCP_REQUEST:
+ return "DHCP REQUEST";
+ case QDF_PROTO_DHCP_OFFER:
+ return "DHCP OFFER";
+ case QDF_PROTO_DHCP_ACK:
+ return "DHCP ACK";
+ case QDF_PROTO_DHCP_NACK:
+ return "DHCP NACK";
+ case QDF_PROTO_DHCP_RELEASE:
+ return "DHCP RELEASE";
+ case QDF_PROTO_DHCP_INFORM:
+ return "DHCP INFORM";
+ case QDF_PROTO_DHCP_DECLINE:
+ return "DHCP DECLINE";
+ case QDF_PROTO_ARP_REQ:
+ return "ARP REQUEST";
+ case QDF_PROTO_ARP_RES:
+ return "ARP RESPONSE";
+ case QDF_PROTO_ICMP_REQ:
+ return "ICMP REQUEST";
+ case QDF_PROTO_ICMP_RES:
+ return "ICMP RESPONSE";
+ case QDF_PROTO_ICMPV6_REQ:
+ return "ICMPV6 REQUEST";
+ case QDF_PROTO_ICMPV6_RES:
+ return "ICMPV6 RESPONSE";
+ case QDF_PROTO_IPV4_UDP:
+ return "IPV4 UDP Packet";
+ case QDF_PROTO_IPV4_TCP:
+ return "IPV4 TCP Packet";
+ case QDF_PROTO_IPV6_UDP:
+ return "IPV6 UDP Packet";
+ case QDF_PROTO_IPV6_TCP:
+ return "IPV6 TCP Packet";
+ default:
+ return "Invalid Packet";
+ }
+}
+
+/**
+ * wma_wow_get_pkt_proto_subtype() - get the proto subtype
+ * of the packet.
+ * @data: Pointer to data buffer
+ * @len: length of the data buffer
+ *
+ * This function gives the proto subtype of the packet.
+ *
+ * Return: proto subtype of the packet.
+ */
+static enum qdf_proto_subtype
+wma_wow_get_pkt_proto_subtype(uint8_t *data,
+ uint32_t len)
+{
+ uint16_t ether_type = (uint16_t)(*(uint16_t *)(data +
+ QDF_NBUF_TRAC_ETH_TYPE_OFFSET));
+
+ WMA_LOGE("Ether Type: 0x%04x",
+ ani_cpu_to_be16(ether_type));
+
+ if (QDF_NBUF_TRAC_EAPOL_ETH_TYPE ==
+ ani_cpu_to_be16(ether_type)) {
+ if (len >= WMA_EAPOL_SUBTYPE_GET_MIN_LEN)
+ return qdf_nbuf_data_get_eapol_subtype(data);
+ QDF_TRACE(QDF_MODULE_ID_WMA,
+ QDF_TRACE_LEVEL_ERROR, "EAPOL Packet");
+ return QDF_PROTO_INVALID;
+ } else if (QDF_NBUF_TRAC_ARP_ETH_TYPE ==
+ ani_cpu_to_be16(ether_type)) {
+ if (len >= WMA_ARP_SUBTYPE_GET_MIN_LEN)
+ return qdf_nbuf_data_get_arp_subtype(data);
+ QDF_TRACE(QDF_MODULE_ID_WMA,
+ QDF_TRACE_LEVEL_ERROR, "ARP Packet");
+ return QDF_PROTO_INVALID;
+ } else if (QDF_NBUF_TRAC_IPV4_ETH_TYPE ==
+ ani_cpu_to_be16(ether_type)) {
+ if (len >= WMA_IPV4_PROTO_GET_MIN_LEN) {
+ uint8_t proto_type;
+
+ proto_type = qdf_nbuf_data_get_ipv4_proto(data);
+ WMA_LOGE("IPV4_proto_type: %u", proto_type);
+ if (proto_type == QDF_NBUF_TRAC_ICMP_TYPE) {
+ if (len >= WMA_ICMP_SUBTYPE_GET_MIN_LEN)
+ return qdf_nbuf_data_get_icmp_subtype(
+ data);
+ QDF_TRACE(QDF_MODULE_ID_WMA,
+ QDF_TRACE_LEVEL_ERROR, "ICMP Packet");
+ return QDF_PROTO_INVALID;
+ } else if (proto_type == QDF_NBUF_TRAC_UDP_TYPE) {
+ if (len >= WMA_IS_DHCP_GET_MIN_LEN) {
+ if (qdf_nbuf_data_is_ipv4_dhcp_pkt(data)) {
+ if (len >=
+ WMA_DHCP_SUBTYPE_GET_MIN_LEN)
+ return qdf_nbuf_data_get_dhcp_subtype(data);
+ QDF_TRACE(QDF_MODULE_ID_WMA,
+ QDF_TRACE_LEVEL_ERROR,
+ "DHCP Packet");
+ return QDF_PROTO_INVALID;
+ }
+ }
+ return QDF_PROTO_IPV4_UDP;
+ } else if (proto_type == QDF_NBUF_TRAC_TCP_TYPE) {
+ return QDF_PROTO_IPV4_TCP;
+ }
+ }
+ QDF_TRACE(QDF_MODULE_ID_WMA,
+ QDF_TRACE_LEVEL_ERROR, "IPV4 Packet");
+ return QDF_PROTO_INVALID;
+ } else if (QDF_NBUF_TRAC_IPV6_ETH_TYPE ==
+ ani_cpu_to_be16(ether_type)) {
+ if (len >= WMA_IPV6_PROTO_GET_MIN_LEN) {
+ uint8_t proto_type;
+
+ proto_type = qdf_nbuf_data_get_ipv6_proto(data);
+ WMA_LOGE("IPV6_proto_type: %u", proto_type);
+ if (proto_type == QDF_NBUF_TRAC_ICMPV6_TYPE) {
+ if (len >= WMA_ICMPV6_SUBTYPE_GET_MIN_LEN)
+ return qdf_nbuf_data_get_icmpv6_subtype(
+ data);
+ QDF_TRACE(QDF_MODULE_ID_WMA,
+ QDF_TRACE_LEVEL_ERROR, "ICMPV6 Packet");
+ return QDF_PROTO_INVALID;
+ } else if (proto_type == QDF_NBUF_TRAC_UDP_TYPE) {
+ return QDF_PROTO_IPV6_UDP;
+ } else if (proto_type == QDF_NBUF_TRAC_TCP_TYPE) {
+ return QDF_PROTO_IPV6_TCP;
+ }
+ }
+ QDF_TRACE(QDF_MODULE_ID_WMA,
+ QDF_TRACE_LEVEL_ERROR, "IPV6 Packet");
+ return QDF_PROTO_INVALID;
+ }
+
+ return QDF_PROTO_INVALID;
+}
+
+/**
+ * wma_wow_parse_data_pkt_buffer() - API to parse data buffer for data
+ * packet that resulted in WOW wakeup.
+ * @data: Pointer to data buffer
+ * @buf_len: data buffer length
+ *
+ * This function parses the data buffer received (first few bytes of
+ * skb->data) to get informaton like src mac addr, dst mac addr, packet
+ * len, seq_num, etc.
+ *
+ * Return: void
+ */
+static void wma_wow_parse_data_pkt_buffer(uint8_t *data,
+ uint32_t buf_len)
+{
+ enum qdf_proto_subtype proto_subtype;
+ uint16_t pkt_len, key_len, seq_num;
+ uint16_t src_port, dst_port;
+ uint32_t transaction_id, tcp_seq_num;
+
+ WMA_LOGD("wow_buf_pkt_len: %u", buf_len);
+ if (buf_len >= QDF_NBUF_TRAC_IPV4_OFFSET)
+ WMA_LOGE("Src_mac: " MAC_ADDRESS_STR " Dst_mac: " MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(data),
+ MAC_ADDR_ARRAY(data + QDF_NBUF_SRC_MAC_OFFSET));
+ else
+ goto end;
+
+ proto_subtype = wma_wow_get_pkt_proto_subtype(data, buf_len);
+ switch (proto_subtype) {
+ case QDF_PROTO_EAPOL_M1:
+ case QDF_PROTO_EAPOL_M2:
+ case QDF_PROTO_EAPOL_M3:
+ case QDF_PROTO_EAPOL_M4:
+ WMA_LOGE("WOW Wakeup: %s rcvd",
+ wma_pkt_proto_subtype_to_string(proto_subtype));
+ if (buf_len >= WMA_EAPOL_INFO_GET_MIN_LEN) {
+ pkt_len = (uint16_t)(*(uint16_t *)(data +
+ EAPOL_PKT_LEN_OFFSET));
+ key_len = (uint16_t)(*(uint16_t *)(data +
+ EAPOL_KEY_LEN_OFFSET));
+ WMA_LOGE("Pkt_len: %u, Key_len: %u",
+ ani_cpu_to_be16(pkt_len),
+ ani_cpu_to_be16(key_len));
+ }
+ break;
+
+ case QDF_PROTO_DHCP_DISCOVER:
+ case QDF_PROTO_DHCP_REQUEST:
+ case QDF_PROTO_DHCP_OFFER:
+ case QDF_PROTO_DHCP_ACK:
+ case QDF_PROTO_DHCP_NACK:
+ case QDF_PROTO_DHCP_RELEASE:
+ case QDF_PROTO_DHCP_INFORM:
+ case QDF_PROTO_DHCP_DECLINE:
+ WMA_LOGE("WOW Wakeup: %s rcvd",
+ wma_pkt_proto_subtype_to_string(proto_subtype));
+ if (buf_len >= WMA_DHCP_INFO_GET_MIN_LEN) {
+ pkt_len = (uint16_t)(*(uint16_t *)(data +
+ DHCP_PKT_LEN_OFFSET));
+ transaction_id = (uint32_t)(*(uint32_t *)(data +
+ DHCP_TRANSACTION_ID_OFFSET));
+ WMA_LOGE("Pkt_len: %u, Transaction_id: %u",
+ ani_cpu_to_be16(pkt_len),
+ ani_cpu_to_be16(transaction_id));
+ }
+ break;
+
+ case QDF_PROTO_ARP_REQ:
+ case QDF_PROTO_ARP_RES:
+ WMA_LOGE("WOW Wakeup: %s rcvd",
+ wma_pkt_proto_subtype_to_string(proto_subtype));
+ break;
+
+ case QDF_PROTO_ICMP_REQ:
+ case QDF_PROTO_ICMP_RES:
+ WMA_LOGE("WOW Wakeup: %s rcvd",
+ wma_pkt_proto_subtype_to_string(proto_subtype));
+ if (buf_len >= WMA_IPV4_PKT_INFO_GET_MIN_LEN) {
+ pkt_len = (uint16_t)(*(uint16_t *)(data +
+ IPV4_PKT_LEN_OFFSET));
+ seq_num = (uint16_t)(*(uint16_t *)(data +
+ ICMP_SEQ_NUM_OFFSET));
+ WMA_LOGE("Pkt_len: %u, Seq_num: %u",
+ ani_cpu_to_be16(pkt_len),
+ ani_cpu_to_be16(seq_num));
+ }
+ break;
+
+ case QDF_PROTO_ICMPV6_REQ:
+ case QDF_PROTO_ICMPV6_RES:
+ WMA_LOGE("WOW Wakeup: %s rcvd",
+ wma_pkt_proto_subtype_to_string(proto_subtype));
+ if (buf_len >= WMA_IPV6_PKT_INFO_GET_MIN_LEN) {
+ pkt_len = (uint16_t)(*(uint16_t *)(data +
+ IPV6_PKT_LEN_OFFSET));
+ seq_num = (uint16_t)(*(uint16_t *)(data +
+ ICMPV6_SEQ_NUM_OFFSET));
+ WMA_LOGE("Pkt_len: %u, Seq_num: %u",
+ ani_cpu_to_be16(pkt_len),
+ ani_cpu_to_be16(seq_num));
+ }
+ break;
+
+ case QDF_PROTO_IPV4_UDP:
+ case QDF_PROTO_IPV4_TCP:
+ WMA_LOGE("WOW Wakeup: %s rcvd",
+ wma_pkt_proto_subtype_to_string(proto_subtype));
+ if (buf_len >= WMA_IPV4_PKT_INFO_GET_MIN_LEN) {
+ pkt_len = (uint16_t)(*(uint16_t *)(data +
+ IPV4_PKT_LEN_OFFSET));
+ src_port = (uint16_t)(*(uint16_t *)(data +
+ IPV4_SRC_PORT_OFFSET));
+ dst_port = (uint16_t)(*(uint16_t *)(data +
+ IPV4_DST_PORT_OFFSET));
+ WMA_LOGE("Pkt_len: %u",
+ ani_cpu_to_be16(pkt_len));
+ WMA_LOGE("src_port: %u, dst_port: %u",
+ ani_cpu_to_be16(src_port),
+ ani_cpu_to_be16(dst_port));
+ if (proto_subtype == QDF_PROTO_IPV4_TCP) {
+ tcp_seq_num = (uint32_t)(*(uint32_t *)(data +
+ IPV4_TCP_SEQ_NUM_OFFSET));
+ WMA_LOGE("TCP_seq_num: %u",
+ ani_cpu_to_be16(tcp_seq_num));
+ }
+ }
+ break;
+
+ case QDF_PROTO_IPV6_UDP:
+ case QDF_PROTO_IPV6_TCP:
+ WMA_LOGE("WOW Wakeup: %s rcvd",
+ wma_pkt_proto_subtype_to_string(proto_subtype));
+ if (buf_len >= WMA_IPV6_PKT_INFO_GET_MIN_LEN) {
+ pkt_len = (uint16_t)(*(uint16_t *)(data +
+ IPV6_PKT_LEN_OFFSET));
+ src_port = (uint16_t)(*(uint16_t *)(data +
+ IPV6_SRC_PORT_OFFSET));
+ dst_port = (uint16_t)(*(uint16_t *)(data +
+ IPV6_DST_PORT_OFFSET));
+ WMA_LOGE("Pkt_len: %u",
+ ani_cpu_to_be16(pkt_len));
+ WMA_LOGE("src_port: %u, dst_port: %u",
+ ani_cpu_to_be16(src_port),
+ ani_cpu_to_be16(dst_port));
+ if (proto_subtype == QDF_PROTO_IPV6_TCP) {
+ tcp_seq_num = (uint32_t)(*(uint32_t *)(data +
+ IPV6_TCP_SEQ_NUM_OFFSET));
+ WMA_LOGE("TCP_seq_num: %u",
+ ani_cpu_to_be16(tcp_seq_num));
+ }
+ }
+ break;
+
+ default:
+end:
+ WMA_LOGE("wow_buf_pkt_len: %u", buf_len);
+ WMA_LOGE("Invalid Packet Type or Smaller WOW packet buffer than expected");
+ break;
+ }
+}
+
+/**
+ * wma_wow_dump_mgmt_buffer() - API to parse data buffer for mgmt.
+ * packet that resulted in WOW wakeup.
+ * @wow_packet_buffer: Pointer to data buffer
+ * @buf_len: length of data buffer
+ *
+ * This function parses the data buffer received (802.11 header)
+ * to get informaton like src mac addr, dst mac addr, seq_num,
+ * frag_num, etc.
+ *
+ * Return: void
+ */
+static void wma_wow_dump_mgmt_buffer(uint8_t *wow_packet_buffer,
+ uint32_t buf_len)
+{
+ struct ieee80211_frame_addr4 *wh;
+
+ WMA_LOGD("wow_buf_pkt_len: %u", buf_len);
+ wh = (struct ieee80211_frame_addr4 *)
+ (wow_packet_buffer + 4);
+ if (buf_len >= sizeof(struct ieee80211_frame)) {
+ uint8_t to_from_ds, frag_num;
+ uint32_t seq_num;
+
+ WMA_LOGE("RA: " MAC_ADDRESS_STR " TA: " MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(wh->i_addr1),
+ MAC_ADDR_ARRAY(wh->i_addr2));
+
+ WMA_LOGE("TO_DS: %u, FROM_DS: %u",
+ wh->i_fc[1] & IEEE80211_FC1_DIR_TODS,
+ wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS);
+
+ to_from_ds = wh->i_fc[1] & IEEE80211_FC1_DIR_DSTODS;
+
+ switch (to_from_ds) {
+ case IEEE80211_NO_DS:
+ WMA_LOGE("BSSID: " MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(wh->i_addr3));
+ break;
+ case IEEE80211_TO_DS:
+ WMA_LOGE("DA: " MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(wh->i_addr3));
+ break;
+ case IEEE80211_FROM_DS:
+ WMA_LOGE("SA: " MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(wh->i_addr3));
+ break;
+ case IEEE80211_DS_TO_DS:
+ if (buf_len >= sizeof(struct ieee80211_frame_addr4))
+ WMA_LOGE("DA: " MAC_ADDRESS_STR " SA: "
+ MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(wh->i_addr3),
+ MAC_ADDR_ARRAY(wh->i_addr4));
+ break;
+ }
+
+ seq_num = (((*(uint16_t *)wh->i_seq) &
+ IEEE80211_SEQ_SEQ_MASK) >>
+ IEEE80211_SEQ_SEQ_SHIFT);
+ frag_num = (((*(uint16_t *)wh->i_seq) &
+ IEEE80211_SEQ_FRAG_MASK) >>
+ IEEE80211_SEQ_FRAG_SHIFT);
+
+ WMA_LOGE("SEQ_NUM: %u, FRAG_NUM: %u",
+ seq_num, frag_num);
+ } else {
+ WMA_LOGE("Insufficient buffer length for mgmt. packet");
+ }
+}
+
+/**
+ * wma_wow_get_wakelock_duration() - return the wakelock duration
+ * for some mgmt packets received.
+ * @wake_reason: wow wakeup reason
+ *
+ * This function returns the wakelock duration for some mgmt packets
+ * received while in wow suspend.
+ *
+ * Return: wakelock duration
+ */
+static uint32_t wma_wow_get_wakelock_duration(int wake_reason)
+{
+ uint32_t wake_lock_duration = 0;
+
+ switch (wake_reason) {
+ case WOW_REASON_AUTH_REQ_RECV:
+ wake_lock_duration = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT;
+ break;
+ case WOW_REASON_ASSOC_REQ_RECV:
+ wake_lock_duration = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION;
+ break;
+ case WOW_REASON_DEAUTH_RECVD:
+ wake_lock_duration = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION;
+ break;
+ case WOW_REASON_DISASSOC_RECVD:
+ wake_lock_duration = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION;
+ break;
+ default:
+ break;
+ }
+
+ return wake_lock_duration;
+}
+
+/**
* wma_wow_wakeup_host_event() - wakeup host event handler
* @handle: wma handle
* @event: event data
@@ -2686,19 +3120,29 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
switch (wake_info->wake_reason) {
case WOW_REASON_AUTH_REQ_RECV:
- wake_lock_duration = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT;
- break;
-
case WOW_REASON_ASSOC_REQ_RECV:
- wake_lock_duration = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION;
- break;
-
case WOW_REASON_DEAUTH_RECVD:
- wake_lock_duration = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION;
- break;
-
case WOW_REASON_DISASSOC_RECVD:
- wake_lock_duration = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION;
+ case WOW_REASON_ASSOC_RES_RECV:
+ case WOW_REASON_REASSOC_REQ_RECV:
+ case WOW_REASON_REASSOC_RES_RECV:
+ case WOW_REASON_BEACON_RECV:
+ case WOW_REASON_ACTION_FRAME_RECV:
+ wake_lock_duration =
+ wma_wow_get_wakelock_duration(wake_info->wake_reason);
+ if (param_buf->wow_packet_buffer) {
+ /* First 4-bytes of wow_packet_buffer is the length */
+ qdf_mem_copy((uint8_t *) &wow_buf_pkt_len,
+ param_buf->wow_packet_buffer, 4);
+ if (wow_buf_pkt_len)
+ wma_wow_dump_mgmt_buffer(
+ param_buf->wow_packet_buffer,
+ wow_buf_pkt_len);
+ else
+ WMA_LOGE("wow packet buffer is empty");
+ } else {
+ WMA_LOGE("No wow packet buffer present");
+ }
break;
case WOW_REASON_AP_ASSOC_LOST:
@@ -2764,14 +3208,25 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
/* First 4-bytes of wow_packet_buffer is the length */
qdf_mem_copy((uint8_t *) &wow_buf_pkt_len,
param_buf->wow_packet_buffer, 4);
- wma_wow_wake_up_stats(wma,
- param_buf->wow_packet_buffer + 4,
- wow_buf_pkt_len,
- WOW_REASON_PATTERN_MATCH_FOUND);
- qdf_trace_hex_dump(QDF_MODULE_ID_WMA,
- QDF_TRACE_LEVEL_DEBUG,
- param_buf->wow_packet_buffer + 4,
- wow_buf_pkt_len);
+ if (wow_buf_pkt_len) {
+ uint8_t *data;
+
+ wma_wow_wake_up_stats(wma,
+ param_buf->wow_packet_buffer + 4,
+ wow_buf_pkt_len,
+ WOW_REASON_PATTERN_MATCH_FOUND);
+ qdf_trace_hex_dump(QDF_MODULE_ID_WMA,
+ QDF_TRACE_LEVEL_DEBUG,
+ param_buf->wow_packet_buffer + 4,
+ wow_buf_pkt_len);
+
+ data = (uint8_t *)
+ (param_buf->wow_packet_buffer + 4);
+ wma_wow_parse_data_pkt_buffer(data,
+ wow_buf_pkt_len);
+ } else {
+ WMA_LOGE("wow packet buffer is empty");
+ }
} else {
WMA_LOGE("No wow packet buffer present");
}
@@ -6775,6 +7230,15 @@ int wma_get_channels(struct dfs_ieee80211_channel *ichan,
chan_list->nchannels = 0;
if (IEEE80211_IS_CHAN_11AC_VHT160(ichan)) {
+
+ /*
+ * as per the latest draft for BSS bandwidth 160MHz,
+ * channel frequency segment 2 represents the center
+ * channel frequency.
+ */
+ if (ichan->ic_vhtop_ch_freq_seg2)
+ center_chan =
+ cds_freq_to_chan(ichan->ic_vhtop_ch_freq_seg2);
/*
* In 160MHz channel width, need to
* check if each of the 8 20MHz channel
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index f61b13b3011d..6e1695f4313f 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -5217,6 +5217,25 @@ void wma_send_flush_logs_to_fw(tp_wma_handle wma_handle)
}
/**
+ * wma_update_wep_default_key - To update default key id
+ * @wma: pointer to wma handler
+ * @update_def_key: pointer to wep_update_default_key_idx
+ *
+ * This function makes a copy of default key index to txrx node
+ *
+ * Return: Success
+ */
+static QDF_STATUS wma_update_wep_default_key(tp_wma_handle wma,
+ struct wep_update_default_key_idx *update_def_key)
+{
+ struct wma_txrx_node *iface =
+ &wma->interfaces[update_def_key->session_id];
+ iface->wep_default_key_idx = update_def_key->default_idx;
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
* wma_mc_process_msg() - process wma messages and call appropriate function.
* @cds_context: cds context
* @msg: message
@@ -6010,6 +6029,11 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
+ case WMA_UPDATE_WEP_DEFAULT_KEY:
+ wma_update_wep_default_key(wma_handle,
+ (struct wep_update_default_key_idx *)msg->bodyptr);
+ qdf_mem_free(msg->bodyptr);
+ break;
default:
WMA_LOGD("unknow msg type %x", msg->type);
/* Do Nothing? MSG Body should be freed at here */
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index 13d5ff3bd232..d001d5005720 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -1766,6 +1766,11 @@ static void wma_set_ibsskey_helper(tp_wma_handle wma_handle,
key_info->encType == eSIR_ED_WEP104)) {
wma_read_cfg_wepkey(wma_handle, key_info->key,
&def_key_idx, &key_info->numKeys);
+ } else if ((key_info->encType == eSIR_ED_WEP40) ||
+ (key_info->encType == eSIR_ED_WEP104)) {
+ struct wma_txrx_node *intf =
+ &wma_handle->interfaces[key_info->smesessionId];
+ key_params.def_key_idx = intf->wep_default_key_idx;
}
for (i = 0; i < key_info->numKeys; i++) {
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 6af4604dad3b..aa868152d1f5 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -86,12 +86,14 @@
* fire completion events regardless of REPORT_EVENTS_EACH_SCAN.
* @EXTSCAN_REPORT_EVENTS_NO_BATCH: controls batching,
* 0 => batching, 1 => no batching
- */
+ * @EXTSCAN_REPORT_EVENTS_CONTEXT_HUB: forward results to context hub
+ */
enum extscan_report_events_type {
EXTSCAN_REPORT_EVENTS_BUFFER_FULL = 0x00,
EXTSCAN_REPORT_EVENTS_EACH_SCAN = 0x01,
EXTSCAN_REPORT_EVENTS_FULL_RESULTS = 0x02,
EXTSCAN_REPORT_EVENTS_NO_BATCH = 0x04,
+ EXTSCAN_REPORT_EVENTS_CONTEXT_HUB = 0x08,
};
#define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION (5 * 1000) /* in msec */
@@ -3617,6 +3619,8 @@ int wma_extscan_operations_event_handler(void *handle,
WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *param_buf;
wmi_extscan_operation_event_fixed_param *oprn_event;
tSirExtScanOnScanEventIndParams *oprn_ind;
+ uint32_t cnt;
+
tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
if (!pMac) {
WMA_LOGE("%s: Invalid pMac", __func__);
@@ -3644,22 +3648,52 @@ int wma_extscan_operations_event_handler(void *handle,
switch (oprn_event->event) {
case WMI_EXTSCAN_BUCKET_COMPLETED_EVENT:
- oprn_ind->scanEventType = WIFI_SCAN_COMPLETE;
oprn_ind->status = 0;
- break;
+ goto exit_handler;
case WMI_EXTSCAN_CYCLE_STARTED_EVENT:
WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_STARTED_EVENT",
__func__);
qdf_wake_lock_timeout_acquire(&wma->extscan_wake_lock,
WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION,
WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN);
- goto exit_handler;
+ oprn_ind->scanEventType = WIFI_EXTSCAN_CYCLE_STARTED_EVENT;
+ oprn_ind->status = 0;
+ oprn_ind->buckets_scanned = 0;
+ for (cnt = 0; cnt < oprn_event->num_buckets; cnt++)
+ oprn_ind->buckets_scanned |=
+ (1 << param_buf->bucket_id[cnt]);
+ WMA_LOGD(FL("num_buckets %u request_id %u buckets_scanned %u"),
+ oprn_event->num_buckets, oprn_ind->requestId,
+ oprn_ind->buckets_scanned);
+ break;
case WMI_EXTSCAN_CYCLE_COMPLETED_EVENT:
WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_COMPLETED_EVENT",
__func__);
qdf_wake_lock_release(&wma->extscan_wake_lock,
WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN);
+ oprn_ind->scanEventType = WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT;
+ oprn_ind->status = 0;
+ /* Set bucket scanned mask to zero on cycle complete */
+ oprn_ind->buckets_scanned = 0;
+ break;
+ case WMI_EXTSCAN_BUCKET_STARTED_EVENT:
+ WMA_LOGD("%s: received WMI_EXTSCAN_BUCKET_STARTED_EVENT",
+ __func__);
+ oprn_ind->scanEventType = WIFI_EXTSCAN_BUCKET_STARTED_EVENT;
+ oprn_ind->status = 0;
goto exit_handler;
+ case WMI_EXTSCAN_THRESHOLD_NUM_SCANS:
+ WMA_LOGD("%s: received WMI_EXTSCAN_THRESHOLD_NUM_SCANS",
+ __func__);
+ oprn_ind->scanEventType = WIFI_EXTSCAN_THRESHOLD_NUM_SCANS;
+ oprn_ind->status = 0;
+ break;
+ case WMI_EXTSCAN_THRESHOLD_PERCENT:
+ WMA_LOGD("%s: received WMI_EXTSCAN_THRESHOLD_PERCENT",
+ __func__);
+ oprn_ind->scanEventType = WIFI_EXTSCAN_THRESHOLD_PERCENT;
+ oprn_ind->status = 0;
+ break;
default:
WMA_LOGE("%s: Unknown event(%d) from target",
__func__, oprn_event->event);
@@ -4159,6 +4193,7 @@ int wma_extscan_cached_results_event_handler(void *handle,
qdf_mem_zero(dest_cachelist, sizeof(*dest_cachelist));
dest_cachelist->request_id = event->request_id;
dest_cachelist->more_data = moredata;
+ dest_cachelist->buckets_scanned = event->buckets_scanned;
scan_ids_cnt = wma_extscan_find_unique_scan_ids(cmd_param_info);
WMA_LOGI("%s: scan_ids_cnt %d", __func__, scan_ids_cnt);
@@ -4656,6 +4691,11 @@ QDF_STATUS wma_get_buf_extscan_start_cmd(tp_wma_handle wma_handle,
dest_blist->configuration_flags =
WMI_EXTSCAN_BUCKET_CACHE_RESULTS;
+ if (src_bucket->reportEvents &
+ EXTSCAN_REPORT_EVENTS_CONTEXT_HUB)
+ dest_blist->configuration_flags |=
+ WMI_EXTSCAN_REPORT_EVENT_CONTEXT_HUB;
+
WMA_LOGI("%s: ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u",
__func__, dest_blist->notify_extscan_events,
dest_blist->configuration_flags,
diff --git a/uapi/linux/pktlog_ac_fmt.h b/uapi/linux/pktlog_ac_fmt.h
index bde0d3e6fea5..27cd5497f882 100644
--- a/uapi/linux/pktlog_ac_fmt.h
+++ b/uapi/linux/pktlog_ac_fmt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -57,7 +57,12 @@
struct ath_pktlog_hdr {
uint16_t flags;
uint16_t missed_cnt;
+#ifdef HELIUMPLUS
+ uint8_t log_type;
+ uint8_t macId;
+#else
uint16_t log_type;
+#endif
uint16_t size;
uint32_t timestamp;
#ifdef HELIUMPLUS
@@ -71,9 +76,19 @@ struct ath_pktlog_hdr {
#define ATH_PKTLOG_HDR_MISSED_CNT_MASK 0xffff0000
#define ATH_PKTLOG_HDR_MISSED_CNT_SHIFT 16
#define ATH_PKTLOG_HDR_MISSED_CNT_OFFSET 0
+#ifdef HELIUMPLUS
+#define ATH_PKTLOG_HDR_LOG_TYPE_MASK 0x00ff
+#define ATH_PKTLOG_HDR_LOG_TYPE_SHIFT 0
+#define ATH_PKTLOG_HDR_LOG_TYPE_OFFSET 1
+#define ATH_PKTLOG_HDR_MAC_ID_MASK 0xff00
+#define ATH_PKTLOG_HDR_MAC_ID_SHIFT 8
+#define ATH_PKTLOG_HDR_MAC_ID_OFFSET 1
+#else
#define ATH_PKTLOG_HDR_LOG_TYPE_MASK 0xffff
#define ATH_PKTLOG_HDR_LOG_TYPE_SHIFT 0
#define ATH_PKTLOG_HDR_LOG_TYPE_OFFSET 1
+#endif
+
#define ATH_PKTLOG_HDR_SIZE_MASK 0xffff0000
#define ATH_PKTLOG_HDR_SIZE_SHIFT 16
#define ATH_PKTLOG_HDR_SIZE_OFFSET 1