diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-08-20 06:08:08 -0600 |
|---|---|---|
| committer | Linux Build Service Account <lnxbuild@localhost> | 2016-08-20 06:08:08 -0600 |
| commit | f2a58117fced98819db0e88932e7d0daba154de6 (patch) | |
| tree | 015486ad2ee59c837fe4599fa3e242d77c554e5e | |
| parent | 74c7f0da5cae60b0499f842105e44f4f1a7c1c0c (diff) | |
| parent | 2807f3d22e432eb66d11ec755850a24e6ce5f88a (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
60 files changed, 1846 insertions, 406 deletions
@@ -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 |
