summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-05-11 16:39:23 -0600
committerLinux Build Service Account <lnxbuild@localhost>2016-05-11 16:39:24 -0600
commitea0a20e27e2336badc357fc38e47b0223ea388ee (patch)
tree2f2c9cdc1b211194b1680be0136822b0382f2cb2
parentd53871d110dbbc7068bec73ae0d65c212cf0b91d (diff)
parentc332b35416aebedd1623c8b22f3564397665e326 (diff)
Promotion of wlan-cld3.driver.lnx.1.1-00008.
CRs Change ID Subject -------------------------------------------------------------------------------------------------------------- 1001252 I783f4a411044268d24ba660ce9f10dabe0cce8bf qcacld-3.0: BMI: Clean up BMI unused code 1003792 I454ef259dfcc4b7c7860a5adfda605837f4a89cc qcacld-3.0: Use qdf macro for epping mode 912560 I64dff8b7d0836340ce3bec5f5985d1919b600c23 qcacld-3.0: Add scenario based BUG report 1000056 Ica36574c2111753e4e23e2cd30d438a4613eefd8 qcacld-3.0: Correct regdomain definition for Japan 1010214 Ie758476b94561d4d67b0fe051c5a72035f2df0ec qcacld-3.0: Remove ifdefs from __ol_transfer_bin_file 934448 Ib04deac6cf7d61fae1a7bb0d0fb8f4dc652b3217 qcacld-3.0: Add diag event for TDLS teardown 1008835 Id3c4383c385eb3d6391c4c066b0034fb2f053cdc qcacld-3.0: Remove FL macro definition from UMAC layer 1011487 I189e9c92727703655b238b3edd1e3b480a09c17e qcacld-3.0: Initialize max peers before default target c 963060 I4ed9696175e63884b5db682a2a4c4df504a7fb20 qcacld-3.0: Add HTT datapath changes to handle monitor m 1010156 I8747edd0f8fc4bd79f72f7fba4b65d8c6ebd6887 qcacld-3.0: Add support for registering runtime PM APIs 1007367 Ied9ef3dddfcb89bac8d49c5c0dd2f21b3d041567 qcacld-3.0: Remove the vhtTxChannelWidthSet parameter 1011996 I7d2df8337f9feed352430774907aa095affa5a69 qcacld-3.0: Initialize spinlocks used for STA and SAP in 952151 If28b7a30147fc11c67817314021fa502d2d8f5ad qcacld-3.0: Ini change for dyanmic min_rest_time and idl 1009162 If9e2d6a360d814b7f1b0c92789dc0fd3fe3d974b qcacld-3.0: Fix use-after-free crash for trace buffer 1009290 I9dd3cea3b9b2563960dd5d81a661c9ac1e61ac0d qcacld-3.0: Define SLOTS_PER_DATAPATH_TX in common proje 1010524 I7f881d4f6793ec8c85e6f4ab41b90fb77d16f828 qcacld-3.0: Fix the missing propagation in MCC to SCC sw 996332 Ife886f06f170a50149c110073469d8fcf183d39b qcacld-3.0: hdd: Refactor wlan_startup (phase 6) 934455 I19fe216ac0900dedbcb7b247cf0d171979308dc5 qcacld-3.0: Add diag event for offload requests 934449 Ib491d8ac1d8a7850a050bf14a60b6eb08ab94078 qcacld-3.0: Add diag event for TDLS enable link 998555 I8089e01025ba07cc18684c277c36bb1694264214 qcacld-3.0: Correct the p2p scan parameters when SAP is 1010374 I7551b0bab4f11fe2d68c014cf89834ba199ad5ff qcacld-3.0: Fix the issue in processing the del_tspec re 1009636 I1ca8670c43e795d874d4e57bca8577b5fb90468a qcacld-3.1: Fix NULL pointer dereference 1009720 I5a418c15474b355ea3c62c2de45052908f28113c qcacld-3.0: Correct comparison for 5G channel width 1000145 Ia0c2096f243b649088a9dc5ed5e5374cea972e51 qcacld-3.0: Fix the issue with VHT SGI settings in SAP m 949293 I63ca0bea23da1430ca0e6f323555c3ac6b2d07cd qcacld-3.0: Flush Scan results in DRIVER command SET_FCC 885880 Ia7286612d81df3bbb266ba217f548516fa38d3de qcacld-3.0: Remove redundant logs 1011483 Icf975661236dba54d2948484445b0509e15f1da0 qcacld-3.0: Wait for Nss update only in the case of beac 993122 Ib2b8653688400a0bbad9c9c1b1d630025ae4edcb qcacld-3.0: Add ioctl to change concurrency system prefe 1010214 Ic801c5aa1e4019ec0e4ceca7b1818848aae0f365 qcacld-3.0: Remove ifdefs of QCA_SIGNED_SPLIT_BINARY_SUP 989502 I77eab3ead005bbb7f951ce7e077cd661813cb628 qcacld-3.0: Replace soc level references of set mac conf 989502 If2a3f93dcd1947eedce8d4eac8ed936166f7e078 qcacld-3.0: Replace soc level references of set hw reque 934452 Ic9bb815667ea9203d44a3c3cfcecbdbae573e717 qcacld-3.0: Add diag event for suspend and resume 1003793 Ib13385cf0a04730d066ffcd53c1f669c7a5ced60 qcacld-3.0: Add wow_nack to TargetSendSuspendComplete ap 940324 I7a68d4d94745cee2274970196642d5041f09d184 qcacld-3.0: Print mac address in Hex 1006992 I4bce2ee176cae43b6a46c47216ed7ab47a82a54c qcacld-3.0: Modify set hw mode sequence on channel switc 997587 I0f42f4264bfe275b38027998b23a061b9cea135f qcacld-3.0: Save scan results in scan timeout failure 1004031 I0e5620a834dd3fef61d8a5f86ce753b9233bf56e qcacld-3.0: Don't Update default country code when no co 934447 I6ec744518b7a391e4511c503cb858d532ef11322 qcacld-3.0: Add diag event for TDLS management frame tx 1000113 Ie329316dd5646aa2130208e2825bedc4f2aef719 qcacld-3.0: HDD: Use PLD APIs (Part 1) 1010156 Ief52f7b078ea62cae18508b9e523e2a19f3519b3 qcacld-3.0: Add PM semaphore related APIs in PLD 963060 I211ece0a66e2d43bc111e523714942e1557e36f4 qcacld-3.0: Add monitor mode support 996332 Ia09960a832674bfcba0ec9b6e8ddc0cc925ec419 qcacld-3.0: hdd: Refactor wlan_startup (phase 7) 880526 I65943d4428f724c39142d1371c04541fcaba7d83 qcacld-3.0: Add INFO logs in mcast/bcast filtering code 688141 I853be50c2af89206383602430b904bb587aedc84 Release 5.1.0.7 637990 Idfde282fe5167c245a3193466db05d73550a7bb4 qcacld-3.0: Correct log level 974833 Ia0dff3ebbfd557f247a14bcff614b9ccc793cb13 qcacld-3.0: Enable LRO 861452 Ibb0ee1edb5bbb1aed57bccbc15354031b0362198 qcacld-3.0: Modify TDLS log for link setup/Teardown 960473 I63a5f7222de74cbb80d656f20f42d1b8453dce26 qcacld-3.0: Add support for BPF data offload 930199 I53215b866cb90f4addf45e3b6ed8af435eb57842 qcacld-3.0: Dont include ext caps in Assoc request if AP 773076 Ib97128b96ca13569f8d247e3eaa3c86938e426d1 qcacld-3.0: TL cleanup is not invoked for TDLS CONNECTIN 1007217 I6c582bc0635ecae2c37b98d761f72f222c408d2f qcacld-3.0: Add new country XA 989502 Ic5d04ce63fbc582dbecb9052f490189c83094bb5 qcacld-3.0: Replace soc level references of hw mode tran 1006872 I5f19a1e2693f54f9d7938b723d0d57487f842daf qcacld-3.0: Increase HTT Rx Ring 817527 I00d30882bce2f49ee3de3fa189e094c04c0d9943 qcacld-3.0: get tsf from fw 1009549 I3928f8eb2c663b12e40239809e0728d07839317a qcacld-3.0: Fix channel number sent in probe response du 688141 I544f83bd429bd6d4f0fb645db6d08c84d4435dc0 Release 5.1.0.7A 900008 Ieeaef582a04aa90ddcdcc373b00b68442c795337 qcacld-3.0: Change conn_state to connecting before sme_r 1000113 Ic9e8305afc599fa02e80d1b60892cc11b4d4025e qcacld-3.0: Clean up OS wrapper functions 1010156 Icba6ec0952f899a2602751340a45f597eaf87d35 qcacld-3.0: Protect cnss_wlan_pm_control under CONFIG_PC 934456 I00dd9d2a54cbe054b400b2d1cb74c0e14b9a13d7 qcacld-3.0: Add diag event for scan blocked by TDLS. 1007653 Iae10d16b29038a8e321ef74ba591b032eedbe425 qcacld-3.0: Save the requested scan and fw mode config 994569 I0414becbf83718155a9ca51d60f34d0e8ffcd4e3 qcacld-3.0: Configure only valid TSF gpio pin 879049 Ic5104e6fb2d306b488adf2a3919e004e5b57e186 qcacld-3.0: Remove redundant logs 994415 I7e6b40b4c0bd20e967dc0a383b480068e256486f qcacld-3.0: Replace mac_id with pdev_id in WMI PDEV comm 1009784 I1325ad541cf69685606e4905275244e207d95b29 qcalcd-3.0: Fix DFS-3 segment ID propagation from radar 998536 Ia9dcb5f5b0d416f930968957ce8a3166ca7056bc qcacld-3.0: Remove ol_target_status in ol layer 962955 I34eab623243d4674c5fc1d0c8139d80efe5786a7 qcacld-3.0: Avoid unexpected TSF GPIO failure 963060 Ibae71a4799e569bf1f1f4d39b23a7d2183fa40e5 qcacld-3.0: Create PE session for monitor mode 1009274 I2cad80573fc0102f210bb0f7c3f9e22c5f8e16f9 qcacld-3.0: Add hif_ctx to fastpath_cb_register api 996332 Ia6eba5a94889cef4502b71edfab773b6295847d6 qcacld-3.0: hdd: Refactor wlan_startup (phase 8) 944663 I69d6e1b0c8298cab1776264f3e61445c95538729 qcacld-3.0: Remove wlan_hdd_band_p2p_2_4_GHZ 688141 I7797caedfa14af14c0491a7818aab3138178797d Release 5.1.0.6 817527 I442f2de3af4f3946a20bf3f4a9d8c9b285aa7a7c qcacld-3.0: Configure tsf gpio pin 979275 I3571fc70f502dc367c65f13b412cd5d37ee41d3c qcacld-3.0: Add PLD layer 1000552 I57f025f14bed73afeb411ea130ca88b5a4155a60 qcacld-3.0: Fix Kconfig entry for MCC to SCC switch/LFR Change-Id: Ia1fdb8e75e4023b3ec1284498948dc7cc281e5ab CRs-Fixed: 1008835, 1009720, 962955, 1011996, 998555, 1010214, 1007653, 963060, 1001252, 1003792, 1003793, 1007367, 1010524, 1004031, 974833, 885880, 934448, 934449, 944663, 912560, 993122, 934447, 1000145, 1009636, 880526, 940324, 989502, 1006872, 1009162, 952151, 1010374, 1010156, 637990, 994415, 1009290, 996332, 979275, 1006992, 817527, 688141, 1000056, 879049, 930199, 1007217, 1011483, 949293, 998536, 1000552, 1011487, 1009784, 1009274, 900008, 1000113, 1009549, 934452, 934455, 773076, 934456, 994569, 960473, 861452, 997587
-rwxr-xr-xKbuild41
-rw-r--r--Kconfig8
-rw-r--r--config/WCNSS_qcom_cfg.ini4
-rw-r--r--core/bmi/inc/ol_if_athvar.h8
-rw-r--r--core/bmi/src/bmi.c71
-rw-r--r--core/bmi/src/bmi_2.c490
-rw-r--r--core/bmi/src/i_bmi.h14
-rw-r--r--core/bmi/src/ol_fw.c132
-rw-r--r--core/cds/inc/cds_api.h30
-rw-r--r--core/cds/inc/cds_concurrency.h28
-rw-r--r--core/cds/inc/cds_packet.h51
-rw-r--r--core/cds/inc/cds_regdomain.h1
-rw-r--r--core/cds/inc/cds_sched.h4
-rw-r--r--core/cds/src/cds_api.c199
-rw-r--r--core/cds/src/cds_concurrency.c459
-rw-r--r--core/cds/src/cds_packet.c58
-rw-r--r--core/cds/src/cds_reg_service.c6
-rw-r--r--core/cds/src/cds_regdomain.c3
-rw-r--r--core/cds/src/cds_sched.c9
-rw-r--r--core/dp/htt/htt.c21
-rw-r--r--core/dp/htt/htt_h2t.c13
-rw-r--r--core/dp/htt/htt_internal.h1
-rw-r--r--core/dp/htt/htt_rx.c485
-rw-r--r--core/dp/htt/htt_types.h11
-rw-r--r--core/dp/htt/rx_desc.h10
-rw-r--r--core/dp/ol/inc/ol_htt_api.h3
-rw-r--r--core/dp/txrx/ol_rx.c17
-rw-r--r--core/dp/txrx/ol_txrx.c13
-rw-r--r--core/dp/txrx/ol_txrx_types.h1
-rw-r--r--core/hdd/inc/qc_sap_ioctl.h50
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h43
-rw-r--r--core/hdd/inc/wlan_hdd_host_offload.h9
-rw-r--r--core/hdd/inc/wlan_hdd_main.h54
-rw-r--r--core/hdd/inc/wlan_hdd_p2p.h3
-rw-r--r--core/hdd/inc/wlan_hdd_power.h24
-rw-r--r--core/hdd/inc/wlan_hdd_tdls.h50
-rw-r--r--core/hdd/inc/wlan_hdd_tsf.h86
-rw-r--r--core/hdd/inc/wlan_hdd_tx_rx.h4
-rw-r--r--core/hdd/src/wlan_hdd_assoc.c67
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c109
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c618
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.h38
-rw-r--r--core/hdd/src/wlan_hdd_driver_ops.c346
-rw-r--r--core/hdd/src/wlan_hdd_ext_scan.c9
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c170
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.h4
-rw-r--r--core/hdd/src/wlan_hdd_ipa.c25
-rw-r--r--core/hdd/src/wlan_hdd_main.c717
-rw-r--r--core/hdd/src/wlan_hdd_p2p.c28
-rw-r--r--core/hdd/src/wlan_hdd_power.c56
-rw-r--r--core/hdd/src/wlan_hdd_scan.c39
-rw-r--r--core/hdd/src/wlan_hdd_scan.h3
-rw-r--r--core/hdd/src/wlan_hdd_tdls.c132
-rw-r--r--core/hdd/src/wlan_hdd_tsf.c227
-rw-r--r--core/hdd/src/wlan_hdd_tx_rx.c121
-rw-r--r--core/hdd/src/wlan_hdd_wext.c160
-rw-r--r--core/hdd/src/wlan_hdd_wmm.c5
-rw-r--r--core/mac/inc/ani_global.h26
-rw-r--r--core/mac/inc/qwlan_version.h6
-rw-r--r--core/mac/inc/sir_api.h85
-rw-r--r--core/mac/inc/sir_mac_prot_def.h3
-rw-r--r--core/mac/inc/wni_api.h2
-rw-r--r--core/mac/src/dph/dph_hash_table.c3
-rw-r--r--core/mac/src/include/parser_api.h1
-rw-r--r--core/mac/src/include/sir_debug.h3
-rw-r--r--core/mac/src/include/sir_params.h17
-rw-r--r--core/mac/src/pe/include/lim_api.h11
-rw-r--r--core/mac/src/pe/include/lim_session.h3
-rw-r--r--core/mac/src/pe/lim/lim_api.c54
-rw-r--r--core/mac/src/pe/lim/lim_process_message_queue.c170
-rw-r--r--core/mac/src/pe/lim/lim_process_mlm_req_messages.c2
-rw-r--r--core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c1
-rw-r--r--core/mac/src/pe/lim/lim_process_sme_req_messages.c8
-rw-r--r--core/mac/src/pe/lim/lim_process_tdls.c4
-rw-r--r--core/mac/src/pe/lim/lim_prop_exts_utils.c5
-rw-r--r--core/mac/src/pe/lim/lim_send_management_frames.c27
-rw-r--r--core/mac/src/pe/lim/lim_send_sme_rsp_messages.c7
-rw-r--r--core/mac/src/pe/lim/lim_session.c6
-rw-r--r--core/mac/src/pe/lim/lim_utils.c4
-rw-r--r--core/mac/src/sys/legacy/src/utils/src/mac_trace.c4
-rw-r--r--core/mac/src/sys/legacy/src/utils/src/parser_api.c22
-rw-r--r--core/pld/inc/pld_common.h358
-rw-r--r--core/pld/src/pld_common.c1157
-rw-r--r--core/pld/src/pld_internal.h46
-rw-r--r--core/pld/src/pld_pcie.c576
-rw-r--r--core/pld/src/pld_pcie.h202
-rw-r--r--core/pld/src/pld_snoc.c317
-rw-r--r--core/pld/src/pld_snoc.h91
-rw-r--r--core/sap/dfs/inc/dfs.h47
-rw-r--r--core/sap/dfs/src/dfs_phyerr_tlv.c29
-rw-r--r--core/sap/dfs/src/dfs_process_phyerr.c48
-rw-r--r--core/sap/dfs/src/dfs_process_radarevent.c35
-rw-r--r--core/sap/src/sap_api_link_cntl.c146
-rw-r--r--core/sme/inc/csr_api.h17
-rw-r--r--core/sme/inc/csr_internal.h13
-rw-r--r--core/sme/inc/sme_api.h22
-rw-r--r--core/sme/inc/sme_internal.h5
-rw-r--r--core/sme/src/common/sme_api.c301
-rw-r--r--core/sme/src/csr/csr_api_roam.c43
-rw-r--r--core/sme/src/csr/csr_api_scan.c37
-rw-r--r--core/sme/src/csr/csr_inside_api.h2
-rw-r--r--core/sme/src/csr/csr_neighbor_roam.c10
-rw-r--r--core/sme/src/csr/csr_tdls_process.c12
-rw-r--r--core/sme/src/csr/csr_util.c4
-rw-r--r--core/sme/src/qos/sme_qos.c7
-rw-r--r--core/utils/epping/inc/epping_internal.h2
-rw-r--r--core/utils/epping/inc/epping_main.h4
-rw-r--r--core/utils/epping/src/epping_main.c31
-rw-r--r--core/utils/host_diag_log/inc/host_diag_core_event.h80
-rw-r--r--core/utils/host_diag_log/inc/host_diag_event_defs.h8
-rw-r--r--core/utils/logging/inc/wlan_logging_sock_svc.h5
-rw-r--r--core/utils/logging/src/wlan_logging_sock_svc.c46
-rw-r--r--core/utils/nlink/src/wlan_nlink_srv.c3
-rw-r--r--core/wma/inc/wma.h20
-rw-r--r--core/wma/inc/wma_api.h4
-rw-r--r--core/wma/inc/wma_internal.h32
-rw-r--r--core/wma/inc/wma_tgt_cfg.h1
-rw-r--r--core/wma/inc/wma_types.h4
-rw-r--r--core/wma/src/wma_data.c43
-rw-r--r--core/wma/src/wma_dev_if.c42
-rw-r--r--core/wma/src/wma_features.c363
-rw-r--r--core/wma/src/wma_main.c192
-rw-r--r--core/wma/src/wma_mgmt.c1
-rw-r--r--core/wma/src/wma_scan_roam.c186
-rw-r--r--target/inc/wlan_tgt_def_config.h2
-rw-r--r--uapi/linux/osapi_linux.h1
126 files changed, 8209 insertions, 2248 deletions
diff --git a/Kbuild b/Kbuild
index d4da7c54807a..5440b8ac1d24 100755
--- a/Kbuild
+++ b/Kbuild
@@ -129,10 +129,6 @@ ifeq ($(KERNEL_BUILD), 0)
CONFIG_LINUX_QCMBR :=y
endif
- ifeq ($(CONFIG_CNSS_EOS),y)
- CONFIG_FEATURE_BMI_2 :=y
- endif
-
CONFIG_MPC_UT_FRAMEWORK := y
#Flag to enable offload packets feature
@@ -377,6 +373,10 @@ ifeq ($(CONFIG_QCOM_TDLS),y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tdls.o
endif
+ifeq ($(CONFIG_WLAN_SYNC_TSF),y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tsf.o
+endif
+
ifeq ($(CONFIG_MPC_UT_FRAMEWORK),y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_conc_ut.o
endif
@@ -671,11 +671,7 @@ BMI_INC := -I$(WLAN_ROOT)/$(BMI_DIR)/inc
BMI_OBJS := $(BMI_DIR)/src/bmi.o \
$(BMI_DIR)/src/ol_fw.o
-ifeq ($(CONFIG_FEATURE_BMI_2), y)
-BMI_OBJS += $(BMI_DIR)/src/bmi_2.o
-else
BMI_OBJS += $(BMI_DIR)/src/bmi_1.o
-endif
########### WMI ###########
WMI_ROOT_DIR := wmi
@@ -847,6 +843,23 @@ ifeq ($(CONFIG_MPC_UT_FRAMEWORK),y)
WMA_OBJS += $(WMA_SRC_DIR)/wma_utils_ut.o
endif
+############## PLD ##########
+PLD_DIR := core/pld
+PLD_INC_DIR := $(PLD_DIR)/inc
+PLD_SRC_DIR := $(PLD_DIR)/src
+
+PLD_INC := -I$(WLAN_ROOT)/$(PLD_INC_DIR) \
+ -I$(WLAN_ROOT)/$(PLD_SRC_DIR)
+
+PLD_OBJS := $(PLD_SRC_DIR)/pld_common.o
+
+ifeq ($(CONFIG_PCI), y)
+PLD_OBJS += $(PLD_SRC_DIR)/pld_pcie.o
+endif
+ifeq ($(CONFIG_ICNSS),y)
+PLD_OBJS += $(PLD_SRC_DIR)/pld_snoc.o
+endif
+
TARGET_INC := -I$(WLAN_ROOT)/target/inc
LINUX_INC := -Iinclude/linux
@@ -884,6 +897,8 @@ INCS += $(NLINK_INC) \
$(PTT_INC) \
$(WLAN_LOGGING_INC)
+INCS += $(PLD_INC)
+
ifeq ($(CONFIG_REMOVE_PKT_LOG), 0)
INCS += $(PKTLOG_INC)
endif
@@ -917,6 +932,8 @@ OBJS += $(WLAN_LOGGING_OBJS)
OBJS += $(NLINK_OBJS)
OBJS += $(PTT_OBJS)
+OBJS += $(PLD_OBJS)
+
ifeq ($(CONFIG_REMOVE_PKT_LOG), 0)
OBJS += $(PKTLOG_OBJS)
endif
@@ -990,10 +1007,6 @@ CDEFINES += -DFEATURE_NAPI_DEBUG
endif
endif
-ifeq ($(CONFIG_FEATURE_BMI_2), y)
-CDEFINES += -DFEATURE_BMI_2
-endif
-
ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM)))
CDEFINES += -DMSM_PLATFORM
endif
@@ -1339,6 +1352,10 @@ ifeq ($(CONFIG_LINUX_QCMBR),y)
CDEFINES += -DLINUX_QCMBR
endif
+# Enable featue sync tsf between multi devices
+ifeq ($(CONFIG_WLAN_SYNC_TSF), y)
+CDEFINES += -DWLAN_FEATURE_TSF
+endif
# Enable full rx re-order offload for adrastea
ifeq (y, $(filter y, $(CONFIG_CNSS_ADRASTEA) $(CONFIG_ICNSS)))
diff --git a/Kconfig b/Kconfig
index 7155ea2a2b4d..51194f09bec4 100644
--- a/Kconfig
+++ b/Kconfig
@@ -107,11 +107,15 @@ config WLAN_FEATURE_RX_WAKELOCK
bool "Enable RX wake lock feature"
default n
-config FEATURE_LFR_SUBNET_DETECTION
+config WLAN_SYNC_TSF
+ bool "Enable QCOM sync multi devices tsf feature"
+ default n
+
+config LFR_SUBNET_DETECTION
bool "Enable LFR Subnet Change Detection"
default n
-config FEATURE_WLAN_MCC_TO_SCC_SWITCH
+config MCC_TO_SCC_SWITCH
bool "Enable MCC to SCC Switch Logic"
default n
diff --git a/config/WCNSS_qcom_cfg.ini b/config/WCNSS_qcom_cfg.ini
index 8b05331feb13..da8550c68556 100644
--- a/config/WCNSS_qcom_cfg.ini
+++ b/config/WCNSS_qcom_cfg.ini
@@ -593,6 +593,10 @@ gEnableFastPath=1
# 1 - enable
TSOEnable=1
+# Enable Large Receive Offload
+# 0 - disable
+# 1 - enable
+LROEnable=1
END
# Note: Configuration parser would not read anything past the END marker
diff --git a/core/bmi/inc/ol_if_athvar.h b/core/bmi/inc/ol_if_athvar.h
index cf0e1c81634c..1eb13f2f76de 100644
--- a/core/bmi/inc/ol_if_athvar.h
+++ b/core/bmi/inc/ol_if_athvar.h
@@ -45,7 +45,6 @@
#endif
#include "ol_ctrl_addba_api.h"
-typedef void *hif_handle_t;
struct ol_version {
uint32_t host_ver;
@@ -55,13 +54,6 @@ struct ol_version {
uint32_t abi_ver;
};
-typedef enum _ol_target_status {
- OL_TRGET_STATUS_CONNECTED = 0, /* target connected */
- OL_TRGET_STATUS_RESET, /* target got reset */
- OL_TRGET_STATUS_EJECT, /* target got ejected */
- OL_TRGET_STATUS_SUSPEND /*target got suspend */
-} ol_target_status;
-
enum ol_ath_tx_ecodes {
TX_IN_PKT_INCR = 0,
TX_OUT_HDR_COMPL,
diff --git a/core/bmi/src/bmi.c b/core/bmi/src/bmi.c
index 5752ccc0d6e9..fc9969d7d993 100644
--- a/core/bmi/src/bmi.c
+++ b/core/bmi/src/bmi.c
@@ -30,38 +30,6 @@
/* APIs visible to the driver */
-/* BMI_1 refers QCA6174 target; the ADDR is AXI addr */
-#define BMI_1_TEST_ADDR (0xa0000)
-/* BMI_2 ; */
-#define BMI_2_TEST_ADDR (0x6E0000)
-/* Enable BMI_TEST COMMANDs; The Value 0x09 is randomly choosen */
-#define BMI_TEST_ENABLE (0x09)
-
-#ifndef CONFIG_CNSS
-#define SHOULD_RUN_BMI_TEST_COMMANDS false
-#else
-#define SHOULD_RUN_BMI_TEST_COMMANDS (BMI_TEST_ENABLE == cnss_get_bmi_setup())
-#endif
-
-static QDF_STATUS
-bmi_command_test(uint32_t command, uint32_t address, uint8_t *data,
- uint32_t length, struct ol_context *ol_ctx)
-{
- switch (command) {
- case BMI_NO_COMMAND:
- return bmi_no_command(ol_ctx);
- case BMI_WRITE_MEMORY:
- return bmi_write_memory(address, data, length, ol_ctx);
- case BMI_READ_MEMORY:
- return bmi_read_memory(address, data, length, ol_ctx);
- case BMI_EXECUTE:
- return bmi_execute(address, (uint32_t *)data, ol_ctx);
- default:
- break;
- }
- return QDF_STATUS_SUCCESS;
-}
-
QDF_STATUS bmi_init(struct ol_context *ol_ctx)
{
struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
@@ -214,43 +182,6 @@ bmi_get_target_info(struct bmi_target_info *targ_info,
return QDF_STATUS_SUCCESS;
}
-#ifdef FEATURE_BMI_2
-static inline uint32_t bmi_get_test_addr(void)
-{
- return BMI_2_TEST_ADDR;
-}
-#else
-static inline uint32_t bmi_get_test_addr(void)
-{
- return BMI_1_TEST_ADDR;
-}
-#endif
-
-/**
- * run_bmi_test() - run some bmi tests
- * @ol_ctx: bmi context
- *
- */
-static void run_bmi_test(struct ol_context *ol_ctx)
-{
- uint8_t data[10], out[10];
- uint32_t address;
- int32_t ret;
-
- ret = snprintf(data, 10, "ABCDEFGHI");
- BMI_DBG("ret:%d writing data:%s\n", ret, data);
- address = bmi_get_test_addr();
-
- if (bmi_init(ol_ctx) != QDF_STATUS_SUCCESS) {
- BMI_WARN("BMI_INIT Failed; No Memory!");
- return;
- }
- bmi_command_test(BMI_NO_COMMAND, address, data, 9, ol_ctx);
- bmi_command_test(BMI_WRITE_MEMORY, address, data, 9, ol_ctx);
- bmi_command_test(BMI_READ_MEMORY, address, out, 9, ol_ctx);
- BMI_DBG("Output:%s", out);
-}
-
QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx)
{
struct hif_opaque_softc *scn = ol_ctx->scn;
@@ -264,8 +195,6 @@ QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx)
return QDF_STATUS_NOT_INITIALIZED;
}
- if (SHOULD_RUN_BMI_TEST_COMMANDS)
- run_bmi_test(ol_ctx);
return bmi_firmware_download(ol_ctx);
}
diff --git a/core/bmi/src/bmi_2.c b/core/bmi/src/bmi_2.c
deleted file mode 100644
index 59c6dd605461..000000000000
--- a/core/bmi/src/bmi_2.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-#include "i_bmi.h"
-#include "cds_api.h"
-/* This need to defined in firmware interface files.
- * Defining here to address compilation issues.
- * Will be deleted once firmware interface files for
- * target are merged
- */
-#define BMI_LOAD_IMAGE 18
-
-QDF_STATUS
-bmi_no_command(struct ol_context *ol_ctx)
-{
- struct hif_opaque_softc *scn = ol_ctx->scn;
- uint32_t cid;
- int status;
- uint32_t length;
- uint8_t ret = 0;
- struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
- uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
- uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
- qdf_dma_addr_t cmd = info->bmi_cmd_da;
- qdf_dma_addr_t rsp = info->bmi_rsp_da;
-
- if (info->bmi_done) {
- BMI_ERR("Command disallowed: BMI DONE ALREADY");
- return QDF_STATUS_E_PERM;
- }
-
- if (!bmi_cmd_buff || !bmi_rsp_buff) {
- BMI_ERR("No Memory Allocated for BMI CMD/RSP Buffer");
- return QDF_STATUS_NOT_INITIALIZED;
- }
- cid = BMI_NO_COMMAND;
-
- qdf_mem_copy(bmi_cmd_buff, &cid, sizeof(cid));
- length = sizeof(ret);
-
- status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, sizeof(cid),
- bmi_rsp_buff, &length, BMI_EXCHANGE_TIMEOUT_MS);
-
- if (status) {
- BMI_ERR("Failed to write bmi no command status:%d", status);
- return QDF_STATUS_E_FAILURE;
- }
-
- qdf_mem_copy(&ret, bmi_rsp_buff, length);
- if (ret != 0) {
- BMI_ERR("bmi no command response error ret 0x%x", ret);
- return QDF_STATUS_E_FAILURE;
- }
- return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-bmi_done_local(struct ol_context *ol_ctx)
-{
- struct hif_opaque_softc *scn = ol_ctx->scn;
- uint32_t cid;
- int status;
- uint32_t length;
- uint8_t ret = 0;
- struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
- uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
- uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
- qdf_device_t qdf_dev = ol_ctx->qdf_dev;
- qdf_dma_addr_t cmd = info->bmi_cmd_da;
- qdf_dma_addr_t rsp = info->bmi_rsp_da;
-
- if (info->bmi_done) {
- BMI_ERR("Command disallowed");
- return QDF_STATUS_E_PERM;
- }
-
- if (!bmi_cmd_buff || !bmi_rsp_buff) {
- BMI_ERR("No Memory Allocated for BMI CMD/RSP Buffer");
- return QDF_STATUS_NOT_INITIALIZED;
- }
-
- if (!qdf_dev->dev) {
- BMI_ERR("%s Invalid Device pointer", __func__);
- return QDF_STATUS_NOT_INITIALIZED;
- }
-
- cid = BMI_DONE;
-
- qdf_mem_copy(bmi_cmd_buff, &cid, sizeof(cid));
- length = sizeof(ret);
-
- status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, sizeof(cid),
- bmi_rsp_buff, &length, BMI_EXCHANGE_TIMEOUT_MS);
-
- if (status) {
- BMI_ERR("Failed to close BMI on target status:%d", status);
- return QDF_STATUS_E_FAILURE;
- }
- qdf_mem_copy(&ret, bmi_rsp_buff, length);
-
- if (ret != 0) {
- BMI_ERR("BMI DONE response failed:%d", ret);
- return QDF_STATUS_E_FAILURE;
- }
-
- if (info->bmi_cmd_buff) {
- qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
- MAX_BMI_CMDBUF_SZ,
- info->bmi_cmd_buff, info->bmi_cmd_da, 0);
- info->bmi_cmd_buff = NULL;
- info->bmi_cmd_da = 0;
- }
-
- if (info->bmi_rsp_buff) {
- qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
- MAX_BMI_CMDBUF_SZ,
- info->bmi_rsp_buff, info->bmi_rsp_da, 0);
- info->bmi_rsp_buff = NULL;
- info->bmi_rsp_da = 0;
- }
-
- return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS bmi_write_memory(uint32_t address, uint8_t *buffer, uint32_t length,
- struct ol_context *ol_ctx)
-{
- uint32_t cid;
- int status;
- uint32_t rsp_len;
- uint8_t ret = 0;
- uint32_t offset;
- uint32_t remaining, txlen;
- const uint32_t header = sizeof(cid) + sizeof(address) + sizeof(length);
- uint8_t aligned_buffer[BMI_DATASZ_MAX];
- uint8_t *src;
- struct hif_opaque_softc *scn = ol_ctx->scn;
- struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
- uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
- uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
- qdf_dma_addr_t cmd = info->bmi_cmd_da;
- qdf_dma_addr_t rsp = info->bmi_rsp_da;
-
- if (info->bmi_done) {
- BMI_ERR("Command disallowed");
- return QDF_STATUS_E_PERM;
- }
-
- if (!bmi_cmd_buff || !bmi_rsp_buff) {
- BMI_ERR("BMI Initialization is not happened");
- return QDF_STATUS_NOT_INITIALIZED;
- }
-
- bmi_assert(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
- qdf_mem_set(bmi_cmd_buff, 0, BMI_DATASZ_MAX + header);
-
- cid = BMI_WRITE_MEMORY;
- rsp_len = sizeof(ret);
-
- remaining = length;
- while (remaining) {
- src = &buffer[length - remaining];
- if (remaining < (BMI_DATASZ_MAX - header)) {
- if (remaining & 3) {
- /* align it with 4 bytes */
- remaining = remaining + (4 - (remaining & 3));
- memcpy(aligned_buffer, src, remaining);
- src = aligned_buffer;
- }
- txlen = remaining;
- } else {
- txlen = (BMI_DATASZ_MAX - header);
- }
- offset = 0;
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &address,
- sizeof(address));
- offset += sizeof(address);
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &txlen, sizeof(txlen));
- offset += sizeof(txlen);
- qdf_mem_copy(&(bmi_cmd_buff[offset]), src, txlen);
- offset += txlen;
- status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff,
- offset, bmi_rsp_buff, &rsp_len,
- BMI_EXCHANGE_TIMEOUT_MS);
- if (status) {
- BMI_ERR("BMI Write Memory Failed status:%d", status);
- return QDF_STATUS_E_FAILURE;
- }
- qdf_mem_copy(&ret, bmi_rsp_buff, rsp_len);
- if (ret != 0) {
- BMI_ERR("BMI Write memory response fail: %x", ret);
- return QDF_STATUS_E_FAILURE;
- }
- remaining -= txlen; address += txlen;
- }
-
- return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-bmi_read_memory(uint32_t address, uint8_t *buffer,
- uint32_t length, struct ol_context *ol_ctx)
-{
- struct hif_opaque_softc *scn = ol_ctx->scn;
- uint32_t cid;
- int status;
- uint8_t ret = 0;
- uint32_t offset;
- uint32_t remaining, rxlen, rsp_len, total_len;
- struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
- uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
- /* note we reuse the same buffer to receive on */
- uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
- uint32_t size = sizeof(cid) + sizeof(address) + sizeof(length);
- qdf_dma_addr_t cmd = info->bmi_cmd_da;
- qdf_dma_addr_t rsp = info->bmi_rsp_da;
-
- if (info->bmi_done) {
- BMI_ERR("Command disallowed");
- return QDF_STATUS_E_PERM;
- }
- if (!bmi_cmd_buff || !bmi_rsp_buff) {
- BMI_ERR("BMI Initialization is not done");
- return QDF_STATUS_NOT_INITIALIZED;
- }
-
- bmi_assert(BMI_COMMAND_FITS(BMI_DATASZ_MAX + size));
- qdf_mem_set(bmi_cmd_buff, 0, BMI_DATASZ_MAX + size);
- qdf_mem_set(bmi_rsp_buff, 0, BMI_DATASZ_MAX + size);
-
- cid = BMI_READ_MEMORY;
- rsp_len = sizeof(ret);
- remaining = length;
-
- while (remaining) {
- rxlen = (remaining < BMI_DATASZ_MAX - rsp_len) ? remaining :
- (BMI_DATASZ_MAX - rsp_len);
- offset = 0;
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &address,
- sizeof(address));
- offset += sizeof(address);
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &rxlen, sizeof(rxlen));
- offset += sizeof(length);
-
- total_len = rxlen + rsp_len;
-
- status = hif_exchange_bmi_msg(scn, cmd, rsp,
- bmi_cmd_buff,
- offset,
- bmi_rsp_buff,
- &total_len,
- BMI_EXCHANGE_TIMEOUT_MS);
-
- if (status) {
- BMI_ERR("BMI Read memory failed status:%d", status);
- return QDF_STATUS_E_FAILURE;
- }
-
- qdf_mem_copy(&ret, bmi_rsp_buff, rsp_len);
-
- if (ret != 0) {
- BMI_ERR("bmi read memory response fail %x", ret);
- return QDF_STATUS_E_FAILURE;
- }
-
- qdf_mem_copy(&buffer[length - remaining],
- (uint8_t *)bmi_rsp_buff + rsp_len, rxlen);
- remaining -= rxlen; address += rxlen;
- }
-
- return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-bmi_execute(uint32_t address, uint32_t *param, struct ol_context *ol_ctx)
-{
- struct hif_opaque_softc *scn = ol_ctx->scn;
- uint32_t cid;
- int status;
- uint32_t length;
- uint8_t ret = 0;
- struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
- uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
- uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
- qdf_dma_addr_t cmd = info->bmi_cmd_da;
- qdf_dma_addr_t rsp = info->bmi_rsp_da;
-
- if (info->bmi_done) {
- BMI_ERR("Command disallowed");
- return QDF_STATUS_E_PERM;
- }
-
- if (!bmi_cmd_buff || !bmi_rsp_buff) {
- BMI_ERR("No Memory Allocated for bmi buffers");
- return QDF_STATUS_NOT_INITIALIZED;
- }
-
- cid = BMI_EXECUTE;
-
- qdf_mem_copy(bmi_cmd_buff, &cid, sizeof(cid));
- length = sizeof(ret);
-
- status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, sizeof(cid),
- bmi_rsp_buff, &length, BMI_EXCHANGE_TIMEOUT_MS);
-
- if (status) {
- BMI_ERR("Failed to do BMI_EXECUTE status:%d", status);
- return QDF_STATUS_E_FAILURE;
- }
-
- qdf_mem_copy(&ret, bmi_rsp_buff, length);
-
- if (ret != 0) {
- BMI_ERR("%s: ret 0x%x", __func__, ret);
- return QDF_STATUS_E_FAILURE;
- }
- return QDF_STATUS_SUCCESS;
-}
-
-static QDF_STATUS
-bmi_load_image(dma_addr_t address,
- uint32_t size, struct ol_context *ol_ctx)
-{
- uint32_t cid;
- QDF_STATUS status;
- uint32_t offset;
- uint32_t length;
- uint8_t ret = 0;
- struct hif_opaque_softc *scn = ol_ctx->scn;
- struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
- uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
- uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
- qdf_dma_addr_t cmd = info->bmi_cmd_da;
- qdf_dma_addr_t rsp = info->bmi_rsp_da;
-
- uint32_t addr_h, addr_l;
-
- if (info->bmi_done) {
- BMI_ERR("Command disallowed");
- return QDF_STATUS_E_PERM;
- }
-
- if (!bmi_cmd_buff || !bmi_rsp_buff) {
- BMI_ERR("No Memory Allocated for BMI CMD/RSP Buffer");
- return QDF_STATUS_NOT_INITIALIZED;
- }
-
- bmi_assert(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
- qdf_mem_set(bmi_cmd_buff, 0, sizeof(cid) + sizeof(address));
-
-
- BMI_DBG("%s: Enter device: 0x%p, size %d", __func__, scn, size);
-
- cid = BMI_LOAD_IMAGE;
-
- offset = 0;
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- addr_l = address & 0xffffffff;
- addr_h = 0x00;
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &addr_l, sizeof(addr_l));
- offset += sizeof(addr_l);
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &addr_h, sizeof(addr_h));
- offset += sizeof(addr_h);
- qdf_mem_copy(&(bmi_cmd_buff[offset]), &size, sizeof(size));
- offset += sizeof(size);
- length = sizeof(ret);
-
- status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, offset,
- bmi_rsp_buff, &length, BMI_EXCHANGE_TIMEOUT_MS);
-
- if (status) {
- BMI_ERR("BMI Load Image Failed; status:%d", status);
- return QDF_STATUS_E_FAILURE;
- }
-
- qdf_mem_copy(&ret, bmi_rsp_buff, length);
- if (ret != 0) {
- BMI_ERR("%s: ret 0x%x", __func__, ret);
- return QDF_STATUS_E_FAILURE;
- }
- return QDF_STATUS_SUCCESS;
-}
-
-static QDF_STATUS bmi_enable(struct ol_context *ol_ctx)
-{
- struct hif_opaque_softc *scn = ol_ctx->scn;
- struct bmi_target_info targ_info;
- struct image_desc_info image_desc_info;
- QDF_STATUS status;
- struct hif_target_info *tgt_info;
- struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
-
- if (!scn) {
- BMI_ERR("Invalid scn context");
- bmi_assert(0);
- return QDF_STATUS_NOT_INITIALIZED;
- }
-
- tgt_info = hif_get_target_info_handle(scn);
-
- if (info->bmi_cmd_buff == NULL || info->bmi_rsp_buff == NULL) {
- BMI_ERR("bmi_open failed!");
- return QDF_STATUS_NOT_INITIALIZED;
- }
-
- status = bmi_get_target_info(&targ_info, ol_ctx);
- if (status != QDF_STATUS_SUCCESS)
- return status;
-
- BMI_DBG("%s: target type 0x%x, target ver 0x%x", __func__,
- targ_info.target_type, targ_info.target_ver);
-
- tgt_info->target_type = targ_info.target_type;
- tgt_info->target_version = targ_info.target_ver;
-
- if (cnss_get_fw_image(&image_desc_info) != 0) {
- BMI_ERR("Failed to get fw image");
- return QDF_STATUS_E_FAILURE;
- }
-
- status = bmi_load_image(image_desc_info.bdata_addr,
- image_desc_info.bdata_size,
- ol_ctx);
- if (status != QDF_STATUS_SUCCESS) {
- BMI_ERR("Load board data failed! status:%d", status);
- return status;
- }
-
- status = bmi_load_image(image_desc_info.fw_addr,
- image_desc_info.fw_size,
- ol_ctx);
- if (status != QDF_STATUS_SUCCESS)
- BMI_ERR("Load fw image failed! status:%d", status);
-
- return status;
-}
-
-QDF_STATUS bmi_firmware_download(struct ol_context *ol_ctx)
-{
- QDF_STATUS status;
-
- if (NO_BMI)
- return QDF_STATUS_SUCCESS;
-
- status = bmi_init(ol_ctx);
- if (status != QDF_STATUS_SUCCESS) {
- BMI_ERR("BMI_INIT Failed status:%d", status);
- goto end;
- }
-
- status = bmi_enable(ol_ctx);
- if (status != QDF_STATUS_SUCCESS) {
- BMI_ERR("BMI_ENABLE failed status:%d\n", status);
- goto err_bmi_enable;
- }
-
- return status;
-err_bmi_enable:
- bmi_cleanup(ol_ctx);
-end:
- return status;
-}
diff --git a/core/bmi/src/i_bmi.h b/core/bmi/src/i_bmi.h
index ae92ca97f93b..1cdc0d2896ef 100644
--- a/core/bmi/src/i_bmi.h
+++ b/core/bmi/src/i_bmi.h
@@ -40,12 +40,24 @@
#include "bmi.h"
#include "ol_fw.h"
+#ifdef CONFIG_CNSS
+#define QCA_FIRMWARE_FILE fw_files->image_file
+#define QCA_UTF_FIRMWARE_FILE fw_files->utf_file
+#define QCA_BOARD_DATA_FILE fw_files->board_data
+#define QCA_UTF_BOARD_DATA_FILE fw_files->utf_board_data
+#define QCA_OTP_FILE fw_files->otp_data
+#define QCA_SETUP_FILE NULL
+#define QCA_FIRMWARE_EPPING_FILE fw_files->epping_file
+#else
#define QCA_FIRMWARE_FILE "athwlan.bin"
#define QCA_UTF_FIRMWARE_FILE "utf.bin"
#define QCA_BOARD_DATA_FILE "fakeboar.bin"
+#define QCA_UTF_BOARD_DATA_FILE "fakeboar.bin"
#define QCA_OTP_FILE "otp.bin"
#define QCA_SETUP_FILE "athsetup.bin"
#define QCA_FIRMWARE_EPPING_FILE "epping.bin"
+#endif
+
/*
* Note that not all the register locations are accessible.
* A list of accessible target registers are specified with
@@ -187,6 +199,8 @@ QDF_STATUS bmi_firmware_download(struct ol_context *ol_ctx);
QDF_STATUS bmi_done_local(struct ol_context *ol_ctx);
QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx);
QDF_STATUS ol_configure_target(struct ol_context *ol_ctx);
+QDF_STATUS bmi_sign_stream_start(uint32_t address, uint8_t *buffer,
+ uint32_t length, struct ol_context *ol_ctx);
void ramdump_work_handler(void *arg);
struct ol_config_info *ol_get_ini_handle(struct ol_context *ol_ctx);
#endif
diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c
index e47ff72fa311..3314d75c7e36 100644
--- a/core/bmi/src/ol_fw.c
+++ b/core/bmi/src/ol_fw.c
@@ -135,6 +135,18 @@ end:
}
#endif
+#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
+#define SIGNED_SPLIT_BINARY_VALUE true
+#else
+#define SIGNED_SPLIT_BINARY_VALUE false
+#endif
+
+#ifdef CONFIG_CNSS
+#define CONFIG_CNSS_DEFINED true
+#else
+#define CONFIG_CNSS_DEFINED false
+#endif
+
static int
__ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file,
uint32_t address, bool compressed)
@@ -146,15 +158,15 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file,
uint32_t fw_entry_size;
uint8_t *temp_eeprom;
uint32_t board_data_size;
-#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
bool bin_sign = false;
int bin_off, bin_len;
SIGN_HEADER_T *sign_header;
-#endif
struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
uint32_t target_type = tgt_info->target_type;
#if defined(CONFIG_CNSS)
+ /* fw_files variable used in filename assignment macros */
struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx);
+ struct cnss_fw_files *fw_files = &bmi_ctx->fw_files;
#endif
qdf_device_t qdf_dev = ol_ctx->qdf_dev;
@@ -163,95 +175,69 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file,
BMI_ERR("%s: Unknown file type", __func__);
return -1;
case ATH_OTP_FILE:
-#if defined(CONFIG_CNSS)
- filename = bmi_ctx->fw_files.otp_data;
-#else
filename = QCA_OTP_FILE;
-#endif
-#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
- bin_sign = true;
-#endif
+ if (SIGNED_SPLIT_BINARY_VALUE)
+ bin_sign = true;
+
break;
case ATH_FIRMWARE_FILE:
- if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
-#if defined(CONFIG_CNSS)
- filename = bmi_ctx->fw_files.epping_file;
-#else
+ if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
filename = QCA_FIRMWARE_EPPING_FILE;
-#endif
BMI_INFO("%s: Loading epping firmware file %s",
__func__, filename);
break;
}
#ifdef QCA_WIFI_FTM
if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
-#if defined(CONFIG_CNSS)
- filename = bmi_ctx->fw_files.utf_file;
-#else
filename = QCA_UTF_FIRMWARE_FILE;
-#endif
-#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
- bin_sign = true;
-#endif
+ if (SIGNED_SPLIT_BINARY_VALUE)
+ bin_sign = true;
BMI_INFO("%s: Loading firmware file %s",
__func__, filename);
break;
}
#endif
-#if defined(CONFIG_CNSS)
- filename = bmi_ctx->fw_files.image_file;
-#else
filename = QCA_FIRMWARE_FILE;
-#endif
-#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
- bin_sign = true;
-#endif
+ if (SIGNED_SPLIT_BINARY_VALUE)
+ bin_sign = true;
break;
case ATH_PATCH_FILE:
BMI_INFO("%s: no Patch file defined", __func__);
return 0;
case ATH_BOARD_DATA_FILE:
+
#ifdef QCA_WIFI_FTM
if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
-#if defined(CONFIG_CNSS)
- filename = bmi_ctx->fw_files.utf_board_data;
-#else
- filename = QCA_BOARD_DATA_FILE;
-#endif
-#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
- bin_sign = true;
-#endif
+ filename = QCA_UTF_BOARD_DATA_FILE;
+
+ if (SIGNED_SPLIT_BINARY_VALUE)
+ bin_sign = true;
+
BMI_INFO("%s: Loading board data file %s",
__func__, filename);
break;
}
#endif /* QCA_WIFI_FTM */
-#if defined(CONFIG_CNSS)
- filename = bmi_ctx->fw_files.board_data;
-#else
filename = QCA_BOARD_DATA_FILE;
-#endif
-#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
- bin_sign = false;
-#endif
+
+ if (SIGNED_SPLIT_BINARY_VALUE)
+ bin_sign = false;
+
break;
case ATH_SETUP_FILE:
- if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE &&
- !WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
-#ifdef CONFIG_CNSS
+ if (CONFIG_CNSS_DEFINED ||
+ cds_get_conparam() == QDF_GLOBAL_FTM_MODE ||
+ QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
BMI_INFO("%s: no Setup file defined", __func__);
return -1;
-#else
+ } else {
filename = QCA_SETUP_FILE;
-#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
- bin_sign = true;
-#endif
+
+ if (SIGNED_SPLIT_BINARY_VALUE)
+ bin_sign = true;
+
BMI_INFO("%s: Loading setup file %s",
__func__, filename);
-#endif /* CONFIG_CNSS */
- } else {
- BMI_INFO("%s: no Setup file needed", __func__);
- return -1;
}
break;
}
@@ -362,8 +348,8 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file,
fw_entry_size = board_data_size;
}
}
-#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
- if (bin_sign) {
+
+ if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) {
uint32_t chip_id;
if (fw_entry_size < sizeof(SIGN_HEADER_T)) {
@@ -417,7 +403,7 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file,
}
}
- if (bin_sign) {
+ if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) {
bin_off += bin_len;
bin_len = sign_header->total_len - sign_header->rampatch_len;
@@ -429,23 +415,6 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file,
BMI_ERR("sign stream error");
}
}
-#else
- if (compressed) {
- status = bmi_fast_download(address,
- (uint8_t *) fw_entry->data,
- fw_entry_size, ol_ctx);
- } else {
- if (file == ATH_BOARD_DATA_FILE && fw_entry->data) {
- status = bmi_write_memory(address,
- (uint8_t *) temp_eeprom,
- fw_entry_size, ol_ctx);
- } else {
- status = bmi_write_memory(address,
- (uint8_t *) fw_entry->data,
- fw_entry_size, ol_ctx);
- }
- }
-#endif /* QCA_SIGNED_SPLIT_BINARY_SUPPORT */
end:
if (temp_eeprom)
@@ -621,8 +590,7 @@ void ol_target_failure(void *instance, QDF_STATUS status)
struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
int ret;
#endif
- ol_target_status target_status =
- hif_get_target_status(scn);
+ enum hif_target_status target_status = hif_get_target_status(scn);
if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SNOC) {
BMI_ERR("SNOC doesn't suppor this code path!");
@@ -631,12 +599,12 @@ void ol_target_failure(void *instance, QDF_STATUS status)
qdf_event_set(&wma->recovery_event);
- if (OL_TRGET_STATUS_RESET == target_status) {
+ if (TARGET_STATUS_RESET == target_status) {
BMI_ERR("Target is already asserted, ignore!");
return;
}
- hif_set_target_status(scn, OL_TRGET_STATUS_RESET);
+ hif_set_target_status(scn, TARGET_STATUS_RESET);
if (cds_is_driver_recovering()) {
BMI_ERR("%s: Recovery in progress, ignore!\n", __func__);
@@ -1296,9 +1264,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx)
/* Execute the OTP code only if entry found and downloaded */
if (status == EOK) {
param = 0;
-#ifndef FEATURE_BMI_2
bmi_execute(address, &param, ol_ctx);
-#endif
} else if (status < 0) {
return status;
}
@@ -1307,9 +1273,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx)
if (ol_transfer_bin_file(ol_ctx, ATH_SETUP_FILE,
BMI_SEGMENTED_WRITE_ADDR, true) == EOK) {
param = 0;
-#ifndef FEATURE_BMI_2
bmi_execute(address, &param, ol_ctx);
-#endif
}
/* Download Target firmware
@@ -1332,9 +1296,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx)
(uint8_t *) &address, 4, ol_ctx);
}
- if (ini_cfg->enable_uart_print ||
- (WLAN_IS_EPPING_ENABLED(cds_get_conparam()) &&
- WLAN_IS_EPPING_FW_UART(cds_get_conparam()))) {
+ if (ini_cfg->enable_uart_print) {
switch (target_version) {
case AR6004_VERSION_REV1_3:
param = 11;
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h
index 103514657291..5b85fa1b0a48 100644
--- a/core/cds/inc/cds_api.h
+++ b/core/cds/inc/cds_api.h
@@ -231,15 +231,37 @@ void cds_set_multicast_logging(uint8_t value);
uint8_t cds_is_multicast_logging(void);
QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
uint32_t type,
- uint32_t sub_type);
-void cds_get_log_completion(uint32_t *is_fatal,
+ uint32_t sub_type,
+ bool recovery_needed);
+void cds_get_and_reset_log_completion(uint32_t *is_fatal,
uint32_t *type,
- uint32_t *sub_type);
+ uint32_t *sub_type,
+ bool *recovery_needed);
bool cds_is_log_report_in_progress(void);
+bool cds_is_fatal_event_enabled(void);
+uint32_t cds_get_log_indicator(void);
+void cds_set_fatal_event(bool value);
+void cds_wlan_flush_host_logs_for_fatal(void);
+
void cds_init_log_completion(void);
void cds_deinit_log_completion(void);
QDF_STATUS cds_flush_logs(uint32_t is_fatal,
uint32_t indicator,
- uint32_t reason_code);
+ uint32_t reason_code,
+ bool dump_mac_trace,
+ bool recovery_needed);
void cds_logging_set_fw_flush_complete(void);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
+ uint8_t type, uint8_t sub_type, uint8_t *peer_mac);
+#else
+static inline
+void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
+ uint8_t type, uint8_t sub_type, uint8_t *peer_mac)
+
+{
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
#endif /* if !defined __CDS_API_H */
diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h
index 45e37f8b0f94..fd44258ef48f 100644
--- a/core/cds/inc/cds_concurrency.h
+++ b/core/cds/inc/cds_concurrency.h
@@ -172,6 +172,18 @@ enum cds_con_mode {
};
/**
+ * enum cds_mac_use - MACs that are used
+ * @CDS_MAC0: Only MAC0 is used
+ * @CDS_MAC1: Only MAC1 is used
+ * @CDS_MAC0_AND_MAC1: Both MAC0 and MAC1 are used
+ */
+enum cds_mac_use {
+ CDS_MAC0 = 1,
+ CDS_MAC1 = 2,
+ CDS_MAC0_AND_MAC1 = 3
+};
+
+/**
* enum cds_pcl_type - Various types of Preferred channel list (PCL).
*
* @CDS_NONE: No channel preference
@@ -481,8 +493,8 @@ enum cds_two_connection_mode {
* @CDS_NOP: No action
* @CDS_DBS: switch to DBS mode
* @CDS_DBS_DOWNGRADE: switch to DBS mode & downgrade to 1x1
- * @CDS_MCC: switch to MCC/SCC mode
- * @CDS_MCC_UPGRADE: switch to MCC/SCC mode & upgrade to 2x2
+ * @CDS_SINGLE_MAC: switch to MCC/SCC mode
+ * @CDS_SINGLE_MAC_UPGRADE: switch to MCC/SCC mode & upgrade to 2x2
* @CDS_MAX_CONC_PRIORITY_MODE: Max place holder
*
* These are generic IDs that identify the various roles
@@ -492,8 +504,8 @@ enum cds_conc_next_action {
CDS_NOP = 0,
CDS_DBS,
CDS_DBS_DOWNGRADE,
- CDS_MCC,
- CDS_MCC_UPGRADE,
+ CDS_SINGLE_MAC,
+ CDS_SINGLE_MAC_UPGRADE,
CDS_MAX_CONC_NEXT_ACTION
};
@@ -540,8 +552,6 @@ struct cds_conc_connection_info {
bool in_use;
};
-enum cds_conc_next_action cds_get_pref_hw_mode_for_chan(uint32_t vdev_id,
- uint32_t target_channel);
bool cds_is_connection_in_progress(void);
void cds_dump_concurrency_info(void);
void cds_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode);
@@ -698,7 +708,7 @@ static inline struct cds_conc_connection_info *cds_get_conn_info(uint32_t *len)
enum cds_con_mode cds_convert_device_mode_to_qdf_type(
enum tQDF_ADAPTER_MODE device_mode);
-QDF_STATUS cds_soc_set_hw_mode(uint32_t session_id,
+QDF_STATUS cds_pdev_set_hw_mode(uint32_t session_id,
enum hw_mode_ss_config mac0_ss,
enum hw_mode_bandwidth mac0_bw,
enum hw_mode_ss_config mac1_ss,
@@ -746,4 +756,8 @@ 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);
QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight);
+QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id);
+void cds_set_do_hw_mode_change_flag(bool flag);
+bool cds_is_hw_mode_change_after_vdev_up(void);
+void cds_dump_connection_status_info(void);
#endif /* __CDS_CONCURRENCY_H */
diff --git a/core/cds/inc/cds_packet.h b/core/cds/inc/cds_packet.h
index f63e9033345c..e85ebb3d34a6 100644
--- a/core/cds/inc/cds_packet.h
+++ b/core/cds/inc/cds_packet.h
@@ -76,42 +76,37 @@ uint8_t cds_pkt_get_proto_type
(struct sk_buff *skb, uint8_t tracking_map, uint8_t dot11_type);
#ifdef QCA_PKT_PROTO_TRACE
-/*---------------------------------------------------------------------------
-
-* brief cds_pkt_trace_buf_update() -
- Update storage buffer with interest event string
-
-* event_string Event String may packet type or outstanding event
-
- ---------------------------------------------------------------------------*/
+/**
+ * cds_pkt_trace_buf_update() - Update storage buffer with interest event string
+ * @event_string: string may be a packet type or an outstanding event
+ *
+ * Return: none
+ */
void cds_pkt_trace_buf_update(char *event_string);
-/*---------------------------------------------------------------------------
-
-* brief cds_pkt_trace_buf_dump() -
- Dump stored information into kernel log
-
- ---------------------------------------------------------------------------*/
+/**
+ * cds_pkt_trace_buf_dump() - Dump stored information into kernel log
+ *
+ * Return: none
+ */
void cds_pkt_trace_buf_dump(void);
-/*---------------------------------------------------------------------------
-
-* brief cds_pkt_proto_trace_init() -
- Initialize protocol trace functionality, allocate required resource
-
- ---------------------------------------------------------------------------*/
+/**
+ * cds_pkt_proto_trace_init() - Initialize protocol trace functionality
+ *
+ * Return: none
+ */
void cds_pkt_proto_trace_init(void);
-/*---------------------------------------------------------------------------
-
-* brief cds_pkt_proto_trace_close() -
- Free required resource
-
- ---------------------------------------------------------------------------*/
-void cds_pkt_proto_trace_close(void);
+/**
+ * cds_pkt_proto_trace_deinit() - Free protocol trace buffer resource
+ *
+ * Return: none
+ */
+void cds_pkt_proto_trace_deinit(void);
#else
static inline void cds_pkt_proto_trace_init(void) { }
-static inline void cds_pkt_proto_trace_close(void) {}
+static inline void cds_pkt_proto_trace_deinit(void) {}
#endif /* QCA_PKT_PROTO_TRACE */
/**
diff --git a/core/cds/inc/cds_regdomain.h b/core/cds/inc/cds_regdomain.h
index 447eec39821a..9fc4d744d63d 100644
--- a/core/cds/inc/cds_regdomain.h
+++ b/core/cds/inc/cds_regdomain.h
@@ -290,6 +290,7 @@ enum country_code {
CTRY_JAPAN49 = 4049,
CTRY_JAPAN55 = 4055,
CTRY_JAPAN56 = 4056,
+ CTRY_XA = 4100,
};
enum reg_domain {
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index 46908e6701f6..cc082411e125 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -209,6 +209,7 @@ typedef struct _cds_sched_context {
* @indicator: Source of bug report
* @reason_code: Reason code for bug report
* @is_report_in_progress: If bug report is in progress
+ * @recovery_needed: if recovery is needed after report completion
*
* This structure internally stores the log related params
*/
@@ -217,6 +218,7 @@ struct cds_log_complete {
uint32_t indicator;
uint32_t reason_code;
bool is_report_in_progress;
+ bool recovery_needed;
};
/*
@@ -291,6 +293,8 @@ typedef struct _cds_context_type {
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t);
#endif
+ bool do_hw_mode_change;
+ bool enable_fatal_event;
} cds_context_type, *p_cds_contextType;
/*---------------------------------------------------------------------------
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index cc950b32ae7b..e0648122ad8d 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -130,6 +130,36 @@ void cds_deinit(void)
return;
}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * cds_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event
+ * @event_id: event id
+ * @tx_rx: tx or rx
+ * @type: type of frame
+ * @action_sub_type: action frame type
+ * @peer_mac: peer mac
+ *
+ * This Function sends tdls mgmt rx tx diag event
+ *
+ * Return: void.
+ */
+void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
+ uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac)
+{
+ WLAN_HOST_DIAG_EVENT_DEF(tdls_tx_rx_mgmt,
+ struct host_event_tdls_tx_rx_mgmt);
+
+ tdls_tx_rx_mgmt.event_id = event_id;
+ tdls_tx_rx_mgmt.tx_rx = tx_rx;
+ tdls_tx_rx_mgmt.type = type;
+ tdls_tx_rx_mgmt.action_sub_type = action_sub_type;
+ qdf_mem_copy(tdls_tx_rx_mgmt.peer_mac,
+ peer_mac, CDS_MAC_ADDRESS_LEN);
+ WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt,
+ EVENT_WLAN_TDLS_TX_RX_MGMT);
+}
+#endif
+
#ifdef WLAN_FEATURE_NAN
/**
* cds_set_nan_enable() - set nan enable flag in mac open param
@@ -193,6 +223,9 @@ QDF_STATUS cds_open(void)
/* Initialize bug reporting structure */
cds_init_log_completion();
+ /* Initialize protocol trace functionality */
+ cds_pkt_proto_trace_init();
+
/* Initialize the probe event */
if (qdf_event_create(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
@@ -823,6 +856,9 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context)
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
}
+ /* De-Initialize protocol trace functionality */
+ cds_pkt_proto_trace_deinit();
+
cds_deinit_log_completion();
gp_cds_context->pHDDContext = NULL;
@@ -1314,11 +1350,15 @@ QDF_STATUS cds_mq_post_message(CDS_MQ_ID msgQueueId, cds_msg_t *pMsg)
if (NULL == pMsgWrapper) {
debug_count = atomic_inc_return(&cds_wrapper_empty_count);
- if (1 == debug_count)
+ if (1 == debug_count) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"%s: CDS Core run out of message wrapper %d",
__func__, debug_count);
-
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_ONLY,
+ WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
+ true, false);
+ }
if (CDS_WRAPPER_MAX_FAIL_COUNT == debug_count)
QDF_BUG(0);
@@ -1548,6 +1588,9 @@ QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type,
case QDF_IBSS_MODE:
*type = WMI_VDEV_TYPE_IBSS;
break;
+ case QDF_MONITOR_MODE:
+ *type = WMI_VDEV_TYPE_MONITOR;
+ break;
default:
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"Invalid device mode %d", mode);
@@ -1565,11 +1608,7 @@ QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type,
*/
void cds_flush_work(void *work)
{
-#if defined (CONFIG_CNSS)
- cnss_flush_work(work);
-#elif defined (WLAN_OPEN_SOURCE)
cancel_work_sync(work);
-#endif
}
/**
@@ -1580,11 +1619,7 @@ void cds_flush_work(void *work)
*/
void cds_flush_delayed_work(void *dwork)
{
-#if defined (CONFIG_CNSS)
- cnss_flush_delayed_work(dwork);
-#elif defined (WLAN_OPEN_SOURCE)
cancel_delayed_work_sync(dwork);
-#endif
}
/**
@@ -1663,15 +1698,10 @@ void cds_trigger_recovery(void)
uint64_t cds_get_monotonic_boottime(void)
{
-#ifdef CONFIG_CNSS
struct timespec ts;
- cnss_get_monotonic_boottime(&ts);
+ get_monotonic_boottime(&ts);
return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
-#else
- return ((uint64_t)qdf_system_ticks_to_msecs(qdf_system_ticks()) *
- 1000);
-#endif
}
/**
@@ -1891,6 +1921,7 @@ void cds_deinit_log_completion(void)
* @is_fatal: Indicates if the event triggering bug report is fatal or not
* @indicator: Source which trigerred the bug report
* @reason_code: Reason for triggering bug report
+ * @recovery_needed: If recovery is needed after bug report
*
* This function is used to set the logging parameters based on the
* caller
@@ -1899,7 +1930,8 @@ void cds_deinit_log_completion(void)
*/
QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
uint32_t indicator,
- uint32_t reason_code)
+ uint32_t reason_code,
+ bool recovery_needed)
{
p_cds_contextType p_cds_context;
@@ -1914,24 +1946,27 @@ QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
p_cds_context->log_complete.is_fatal = is_fatal;
p_cds_context->log_complete.indicator = indicator;
p_cds_context->log_complete.reason_code = reason_code;
+ p_cds_context->log_complete.recovery_needed = recovery_needed;
p_cds_context->log_complete.is_report_in_progress = true;
qdf_spinlock_release(&p_cds_context->bug_report_lock);
return QDF_STATUS_SUCCESS;
}
/**
- * cds_get_log_completion() - Get the logging related params
+ * cds_get_and_reset_log_completion() - Get and reset logging related params
* @is_fatal: Indicates if the event triggering bug report is fatal or not
* @indicator: Source which trigerred the bug report
* @reason_code: Reason for triggering bug report
+ * @recovery_needed: If recovery is needed after bug report
*
* This function is used to get the logging related parameters
*
* Return: None
*/
-void cds_get_log_completion(uint32_t *is_fatal,
+void cds_get_and_reset_log_completion(uint32_t *is_fatal,
uint32_t *indicator,
- uint32_t *reason_code)
+ uint32_t *reason_code,
+ bool *recovery_needed)
{
p_cds_contextType p_cds_context;
@@ -1946,7 +1981,14 @@ void cds_get_log_completion(uint32_t *is_fatal,
*is_fatal = p_cds_context->log_complete.is_fatal;
*indicator = p_cds_context->log_complete.indicator;
*reason_code = p_cds_context->log_complete.reason_code;
+ *recovery_needed = p_cds_context->log_complete.recovery_needed;
+
+ /* reset */
+ p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
+ p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
p_cds_context->log_complete.is_report_in_progress = false;
+ p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
+ p_cds_context->log_complete.recovery_needed = false;
qdf_spinlock_release(&p_cds_context->bug_report_lock);
}
@@ -1971,10 +2013,79 @@ bool cds_is_log_report_in_progress(void)
}
/**
+ * cds_is_fatal_event_enabled() - Return if fatal event is enabled
+ *
+ * Return true if fatal event is enabled.
+ */
+bool cds_is_fatal_event_enabled(void)
+{
+ p_cds_contextType p_cds_context;
+
+ p_cds_context = cds_get_global_context();
+ if (!p_cds_context) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: cds context is Invalid", __func__);
+ return false;
+ }
+
+
+ return p_cds_context->enable_fatal_event;
+}
+
+/**
+ * cds_get_log_indicator() - Get the log flush indicator
+ *
+ * This function is used to get the log flush indicator
+ *
+ * Return: log indicator
+ */
+uint32_t cds_get_log_indicator(void)
+{
+ p_cds_contextType p_cds_context;
+ uint32_t indicator;
+
+ p_cds_context = cds_get_global_context();
+ if (!p_cds_context) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: cds context is Invalid", __func__);
+ return WLAN_LOG_INDICATOR_UNUSED;
+ }
+
+ if (cds_is_load_or_unload_in_progress() ||
+ cds_is_driver_recovering()) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: vos context initialization is in progress"
+ , __func__);
+ return WLAN_LOG_INDICATOR_UNUSED;
+ }
+
+ qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
+ indicator = p_cds_context->log_complete.indicator;
+ qdf_spinlock_release(&p_cds_context->bug_report_lock);
+ return indicator;
+}
+
+/**
+ * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
+ *
+ * This function is used to send signal to the logger thread to
+ * flush the host logs.
+ *
+ * Return: None
+ *
+ */
+void cds_wlan_flush_host_logs_for_fatal(void)
+{
+ wlan_flush_host_logs_for_fatal();
+}
+
+/**
* cds_flush_logs() - Report fatal event to userspace
* @is_fatal: Indicates if the event triggering bug report is fatal or not
* @indicator: Source which trigerred the bug report
* @reason_code: Reason for triggering bug report
+ * @dump_mac_trace: If mac trace are needed in logs.
+ * @recovery_needed: If recovery is needed after bug report
*
* This function sets the log related params and send the WMI command to the
* FW to flush its logs. On receiving the flush completion event from the FW
@@ -1984,7 +2095,9 @@ bool cds_is_log_report_in_progress(void)
*/
QDF_STATUS cds_flush_logs(uint32_t is_fatal,
uint32_t indicator,
- uint32_t reason_code)
+ uint32_t reason_code,
+ bool dump_mac_trace,
+ bool recovery_needed)
{
uint32_t ret;
QDF_STATUS status;
@@ -1997,6 +2110,17 @@ QDF_STATUS cds_flush_logs(uint32_t is_fatal,
"%s: cds context is Invalid", __func__);
return QDF_STATUS_E_FAILURE;
}
+ if (!p_cds_context->enable_fatal_event) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: Fatal event not enabled", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (cds_is_load_or_unload_in_progress() ||
+ cds_is_driver_recovering()) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: un/Load/SSR in progress", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
if (cds_is_log_report_in_progress() == true) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
@@ -2005,17 +2129,26 @@ QDF_STATUS cds_flush_logs(uint32_t is_fatal,
return QDF_STATUS_E_FAILURE;
}
- status = cds_set_log_completion(is_fatal, indicator, reason_code);
+ status = cds_set_log_completion(is_fatal, indicator,
+ reason_code, recovery_needed);
if (QDF_STATUS_SUCCESS != status) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"%s: Failed to set log trigger params", __func__);
return QDF_STATUS_E_FAILURE;
}
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
__func__, is_fatal, indicator, reason_code);
+ if (dump_mac_trace)
+ qdf_trace_dump_all(p_cds_context->pMACContext, 0, 0, 500, 0);
+
+ if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
+ cds_wlan_flush_host_logs_for_fatal();
+ return QDF_STATUS_SUCCESS;
+ }
+
ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
if (0 != ret) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
@@ -2040,3 +2173,23 @@ void cds_logging_set_fw_flush_complete(void)
{
wlan_logging_set_fw_flush_complete();
}
+
+/**
+ * cds_set_fatal_event() - set fatal event status
+ * @value: pending statue to set
+ *
+ * Return: None
+ */
+void cds_set_fatal_event(bool value)
+{
+ p_cds_contextType p_cds_context;
+
+ p_cds_context = cds_get_global_context();
+ if (!p_cds_context) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: cds context is Invalid", __func__);
+ return;
+ }
+ p_cds_context->enable_fatal_event = value;
+}
+
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index f211ace0dfc5..bf67f59c75c2 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -1927,9 +1927,9 @@ bool cds_is_sta_connection_pending(void)
return false;
}
- spin_lock(&hdd_ctx->sta_update_info_lock);
+ qdf_spin_lock(&hdd_ctx->sta_update_info_lock);
status = hdd_ctx->is_sta_connection_pending;
- spin_unlock(&hdd_ctx->sta_update_info_lock);
+ qdf_spin_unlock(&hdd_ctx->sta_update_info_lock);
return status;
}
@@ -1952,9 +1952,9 @@ void cds_change_sta_conn_pending_status(bool value)
return;
}
- spin_lock(&hdd_ctx->sta_update_info_lock);
+ qdf_spin_lock(&hdd_ctx->sta_update_info_lock);
hdd_ctx->is_sta_connection_pending = value;
- spin_unlock(&hdd_ctx->sta_update_info_lock);
+ qdf_spin_unlock(&hdd_ctx->sta_update_info_lock);
}
/**
@@ -1976,9 +1976,9 @@ static bool cds_is_sap_restart_required(void)
return false;
}
- spin_lock(&hdd_ctx->sap_update_info_lock);
+ qdf_spin_lock(&hdd_ctx->sap_update_info_lock);
status = hdd_ctx->is_sap_restart_required;
- spin_unlock(&hdd_ctx->sap_update_info_lock);
+ qdf_spin_unlock(&hdd_ctx->sap_update_info_lock);
return status;
}
@@ -2001,9 +2001,9 @@ void cds_change_sap_restart_required_status(bool value)
return;
}
- spin_lock(&hdd_ctx->sap_update_info_lock);
+ qdf_spin_lock(&hdd_ctx->sap_update_info_lock);
hdd_ctx->is_sap_restart_required = value;
- spin_unlock(&hdd_ctx->sap_update_info_lock);
+ qdf_spin_unlock(&hdd_ctx->sap_update_info_lock);
}
/**
@@ -2085,6 +2085,8 @@ static void cds_update_conc_list(uint32_t conn_index,
conc_connection_list[conn_index].original_nss = original_nss;
conc_connection_list[conn_index].vdev_id = vdev_id;
conc_connection_list[conn_index].in_use = in_use;
+
+ cds_dump_connection_status_info();
}
/**
@@ -2239,6 +2241,7 @@ static void cds_update_hw_mode_conn_info(uint32_t num_vdev_mac_entries,
conc_connection_list[conn_index].rx_spatial_stream);
}
}
+ cds_dump_connection_status_info();
qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}
@@ -2379,7 +2382,7 @@ void cds_set_dual_mac_fw_mode_config(uint8_t dbs, uint8_t dfs)
}
/**
- * cds_soc_set_hw_mode_cb() - Callback for set hw mode
+ * cds_pdev_set_hw_mode_cb() - Callback for set hw mode
* @status: Status
* @cfgd_hw_mode_index: Configured HW mode index
* @num_vdev_mac_entries: Number of vdev-mac id mapping that follows
@@ -2391,7 +2394,7 @@ void cds_set_dual_mac_fw_mode_config(uint8_t dbs, uint8_t dfs)
*
* Return: None
*/
-static void cds_soc_set_hw_mode_cb(uint32_t status,
+static void cds_pdev_set_hw_mode_cb(uint32_t status,
uint32_t cfgd_hw_mode_index,
uint32_t num_vdev_mac_entries,
struct sir_vdev_mac_map *vdev_mac_map)
@@ -2498,7 +2501,7 @@ static void cds_hw_mode_transition_cb(uint32_t old_hw_mode_index,
}
/**
- * cds_soc_set_hw_mode() - Set HW mode command to SME
+ * cds_pdev_set_hw_mode() - Set HW mode command to SME
* @session_id: Session ID
* @mac0_ss: MAC0 spatial stream configuration
* @mac0_bw: MAC0 bandwidth configuration
@@ -2526,7 +2529,7 @@ static void cds_hw_mode_transition_cb(uint32_t old_hw_mode_index,
*
* Return: Success if the message made it down to the next layer
*/
-QDF_STATUS cds_soc_set_hw_mode(uint32_t session_id,
+QDF_STATUS cds_pdev_set_hw_mode(uint32_t session_id,
enum hw_mode_ss_config mac0_ss,
enum hw_mode_bandwidth mac0_bw,
enum hw_mode_ss_config mac1_ss,
@@ -2554,14 +2557,14 @@ QDF_STATUS cds_soc_set_hw_mode(uint32_t session_id,
}
msg.hw_mode_index = hw_mode_index;
- msg.set_hw_mode_cb = (void *)cds_soc_set_hw_mode_cb;
+ msg.set_hw_mode_cb = (void *)cds_pdev_set_hw_mode_cb;
msg.reason = reason;
msg.session_id = session_id;
cds_info("set hw mode to sme: hw_mode_index: %d session:%d reason:%d",
msg.hw_mode_index, msg.session_id, msg.reason);
- status = sme_soc_set_hw_mode(hdd_ctx->hHal, msg);
+ status = sme_pdev_set_hw_mode(hdd_ctx->hHal, msg);
if (status != QDF_STATUS_SUCCESS) {
cds_err("Failed to set hw mode to SME");
return status;
@@ -3391,6 +3394,7 @@ void cds_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode)
case QDF_P2P_GO_MODE:
case QDF_SAP_MODE:
case QDF_IBSS_MODE:
+ case QDF_MONITOR_MODE:
hdd_ctx->concurrency_mode |= (1 << mode);
hdd_ctx->no_of_open_sessions[mode]++;
break;
@@ -3425,6 +3429,7 @@ void cds_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode)
case QDF_P2P_CLIENT_MODE:
case QDF_P2P_GO_MODE:
case QDF_SAP_MODE:
+ case QDF_MONITOR_MODE:
hdd_ctx->no_of_open_sessions[mode]--;
if (!(hdd_ctx->no_of_open_sessions[mode]))
hdd_ctx->concurrency_mode &= (~(1 << mode));
@@ -3588,7 +3593,7 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void)
return upgrade;
}
- /* Are both mac's still in use*/
+ /* Are both mac's still in use */
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
cds_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
@@ -3599,13 +3604,13 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void)
conc_connection_list[conn_index].original_nss);
if ((conc_connection_list[conn_index].mac == 0) &&
conc_connection_list[conn_index].in_use) {
- mac |= 1;
- if (3 == mac)
+ mac |= CDS_MAC0;
+ if (CDS_MAC0_AND_MAC1 == mac)
goto done;
} else if ((conc_connection_list[conn_index].mac == 1) &&
conc_connection_list[conn_index].in_use) {
- mac |= 2;
- if (3 == mac)
+ mac |= CDS_MAC1;
+ if (CDS_MAC0_AND_MAC1 == mac)
goto done;
}
}
@@ -3618,13 +3623,13 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void)
}
#endif
/* Let's request for single MAC mode */
- upgrade = CDS_MCC;
+ upgrade = CDS_SINGLE_MAC;
/* Is there any connection had an initial connection with 2x2 */
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list[conn_index].original_nss == 1) &&
conc_connection_list[conn_index].in_use) {
- upgrade = CDS_MCC_UPGRADE;
+ upgrade = CDS_SINGLE_MAC_UPGRADE;
goto done;
}
}
@@ -3955,6 +3960,8 @@ QDF_STATUS cds_init_policy_mgr(void)
return status;
}
+ cds_ctx->do_hw_mode_change = false;
+
return QDF_STATUS_SUCCESS;
}
@@ -5971,12 +5978,16 @@ bool cds_wait_for_nss_update(uint8_t action)
[conn_index].tx_spatial_stream == 2) &&
(conc_connection_list
[conn_index].rx_spatial_stream == 2) &&
- conc_connection_list[conn_index].in_use) {
+ conc_connection_list[conn_index].in_use &&
+ ((conc_connection_list[conn_index].mode ==
+ CDS_P2P_GO_MODE) ||
+ (conc_connection_list[conn_index].mode ==
+ CDS_SAP_MODE))) {
wait = true;
break;
}
}
- } else if (CDS_MCC == action) {
+ } else if (CDS_SINGLE_MAC == action) {
for (conn_index = 0;
conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
@@ -5986,7 +5997,11 @@ bool cds_wait_for_nss_update(uint8_t action)
[conn_index].tx_spatial_stream == 1) &&
(conc_connection_list
[conn_index].rx_spatial_stream == 1) &&
- conc_connection_list[conn_index].in_use) {
+ conc_connection_list[conn_index].in_use &&
+ ((conc_connection_list[conn_index].mode ==
+ CDS_P2P_GO_MODE) ||
+ (conc_connection_list[conn_index].mode ==
+ CDS_SAP_MODE))) {
wait = true;
break;
}
@@ -6046,7 +6061,7 @@ void cds_nss_update_cb(void *context, uint8_t tx_status, uint8_t vdev_id,
conc_connection_list[conn_index].rx_spatial_stream = 1;
wait = cds_wait_for_nss_update(next_action);
break;
- case CDS_MCC:
+ case CDS_SINGLE_MAC:
conc_connection_list[conn_index].tx_spatial_stream = 2;
conc_connection_list[conn_index].rx_spatial_stream = 2;
wait = cds_wait_for_nss_update(next_action);
@@ -6196,8 +6211,8 @@ QDF_STATUS cds_next_actions(uint32_t session_id,
*/
if ((((CDS_DBS_DOWNGRADE == action) || (CDS_DBS == action))
&& hw_mode.dbs_cap) ||
- (((CDS_MCC_UPGRADE == action) || (CDS_MCC == action))
- && !hw_mode.dbs_cap)) {
+ (((CDS_SINGLE_MAC_UPGRADE == action) ||
+ (CDS_SINGLE_MAC == action)) && !hw_mode.dbs_cap)) {
cds_err("driver is already in %s mode, no further action needed",
(hw_mode.dbs_cap) ? "dbs" : "non dbs");
return QDF_STATUS_E_ALREADY;
@@ -6214,7 +6229,7 @@ QDF_STATUS cds_next_actions(uint32_t session_id,
session_id);
break;
case CDS_DBS:
- status = cds_soc_set_hw_mode(session_id,
+ status = cds_pdev_set_hw_mode(session_id,
HW_MODE_SS_1x1,
HW_MODE_80_MHZ,
HW_MODE_SS_1x1, HW_MODE_40_MHZ,
@@ -6222,17 +6237,17 @@ QDF_STATUS cds_next_actions(uint32_t session_id,
HW_MODE_AGILE_DFS_NONE,
reason);
break;
- case CDS_MCC_UPGRADE:
+ case CDS_SINGLE_MAC_UPGRADE:
/*
* check if we have a beaconing entity that advertised 2x2
* intially. If yes, update the beacon template & notify FW.
* Once FW confirms beacon updated, send the HW mode change req
*/
- status = cds_complete_action(CDS_RX_NSS_2, CDS_MCC, reason,
- session_id);
+ status = cds_complete_action(CDS_RX_NSS_2, CDS_SINGLE_MAC,
+ reason, session_id);
break;
- case CDS_MCC:
- status = cds_soc_set_hw_mode(session_id,
+ case CDS_SINGLE_MAC:
+ status = cds_pdev_set_hw_mode(session_id,
HW_MODE_SS_2x2,
HW_MODE_80_MHZ,
HW_MODE_SS_0x0, HW_MODE_BW_NONE,
@@ -6374,13 +6389,8 @@ QDF_STATUS cds_check_and_restart_sap(eCsrRoamResult roam_result,
* creating workqueue then our main thread might go to sleep
* which is not acceptable.
*/
-#ifdef CONFIG_CNSS
- cnss_init_work(&hdd_ctx->sap_start_work,
- cds_sap_restart_handle);
-#else
INIT_WORK(&hdd_ctx->sap_start_work,
cds_sap_restart_handle);
-#endif
schedule_work(&hdd_ctx->sap_start_work);
return QDF_STATUS_SUCCESS;
}
@@ -8073,22 +8083,19 @@ QDF_STATUS qdf_init_connection_update(void)
}
/**
- * cds_get_pref_hw_mode_for_chan() - Get preferred hw mode for new channel
- * @vdev_id: vdev id whose target channel needs to change
- * @target_channel: Target channel
+ * cds_get_current_pref_hw_mode() - Get the current preferred hw mode
*
- * Get the preferred hw mode based on the vdev whose channel is going to change
+ * Get the preferred hw mode based on the current connection combinations
*
- * Return: No change (CDS_NOP), MCC (CDS_MCC_UPGRADE), DBS (CDS_DBS_DOWNGRADE)
+ * Return: No change (CDS_NOP), MCC (CDS_SINGLE_MAC_UPGRADE),
+ * DBS (CDS_DBS_DOWNGRADE)
*/
-enum cds_conc_next_action cds_get_pref_hw_mode_for_chan(uint32_t vdev_id,
- uint32_t target_channel)
+enum cds_conc_next_action cds_get_current_pref_hw_mode(void)
{
uint32_t num_connections;
- uint32_t conn_index = 0;
- bool found = false;
- uint8_t old_band, new_band;
-#ifdef QCA_WIFI_3_0_EMU
+ uint8_t band1, band2, band3;
+ struct sir_hw_mode_params hw_mode;
+ QDF_STATUS status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
@@ -8096,40 +8103,22 @@ enum cds_conc_next_action cds_get_pref_hw_mode_for_chan(uint32_t vdev_id,
cds_err("HDD context is NULL");
return CDS_NOP;
}
-#endif
- while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
- if ((vdev_id == conc_connection_list[conn_index].vdev_id) &&
- (conc_connection_list[conn_index].in_use == true)) {
- found = true;
- break;
- }
- conn_index++;
- }
-
- if (!found) {
- cds_err("vdev_id:%d not available in the conn info", vdev_id);
+ status = wma_get_current_hw_mode(&hw_mode);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ cds_err("wma_get_current_hw_mode failed");
return CDS_NOP;
}
- old_band = cds_chan_to_band(conc_connection_list[conn_index].chan);
- new_band = cds_chan_to_band(target_channel);
-
num_connections = cds_get_connection_count();
- cds_debug("vdev_id:%d conn_index:%d target_channel:%d chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d",
- vdev_id, conn_index, target_channel,
+ cds_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d",
conc_connection_list[0].chan, conc_connection_list[1].chan,
- conc_connection_list[2].chan,
- num_connections);
+ conc_connection_list[2].chan, num_connections, hw_mode.dbs_cap);
- /* If the band of the new channel to which the switching is done is same
- * as the band of the old channel, then there is no need for a hw mode
- * change. The driver would already be in the required hw mode.
+ /* If the band of operation of both the MACs is the same,
+ * single MAC is preferred, otherwise DBS is preferred.
*/
- if (old_band == new_band)
- return CDS_NOP;
-
switch (num_connections) {
case 1:
#ifdef QCA_WIFI_3_0_EMU
@@ -8137,69 +8126,33 @@ enum cds_conc_next_action cds_get_pref_hw_mode_for_chan(uint32_t vdev_id,
* request DBS
*/
if (hdd_ctx->config->enable_m2m_limitation &&
- CDS_IS_CHANNEL_24GHZ(target_channel))
+ CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan))
return CDS_DBS_DOWNGRADE;
#endif
/* The driver would already be in the required hw mode */
return CDS_NOP;
case 2:
- /* If the band of the new channel, is same as that of the band
- * of the channel on the other interface, the driver needs to
- * move to single MAC.
- *
- * If the band of the new channel, is different than that of the
- * band of the channel on the other interface, the driver needs
- * to move to DBS.
- */
- if (conn_index == 0) {
- if (new_band == cds_chan_to_band(
- conc_connection_list[1].chan))
- return CDS_MCC_UPGRADE;
- else if (new_band != cds_chan_to_band(
- conc_connection_list[1].chan))
- return CDS_DBS_DOWNGRADE;
- } else {
- if (new_band == cds_chan_to_band(
- conc_connection_list[0].chan))
- return CDS_MCC_UPGRADE;
- else if (new_band != cds_chan_to_band(
- conc_connection_list[0].chan))
- return CDS_DBS_DOWNGRADE;
- }
+ band1 = cds_chan_to_band(conc_connection_list[0].chan);
+ band2 = cds_chan_to_band(conc_connection_list[1].chan);
+ if ((band1 == band2) && (hw_mode.dbs_cap))
+ return CDS_SINGLE_MAC_UPGRADE;
+ else if ((band1 != band2) && (!hw_mode.dbs_cap))
+ return CDS_DBS_DOWNGRADE;
+ else
+ return CDS_NOP;
+
case 3:
- /* If the band of the new channel, is same as that of the band
- * of the channel on the other two interfaces, the driver needs
- * to move to single MAC.
- *
- * If the band of the new channel, is different than that of the
- * band of the channel on the other two interfaces, the driver
- * needs to move to DBS.
- */
- if (conn_index == 0) {
- if ((new_band == cds_chan_to_band(
- conc_connection_list[1].chan)) &&
- (new_band == cds_chan_to_band(
- conc_connection_list[2].chan)))
- return CDS_MCC_UPGRADE;
- else
- return CDS_DBS_DOWNGRADE;
- } else if (conn_index == 1) {
- if ((new_band == cds_chan_to_band(
- conc_connection_list[0].chan)) &&
- (new_band == cds_chan_to_band(
- conc_connection_list[2].chan)))
- return CDS_MCC_UPGRADE;
- else
- return CDS_DBS_DOWNGRADE;
- } else {
- if ((new_band == cds_chan_to_band(
- conc_connection_list[0].chan)) &&
- (new_band == cds_chan_to_band(
- conc_connection_list[1].chan)))
- return CDS_MCC_UPGRADE;
- else
- return CDS_DBS_DOWNGRADE;
- }
+ band1 = cds_chan_to_band(conc_connection_list[0].chan);
+ band2 = cds_chan_to_band(conc_connection_list[1].chan);
+ band3 = cds_chan_to_band(conc_connection_list[2].chan);
+ if (((band1 == band2) && (band2 == band3)) &&
+ (hw_mode.dbs_cap))
+ return CDS_SINGLE_MAC_UPGRADE;
+ else if (((band1 != band2) || (band2 != band3) ||
+ (band1 != band3)) && (!hw_mode.dbs_cap))
+ return CDS_DBS_DOWNGRADE;
+ else
+ return CDS_NOP;
default:
cds_err("unexpected num_connections value %d",
num_connections);
@@ -8239,87 +8192,6 @@ QDF_STATUS cds_stop_start_opportunistic_timer(void)
return status;
}
-/**
- * cds_handle_hw_mode_change_on_csa() - handle hw mode change for csa
- * @session_id: SME session id
- * @channel: given channel
- * @bssid: pointer to bssid
- * @dst: pointer to dest buffer
- * @src: pointer to src buffer
- * @numbytes: number of bytes to copy from src to dst
- *
- * Use this function to decide whether the hw mode upgrage or downgrade
- * is required based on session_id and given channel
- *
- * Return: QDF_STATUS
- */
-QDF_STATUS cds_handle_hw_mode_change_on_csa(uint16_t session_id,
- uint8_t channel, uint8_t *bssid, void *dst, void *src,
- uint32_t numbytes)
-{
- enum cds_conc_next_action action;
- QDF_STATUS status;
-
- /*
- * Since all the write to the policy manager table happens in the
- * MC thread context and this channel change event is also processed
- * in the MC thread context, explicit lock/unlock of qdf_conc_list_lock
- * is not done here
- */
- action = cds_get_pref_hw_mode_for_chan(session_id, channel);
-
- if (action == CDS_NOP) {
- cds_info("no need for hw mode change");
- /* Proceed with processing csa params. So, not freeing it */
- return QDF_STATUS_SUCCESS;
- }
- cds_info("session:%d action:%d", session_id, action);
-
- /*
- * 1. Start opportunistic timer
- * 2. Do vdev restart on the new channel (by the caller)
- * 3. PM will check if MCC upgrade can be done after timer expiry
- */
- if (action == CDS_MCC_UPGRADE) {
- status = cds_stop_start_opportunistic_timer();
- if (QDF_IS_STATUS_SUCCESS(status))
- cds_info("opportunistic timer for MCC upgrade");
-
- /*
- * After opportunistic timer is triggered, we can go ahead
- * with processing the csa params. So, not freeing the memory
- * through 'err' label.
- */
- return QDF_STATUS_SUCCESS;
- }
-
- /*
- * CDS_DBS_DOWNGRADE:
- * 1. PM will initiate HW mode change to DBS rightaway
- * 2. Do vdev restart on the new channel (on getting hw mode resp)
- */
- status = cds_next_actions(session_id, action,
- SIR_UPDATE_REASON_CHANNEL_SWITCH_STA);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- cds_err("no set hw mode command was issued");
- /* Proceed with processing csa params. So, not freeing it */
- return QDF_STATUS_SUCCESS;
- } else {
- if ((NULL == dst) || (NULL == src)) {
- cds_err("given buffers are null, can't copy csa param");
- return QDF_STATUS_E_FAILURE;
- }
- /* Save the csa params to be used after DBS downgrade */
- qdf_mem_copy(dst, src, numbytes);
- cds_info("saved csa params for dbs downgrade for bssid %pM",
- bssid);
-
- /* Returning error so that csa params are not processed here */
- status = QDF_STATUS_E_FAILURE;
- }
- return status;
-}
-
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
/**
* cds_register_sap_restart_channel_switch_cb() - Register callback for SAP
@@ -8500,3 +8372,166 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight)
return QDF_STATUS_SUCCESS;
}
+
+/**
+ * cds_set_hw_mode_on_channel_switch() - Set hw mode after channel switch
+ * @session_id: Session ID
+ *
+ * Sets hw mode after doing a channel switch
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id)
+{
+ QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
+ cds_context_type *cds_ctx;
+ enum cds_conc_next_action action;
+ hdd_context_t *hdd_ctx;
+
+ hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ if (!hdd_ctx) {
+ cds_err("HDD context is NULL");
+ return status;
+ }
+
+ if (!(hdd_ctx->config->policy_manager_enabled &&
+ wma_is_hw_dbs_capable())) {
+ cds_err("PM/DBS is disabled");
+ return status;
+ }
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid CDS Context"));
+ return status;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
+
+ action = cds_get_current_pref_hw_mode();
+
+ if ((action != CDS_DBS_DOWNGRADE) &&
+ (action != CDS_SINGLE_MAC_UPGRADE)) {
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid action: %d"), action);
+ status = QDF_STATUS_SUCCESS;
+ goto done;
+ }
+
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+ FL("action:%d session id:%d"),
+ action, session_id);
+
+ /* Opportunistic timer is started, PM will check if MCC upgrade can be
+ * done on timer expiry. This avoids any possible ping pong effect
+ * as well.
+ */
+ if (action == CDS_SINGLE_MAC_UPGRADE) {
+ qdf_status = cds_stop_start_opportunistic_timer();
+ if (QDF_IS_STATUS_SUCCESS(qdf_status))
+ cds_info("opportunistic timer for MCC upgrade");
+ goto done;
+ }
+
+ /* For DBS, we want to move right away to DBS mode */
+ status = cds_next_actions(session_id, action,
+ SIR_UPDATE_REASON_CHANNEL_SWITCH);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+ FL("no set hw mode command was issued"));
+ goto done;
+ }
+done:
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ /* success must be returned only when a set hw mode was done */
+ return status;
+}
+
+/**
+ * cds_dump_connection_status_info() - Dump the concurrency information
+ *
+ * Prints the concurrency information such as tx/rx spatial stream, chainmask,
+ * etc.
+ *
+ * Return: None
+ */
+void cds_dump_connection_status_info(void)
+{
+ 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;
+ }
+
+ for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+ cds_debug("%d: use:%d vdev:%d tx:%d rx:%d mode:%d mac:%d chan:%d chainmask:%d orig nss:%d bw:%d",
+ i, conc_connection_list[i].in_use,
+ conc_connection_list[i].vdev_id,
+ conc_connection_list[i].tx_spatial_stream,
+ conc_connection_list[i].rx_spatial_stream,
+ conc_connection_list[i].mode,
+ conc_connection_list[i].mac,
+ conc_connection_list[i].chan,
+ conc_connection_list[i].chain_mask,
+ conc_connection_list[i].original_nss,
+ conc_connection_list[i].bw);
+ }
+}
+
+/**
+ * cds_set_do_hw_mode_change_flag() - Set flag to indicate hw mode change
+ * @flag: Indicate if hw mode change is required or not
+ *
+ * Set the flag to indicate whether a hw mode change is required after a
+ * vdev up or not. Flag value of true indicates that a hw mode change is
+ * required after vdev up.
+ *
+ * Return: None
+ */
+void cds_set_do_hw_mode_change_flag(bool flag)
+{
+ cds_context_type *cds_ctx;
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
+ cds_ctx->do_hw_mode_change = flag;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+
+ cds_debug("hw_mode_change_channel:%d", flag);
+}
+
+/**
+ * cds_is_hw_mode_change_after_vdev_up() - Check if hw mode change is needed
+ *
+ * Returns the flag which indicates if a hw mode change is required after
+ * vdev up.
+ *
+ * Return: True if hw mode change is required, false otherwise
+ */
+bool cds_is_hw_mode_change_after_vdev_up(void)
+{
+ cds_context_type *cds_ctx;
+ bool flag;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return INVALID_CHANNEL_ID;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
+ flag = cds_ctx->do_hw_mode_change;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+
+ return flag;
+}
diff --git a/core/cds/src/cds_packet.c b/core/cds/src/cds_packet.c
index 38447aeef712..f8f610459f4e 100644
--- a/core/cds/src/cds_packet.c
+++ b/core/cds/src/cds_packet.c
@@ -181,12 +181,12 @@ uint8_t cds_pkt_get_proto_type(struct sk_buff *skb, uint8_t tracking_map,
}
#ifdef QCA_PKT_PROTO_TRACE
-/*---------------------------------------------------------------------------
-* @brief cds_pkt_trace_buf_update() -
- Update storage buffer with interest event string
-
-* event_string Event String may packet type or outstanding event
- ---------------------------------------------------------------------------*/
+/**
+ * cds_pkt_trace_buf_update() - Update storage buffer with interest event string
+ * @event_string: string may be a packet type or an outstanding event
+ *
+ * Return: none
+ */
void cds_pkt_trace_buf_update(char *event_string)
{
uint32_t slot;
@@ -194,6 +194,11 @@ void cds_pkt_trace_buf_update(char *event_string)
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
"%s %d, %s", __func__, __LINE__, event_string);
qdf_spinlock_acquire(&trace_buffer_lock);
+ if (!trace_buffer) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "trace_buffer is null");
+ goto release_lock;
+ }
slot = trace_buffer_order % CDS_PKT_TRAC_MAX_TRACE_BUF;
trace_buffer[slot].order = trace_buffer_order;
trace_buffer[slot].event_time = qdf_mc_timer_get_system_time();
@@ -204,20 +209,27 @@ void cds_pkt_trace_buf_update(char *event_string)
(CDS_PKT_TRAC_MAX_STRING_LEN < strlen(event_string)) ?
CDS_PKT_TRAC_MAX_STRING_LEN : strlen(event_string));
trace_buffer_order++;
- qdf_spinlock_release(&trace_buffer_lock);
+release_lock:
+ qdf_spinlock_release(&trace_buffer_lock);
return;
}
-/*---------------------------------------------------------------------------
-* @brief cds_pkt_trace_buf_dump() -
- Dump stored information into kernel log
- ---------------------------------------------------------------------------*/
+/**
+ * cds_pkt_trace_buf_dump() - Dump stored information into kernel log
+ *
+ * Return: none
+ */
void cds_pkt_trace_buf_dump(void)
{
uint32_t slot, idx;
qdf_spinlock_acquire(&trace_buffer_lock);
+ if (!trace_buffer) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "trace_buffer is null");
+ goto release_lock;
+ }
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"PACKET TRACE DUMP START Current Timestamp %u",
(unsigned int)qdf_mc_timer_get_system_time());
@@ -245,15 +257,16 @@ void cds_pkt_trace_buf_dump(void)
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"PACKET TRACE DUMP END");
+release_lock:
qdf_spinlock_release(&trace_buffer_lock);
-
return;
}
-/*---------------------------------------------------------------------------
-* @brief cds_pkt_proto_trace_init() -
- Initialize protocol trace functionality, allocate required resource
- ---------------------------------------------------------------------------*/
+/**
+ * cds_pkt_proto_trace_init() - Initialize protocol trace functionality
+ *
+ * Return: none
+ */
void cds_pkt_proto_trace_init(void)
{
/* Init spin lock to protect global memory */
@@ -269,17 +282,18 @@ void cds_pkt_proto_trace_init(void)
return;
}
-/*---------------------------------------------------------------------------
-* @brief cds_pkt_proto_trace_close() -
- Free required resource
- ---------------------------------------------------------------------------*/
-void cds_pkt_proto_trace_close(void)
+/**
+ * cds_pkt_proto_trace_deinit() - Free trace_buffer resource
+ *
+ * Return: none
+ */
+void cds_pkt_proto_trace_deinit(void)
{
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"%s %d", __func__, __LINE__);
qdf_mem_free(trace_buffer);
+ trace_buffer = NULL;
qdf_spinlock_destroy(&trace_buffer_lock);
-
return;
}
#endif /* QCA_PKT_PROTO_TRACE */
diff --git a/core/cds/src/cds_reg_service.c b/core/cds/src/cds_reg_service.c
index cd0ed13839c2..dcdc20031e6c 100644
--- a/core/cds/src/cds_reg_service.c
+++ b/core/cds/src/cds_reg_service.c
@@ -450,7 +450,7 @@ static void cds_set_5g_channel_params(uint16_t oper_ch,
enum channel_state chan_state2 = CHANNEL_STATE_ENABLE;
const struct bonded_chan *bonded_chan_ptr;
- if (CH_WIDTH_MAX >= ch_params->ch_width)
+ if (CH_WIDTH_MAX <= ch_params->ch_width)
ch_params->ch_width = CH_WIDTH_80P80MHZ;
while (ch_params->ch_width != CH_WIDTH_INVALID) {
@@ -506,8 +506,8 @@ static void cds_set_2g_channel_params(uint16_t oper_ch,
{
enum channel_state chan_state = CHANNEL_STATE_ENABLE;
- if (CH_WIDTH_MAX >= ch_params->ch_width)
- ch_params->ch_width = CH_WIDTH_80P80MHZ;
+ if (CH_WIDTH_MAX <= ch_params->ch_width)
+ ch_params->ch_width = CH_WIDTH_40MHZ;
while (ch_params->ch_width != CH_WIDTH_INVALID) {
chan_state = cds_get_2g_bonded_channel_state(oper_ch,
diff --git a/core/cds/src/cds_regdomain.c b/core/cds/src/cds_regdomain.c
index a7e8e3ec1e41..5fffb2d6de2d 100644
--- a/core/cds/src/cds_regdomain.c
+++ b/core/cds/src/cds_regdomain.c
@@ -379,7 +379,8 @@ static const struct country_code_to_reg_dmn g_all_countries[] = {
{CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF" "WALLIS"},
{CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN"},
{CTRY_ZIMBABWE, ETSI1_WORLD, "ZW", "ZIMBABWE"},
- {CTRY_JAPAN14, MKK5_MKKA, "JP", "JAPAN"}
+ {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN"},
+ {CTRY_XA, MKK5_MKKA2, "XA", "JAPAN PASSIVE"}
};
static const struct reg_dmn g_reg_dmns[] = {
diff --git a/core/cds/src/cds_sched.c b/core/cds/src/cds_sched.c
index bbf9b754d775..4f9a39c5fe2b 100644
--- a/core/cds/src/cds_sched.c
+++ b/core/cds/src/cds_sched.c
@@ -46,9 +46,6 @@
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/cpu.h>
-#if defined(QCA_CONFIG_SMP) && defined(CONFIG_CNSS)
-#include <net/cnss.h>
-#endif
/* Preprocessor Definitions and Constants */
#define CDS_SCHED_THREAD_HEART_BEAT INFINITE
/* Milli seconds to delay SSR thread when an Entry point is Active */
@@ -89,13 +86,7 @@ static QDF_STATUS cds_alloc_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext);
#define CDS_CORE_PER_CLUSTER (4)
static int cds_set_cpus_allowed_ptr(struct task_struct *task, unsigned long cpu)
{
-#ifdef WLAN_OPEN_SOURCE
return set_cpus_allowed_ptr(task, cpumask_of(cpu));
-#elif defined(CONFIG_CNSS)
- return cnss_set_cpus_allowed_ptr(task, cpu);
-#else
- return 0;
-#endif
}
/**
diff --git a/core/dp/htt/htt.c b/core/dp/htt/htt.c
index 1672a39c2ea5..fe30c3405d3a 100644
--- a/core/dp/htt/htt.c
+++ b/core/dp/htt/htt.c
@@ -137,6 +137,14 @@ void htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev)
}
#endif
+
+/* AR6004 don't need HTT layer. */
+#ifdef AR6004_HW
+#define NO_HTT_NEEDED true
+#else
+#define NO_HTT_NEEDED false
+#endif
+
/**
* htt_pdev_alloc() - allocate HTT pdev
* @txrx_pdev: txrx pdev
@@ -152,6 +160,10 @@ htt_pdev_alloc(ol_txrx_pdev_handle txrx_pdev,
HTC_HANDLE htc_pdev, qdf_device_t osdev)
{
struct htt_pdev_t *pdev;
+ struct hif_opaque_softc *osc = cds_get_context(QDF_MODULE_ID_HIF);
+
+ if (!osc)
+ goto fail1;
pdev = qdf_mem_malloc(sizeof(*pdev));
if (!pdev)
@@ -186,14 +198,14 @@ htt_pdev_alloc(ol_txrx_pdev_handle txrx_pdev,
HTT_SET_WIFI_IP(pdev, 2, 0);
#endif /* defined(HELIUMPLUS_PADDR64) */
+ if (NO_HTT_NEEDED)
+ goto success;
/*
* Connect to HTC service.
* This has to be done before calling htt_rx_attach,
* since htt_rx_attach involves sending a rx ring configure
* message to the target.
*/
-/* AR6004 don't need HTT layer. */
-#ifndef AR6004_HW
if (htt_htc_attach(pdev, HTT_DATA_MSG_SVC))
goto fail2;
if (htt_htc_attach(pdev, HTT_DATA2_MSG_SVC))
@@ -204,11 +216,10 @@ htt_pdev_alloc(ol_txrx_pdev_handle txrx_pdev,
;
/* TODO: enable the following line once FW is ready */
/* goto fail2; */
- if (hif_ce_fastpath_cb_register(htt_t2h_msg_handler_fast, pdev))
+ if (hif_ce_fastpath_cb_register(osc, htt_t2h_msg_handler_fast, pdev))
qdf_print("failed to register fastpath callback\n");
-#endif
-
+success:
return pdev;
fail2:
diff --git a/core/dp/htt/htt_h2t.c b/core/dp/htt/htt_h2t.c
index 9662eb4d6980..c7aeb9f70006 100644
--- a/core/dp/htt/htt_h2t.c
+++ b/core/dp/htt/htt_h2t.c
@@ -51,6 +51,7 @@
#include <ol_htt_tx_api.h>
#include <htt_internal.h>
+#include <cds_concurrency.h>
#define HTT_MSG_BUF_SIZE(msg_bytes) \
((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING)
@@ -356,6 +357,18 @@ A_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev)
enable_ppdu_start = 0;
enable_ppdu_end = 0;
#endif
+ if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) {
+ enable_ctrl_data = 1;
+ enable_mgmt_data = 1;
+ enable_null_data = 1;
+ enable_phy_data = 1;
+ enable_hdr = 1;
+ enable_ppdu_start = 1;
+ enable_ppdu_end = 1;
+ /* Disable ASPM for monitor mode */
+ qdf_print("Monitor mode is enabled\n");
+ }
+
HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, enable_hdr);
HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1);
HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, enable_ppdu_start);
diff --git a/core/dp/htt/htt_internal.h b/core/dp/htt/htt_internal.h
index 7d3ffbddafcb..271e77eec211 100644
--- a/core/dp/htt/htt_internal.h
+++ b/core/dp/htt/htt_internal.h
@@ -331,6 +331,7 @@ static inline void htt_print_rx_desc(struct htt_host_rx_desc_base *rx_desc)
* rounded up to a cache line size.
*/
#define HTT_RX_BUF_SIZE 1920
+#define MAX_RX_PAYLOAD_SZ (HTT_RX_BUF_SIZE - RX_STD_DESC_SIZE)
/*
* DMA_MAP expects the buffer to be an integral number of cache lines.
* Rather than checking the actual cache line size, this code makes a
diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c
index 0064a8f282d6..b5d8667c5f3a 100644
--- a/core/dp/htt/htt_rx.c
+++ b/core/dp/htt/htt_rx.c
@@ -53,12 +53,20 @@
#include <cds_ieee80211_common.h> /* ieee80211_frame, ieee80211_qoscntl */
#include <cds_ieee80211_defines.h> /* ieee80211_rx_status */
+#include <cds_utils.h>
+#include <cds_concurrency.h>
#ifdef DEBUG_DMA_DONE
#include <asm/barrier.h>
#include <wma_api.h>
#endif
+#ifdef HTT_DEBUG_DATA
+#define HTT_PKT_DUMP(x) x
+#else
+#define HTT_PKT_DUMP(x) /* no-op */
+#endif
+
/* AR9888v1 WORKAROUND for EV#112367 */
/* FIX THIS - remove this WAR when the bug is fixed */
#define PEREGRINE_1_0_ZERO_LEN_PHY_ERR_WAR
@@ -81,8 +89,9 @@
#define HTT_RX_HOST_LATENCY_MAX_MS 20 /* ms */ /* very conservative */
#endif
+ /* very conservative to ensure enough buffers are allocated */
#ifndef HTT_RX_HOST_LATENCY_WORST_LIKELY_MS
-#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 10 /* ms */ /* conservative */
+#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 20
#endif
#ifndef HTT_RX_RING_REFILL_RETRY_TIME_MS
@@ -203,7 +212,9 @@ static int htt_rx_ring_fill_level(struct htt_pdev_t *pdev)
size = ol_cfg_max_thruput_mbps(pdev->ctrl_pdev) *
1000 /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */ /
- 8 * HTT_RX_AVG_FRM_BYTES * HTT_RX_HOST_LATENCY_WORST_LIKELY_MS;
+ (8 * HTT_RX_AVG_FRM_BYTES) * HTT_RX_HOST_LATENCY_WORST_LIKELY_MS;
+
+ size = qdf_get_pwr2(size);
/*
* Make sure the fill level is at least 1 less than the ring size.
* Leaving 1 element empty allows the SW to easily distinguish
@@ -1148,8 +1159,313 @@ htt_rx_offload_paddr_msdu_pop_ll(htt_pdev_handle pdev,
return 0;
}
-extern void
-dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len);
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#if HTT_PADDR64
+#define NEXT_FIELD_OFFSET_IN32 2
+#else /* ! HTT_PADDR64 */
+#define NEXT_FIELD_OFFSET_IN32 1
+#endif /* HTT_PADDR64 */
+
+/**
+ * htt_mon_rx_handle_amsdu_packet() - Handle consecutive fragments of amsdu
+ * @msdu: pointer to first msdu of amsdu
+ * @pdev: Handle to htt_pdev_handle
+ * @msg_word: Input and output variable, so pointer to HTT msg pointer
+ * @amsdu_len: remaining length of all N-1 msdu msdu's
+ *
+ * This function handles the (N-1) msdu's of amsdu, N'th msdu is already
+ * handled by calling function. N-1 msdu's are tied using frags_list.
+ * msdu_info field updated by FW indicates if this is last msdu. All the
+ * msdu's before last msdu will be of MAX payload.
+ *
+ * Return: 1 on success and 0 on failure.
+ */
+int htt_mon_rx_handle_amsdu_packet(qdf_nbuf_t msdu, htt_pdev_handle pdev,
+ uint32_t **msg_word, uint32_t amsdu_len)
+{
+ qdf_nbuf_t frag_nbuf;
+ qdf_nbuf_t prev_frag_nbuf;
+ uint32_t len;
+ uint32_t last_frag;
+
+ *msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+ frag_nbuf = htt_rx_in_order_netbuf_pop(pdev,
+ HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(**msg_word));
+ if (qdf_unlikely(NULL == frag_nbuf)) {
+ qdf_print("%s: netbuf pop failed!\n", __func__);
+ return 0;
+ }
+ last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)*msg_word)->
+ msdu_info;
+ qdf_nbuf_append_ext_list(msdu, frag_nbuf, amsdu_len);
+ qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
+ qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
+ /* For msdu's other than parent will not have htt_host_rx_desc_base */
+ len = MIN(amsdu_len, HTT_RX_BUF_SIZE);
+ amsdu_len -= len;
+ qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
+
+ HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+ QDF_TRACE_LEVEL_FATAL,
+ qdf_nbuf_data(frag_nbuf),
+ qdf_nbuf_len(frag_nbuf)));
+ prev_frag_nbuf = frag_nbuf;
+ while (!last_frag) {
+ *msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+ frag_nbuf = htt_rx_in_order_netbuf_pop(pdev,
+ HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(**msg_word));
+ last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
+ *msg_word)->msdu_info;
+
+ if (qdf_unlikely(NULL == frag_nbuf)) {
+ qdf_print("%s: netbuf pop failed!\n", __func__);
+ prev_frag_nbuf->next = NULL;
+ return 0;
+ }
+ qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
+ qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
+
+ len = MIN(amsdu_len, HTT_RX_BUF_SIZE);
+ amsdu_len -= len;
+ qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
+ HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+ QDF_TRACE_LEVEL_FATAL,
+ qdf_nbuf_data(frag_nbuf),
+ qdf_nbuf_len(frag_nbuf)));
+
+ qdf_nbuf_set_next(prev_frag_nbuf, frag_nbuf);
+ prev_frag_nbuf = frag_nbuf;
+ }
+ qdf_nbuf_set_next(prev_frag_nbuf, NULL);
+ return 1;
+}
+
+/**
+ * htt_mon_rx_get_phy_info() - Get rate interms of 500Kbps.
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ * @rx_status: Return variable updated with phy_info in rx_status
+ *
+ * If l_sig_rate_select is 0:
+ * 0x8: OFDM 48 Mbps
+ * 0x9: OFDM 24 Mbps
+ * 0xA: OFDM 12 Mbps
+ * 0xB: OFDM 6 Mbps
+ * 0xC: OFDM 54 Mbps
+ * 0xD: OFDM 36 Mbps
+ * 0xE: OFDM 18 Mbps
+ * 0xF: OFDM 9 Mbps
+ * If l_sig_rate_select is 1:
+ * 0x8: CCK 11 Mbps long preamble
+ * 0x9: CCK 5.5 Mbps long preamble
+ * 0xA: CCK 2 Mbps long preamble
+ * 0xB: CCK 1 Mbps long preamble
+ * 0xC: CCK 11 Mbps short preamble
+ * 0xD: CCK 5.5 Mbps short preamble
+ * 0xE: CCK 2 Mbps short preamble
+ *
+ * Return: None
+ */
+static void htt_mon_rx_get_phy_info(struct htt_host_rx_desc_base *rx_desc,
+ struct mon_rx_status *rx_status)
+{
+#define SHORT_PREAMBLE 1
+#define LONG_PREAMBLE 0
+ char rate = 0x0;
+ uint8_t preamble = SHORT_PREAMBLE;
+ uint8_t preamble_type = rx_desc->ppdu_start.preamble_type;
+ uint8_t mcs = 0, nss = 0, sgi = 0, bw = 0, beamformed = 0;
+ uint16_t vht_flags = 0;
+ uint32_t l_sig_rate_select = rx_desc->ppdu_start.l_sig_rate_select;
+ uint32_t l_sig_rate = rx_desc->ppdu_start.l_sig_rate;
+ bool is_stbc = 0, ldpc = 0;
+
+ if (l_sig_rate_select == 0) {
+ switch (l_sig_rate) {
+ case 0x8:
+ rate = 0x60;
+ break;
+ case 0x9:
+ rate = 0x30;
+ break;
+ case 0xA:
+ rate = 0x18;
+ break;
+ case 0xB:
+ rate = 0x0c;
+ break;
+ case 0xC:
+ rate = 0x6c;
+ break;
+ case 0xD:
+ rate = 0x48;
+ break;
+ case 0xE:
+ rate = 0x24;
+ break;
+ case 0xF:
+ rate = 0x12;
+ break;
+ default:
+ break;
+ }
+ } else if (l_sig_rate_select == 1) {
+ switch (l_sig_rate) {
+ case 0x8:
+ rate = 0x16;
+ preamble = LONG_PREAMBLE;
+ break;
+ case 0x9:
+ rate = 0x0B;
+ preamble = LONG_PREAMBLE;
+ break;
+ case 0xA:
+ rate = 0x04;
+ preamble = LONG_PREAMBLE;
+ break;
+ case 0xB:
+ rate = 0x02;
+ preamble = LONG_PREAMBLE;
+ break;
+ case 0xC:
+ rate = 0x16;
+ break;
+ case 0xD:
+ rate = 0x0B;
+ break;
+ case 0xE:
+ rate = 0x04;
+ break;
+ default:
+ break;
+ }
+ } else {
+ qdf_print("Invalid rate info\n");
+ }
+
+ switch (preamble_type) {
+ case 8:
+ is_stbc = ((VHT_SIG_A_2(rx_desc) >> 4) & 3);
+ /* fallthrough */
+ case 9:
+ vht_flags = 1;
+ sgi = (VHT_SIG_A_2(rx_desc) >> 7) & 0x01;
+ bw = (VHT_SIG_A_1(rx_desc) >> 7) & 0x01;
+ mcs = (VHT_SIG_A_1(rx_desc) & 0x7f);
+ nss = mcs>>3;
+ beamformed =
+ (VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
+ break;
+ case 0x0c:
+ vht_flags = 1;
+ is_stbc = (VHT_SIG_A_2(rx_desc) >> 3) & 1;
+ ldpc = (VHT_SIG_A_2(rx_desc) >> 2) & 1;
+ /* fallthrough */
+ case 0x0d:
+ {
+ uint8_t gid_in_sig = ((VHT_SIG_A_1(rx_desc) >> 4) & 0x3f);
+
+ vht_flags = 1;
+ sgi = VHT_SIG_A_2(rx_desc) & 0x01;
+ bw = (VHT_SIG_A_1(rx_desc) & 0x03);
+ if (gid_in_sig == 0 || gid_in_sig == 63) {
+ /* SU case */
+ mcs = (VHT_SIG_A_2(rx_desc) >> 4) &
+ 0xf;
+ nss = (VHT_SIG_A_1(rx_desc) >> 10) &
+ 0x7;
+ } else {
+ /* SU case */
+ uint8_t sta_user_pos =
+ (uint8_t)((rx_desc->ppdu_start.reserved_4a >> 8)
+ & 0x3);
+ mcs = (rx_desc->ppdu_start.vht_sig_b >> 16);
+ if (bw >= 2)
+ mcs >>= 3;
+ else if (bw > 0)
+ mcs >>= 1;
+ mcs &= 0xf;
+ nss = (((VHT_SIG_A_1(rx_desc) >> 10) +
+ sta_user_pos * 3) & 0x7);
+ }
+ beamformed = (VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
+ }
+ /* fallthrough */
+ default:
+ break;
+ }
+
+ rx_status->mcs = mcs;
+ rx_status->nr_ant = nss;
+ rx_status->is_stbc = is_stbc;
+ rx_status->sgi = sgi;
+ rx_status->ldpc = ldpc;
+ rx_status->beamformed = beamformed;
+ rx_status->vht_flag_values3[0] = mcs << 0x4;
+ rx_status->rate = rate;
+ rx_status->vht_flags = vht_flags;
+ rx_status->rtap_flags |= ((preamble == SHORT_PREAMBLE) ? BIT(1) : 0);
+ rx_status->vht_flag_values2 = 0x01 < bw;
+}
+
+/**
+ * htt_mon_rx_get_rtap_flags() - Get radiotap flags
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ *
+ * Return: Bitmapped radiotap flags.
+ */
+static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc)
+{
+ uint8_t rtap_flags = 0;
+
+ /* WEP40 || WEP104 || WEP128 */
+ if (rx_desc->mpdu_start.encrypt_type == 0 ||
+ rx_desc->mpdu_start.encrypt_type == 1 ||
+ rx_desc->mpdu_start.encrypt_type == 3)
+ rtap_flags |= BIT(2);
+
+ /* IEEE80211_RADIOTAP_F_FRAG */
+ if (rx_desc->attention.fragment)
+ rtap_flags |= BIT(3);
+
+ /* IEEE80211_RADIOTAP_F_FCS */
+ rtap_flags |= BIT(4);
+
+ /* IEEE80211_RADIOTAP_F_BADFCS */
+ if (rx_desc->mpdu_end.fcs_err)
+ rtap_flags |= BIT(6);
+
+ return rtap_flags;
+}
+
+/**
+ * htt_rx_mon_get_rx_status() - Update information about the rx status,
+ * which is used later for radiotap updation.
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ * @rx_status: Return variable updated with rx_status
+ *
+ * Return: None
+ */
+void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
+ struct htt_host_rx_desc_base *rx_desc,
+ struct mon_rx_status *rx_status)
+{
+ uint16_t channel_flags = 0;
+ struct mon_channel *ch_info = &pdev->mon_ch_info;
+
+ rx_status->tsft = (u_int64_t)TSF_TIMESTAMP(rx_desc);
+ rx_status->chan_freq = ch_info->ch_freq;
+ rx_status->chan_num = ch_info->ch_num;
+ htt_mon_rx_get_phy_info(rx_desc, rx_status);
+ rx_status->rtap_flags |= htt_mon_rx_get_rtap_flags(rx_desc);
+ channel_flags |= rx_desc->ppdu_start.l_sig_rate_select ?
+ IEEE80211_CHAN_CCK : IEEE80211_CHAN_OFDM;
+ channel_flags |=
+ (cds_chan_to_band(ch_info->ch_num) == CDS_BAND_2GHZ ?
+ IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
+
+ rx_status->chan_flags = channel_flags;
+ rx_status->ant_signal_db = rx_desc->ppdu_start.rssi_comb;
+}
#ifdef RX_HASH_DEBUG
#define HTT_RX_CHECK_MSDU_COUNT(msdu_count) HTT_ASSERT_ALWAYS(msdu_count)
@@ -1157,6 +1473,164 @@ dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len);
#define HTT_RX_CHECK_MSDU_COUNT(msdu_count) /* no-op */
#endif
+/**
+ * htt_rx_mon_amsdu_rx_in_order_pop_ll() - Monitor mode HTT Rx in order pop
+ * function
+ * @pdev: Handle to htt_pdev_handle
+ * @rx_ind_msg: In order indication message.
+ * @head_msdu: Return variable pointing to head msdu.
+ * @tail_msdu: Return variable pointing to tail msdu.
+ *
+ * This function pops the msdu based on paddr:length of inorder indication
+ * message.
+ *
+ * Return: 1 for success, 0 on failure.
+ */
+int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+ qdf_nbuf_t rx_ind_msg,
+ qdf_nbuf_t *head_msdu,
+ qdf_nbuf_t *tail_msdu)
+{
+ qdf_nbuf_t msdu, next;
+ uint8_t *rx_ind_data;
+ uint32_t *msg_word;
+ uint32_t msdu_count;
+ struct htt_host_rx_desc_base *rx_desc;
+ struct mon_rx_status rx_status = {0};
+ uint32_t amsdu_len;
+ uint32_t len;
+ uint32_t last_frag;
+
+ HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
+
+ rx_ind_data = qdf_nbuf_data(rx_ind_msg);
+ msg_word = (uint32_t *)rx_ind_data;
+
+ HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+ QDF_TRACE_LEVEL_FATAL,
+ (void *)rx_ind_data,
+ (int)qdf_nbuf_len(rx_ind_msg)));
+
+ /* Get the total number of MSDUs */
+ msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1));
+ HTT_RX_CHECK_MSDU_COUNT(msdu_count);
+
+ msg_word = (uint32_t *)(rx_ind_data +
+ HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES);
+
+ (*head_msdu) = msdu = htt_rx_in_order_netbuf_pop(pdev,
+ HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*msg_word));
+
+ if (qdf_unlikely(NULL == msdu)) {
+ qdf_print("%s: netbuf pop failed!\n", __func__);
+ *tail_msdu = NULL;
+ return 0;
+ }
+ while (msdu_count > 0) {
+
+ msdu_count--;
+ /*
+ * Set the netbuf length to be the entire buffer length
+ * initially, so the unmap will unmap the entire buffer.
+ */
+ qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
+ qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
+
+ /*
+ * cache consistency has been taken care of by the
+ * qdf_nbuf_unmap
+ */
+ rx_desc = htt_rx_desc(msdu);
+ HTT_PKT_DUMP(htt_print_rx_desc(rx_desc));
+ /*
+ * Make the netbuf's data pointer point to the payload rather
+ * than the descriptor.
+ */
+ htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status);
+ /*
+ * 350 bytes of RX_STD_DESC size should be sufficient for
+ * radiotap.
+ */
+ qdf_nbuf_update_radiotap(&rx_status, msdu,
+ HTT_RX_STD_DESC_RESERVATION);
+ amsdu_len = HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(*(msg_word +
+ NEXT_FIELD_OFFSET_IN32));
+
+ /*
+ * MAX_RX_PAYLOAD_SZ when we have AMSDU packet. amsdu_len in
+ * which case is the total length of sum of all AMSDU's
+ */
+ len = MIN(amsdu_len, MAX_RX_PAYLOAD_SZ);
+ amsdu_len -= len;
+ qdf_nbuf_trim_tail(msdu,
+ HTT_RX_BUF_SIZE -
+ (RX_STD_DESC_SIZE + len));
+
+
+ HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+ QDF_TRACE_LEVEL_FATAL,
+ qdf_nbuf_data(msdu),
+ qdf_nbuf_len(msdu)));
+ last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
+ msg_word)->msdu_info;
+
+#undef NEXT_FIELD_OFFSET_IN32
+ /* Handle amsdu packet */
+ if (!last_frag) {
+ /*
+ * For AMSDU packet msdu->len is sum of all the msdu's
+ * length, msdu->data_len is sum of length's of
+ * remaining msdu's other than parent.
+ */
+ if (!htt_mon_rx_handle_amsdu_packet(msdu, pdev,
+ &msg_word,
+ amsdu_len)) {
+ qdf_print("%s: failed to handle amsdu packet\n",
+ __func__);
+ return 0;
+ }
+ }
+ /* check if this is the last msdu */
+ if (msdu_count) {
+ msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+ next = htt_rx_in_order_netbuf_pop(pdev,
+ HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*msg_word));
+ if (qdf_unlikely(NULL == next)) {
+ qdf_print("%s: netbuf pop failed!\n",
+ __func__);
+ *tail_msdu = NULL;
+ return 0;
+ }
+ qdf_nbuf_set_next(msdu, next);
+ msdu = next;
+ } else {
+ *tail_msdu = msdu;
+ qdf_nbuf_set_next(msdu, NULL);
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * htt_rx_mon_note_capture_channel() - Make note of channel to update in
+ * radiotap
+ * @pdev: handle to htt_pdev
+ * @mon_ch: capture channel number.
+ *
+ * Return: None
+ */
+void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch)
+{
+ struct mon_channel *ch_info = &pdev->mon_ch_info;
+
+ ch_info->ch_num = mon_ch;
+ ch_info->ch_freq = cds_chan_to_freq(mon_ch);
+}
+
+extern void
+dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len);
+
/* Return values: 1 - success, 0 - failure */
int
htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
@@ -2228,6 +2702,9 @@ int htt_rx_attach(struct htt_pdev_t *pdev)
htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_ll;
}
+ if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
+ htt_rx_amsdu_pop = htt_rx_mon_amsdu_rx_in_order_pop_ll;
+
htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_ll;
htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_ll;
htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_ll;
diff --git a/core/dp/htt/htt_types.h b/core/dp/htt/htt_types.h
index b0bcf811a926..7900d1c6f9e2 100644
--- a/core/dp/htt/htt_types.h
+++ b/core/dp/htt/htt_types.h
@@ -211,6 +211,16 @@ struct msdu_ext_desc_t {
};
#endif /* defined(HELIUMPLUS_PADDR64) */
+/**
+ * struct mon_channel
+ * @ch_num: Monitor mode capture channel number
+ * @ch_freq: channel frequency.
+ */
+struct mon_channel {
+ uint32_t ch_num;
+ uint32_t ch_freq;
+};
+
struct htt_pdev_t {
ol_pdev_handle ctrl_pdev;
ol_txrx_pdev_handle txrx_pdev;
@@ -385,6 +395,7 @@ struct htt_pdev_t {
struct rx_buf_debug *rx_buff_list;
int rx_buff_index;
#endif
+ struct mon_channel mon_ch_info;
};
#define HTT_EPID_GET(_htt_pdev_hdl) \
diff --git a/core/dp/htt/rx_desc.h b/core/dp/htt/rx_desc.h
index 66963d1e2b30..fc1b39ac52f7 100644
--- a/core/dp/htt/rx_desc.h
+++ b/core/dp/htt/rx_desc.h
@@ -257,6 +257,12 @@ struct rx_ppdu_start {
uint32_t service:16, /* [15:0] */
reserved_9:16; /* [31:16] */
};
+
+#define VHT_SIG_A_1(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_ah_sig_a_1)
+#define VHT_SIG_A_2(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_ah_sig_a_2)
+#define TSF_TIMESTAMP(rx_desc) \
+((rx_desc)->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32)
+
struct rx_location_info {
volatile
uint32_t rtt_fac_legacy:14, /* [13:0] */
@@ -469,6 +475,10 @@ struct rx_ppdu_start {
reserved_9:16; /* [31:16] */
};
+#define VHT_SIG_A_1(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_a_1)
+#define VHT_SIG_A_2(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_a_2)
+
+#define TSF_TIMESTAMP(rx_desc) ((rx_desc)->ppdu_end.tsf_timestamp)
struct rx_mpdu_start {
volatile
diff --git a/core/dp/ol/inc/ol_htt_api.h b/core/dp/ol/inc/ol_htt_api.h
index f55ddfb730ec..371af50bfa20 100644
--- a/core/dp/ol/inc/ol_htt_api.h
+++ b/core/dp/ol/inc/ol_htt_api.h
@@ -362,4 +362,7 @@ static inline void htt_ipa_uc_detach(struct htt_pdev_t *pdev)
}
#endif /* IPA_OFFLOAD */
+void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch);
+
+void ol_htt_mon_note_chan(ol_txrx_pdev_handle pdev, int mon_ch);
#endif /* _OL_HTT_API__H_ */
diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c
index 350d4c7a298d..eea89ab5570a 100644
--- a/core/dp/txrx/ol_rx.c
+++ b/core/dp/txrx/ol_rx.c
@@ -57,6 +57,7 @@
#include <ipv6_defs.h> /* IPv6 header defs */
#include <ol_vowext_dbg_defs.h>
#include <wma.h>
+#include <cds_concurrency.h>
#ifdef HTT_RX_RESTORE
#if defined(CONFIG_CNSS)
@@ -1243,7 +1244,10 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
qdf_nbuf_t head_msdu, tail_msdu = NULL;
if (pdev) {
- peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+ if (qdf_unlikely(QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()))
+ peer = pdev->self_peer;
+ else
+ peer = ol_txrx_peer_find_by_id(pdev, peer_id);
htt_pdev = pdev->htt_pdev;
} else {
TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
@@ -1374,6 +1378,17 @@ ol_rx_offload_paddr_deliver_ind_handler(htt_pdev_handle htt_pdev,
htt_rx_msdu_buff_replenish(htt_pdev);
}
+/**
+ * ol_htt_mon_note_chan() - Update monitor channel information
+ * @pdev: handle to the physical device
+ * @mon_ch: Monitor channel
+ *
+ * Return: None
+ */
+void ol_htt_mon_note_chan(ol_txrx_pdev_handle pdev, int mon_ch)
+{
+ htt_rx_mon_note_capture_channel(pdev->htt_pdev, mon_ch);
+}
#ifdef NEVERDEFINED
/**
diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c
index ff9f0a8180ce..c2b2490960dc 100644
--- a/core/dp/txrx/ol_txrx.c
+++ b/core/dp/txrx/ol_txrx.c
@@ -470,7 +470,7 @@ void htt_pkt_log_init(struct ol_txrx_pdev_t *handle, void *scn)
return;
if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE &&
- !WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
+ !QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
ol_pl_sethandle(&handle->pl_dev, scn);
if (pktlogmod_init(scn))
qdf_print("%s: pktlogmod_init failed", __func__);
@@ -489,7 +489,7 @@ void htt_pkt_log_init(struct ol_txrx_pdev_t *handle, void *scn)
void htt_pktlogmod_exit(struct ol_txrx_pdev_t *handle, void *scn)
{
if (scn && cds_get_conparam() != QDF_GLOBAL_FTM_MODE &&
- !WLAN_IS_EPPING_ENABLED(cds_get_conparam()) &&
+ !QDF_IS_EPPING_ENABLED(cds_get_conparam()) &&
handle->pkt_log_init) {
pktlogmod_exit(scn);
handle->pkt_log_init = false;
@@ -1569,6 +1569,15 @@ ol_txrx_peer_attach(ol_txrx_vdev_handle vdev, uint8_t *peer_mac_addr)
#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI
peer->rssi_dbm = HTT_RSSI_INVALID;
#endif
+ if ((QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) &&
+ !pdev->self_peer) {
+ pdev->self_peer = peer;
+ /*
+ * No Tx in monitor mode, otherwise results in target assert.
+ * Setting disable_intrabss_fwd to true
+ */
+ ol_vdev_rx_set_intrabss_fwd(vdev, true);
+ }
ol_txrx_local_peer_id_alloc(pdev, peer);
diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h
index a36346e63f1c..42d7b368427b 100644
--- a/core/dp/txrx/ol_txrx_types.h
+++ b/core/dp/txrx/ol_txrx_types.h
@@ -767,6 +767,7 @@ struct ol_txrx_pdev_t {
void *lro_data;
void (*lro_flush_cb)(void *);
} lro_info;
+ struct ol_txrx_peer_t *self_peer;
};
struct ol_txrx_ocb_chan_info {
diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h
index 5a1bfbef9f48..232a1d1c6f6e 100644
--- a/core/hdd/inc/qc_sap_ioctl.h
+++ b/core/hdd/inc/qc_sap_ioctl.h
@@ -131,42 +131,43 @@ typedef struct {
* (regardless of the incorrect comment in wireless.h!)
*/
-#define QCSAP_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0)
-#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1)
+#define QCSAP_IOCTL_SETPARAM (SIOCIWFIRSTPRIV + 0)
+#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV + 1)
/* (SIOCIWFIRSTPRIV+2) is unused */
-/* (SIOCIWFIRSTPRIV+3) is unused */
-#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV+4)
-#define QCSAP_IOCTL_SETWPAIE (SIOCIWFIRSTPRIV+5)
-#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV+6)
-#define QCSAP_IOCTL_VERSION (SIOCIWFIRSTPRIV+7)
-#define QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES (SIOCIWFIRSTPRIV+8)
-#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV+9)
-#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV+10)
-#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV+11)
+#define QCSAP_IOCTL_SET_NONE_GET_THREE (SIOCIWFIRSTPRIV + 3)
+#define WE_GET_TSF 1
+#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV + 4)
+#define QCSAP_IOCTL_SETWPAIE (SIOCIWFIRSTPRIV + 5)
+#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV + 6)
+#define QCSAP_IOCTL_VERSION (SIOCIWFIRSTPRIV + 7)
+#define QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES (SIOCIWFIRSTPRIV + 8)
+#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV + 9)
+#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV + 10)
+#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV + 11)
/* (SIOCIWFIRSTPRIV+12) is unused */
/* Private ioctls and their sub-ioctls */
#define QCSAP_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 13)
#define QCSAP_GET_STATS 1
#define QCSAP_LIST_FW_PROFILE 2
-#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV+14)
+#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV + 14)
-#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV+15)
+#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 15)
#define WE_SET_WLAN_DBG 1
#define WE_SET_DP_TRACE 2
#define WE_SET_SAP_CHANNELS 3
-#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV+16)
+#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 16)
#define WE_UNIT_TEST_CMD 7
-#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV+17)
+#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV + 17)
#define WE_P2P_NOA_CMD 2
-#define QCSAP_IOCTL_MODIFY_ACL (SIOCIWFIRSTPRIV+18)
-#define QCSAP_IOCTL_GET_CHANNEL_LIST (SIOCIWFIRSTPRIV+19)
-#define QCSAP_IOCTL_SET_TX_POWER (SIOCIWFIRSTPRIV+20)
-#define QCSAP_IOCTL_GET_STA_INFO (SIOCIWFIRSTPRIV+21)
-#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV+22)
-#define QCSAP_IOCTL_GET_INI_CFG (SIOCIWFIRSTPRIV+25)
-#define QCSAP_IOCTL_SET_INI_CFG (SIOCIWFIRSTPRIV+26)
+#define QCSAP_IOCTL_MODIFY_ACL (SIOCIWFIRSTPRIV + 18)
+#define QCSAP_IOCTL_GET_CHANNEL_LIST (SIOCIWFIRSTPRIV + 19)
+#define QCSAP_IOCTL_SET_TX_POWER (SIOCIWFIRSTPRIV + 20)
+#define QCSAP_IOCTL_GET_STA_INFO (SIOCIWFIRSTPRIV + 21)
+#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV + 22)
+#define QCSAP_IOCTL_GET_INI_CFG (SIOCIWFIRSTPRIV + 25)
+#define QCSAP_IOCTL_SET_INI_CFG (SIOCIWFIRSTPRIV + 26)
#define QCSAP_IOCTL_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28)
#ifdef DEBUG
#define QCSAP_IOCTL_SET_FW_CRASH_INJECT 1
@@ -241,7 +242,10 @@ enum {
QCASAP_CLEAR_STATS,
QCASAP_SET_RADAR_DBG,
QCSAP_GET_FW_PROFILE_DATA,
- QCSAP_START_FW_PROFILING
+ QCSAP_START_FW_PROFILING,
+ QCSAP_CAP_TSF,
+ QCSAP_GET_TSF,
+ QCSAP_PARAM_CONC_SYSTEM_PREF
};
int iw_softap_get_channel_list(struct net_device *dev,
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 98c9f9a35855..10b6c72a8331 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -463,6 +463,25 @@ typedef enum {
#define CFG_REST_TIME_CONC_MAX (10000)
#define CFG_REST_TIME_CONC_DEFAULT (100)
+/* Mininum time spent on home channel before moving to a new channel to scan */
+#define CFG_MIN_REST_TIME_NAME "gMinRestTimeConc"
+#define CFG_MIN_REST_TIME_MIN (0)
+#define CFG_MIN_REST_TIME_MAX (50)
+#define CFG_MIN_REST_TIME_DEFAULT (50)
+
+/* Data inactivity time in msec on bss channel that will be used
+ * by scan engine in firmware.
+ * for example if this value is 25ms then firmware will check for
+ * data inactivity every 25ms till gRestTimeConc is reached.
+ * If inactive then scan engine will move from home channel to
+ * scan the next frequency.
+ */
+#define CFG_IDLE_TIME_NAME "gIdleTimeConc"
+#define CFG_IDLE_TIME_MIN (0)
+#define CFG_IDLE_TIME_MAX (25)
+#define CFG_IDLE_TIME_DEFAULT (25)
+
+
#define CFG_NUM_STA_CHAN_COMBINED_CONC_NAME "gNumStaChanCombinedConc"
#define CFG_NUM_STA_CHAN_COMBINED_CONC_MIN (1)
#define CFG_NUM_STA_CHAN_COMBINED_CONC_MAX (255)
@@ -2911,6 +2930,12 @@ enum dot11p_mode {
#define CFG_INFORM_BSS_RSSI_RAW_MAX (1)
#define CFG_INFORM_BSS_RSSI_RAW_DEFAULT (1)
+/* GPIO pin to toggle when capture tsf */
+#define CFG_SET_TSF_GPIO_PIN_NAME "gtsf_gpio_pin"
+#define CFG_SET_TSF_GPIO_PIN_MIN (0)
+#define CFG_SET_TSF_GPIO_PIN_MAX (254)
+#define TSF_GPIO_PIN_INVALID (255)
+#define CFG_SET_TSF_GPIO_PIN_DEFAULT (TSF_GPIO_PIN_INVALID)
/*
* OBSS scan parameters
@@ -2989,6 +3014,15 @@ enum dot11p_mode {
#define CFG_ROAM_DENSE_MIN_APS_MAX (5)
#define CFG_ROAM_DENSE_MIN_APS_DEFAULT (1)
+/*
+ * Enable/Disable to initiate BUG report in case of fatal event
+ * Default: Enable
+ */
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER "gEnableFatalEvent"
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER_MIN (0)
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER_MAX (1)
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER_DEFAULT (1)
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -3096,6 +3130,10 @@ struct hdd_config {
uint32_t nActiveMinChnTimeConc; /* in units of milliseconds */
uint32_t nActiveMaxChnTimeConc; /* in units of milliseconds */
uint32_t nRestTimeConc; /* in units of milliseconds */
+ /* In units of milliseconds */
+ uint32_t min_rest_time_conc;
+ /* In units of milliseconds */
+ uint32_t idle_time_conc;
uint8_t nNumStaChanCombinedConc; /* number of channels combined for */
/* STA in each split scan operation */
uint8_t nNumP2PChanCombinedConc; /* number of channels combined for */
@@ -3579,6 +3617,9 @@ struct hdd_config {
uint16_t obss_passive_dwelltime;
uint16_t obss_width_trigger_interval;
uint8_t inform_bss_rssi_raw;
+#ifdef WLAN_FEATURE_TSF
+ uint32_t tsf_gpio_pin;
+#endif
#ifdef QCA_WIFI_3_0_EMU
bool enable_m2m_limitation;
#endif
@@ -3586,6 +3627,8 @@ struct hdd_config {
uint32_t roam_dense_rssi_thresh_offset;
bool ignore_peer_ht_opmode;
uint32_t roam_dense_min_aps;
+ bool enable_fatal_event;
+ bool bpf_enabled;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/inc/wlan_hdd_host_offload.h b/core/hdd/inc/wlan_hdd_host_offload.h
index 79d52ab3dbc9..873b6a73d1e3 100644
--- a/core/hdd/inc/wlan_hdd_host_offload.h
+++ b/core/hdd/inc/wlan_hdd_host_offload.h
@@ -57,4 +57,13 @@ typedef struct {
struct qdf_mac_addr bssId;
} tHostOffloadRequest, *tpHostOffloadRequest;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void hdd_wlan_offload_event(uint8_t type, uint8_t state);
+#else
+static inline
+void hdd_wlan_offload_event(uint8_t type, uint8_t state)
+{
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
#endif /* __WLAN_HDD_HOST_OFFLOAD_H__ */
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 39fe7e1a7d97..cdd77891d7e1 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -57,6 +57,7 @@
#ifdef FEATURE_WLAN_TDLS
#include "wlan_hdd_tdls.h"
#endif
+#include "wlan_hdd_tsf.h"
#include "wlan_hdd_cfg80211.h"
#include <qdf_defer.h>
#ifdef WLAN_FEATURE_MBSSID
@@ -149,6 +150,8 @@
#define WLAN_WAIT_TIME_ANTENNA_MODE_REQ 3000
#define WLAN_WAIT_TIME_SET_DUAL_MAC_CFG 1500
+#define WLAN_WAIT_TIME_BPF 1000
+
#define MAX_NUMBER_OF_ADAPTERS 4
#define MAX_CFG_STRING_LEN 255
@@ -244,12 +247,6 @@
*/
#define WLAN_TFC_IPAUC_TX_DESC_RESERVE 100
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
-#ifdef CONFIG_CNSS
-#define cfg80211_vendor_cmd_reply(skb) cnss_vendor_cmd_reply(skb)
-#endif
-#endif
-
/*
* NET_NAME_UNKNOWN is only introduced after Kernel 3.17, to have a macro
* here if the Kernel version is less than 3.17 to avoid the interleave
@@ -314,6 +311,7 @@ extern spinlock_t hdd_context_lock;
#define LINK_CONTEXT_MAGIC 0x4C494E4B /* LINKSPEED */
#define LINK_STATUS_MAGIC 0x4C4B5354 /* LINKSTATUS(LNST) */
#define TEMP_CONTEXT_MAGIC 0x74656d70 /* TEMP (temperature) */
+#define BPF_CONTEXT_MAGIC 0x4575354 /* BPF */
/* MAX OS Q block time value in msec
* Prevent from permanent stall, resume OS Q if timer expired */
@@ -627,6 +625,20 @@ typedef struct hdd_cfg80211_state_s {
eP2PActionFrameState actionFrmState;
} hdd_cfg80211_state_t;
+/**
+ * struct hdd_mon_set_ch_info - Holds monitor mode channel switch params
+ * @channel: Channel number.
+ * @cb_mode: Channel bonding
+ * @channel_width: Channel width 0/1/2 for 20/40/80MHz respectively.
+ * @phy_mode: PHY mode
+ */
+struct hdd_mon_set_ch_info {
+ uint8_t channel;
+ uint8_t cb_mode;
+ uint32_t channel_width;
+ eCsrPhyMode phy_mode;
+};
+
struct hdd_station_ctx {
/** Handle to the Wireless Extension State */
hdd_wext_state_t WextState;
@@ -661,6 +673,8 @@ struct hdd_station_ctx {
int staDebugState;
uint8_t broadcast_ibss_staid;
+
+ struct hdd_mon_set_ch_info ch_info;
};
#define BSS_STOP 0
@@ -940,6 +954,14 @@ struct hdd_adapter_s {
hdd_ap_ctx_t ap;
} sessionCtx;
+#ifdef WLAN_FEATURE_TSF
+ /* tsf value received from firmware */
+ uint32_t tsf_low;
+ uint32_t tsf_high;
+ /* TSF capture state */
+ enum hdd_tsf_capture_state tsf_state;
+#endif
+
hdd_cfg80211_state_t cfg80211State;
#ifdef WLAN_FEATURE_PACKET_FILTERING
@@ -1123,6 +1145,18 @@ struct hdd_offloaded_packets_ctx {
};
#endif
+/**
+ * struct hdd_bpf_context - hdd Context for bpf
+ * @magic: magic number
+ * @completion: Completion variable for BPF Get Capability
+ * @capability_response: capabilities response received from fw
+ */
+struct hdd_bpf_context {
+ unsigned int magic;
+ struct completion completion;
+ struct sir_bpf_get_offload capability_response;
+};
+
/** Adapter structure definition */
struct hdd_context_s {
@@ -1286,8 +1320,8 @@ struct hdd_context_s {
struct work_struct sap_start_work;
bool is_sap_restart_required;
bool is_sta_connection_pending;
- spinlock_t sap_update_info_lock;
- spinlock_t sta_update_info_lock;
+ qdf_spinlock_t sap_update_info_lock;
+ qdf_spinlock_t sta_update_info_lock;
uint8_t dev_dfs_cac_status;
@@ -1364,6 +1398,7 @@ struct hdd_context_s {
struct completion set_antenna_mode_cmpl;
/* Current number of TX X RX chains being used */
enum antenna_mode current_antenna_mode;
+ bool bpf_enabled;
};
/*---------------------------------------------------------------------------
@@ -1588,6 +1623,9 @@ uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
uint8_t bw_offset);
void hdd_update_config(hdd_context_t *hdd_ctx);
+QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter,
+ struct net_device *dev, uint8_t oper_chan);
+
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void);
#else
diff --git a/core/hdd/inc/wlan_hdd_p2p.h b/core/hdd/inc/wlan_hdd_p2p.h
index 3cc7dc7c0d18..9fcf9ecc2fed 100644
--- a/core/hdd/inc/wlan_hdd_p2p.h
+++ b/core/hdd/inc/wlan_hdd_p2p.h
@@ -51,6 +51,9 @@
#define WLAN_HDD_80211_FRM_DA_OFFSET 4
#define P2P_WILDCARD_SSID_LEN 7
#define P2P_WILDCARD_SSID "DIRECT-"
+#define WLAN_HDD_80211_PEER_ADDR_OFFSET (WLAN_HDD_80211_FRM_DA_OFFSET + \
+ MAC_ADDR_LEN)
+
#ifdef QCA_WIFI_3_0_EMU
#define P2P_ROC_DURATION_MULTIPLIER_GO_PRESENT 2
diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h
index 2ce7f2dd2957..d872fae107ac 100644
--- a/core/hdd/inc/wlan_hdd_power.h
+++ b/core/hdd/inc/wlan_hdd_power.h
@@ -126,6 +126,22 @@ struct pkt_filter_cfg {
#endif
+/**
+ * enum suspend_resume_state - Suspend resume state
+ * @HDD_WLAN_EARLY_SUSPEND: Early suspend state.
+ * @HDD_WLAN_SUSPEND: Suspend state.
+ * @HDD_WLAN_EARLY_RESUME: Early resume state.
+ * @HDD_WLAN_RESUME: Resume state.
+ *
+ * Suspend state to indicate in diag event of suspend resume.
+ */
+enum suspend_resume_state {
+ HDD_WLAN_EARLY_SUSPEND,
+ HDD_WLAN_SUSPEND,
+ HDD_WLAN_EARLY_RESUME,
+ HDD_WLAN_RESUME
+};
+
/* SSR shutdown & re-init functions */
QDF_STATUS hdd_wlan_shutdown(void);
@@ -171,4 +187,12 @@ int wlan_hdd_ipv4_changed(struct notifier_block *nb,
int wlan_hdd_ipv6_changed(struct notifier_block *nb,
unsigned long data, void *arg);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void hdd_wlan_suspend_resume_event(uint8_t state);
+#else
+static inline
+void hdd_wlan_suspend_resume_event(uint8_t state) {}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+
#endif /* __WLAN_HDD_POWER_H */
diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h
index 8a4cd45e7f89..2d446b4fe504 100644
--- a/core/hdd/inc/wlan_hdd_tdls.h
+++ b/core/hdd/inc/wlan_hdd_tdls.h
@@ -161,6 +161,30 @@ typedef enum eTDLSLinkStatus {
} tTDLSLinkStatus;
/**
+ * enum tdls_teardown_reason - Reason for TDLS teardown
+ * @eTDLS_TEARDOWN_EXT_CTRL: Reason ext ctrl.
+ * @eTDLS_TEARDOWN_CONCURRENCY: Reason concurrency.
+ * @eTDLS_TEARDOWN_RSSI_THRESHOLD: Reason rssi threshold.
+ * @eTDLS_TEARDOWN_TXRX_THRESHOLD: Reason txrx threshold.
+ * @eTDLS_TEARDOWN_BTCOEX: Reason BTCOEX.
+ * @eTDLS_TEARDOWN_SCAN: Reason scan.
+ * @eTDLS_TEARDOWN_BSS_DISCONNECT: Reason bss disconnected.
+ * @eTDLS_TEARDOWN_ANTENNA_SWITCH: Disconnected due to antenna switch
+ *
+ * Reason to indicate in diag event of tdls teardown.
+ */
+enum tdls_teardown_reason {
+ eTDLS_TEARDOWN_EXT_CTRL,
+ eTDLS_TEARDOWN_CONCURRENCY,
+ eTDLS_TEARDOWN_RSSI_THRESHOLD,
+ eTDLS_TEARDOWN_TXRX_THRESHOLD,
+ eTDLS_TEARDOWN_BTCOEX,
+ eTDLS_TEARDOWN_SCAN,
+ eTDLS_TEARDOWN_BSS_DISCONNECT,
+ eTDLS_TEARDOWN_ANTENNA_SWITCH,
+};
+
+/**
* enum tTDLSLinkReason - tdls link reason
*
* @eTDLS_LINK_SUCCESS: Success
@@ -607,7 +631,8 @@ int hdd_set_tdls_offchannel(hdd_context_t *hdd_ctx, int offchannel);
int hdd_set_tdls_secoffchanneloffset(hdd_context_t *hdd_ctx, int offchanoffset);
int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode);
int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val);
-void hdd_tdls_pre_init(hdd_context_t *hdd_ctx);
+void hdd_tdls_context_init(hdd_context_t *hdd_ctx);
+void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx);
#else
static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter,
@@ -622,7 +647,28 @@ static inline void wlan_hdd_tdls_exit(hdd_adapter_t *adapter)
{
}
-static inline void hdd_tdls_pre_init(hdd_context_t *hdd_ctx) { }
+static inline void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { }
+static inline void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) { }
#endif /* End of FEATURE_WLAN_TDLS */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void hdd_send_wlan_tdls_teardown_event(uint32_t reason,
+ uint8_t *peer_mac);
+void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac,
+ uint8_t is_off_chan_supported,
+ uint8_t is_off_chan_configured,
+ uint8_t is_off_chan_established);
+void hdd_wlan_block_scan_by_tdls_event(void);
+#else
+static inline
+void hdd_send_wlan_tdls_teardown_event(uint32_t reason,
+ uint8_t *peer_mac) {}
+static inline
+void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac,
+ uint8_t is_off_chan_supported,
+ uint8_t is_off_chan_configured,
+ uint8_t is_off_chan_established) {}
+static inline void hdd_wlan_block_scan_by_tdls_event(void) {}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
#endif /* __HDD_TDLS_H */
diff --git a/core/hdd/inc/wlan_hdd_tsf.h b/core/hdd/inc/wlan_hdd_tsf.h
new file mode 100644
index 000000000000..f251327d7f06
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_tsf.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#if !defined WLAN_HDD_TSF_H
+#define WLAN_HDD_TSF_H
+
+/**
+ * enum hdd_tsf_get_state - status of get tsf action
+ * @TSF_RETURN: get tsf
+ * @TSF_STA_NOT_CONNECTED_NO_TSF: sta not connected to ap
+ * @TSF_NOT_RETURNED_BY_FW: fw not returned tsf
+ * @TSF_CURRENT_IN_CAP_STATE: driver in capture state
+ * @TSF_CAPTURE_FAIL: capture fail
+ * @TSF_GET_FAIL: get fail
+ * @TSF_RESET_GPIO_FAIL: GPIO reset fail
+ * @TSF_SAP_NOT_STARTED_NO_TSF SAP not started
+ */
+enum hdd_tsf_get_state {
+ TSF_RETURN = 0,
+ TSF_STA_NOT_CONNECTED_NO_TSF,
+ TSF_NOT_RETURNED_BY_FW,
+ TSF_CURRENT_IN_CAP_STATE,
+ TSF_CAPTURE_FAIL,
+ TSF_GET_FAIL,
+ TSF_RESET_GPIO_FAIL,
+ TSF_SAP_NOT_STARTED_NO_TSF
+};
+
+/**
+ * enum hdd_tsf_capture_state - status of capture
+ * @TSF_IDLE: idle
+ * @TSF_CAP_STATE: current is in capture state
+ */
+enum hdd_tsf_capture_state {
+ TSF_IDLE = 0,
+ TSF_CAP_STATE
+};
+
+#ifdef WLAN_FEATURE_TSF
+void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx);
+int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len);
+int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len);
+#else
+static inline void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx)
+{
+ return;
+}
+
+static inline int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf,
+ int len)
+{
+ return -ENOTSUPP;
+}
+
+static inline int
+hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
+{
+ return -ENOTSUPP;
+}
+#endif
+
+#endif
diff --git a/core/hdd/inc/wlan_hdd_tx_rx.h b/core/hdd/inc/wlan_hdd_tx_rx.h
index df570cd83e48..526d8d098536 100644
--- a/core/hdd/inc/wlan_hdd_tx_rx.h
+++ b/core/hdd/inc/wlan_hdd_tx_rx.h
@@ -128,11 +128,9 @@ static inline void wlan_hdd_log_eapol(struct sk_buff *skb,
}
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
-
const char *hdd_reason_type_to_string(enum netif_reason_type reason);
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);
#endif /* end #if !defined(WLAN_HDD_TX_RX_H) */
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index 67066ebc1733..d1464e4d5eb6 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -3172,13 +3172,22 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
pRoamInfo->
peerMac.bytes,
true);
- if (NULL != curr_peer
- && TDLS_IS_CONNECTED(curr_peer)) {
+ if (NULL != curr_peer) {
+ hdd_info("Current status for peer " MAC_ADDRESS_STR " is %d",
+ MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
+ curr_peer->link_status);
+ if (TDLS_IS_CONNECTED(curr_peer)) {
hdd_roam_deregister_tdlssta
(pAdapter,
pRoamInfo->staId);
wlan_hdd_tdls_decrement_peer_count
(pAdapter);
+ } else if (eTDLS_LINK_CONNECTING ==
+ curr_peer->link_status) {
+ hdd_roam_deregister_tdlssta
+ (pAdapter,
+ pRoamInfo->staId);
+ }
}
wlan_hdd_tdls_reset_peer(pAdapter,
pRoamInfo->
@@ -3209,6 +3218,8 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
pRoamInfo->peerMac.bytes, true);
wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
pRoamInfo->reasonCode);
+ hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT,
+ curr_peer->peerMac);
status = QDF_STATUS_SUCCESS;
break;
}
@@ -3388,6 +3399,9 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
wlan_hdd_tdls_indicate_teardown
(pHddTdlsCtx->pAdapter, curr_peer,
reason);
+ hdd_send_wlan_tdls_teardown_event(
+ eTDLS_TEARDOWN_BSS_DISCONNECT,
+ curr_peer->peerMac);
} else {
hddLog(LOGE,
FL
@@ -3436,6 +3450,9 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
wlan_hdd_tdls_indicate_teardown
(pHddTdlsCtx->pAdapter, curr_peer,
reason);
+ hdd_send_wlan_tdls_teardown_event(
+ eTDLS_TEARDOWN_BSS_DISCONNECT,
+ curr_peer->peerMac);
} else {
hddLog(LOGE,
FL
@@ -4296,6 +4313,19 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
break;
}
#endif /* FEATURE_WLAN_ESE */
+ case eCSR_ROAM_STA_CHANNEL_SWITCH:
+ hdd_info("channel switch for session:%d to channel:%d",
+ pAdapter->sessionId, pRoamInfo->chan_info.chan_id);
+
+ status = hdd_chan_change_notify(pAdapter, pAdapter->dev,
+ pRoamInfo->chan_info.chan_id);
+ if (QDF_IS_STATUS_ERROR(status))
+ hdd_err("channel change notification failed");
+
+ status = cds_set_hw_mode_on_channel_switch(pAdapter->sessionId);
+ if (QDF_IS_STATUS_ERROR(status))
+ hdd_info("set hw mode change not done");
+ break;
default:
break;
}
@@ -4971,8 +5001,41 @@ static int __iw_set_essid(struct net_device *dev,
(WLAN_HDD_GET_CTX(pAdapter))->config->
AdHocChannel5G);
}
+ /*
+ * Change conn_state to connecting before sme_roam_connect(),
+ * because sme_roam_connect() has a direct path to call
+ * hdd_sme_roam_callback(), which will change the conn_state
+ * If direct path, conn_state will be accordingly changed to
+ * NotConnected or Associated by either
+ * hdd_association_completion_handler() or hdd_dis_connect_handler()
+ * in sme_RoamCallback()if sme_RomConnect is to be queued,
+ * Connecting state will remain until it is completed.
+ *
+ * If connection state is not changed,
+ * connection state will remain in eConnectionState_NotConnected state.
+ * In hdd_association_completion_handler, "hddDisconInProgress" is
+ * set to true if conn state is eConnectionState_NotConnected.
+ * If "hddDisconInProgress" is set to true then cfg80211 layer is not
+ * informed of connect result indication which is an issue.
+ */
+ if (QDF_STA_MODE == pAdapter->device_mode ||
+ QDF_P2P_CLIENT_MODE == pAdapter->device_mode) {
+ hdd_info("Set HDD connState to eConnectionState_Connecting");
+ hdd_conn_set_connection_state(pAdapter,
+ eConnectionState_Connecting);
+ }
+
status = sme_roam_connect(hHal, pAdapter->sessionId,
&(pWextState->roamProfile), &roamId);
+ if ((QDF_STATUS_SUCCESS != status) &&
+ (QDF_STA_MODE == pAdapter->device_mode ||
+ QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
+ hdd_err("sme_roam_connect (session %d) failed with status %d. -> NotConnected",
+ pAdapter->sessionId, status);
+ /* change back to NotAssociated */
+ hdd_conn_set_connection_state(pAdapter,
+ eConnectionState_NotConnected);
+ }
pRoamProfile->ChannelInfo.ChannelList = NULL;
pRoamProfile->ChannelInfo.numOfChannels = 0;
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index eba3d85c8a67..e5a3164a9443 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -44,6 +44,7 @@
#include <csr_api.h>
#include <wlan_hdd_misc.h>
#include <wlan_hdd_napi.h>
+#include <cds_concurrency.h>
static void
cb_notify_set_roam_prefer5_g_hz(hdd_context_t *pHddCtx, unsigned long notifyId)
@@ -802,6 +803,20 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_REST_TIME_CONC_MIN,
CFG_REST_TIME_CONC_MAX),
+ REG_VARIABLE(CFG_MIN_REST_TIME_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, min_rest_time_conc,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MIN_REST_TIME_DEFAULT,
+ CFG_MIN_REST_TIME_MIN,
+ CFG_MIN_REST_TIME_MAX),
+
+ REG_VARIABLE(CFG_IDLE_TIME_NAME , WLAN_PARAM_Integer,
+ struct hdd_config, idle_time_conc,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_IDLE_TIME_DEFAULT,
+ CFG_IDLE_TIME_MIN,
+ CFG_IDLE_TIME_MAX) ,
+
REG_VARIABLE(CFG_NUM_STA_CHAN_COMBINED_CONC_NAME, WLAN_PARAM_Integer,
struct hdd_config, nNumStaChanCombinedConc,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -3725,6 +3740,15 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_INFORM_BSS_RSSI_RAW_MIN,
CFG_INFORM_BSS_RSSI_RAW_MAX),
+#ifdef WLAN_FEATURE_TSF
+ REG_VARIABLE(CFG_SET_TSF_GPIO_PIN_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, tsf_gpio_pin,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_SET_TSF_GPIO_PIN_DEFAULT,
+ CFG_SET_TSF_GPIO_PIN_MIN,
+ CFG_SET_TSF_GPIO_PIN_MAX),
+#endif
+
#ifdef QCA_WIFI_3_0_EMU
REG_VARIABLE(CFG_ENABLE_M2M_LIMITATION, WLAN_PARAM_Integer,
struct hdd_config, enable_m2m_limitation,
@@ -3763,6 +3787,15 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ROAM_DENSE_MIN_APS_MIN,
CFG_ROAM_DENSE_MIN_APS_MAX),
+ REG_VARIABLE(CFG_ENABLE_FATAL_EVENT_TRIGGER, WLAN_PARAM_Integer,
+ struct hdd_config, enable_fatal_event,
+ VAR_FLAGS_OPTIONAL |
+ VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ENABLE_FATAL_EVENT_TRIGGER_DEFAULT,
+ CFG_ENABLE_FATAL_EVENT_TRIGGER_MIN,
+ CFG_ENABLE_FATAL_EVENT_TRIGGER_MAX),
+
+
};
@@ -5354,8 +5387,18 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
CFG_IGNORE_PEER_HT_MODE_NAME,
pHddCtx->config->ignore_peer_ht_opmode);
hdd_info("Name = [%s] Value = [%u]",
+ CFG_ENABLE_FATAL_EVENT_TRIGGER,
+ pHddCtx->config->enable_fatal_event);
+ hdd_info("Name = [%s] Value = [%u]",
CFG_ROAM_DENSE_MIN_APS,
pHddCtx->config->roam_dense_min_aps);
+ hdd_info("Name = [%s] Value = [%u]",
+ CFG_MIN_REST_TIME_NAME,
+ pHddCtx->config->min_rest_time_conc);
+ hdd_info("Name = [%s] Value = [%u]",
+ CFG_IDLE_TIME_NAME,
+ pHddCtx->config->idle_time_conc);
+
}
@@ -5454,6 +5497,66 @@ config_exit:
}
/**
+ * hdd_disable_runtime_pm() - Override to disable runtime_pm.
+ * @cfg_ini: Handle to struct hdd_config
+ *
+ * Return: None
+ */
+#ifdef FEATURE_RUNTIME_PM
+static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini)
+{
+ cfg_ini->runtime_pm = 0;
+}
+#else
+static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini)
+{
+}
+#endif
+
+/**
+ * hdd_disable_auto_shutdown() - Override to disable auto_shutdown.
+ * @cfg_ini: Handle to struct hdd_config
+ *
+ * Return: None
+ */
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini)
+{
+ cfg_ini->WlanAutoShutdown = 0;
+}
+#else
+static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini)
+{
+}
+#endif
+
+/**
+ * hdd_override_all_ps() - overrides to disables all the powersave features.
+ * @hdd_ctx: Pointer to HDD context.
+ * Overrides below powersave ini configurations.
+ * gEnableImps=0
+ * gEnableBmps=0
+ * gRuntimePM=0
+ * gWlanAutoShutdown = 0
+ * gEnableSuspend=0
+ * gEnablePowerSaveOffload=0
+ * gEnableWoW=0
+ *
+ * Return: None
+ */
+static void hdd_override_all_ps(hdd_context_t *hdd_ctx)
+{
+ struct hdd_config *cfg_ini = hdd_ctx->config;
+
+ cfg_ini->fIsImpsEnabled = 0;
+ cfg_ini->is_ps_enabled = 0;
+ hdd_disable_runtime_pm(cfg_ini);
+ hdd_disable_auto_shutdown(cfg_ini);
+ cfg_ini->enablePowersaveOffload = 0;
+ cfg_ini->wowEnable = 0;
+}
+
+/**
* hdd_parse_config_ini() - parse the ini configuration file
* @pHddCtx: the pointer to hdd context
*
@@ -5556,6 +5659,8 @@ QDF_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx)
hdd_napi_event(NAPI_EVT_INI_FILE,
(void *)pHddCtx->config->napi_enable);
#endif /* FEATURE_NAPI */
+ if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
+ hdd_override_all_ps(pHddCtx);
config_exit:
release_firmware(fw);
@@ -6565,6 +6670,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
smeConfig->csrConfig.nPassiveMinChnTimeConc =
pConfig->nPassiveMinChnTimeConc;
smeConfig->csrConfig.nRestTimeConc = pConfig->nRestTimeConc;
+ smeConfig->csrConfig.min_rest_time_conc = pConfig->min_rest_time_conc;
+ smeConfig->csrConfig.idle_time_conc = pConfig->idle_time_conc;
smeConfig->csrConfig.nNumStaChanCombinedConc =
pConfig->nNumStaChanCombinedConc;
smeConfig->csrConfig.nNumP2PChanCombinedConc =
@@ -6799,6 +6906,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
pHddCtx->config->obss_passive_dwelltime;
smeConfig->csrConfig.ignore_peer_ht_opmode =
pConfig->ignore_peer_ht_opmode;
+ smeConfig->csrConfig.enable_fatal_event =
+ pConfig->enable_fatal_event;
status = sme_update_config(pHddCtx->hHal, smeConfig);
if (!QDF_IS_STATUS_SUCCESS(status)) {
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index c8af93844f02..79cc8b41943a 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -42,9 +42,6 @@
#include <net/arp.h>
#include <net/cfg80211.h>
#include <qdf_trace.h>
-#ifdef CONFIG_CNSS
-#include <net/cnss.h>
-#endif
#include <wlan_hdd_wowl.h>
#include <ani_global.h>
#include "sir_params.h"
@@ -177,12 +174,6 @@ static struct ieee80211_channel hdd_channels_2_4_ghz[] = {
HDD2GHZCHAN(2484, 14, 0),
};
-static struct ieee80211_channel hdd_social_channels_2_4_ghz[] = {
- HDD2GHZCHAN(2412, 1, 0),
- HDD2GHZCHAN(2437, 6, 0),
- HDD2GHZCHAN(2462, 11, 0),
-};
-
static struct ieee80211_channel hdd_channels_5_ghz[] = {
HDD5GHZCHAN(5180, 36, 0),
HDD5GHZCHAN(5200, 40, 0),
@@ -271,23 +262,6 @@ static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
};
-static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_ghz = {
- .channels = hdd_social_channels_2_4_ghz,
- .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_ghz),
- .band = IEEE80211_BAND_2GHZ,
- .bitrates = g_mode_rates,
- .n_bitrates = g_mode_rates_size,
- .ht_cap.ht_supported = 1,
- .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
- | IEEE80211_HT_CAP_GRN_FLD
- | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
- .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
- .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
- .ht_cap.mcs.rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
- .ht_cap.mcs.rx_highest = cpu_to_le16(72),
- .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
-};
-
static struct ieee80211_supported_band wlan_hdd_band_5_ghz = {
.channels = hdd_channels_5_ghz,
.n_channels = ARRAY_SIZE(hdd_channels_5_ghz),
@@ -505,6 +479,24 @@ wlan_hdd_p2p_p2p_iface_limit[] = {
},
};
+static const struct ieee80211_iface_limit
+ wlan_hdd_mon_iface_limit[] = {
+ {
+ .max = 3, /* Monitor interface */
+ .types = BIT(NL80211_IFTYPE_MONITOR),
+ },
+};
+
+static struct ieee80211_iface_combination
+ wlan_hdd_mon_iface[] = {
+ {
+ .limits = wlan_hdd_mon_iface_limit,
+ .max_interfaces = 3,
+ .num_different_channels = 2,
+ .n_limits = ARRAY_SIZE(wlan_hdd_mon_iface_limit),
+ },
+};
+
static struct ieee80211_iface_combination
wlan_hdd_iface_combination[] = {
/* STA */
@@ -585,7 +577,7 @@ static struct ieee80211_iface_combination
};
static struct cfg80211_ops wlan_hdd_cfg80211_ops;
-
+struct hdd_bpf_context bpf_context;
#ifdef WLAN_NL80211_TESTMODE
enum wlan_hdd_tm_attr {
@@ -1773,13 +1765,8 @@ void wlan_hdd_cfg80211_acs_ch_select_evt(hdd_adapter_t *adapter)
con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
if (con_sap_adapter &&
test_bit(ACS_PENDING, &con_sap_adapter->event_flags)) {
-#ifdef CONFIG_CNSS
- cnss_init_delayed_work(&con_sap_adapter->acs_pending_work,
- wlan_hdd_cfg80211_start_pending_acs);
-#else
INIT_DELAYED_WORK(&con_sap_adapter->acs_pending_work,
wlan_hdd_cfg80211_start_pending_acs);
-#endif
/* Lets give 500ms for OBSS + START_BSS to complete */
schedule_delayed_work(&con_sap_adapter->acs_pending_work,
msecs_to_jiffies(500));
@@ -3563,7 +3550,8 @@ static int __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
status = cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
WLAN_LOG_INDICATOR_FRAMEWORK,
- WLAN_LOG_REASON_CODE_UNUSED);
+ WLAN_LOG_REASON_CODE_UNUSED,
+ true, false);
if (QDF_STATUS_SUCCESS != status) {
hddLog(LOGE, FL("Failed to trigger bug report"));
return -EINVAL;
@@ -4913,7 +4901,363 @@ static int wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy,
return ret;
}
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_bpf_offload()
+ */
+#define BPF_INVALID \
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID
+#define BPF_SET_RESET \
+ QCA_WLAN_VENDOR_ATTR_SET_RESET_PACKET_FILTER
+#define BPF_VERSION \
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION
+#define BPF_FILTER_ID \
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID
+#define BPF_PACKET_SIZE \
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE
+#define BPF_CURRENT_OFFSET \
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET
+#define BPF_PROGRAM \
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM
+#define BPF_MAX \
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX
+
+static const struct nla_policy
+wlan_hdd_bpf_offload_policy[BPF_MAX + 1] = {
+ [BPF_SET_RESET] = {.type = NLA_U32},
+ [BPF_VERSION] = {.type = NLA_U32},
+ [BPF_FILTER_ID] = {.type = NLA_U32},
+ [BPF_PACKET_SIZE] = {.type = NLA_U32},
+ [BPF_CURRENT_OFFSET] = {.type = NLA_U32},
+ [BPF_PROGRAM] = {.type = NLA_U8},
+};
+
+/**
+ * hdd_get_bpf_offload_cb() - Callback function to BPF Offload
+ * @hdd_context: hdd_context
+ * @bpf_get_offload: struct for get offload
+ *
+ * This function receives the response/data from the lower layer and
+ * checks to see if the thread is still waiting then post the results to
+ * upper layer, if the request has timed out then ignore.
+ *
+ * Return: None
+ */
+void hdd_get_bpf_offload_cb(void *hdd_context,
+ struct sir_bpf_get_offload *data)
+{
+ hdd_context_t *hdd_ctx = hdd_context;
+ struct hdd_bpf_context *context;
+
+ ENTER();
+
+ if (wlan_hdd_validate_context(hdd_ctx) || !data) {
+ hddLog(LOGE, FL("HDD context is invalid or data(%p) is null"),
+ data);
+ return;
+ }
+
+ spin_lock(&hdd_context_lock);
+
+ context = &bpf_context;
+ /* The caller presumably timed out so there is nothing we can do */
+ if (context->magic != BPF_CONTEXT_MAGIC) {
+ spin_unlock(&hdd_context_lock);
+ return;
+ }
+
+ /* context is valid so caller is still waiting */
+ /* paranoia: invalidate the magic */
+ context->magic = 0;
+
+ context->capability_response = *data;
+ complete(&context->completion);
+
+ spin_unlock(&hdd_context_lock);
+
+ return;
+}
+
+/**
+ * hdd_post_get_bpf_capabilities_rsp() - Callback function to BPF Offload
+ * @hdd_context: hdd_context
+ * @bpf_get_offload: struct for get offload
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+static int hdd_post_get_bpf_capabilities_rsp(hdd_context_t *hdd_ctx,
+ struct sir_bpf_get_offload *bpf_get_offload)
+{
+ struct sk_buff *skb;
+ uint32_t nl_buf_len;
+
+ ENTER();
+
+ nl_buf_len = NLMSG_HDRLEN;
+ nl_buf_len +=
+ (sizeof(bpf_get_offload->max_bytes_for_bpf_inst) + NLA_HDRLEN) +
+ (sizeof(bpf_get_offload->bpf_version) + NLA_HDRLEN);
+
+ skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+ if (!skb) {
+ hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
+ return -ENOMEM;
+ }
+
+ hddLog(LOG1, "BPF Version: %u BPF max bytes: %u",
+ bpf_get_offload->bpf_version,
+ bpf_get_offload->max_bytes_for_bpf_inst);
+
+ if (nla_put_u32(skb, BPF_PACKET_SIZE,
+ bpf_get_offload->max_bytes_for_bpf_inst) ||
+ nla_put_u32(skb, BPF_VERSION, bpf_get_offload->bpf_version)) {
+ hddLog(LOGE, FL("nla put failure"));
+ goto nla_put_failure;
+ }
+
+ cfg80211_vendor_cmd_reply(skb);
+ EXIT();
+ return 0;
+
+nla_put_failure:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+/**
+ * hdd_get_bpf_offload - Get BPF offload Capabilities
+ * @hdd_ctx: Hdd context
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int hdd_get_bpf_offload(hdd_context_t *hdd_ctx)
+{
+ unsigned long rc;
+ struct hdd_bpf_context *context;
+ QDF_STATUS status;
+ int ret;
+
+ ENTER();
+
+ spin_lock(&hdd_context_lock);
+ context = &bpf_context;
+ context->magic = BPF_CONTEXT_MAGIC;
+ INIT_COMPLETION(context->completion);
+ spin_unlock(&hdd_context_lock);
+
+ status = sme_get_bpf_offload_capabilities(hdd_ctx->hHal);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hddLog(LOGE, FL("Unable to retrieve BPF caps"));
+ return -EINVAL;
+ }
+ /* request was sent -- wait for the response */
+ rc = wait_for_completion_timeout(&context->completion,
+ msecs_to_jiffies(WLAN_WAIT_TIME_BPF));
+ if (!rc) {
+ hddLog(LOGE, FL("Target response timed out"));
+ spin_lock(&hdd_context_lock);
+ context->magic = 0;
+ spin_unlock(&hdd_context_lock);
+
+ return -ETIMEDOUT;
+ }
+ ret = hdd_post_get_bpf_capabilities_rsp(hdd_ctx,
+ &bpf_context.capability_response);
+ if (ret)
+ hddLog(LOGE, FL("Failed to post get bpf capabilities"));
+
+ EXIT();
+ return ret;
+}
+
+/**
+ * hdd_set_reset_bpf_offload - Post set/reset bpf to SME
+ * @hdd_ctx: Hdd context
+ * @tb: Length of @data
+ * @session_id: Session identifier
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int hdd_set_reset_bpf_offload(hdd_context_t *hdd_ctx,
+ struct nlattr **tb,
+ uint8_t session_id)
+{
+ struct sir_bpf_set_offload *bpf_set_offload;
+ QDF_STATUS status;
+ int prog_len;
+
+ ENTER();
+
+ bpf_set_offload = qdf_mem_malloc(sizeof(*bpf_set_offload));
+ if (bpf_set_offload == NULL) {
+ hddLog(LOGE, FL("qdf_mem_malloc failed for bpf_set_offload"));
+ return -ENOMEM;
+ }
+ qdf_mem_zero(bpf_set_offload, sizeof(*bpf_set_offload));
+
+ /* Parse and fetch bpf packet size */
+ if (!tb[BPF_PACKET_SIZE]) {
+ hddLog(LOGE, FL("attr bpf packet size failed"));
+ goto fail;
+ }
+ bpf_set_offload->total_length = nla_get_u32(tb[BPF_PACKET_SIZE]);
+
+ if (!bpf_set_offload->total_length) {
+ hddLog(LOG1, FL("BPF reset packet filter received"));
+ goto post_sme;
+ }
+
+ /* Parse and fetch bpf program */
+ if (!tb[BPF_PROGRAM]) {
+ hddLog(LOGE, FL("attr bpf program failed"));
+ goto fail;
+ }
+
+ prog_len = nla_len(tb[BPF_PROGRAM]);
+ bpf_set_offload->program = qdf_mem_malloc(sizeof(uint8_t) * prog_len);
+ 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;
+
+ /* Parse and fetch filter Id */
+ if (!tb[BPF_FILTER_ID]) {
+ hddLog(LOGE, FL("attr filter id failed"));
+ goto fail;
+ }
+ bpf_set_offload->filter_id = nla_get_u32(tb[BPF_FILTER_ID]);
+
+ /* Parse and fetch current offset */
+ if (!tb[BPF_CURRENT_OFFSET]) {
+ hddLog(LOGE, FL("attr current offset failed"));
+ goto fail;
+ }
+ bpf_set_offload->current_offset = nla_get_u32(tb[BPF_CURRENT_OFFSET]);
+
+post_sme:
+ hddLog(LOG1, FL("Posting BPF SET/RESET to SME, session_id: %d Bpf Version: %d filter ID: %d total_length: %d current_length: %d current offset: %d"),
+ bpf_set_offload->session_id,
+ bpf_set_offload->version,
+ bpf_set_offload->filter_id,
+ bpf_set_offload->total_length,
+ bpf_set_offload->current_length,
+ bpf_set_offload->current_offset);
+
+ status = sme_set_bpf_instructions(hdd_ctx->hHal, bpf_set_offload);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hddLog(LOGE,
+ FL("sme_set_bpf_instructions failed(err=%d)"), status);
+ 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;
+}
+
+/**
+ * wlan_hdd_cfg80211_bpf_offload() - Set/Reset to BPF Offload
+ * @wiphy: wiphy structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_bpf_offload(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ struct net_device *dev = wdev->netdev;
+ hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ struct nlattr *tb[BPF_MAX + 1];
+ int ret_val, packet_filter_subcmd;
+
+ ENTER();
+
+ ret_val = wlan_hdd_validate_context(hdd_ctx);
+ if (ret_val)
+ return ret_val;
+
+ if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+ hddLog(LOGE, FL("Command not allowed in FTM mode"));
+ return -EINVAL;
+ }
+
+ if (!hdd_ctx->bpf_enabled) {
+ hddLog(LOGE, FL("BPF offload is not supported by firmware"));
+ return -ENOTSUPP;
+ }
+
+ if (nla_parse(tb, BPF_MAX, data, data_len,
+ wlan_hdd_bpf_offload_policy)) {
+ hddLog(LOGE, FL("Invalid ATTR"));
+ return -EINVAL;
+ }
+
+ if (!tb[BPF_SET_RESET]) {
+ hddLog(LOGE, FL("attr bpf set reset failed"));
+ return -EINVAL;
+ }
+
+ packet_filter_subcmd = nla_get_u32(tb[BPF_SET_RESET]);
+
+ if (packet_filter_subcmd == QCA_WLAN_GET_PACKET_FILTER)
+ return hdd_get_bpf_offload(hdd_ctx);
+ else
+ return hdd_set_reset_bpf_offload(hdd_ctx, tb,
+ pAdapter->sessionId);
+}
+
+/**
+ * wlan_hdd_cfg80211_bpf_offload() - SSR Wrapper to BPF Offload
+ * @wiphy: wiphy structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; errno on failure
+ */
+
+static int wlan_hdd_cfg80211_bpf_offload(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int ret;
+
+ cds_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_bpf_offload(wiphy, wdev, data, data_len);
+ cds_ssr_unprotect(__func__);
+
+ return ret;
+}
+
+/**
+ * hdd_init_bpf_completion() - Initialize the completion event for bpf
+ *
+ * Return: None
+ */
+void hdd_init_bpf_completion(void)
+{
+ init_completion(&bpf_context.completion);
+}
+#undef BPF_INVALID
+#undef BPF_SET_RESET
+#undef BPF_VERSION
+#undef BPF_ID
+#undef BPF_PACKET_SIZE
+#undef BPF_CURRENT_OFFSET
+#undef BPF_PROGRAM
+#undef BPF_MAX
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
{
.info.vendor_id = QCA_NL80211_VENDOR_ID,
@@ -5368,6 +5712,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_txpower_scale_decr_db
},
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_bpf_offload
+ },
};
/**
@@ -5543,26 +5895,35 @@ int wlan_hdd_cfg80211_init(struct device *dev,
wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
- /* Supports STATION & AD-HOC modes right now */
- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
- | BIT(NL80211_IFTYPE_ADHOC)
- | BIT(NL80211_IFTYPE_P2P_CLIENT)
- | BIT(NL80211_IFTYPE_P2P_GO)
- | BIT(NL80211_IFTYPE_AP);
-
- if (pCfg->advertiseConcurrentOperation) {
- if (pCfg->enableMCC) {
- int i;
- for (i = 0; i < ARRAY_SIZE(wlan_hdd_iface_combination);
- i++) {
- if (!pCfg->allowMCCGODiffBI)
- wlan_hdd_iface_combination[i].
- beacon_int_infra_match = true;
+ if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE) {
+ /* Supports STATION & AD-HOC modes right now */
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+ | BIT(NL80211_IFTYPE_ADHOC)
+ | BIT(NL80211_IFTYPE_P2P_CLIENT)
+ | BIT(NL80211_IFTYPE_P2P_GO)
+ | BIT(NL80211_IFTYPE_AP);
+
+ if (pCfg->advertiseConcurrentOperation) {
+ if (pCfg->enableMCC) {
+ int i;
+
+ for (i = 0;
+ i < ARRAY_SIZE(wlan_hdd_iface_combination);
+ i++) {
+ if (!pCfg->allowMCCGODiffBI)
+ wlan_hdd_iface_combination[i].
+ beacon_int_infra_match = true;
+ }
}
+ wiphy->n_iface_combinations =
+ ARRAY_SIZE(wlan_hdd_iface_combination);
+ wiphy->iface_combinations = wlan_hdd_iface_combination;
}
+ } else {
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_MONITOR);
wiphy->n_iface_combinations =
- ARRAY_SIZE(wlan_hdd_iface_combination);
- wiphy->iface_combinations = wlan_hdd_iface_combination;
+ ARRAY_SIZE(wlan_hdd_mon_iface);
+ wiphy->iface_combinations = wlan_hdd_mon_iface;
}
/* Before registering we need to update the ht capabilitied based
@@ -5570,8 +5931,6 @@ int wlan_hdd_cfg80211_init(struct device *dev,
if (!pCfg->ShortGI20MhzEnable) {
wlan_hdd_band_2_4_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
wlan_hdd_band_5_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
- wlan_hdd_band_p2p_2_4_ghz.ht_cap.cap &=
- ~IEEE80211_HT_CAP_SGI_20;
}
if (!pCfg->ShortGI40MhzEnable) {
@@ -7434,9 +7793,7 @@ wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter,
int rssi = 0;
hdd_context_t *pHddCtx;
int status;
-#ifdef CONFIG_CNSS
struct timespec ts;
-#endif
struct hdd_config *cfg_param;
ENTER();
@@ -7455,18 +7812,11 @@ wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter,
memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
-#ifdef CONFIG_CNSS
/* Android does not want the timestamp from the frame.
Instead it wants a monotonic increasing value */
- cnss_get_monotonic_boottime(&ts);
+ get_monotonic_boottime(&ts);
mgmt->u.probe_resp.timestamp =
((u64) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
-#else
- /* keep old behavior for non-open source (for now) */
- memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
- sizeof(bss_desc->timeStamp));
-
-#endif
mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
@@ -7877,6 +8227,10 @@ void hdd_select_cbmode(hdd_adapter_t *pAdapter, uint8_t operationChannel)
uint8_t iniDot11Mode = (WLAN_HDD_GET_CTX(pAdapter))->config->dot11Mode;
eHddDot11Mode hddDot11Mode = iniDot11Mode;
struct ch_params_s ch_params;
+ hdd_station_ctx_t *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+ uint32_t cb_mode;
+ struct hdd_mon_set_ch_info *ch_info = &station_ctx->ch_info;
+
ch_params.ch_width =
(WLAN_HDD_GET_CTX(pAdapter))->config->vhtChannelWidth;
@@ -7899,10 +8253,20 @@ void hdd_select_cbmode(hdd_adapter_t *pAdapter, uint8_t operationChannel)
break;
}
/* This call decides required channel bonding mode */
- sme_set_ch_params((WLAN_HDD_GET_CTX(pAdapter)->hHal),
+ cb_mode = sme_set_ch_params((WLAN_HDD_GET_CTX(pAdapter)->hHal),
hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
operationChannel, 0,
&ch_params);
+
+ if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) {
+ ch_info->channel_width = ch_params.ch_width;
+ ch_info->phy_mode = hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode);
+ ch_info->channel = operationChannel;
+ ch_info->cb_mode = cb_mode;
+ hdd_info("ch_info width %d, phymode %d channel %d",
+ ch_info->channel_width, ch_info->phy_mode,
+ ch_info->channel);
+ }
}
/**
@@ -8194,20 +8558,6 @@ int wlan_hdd_cfg80211_connect_start(hdd_adapter_t *pAdapter,
return -EINVAL;
}
- /* change conn_state to connecting before sme_roam_connect(), because sme_roam_connect()
- * has a direct path to call hdd_sme_roam_callback(), which will change the conn_state
- * If direct path, conn_state will be accordingly changed to NotConnected or Associated
- * by either hdd_association_completion_handler() or hdd_dis_connect_handler() in sme_RoamCallback()
- * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
- */
- if (QDF_STA_MODE == pAdapter->device_mode ||
- QDF_P2P_CLIENT_MODE == pAdapter->device_mode) {
- hddLog(LOG1,
- FL("Set HDD connState to eConnectionState_Connecting"));
- hdd_conn_set_connection_state(pAdapter,
- eConnectionState_Connecting);
- }
-
/* After 8-way handshake supplicant should give the scan command
* in that it update the additional IEs, But because of scan
* enhancements, the supplicant is not issuing the scan command now.
@@ -8263,6 +8613,32 @@ int wlan_hdd_cfg80211_connect_start(hdd_adapter_t *pAdapter,
pHddCtx->config->nChannelBondingMode24GHz;
sme_update_config(pHddCtx->hHal, sme_config);
qdf_mem_free(sme_config);
+ /*
+ * Change conn_state to connecting before sme_roam_connect(),
+ * because sme_roam_connect() has a direct path to call
+ * hdd_sme_roam_callback(), which will change the conn_state
+ * If direct path, conn_state will be accordingly changed to
+ * NotConnected or Associated by either
+ * hdd_association_completion_handler() or
+ * hdd_dis_connect_handler() in sme_RoamCallback()if
+ * sme_RomConnect is to be queued,
+ * Connecting state will remain until it is completed.
+ *
+ * If connection state is not changed, connection state will
+ * remain in eConnectionState_NotConnected state.
+ * In hdd_association_completion_handler, "hddDisconInProgress"
+ * is set to true if conn state is
+ * eConnectionState_NotConnected.
+ * If "hddDisconInProgress" is set to true then cfg80211 layer
+ * is not informed of connect result indication which
+ * is an issue.
+ */
+ if (QDF_STA_MODE == pAdapter->device_mode ||
+ QDF_P2P_CLIENT_MODE == pAdapter->device_mode) {
+ hdd_info("Set HDD connState to eConnectionState_Connecting");
+ hdd_conn_set_connection_state(pAdapter,
+ eConnectionState_Connecting);
+ }
status = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId, pRoamProfile,
@@ -11477,6 +11853,93 @@ enum cds_con_mode wlan_hdd_convert_nl_iftype_to_hdd_type(
}
/**
+ * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
+ * @wiphy: Handle to struct wiphy to get handle to module context.
+ * @chandef: Contains information about the capture channel to be set.
+ *
+ * This interface is called if and only if monitor mode interface alone is
+ * active.
+ *
+ * Return: 0 success or error code on failure.
+ */
+static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
+ struct cfg80211_chan_def *chandef)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ hdd_adapter_t *adapter;
+ hdd_station_ctx_t *sta_ctx;
+ struct hdd_mon_set_ch_info *ch_info;
+ QDF_STATUS status;
+ tHalHandle hal_hdl;
+ struct qdf_mac_addr bssid;
+ tCsrRoamProfile roam_profile;
+ struct ch_params_s ch_params;
+ int ret;
+ uint16_t chan_num = cds_freq_to_chan(chandef->chan->center_freq);
+
+ ENTER();
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret)
+ return ret;
+
+ hal_hdl = hdd_ctx->hHal;
+
+ adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
+ if (!adapter)
+ return -EIO;
+
+ hdd_info("%s: set monitor mode Channel %d and freq %d",
+ adapter->dev->name, chan_num, chandef->chan->center_freq);
+
+ sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ ch_info = &sta_ctx->ch_info;
+ hdd_select_cbmode(adapter, chan_num);
+ roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
+ roam_profile.ChannelInfo.numOfChannels = 1;
+ roam_profile.phyMode = ch_info->phy_mode;
+ roam_profile.ch_params.ch_width = chandef->width;
+
+ qdf_mem_copy(bssid.bytes, adapter->macAddressCurrent.bytes,
+ QDF_MAC_ADDR_SIZE);
+
+ ch_params.ch_width = chandef->width;
+ sme_set_ch_params(hal_hdl, ch_info->phy_mode, chan_num, 0,
+ &ch_params);
+ status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params,
+ &roam_profile);
+ if (status) {
+ hdd_err("Status: %d Failed to set sme_RoamChannel for monitor mode",
+ status);
+ ret = qdf_status_to_os_return(status);
+ return ret;
+ }
+ EXIT();
+ return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
+ * @wiphy: Handle to struct wiphy to get handle to module context.
+ * @chandef: Contains information about the capture channel to be set.
+ *
+ * This interface is called if and only if monitor mode interface alone is
+ * active.
+ *
+ * Return: 0 success or error code on failure.
+ */
+static int wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
+ struct cfg80211_chan_def *chandef)
+{
+ int ret;
+
+ cds_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_set_mon_ch(wiphy, chandef);
+ cds_ssr_unprotect(__func__);
+ return ret;
+}
+
+/**
* struct cfg80211_ops - cfg80211_ops
*
* @add_virtual_intf: Add virtual interface
@@ -11591,4 +12054,5 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = {
#ifdef CHANNEL_SWITCH_SUPPORTED
.channel_switch = wlan_hdd_cfg80211_channel_switch,
#endif
+ .set_monitor_channel = wlan_hdd_cfg80211_set_mon_ch,
};
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
index 9ba52bb31790..1a185b0e30fd 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -344,6 +344,7 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS = 79,
QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI = 80,
+ QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER = 83,
/* OCB commands */
QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG = 92,
QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME = 93,
@@ -2139,6 +2140,40 @@ enum qca_wlan_vendor_attr_rssi_monitoring {
};
/**
+ * enum set_reset_packet_filter - set packet filter control commands
+ * @QCA_WLAN_SET_PACKET_FILTER: Set Packet Filter
+ * @QCA_WLAN_GET_PACKET_FILTER: Get Packet filter
+ */
+enum set_reset_packet_filter {
+ QCA_WLAN_SET_PACKET_FILTER = 1,
+ QCA_WLAN_GET_PACKET_FILTER = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_packet_filter - BPF control commands
+ * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID: Invalid
+ * @QCA_WLAN_VENDOR_ATTR_SET_RESET_PACKET_FILTER: Filter ID
+ * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION: Filter Version
+ * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE: Total Length
+ * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET: Current offset
+ * @QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM: length of BPF instructions
+ */
+enum qca_wlan_vendor_attr_packet_filter {
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_SET_RESET_PACKET_FILTER,
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION,
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID,
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE,
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET,
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX =
+ QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST - 1,
+};
+
+/**
* enum qca_vendor_attr_get_preferred_freq_list - get preferred channel list
* @QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_INVALID: invalid value
* @QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE: interface type
@@ -2435,4 +2470,7 @@ int wlan_hdd_disable_dfs_chan_scan(hdd_context_t *hdd_ctx,
int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy,
eCsrBand eBand);
+
+void hdd_get_bpf_offload_cb(void *hdd_context, struct sir_bpf_get_offload *);
+void hdd_init_bpf_completion(void);
#endif
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index 1649840e98ae..c5fc181def9b 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -54,6 +54,7 @@
#include "qwlan_version.h"
#include "bmi.h"
#include "cdp_txrx_bus.h"
+#include "pld_common.h"
#ifdef MODULE
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
@@ -61,25 +62,7 @@
#define WLAN_MODULE_NAME "wlan"
#endif
-#ifdef HIF_PCI
-#ifdef CONFIG_CNSS
-#define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \
- cnss_wlan_register_driver(wlan_drv_ops)
-#define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \
- cnss_wlan_unregister_driver(wlan_drv_ops)
-#else
-#define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \
- pci_register_driver(wlan_drv_ops)
-#define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \
- pci_unregister_driver(wlan_drv_ops)
-#endif /* CONFIG_CNSS */
-#else
-#define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \
- icnss_register_driver(wlan_drv_ops)
-#define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \
- icnss_unregister_driver(wlan_drv_ops)
-#endif /* HIF_PCI */
-#define DISABLE_KRAIT_IDLE_PS_VAL 1
+#define DISABLE_KRAIT_IDLE_PS_VAL 1
/*
* In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
@@ -210,6 +193,26 @@ static void hdd_deinit_cds_hif_context(void)
}
/**
+ * to_bus_type() - Map PLD bus type to low level bus type
+ * @bus_type: PLD bus type
+ *
+ * Map PLD bus type to low level bus type.
+ *
+ * Return: low level bus type.
+ */
+static enum qdf_bus_type to_bus_type(enum pld_bus_type bus_type)
+{
+ switch (bus_type) {
+ case PLD_BUS_TYPE_PCIE:
+ return QDF_BUS_TYPE_PCI;
+ case PLD_BUS_TYPE_SNOC:
+ return QDF_BUS_TYPE_SNOC;
+ default:
+ return QDF_BUS_TYPE_NONE;
+ }
+}
+
+/**
* hdd_hif_open() - HIF open helper
* @dev: wlan device structure
* @bdev: bus device structure
@@ -353,7 +356,7 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid,
cds_set_load_in_progress(true);
}
- if (WLAN_IS_EPPING_ENABLED(mode)) {
+ if (QDF_IS_EPPING_ENABLED(mode)) {
status = epping_open();
if (status != QDF_STATUS_SUCCESS)
goto err_hdd_deinit;
@@ -403,7 +406,7 @@ err_bmi_close:
err_hif_close:
hdd_hif_close(hif_ctx);
err_epping_close:
- if (WLAN_IS_EPPING_ENABLED(mode))
+ if (QDF_IS_EPPING_ENABLED(mode))
epping_close();
err_hdd_deinit:
cds_set_load_in_progress(false);
@@ -457,7 +460,7 @@ static void wlan_hdd_remove(void)
hif_disable_power_management(hif_ctx);
- if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
+ if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
epping_disable();
epping_close();
} else {
@@ -493,7 +496,7 @@ static void wlan_hdd_shutdown(void)
if (!cds_wait_for_external_threads_completion(__func__))
hdd_err("Host is not ready for SSR, attempting anyway");
- if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
+ if (!QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
hif_disable_isr(hif_ctx);
hdd_wlan_shutdown();
}
@@ -527,7 +530,7 @@ void wlan_hdd_crash_shutdown(void)
*/
void wlan_hdd_notify_handler(int state)
{
- if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
+ if (!QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
int ret = 0;
ret = hdd_wlan_notify_modem_power_state(state);
if (ret < 0)
@@ -790,268 +793,181 @@ static int wlan_hdd_runtime_resume(void)
}
#endif
-#ifdef HIF_PCI
/**
- * wlan_hdd_pci_probe() - probe callback for pci platform driver
- * @pdev: bus dev
+ * wlan_hdd_pld_probe() - probe function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ * @bdev: bus device structure
+ * @id: bus identifier for shared busses
*
- * Return: void
+ * Return: 0 on success
*/
-static int wlan_hdd_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int wlan_hdd_pld_probe(struct device *dev,
+ enum pld_bus_type pld_bus_type,
+ void *bdev, void *id)
{
- return wlan_hdd_probe(&pdev->dev, pdev, (void *)id,
- QDF_BUS_TYPE_PCI, false);
+ enum qdf_bus_type bus_type;
+
+ bus_type = to_bus_type(pld_bus_type);
+ if (bus_type == QDF_BUS_TYPE_NONE) {
+ hdd_err("Invalid bus type %d->%d",
+ pld_bus_type, bus_type);
+ return -EINVAL;
+ }
+
+ return wlan_hdd_probe(dev, bdev, id, bus_type, false);
}
/**
- * wlan_hdd_pci_remove() - wlan_hdd_pci_remove
+ * wlan_hdd_pld_remove() - remove function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
*
* Return: void
*/
-void wlan_hdd_pci_remove(struct pci_dev *pdev)
+static void wlan_hdd_pld_remove(struct device *dev,
+ enum pld_bus_type bus_type)
{
wlan_hdd_remove();
}
/**
- * wlan_hdd_pci_reinit() - wlan_hdd_pci_reinit
- * @pdev: bus dev
- * @id: bus id
- *
- * Return: int
- */
-int wlan_hdd_pci_reinit(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- return wlan_hdd_probe(&pdev->dev, pdev, (void *)id,
- QDF_BUS_TYPE_PCI, true);
-}
-
-/**
- * wlan_hdd_pci_shutdown() - wlan_hdd_pci_shutdown
- * @pdev: pdev
+ * wlan_hdd_pld_shutdown() - shutdown function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
*
* Return: void
*/
-void wlan_hdd_pci_shutdown(struct pci_dev *pdev)
+static void wlan_hdd_pld_shutdown(struct device *dev,
+ enum pld_bus_type bus_type)
{
wlan_hdd_shutdown();
}
/**
- * wlan_hdd_pci_crash_shutdown() - wlan_hdd_pci_crash_shutdown
- * @pdev: pdev
+ * wlan_hdd_pld_reinit() - reinit function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ * @bdev: bus device structure
+ * @id: bus identifier for shared busses
*
- * Return: void
+ * Return: 0 on success
*/
-void wlan_hdd_pci_crash_shutdown(struct pci_dev *pdev)
+static int wlan_hdd_pld_reinit(struct device *dev,
+ enum pld_bus_type pld_bus_type,
+ void *bdev, void *id)
{
- wlan_hdd_crash_shutdown();
-}
+ enum qdf_bus_type bus_type;
-/**
- * wlan_hdd_pci_notify_handler() - wlan_hdd_pci_notify_handler
- * @pdev: pdev
- * @state: state
- *
- * Return: void
- */
-void wlan_hdd_pci_notify_handler(struct pci_dev *pdev, int state)
-{
- wlan_hdd_notify_handler(state);
-}
+ bus_type = to_bus_type(pld_bus_type);
+ if (bus_type == QDF_BUS_TYPE_NONE) {
+ hdd_err("Invalid bus type %d->%d",
+ pld_bus_type, bus_type);
+ return -EINVAL;
+ }
-/**
- * wlan_hdd_pci_suspend() - wlan_hdd_pci_suspend
- * @pdev: pdev
- * @state: state
- *
- * Return: void
- */
-static int wlan_hdd_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- return wlan_hdd_bus_suspend(state);
+ return wlan_hdd_probe(dev, bdev, id, bus_type, true);
}
/**
- * wlan_hdd_pci_resume() - wlan_hdd_pci_resume
- * @pdev: pdev
+ * wlan_hdd_pld_crash_shutdown() - crash_shutdown function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
*
* Return: void
*/
-static int wlan_hdd_pci_resume(struct pci_dev *pdev)
-{
- return wlan_hdd_bus_resume();
-}
-
-#ifdef FEATURE_RUNTIME_PM
-/**
- * wlan_hdd_pci_runtime_suspend() - wlan_hdd_pci_suspend
- * @pdev: pdev
- * @state: state
- *
- * Return: success or errno
- */
-static int wlan_hdd_pci_runtime_suspend(struct pci_dev *pdev)
+static void wlan_hdd_pld_crash_shutdown(struct device *dev,
+ enum pld_bus_type bus_type)
{
- return wlan_hdd_runtime_suspend();
-}
-
-/**
- * wlan_hdd_pci_runtime_resume() - runtime resume callback to register with pci
- * @pdev: pci device id
- *
- * Return: success or errno
- */
-static int wlan_hdd_pci_runtime_resume(struct pci_dev *pdev)
-{
- return wlan_hdd_runtime_resume();
-}
-#endif
-
-#else
-/**
- * wlan_hdd_snoc_probe() - wlan_hdd_snoc_probe
- * @dev: dev
- *
- * Return: int
- */
-static int wlan_hdd_snoc_probe(struct device *dev)
-{
- return wlan_hdd_probe(dev, NULL, NULL, QDF_BUS_TYPE_SNOC, false);
+ wlan_hdd_crash_shutdown();
}
/**
- * wlan_hdd_snoc_remove() - wlan_hdd_snoc_remove
- * @dev: dev
+ * wlan_hdd_pld_suspend() - suspend function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ * @state: PM state
*
- * Return: void
+ * Return: 0 on success
*/
-void wlan_hdd_snoc_remove(struct device *dev)
-{
- wlan_hdd_remove();
-}
+static int wlan_hdd_pld_suspend(struct device *dev,
+ enum pld_bus_type bus_type,
+ pm_message_t state)
-/**
- * wlan_hdd_snoc_shutdown() - wlan_hdd_snoc_shutdown
- * @dev: dev
- *
- * Return: void
- */
-void wlan_hdd_snoc_shutdown(struct device *dev)
{
- wlan_hdd_shutdown();
+ return wlan_hdd_bus_suspend(state);
}
/**
- * wlan_hdd_snoc_reinit() - wlan_hdd_snoc_reinit
- * @dev: dev
+ * wlan_hdd_pld_resume() - resume function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
*
- * Return: int
+ * Return: 0 on success
*/
-int wlan_hdd_snoc_reinit(struct device *dev)
+static int wlan_hdd_pld_resume(struct device *dev,
+ enum pld_bus_type bus_type)
{
- return wlan_hdd_probe(dev, NULL, NULL, QDF_BUS_TYPE_SNOC, true);
+ return wlan_hdd_bus_resume();
}
/**
- * wlan_hdd_snoc_crash_shutdown() - wlan_hdd_snoc_crash_shutdown
- * @dev: dev
+ * wlan_hdd_pld_notify_handler() - notify_handler function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ * @state: Modem power state
*
* Return: void
*/
-void wlan_hdd_snoc_crash_shutdown(void *pdev)
+static void wlan_hdd_pld_notify_handler(struct device *dev,
+ enum pld_bus_type bus_type,
+ int state)
{
- wlan_hdd_crash_shutdown();
+ wlan_hdd_notify_handler(state);
}
+#ifdef FEATURE_RUNTIME_PM
/**
- * wlan_hdd_snoc_suspend() - wlan_hdd_snoc_suspend
- * @dev: dev
- * @state: state
+ * wlan_hdd_pld_runtime_suspend() - runtime suspend function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
*
- * Return: int
+ * Return: 0 on success
*/
-static int wlan_hdd_snoc_suspend(struct device *dev, pm_message_t state)
+static int wlan_hdd_pld_runtime_suspend(struct device *dev,
+ enum pld_bus_type bus_type)
{
- return wlan_hdd_bus_suspend(state);
+ return wlan_hdd_runtime_suspend();
}
/**
- * wlan_hdd_snoc_resume() - wlan_hdd_snoc_resume
- * @dev: dev
+ * wlan_hdd_pld_runtime_resume() - runtime resume function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
*
- * Return: int
+ * Return: 0 on success
*/
-static int wlan_hdd_snoc_resume(struct device *dev)
+static int wlan_hdd_pld_runtime_resume(struct device *dev,
+ enum pld_bus_type bus_type)
{
- return wlan_hdd_bus_resume();
+ return wlan_hdd_runtime_resume();
}
-#endif /* HIF_PCI */
-
-#ifdef HIF_PCI
-static struct pci_device_id wlan_hdd_pci_id_table[] = {
- { 0x168c, 0x003c, PCI_ANY_ID, PCI_ANY_ID },
- { 0x168c, 0x003e, PCI_ANY_ID, PCI_ANY_ID },
- { 0x168c, 0x0041, PCI_ANY_ID, PCI_ANY_ID },
- { 0x168c, 0xabcd, PCI_ANY_ID, PCI_ANY_ID },
- { 0x168c, 0x7021, PCI_ANY_ID, PCI_ANY_ID },
- { 0 }
-};
-
-#ifdef CONFIG_CNSS
-
-#ifdef FEATURE_RUNTIME_PM
-struct cnss_wlan_runtime_ops runtime_pm_ops = {
- .runtime_suspend = wlan_hdd_pci_runtime_suspend,
- .runtime_resume = wlan_hdd_pci_runtime_resume,
-};
#endif
-struct cnss_wlan_driver wlan_drv_ops = {
- .name = "wlan_hdd_pci",
- .id_table = wlan_hdd_pci_id_table,
- .probe = wlan_hdd_pci_probe,
- .remove = wlan_hdd_pci_remove,
- .reinit = wlan_hdd_pci_reinit,
- .shutdown = wlan_hdd_pci_shutdown,
- .crash_shutdown = wlan_hdd_pci_crash_shutdown,
- .modem_status = wlan_hdd_pci_notify_handler,
-#ifdef ATH_BUS_PM
- .suspend = wlan_hdd_pci_suspend,
- .resume = wlan_hdd_pci_resume,
-#endif /* ATH_BUS_PM */
+struct pld_driver_ops wlan_drv_ops = {
+ .probe = wlan_hdd_pld_probe,
+ .remove = wlan_hdd_pld_remove,
+ .shutdown = wlan_hdd_pld_shutdown,
+ .reinit = wlan_hdd_pld_reinit,
+ .crash_shutdown = wlan_hdd_pld_crash_shutdown,
+ .suspend = wlan_hdd_pld_suspend,
+ .resume = wlan_hdd_pld_resume,
+ .modem_status = wlan_hdd_pld_notify_handler,
#ifdef FEATURE_RUNTIME_PM
- .runtime_ops = &runtime_pm_ops,
+ .runtime_suspend = wlan_hdd_pld_runtime_suspend,
+ .runtime_resume = wlan_hdd_pld_runtime_resume,
#endif
};
-#else
-MODULE_DEVICE_TABLE(pci, wlan_hdd_pci_id_table);
-struct pci_driver wlan_drv_ops = {
- .name = "wlan_hdd_pci",
- .id_table = wlan_hdd_pci_id_table,
- .probe = wlan_hdd_pci_probe,
- .remove = wlan_hdd_pci_remove,
-#ifdef ATH_BUS_PM
- .suspend = wlan_hdd_pci_suspend,
- .resume = wlan_hdd_pci_resume,
-#endif /* ATH_BUS_PM */
-
-};
-#endif /* CONFIG_CNSS */
-#else
-struct icnss_driver_ops wlan_drv_ops = {
- .name = "wlan_hdd_drv",
- .probe = wlan_hdd_snoc_probe,
- .remove = wlan_hdd_snoc_remove,
- .shutdown = wlan_hdd_snoc_shutdown,
- .reinit = wlan_hdd_snoc_reinit,
- .crash_shutdown = wlan_hdd_snoc_crash_shutdown,
- .suspend = wlan_hdd_snoc_suspend,
- .resume = wlan_hdd_snoc_resume,
-};
-#endif
/**
* wlan_hdd_register_driver() - wlan_hdd_register_driver
@@ -1060,7 +976,7 @@ struct icnss_driver_ops wlan_drv_ops = {
*/
int wlan_hdd_register_driver(void)
{
- return WLAN_HDD_REGISTER_DRIVER(&wlan_drv_ops);
+ return pld_register_driver(&wlan_drv_ops);
}
/**
@@ -1070,5 +986,5 @@ int wlan_hdd_register_driver(void)
*/
void wlan_hdd_unregister_driver(void)
{
- WLAN_HDD_UNREGISTER_DRIVER(&wlan_drv_ops);
+ pld_unregister_driver();
}
diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c
index 06473990b67c..34a943e47df4 100644
--- a/core/hdd/src/wlan_hdd_ext_scan.c
+++ b/core/hdd/src/wlan_hdd_ext_scan.c
@@ -772,9 +772,8 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
{
hdd_context_t *pHddCtx = (hdd_context_t *) ctx;
struct sk_buff *skb = NULL;
-#ifdef CONFIG_CNSS
struct timespec ts;
-#endif
+
int flags = cds_get_gfp_flags();
ENTER();
@@ -804,12 +803,12 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
}
pData->ap.channel = cds_chan_to_freq(pData->ap.channel);
-#ifdef CONFIG_CNSS
+
/* Android does not want the time stamp from the frame.
Instead it wants a monotonic increasing value since boot */
- cnss_get_monotonic_boottime(&ts);
+ get_monotonic_boottime(&ts);
pData->ap.ts = ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
-#endif
+
hddLog(LOG1, "Req Id %u More Data %u", pData->requestId,
pData->moreData);
hddLog(LOG1, "AP Info: Timestamp %llu Ssid: %s "
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 3e5e6406c430..bf0cb5c310ba 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -75,6 +75,7 @@
#include "qdf_trace.h"
#include "wlan_hdd_cfg.h"
#include "cds_concurrency.h"
+#include "wlan_hdd_tsf.h"
#include "wlan_hdd_green_ap.h"
#define IS_UP(_dev) \
@@ -101,16 +102,25 @@
/* Function definitions */
/**
- * hdd_hostapd_channel_wakelock_init() - init the channel wakelock
- * @pHddCtx: pointer to hdd context
+ * hdd_sap_context_init() - Initialize SAP context.
+ * @hdd_ctx: HDD context.
*
- * Return: None
+ * Initialize SAP context.
+ *
+ * Return: 0 on success.
*/
-void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx)
+int hdd_sap_context_init(hdd_context_t *hdd_ctx)
{
- /* Initialize the wakelock */
- qdf_wake_lock_create(&pHddCtx->sap_dfs_wakelock, "sap_dfs_wakelock");
- atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
+ qdf_wake_lock_create(&hdd_ctx->sap_dfs_wakelock, "sap_dfs_wakelock");
+ atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
+
+ mutex_init(&hdd_ctx->sap_lock);
+ qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock");
+ qdf_spinlock_create(&hdd_ctx->sap_update_info_lock);
+
+ mutex_init(&hdd_ctx->dfs_lock);
+
+ return 0;
}
/**
@@ -186,25 +196,33 @@ void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter,
}
/**
- * hdd_hostapd_channel_wakelock_deinit() - destroy the channel wakelock
+ * hdd_sap_context_destroy() - Destroy SAP context
*
- * @pHddCtx: pointer to hdd context
+ * @hdd_ctx: HDD context.
+ *
+ * Destroy SAP context.
*
* Return: None
*/
-void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx)
+void hdd_sap_context_destroy(hdd_context_t *hdd_ctx)
{
- if (atomic_read(&pHddCtx->sap_dfs_ref_cnt)) {
- /* Release wakelock */
- qdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
+ if (atomic_read(&hdd_ctx->sap_dfs_ref_cnt)) {
+ qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock,
WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
- /* Reset the reference count */
- atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
- hddLog(LOGE, FL("DFS: allowing suspend"));
+
+ atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
+ hdd_warn("DFS: Allowing suspend");
}
- /* Destroy lock */
- qdf_wake_lock_destroy(&pHddCtx->sap_dfs_wakelock);
+ qdf_wake_lock_destroy(&hdd_ctx->sap_dfs_wakelock);
+
+ mutex_destroy(&hdd_ctx->sap_lock);
+ qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock);
+
+ mutex_destroy(&hdd_ctx->dfs_lock);
+
+ qdf_spinlock_destroy(&hdd_ctx->sap_update_info_lock);
+
}
/**
@@ -705,7 +723,7 @@ hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
* Return: Success on intimating userspace
*
*/
-QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
+QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter,
struct net_device *dev,
uint8_t oper_chan)
{
@@ -715,7 +733,7 @@ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
eCsrPhyMode phy_mode;
ePhyChanBondState cb_mode;
uint32_t freq;
- tHalHandle hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter);
+ tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
if (NULL == hal) {
hdd_err("hal is NULL");
@@ -724,14 +742,18 @@ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
freq = cds_chan_to_freq(oper_chan);
- chan = __ieee80211_get_channel(hostapd_adapter->wdev.wiphy, freq);
+ chan = __ieee80211_get_channel(adapter->wdev.wiphy, freq);
if (!chan) {
hdd_err("Invalid input frequency for channel conversion");
return QDF_STATUS_E_FAILURE;
}
- phy_mode = hdd_sap_get_phymode(hostapd_adapter);
+ if (adapter->device_mode == QDF_SAP_MODE ||
+ adapter->device_mode == QDF_P2P_GO_MODE)
+ phy_mode = hdd_sap_get_phymode(adapter);
+ else
+ phy_mode = sme_get_phy_mode(hal);
if (oper_chan <= 14)
cb_mode = sme_get_cb_phy_state_from_cb_ini_value(
@@ -766,7 +788,7 @@ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
if ((phy_mode == eCSR_DOT11_MODE_11ac) ||
(phy_mode == eCSR_DOT11_MODE_11ac_ONLY))
- hdd_update_chandef(hostapd_adapter, &chandef, cb_mode);
+ hdd_update_chandef(adapter, &chandef, cb_mode);
cfg80211_ch_switch_notify(dev, &chandef);
@@ -1098,6 +1120,15 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
cds_dump_concurrency_info();
/* Send SCC/MCC Switching event to IPA */
hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
+
+ if (cds_is_hw_mode_change_after_vdev_up()) {
+ hdd_info("check for possible hw mode change");
+ status = cds_set_hw_mode_on_channel_switch(
+ pHostapdAdapter->sessionId);
+ if (QDF_IS_STATUS_ERROR(status))
+ hdd_info("set hw mode change not done");
+ cds_set_do_hw_mode_change_flag(false);
+ }
break; /* Event will be sent after Switch-Case stmt */
case eSAP_STOP_BSS_EVENT:
@@ -2453,7 +2484,16 @@ static __iw_softap_setparam(struct net_device *dev,
else
ret = -EINVAL;
break;
-
+ case QCSAP_PARAM_CONC_SYSTEM_PREF:
+ hdd_info("New preference: %d", set_value);
+ if (!((set_value >= CFG_CONC_SYSTEM_PREF_MIN) &&
+ (set_value <= CFG_CONC_SYSTEM_PREF_MAX))) {
+ hdd_err("Invalid system preference %d", set_value);
+ return -EINVAL;
+ }
+ /* hdd_ctx, hdd_ctx->config are already checked for null */
+ hdd_ctx->config->conc_system_pref = set_value;
+ break;
case QCSAP_PARAM_MAX_ASSOC:
if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) {
hddLog(LOGE, FL("Invalid setMaxAssoc value %d"),
@@ -3011,6 +3051,66 @@ static __iw_softap_setparam(struct net_device *dev,
return ret;
}
+/**
+ * __iw_softap_get_three() - return three value to upper layer.
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/out
+ *
+ * Return: execute result
+ */
+static int __iw_softap_get_three(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ uint32_t *value = (uint32_t *)extra;
+ uint32_t sub_cmd = value[0];
+ int ret = 0; /* success */
+ struct hdd_context_s *hdd_ctx;
+ struct hdd_adapter_s *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret != 0)
+ return ret;
+
+ switch (sub_cmd) {
+ case QCSAP_GET_TSF:
+ ret = hdd_indicate_tsf(adapter, value, 3);
+ break;
+ default:
+ hdd_err(FL("Invalid getparam command %d"), sub_cmd);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+
+/**
+ * iw_softap_get_three() - return three value to upper layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int iw_softap_get_three(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret;
+
+ cds_ssr_protect(__func__);
+ ret = __iw_softap_get_three(dev, info, wrqu, extra);
+ cds_ssr_unprotect(__func__);
+
+ return ret;
+}
+
int
static iw_softap_setparam(struct net_device *dev,
struct iw_request_info *info,
@@ -3211,6 +3311,9 @@ static __iw_softap_getparam(struct net_device *dev,
VDEV_CMD);
break;
}
+ case QCSAP_CAP_TSF:
+ ret = hdd_capture_tsf(pHostapdAdapter, (uint32_t *)value, 1);
+ break;
case QCASAP_GET_TEMP_CMD:
{
hddLog(LOG1, "QCASAP_GET_TEMP_CMD");
@@ -5608,6 +5711,10 @@ static const struct iw_priv_args hostapd_private_args[] = {
QCSAP_PARAM_AUTO_CHANNEL,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
"setAutoChannel"
+ }, {
+ QCSAP_PARAM_CONC_SYSTEM_PREF,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+ "setConcSysPref"
},
/* Sub-cmds DBGLOG specific commands */
{
@@ -5822,6 +5929,15 @@ static const struct iw_priv_args hostapd_private_args[] = {
QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_nss"
}, {
+ QCSAP_CAP_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "cap_tsf"
+ }, {
+ QCSAP_IOCTL_SET_NONE_GET_THREE, 0, IW_PRIV_TYPE_INT |
+ IW_PRIV_SIZE_FIXED | 3, ""
+ }, {
+ QCSAP_GET_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+ "get_tsf"
+ }, {
QCASAP_GET_TEMP_CMD, 0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
}, {
@@ -5997,6 +6113,8 @@ static const iw_handler hostapd_private[] = {
[QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
/* get priv ioctl */
[QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
+ [QCSAP_IOCTL_SET_NONE_GET_THREE - SIOCIWFIRSTPRIV] =
+ iw_softap_get_three,
/* get station genIE */
[QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
[QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
@@ -8046,9 +8164,9 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
(QDF_SAP_MODE == pAdapter->device_mode)) {
cds_flush_work(&pHddCtx->sap_start_work);
hddLog(LOGW, FL("Canceled the pending restart work"));
- spin_lock(&pHddCtx->sap_update_info_lock);
+ qdf_spin_lock(&pHddCtx->sap_update_info_lock);
pHddCtx->is_sap_restart_required = false;
- spin_unlock(&pHddCtx->sap_update_info_lock);
+ qdf_spin_unlock(&pHddCtx->sap_update_info_lock);
}
pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list)
diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h
index 223b1c12cf0e..ed8c0ac5d3e0 100644
--- a/core/hdd/src/wlan_hdd_hostapd.h
+++ b/core/hdd/src/wlan_hdd_hostapd.h
@@ -98,8 +98,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter);
void hdd_set_ap_ops(struct net_device *pWlanHostapdDev);
int hdd_hostapd_stop(struct net_device *dev);
-void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx);
-void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx);
+int hdd_sap_context_init(hdd_context_t *hdd_ctx);
+void hdd_sap_context_destroy(hdd_context_t *hdd_ctx);
#ifdef FEATURE_WLAN_FORCE_SAP_SCC
void hdd_restart_softap(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter);
#endif /* FEATURE_WLAN_FORCE_SAP_SCC */
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index 84cc0e37cb38..90e6c7228e87 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -1743,19 +1743,11 @@ end:
*
* Return: none
*/
-#ifdef CONFIG_CNSS
-static void hdd_ipa_init_uc_op_work(struct work_struct *work,
- work_func_t work_handler)
-{
- cnss_init_work(work, work_handler);
-}
-#else
static void hdd_ipa_init_uc_op_work(struct work_struct *work,
work_func_t work_handler)
{
INIT_WORK(work, work_handler);
}
-#endif
/**
@@ -2353,19 +2345,11 @@ int hdd_ipa_set_perf_level(hdd_context_t *hdd_ctx, uint64_t tx_packets,
*
* Return: none
*/
-#ifdef CONFIG_CNSS
-static void hdd_ipa_init_uc_rm_work(struct work_struct *work,
- work_func_t work_handler)
-{
- cnss_init_work(work, work_handler);
-}
-#else
static void hdd_ipa_init_uc_rm_work(struct work_struct *work,
work_func_t work_handler)
{
INIT_WORK(work, work_handler);
}
-#endif
/**
* hdd_ipa_setup_rm() - Setup IPA resource management
@@ -2430,13 +2414,8 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa)
}
qdf_wake_lock_create(&hdd_ipa->wake_lock, "wlan_ipa");
-#ifdef CONFIG_CNSS
- cnss_init_delayed_work(&hdd_ipa->wake_lock_work,
- hdd_ipa_wake_lock_timer_func);
-#else
INIT_DELAYED_WORK(&hdd_ipa->wake_lock_work,
hdd_ipa_wake_lock_timer_func);
-#endif
qdf_spinlock_create(&hdd_ipa->rm_lock);
hdd_ipa->rm_state = HDD_IPA_RM_RELEASED;
hdd_ipa->wake_lock_released = true;
@@ -4045,11 +4024,7 @@ QDF_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
qdf_spinlock_create(&iface_context->interface_lock);
}
-#ifdef CONFIG_CNSS
- cnss_init_work(&hdd_ipa->pm_work, hdd_ipa_pm_send_pkt_to_tl);
-#else
INIT_WORK(&hdd_ipa->pm_work, hdd_ipa_pm_send_pkt_to_tl);
-#endif
qdf_spinlock_create(&hdd_ipa->pm_lock);
qdf_nbuf_queue_init(&hdd_ipa->pm_queue_head);
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index acf6f9de0335..eb70039025e4 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -55,6 +55,7 @@
#include "wlan_hdd_ftm.h"
#include "wlan_hdd_power.h"
#include "wlan_hdd_stats.h"
+#include "wlan_hdd_scan.h"
#include "qdf_types.h"
#include "qdf_trace.h"
#include <cdp_txrx_peer_ops.h>
@@ -90,6 +91,7 @@
#include "cds_regdomain.h"
#include "cdp_txrx_flow_ctrl_v2.h"
#endif /* FEATURE_WLAN_CH_AVOID */
+#include "pld_common.h"
#include "wlan_hdd_ocb.h"
#include "wlan_hdd_nan.h"
#include "wlan_hdd_debugfs.h"
@@ -101,6 +103,7 @@
#include "hif.h"
#include "wma.h"
#include "cds_concurrency.h"
+#include "wlan_hdd_tsf.h"
#include "wlan_hdd_green_ap.h"
#include "platform_icnss.h"
#include "bmi.h"
@@ -1335,6 +1338,7 @@ 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;
}
/**
@@ -1433,6 +1437,42 @@ bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
}
/**
+ * __hdd__mon_open() - HDD Open function
+ * @dev: Pointer to net_device structure
+ *
+ * This is called in response to ifconfig up
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+static int __hdd_mon_open(struct net_device *dev)
+{
+ int ret;
+
+ ENTER_DEV(dev);
+ ret = hdd_set_mon_rx_cb(dev);
+ return ret;
+}
+
+/**
+ * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
+ * @dev: Pointer to net_device structure
+ *
+ * This is called in response to ifconfig up
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_mon_open(struct net_device *dev)
+{
+ int ret;
+
+ cds_ssr_protect(__func__);
+ ret = __hdd_mon_open(dev);
+ cds_ssr_unprotect(__func__);
+
+ return ret;
+}
+
+/**
* __hdd_open() - HDD Open function
* @dev: Pointer to net_device structure
*
@@ -1889,9 +1929,44 @@ static struct net_device_ops wlan_drv_ops = {
#endif
};
+/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
+static struct net_device_ops wlan_mon_drv_ops = {
+ .ndo_open = hdd_mon_open,
+ .ndo_stop = hdd_stop,
+ .ndo_get_stats = hdd_get_stats,
+};
+
+/**
+ * hdd_set_station_ops() - update net_device ops for monitor mode
+ * @pWlanDev: Handle to struct net_device to be updated.
+ * Return: None
+ */
void hdd_set_station_ops(struct net_device *pWlanDev)
{
- pWlanDev->netdev_ops = &wlan_drv_ops;
+ if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
+ pWlanDev->netdev_ops = &wlan_mon_drv_ops;
+ else
+ pWlanDev->netdev_ops = &wlan_drv_ops;
+}
+
+/**
+ * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
+ * @dev: Handle to struct net_device to be updated.
+ *
+ * Return: None
+ */
+static void hdd_mon_mode_ether_setup(struct net_device *dev)
+{
+ dev->header_ops = NULL;
+ dev->type = ARPHRD_IEEE80211_RADIOTAP;
+ dev->hard_header_len = ETH_HLEN;
+ dev->mtu = ETH_DATA_LEN;
+ dev->addr_len = ETH_ALEN;
+ dev->tx_queue_len = 1000; /* Ethernet wants good queues */
+ dev->flags = IFF_BROADCAST|IFF_MULTICAST;
+ dev->priv_flags |= IFF_TX_SKB_SHARING;
+
+ memset(dev->broadcast, 0xFF, ETH_ALEN);
}
/**
@@ -1919,7 +1994,9 @@ static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
name_assign_type,
#endif
- ether_setup, NUM_TX_QUEUES);
+ (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() ?
+ hdd_mon_mode_ether_setup : ether_setup),
+ NUM_TX_QUEUES);
if (pWlanDev != NULL) {
@@ -2431,6 +2508,7 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
case QDF_P2P_CLIENT_MODE:
case QDF_P2P_DEVICE_MODE:
case QDF_OCB_MODE:
+ case QDF_MONITOR_MODE:
{
adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
name_assign_type,
@@ -2447,6 +2525,8 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
else if (QDF_P2P_DEVICE_MODE == session_type)
adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
+ else if (QDF_MONITOR_MODE == session_type)
+ adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
else
adapter->wdev.iftype = NL80211_IFTYPE_STATION;
@@ -2462,27 +2542,17 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
* Workqueue which gets scheduled in IPv4 notification
* callback
*/
-#ifdef CONFIG_CNSS
- cnss_init_work(&adapter->ipv4NotifierWorkQueue,
- hdd_ipv4_notifier_work_queue);
-#else
INIT_WORK(&adapter->ipv4NotifierWorkQueue,
hdd_ipv4_notifier_work_queue);
-#endif
#ifdef WLAN_NS_OFFLOAD
/*
* Workqueue which gets scheduled in IPv6
* notification callback.
*/
-#ifdef CONFIG_CNSS
- cnss_init_work(&adapter->ipv6NotifierWorkQueue,
- hdd_ipv6_notifier_work_queue);
-#else
INIT_WORK(&adapter->ipv6NotifierWorkQueue,
hdd_ipv6_notifier_work_queue);
#endif
-#endif
status = hdd_register_interface(adapter, rtnl_held);
if (QDF_STATUS_SUCCESS != status) {
hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
@@ -3587,9 +3657,11 @@ QDF_STATUS hdd_abort_mac_scan_all_adapters(hdd_context_t *hdd_ctx)
#ifdef WLAN_NS_OFFLOAD
/**
- * hdd_wlan_unregister_ip6_notifier() - unregister IP6 change notifier
+ * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
* @hdd_ctx: Pointer to hdd context
*
+ * Unregister for IPv6 address change notifications.
+ *
* Return: None
*/
static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
@@ -3600,42 +3672,52 @@ static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
}
/**
- * hdd_wlan_register_ip6_notifier() - register IP6 change notifier
+ * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
* @hdd_ctx: Pointer to hdd context
*
- * Return: None
+ * Register for IPv6 address change notifications.
+ *
+ * Return: 0 on success and errno on failure.
*/
-static void hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
+static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
{
int ret;
hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
- if (ret)
- hddLog(LOGE, FL("Failed to register IPv6 notifier"));
- else
- hdd_info("Registered IPv6 notifier");
+ if (ret) {
+ hdd_err("Failed to register IPv6 notifier: %d", ret);
+ goto out;
+ }
- return;
+ hdd_info("Registered IPv6 notifier");
+out:
+ return ret;
}
#else
/**
- * hdd_wlan_unregister_ip6_notifier() - unregister IP6 change notifier
+ * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
* @hdd_ctx: Pointer to hdd context
*
+ * Unregister for IPv6 address change notifications.
+ *
* Return: None
*/
static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
{
}
+
/**
- * hdd_wlan_register_ip6_notifier() - register IP6 change notifier
+ * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
* @hdd_ctx: Pointer to hdd context
*
+ * Register for IPv6 address change notifications.
+ *
* Return: None
*/
-static void hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
+static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
{
+ return 0;
}
#endif
@@ -3770,6 +3852,63 @@ static inline int hdd_logging_sock_deactivate_svc(hdd_context_t *hdd_ctx)
#endif
/**
+ * hdd_register_notifiers - Register netdev notifiers.
+ * @hdd_ctx: HDD context
+ *
+ * Register netdev notifiers like IPv4 and IPv6.
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_register_notifiers(hdd_context_t *hdd_ctx)
+{
+ int ret;
+
+ ret = register_netdevice_notifier(&hdd_netdev_notifier);
+ if (ret) {
+ hdd_err("register_netdevice_notifier failed: %d", ret);
+ goto out;
+ }
+
+ ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
+ if (ret)
+ goto unregister_notifier;
+
+ hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
+ ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
+ if (ret) {
+ hdd_err("Failed to register IPv4 notifier: %d", ret);
+ goto unregister_ip6_notifier;
+ }
+
+ return 0;
+
+unregister_ip6_notifier:
+ hdd_wlan_unregister_ip6_notifier(hdd_ctx);
+unregister_notifier:
+ unregister_netdevice_notifier(&hdd_netdev_notifier);
+out:
+ return ret;
+
+}
+
+/**
+ * hdd_unregister_notifiers - Unregister netdev notifiers.
+ * @hdd_ctx: HDD context
+ *
+ * Unregister netdev notifiers like IPv4 and IPv6.
+ *
+ * Return: None.
+ */
+static void hdd_unregister_notifiers(hdd_context_t *hdd_ctx)
+{
+ hdd_wlan_unregister_ip6_notifier(hdd_ctx);
+
+ unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
+
+ unregister_netdevice_notifier(&hdd_netdev_notifier);
+}
+
+/**
* hdd_exit_netlink_services - Exit netlink services
* @hdd_ctx: HDD context
*
@@ -3844,20 +3983,94 @@ out:
return ret;
}
+#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
+/**
+ * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
+ * @hdd_ctx: HDD context.
+ *
+ * Destroy RX wakelock.
+ *
+ * Return: None.
+ */
+static void hdd_rx_wake_lock_destroy(hdd_context_t *hdd_ctx)
+{
+ qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
+}
+
+/**
+ * hdd_rx_wake_lock_create() - Create RX wakelock
+ * @hdd_ctx: HDD context.
+ *
+ * Create RX wakelock.
+ *
+ * Return: None.
+ */
+static void hdd_rx_wake_lock_create(hdd_context_t *hdd_ctx)
+{
+ qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
+}
+#else
+static void hdd_rx_wake_lock_destroy(hdd_context_t *hdd_ctx) { }
+static void hdd_rx_wake_lock_create(hdd_context_t *hdd_ctx) { }
+#endif
+
+/**
+ * hdd_roc_context_init() - Init ROC context
+ * @hdd_ctx: HDD context.
+ *
+ * Initialize ROC context.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_roc_context_init(hdd_context_t *hdd_ctx)
+{
+ qdf_spinlock_create(&hdd_ctx->hdd_roc_req_q_lock);
+ qdf_list_create(&hdd_ctx->hdd_roc_req_q, MAX_ROC_REQ_QUEUE_ENTRY);
+
+ INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue);
+
+ return 0;
+}
+
+/**
+ * hdd_roc_context_destroy() - Destroy ROC context
+ * @hdd_ctx: HDD context.
+ *
+ * Destroy roc list and flush the pending roc work.
+ *
+ * Return: None.
+ */
+static void hdd_roc_context_destroy(hdd_context_t *hdd_ctx)
+{
+ flush_delayed_work(&hdd_ctx->roc_req_work);
+ qdf_list_destroy(&hdd_ctx->hdd_roc_req_q);
+}
/**
- * hdd_free_context - Free HDD context
- * @hdd_ctx: HDD context to be freed.
+ * hdd_context_destroy() - Destroy HDD context
+ * @hdd_ctx: HDD context to be destroyed.
*
- * Free config and HDD context.
+ * Free config and HDD context as well as destroy all the resources.
*
* Return: None
*/
-static void hdd_free_context(hdd_context_t *hdd_ctx)
+static void hdd_context_destroy(hdd_context_t *hdd_ctx)
{
if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam())
hdd_logging_sock_deactivate_svc(hdd_ctx);
+ hdd_roc_context_destroy(hdd_ctx);
+
+ hdd_sap_context_destroy(hdd_ctx);
+
+ hdd_rx_wake_lock_destroy(hdd_ctx);
+
+ hdd_tdls_context_destroy(hdd_ctx);
+
+ hdd_scan_context_destroy(hdd_ctx);
+
+ qdf_list_destroy(&hdd_ctx->hddAdapters);
+
qdf_mem_free(hdd_ctx->config);
hdd_ctx->config = NULL;
@@ -3880,11 +4093,6 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
ENTER();
- hddLog(LOGE, FL("Unregister IPv6 notifier"));
- hdd_wlan_unregister_ip6_notifier(hdd_ctx);
- hddLog(LOGE, FL("Unregister IPv4 notifier"));
- unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
-
hdd_unregister_wext_all_adapters(hdd_ctx);
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
@@ -3894,6 +4102,8 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
goto free_hdd_ctx;
}
+ hdd_unregister_notifiers(hdd_ctx);
+
/*
* Cancel any outstanding scan requests. We are about to close all
* of our adapters, but an adapter structure is what SME passes back
@@ -3972,14 +4182,10 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
FL("Failed to close CDS Scheduler"));
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
}
-#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
- /* Destroy the wake lock */
- qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
-#endif
- /* Destroy the wake lock */
- qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock);
- hdd_hostapd_channel_wakelock_deinit(hdd_ctx);
+ qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
+ qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock);
+ qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
/*
* Close CDS
@@ -3998,8 +4204,6 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
/* Free up RoC request queue and flush workqueue */
cds_flush_work(&hdd_ctx->roc_req_work);
- qdf_list_destroy(&hdd_ctx->hdd_roc_req_q);
- qdf_list_destroy(&hdd_ctx->hdd_scan_req_q);
if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {
hdd_err("Failed to deinit policy manager");
@@ -4010,7 +4214,7 @@ free_hdd_ctx:
wiphy_unregister(wiphy);
- hdd_free_context(hdd_ctx);
+ hdd_context_destroy(hdd_ctx);
}
void __hdd_wlan_exit(void)
@@ -4035,11 +4239,9 @@ void __hdd_wlan_exit(void)
memdump_deinit();
-#ifdef QCA_PKT_PROTO_TRACE
- cds_pkt_proto_trace_close();
-#endif
/* Do all the cleanup before deregistering the driver */
hdd_wlan_exit(hdd_ctx);
+
EXIT();
}
@@ -5264,7 +5466,80 @@ static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx)
}
/**
- * hdd_init_context - Alloc and initialize HDD context
+ * hdd_context_init() - Initialize HDD context
+ * @hdd_ctx: HDD context.
+ *
+ * Initialize HDD context along with all the feature specific contexts.
+ *
+ * return: 0 on success and errno on failure.
+ */
+static int hdd_context_init(hdd_context_t *hdd_ctx)
+{
+ int ret;
+
+ hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
+ hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
+
+ hdd_init_ll_stats_ctx();
+
+ init_completion(&hdd_ctx->mc_sus_event_var);
+ init_completion(&hdd_ctx->ready_to_suspend);
+
+ hdd_init_bpf_completion();
+
+ qdf_spinlock_create(&hdd_ctx->connection_status_lock);
+ qdf_spinlock_create(&hdd_ctx->sta_update_info_lock);
+ qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
+
+ qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS);
+
+ init_completion(&hdd_ctx->set_antenna_mode_cmpl);
+
+ ret = hdd_scan_context_init(hdd_ctx);
+ if (ret)
+ goto list_destroy;
+
+ hdd_tdls_context_init(hdd_ctx);
+
+ hdd_rx_wake_lock_create(hdd_ctx);
+
+ ret = hdd_sap_context_init(hdd_ctx);
+ if (ret)
+ goto scan_destroy;
+
+ ret = hdd_roc_context_init(hdd_ctx);
+ if (ret)
+ goto sap_destroy;
+
+ wlan_hdd_cfg80211_extscan_init(hdd_ctx);
+
+ hdd_init_offloaded_packets_ctx(hdd_ctx);
+
+ ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
+ hdd_ctx->config);
+ if (ret)
+ goto roc_destroy;
+
+ return 0;
+
+roc_destroy:
+ hdd_roc_context_destroy(hdd_ctx);
+
+sap_destroy:
+ hdd_sap_context_destroy(hdd_ctx);
+
+scan_destroy:
+ hdd_scan_context_destroy(hdd_ctx);
+ hdd_rx_wake_lock_destroy(hdd_ctx);
+ hdd_tdls_context_destroy(hdd_ctx);
+
+list_destroy:
+ qdf_list_destroy(&hdd_ctx->hddAdapters);
+ return ret;
+}
+
+/**
+ * hdd_context_create() - Allocate and inialize HDD context.
* @dev: Pointer to the underlying device
* @hif_sc: HIF context
*
@@ -5273,7 +5548,7 @@ static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx)
*
* Return: HDD context on success and ERR_PTR on failure
*/
-hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc)
+hdd_context_t *hdd_context_create(struct device *dev, void *hif_sc)
{
QDF_STATUS status;
int ret = 0;
@@ -5298,6 +5573,7 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc)
}
hdd_ctx->pcds_context = p_cds_context;
+ hdd_ctx->parent_dev = dev;
hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
if (hdd_ctx->config == NULL) {
@@ -5315,53 +5591,26 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc)
goto err_free_config;
}
- ((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx;
-
- hdd_ctx->parent_dev = dev;
-
- hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
-
- hdd_init_ll_stats_ctx();
-
- init_completion(&hdd_ctx->mc_sus_event_var);
- init_completion(&hdd_ctx->ready_to_suspend);
-
- qdf_spinlock_create(&hdd_ctx->connection_status_lock);
- qdf_spinlock_create(&hdd_ctx->sched_scan_lock);
-
- qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
- qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS);
-
- wlan_hdd_cfg80211_extscan_init(hdd_ctx);
-
- hdd_tdls_pre_init(hdd_ctx);
- mutex_init(&hdd_ctx->dfs_lock);
- mutex_init(&hdd_ctx->sap_lock);
-
- init_completion(&hdd_ctx->set_antenna_mode_cmpl);
-
- hdd_ctx->target_type = tgt_info->target_type;
-
- hdd_init_offloaded_packets_ctx(hdd_ctx);
-
- icnss_set_fw_debug_mode(hdd_ctx->config->enable_fw_log);
-
- hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
-
hdd_ctx->configuredMcastBcastFilter =
hdd_ctx->config->mcastBcastFilterSetting;
hdd_notice("Setting configuredMcastBcastFilter: %d",
hdd_ctx->config->mcastBcastFilterSetting);
+ cds_set_fatal_event(hdd_ctx->config->enable_fatal_event);
+
hdd_override_ini_config(hdd_ctx);
- ret = wlan_hdd_cfg80211_init(dev, hdd_ctx->wiphy, hdd_ctx->config);
+ ((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx;
- if (ret) {
- hdd_err("CFG80211 wiphy init failed: %d", ret);
+ ret = hdd_context_init(hdd_ctx);
+
+ if (ret)
goto err_free_config;
- }
+
+ hdd_ctx->target_type = tgt_info->target_type;
+
+ icnss_set_fw_debug_mode(hdd_ctx->config->enable_fw_log);
hdd_enable_fastpath(hdd_ctx->config, hif_sc);
@@ -5459,6 +5708,21 @@ static inline int hdd_open_p2p_interface(struct hdd_context_t *hdd_ctx,
#endif
/**
+ * hdd_open_monitor_interface() - Open monitor mode interface
+ * @hdd_ctx: HDD context
+ * @rtnl_held: True if RTNL lock is held
+ *
+ * Return: Primary adapter on success and PTR_ERR on failure
+ */
+static hdd_adapter_t *hdd_open_monitor_interface(hdd_context_t *hdd_ctx,
+ bool rtnl_held)
+{
+ return hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
+ wlan_hdd_get_intf_addr(hdd_ctx),
+ NET_NAME_UNKNOWN, rtnl_held);
+}
+
+/**
* hdd_open_interfaces - Open all required interfaces
* hdd_ctx: HDD context
* rtnl_held: True if RTNL lock is held
@@ -5671,6 +5935,124 @@ QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void)
#endif
/**
+ * hdd_tsf_init() - Initialize the TSF synchronization interface
+ * @hdd_ctx: HDD global context
+ *
+ * When TSF synchronization via GPIO is supported by the driver and
+ * has been enabled in the configuration file, this function plumbs
+ * the GPIO value down to firmware via SME.
+ *
+ * Return: None
+ */
+#ifdef WLAN_FEATURE_TSF
+static void hdd_tsf_init(hdd_context_t *hdd_ctx)
+{
+ QDF_STATUS status;
+
+ if (hdd_ctx->config->tsf_gpio_pin == TSF_GPIO_PIN_INVALID)
+ return;
+
+ status = sme_set_tsf_gpio(hdd_ctx->hHal,
+ hdd_ctx->config->tsf_gpio_pin);
+ if (!QDF_IS_STATUS_SUCCESS(status))
+ hdd_err("Set tsf GPIO failed, status: %d", status);
+}
+#else
+static void hdd_tsf_init(hdd_context_t *hdd_ctx)
+{
+}
+#endif
+
+/**
+ * hdd_pre_enable_configure() - Configurations prior to cds_enable
+ * @hdd_ctx: HDD context
+ *
+ * Pre configurations to be done at lower layer before calling cds enable.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_pre_enable_configure(hdd_context_t *hdd_ctx)
+{
+ int ret;
+ QDF_STATUS status;
+ tSirRetStatus hal_status;
+
+ ol_txrx_register_pause_cb(wlan_hdd_txrx_pause_cb);
+
+ /*
+ * Set 802.11p config
+ * TODO-OCB: This has been temporarily added here to ensure this
+ * parameter is set in CSR when we init the channel list. This should
+ * be removed once the 5.9 GHz channels are added to the regulatory
+ * domain.
+ */
+ hdd_set_dot11p_config(hdd_ctx);
+
+ /*
+ * Note that the cds_pre_enable() sequence triggers the cfg download.
+ * The cfg download must occur before we update the SME config
+ * since the SME config operation must access the cfg database
+ */
+ status = hdd_set_sme_config(hdd_ctx);
+
+ if (QDF_STATUS_SUCCESS != status) {
+ hdd_alert("Failed hdd_set_sme_config: %d", status);
+ ret = qdf_status_to_os_return(status);
+ goto out;
+ }
+
+ ret = wma_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
+ hdd_ctx->config->tx_chain_mask_1ss,
+ PDEV_CMD);
+ if (0 != ret) {
+ hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
+ goto out;
+ }
+
+ hdd_program_country_code(hdd_ctx);
+
+ status = hdd_set_sme_chan_list(hdd_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ hdd_alert("Failed to init channel list: %d", status);
+ ret = qdf_status_to_os_return(status);
+ goto out;
+ }
+
+ /* Apply the cfg.ini to cfg.dat */
+ if (!hdd_update_config_dat(hdd_ctx)) {
+ hdd_alert("config update failed");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ status = hdd_update_mac_config(hdd_ctx);
+ if (QDF_STATUS_SUCCESS != status) {
+ hdd_warn("can't update mac config, using MAC from ini file: %d",
+ status);
+ }
+
+ /*
+ * Set the MAC Address Currently this is used by HAL to add self sta.
+ * Remove this once self sta is added as part of session open.
+ */
+ hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID,
+ hdd_ctx->config->intfMacAddr[0].bytes,
+ sizeof(hdd_ctx->config->intfMacAddr[0]));
+
+ if (!IS_SIR_STATUS_SUCCESS(hal_status)) {
+ hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]",
+ hal_status, hal_status);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ hdd_init_channel_avoidance(hdd_ctx);
+
+out:
+ return ret;
+}
+
+/**
* hdd_wlan_startup() - HDD init function
* @dev: Pointer to the underlying device
*
@@ -5686,18 +6068,16 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
int ret;
tSirTxPowerLimit hddtxlimit;
bool rtnl_held;
- tSirRetStatus hal_status;
- int ret_val;
ENTER();
- if (WLAN_IS_EPPING_ENABLED(con_mode)) {
+ if (QDF_IS_EPPING_ENABLED(con_mode)) {
ret = epping_enable(dev);
EXIT();
return ret;
}
- hdd_ctx = hdd_init_context(dev, hif_sc);
+ hdd_ctx = hdd_context_create(dev, hif_sc);
if (IS_ERR(hdd_ctx))
return PTR_ERR(hdd_ctx);
@@ -5734,80 +6114,15 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
goto err_cds_close;
}
- ol_txrx_register_pause_cb(wlan_hdd_txrx_pause_cb);
-
- ret_val = hdd_wiphy_init(hdd_ctx);
-
- if (ret_val) {
- hdd_alert("failed to initialize wiphy");
+ ret = hdd_wiphy_init(hdd_ctx);
+ if (ret) {
+ hdd_alert("Failed to initialize wiphy: %d", ret);
goto err_cds_close;
}
- /*
- * Set 802.11p config
- * TODO-OCB: This has been temporarily added here to ensure this
- * parameter is set in CSR when we init the channel list. This should
- * be removed once the 5.9 GHz channels are added to the regulatory
- * domain.
- */
- hdd_set_dot11p_config(hdd_ctx);
-
- /*
- * Note that the cds_pre_enable() sequence triggers the cfg download.
- * The cfg download must occur before we update the SME config
- * since the SME config operation must access the cfg database
- */
- status = hdd_set_sme_config(hdd_ctx);
-
- if (QDF_STATUS_SUCCESS != status) {
- hddLog(QDF_TRACE_LEVEL_FATAL, FL("Failed hdd_set_sme_config"));
- goto err_wiphy_unregister;
- }
-
- ret = wma_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
- hdd_ctx->config->tx_chain_mask_1ss,
- PDEV_CMD);
- if (0 != ret) {
- hddLog(QDF_TRACE_LEVEL_ERROR,
- "%s: WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d",
- __func__, ret);
- }
-
- hdd_program_country_code(hdd_ctx);
-
- status = hdd_set_sme_chan_list(hdd_ctx);
- if (status != QDF_STATUS_SUCCESS) {
- hddLog(QDF_TRACE_LEVEL_FATAL,
- FL("Failed to init channel list"));
- goto err_wiphy_unregister;
- }
-
- /* Apply the cfg.ini to cfg.dat */
- if (false == hdd_update_config_dat(hdd_ctx)) {
- hddLog(QDF_TRACE_LEVEL_FATAL,
- FL("config update failed"));
- goto err_wiphy_unregister;
- }
-
- if (QDF_STATUS_SUCCESS != hdd_update_mac_config(hdd_ctx)) {
- hddLog(QDF_TRACE_LEVEL_WARN,
- FL("can't update mac config, using MAC from ini file"));
- }
-
- /*
- * Set the MAC Address Currently this is used by HAL to add self sta.
- * Remove this once self sta is added as part of session open.
- */
- hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID,
- hdd_ctx->config->intfMacAddr[0].bytes,
- sizeof(hdd_ctx->config->intfMacAddr[0]));
-
- if (!IS_SIR_STATUS_SUCCESS(hal_status)) {
- hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]",
- hal_status, hal_status);
- ret = -EINVAL;
+ ret = hdd_pre_enable_configure(hdd_ctx);
+ if (ret)
goto err_wiphy_unregister;
- }
if (hdd_ipa_init(hdd_ctx) == QDF_STATUS_E_FAILURE)
goto err_wiphy_unregister;
@@ -5822,8 +6137,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
goto err_ipa_cleanup;
}
- hdd_init_channel_avoidance(hdd_ctx);
-
status = hdd_post_cds_enable_config(hdd_ctx);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hddLog(QDF_TRACE_LEVEL_FATAL,
@@ -5831,11 +6144,12 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
goto err_cds_disable;
}
- cds_pkt_proto_trace_init();
-
rtnl_held = hdd_hold_rtnl_lock();
- adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);
+ if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam())
+ adapter = hdd_open_monitor_interface(hdd_ctx, rtnl_held);
+ else
+ adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);
if (IS_ERR(adapter)) {
ret = PTR_ERR(adapter);
@@ -5869,7 +6183,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
ret = hdd_init_netlink_services(hdd_ctx);
if (ret)
- goto err_debugfs_exit;
+ goto err_close_adapter;
/*
* Action frame registered in one adapter which will
@@ -5880,21 +6194,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
hdd_release_rtnl_lock();
rtnl_held = false;
- ret = register_netdevice_notifier(&hdd_netdev_notifier);
- if (ret < 0) {
- hdd_err("register_netdevice_notifier failed: %d", ret);
- goto err_exit_nl_srv;
- }
-
-#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
- /* Initialize the wake lcok */
- qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
-#endif
- /* Initialize the wake lcok */
- qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock");
-
- hdd_hostapd_channel_wakelock_init(hdd_ctx);
-
if (hdd_ctx->config->fIsImpsEnabled)
hdd_set_idle_ps_config(hdd_ctx, true);
else
@@ -5942,6 +6241,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
if (QDF_IS_STATUS_SUCCESS(status))
hdd_err("Error setting txlimit in sme: %d", status);
+ hdd_tsf_init(hdd_ctx);
#ifdef MSM_PLATFORM
spin_lock_init(&hdd_ctx->bus_bw_lock);
qdf_mc_timer_init(&hdd_ctx->bus_bw_timer,
@@ -5956,64 +6256,41 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
status = hdd_register_for_sap_restart_with_channel_switch();
if (!QDF_IS_STATUS_SUCCESS(status))
- /* Error already logged */
- goto err_unreg_netdev_notifier;
+ goto err_exit_nl_srv;
sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal,
hdd_rssi_threshold_breached);
- hdd_cfg80211_link_layer_stats_init(hdd_ctx);
+ status = sme_bpf_offload_register_callback(hdd_ctx->hHal,
+ hdd_get_bpf_offload_cb);
+ if (QDF_IS_STATUS_SUCCESS(status))
+ hdd_err("set bpf offload callback failed");
+ hdd_cfg80211_link_layer_stats_init(hdd_ctx);
+ wlan_hdd_tsf_init(hdd_ctx);
wlan_hdd_send_all_scan_intf_info(hdd_ctx);
wlan_hdd_send_version_pkg(hdd_ctx->target_fw_version,
hdd_ctx->target_hw_version,
hdd_ctx->target_hw_name);
- qdf_spinlock_create(&hdd_ctx->hdd_roc_req_q_lock);
- qdf_list_create((&hdd_ctx->hdd_roc_req_q), MAX_ROC_REQ_QUEUE_ENTRY);
- qdf_spinlock_create(&hdd_ctx->hdd_scan_req_q_lock);
- qdf_list_create((&hdd_ctx->hdd_scan_req_q), CFG_MAX_SCAN_COUNT_MAX);
-#ifdef CONFIG_CNSS
- cnss_init_delayed_work(&hdd_ctx->roc_req_work,
- wlan_hdd_roc_request_dequeue);
-#else
- INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue);
-#endif
-
- /*
- * Register IPv6 notifier to notify if any change in IP
- * So that we can reconfigure the offload parameters
- */
- hdd_wlan_register_ip6_notifier(hdd_ctx);
-
- /*
- * Register IPv4 notifier to notify if any change in IP
- * So that we can reconfigure the offload parameters
- */
- hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
- ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
- if (ret)
- hddLog(LOGE, FL("Failed to register IPv4 notifier"));
- else
- hdd_info("Registered IPv4 notifier");
-
wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
if (hdd_ctx->config->dual_mac_feature_disable) {
status = wlan_hdd_disable_all_dual_mac_features(hdd_ctx);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Failed to disable dual mac features");
- goto err_unreg_netdev_notifier;
+ goto err_exit_nl_srv;
}
}
+ ret = hdd_register_notifiers(hdd_ctx);
+ if (ret)
+ goto err_exit_nl_srv;
+
memdump_init();
goto success;
-err_unreg_netdev_notifier:
- unregister_netdevice_notifier(&hdd_netdev_notifier);
-
err_exit_nl_srv:
hdd_exit_netlink_services(hdd_ctx);
@@ -6022,9 +6299,6 @@ err_exit_nl_srv:
/* Proceed and complete the clean up */
}
-err_debugfs_exit:
- hdd_debugfs_exit(adapter);
-
err_close_adapter:
hdd_release_rtnl_lock();
@@ -6049,7 +6323,7 @@ err_cds_close:
cds_close(hdd_ctx->pcds_context);
err_hdd_free_context:
- hdd_free_context(hdd_ctx);
+ hdd_context_destroy(hdd_ctx);
QDF_BUG(1);
return -EIO;
@@ -7019,6 +7293,8 @@ static int __hdd_module_init(void)
pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
+ pld_init();
+
qdf_wake_lock_create(&wlan_wake_lock, "wlan");
hdd_set_conparam((uint32_t) con_mode);
@@ -7034,6 +7310,7 @@ static int __hdd_module_init(void)
return 0;
out:
qdf_wake_lock_destroy(&wlan_wake_lock);
+ pld_deinit();
return ret;
}
@@ -7051,6 +7328,8 @@ static void __hdd_module_exit(void)
qdf_wake_lock_destroy(&wlan_wake_lock);
+ pld_deinit();
+
return;
}
diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c
index b54a41baba96..89a25740cde6 100644
--- a/core/hdd/src/wlan_hdd_p2p.c
+++ b/core/hdd/src/wlan_hdd_p2p.c
@@ -206,9 +206,7 @@ QDF_STATUS wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void *pCtx,
if (REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) {
if (cfgState->buf) {
- hddLog(LOGP,
- "%s: We need to receive yet an ack from one of tx packet",
- __func__);
+ hdd_info("We need to receive yet an ack from one of tx packet");
}
cfg80211_remain_on_channel_expired(
pRemainChanCtx->dev->
@@ -319,6 +317,10 @@ void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter)
hddLog(LOGE,
"%s: timeout waiting for remain on channel ready indication",
__func__);
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_HDD_TIME_OUT,
+ true, false);
}
INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
@@ -1171,6 +1173,10 @@ int __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
cds_get_driver_state());
return -EAGAIN;
}
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_HDD_TIME_OUT,
+ true, false);
}
INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
/* Issue abort remain on chan request to sme.
@@ -2247,8 +2253,8 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
+ 2], SIR_MAC_P2P_OUI,
SIR_MAC_P2P_OUI_SIZE)) {
/* P2P action frames */
- u8 *macFrom =
- &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET + 6];
+ u8 *macFrom = &pbFrames
+ [WLAN_HDD_80211_PEER_ADDR_OFFSET];
actionFrmType =
pbFrames
[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
@@ -2409,8 +2415,8 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
else if (pbFrames
[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1] ==
WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP) {
- u8 *mac =
- &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET + 6];
+ u8 *mac = &pbFrames
+ [WLAN_HDD_80211_PEER_ADDR_OFFSET];
hddLog(LOG1,
"[TDLS] TDLS Discovery Response,"
@@ -2420,6 +2426,10 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
wlan_hdd_tdls_set_rssi(pAdapter, mac, rxRssi);
wlan_hdd_tdls_recv_discovery_resp(pAdapter,
mac);
+ cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS,
+ SIR_MAC_ACTION_RX, SIR_MAC_MGMT_ACTION,
+ WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP,
+ &pbFrames[WLAN_HDD_80211_PEER_ADDR_OFFSET]);
}
#endif
}
@@ -2437,6 +2447,10 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
"[TDLS] %s <--- OTA",
tdls_action_frame_type[actionFrmType]);
}
+ cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS,
+ SIR_MAC_ACTION_RX, SIR_MAC_MGMT_ACTION,
+ actionFrmType,
+ &pbFrames[WLAN_HDD_80211_PEER_ADDR_OFFSET]);
}
if ((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] ==
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index 7961eb5a626d..7346aa087605 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -87,6 +87,46 @@ enum hdd_power_mode {
DRIVER_POWER_MODE_ACTIVE = 1,
};
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * hdd_wlan_suspend_resume_event()- send suspend/resume state
+ * @state: suspend/resume state
+ *
+ * This Function send send suspend resume state diag event
+ *
+ * Return: void.
+ */
+void hdd_wlan_suspend_resume_event(uint8_t state)
+{
+ WLAN_HOST_DIAG_EVENT_DEF(suspend_state, struct host_event_suspend);
+ qdf_mem_zero(&suspend_state, sizeof(suspend_state));
+
+ suspend_state.state = state;
+ WLAN_HOST_DIAG_EVENT_REPORT(&suspend_state, EVENT_WLAN_SUSPEND_RESUME);
+}
+
+/**
+ * hdd_wlan_offload_event()- send offloads event
+ * @type: offload type
+ * @state: enabled or disabled
+ *
+ * This Function send offloads enable/disable diag event
+ *
+ * Return: void.
+ */
+
+void hdd_wlan_offload_event(uint8_t type, uint8_t state)
+{
+ WLAN_HOST_DIAG_EVENT_DEF(host_offload, struct host_event_offload_req);
+ qdf_mem_zero(&host_offload, sizeof(host_offload));
+
+ host_offload.offload_type = type;
+ host_offload.state = state;
+
+ WLAN_HOST_DIAG_EVENT_REPORT(&host_offload, EVENT_WLAN_OFFLOAD_REQ);
+}
+#endif
+
/* Function and variables declarations */
extern struct notifier_block hdd_netdev_notifier;
@@ -387,6 +427,8 @@ static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, bool fenable)
&offLoadRequest.nsOffloadInfo.selfIPv6Addr[i],
&offLoadRequest.nsOffloadInfo.targetIPv6Addr[i], i);
}
+ hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
+ SIR_OFFLOAD_ENABLE);
offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
qdf_copy_macaddr(&offLoadRequest.nsOffloadInfo.self_macaddr,
@@ -405,6 +447,8 @@ static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, bool fenable)
return;
}
} else {
+ hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
+ SIR_OFFLOAD_DISABLE);
/* Disable NSOffload */
qdf_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
@@ -720,6 +764,8 @@ QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable)
if (ifa && ifa->ifa_local) {
offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
+ hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
+ SIR_OFFLOAD_ENABLE);
hddLog(QDF_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
@@ -734,7 +780,9 @@ QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable)
hddLog(QDF_TRACE_LEVEL_INFO,
"offload: inside arp offload conditional check");
}
-
+ hdd_wlan_offload_event(
+ SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE,
+ SIR_OFFLOAD_ENABLE);
hddLog(QDF_TRACE_LEVEL_INFO,
"offload: arp filter programmed = %d",
offLoadRequest.enableOrDisable);
@@ -767,6 +815,8 @@ QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable)
return QDF_STATUS_SUCCESS;
} else {
+ hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
+ SIR_OFFLOAD_DISABLE);
qdf_mem_zero((void *)&offLoadRequest,
sizeof(tSirHostOffloadReq));
offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
@@ -810,6 +860,7 @@ static void hdd_mcbc_filter_modification(hdd_context_t *pHddCtx,
* of Broadcast BIT
*/
*pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
+ hdd_info("ARP offload is enabled");
}
#ifdef WLAN_NS_OFFLOAD
if (pHddCtx->config->fhostNSOffload) {
@@ -818,6 +869,7 @@ static void hdd_mcbc_filter_modification(hdd_context_t *pHddCtx,
* disable Multicast filtering, Anding with the negation
* of Multicast BIT
*/
+ hdd_info("NS offload is enabled");
*pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
}
#endif
@@ -1137,6 +1189,7 @@ hdd_suspend_wlan(void (*callback)(void *callbackContext, bool suspended),
callbackContext);
pHddCtx->hdd_wlan_suspended = true;
+ hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
return;
}
@@ -1170,6 +1223,7 @@ static void hdd_resume_wlan(void)
}
pHddCtx->hdd_wlan_suspended = false;
+ hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
/*loop through all adapters. Concurrency */
status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
index d35f21bd0d0f..b2c367d03288 100644
--- a/core/hdd/src/wlan_hdd_scan.c
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -1331,13 +1331,8 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
*/
pAdapter->request = request;
-#ifdef CONFIG_CNSS
- cnss_init_work(&pAdapter->scan_block_work,
- wlan_hdd_cfg80211_scan_block_cb);
-#else
INIT_WORK(&pAdapter->scan_block_work,
wlan_hdd_cfg80211_scan_block_cb);
-#endif
schedule_work(&pAdapter->scan_block_work);
return 0;
}
@@ -1378,6 +1373,7 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
else
hddLog(LOGE, FL("TDLS teardown is ongoing %d"),
status);
+ hdd_wlan_block_scan_by_tdls_event();
return status;
}
#endif
@@ -1390,7 +1386,6 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
qdf_mem_zero(&scan_req, sizeof(scan_req));
- hddLog(LOG1, "scan request for ssid = %d", request->n_ssids);
scan_req.timestamp = qdf_mc_timer_get_system_ticks();
/* Even though supplicant doesn't provide any SSIDs, n_ssids is
@@ -2494,3 +2489,35 @@ void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx)
return;
}
+
+/**
+ * hdd_scan_context_destroy() - Destroy scan context
+ * @hdd_ctx: HDD context.
+ *
+ * Destroy scan context.
+ *
+ * Return: None.
+ */
+void hdd_scan_context_destroy(hdd_context_t *hdd_ctx)
+{
+ qdf_list_destroy(&hdd_ctx->hdd_scan_req_q);
+ qdf_spinlock_destroy(&hdd_ctx->sched_scan_lock);
+}
+
+/**
+ * hdd_scan_context_init() - Initialize scan context
+ * @hdd_ctx: HDD context.
+ *
+ * Initialize scan related resources like spin lock and lists.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+int hdd_scan_context_init(hdd_context_t *hdd_ctx)
+{
+ qdf_spinlock_create(&hdd_ctx->sched_scan_lock);
+
+ qdf_spinlock_create(&hdd_ctx->hdd_scan_req_q_lock);
+ qdf_list_create(&hdd_ctx->hdd_scan_req_q, CFG_MAX_SCAN_COUNT_MAX);
+
+ return 0;
+}
diff --git a/core/hdd/src/wlan_hdd_scan.h b/core/hdd/src/wlan_hdd_scan.h
index 8b1d7489d80f..50a6a8ddf273 100644
--- a/core/hdd/src/wlan_hdd_scan.h
+++ b/core/hdd/src/wlan_hdd_scan.h
@@ -50,6 +50,9 @@ int iw_get_scan(struct net_device *dev, struct iw_request_info *info,
int iw_set_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
+int hdd_scan_context_init(hdd_context_t *hdd_ctx);
+void hdd_scan_context_destroy(hdd_context_t *hdd_ctx);
+
int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
struct cfg80211_scan_request *request);
diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c
index e0978c31b2e1..a0077b4b106c 100644
--- a/core/hdd/src/wlan_hdd_tdls.c
+++ b/core/hdd/src/wlan_hdd_tdls.c
@@ -85,6 +85,85 @@ static void wlan_hdd_tdls_determine_channel_opclass(hdd_context_t *hddctx,
}
}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * hdd_send_wlan_tdls_teardown_event()- send TDLS teardown event
+ * @reason: reason for tear down.
+ * @peer_mac: peer mac
+ *
+ * This Function sends TDLS teardown diag event
+ *
+ * Return: void.
+ */
+void hdd_send_wlan_tdls_teardown_event(uint32_t reason,
+ uint8_t *peer_mac)
+{
+ WLAN_HOST_DIAG_EVENT_DEF(tdls_tear_down,
+ struct host_event_tdls_teardown);
+ qdf_mem_zero(&tdls_tear_down,
+ sizeof(tdls_tear_down));
+
+ tdls_tear_down.reason = reason;
+ qdf_mem_copy(tdls_tear_down.peer_mac, peer_mac, MAC_ADDR_LEN);
+ WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tear_down,
+ EVENT_WLAN_TDLS_TEARDOWN);
+}
+
+/**
+ * hdd_wlan_tdls_enable_link_event()- send TDLS enable link event
+ * @peer_mac: peer mac
+ * @is_off_chan_supported: Does peer supports off chan
+ * @is_off_chan_configured: If off channel is configured
+ * @is_off_chan_established: If off chan is established
+ *
+ * This Function send TDLS enable link diag event
+ *
+ * Return: void.
+ */
+
+void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac,
+ uint8_t is_off_chan_supported,
+ uint8_t is_off_chan_configured,
+ uint8_t is_off_chan_established)
+{
+ WLAN_HOST_DIAG_EVENT_DEF(tdls_event,
+ struct host_event_tdls_enable_link);
+
+ qdf_mem_copy(tdls_event.peer_mac,
+ peer_mac, MAC_ADDR_LEN);
+
+ tdls_event.is_off_chan_supported =
+ is_off_chan_supported;
+ tdls_event.is_off_chan_configured =
+ is_off_chan_configured;
+ tdls_event.is_off_chan_established =
+ is_off_chan_established;
+
+ WLAN_HOST_DIAG_EVENT_REPORT(&tdls_event,
+ EVENT_WLAN_TDLS_ENABLE_LINK);
+}
+
+/**
+ * hdd_wlan_block_scan_by_tdls_event()- send event
+ * if scan is blocked by tdls
+ *
+ * This Function send send diag event if scan is
+ * blocked by tdls
+ *
+ * Return: void.
+ */
+void hdd_wlan_block_scan_by_tdls_event(void)
+{
+ WLAN_HOST_DIAG_EVENT_DEF(tdls_scan_block_status,
+ struct host_event_tdls_scan_rejected);
+
+ tdls_scan_block_status.status = true;
+ WLAN_HOST_DIAG_EVENT_REPORT(&tdls_scan_block_status,
+ EVENT_TDLS_SCAN_BLOCK);
+}
+
+#endif
+
/**
* wlan_hdd_tdls_hash_key() - calculate tdls hash key given mac address
* @mac: mac address
@@ -168,6 +247,8 @@ void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx)
curr_peer->pHddTdlsCtx->pAdapter,
curr_peer,
eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+ hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_CONCURRENCY,
+ curr_peer->peerMac);
}
}
@@ -508,21 +589,32 @@ static void wlan_hdd_tdls_del_non_forced_peers(tdlsCtx_t *hdd_tdls_ctx)
}
/**
- * hdd_tdls_pre_init - TDLS pre init
+ * hdd_tdls_context_init() - Init TDLS context
* @hdd_ctx: HDD context
*
- * tdls_lock is initialized before an hdd_open_adapter ( which is
- * invoked by other instances also) to protect the concurrent
- * access for the Adapters by TDLS module.
+ * Initialize TDLS global context.
*
* Return: None
*/
-void hdd_tdls_pre_init(hdd_context_t *hdd_ctx)
+void hdd_tdls_context_init(hdd_context_t *hdd_ctx)
{
mutex_init(&hdd_ctx->tdls_lock);
}
/**
+ * hdd_tdls_context_destroy() - Destroy TDLS context
+ * @hdd_ctx: HDD context
+ *
+ * Destroy TDLS global context.
+ *
+ * Return: None
+ */
+void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx)
+{
+ mutex_destroy(&hdd_ctx->tdls_lock);
+}
+
+/**
* wlan_hdd_tdls_init() - tdls initializaiton
* @pAdapter: hdd adapter
*
@@ -658,19 +750,10 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter)
pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
}
-#ifdef CONFIG_CNSS
- cnss_init_work(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup);
-#else
INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup);
-#endif
-#ifdef CONFIG_CNSS
- cnss_init_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work,
- wlan_hdd_tdls_schedule_scan);
-#else
INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work,
wlan_hdd_tdls_schedule_scan);
-#endif
/*
* Release tdls lock before calling in SME api
@@ -748,7 +831,7 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
if (!pHddCtx) {
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
+ QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
FL("pHddCtx is NULL"));
return;
}
@@ -2764,6 +2847,9 @@ int wlan_hdd_tdls_scan_callback(hdd_adapter_t *pAdapter, struct wiphy *wiphy,
(connectedPeerList[i]->pHddTdlsCtx->
pAdapter, connectedPeerList[i],
eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+ hdd_send_wlan_tdls_teardown_event(
+ eTDLS_TEARDOWN_SCAN,
+ connectedPeerList[i]->peerMac);
}
}
/* schedule scan */
@@ -2876,6 +2962,7 @@ void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter,
wlan_hdd_tdls_set_peer_link_status(curr_peer,
eTDLS_LINK_TEARING,
eTDLS_LINK_UNSPECIFIED);
+ hdd_info("Teardown reason %d", reason);
cfg80211_tdls_oper_request(pAdapter->dev,
curr_peer->peerMac,
NL80211_TDLS_TEARDOWN, reason, GFP_KERNEL);
@@ -3899,7 +3986,11 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
cds_get_driver_state());
return -EAGAIN;
}
-
+ if (rc <= 0)
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_HDD_TIME_OUT,
+ true, false);
pAdapter->mgmtTxCompletionStatus = false;
return -EINVAL;
}
@@ -4117,6 +4208,9 @@ int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
} else {
wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+ hdd_send_wlan_tdls_teardown_event(
+ eTDLS_TEARDOWN_EXT_CTRL,
+ pTdlsPeer->peerMac);
}
if (0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, false)) {
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
@@ -4425,7 +4519,9 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
}
}
}
-
+ hdd_wlan_tdls_enable_link_event(peer,
+ pTdlsPeer->isOffChannelSupported,
+ 0, 0);
}
break;
case NL80211_TDLS_DISABLE_LINK:
@@ -4519,7 +4615,7 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
return -ENOTSUPP;
default:
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
- "%s: unsupported event", __func__);
+ "%s: unsupported event %d", __func__, oper);
return -ENOTSUPP;
}
EXIT();
diff --git a/core/hdd/src/wlan_hdd_tsf.c b/core/hdd/src/wlan_hdd_tsf.c
new file mode 100644
index 000000000000..2563a94bddbd
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_tsf.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**
+ * wlan_hdd_tsf.c - WLAN Host Device Driver tsf related implementation
+ */
+
+#include "wlan_hdd_main.h"
+#include "wma_api.h"
+
+/**
+ * hdd_capture_tsf() - capture tsf
+ * @adapter: pointer to adapter
+ * @buf: pointer to uplayer buf
+ * @len : the length of buf
+ *
+ * This function returns tsf value to uplayer.
+ *
+ * Return: 0 for success or non-zero negative failure code
+ */
+int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
+{
+ int ret = 0;
+ hdd_station_ctx_t *hdd_sta_ctx;
+
+ if (adapter == NULL || buf == NULL) {
+ hdd_err(FL("invalid pointer"));
+ return -EINVAL;
+ }
+ if (len != 1)
+ return -EINVAL;
+
+ /* Reset TSF value for new capture */
+ adapter->tsf_high = 0;
+ adapter->tsf_low = 0;
+
+ if (adapter->device_mode == QDF_STA_MODE ||
+ adapter->device_mode == QDF_P2P_CLIENT_MODE) {
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ if (hdd_sta_ctx->conn_info.connState !=
+ eConnectionState_Associated) {
+
+ hdd_err(FL("failed to cap tsf, not connect with ap"));
+ buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
+ return ret;
+ }
+ }
+ if ((adapter->device_mode == QDF_SAP_MODE ||
+ adapter->device_mode == QDF_P2P_GO_MODE) &&
+ !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
+ hdd_err(FL("Soft AP / P2p GO not beaconing"));
+ buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
+ return ret;
+ }
+ if (adapter->tsf_state == TSF_CAP_STATE) {
+ hdd_err(FL("current in capture state, pls reset"));
+ buf[0] = TSF_CURRENT_IN_CAP_STATE;
+ } else {
+ hdd_info(FL("Send TSF capture to FW"));
+ buf[0] = TSF_RETURN;
+ adapter->tsf_state = TSF_CAP_STATE;
+ ret = wma_cli_set_command((int)adapter->sessionId,
+ (int)GEN_PARAM_CAPTURE_TSF,
+ adapter->sessionId,
+ GEN_CMD);
+
+ if (ret != QDF_STATUS_SUCCESS) {
+ hdd_err(FL("capture fail"));
+ buf[0] = TSF_CAPTURE_FAIL;
+ adapter->tsf_state = TSF_IDLE;
+ }
+ }
+ return ret;
+}
+
+/**
+ * hdd_indicate_tsf() - return tsf to uplayer
+ * @adapter: pointer to adapter
+ * @buf: pointer to uplayer buf
+ * @len : the length of buf
+ *
+ * This function returns tsf value to upper layer.
+ *
+ * Return: 0 for success or non-zero negative failure code
+ */
+int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
+{
+ int ret = 0;
+ hdd_station_ctx_t *hdd_sta_ctx;
+
+ if (adapter == NULL || buf == NULL) {
+ hdd_err(FL("invalid pointer"));
+ return -EINVAL;
+ }
+
+ if (len != 3)
+ return -EINVAL;
+
+ buf[1] = 0;
+ buf[2] = 0;
+ if (adapter->device_mode == QDF_STA_MODE ||
+ adapter->device_mode == QDF_P2P_CLIENT_MODE) {
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ if (hdd_sta_ctx->conn_info.connState !=
+ eConnectionState_Associated) {
+
+ hdd_info(FL("fail to get tsf, sta in disconnected"));
+ buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
+ return ret;
+ }
+ }
+ if ((adapter->device_mode == QDF_SAP_MODE ||
+ adapter->device_mode == QDF_P2P_GO_MODE) &&
+ !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
+ hdd_err(FL("Soft AP / P2p GO not beaconing"));
+ buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
+ return ret;
+ }
+ if (adapter->tsf_high == 0 && adapter->tsf_low == 0) {
+ hdd_info(FL("TSF value not received"));
+ buf[0] = TSF_NOT_RETURNED_BY_FW;
+ } else {
+ buf[0] = TSF_RETURN;
+ buf[1] = adapter->tsf_low;
+ buf[2] = adapter->tsf_high;
+ adapter->tsf_state = TSF_IDLE;
+
+ ret = wma_cli_set_command((int)adapter->sessionId,
+ (int)GEN_PARAM_RESET_TSF_GPIO,
+ adapter->sessionId,
+ GEN_CMD);
+
+ if (0 != ret) {
+ hdd_err(FL("tsf get fail "));
+ buf[0] = TSF_RESET_GPIO_FAIL;
+ }
+ hdd_info(FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
+ buf[0], buf[1], buf[2]);
+ }
+ return ret;
+}
+
+/**
+ * hdd_get_tsf_cb() - handle tsf callback
+ * @pcb_cxt: pointer to the hdd_contex
+ * @ptsf: pointer to struct stsf
+ *
+ * This function handle the event that reported by firmware at first.
+ * The event contains the vdev_id, current tsf value of this vdev,
+ * tsf value is 64bits, discripted in two varaible tsf_low and tsf_high.
+ * These two values each is uint32.
+ *
+ * Return: 0 for success or non-zero negative failure code
+ */
+static int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
+{
+ struct hdd_context_s *hddctx;
+ struct hdd_adapter_s *adapter;
+ int status;
+
+ if (pcb_cxt == NULL || ptsf == NULL) {
+ hdd_err(FL("HDD context is not valid"));
+ return -EINVAL;
+ }
+
+ hddctx = (struct hdd_context_s *)pcb_cxt;
+ status = wlan_hdd_validate_context(hddctx);
+ if (0 != status) {
+ hdd_err(FL("hdd context is not valid"));
+ return -EINVAL;
+ }
+
+ adapter = hdd_get_adapter_by_vdev(hddctx, ptsf->vdev_id);
+
+ if (NULL == adapter) {
+ hdd_err(FL("failed to find adapter"));
+ return -EINVAL;
+ }
+
+ hdd_info(FL("tsf cb handle event, device_mode is %d"),
+ adapter->device_mode);
+
+ adapter->tsf_low = ptsf->tsf_low;
+ adapter->tsf_high = ptsf->tsf_high;
+
+ hdd_info(FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
+ ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
+ return 0;
+}
+
+/**
+ * wlan_hdd_tsf_init() - set callback to handle tsf value.
+ * @hdd_ctx: pointer to the struct hdd_context_s
+ *
+ * This function set the callback to sme module, the callback will be
+ * called when a tsf event is reported by firmware
+ *
+ * Return: none
+ */
+void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx)
+{
+ sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
+}
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index 60d3162afaed..2e390476d5ef 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -55,6 +55,7 @@
#include "wlan_hdd_lro.h"
#include "cdp_txrx_peer_ops.h"
+#include "ol_txrx.h"
#ifdef FEATURE_WLAN_DIAG_SUPPORT
#define HDD_EAPOL_ETHER_TYPE (0x888E)
@@ -670,6 +671,84 @@ QDF_STATUS hdd_deinit_tx_rx(hdd_adapter_t *pAdapter)
}
/**
+ * hdd_mon_rx_packet_cbk() - Receive callback registered with OL layer.
+ * @context: [in] pointer to qdf context
+ * @rxBuf: [in] pointer to rx qdf_nbuf
+ *
+ * TL will call this to notify the HDD when one or more packets were
+ * received for a registered STA.
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered, QDF_STATUS_SUCCESS
+ * otherwise
+ */
+static QDF_STATUS hdd_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf)
+{
+ hdd_adapter_t *adapter;
+ int rxstat;
+ struct sk_buff *skb;
+ struct sk_buff *skb_next;
+ unsigned int cpu_index;
+
+ /* Sanity check on inputs */
+ if ((NULL == context) || (NULL == rxbuf)) {
+ QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+ "%s: Null params being passed", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ adapter = (hdd_adapter_t *)context;
+ if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+ QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+ "invalid adapter %p", adapter);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ cpu_index = wlan_hdd_get_cpu();
+
+ /* walk the chain until all are processed */
+ skb = (struct sk_buff *) rxbuf;
+ while (NULL != skb) {
+ skb_next = skb->next;
+ skb->dev = adapter->dev;
+
+ ++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
+ ++adapter->stats.rx_packets;
+ adapter->stats.rx_bytes += skb->len;
+
+ /* Remove SKB from internal tracking table before submitting
+ * it to stack
+ */
+ qdf_net_buf_debug_release_skb(skb);
+
+ /*
+ * If this is not a last packet on the chain
+ * Just put packet into backlog queue, not scheduling RX sirq
+ */
+ if (skb->next) {
+ rxstat = netif_rx(skb);
+ } else {
+ /*
+ * This is the last packet on the chain
+ * Scheduling rx sirq
+ */
+ rxstat = netif_rx_ni(skb);
+ }
+
+ if (NET_RX_SUCCESS == rxstat)
+ ++adapter->
+ hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
+ else
+ ++adapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
+
+ skb = skb_next;
+ }
+
+ adapter->dev->last_rx = jiffies;
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
* hdd_rx_packet_cbk() - Receive packet handler
* @context: pointer to HDD context
* @rxBuf: pointer to rx qdf_nbuf
@@ -1108,3 +1187,45 @@ void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
return;
}
+/**
+ * hdd_set_mon_rx_cb() - Set Monitor mode Rx callback
+ * @dev: Pointer to net_device structure
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_set_mon_rx_cb(struct net_device *dev)
+{
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ int ret;
+ QDF_STATUS qdf_status;
+ struct ol_txrx_desc_type sta_desc = {0};
+ struct ol_txrx_ops txrx_ops;
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret)
+ return ret;
+
+ qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
+ txrx_ops.rx.rx = hdd_mon_rx_packet_cbk;
+ ol_txrx_vdev_register(
+ ol_txrx_get_vdev_from_vdev_id(adapter->sessionId),
+ adapter, &txrx_ops);
+ /* peer is created wma_vdev_attach->wma_create_peer */
+ qdf_status = ol_txrx_register_peer(&sta_desc);
+ if (QDF_STATUS_SUCCESS != qdf_status) {
+ hdd_err("WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
+ qdf_status, qdf_status);
+ goto exit;
+ }
+
+ qdf_status = sme_create_mon_session(hdd_ctx->hHal,
+ adapter->macAddressCurrent.bytes);
+ if (QDF_STATUS_SUCCESS != qdf_status) {
+ hdd_err("sme_create_mon_session() failed to register. Status= %d [0x%08X]",
+ qdf_status, qdf_status);
+ }
+exit:
+ ret = qdf_status_to_os_return(qdf_status);
+ return ret;
+}
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index f8f4137c4e6c..28a9522582cc 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -80,6 +80,7 @@
#include "sme_power_save_api.h"
#include "cds_concurrency.h"
#include "wlan_hdd_conc_ut.h"
+#include "wlan_hdd_tsf.h"
#include "wlan_hdd_ocb.h"
#include "wlan_hdd_napi.h"
#include "cdp_txrx_flow_ctrl_legacy.h"
@@ -215,6 +216,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
/* Private sub ioctl for starting/stopping the profiling */
#define WE_START_FW_PROFILE 87
#define WE_SET_CHANNEL 88
+#define WE_SET_CONC_SYSTEM_PREF 89
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -273,6 +275,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
#define WE_GET_GTX_MINTPC 53
#define WE_GET_GTX_BWMASK 54
#define WE_GET_TEMPERATURE 56
+#define WE_CAP_TSF 58
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2)
@@ -364,6 +367,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
#define WE_SET_DUAL_MAC_SCAN_CONFIG 21
#define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22
+#define WE_SET_MON_MODE_CHAN 23
#ifdef FEATURE_WLAN_TDLS
#undef MAX_VAR_ARGS
@@ -383,7 +387,8 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
/* (SIOCIWFIRSTPRIV + 10) is currently unused */
/* (SIOCIWFIRSTPRIV + 12) is currently unused */
/* (SIOCIWFIRSTPRIV + 14) is currently unused */
-/* (SIOCIWFIRSTPRIV + 15) is currently unused */
+#define WLAN_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV + 15)
+#define WE_GET_TSF 1
/* (SIOCIWFIRSTPRIV + 16) is currently unused */
/* (SIOCIWFIRSTPRIV + 17) is currently unused */
/* (SIOCIWFIRSTPRIV + 19) is currently unused */
@@ -6271,7 +6276,19 @@ static int __iw_setint_getnone(struct net_device *dev,
}
break;
}
+ case WE_SET_CONC_SYSTEM_PREF:
+ {
+ hdd_info("New preference: %d", set_value);
+ if (!((set_value >= CFG_CONC_SYSTEM_PREF_MIN) &&
+ (set_value <= CFG_CONC_SYSTEM_PREF_MAX))) {
+ hdd_err("Invalid system preference %d", set_value);
+ return -EINVAL;
+ }
+ /* hdd_ctx, hdd_ctx->config are already checked for null */
+ hdd_ctx->config->conc_system_pref = set_value;
+ break;
+ }
default:
{
hddLog(LOGE, "%s: Invalid sub command %d", __func__,
@@ -6299,6 +6316,65 @@ static int iw_setint_getnone(struct net_device *dev,
}
/**
+ * __iw_setnone_get_threeint() - return three value to up layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int __iw_setnone_get_threeint(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret = 0; /* success */
+ uint32_t *value = (int *)extra;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+ ENTER_DEV(dev);
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret)
+ return ret;
+
+ hdd_info(FL("param = %d"), value[0]);
+ switch (value[0]) {
+ case WE_GET_TSF:
+ ret = hdd_indicate_tsf(adapter, value, 3);
+ break;
+ default:
+ hdd_err("Invalid IOCTL get_value command %d", value[0]);
+ break;
+ }
+ return ret;
+}
+
+/**
+ * iw_setnone_get_threeint() - return three value to up layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int iw_setnone_get_threeint(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret;
+
+ cds_ssr_protect(__func__);
+ ret = __iw_setnone_get_threeint(dev, info, wrqu, extra);
+ cds_ssr_unprotect(__func__);
+
+ return ret;
+}
+
+/**
* iw_setchar_getnone() - Generic "set string" private ioctl handler
* @dev: device upon which the ioctl was received
* @info: ioctl request information
@@ -6914,7 +6990,9 @@ static int __iw_setnone_getint(struct net_device *dev,
QPOWER_CMD);
break;
}
-
+ case WE_CAP_TSF:
+ ret = hdd_capture_tsf(pAdapter, (uint32_t *)value, 1);
+ break;
case WE_GET_TEMPERATURE:
{
hddLog(QDF_TRACE_LEVEL_INFO, "WE_GET_TEMPERATURE");
@@ -7977,7 +8055,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
if (apps_args[0] == 0) {
hddLog(LOGE,
FL("set hw mode for single mac\n"));
- cds_soc_set_hw_mode(
+ cds_pdev_set_hw_mode(
pAdapter->sessionId,
HW_MODE_SS_2x2,
HW_MODE_80_MHZ,
@@ -7988,7 +8066,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
} else if (apps_args[0] == 1) {
hddLog(LOGE,
FL("set hw mode for dual mac\n"));
- cds_soc_set_hw_mode(
+ cds_pdev_set_hw_mode(
pAdapter->sessionId,
HW_MODE_SS_1x1,
HW_MODE_80_MHZ,
@@ -9651,6 +9729,53 @@ static int iw_set_band_config(struct net_device *dev,
return ret;
}
+/**
+ * wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface.
+ * @adapter: Handle to adapter
+ * @chan: Monitor mode channel
+ * @bandwidth: Capture channel bandwidth
+ *
+ * Return: 0 on success else error code.
+ */
+static int wlan_hdd_set_mon_chan(hdd_adapter_t *adapter, uint32_t chan,
+ uint32_t bandwidth)
+{
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
+ QDF_STATUS status;
+ tHalHandle hal_hdl = hdd_ctx->hHal;
+ struct qdf_mac_addr bssid;
+ tCsrRoamProfile roam_profile;
+ struct ch_params_s ch_params;
+
+ if (QDF_GLOBAL_MONITOR_MODE != hdd_get_conparam()) {
+ hdd_err("Not supported, device is not in monitor mode");
+ return -EINVAL;
+ }
+
+ hdd_info("Set monitor mode Channel %d", chan);
+ hdd_select_cbmode(adapter, chan);
+ roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
+ roam_profile.ChannelInfo.numOfChannels = 1;
+ roam_profile.phyMode = ch_info->phy_mode;
+ roam_profile.ch_params.ch_width = bandwidth;
+
+ qdf_mem_copy(bssid.bytes, adapter->macAddressCurrent.bytes,
+ QDF_MAC_ADDR_SIZE);
+
+ ch_params.ch_width = bandwidth;
+ sme_set_ch_params(hal_hdl, ch_info->phy_mode, chan, 0, &ch_params);
+ status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params,
+ &roam_profile);
+ if (status) {
+ hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
+ status);
+ }
+
+ return qdf_status_to_os_return(status);
+}
+
static int __iw_set_two_ints_getnone(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -9716,6 +9841,9 @@ static int __iw_set_two_ints_getnone(struct net_device *dev,
if (value[1] == DUMP_DP_TRACE)
qdf_dp_trace_dump_all(value[2]);
break;
+ case WE_SET_MON_MODE_CHAN:
+ ret = wlan_hdd_set_mon_chan(pAdapter, value[1], value[2]);
+ break;
default:
hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
break;
@@ -9809,6 +9937,8 @@ static const iw_handler we_private[] = {
[WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, /* action priv ioctl */
[WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] =
iw_hdd_set_var_ints_getnone,
+ [WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] =
+ iw_setnone_get_threeint,
[WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
[WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
[WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
@@ -10256,6 +10386,10 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "setChanChange" },
+ {WE_SET_CONC_SYSTEM_PREF,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "setConcSysPref" },
+
{WLAN_PRIV_SET_NONE_GET_INT,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -10506,6 +10640,11 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_qnodatapoll"},
+ {WE_CAP_TSF,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "cap_tsf"},
+
{WE_GET_TEMPERATURE,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -10565,6 +10704,15 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
0,
"setsapchannels"},
+ /* handlers for main ioctl */
+ {WLAN_PRIV_SET_NONE_GET_THREE_INT,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+ "" },
+ {WE_GET_TSF,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+ "get_tsf" },
{WE_SET_DUAL_MAC_SCAN_CONFIG,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
@@ -10917,6 +11065,10 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
0, "dump_dp_trace"}
,
+ {WE_SET_MON_MODE_CHAN,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+ 0, "setMonChan"}
+ ,
};
const struct iw_handler_def we_handler_def = {
diff --git a/core/hdd/src/wlan_hdd_wmm.c b/core/hdd/src/wlan_hdd_wmm.c
index 28e96fb7b299..5fbfb179fc9d 100644
--- a/core/hdd/src/wlan_hdd_wmm.c
+++ b/core/hdd/src/wlan_hdd_wmm.c
@@ -1882,12 +1882,7 @@ QDF_STATUS hdd_wmm_acquire_access(hdd_adapter_t *pAdapter,
pQosContext->magic = HDD_WMM_CTX_MAGIC;
pQosContext->is_inactivity_timer_running = false;
-#ifdef CONFIG_CNSS
- cnss_init_work(&pQosContext->wmmAcSetupImplicitQos,
- hdd_wmm_do_implicit_qos);
-#else
INIT_WORK(&pQosContext->wmmAcSetupImplicitQos, hdd_wmm_do_implicit_qos);
-#endif
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
"%s: Scheduling work for AC %d, context %p",
diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h
index 8f68465306b0..05430a9bb978 100644
--- a/core/mac/inc/ani_global.h
+++ b/core/mac/inc/ani_global.h
@@ -131,6 +131,7 @@ enum log_event_type {
* @WLAN_LOG_INDICATOR_FRAMEWORK: Framework triggers bug report
* @WLAN_LOG_INDICATOR_HOST_DRIVER: Host driver triggers bug report
* @WLAN_LOG_INDICATOR_FIRMWARE: FW initiates bug report
+ * @WLAN_LOG_INDICATOR_HOST_ONLY: Host triggers fatal event bug report
*
* Enum indicating the module that triggered the bug report
*/
@@ -139,52 +140,39 @@ enum log_event_indicator {
WLAN_LOG_INDICATOR_FRAMEWORK,
WLAN_LOG_INDICATOR_HOST_DRIVER,
WLAN_LOG_INDICATOR_FIRMWARE,
+ WLAN_LOG_INDICATOR_HOST_ONLY,
};
/**
* enum log_event_host_reason_code - Reason code for bug report
* @WLAN_LOG_REASON_CODE_UNUSED: Unused
- * @WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL: Command response status from FW
- * is error
* @WLAN_LOG_REASON_ROAM_FAIL: Driver initiated roam has failed
- * @WLAN_LOG_REASON_THREAD_STUCK: Monitor Health of host threads and report
- * fatal event if some thread is stuck
* @WLAN_LOG_REASON_DATA_STALL: Unable to send/receive data due to low resource
* scenario for a prolonged period
* @WLAN_LOG_REASON_SME_COMMAND_STUCK: SME command is stuck in SME active queue
- * @WLAN_LOG_REASON_ZERO_SCAN_RESULTS: Full scan resulted in zero scan results
* @WLAN_LOG_REASON_QUEUE_FULL: Defer queue becomes full for a prolonged period
* @WLAN_LOG_REASON_POWER_COLLAPSE_FAIL: Unable to allow apps power collapse
* for a prolonged period
- * @WLAN_LOG_REASON_SSR_FAIL: Unable to gracefully complete SSR
- * @WLAN_LOG_REASON_DISCONNECT_FAIL: Disconnect from Supplicant is not
- * successful
- * @WLAN_LOG_REASON_CLEAN_UP_FAIL: Clean up of TDLS or Pre-Auth Sessions
- * not successful
* @WLAN_LOG_REASON_MALLOC_FAIL: Memory allocation Fails
* @WLAN_LOG_REASON_VOS_MSG_UNDER_RUN: VOS Core runs out of message wrapper
- * @WLAN_LOG_REASON_MSG_POST_FAIL: Unable to post msg
- *
+ * @WLAN_LOG_REASON_HDD_TIME_OUT: Wait for event Timeout in HDD layer
+ @WLAN_LOG_REASON_SME_OUT_OF_CMD_BUFL sme out of cmd buffer
* This enum contains the different reason codes for bug report
*/
enum log_event_host_reason_code {
WLAN_LOG_REASON_CODE_UNUSED,
- WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL,
WLAN_LOG_REASON_ROAM_FAIL,
- WLAN_LOG_REASON_THREAD_STUCK,
WLAN_LOG_REASON_DATA_STALL,
WLAN_LOG_REASON_SME_COMMAND_STUCK,
- WLAN_LOG_REASON_ZERO_SCAN_RESULTS,
WLAN_LOG_REASON_QUEUE_FULL,
WLAN_LOG_REASON_POWER_COLLAPSE_FAIL,
- WLAN_LOG_REASON_SSR_FAIL,
- WLAN_LOG_REASON_DISCONNECT_FAIL,
- WLAN_LOG_REASON_CLEAN_UP_FAIL,
WLAN_LOG_REASON_MALLOC_FAIL,
WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
- WLAN_LOG_REASON_MSG_POST_FAIL,
+ WLAN_LOG_REASON_HDD_TIME_OUT,
+ WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
};
+
/**
* enum userspace_log_level - Log level at userspace
* @LOG_LEVEL_NO_COLLECTION: verbose_level 0 corresponds to no collection
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
index 738e05d5cb54..b225c7fecf54 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 ""
-#define QWLAN_VERSION_BUILD 5
+#define QWLAN_VERSION_EXTRA "A"
+#define QWLAN_VERSION_BUILD 7
-#define QWLAN_VERSIONSTR "5.1.0.5"
+#define QWLAN_VERSIONSTR "5.1.0.7A"
#endif /* QWLAN_VERSION_H */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 5c5ff30e87f9..7cb2188783c3 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -494,6 +494,7 @@ typedef enum eSirBssType {
eSIR_INFRA_AP_MODE, /* Added for softAP support */
eSIR_IBSS_MODE,
eSIR_AUTO_MODE,
+ eSIR_MONITOR_MODE,
eSIR_DONOT_USE_BSS_TYPE = SIR_MAX_ENUM_SIZE
} tSirBssType;
@@ -682,7 +683,6 @@ typedef struct sSirSmeHTProfile {
uint8_t htRecommendedTxWidthSet;
ePhyChanBondState htSecondaryChannelOffset;
uint8_t vhtCapability;
- uint8_t vhtTxChannelWidthSet;
uint8_t apCenterChan;
uint8_t apChanWidth;
} tSirSmeHTProfile;
@@ -778,6 +778,10 @@ typedef struct sSirSmeScanReq {
*/
/* in units of milliseconds, ignored when not connected */
uint32_t restTime;
+ /*in units of milliseconds, ignored when not connected*/
+ uint32_t min_rest_time;
+ /*in units of milliseconds, ignored when not connected*/
+ uint32_t idle_time;
uint8_t returnAfterFirstMatch;
/**
@@ -2430,6 +2434,18 @@ typedef struct sSirUpdateParams {
uint8_t ssidHidden; /* Hide SSID */
} tSirUpdateParams, *tpSirUpdateParams;
+/**
+ * struct sir_create_session - Used for creating session in monitor mode
+ * @type: SME host message type.
+ * @msg_len: Length of the message.
+ * @bss_id: bss_id for creating the session.
+ */
+struct sir_create_session {
+ uint16_t type;
+ uint16_t msg_len;
+ struct qdf_mac_addr bss_id;
+};
+
/* Beacon Interval */
typedef struct sSirChangeBIParams {
uint16_t messageType;
@@ -3571,6 +3587,10 @@ typedef struct sSirScanOffloadReq {
uint32_t scan_requestor_id;
/* in units of milliseconds, ignored when not connected */
uint32_t restTime;
+ /*in units of milliseconds, ignored when not connected*/
+ uint32_t min_rest_time;
+ /*in units of milliseconds, ignored when not connected*/
+ uint32_t idle_time;
tSirP2pScanType p2pScanType;
uint16_t uIEFieldLen;
uint16_t uIEFieldOffset;
@@ -5564,6 +5584,21 @@ struct sir_sme_ext_cng_chan_ind {
};
/**
+ * struct stsf - the basic stsf structure
+ *
+ * @vdev_id: vdev id
+ * @tsf_low: low 32bits of tsf
+ * @tsf_high: high 32bits of tsf
+ *
+ * driver use this struct to store the tsf info
+ */
+struct stsf {
+ uint32_t vdev_id;
+ uint32_t tsf_low;
+ uint32_t tsf_high;
+};
+
+/**
* struct egap_params - the enhanced green ap params
* @vdev_id: vdev id
* @enable: enable or disable the enhance green ap in firmware
@@ -5615,18 +5650,6 @@ struct csa_offload_params {
};
/**
- * struct sir_saved_csa_params - saved csa offload params
- * @message_type: Message type
- * @length: Message length
- * @session_id: Session id
- */
-struct sir_saved_csa_params {
- uint16_t message_type;
- uint16_t length;
- uint32_t session_id;
-};
-
-/**
* enum obss_ht40_scancmd_type - obss scan command type
* @HT40_OBSS_SCAN_PARAM_START: OBSS scan start
* @HT40_OBSS_SCAN_PARAM_UPDATE: OBSS scan param update
@@ -5711,4 +5734,40 @@ struct obss_scanparam {
uint16_t obss_activity_threshold;
};
+/**
+ * struct sir_bpf_set_offload - set bpf filter instructions
+ * @session_id: session identifier
+ * @version: host bpf version
+ * @filter_id: Filter ID for BPF filter
+ * @total_length: The total length of the full instruction
+ * total_length equal to 0 means reset
+ * @current_offset: current offset, 0 means start a new setting
+ * @current_length: Length of current @program
+ * @program: BPF instructions
+ */
+struct sir_bpf_set_offload {
+ uint8_t session_id;
+ uint32_t version;
+ uint32_t filter_id;
+ uint32_t total_length;
+ uint32_t current_offset;
+ uint32_t current_length;
+ uint8_t *program;
+};
+
+/**
+ * struct sir_bpf_offload_capabilities - get bpf Capabilities
+ * @bpf_version: fw's implement version
+ * @max_bpf_filters: max filters that fw supports
+ * @max_bytes_for_bpf_inst: the max bytes that can be used as bpf instructions
+ * @remaining_bytes_for_bpf_inst: remaining bytes for bpf instructions
+ *
+ */
+struct sir_bpf_get_offload {
+ uint32_t bpf_version;
+ uint32_t max_bpf_filters;
+ uint32_t max_bytes_for_bpf_inst;
+ uint32_t remaining_bytes_for_bpf_inst;
+};
+
#endif /* __SIR_API_H */
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index 2585a4fa3445..596f55889671 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -145,6 +145,9 @@
#define SIR_MAC_ACTION_FST 18
#define SIR_MAC_ACTION_VHT 21
+#define SIR_MAC_ACTION_TX 1
+#define SIR_MAC_ACTION_RX 2
+
/* QoS management action codes */
#define SIR_MAC_QOS_ADD_TS_REQ 0
diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h
index 23ab4d2dffe1..e6dfb2dda66a 100644
--- a/core/mac/inc/wni_api.h
+++ b/core/mac/inc/wni_api.h
@@ -248,6 +248,8 @@ enum eWniMsgTypes {
eWNI_SME_HT40_OBSS_SCAN_IND, /* START and UPDATE OBSS SCAN Indication*/
eWNI_SME_SET_ANTENNA_MODE_REQ,
eWNI_SME_SET_ANTENNA_MODE_RESP,
+ eWNI_SME_TSF_EVENT,
+ eWNI_SME_MON_INIT_SESSION,
eWNI_SME_MSG_TYPES_END
};
diff --git a/core/mac/src/dph/dph_hash_table.c b/core/mac/src/dph/dph_hash_table.c
index 0e592d18a774..af64bd5899a8 100644
--- a/core/mac/src/dph/dph_hash_table.c
+++ b/core/mac/src/dph/dph_hash_table.c
@@ -450,7 +450,8 @@ tSirRetStatus dph_delete_hash_entry(tpAniSirGlobal pMac, tSirMacAddr staAddr,
void dph_print_mac_addr(tpAniSirGlobal pMac, uint8_t addr[], uint32_t level)
{
- lim_log(pMac, (uint16_t) level, FL("MAC ADDR = %d:%d:%d:%d:%d:%d"),
+ lim_log(pMac, (uint16_t) level,
+ FL("MAC ADDR = %02x:%02x:%02x:%02x:%02x:%02x"),
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
}
diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h
index f48aac5c416f..4a99241f7304 100644
--- a/core/mac/src/include/parser_api.h
+++ b/core/mac/src/include/parser_api.h
@@ -148,6 +148,7 @@ typedef struct sSirProbeRespBeacon {
tDot11fIEVHTCaps VHTCaps;
tDot11fIEVHTOperation VHTOperation;
tDot11fIEVHTExtBssLoad VHTExtBssLoad;
+ tDot11fIEExtCap ext_cap;
tDot11fIEOperatingMode OperatingMode;
uint8_t WiderBWChanSwitchAnnPresent;
tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
diff --git a/core/mac/src/include/sir_debug.h b/core/mac/src/include/sir_debug.h
index 674855d0567b..c038523cf784 100644
--- a/core/mac/src/include/sir_debug.h
+++ b/core/mac/src/include/sir_debug.h
@@ -100,9 +100,6 @@
#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
-#define FL(x) "%s: %d: " \
- x, __func__, __LINE__
-
#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index 6287638b2b8f..9959dda2df43 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -411,8 +411,8 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_DEL_PERIODIC_TX_PTRN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 153)
/* Messages between 156 to 157 are not used */
-#define SIR_HAL_SOC_DUAL_MAC_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 154)
-#define SIR_HAL_SOC_DUAL_MAC_CFG_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 155)
+#define SIR_HAL_PDEV_DUAL_MAC_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 154)
+#define SIR_HAL_PDEV_MAC_CFG_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 155)
/* For IBSS peer info related messages */
#define SIR_HAL_IBSS_PEER_INFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 158)
@@ -587,9 +587,9 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_FW_MEM_DUMP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 327)
#define SIR_HAL_START_STOP_LOGGING (SIR_HAL_ITC_MSG_TYPES_BEGIN + 328)
-#define SIR_HAL_SOC_SET_HW_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 329)
-#define SIR_HAL_SOC_SET_HW_MODE_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 330)
-#define SIR_HAL_SOC_HW_MODE_TRANS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 331)
+#define SIR_HAL_PDEV_SET_HW_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 329)
+#define SIR_HAL_PDEV_SET_HW_MODE_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 330)
+#define SIR_HAL_PDEV_HW_MODE_TRANS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 331)
#define SIR_HAL_SET_RSSI_MONITOR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 333)
#define SIR_HAL_SET_IE_INFO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 334)
@@ -599,9 +599,14 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_SET_EGAP_CONF_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 336)
#define SIR_HAL_HT40_OBSS_SCAN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 337)
+#define SIR_HAL_TSF_GPIO_PIN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 338)
+
#define SIR_HAL_ADD_BCN_FILTER_CMDID (SIR_HAL_ITC_MSG_TYPES_BEGIN + 339)
#define SIR_HAL_REMOVE_BCN_FILTER_CMDID (SIR_HAL_ITC_MSG_TYPES_BEGIN + 340)
+#define SIR_HAL_BPF_GET_CAPABILITIES_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 341)
+#define SIR_HAL_BPF_SET_INSTRUCTIONS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 342)
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
/* CFG message types */
@@ -635,7 +640,7 @@ typedef struct sSirMbMsgP2p {
#define SIR_LIM_SCH_CLEAN_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xB)
/* Message from ISR upon Radar Detection */
#define SIR_LIM_RADAR_DETECT_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xC)
-#define SIR_LIM_CSA_POST_HW_MODE_CHANGE (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xD)
+/* Message id 0xD available */
/* Message from Hal to send out a DEL-TS indication */
#define SIR_LIM_DEL_TS_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xE)
diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h
index e66de6befda7..dabb6b4d76e5 100644
--- a/core/mac/src/pe/include/lim_api.h
+++ b/core/mac/src/pe/include/lim_api.h
@@ -172,6 +172,17 @@ static inline QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
return QDF_STATUS_E_NOSUPPORT;
}
#endif
+
+/**
+ * lim_mon_init_session() - create PE session for monitor mode operation
+ * @mac_ptr: mac pointer
+ * @msg: Pointer to struct sir_create_session type.
+ *
+ * Return: NONE
+ */
+void lim_mon_init_session(tpAniSirGlobal mac_ptr,
+ struct sir_create_session *msg);
+
#define limGetQosMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limQosEnabled)
#define limGetWmeMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWmeEnabled)
#define limGetWsmMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWsmEnabled)
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
index 8ff3010ee5a7..779070b6ed12 100644
--- a/core/mac/src/pe/include/lim_session.h
+++ b/core/mac/src/pe/include/lim_session.h
@@ -309,7 +309,6 @@ typedef struct sPESession /* Added to Support BT-AMP */
tBeaconParams beaconParams;
uint8_t vhtCapability;
- uint8_t vhtTxChannelWidthSet;
tLimOperatingModeInfo gLimOperatingMode;
uint8_t vhtCapabilityPresentInBeacon;
uint8_t ch_center_freq_seg0;
@@ -472,11 +471,11 @@ typedef struct sPESession /* Added to Support BT-AMP */
uint8_t country_info_present;
uint8_t nss;
bool add_bss_failed;
- struct csa_offload_params saved_csa_params;
/* To hold OBSS Scan IE Parameters */
struct obss_scanparam obss_ht40_scanparam;
/* Supported NSS is intersection of self and peer NSS */
bool supported_nss_1x1;
+ bool is_ext_caps_present;
} tPESession, *tpPESession;
/*-------------------------------------------------------------------------
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index 5912165c93aa..3c440df4627b 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -1699,8 +1699,6 @@ void lim_fill_join_rsp_ht_caps(tpPESession session, tpSirSmeJoinRsp join_rsp)
ht_profile->dot11mode = session->dot11mode;
ht_profile->htCapability = session->htCapability;
ht_profile->vhtCapability = session->vhtCapability;
- ht_profile->vhtTxChannelWidthSet =
- session->vhtTxChannelWidthSet;
ht_profile->apCenterChan = session->ch_center_freq_seg0;
ht_profile->apChanWidth = session->ch_width;
}
@@ -1880,6 +1878,7 @@ QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
tpAddBssParams add_bss_params;
uint8_t local_nss;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
+ uint16_t join_rsp_len;
if (!roam_sync_ind_ptr) {
lim_log(mac_ctx, LOGE, FL("LFR3:roam_sync_ind_ptr is NULL"));
@@ -1989,6 +1988,31 @@ QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
curr_sta_ds->nss = local_nss;
ft_session_ptr->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
lim_init_tdls_data(mac_ctx, ft_session_ptr);
+ join_rsp_len = ft_session_ptr->RICDataLen + sizeof(tSirSmeJoinRsp) -
+ sizeof(uint8_t);
+ roam_sync_ind_ptr->join_rsp = qdf_mem_malloc(join_rsp_len);
+ if (NULL == roam_sync_ind_ptr->join_rsp) {
+ lim_log(mac_ctx, LOGE, FL("LFR3:mem alloc failed"));
+ ft_session_ptr->bRoamSynchInProgress = false;
+ if (mac_ctx->roam.pReassocResp)
+ qdf_mem_free(mac_ctx->roam.pReassocResp);
+ mac_ctx->roam.pReassocResp = NULL;
+ return QDF_STATUS_E_NOMEM;
+ }
+ qdf_mem_zero(roam_sync_ind_ptr->join_rsp, join_rsp_len);
+
+ lim_log(mac_ctx, LOG1, FL("Session RicLength = %d"),
+ ft_session_ptr->RICDataLen);
+ if (ft_session_ptr->ricData != NULL) {
+ roam_sync_ind_ptr->join_rsp->parsedRicRspLen =
+ ft_session_ptr->RICDataLen;
+ qdf_mem_copy(roam_sync_ind_ptr->join_rsp->frames,
+ ft_session_ptr->ricData,
+ roam_sync_ind_ptr->join_rsp->parsedRicRspLen);
+ qdf_mem_free(ft_session_ptr->ricData);
+ ft_session_ptr->ricData = NULL;
+ ft_session_ptr->RICDataLen = 0;
+ }
roam_sync_ind_ptr->join_rsp->vht_channel_width =
ft_session_ptr->ch_width;
roam_sync_ind_ptr->join_rsp->staId = curr_sta_ds->staIndex;
@@ -2145,3 +2169,29 @@ QDF_STATUS pe_release_global_lock(tAniSirLim *psPe)
return status;
}
+/**
+ * lim_mon_init_session() - create PE session for monitor mode operation
+ * @mac_ptr: mac pointer
+ * @msg: Pointer to struct sir_create_session type.
+ *
+ * Return: NONE
+ */
+void lim_mon_init_session(tpAniSirGlobal mac_ptr,
+ struct sir_create_session *msg)
+{
+ tpPESession psession_entry;
+ uint8_t session_id;
+
+ lim_print_mac_addr(mac_ptr, msg->bss_id.bytes, LOGE);
+ psession_entry = pe_create_session(mac_ptr, msg->bss_id.bytes,
+ &session_id,
+ mac_ptr->lim.maxStation,
+ eSIR_MONITOR_MODE);
+ if (psession_entry == NULL) {
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+ ("Monitor mode: Session Can not be created"));
+ lim_print_mac_addr(mac_ptr, msg->bss_id.bytes, LOGE);
+ return;
+ }
+ psession_entry->vhtCapability = 1;
+}
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
index 27d6a4159760..bebe8120dafc 100644
--- a/core/mac/src/pe/lim/lim_process_message_queue.c
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -1241,160 +1241,6 @@ static void lim_process_sme_obss_scan_ind(tpAniSirGlobal mac_ctx,
}
/**
- * lim_handle_hw_mode_change_on_csa() - Do HW mode change on CSA for STA mode
- * @mac_ctx: Global MAC context
- * @msg: Received message
- *
- * Checks if hw mode change is required for the new channel.
- * If MCC upgrade is required, this function will start the opportunistic
- * timer and the caller will invoke the other APIs to perform vdev restart on
- * the new channel.
- *
- * If DBS downgrade is required, this function will initiate the hw mode
- * change and vdev restart will happen on the new channel after getting hw
- * mode response
- *
- * Return: QDF_STATUS_SUCCESS if processing of csa params (and hence vdev
- * restart) needs to happen or if no hw mode change is required,
- * QDF_STATUS_E_FAILURE otherwise.
- */
-static QDF_STATUS lim_handle_hw_mode_change_on_csa(tpAniSirGlobal mac_ctx,
- tpSirMsgQ msg)
-{
- tpPESession session_entry;
- struct csa_offload_params *csa_params =
- (struct csa_offload_params *) (msg->bodyptr);
- tpDphHashNode sta_ds = NULL;
- uint8_t session_id;
- uint16_t aid = 0;
- QDF_STATUS status = QDF_STATUS_E_FAILURE;
-
- lim_log(mac_ctx, LOG1, FL("handle hw mode change for csa"));
-
- if (!csa_params) {
- lim_log(mac_ctx, LOGE, FL("limMsgQ body ptr is NULL"));
- /* qdf_mem_free() can handle NULL values */
- goto err;
- }
-
- session_entry = pe_find_session_by_bssid(mac_ctx,
- csa_params->bssId, &session_id);
- if (!session_entry) {
- lim_log(mac_ctx, LOGE, FL("Session does not exist"));
- goto err;
- }
-
- sta_ds = dph_lookup_hash_entry(mac_ctx, session_entry->bssId, &aid,
- &session_entry->dph.dphHashTable);
-
- if (!sta_ds) {
- lim_log(mac_ctx, LOGE, FL("sta_ds does not exist"));
- goto err;
- }
-
- status = cds_handle_hw_mode_change_on_csa(session_entry->smeSessionId,
- csa_params->channel, csa_params->bssId,
- &session_entry->saved_csa_params, csa_params,
- sizeof(session_entry->saved_csa_params));
-
- if (QDF_IS_STATUS_SUCCESS(status))
- return status;
-
-err:
- qdf_mem_free(csa_params);
- return status;
-}
-
-/**
- * lim_handle_hw_mode_change_on_csa_event() - Handle hw mode change on csa
- * @mac_ctx: Pointer to the Global Mac Context
- * @msg: Received message
- *
- * Checks if a hw mode change is required for the received csa event. Processes
- * csa params and do vdev restart immediately if the there is no need for a hw
- * mode change or if MCC upgrade is required
- *
- * Return: None
- */
-static void lim_handle_hw_mode_change_on_csa_event(tpAniSirGlobal mac_ctx,
- tpSirMsgQ msg)
-{
- QDF_STATUS qdf_status;
-
- lim_log(mac_ctx, LOG1, FL("lim received csa offload event"));
- if (mac_ctx->policy_manager_enabled &&
- wma_is_hw_dbs_capable() == true) {
- /* Check if a hw mode change is required */
- qdf_status = lim_handle_hw_mode_change_on_csa(mac_ctx,
- msg);
- /* Process csa params and do vdev restart immediately if
- * there is no need for a hw mode change or if MCC upgrade is
- * required.
- */
- if (QDF_IS_STATUS_SUCCESS(qdf_status))
- lim_handle_csa_offload_msg(mac_ctx, msg);
- } else {
- lim_handle_csa_offload_msg(mac_ctx, msg);
- }
-}
-
-/**
- * lim_handle_csa_event_post_dbs_downgrade() - Process csa event post dbs
- * downgrade
- * @mac_ctx: Pointer to the Global Mac Context
- * @msg: Received message
- *
- * Process the csa event to do vdev restart on the new channel after the dbs
- * downgrade. If there was a DBS downgrade as part of the event
- * WMA_CSA_OFFLOAD_EVENT, SIR_LIM_CSA_POST_HW_MODE_CHANGE will be received after
- * receiving the set hw mode response, where this processing will happen.
- *
- * Return: None
- */
-static void lim_handle_csa_event_post_dbs_downgrade(tpAniSirGlobal mac_ctx,
- tpSirMsgQ msg)
-{
- tSirMsgQ csa_msg;
- tpPESession session_entry;
-
- struct sir_saved_csa_params *buf =
- (struct sir_saved_csa_params *)msg->bodyptr;
-
- /* Null check for 'msg' already done before coming here in the caller */
-
- session_entry = pe_find_session_by_sme_session_id(mac_ctx,
- buf->session_id);
- if (!session_entry) {
- lim_log(mac_ctx, LOGE, FL("Invalid session id:%d"),
- buf->session_id);
- return;
- }
-
- lim_log(mac_ctx, LOG1,
- FL("received csa offload event post hw change for %pM"),
- session_entry->saved_csa_params.bssId);
-
- csa_msg.bodyptr = qdf_mem_malloc(
- sizeof(struct csa_offload_params));
- if (!csa_msg.bodyptr) {
- lim_log(mac_ctx, LOGE, FL("malloc failed for csa msg"));
- goto clean_msg_body;
- }
-
- qdf_mem_copy((void *)csa_msg.bodyptr,
- (void *)&session_entry->saved_csa_params,
- sizeof(struct csa_offload_params));
- /* If there was a DBS downgrade as part of the event
- * WMA_CSA_OFFLOAD_EVENT, SIR_LIM_CSA_POST_HW_MODE_CHANGE will
- * be received after receiving the set hw mode response.
- */
- lim_handle_csa_offload_msg(mac_ctx, &csa_msg);
-clean_msg_body:
- if (msg->bodyptr)
- qdf_mem_free(msg->bodyptr);
-}
-
-/**
* lim_process_messages() - Process messages from upper layers.
*
* @mac_ctx: Pointer to the Global Mac Context.
@@ -1626,6 +1472,11 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
break;
+ case eWNI_SME_MON_INIT_SESSION:
+ lim_mon_init_session(mac_ctx, msg->bodyptr);
+ qdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
case SIR_HAL_P2P_NOA_START_IND:
session_entry = &mac_ctx->lim.gpSession[0];
lim_log(mac_ctx, LOG1, "LIM received NOA start %x", msg->type);
@@ -1853,10 +1704,7 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
lim_handle_delete_bss_rsp(mac_ctx, msg);
break;
case WMA_CSA_OFFLOAD_EVENT:
- lim_handle_hw_mode_change_on_csa_event(mac_ctx, msg);
- break;
- case SIR_LIM_CSA_POST_HW_MODE_CHANGE:
- lim_handle_csa_event_post_dbs_downgrade(mac_ctx, msg);
+ lim_handle_csa_offload_msg(mac_ctx, msg);
break;
case WMA_SET_BSSKEY_RSP:
case WMA_SET_STA_BCASTKEY_RSP:
@@ -2046,17 +1894,17 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
msg->bodyptr = NULL;
break;
#endif
- case SIR_HAL_SOC_SET_HW_MODE_RESP:
+ case SIR_HAL_PDEV_SET_HW_MODE_RESP:
lim_process_set_hw_mode_resp(mac_ctx, msg->bodyptr);
qdf_mem_free((void *)msg->bodyptr);
msg->bodyptr = NULL;
break;
- case SIR_HAL_SOC_HW_MODE_TRANS_IND:
+ case SIR_HAL_PDEV_HW_MODE_TRANS_IND:
lim_process_hw_mode_trans_ind(mac_ctx, msg->bodyptr);
qdf_mem_free((void *)msg->bodyptr);
msg->bodyptr = NULL;
break;
- case SIR_HAL_SOC_DUAL_MAC_CFG_RESP:
+ case SIR_HAL_PDEV_MAC_CFG_RESP:
lim_process_dual_mac_cfg_resp(mac_ctx, msg->bodyptr);
qdf_mem_free((void *)msg->bodyptr);
msg->bodyptr = NULL;
diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
index d57a1ca3735e..897f3621a52e 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
@@ -315,7 +315,6 @@ void lim_set_dfs_channel_list(tpAniSirGlobal mac_ctx, uint8_t chan_num,
dfs_ch_list->timeStamp[chan_num] =
qdf_mc_timer_get_system_time();
} else {
- lim_log(mac_ctx, LOG1, FL("Channel %d is Active"), chan_num);
return;
}
@@ -2309,7 +2308,6 @@ static void lim_process_periodic_probe_req_timer(tpAniSirGlobal mac_ctx)
}
mlm_scan_req = mac_ctx->lim.gpLimMlmScanReq;
- lim_log(mac_ctx, LOG1, FL("Scanning : Periodic scanning"));
mac_ctx->lim.probeCounter++;
/* Periodic channel timer timed out to send probe request. */
channel_num = lim_get_current_scan_channel(mac_ctx);
diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
index 4659053ecb90..c25da0223394 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
@@ -3207,6 +3207,7 @@ void lim_process_switch_channel_rsp(tpAniSirGlobal pMac, void *body)
* the policy manager connection table needs to be updated.
*/
cds_update_connection_info(psessionEntry->smeSessionId);
+ cds_set_do_hw_mode_change_flag(true);
}
break;
default:
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 8de45fe8734f..7e34ab80affe 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -165,7 +165,7 @@ static QDF_STATUS lim_process_set_hw_mode(tpAniSirGlobal mac, uint32_t *msg)
/* Other parameters are not needed for WMA */
cds_message.bodyptr = req_msg;
- cds_message.type = SIR_HAL_SOC_SET_HW_MODE;
+ cds_message.type = SIR_HAL_PDEV_SET_HW_MODE;
lim_log(mac, LOG1, FL("Posting SIR_HAL_SOC_SET_HW_MOD to WMA"));
status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
@@ -238,10 +238,10 @@ static QDF_STATUS lim_process_set_dual_mac_cfg_req(tpAniSirGlobal mac,
/* Other parameters are not needed for WMA */
cds_message.bodyptr = req_msg;
- cds_message.type = SIR_HAL_SOC_DUAL_MAC_CFG_REQ;
+ cds_message.type = SIR_HAL_PDEV_DUAL_MAC_CFG_REQ;
lim_log(mac, LOG1,
- FL("Post SIR_HAL_SOC_DUAL_MAC_CFG_REQ to WMA: %x %x"),
+ FL("Post SIR_HAL_PDEV_DUAL_MAC_CFG_REQ to WMA: %x %x"),
req_msg->scan_config, req_msg->fw_mode_config);
status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
if (!QDF_IS_STATUS_SUCCESS(status)) {
@@ -1298,6 +1298,8 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
pScanOffloadReq->minChannelTime = pScanReq->minChannelTime;
pScanOffloadReq->maxChannelTime = pScanReq->maxChannelTime;
pScanOffloadReq->restTime = pScanReq->restTime;
+ pScanOffloadReq->min_rest_time = pScanReq->min_rest_time;
+ pScanOffloadReq->idle_time = pScanReq->idle_time;
/* for normal scan, the value for p2pScanType should be 0
always */
diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c
index 5950dd373704..9016fbf2c412 100644
--- a/core/mac/src/pe/lim/lim_process_tdls.c
+++ b/core/mac/src/pe/lim/lim_process_tdls.c
@@ -2757,6 +2757,10 @@ tSirRetStatus lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal mac_ctx,
goto lim_tdls_send_mgmt_error;
}
+ cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS,
+ SIR_MAC_ACTION_TX, SIR_MAC_MGMT_ACTION,
+ send_req->reqType, send_req->peer_mac.bytes);
+
switch (send_req->reqType) {
case SIR_MAC_TDLS_DIS_REQ:
lim_log(mac_ctx, LOG1, FL("Transmit Discovery Request Frame"));
diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.c b/core/mac/src/pe/lim/lim_prop_exts_utils.c
index 93f820141d72..869706e327f1 100644
--- a/core/mac/src/pe/lim/lim_prop_exts_utils.c
+++ b/core/mac/src/pe/lim/lim_prop_exts_utils.c
@@ -123,8 +123,6 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
beacon_struct->VHTOperation.present &&
session->vhtCapability) {
session->vhtCapabilityPresentInBeacon = 1;
- session->vhtTxChannelWidthSet =
- beacon_struct->VHTOperation.chanWidth;
if (((beacon_struct->Vendor1IEPresent &&
beacon_struct->vendor2_ie.present &&
beacon_struct->Vendor3IEPresent)) &&
@@ -217,6 +215,9 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
if (beacon_struct->countryInfoPresent)
session->country_info_present = true;
}
+ /* Check if Extended caps are present in probe resp or not */
+ if (beacon_struct->ext_cap.present)
+ session->is_ext_caps_present = true;
qdf_mem_free(beacon_struct);
return;
} /****** end lim_extract_ap_capability() ******/
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
index 757ffe9d827c..ef138b90b7d6 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -1207,6 +1207,15 @@ lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
pe_session);
}
+ lim_log(mac_ctx, LOG1,
+ FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"),
+ frm.HTCaps.supportedChannelWidthSet,
+ frm.HTCaps.mimoPowerSave,
+ frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz,
+ frm.HTCaps.shortGI40MHz,
+ frm.HTCaps.dsssCckMode40MHz,
+ frm.HTCaps.maxRxAMPDUFactor);
+
if (sta->mlmStaContext.vhtCapability &&
pe_session->vhtCapability) {
lim_log(mac_ctx, LOG1,
@@ -1614,7 +1623,7 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
- if (add_ie_len) {
+ if (add_ie_len && pe_session->is_ext_caps_present) {
qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
0);
sir_status = lim_strip_extcap_update_struct(mac_ctx,
@@ -1642,7 +1651,8 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
}
}
} else {
- lim_log(mac_ctx, LOG1, FL("No additional IE for Assoc Req"));
+ lim_log(mac_ctx, LOG1,
+ FL("No addn IE or peer dosen't support addnIE for Assoc Req"));
extr_ext_flag = false;
}
@@ -1761,6 +1771,15 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request"));
populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
}
+ lim_log(mac_ctx, LOG1,
+ FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"),
+ frm->HTCaps.supportedChannelWidthSet,
+ frm->HTCaps.mimoPowerSave,
+ frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
+ frm->HTCaps.shortGI40MHz,
+ frm->HTCaps.dsssCckMode40MHz,
+ frm->HTCaps.maxRxAMPDUFactor);
+
if (pe_session->vhtCapability &&
pe_session->vhtCapabilityPresentInBeacon) {
lim_log(mac_ctx, LOG1, FL("Populate VHT IEs in Assoc Request"));
@@ -1782,7 +1801,9 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
&frm->vendor2_ie.VHTCaps);
vht_enabled = true;
}
- populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm->ExtCap, pe_session);
+ if (pe_session->is_ext_caps_present)
+ populate_dot11f_ext_cap(mac_ctx, vht_enabled,
+ &frm->ExtCap, pe_session);
if (pe_session->pLimJoinReq->is11Rconnection) {
tSirBssDescription *bssdescr;
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index 50719daca663..d61aeb308648 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -353,8 +353,6 @@ static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
ht_profile->htCapability = session_entry->htCapability;
ht_profile->vhtCapability =
session_entry->vhtCapability;
- ht_profile->vhtTxChannelWidthSet =
- session_entry->vhtTxChannelWidthSet;
ht_profile->apCenterChan = session_entry->ch_center_freq_seg0;
ht_profile->apChanWidth = session_entry->ch_width;
}
@@ -648,8 +646,6 @@ lim_send_sme_start_bss_rsp(tpAniSirGlobal pMac,
psessionEntry->htCapability;
pSirSmeRsp->HTProfile.vhtCapability =
psessionEntry->vhtCapability;
- pSirSmeRsp->HTProfile.vhtTxChannelWidthSet =
- psessionEntry->vhtTxChannelWidthSet;
pSirSmeRsp->HTProfile.apCenterChan =
psessionEntry->ch_center_freq_seg0;
pSirSmeRsp->HTProfile.apChanWidth =
@@ -704,9 +700,6 @@ lim_send_sme_scan_rsp(tpAniSirGlobal pMac, tSirResultCodes resultCode,
uint8_t smesessionId, uint16_t smetranscationId,
uint32_t scan_id)
{
- lim_log(pMac, LOG1,
- FL("Sending message SME_SCAN_RSP reasonCode %s scanId %d"),
- lim_result_code_str(resultCode), scan_id);
lim_post_sme_scan_rsp_message(pMac, resultCode, smesessionId,
smetranscationId, scan_id);
}
diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c
index 1aa2a6080bf3..8f1a8c139833 100644
--- a/core/mac/src/pe/lim/lim_session.c
+++ b/core/mac/src/pe/lim/lim_session.c
@@ -295,6 +295,8 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId,
session_ptr->gLimNumOfCurrentSTAs = 0;
/* Copy the BSSID to the session table */
sir_copy_mac_addr(session_ptr->bssId, bssid);
+ if (bssType == eSIR_MONITOR_MODE)
+ sir_copy_mac_addr(pMac->lim.gpSession[i].selfMacAddr, bssid);
session_ptr->valid = true;
/* Intialize the SME and MLM states to IDLE */
session_ptr->limMlmState = eLIM_MLM_IDLE_STATE;
@@ -355,6 +357,10 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId,
}
if (eSIR_INFRASTRUCTURE_MODE == bssType)
lim_ft_open(pMac, &pMac->lim.gpSession[i]);
+
+ if (eSIR_MONITOR_MODE == bssType)
+ lim_ft_open(pMac, &pMac->lim.gpSession[i]);
+
if (eSIR_INFRA_AP_MODE == bssType) {
session_ptr->old_protection_state = 0;
session_ptr->mac_ctx = (void *)pMac;
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index 45265686cd83..3dbf1ff563e0 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -868,6 +868,10 @@ uint8_t lim_write_deferred_msg_q(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg)
FL("queue->MsgQ full Msg:%d Msgs Failed:%d"),
lim_msg->type,
++mac_ctx->lim.deferredMsgCnt);
+ cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_QUEUE_FULL,
+ true, false);
} else {
mac_ctx->lim.deferredMsgCnt++;
}
diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
index db836f05c46f..99ee02af2fd1 100644
--- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
+++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
@@ -527,8 +527,8 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg)
CASE_RETURN_STRING(SIR_HAL_START_STOP_LOGGING);
CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW);
CASE_RETURN_STRING(SIR_HAL_PDEV_SET_PCL_TO_FW);
- CASE_RETURN_STRING(SIR_HAL_SOC_SET_HW_MODE);
- CASE_RETURN_STRING(SIR_HAL_SOC_DUAL_MAC_CFG_REQ);
+ CASE_RETURN_STRING(SIR_HAL_PDEV_SET_HW_MODE);
+ CASE_RETURN_STRING(SIR_HAL_PDEV_DUAL_MAC_CFG_REQ);
CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND);
CASE_RETURN_STRING(WMA_TIMER_TRAFFIC_STATS_IND);
#ifdef WLAN_FEATURE_11W
diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
index db860844cef0..8063d79d0c31 100644
--- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c
+++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
@@ -304,7 +304,7 @@ populate_dot11_supp_operating_classes(tpAniSirGlobal mac_ptr,
{
uint8_t ch_bandwidth;
- if (session_entry->vhtTxChannelWidthSet == eHT_CHANNEL_WIDTH_80MHZ) {
+ if (session_entry->ch_width == CH_WIDTH_80MHZ) {
ch_bandwidth = BW80;
} else {
switch (session_entry->htSecondaryChannelOffset) {
@@ -747,13 +747,6 @@ populate_dot11f_ht_caps(tpAniSirGlobal pMac,
pDot11f->shortGI40MHz = 0;
}
- dot11f_log(pMac, LOG2,
- FL
- ("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d\n"),
- pDot11f->supportedChannelWidthSet, pDot11f->mimoPowerSave,
- pDot11f->greenField, pDot11f->shortGI20MHz,
- pDot11f->shortGI40MHz, pDot11f->dsssCckMode40MHz);
-
CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_AMPDU_PARAMS, nCfgValue);
nCfgValue8 = (uint8_t) nCfgValue;
@@ -763,8 +756,6 @@ populate_dot11f_ht_caps(tpAniSirGlobal pMac,
pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
pDot11f->reserved1 = pHTParametersInfo->reserved;
- dot11f_log(pMac, LOG2, FL("AMPDU Param: %x\n"), nCfgValue);
-
CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_MCS_SET,
pDot11f->supportedMCSSet, nCfgLen,
SIZE_OF_SUPPORTED_MCS_SET);
@@ -977,8 +968,7 @@ populate_dot11f_vht_caps(tpAniSirGlobal pMac,
nCfgValue);
pDot11f->ldpcCodingCap = (nCfgValue & 0x0001);
- if (psessionEntry->vhtTxChannelWidthSet <
- WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
+ if (psessionEntry->ch_width < CH_WIDTH_80MHZ) {
pDot11f->shortGI80MHz = 0;
} else {
nCfgValue = 0;
@@ -989,8 +979,7 @@ populate_dot11f_vht_caps(tpAniSirGlobal pMac,
pDot11f->shortGI80MHz = (nCfgValue & 0x0001);
}
- if (psessionEntry->vhtTxChannelWidthSet <
- WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {
+ if (psessionEntry->ch_width < CH_WIDTH_160MHZ) {
pDot11f->shortGI160and80plus80MHz = 0;
} else {
nCfgValue = 0;
@@ -3658,6 +3647,11 @@ sir_parse_beacon_ie(tpAniSirGlobal pMac,
&pBies->vendor2_ie.VHTOperation,
sizeof(tDot11fIEVHTOperation));
}
+ if (pBies->ExtCap.present) {
+ pBeaconStruct->ext_cap.present = 1;
+ qdf_mem_copy(&pBeaconStruct->ext_cap, &pBies->ExtCap,
+ sizeof(tDot11fIEExtCap));
+ }
qdf_mem_free(pBies);
return eSIR_SUCCESS;
} /* End sir_parse_beacon_ie. */
diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h
new file mode 100644
index 000000000000..53f25b4394a1
--- /dev/null
+++ b/core/pld/inc/pld_common.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __PLD_COMMON_H__
+#define __PLD_COMMON_H__
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+
+/**
+ * enum pld_bus_type - bus type
+ * @PLD_BUS_TYPE_NONE: invalid bus type, only return in error cases
+ * @PLD_BUS_TYPE_PCIE: PCIE bus
+ * @PLD_BUS_TYPE_SNOC: SNOC bus
+ */
+enum pld_bus_type {
+ PLD_BUS_TYPE_NONE = -1,
+ PLD_BUS_TYPE_PCIE = 0,
+ PLD_BUS_TYPE_SNOC
+};
+
+#define PLD_MAX_FIRMWARE_SIZE (1 * 1024 * 1024)
+
+/**
+ * enum pld_bus_width_type - bus bandwith
+ * @PLD_BUS_WIDTH_NONE: don't vote for bus bandwidth
+ * @PLD_BUS_WIDTH_LOW: vote for low bus bandwidth
+ * @PLD_BUS_WIDTH_MEDIUM: vote for medium bus bandwidth
+ * @PLD_BUS_WIDTH_HIGH: vote for high bus bandwidth
+ */
+enum pld_bus_width_type {
+ PLD_BUS_WIDTH_NONE,
+ PLD_BUS_WIDTH_LOW,
+ PLD_BUS_WIDTH_MEDIUM,
+ PLD_BUS_WIDTH_HIGH
+};
+
+#define PLD_MAX_FILE_NAME 20
+
+/**
+ * struct pld_fw_file - WLAN FW file names
+ * @image_file: WLAN FW image file
+ * @board_data: WLAN FW board data file
+ * @otp_data: WLAN FW OTP file
+ * @utf_file: WLAN FW UTF file
+ * @utf_board_data: WLAN FW UTF board data file
+ * @epping_file: WLAN FW EPPING mode file
+ * @evicted_data: WLAN FW evicted file
+ *
+ * pld_fw_files is used to store WLAN FW file names
+ */
+struct pld_fw_files {
+ char image_file[PLD_MAX_FILE_NAME];
+ char board_data[PLD_MAX_FILE_NAME];
+ char otp_data[PLD_MAX_FILE_NAME];
+ char utf_file[PLD_MAX_FILE_NAME];
+ char utf_board_data[PLD_MAX_FILE_NAME];
+ char epping_file[PLD_MAX_FILE_NAME];
+ char evicted_data[PLD_MAX_FILE_NAME];
+};
+
+/**
+ * struct pld_image_desc_info - FW image description
+ * @fw_addr: FW image address
+ * @fw_size: FW image size
+ * @bdata_addr: FW board data address
+ * @bdata_size: FW board data size
+ *
+ * pld_image_desc_info is used to store FW image description
+ * information.
+ */
+struct pld_image_desc_info {
+ dma_addr_t fw_addr;
+ u32 fw_size;
+ dma_addr_t bdata_addr;
+ u32 bdata_size;
+};
+
+#define PLD_CODESWAP_MAX_CODESEGS 16
+
+/**
+ * struct pld_codeswap_codeseg_info - code swap segment information
+ * @codeseg_total_bytes: total bytes of segments
+ * @num_codesegs: number of code segments
+ * @codeseg_size: code segment size
+ * @codeseg_size_log2: log2 of code segment size
+ * @codeseg_busaddr: array of addresses of each code segment
+ *
+ * pld_codeswap_codeseg_info is used to store code swap segment
+ * information.
+ */
+struct pld_codeswap_codeseg_info {
+ u32 codeseg_total_bytes;
+ u32 num_codesegs;
+ u32 codeseg_size;
+ u32 codeseg_size_log2;
+ void *codeseg_busaddr[PLD_CODESWAP_MAX_CODESEGS];
+};
+
+/**
+ * enum pld_platform_cap_flag - platform capability flag
+ * @PLD_HAS_EXTERNAL_SWREG: has external regulator
+ * @PLD_HAS_UART_ACCESS: has UART access
+ */
+enum pld_platform_cap_flag {
+ PLD_HAS_EXTERNAL_SWREG = 0x01,
+ PLD_HAS_UART_ACCESS = 0x02,
+};
+
+/**
+ * struct pld_platform_cap - platform capabilities
+ * @cap_flag: capabilities flag
+ *
+ * pld_platform_cap provides platform capabilities which are
+ * extracted from DTS.
+ */
+struct pld_platform_cap {
+ u32 cap_flag;
+};
+
+/**
+ * enum pld_driver_status - WLAN driver status
+ * @PLD_UNINITIALIZED: driver is uninitialized
+ * @PLD_INITIALIZED: driver is initialized
+ * @PLD_LOAD_UNLOADL: driver is in load-unload status
+ */
+enum pld_driver_status {
+ PLD_UNINITIALIZED,
+ PLD_INITIALIZED,
+ PLD_LOAD_UNLOAD
+};
+
+/**
+ * struct pld_ce_tgt_pipe_cfg - copy engine target pipe configuration
+ * @pipe_num: pipe number
+ * @pipe_dir: pipe direction
+ * @nentries: number of entries
+ * @nbytes_max: max number of bytes
+ * @flags: flags
+ * @reserved: reserved
+ *
+ * pld_ce_tgt_pipe_cfg is used to store copy engine target pipe
+ * configuration.
+ */
+struct pld_ce_tgt_pipe_cfg {
+ u32 pipe_num;
+ u32 pipe_dir;
+ u32 nentries;
+ u32 nbytes_max;
+ u32 flags;
+ u32 reserved;
+};
+
+/**
+ * struct pld_ce_svc_pipe_cfg - copy engine service pipe configuration
+ * @service_id: service ID
+ * @pipe_dir: pipe direction
+ * @pipe_num: pipe number
+ *
+ * pld_ce_svc_pipe_cfg is used to store copy engine service pipe
+ * configuration.
+ */
+struct pld_ce_svc_pipe_cfg {
+ u32 service_id;
+ u32 pipe_dir;
+ u32 pipe_num;
+};
+
+/**
+ * struct pld_shadow_reg_cfg - shadow register configuration
+ * @ce_id: copy engine ID
+ * @reg_offset: register offset
+ *
+ * pld_shadow_reg_cfg is used to store shadow register configuration.
+ */
+struct pld_shadow_reg_cfg {
+ u16 ce_id;
+ u16 reg_offset;
+};
+
+/**
+ * struct pld_wlan_enable_cfg - WLAN FW configuration
+ * @num_ce_tgt_cfg: number of CE target configuration
+ * @ce_tgt_cfg: CE target configuration
+ * @num_ce_svc_pipe_cfg: number of CE service configuration
+ * @ce_svc_cfg: CE service configuration
+ * @num_shadow_reg_cfg: number of shadow register configuration
+ * @shadow_reg_cfg: shadow register configuration
+ *
+ * pld_wlan_enable_cfg stores WLAN FW configurations. It will be
+ * passed to WLAN FW when WLAN host driver calls wlan_enable.
+ */
+struct pld_wlan_enable_cfg {
+ u32 num_ce_tgt_cfg;
+ struct pld_ce_tgt_pipe_cfg *ce_tgt_cfg;
+ u32 num_ce_svc_pipe_cfg;
+ struct pld_ce_svc_pipe_cfg *ce_svc_cfg;
+ u32 num_shadow_reg_cfg;
+ struct pld_shadow_reg_cfg *shadow_reg_cfg;
+};
+
+/**
+ * enum pld_driver_mode - WLAN host driver mode
+ * @PLD_MISSION: mission mode
+ * @PLD_FTM: FTM mode
+ * @PLD_EPPING: EPPING mode
+ * @PLD_WALTEST: WAL test mode, FW standalone test mode
+ * @PLD_OFF: OFF mode
+ */
+enum pld_driver_mode {
+ PLD_MISSION,
+ PLD_FTM,
+ PLD_EPPING,
+ PLD_WALTEST,
+ PLD_OFF
+};
+
+/**
+ * struct pld_soc_info - SOC information
+ * @v_addr: virtual address of preallocated memory
+ * @p_addr: physical address of preallcoated memory
+ * @version: version number
+ *
+ * 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;
+};
+
+/**
+ * struct pld_driver_ops - driver callback functions
+ * @probe: required operation, will be called when device is detected
+ * @remove: required operation, will be called when device is removed
+ * @shutdown: optional operation, will be called during SSR
+ * @reinit: optional operation, will be called during SSR
+ * @crash_shutdown: optional operation, will be called when a crash is
+ * detected
+ * @suspend: required operation, will be called for power management
+ * is enabled
+ * @resume: required operation, will be called for power management
+ * is enabled
+ * @modem_status: optional operation, will be called when platform driver
+ * sending modem power status to WLAN FW
+ * @runtime_suspend: optional operation, prepare the device for a condition
+ * in which it won't be able to communicate with the CPU(s)
+ * and RAM due to power management.
+ * @runtime_resume: optional operation, put the device into the fully
+ * active state in response to a wakeup event generated by
+ * hardware or at the request of software.
+ */
+struct pld_driver_ops {
+ int (*probe)(struct device *dev,
+ enum pld_bus_type bus_type,
+ void *bdev, void *id);
+ void (*remove)(struct device *dev,
+ enum pld_bus_type bus_type);
+ void (*shutdown)(struct device *dev,
+ enum pld_bus_type bus_type);
+ int (*reinit)(struct device *dev,
+ enum pld_bus_type bus_type,
+ void *bdev, void *id);
+ void (*crash_shutdown)(struct device *dev,
+ enum pld_bus_type bus_type);
+ int (*suspend)(struct device *dev,
+ enum pld_bus_type bus_type,
+ pm_message_t state);
+ int (*resume)(struct device *dev,
+ enum pld_bus_type bus_type);
+ void (*modem_status)(struct device *dev,
+ enum pld_bus_type bus_type,
+ int state);
+ int (*runtime_suspend)(struct device *dev,
+ enum pld_bus_type bus_type);
+ int (*runtime_resume)(struct device *dev,
+ enum pld_bus_type bus_type);
+};
+
+int pld_init(void);
+void pld_deinit(void);
+
+int pld_register_driver(struct pld_driver_ops *ops);
+void pld_unregister_driver(void);
+
+int pld_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+ enum pld_driver_mode mode, const char *host_version);
+int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode);
+int pld_set_fw_debug_mode(struct device *dev, bool enablefwlog);
+int pld_get_fw_files_for_target(struct device *dev,
+ struct pld_fw_files *pfw_files,
+ u32 target_type, u32 target_version);
+int pld_get_fw_image(struct device *dev,
+ struct pld_image_desc_info *image_desc_info);
+void pld_is_pci_link_down(struct device *dev);
+int pld_pcie_shadow_control(struct device *dev, bool enable);
+int pld_get_codeswap_struct(struct device *dev,
+ struct pld_codeswap_codeseg_info *swap_seg);
+int pld_set_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
+ u16 ch_count);
+int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
+ u16 *ch_count, u16 buf_len);
+int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len);
+int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len);
+int pld_wlan_pm_control(struct device *dev, bool vote);
+void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size);
+void pld_device_crashed(struct device *dev);
+void pld_device_self_recovery(struct device *dev);
+void pld_intr_notify_q6(struct device *dev);
+void pld_request_pm_qos(struct device *dev, u32 qos_val);
+void pld_remove_pm_qos(struct device *dev);
+int pld_request_bus_bandwidth(struct device *dev, int bandwidth);
+int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap);
+void pld_set_driver_status(struct device *dev, enum pld_driver_status status);
+int pld_get_bmi_setup(struct device *dev);
+int pld_get_sha_hash(struct device *dev, const u8 *data,
+ u32 data_len, u8 *hash_idx, u8 *out);
+void *pld_get_fw_ptr(struct device *dev);
+int pld_auto_suspend(struct device *dev);
+int pld_auto_resume(struct device *dev);
+
+int pld_ce_request_irq(struct device *dev, unsigned int ce_id,
+ irqreturn_t (*handler)(int, void *),
+ unsigned long flags, const char *name, void *ctx);
+int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx);
+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);
+void pld_lock_pm_sem(struct device *dev);
+void pld_release_pm_sem(struct device *dev);
+
+#endif
diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c
new file mode 100644
index 000000000000..00d0e79368fc
--- /dev/null
+++ b/core/pld/src/pld_common.c
@@ -0,0 +1,1157 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#define pr_fmt(fmt) "wlan_pld:%s:%d:: " fmt, __func__, __LINE__
+
+#include <linux/printk.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+
+#ifdef CONFIG_CNSS
+#include <net/cnss.h>
+#endif
+#ifdef CONFIG_ICNSS
+#include <soc/qcom/icnss.h>
+#endif
+
+#include "pld_pcie.h"
+#include "pld_snoc.h"
+#include "pld_common.h"
+#include "pld_internal.h"
+
+#define PLD_PCIE_REGISTERED BIT(0)
+#define PLD_SNOC_REGISTERED BIT(1)
+
+static struct pld_context *pld_ctx;
+
+/**
+ * pld_init() - Initialize PLD module
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_init(void)
+{
+ struct pld_context *pld_context;
+
+ pld_context = kzalloc(sizeof(*pld_context), GFP_KERNEL);
+ if (!pld_context)
+ return -ENOMEM;
+
+ spin_lock_init(&pld_context->pld_lock);
+
+ INIT_LIST_HEAD(&pld_context->dev_list);
+
+ pld_ctx = pld_context;
+
+ return 0;
+}
+
+/**
+ * pld_deinit() - Uninitialize PLD module
+ *
+ * Return: void
+ */
+void pld_deinit(void)
+{
+ struct dev_node *dev_node;
+ struct pld_context *pld_context;
+ unsigned long flags;
+
+ pld_context = pld_ctx;
+ if (!pld_context) {
+ pld_ctx = NULL;
+ return;
+ }
+
+ spin_lock_irqsave(&pld_context->pld_lock, flags);
+ while (!list_empty(&pld_context->dev_list)) {
+ dev_node = list_first_entry(&pld_context->dev_list,
+ struct dev_node, list);
+ list_del(&dev_node->list);
+ kfree(dev_node);
+ }
+ spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+ kfree(pld_context);
+
+ pld_ctx = NULL;
+}
+
+/**
+ * pld_get_global_context() - Get global context of PLD
+ *
+ * Return: PLD global context
+ */
+struct pld_context *pld_get_global_context(void)
+{
+ return pld_ctx;
+}
+
+/**
+ * pld_get_bus_type() - Bus type of the device
+ * @dev: device
+ *
+ * Return: PLD bus type
+ */
+enum pld_bus_type pld_get_bus_type(struct device *dev)
+{
+ struct pld_context *pld_context;
+ struct dev_node *dev_node;
+ unsigned long flags;
+
+ pld_context = pld_get_global_context();
+
+ if (dev == NULL || pld_context == NULL) {
+ pr_err("Invalid info: dev %p, context %p\n",
+ dev, pld_context);
+ return PLD_BUS_TYPE_NONE;
+ }
+
+ spin_lock_irqsave(&pld_context->pld_lock, flags);
+ list_for_each_entry(dev_node, &pld_context->dev_list, list) {
+ if (dev_node->dev == dev) {
+ spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+ return dev_node->bus_type;
+ }
+ }
+ spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+ return PLD_BUS_TYPE_NONE;
+}
+
+/**
+ * pld_register_driver() - Register driver to kernel
+ * @ops: Callback functions that will be registered to kernel
+ *
+ * This function should be called when other modules want to
+ * register platform driver callback functions to kernel. The
+ * probe() is expected to be called after registration if the
+ * device is online.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_register_driver(struct pld_driver_ops *ops)
+{
+ int ret = 0;
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+
+ if (pld_context == NULL) {
+ pr_err("global context is NULL\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (pld_context->ops) {
+ pr_err("driver already registered\n");
+ ret = -EEXIST;
+ goto out;
+ }
+
+ if (!ops || !ops->probe || !ops->remove ||
+ !ops->suspend || !ops->resume) {
+ pr_err("Required callback functions are missing\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pld_context->ops = ops;
+
+ if (0 == pld_pcie_register_driver())
+ pld_context->pld_driver_state |= PLD_PCIE_REGISTERED;
+ if (0 == pld_snoc_register_driver())
+ pld_context->pld_driver_state |= PLD_SNOC_REGISTERED;
+
+ if (0 == pld_context->pld_driver_state) {
+ pr_err("All driver falied to register\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+/**
+ * pld_unregister_driver() - Unregister driver to kernel
+ *
+ * This function should be called when other modules want to
+ * unregister callback functions from kernel. The remove() is
+ * expected to be called after registration.
+ *
+ * Return: void
+ */
+void pld_unregister_driver(void)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+
+ if (pld_context == NULL) {
+ pr_err("global context is NULL\n");
+ return;
+ }
+
+ if (pld_context->ops == NULL) {
+ pr_err("driver not registered\n");
+ return;
+ }
+
+ pld_pcie_unregister_driver();
+ pld_snoc_unregister_driver();
+
+ pld_context->pld_driver_state = 0;
+
+ pld_context->ops = NULL;
+}
+
+/**
+ * pld_wlan_enable() - Enable WLAN
+ * @dev: device
+ * @config: WLAN configuration data
+ * @mode: WLAN mode
+ * @host_version: host software version
+ *
+ * This function enables WLAN FW. It passed WLAN configuration data,
+ * WLAN mode and host software version to FW.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+ enum pld_driver_mode mode, const char *host_version)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_wlan_enable(config, mode, host_version);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ ret = pld_snoc_wlan_enable(config, mode, host_version);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_wlan_disable() - Disable WLAN
+ * @dev: device
+ * @mode: WLAN mode
+ *
+ * This function disables WLAN FW. It passes WLAN mode to FW.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_wlan_disable(mode);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ ret = pld_snoc_wlan_disable(mode);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_set_fw_debug_mode() - Set FW debug mode
+ * @dev: device
+ * @enablefwlog: 0 for QXDM, 1 for WMI
+ *
+ * Switch Fw debug mode between DIAG logging and WMI logging.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_set_fw_debug_mode(struct device *dev, bool enablefwlog)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_set_fw_debug_mode(enablefwlog);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_get_fw_files_for_target() - Get FW file names
+ * @dev: device
+ * @pfw_files: buffer for FW file names
+ * @target_type: target type
+ * @target_version: target version
+ *
+ * Return target specific FW file names to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_get_fw_files_for_target(struct device *dev,
+ struct pld_fw_files *pfw_files,
+ u32 target_type, u32 target_version)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_get_fw_files_for_target(pfw_files,
+ target_type, target_version);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_get_fw_image() - Get FW image descriptor
+ * @dev: device
+ * @image_desc_info: buffer for image descriptor
+ *
+ * Return FW image descriptor to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_get_fw_image(struct device *dev,
+ struct pld_image_desc_info *image_desc_info)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_get_fw_image(image_desc_info);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_is_pci_link_down() - Notification for pci link down event
+ * @dev: device
+ *
+ * Notify platform that pci link is down.
+ *
+ * Return: void
+ */
+void pld_is_pci_link_down(struct device *dev)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ cnss_wlan_pci_link_down();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_pcie_shadow_control() - Control pci shadow registers
+ * @dev: device
+ * @enable: 0 for disable, 1 for enable
+ *
+ * This function is for suspend/resume. It can control if we
+ * use pci shadow registers (for saving config space) or not.
+ * During suspend we disable it to avoid config space corruption.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_pcie_shadow_control(struct device *dev, bool enable)
+{
+ int ret = 0;
+
+ /* cnss_shadow_control is not supported on BF64.0.3 kernel yet
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_shadow_control(enable);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ */
+ return ret;
+}
+
+/**
+ * pld_get_codeswap_struct() - Get codeswap structure
+ * @dev: device
+ * @swap_seg: buffer to codeswap information
+ *
+ * Return codeswap structure information to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_get_codeswap_struct(struct device *dev,
+ struct pld_codeswap_codeseg_info *swap_seg)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_get_codeswap_struct(swap_seg);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_set_wlan_unsafe_channel() - Set unsafe channel
+ * @dev: device
+ * @unsafe_ch_list: unsafe channel list
+ * @ch_count: number of channel
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_set_wlan_unsafe_channel(struct device *dev,
+ u16 *unsafe_ch_list, u16 ch_count)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_set_wlan_unsafe_channel(unsafe_ch_list,
+ ch_count);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_get_wlan_unsafe_channel() - Get unsafe channel
+ * @dev: device
+ * @unsafe_ch_list: buffer to unsafe channel list
+ * @ch_count: number of channel
+ * @buf_len: buffer length
+ *
+ * Return WLAN unsafe channel to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
+ u16 *ch_count, u16 buf_len)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_get_wlan_unsafe_channel(unsafe_ch_list,
+ ch_count, buf_len);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_wlan_set_dfs_nol() - Set DFS info
+ * @dev: device
+ * @info: DFS info
+ * @info_len: info length
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_wlan_set_dfs_nol(info, info_len);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_wlan_get_dfs_nol() - Get DFS info
+ * @dev: device
+ * @info: buffer to DFS info
+ * @info_len: info length
+ *
+ * Return DFS info to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_wlan_get_dfs_nol(info, info_len);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_wlan_pm_control() - WLAN PM control on PCIE
+ * @dev: device
+ * @vote: 0 for enable PCIE PC, 1 for disable PCIE PC
+ *
+ * This is for PCIE power collaps control during suspend/resume.
+ * When PCIE power collaps is disabled, WLAN FW can access memory
+ * through PCIE when system is suspended.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_wlan_pm_control(struct device *dev, bool vote)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_wlan_pm_control(vote);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_get_virt_ramdump_mem() - Get virtual ramdump memory
+ * @dev: device
+ * @size: buffer to virtual memory size
+ *
+ * Return: virtual ramdump memory address
+ */
+void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
+{
+ void *mem = NULL;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ mem = cnss_get_virt_ramdump_mem(size);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+
+ return mem;
+}
+
+/**
+ * pld_device_crashed() - Notification for device crash event
+ * @dev: device
+ *
+ * Notify subsystem a device crashed event. A subsystem restart
+ * is expected to happen after calling this function.
+ *
+ * Return: void
+ */
+void pld_device_crashed(struct device *dev)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ cnss_device_crashed();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_device_self_recovery() - Device self recovery
+ * @dev: device
+ *
+ * Return: void
+ */
+void pld_device_self_recovery(struct device *dev)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ cnss_device_self_recovery();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_intr_notify_q6() - Notify Q6 FW interrupts
+ * @dev: device
+ *
+ * Notify Q6 that a FW interrupt is triggered.
+ *
+ * Return: void
+ */
+void pld_intr_notify_q6(struct device *dev)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ cnss_intr_notify_q6();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_request_pm_qos() - Request system PM
+ * @dev: device
+ * @qos_val: request value
+ *
+ * It votes for the value of aggregate QoS expectations.
+ *
+ * Return: void
+ */
+void pld_request_pm_qos(struct device *dev, u32 qos_val)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ cnss_request_pm_qos(qos_val);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_remove_pm_qos() - Remove system PM
+ * @dev: device
+ *
+ * Remove the vote request for Qos expectations.
+ *
+ * Return: void
+ */
+void pld_remove_pm_qos(struct device *dev)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ cnss_remove_pm_qos();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_request_bus_bandwidth() - Request bus bandwidth
+ * @dev: device
+ * @bandwidth: bus bandwidth
+ *
+ * Votes for HIGH/MEDIUM/LOW bus bandwidth.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_request_bus_bandwidth(struct device *dev, int bandwidth)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_request_bus_bandwidth(bandwidth);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_get_platform_cap() - Get platform capabilities
+ * @dev: device
+ * @cap: buffer to the capabilities
+ *
+ * Return capabilities to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_get_platform_cap(cap);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_set_driver_status() - Set driver status
+ * @dev: device
+ * @status: driver status
+ *
+ * Return: void
+ */
+void pld_set_driver_status(struct device *dev, enum pld_driver_status status)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ pld_pcie_set_driver_status(status);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_get_bmi_setup() - Get BMI setup
+ * @dev: device
+ *
+ * BMI read/write test should be run if BMI test is enabled.
+ *
+ * Return: BMI test setup
+ */
+int pld_get_bmi_setup(struct device *dev)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_get_bmi_setup();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_get_sha_hash() - Get sha hash number
+ * @dev: device
+ * @data: input data
+ * @data_len: data length
+ * @hash_idx: hash index
+ * @out: output buffer
+ *
+ * Return computed hash to the out buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_get_sha_hash(struct device *dev, const u8 *data,
+ u32 data_len, u8 *hash_idx, u8 *out)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_get_sha_hash(data, data_len,
+ hash_idx, out);
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_get_fw_ptr() - Get secure FW memory address
+ * @dev: device
+ *
+ * Return: secure memory address
+ */
+void *pld_get_fw_ptr(struct device *dev)
+{
+ void *ptr = NULL;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ptr = cnss_get_fw_ptr();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+
+ return ptr;
+}
+
+/**
+ * pld_auto_suspend() - Auto suspend
+ * @dev: device
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_auto_suspend(struct device *dev)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_auto_suspend();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_auto_resume() - Auto resume
+ * @dev: device
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_auto_resume(struct device *dev)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ ret = cnss_auto_resume();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_ce_request_irq() - Register IRQ for CE
+ * @dev: device
+ * @ce_id: CE number
+ * @handler: IRQ callback function
+ * @flags: IRQ flags
+ * @name: IRQ name
+ * @ctx: IRQ context
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_ce_request_irq(struct device *dev, unsigned int ce_id,
+ irqreturn_t (*handler)(int, void *),
+ unsigned long flags, const char *name, void *ctx)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_SNOC:
+ ret = icnss_ce_request_irq(ce_id, handler, flags, name, ctx);
+ break;
+ case PLD_BUS_TYPE_PCIE:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_ce_free_irq() - Free IRQ for CE
+ * @dev: device
+ * @ce_id: CE number
+ * @ctx: IRQ context
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_SNOC:
+ ret = icnss_ce_free_irq(ce_id, ctx);
+ break;
+ case PLD_BUS_TYPE_PCIE:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_enable_irq() - Enable IRQ for CE
+ * @dev: device
+ * @ce_id: CE number
+ *
+ * Return: void
+ */
+void pld_enable_irq(struct device *dev, unsigned int ce_id)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_SNOC:
+ icnss_enable_irq(ce_id);
+ break;
+ case PLD_BUS_TYPE_PCIE:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_disable_irq() - Disable IRQ for CE
+ * @dev: device
+ * @ce_id: CE number
+ *
+ * Return: void
+ */
+void pld_disable_irq(struct device *dev, unsigned int ce_id)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_SNOC:
+ icnss_disable_irq(ce_id);
+ break;
+ case PLD_BUS_TYPE_PCIE:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_get_soc_info() - Get SOC information
+ * @dev: device
+ * @info: buffer to SOC information
+ *
+ * Return SOC info to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_get_soc_info(struct device *dev, struct pld_soc_info *info)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_SNOC:
+ ret = pld_snoc_get_soc_info(info);
+ break;
+ case PLD_BUS_TYPE_PCIE:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_get_ce_id() - Get CE number for the provided IRQ
+ * @dev: device
+ * @irq: IRQ number
+ *
+ * Return: CE number
+ */
+int pld_get_ce_id(struct device *dev, int irq)
+{
+ int ret = 0;
+
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_SNOC:
+ ret = icnss_get_ce_id(irq);
+ break;
+ case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_get_ce_id(irq);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pld_lock_pm_sem() - Lock PM semaphore
+ * @dev: device
+ *
+ * Return: void
+ */
+void pld_lock_pm_sem(struct device *dev)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ cnss_lock_pm_sem();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
+
+/**
+ * pld_release_pm_sem() - Release PM semaphore
+ * @dev: device
+ *
+ * Return: void
+ */
+void pld_release_pm_sem(struct device *dev)
+{
+ switch (pld_get_bus_type(dev)) {
+ case PLD_BUS_TYPE_PCIE:
+ cnss_release_pm_sem();
+ break;
+ case PLD_BUS_TYPE_SNOC:
+ break;
+ default:
+ pr_err("Invalid device type\n");
+ break;
+ }
+}
diff --git a/core/pld/src/pld_internal.h b/core/pld/src/pld_internal.h
new file mode 100644
index 000000000000..3619848b6bbc
--- /dev/null
+++ b/core/pld/src/pld_internal.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __PLD_COMMON_I_H__
+#define __PLD_COMMON_I_H__
+
+struct dev_node {
+ struct device *dev;
+ struct list_head list;
+ enum pld_bus_type bus_type;
+};
+
+struct pld_context {
+ struct pld_driver_ops *ops;
+ spinlock_t pld_lock;
+ struct list_head dev_list;
+ uint32_t pld_driver_state;
+};
+
+struct pld_context *pld_get_global_context(void);
+
+#endif
diff --git a/core/pld/src/pld_pcie.c b/core/pld/src/pld_pcie.c
new file mode 100644
index 000000000000..ab3cbd1e52eb
--- /dev/null
+++ b/core/pld/src/pld_pcie.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_CNSS
+#include <net/cnss.h>
+#endif
+
+#include "pld_common.h"
+#include "pld_internal.h"
+
+#ifdef CONFIG_PCI
+
+#ifdef QCA_WIFI_3_0_ADRASTEA
+#define CE_COUNT_MAX 12
+#else
+#define CE_COUNT_MAX 8
+#endif
+
+/**
+ * pld_pcie_probe() - Probe function for PCIE platform driver
+ * @pdev: PCIE device
+ * @id: PCIE device ID table
+ *
+ * The probe function will be called when PCIE device provided
+ * in the ID table is detected.
+ *
+ * Return: int
+ */
+static int pld_pcie_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct pld_context *pld_context;
+ unsigned long flags;
+ struct dev_node *dev_node;
+ int ret = 0;
+
+ pld_context = pld_get_global_context();
+ if (!pld_context) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ dev_node = kzalloc(sizeof(*dev_node), GFP_KERNEL);
+ if (dev_node == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ dev_node->dev = &pdev->dev;
+ dev_node->bus_type = PLD_BUS_TYPE_PCIE;
+
+ spin_lock_irqsave(&pld_context->pld_lock, flags);
+ list_add_tail(&dev_node->list, &pld_context->dev_list);
+ spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+ return pld_context->ops->probe(&pdev->dev,
+ PLD_BUS_TYPE_PCIE, pdev, (void *)id);
+
+out:
+ return ret;
+}
+
+
+/**
+ * pld_pcie_remove() - Remove function for PCIE device
+ * @pdev: PCIE device
+ *
+ * The remove function will be called when PCIE device is disconnected
+ *
+ * Return: void
+ */
+static void pld_pcie_remove(struct pci_dev *pdev)
+{
+ struct pld_context *pld_context;
+ unsigned long flags;
+ struct dev_node *dev_node, *tmp;
+
+ pld_context = pld_get_global_context();
+
+ if (!pld_context)
+ return;
+
+ spin_lock_irqsave(&pld_context->pld_lock, flags);
+ list_for_each_entry_safe(dev_node, tmp, &pld_context->dev_list, list) {
+ if (dev_node->dev == &pdev->dev) {
+ list_del(&dev_node->list);
+ kfree(dev_node);
+ }
+ }
+ spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+ pld_context->ops->remove(&pdev->dev, PLD_BUS_TYPE_PCIE);
+}
+
+#ifdef CONFIG_CNSS
+/**
+ * pld_pcie_reinit() - SSR re-initialize function for PCIE device
+ * @pdev: PCIE device
+ * @id: PCIE device ID
+ *
+ * During subsystem restart(SSR), this function will be called to
+ * re-initialize PCIE device.
+ *
+ * Return: int
+ */
+static int pld_pcie_reinit(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->reinit)
+ return pld_context->ops->reinit(&pdev->dev,
+ PLD_BUS_TYPE_PCIE, pdev, (void *)id);
+
+ return -ENODEV;
+}
+
+/**
+ * pld_pcie_shutdown() - SSR shutdown function for PCIE device
+ * @pdev: PCIE device
+ *
+ * During SSR, this function will be called to shutdown PCIE device.
+ *
+ * Return: void
+ */
+static void pld_pcie_shutdown(struct pci_dev *pdev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->shutdown)
+ pld_context->ops->shutdown(&pdev->dev, PLD_BUS_TYPE_PCIE);
+}
+
+/**
+ * pld_pcie_crash_shutdown() - Crash shutdown function for PCIE device
+ * @pdev: PCIE device
+ *
+ * This function will be called when a crash is detected, it will shutdown
+ * the PCIE device.
+ *
+ * Return: void
+ */
+static void pld_pcie_crash_shutdown(struct pci_dev *pdev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->crash_shutdown)
+ pld_context->ops->crash_shutdown(&pdev->dev, PLD_BUS_TYPE_PCIE);
+}
+
+/**
+ * pld_pcie_notify_handler() - Modem state notification callback function
+ * @pdev: PCIE device
+ * @state: modem power state
+ *
+ * This function will be called when there's a modem power state change.
+ *
+ * Return: void
+ */
+static void pld_pcie_notify_handler(struct pci_dev *pdev, int state)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->modem_status)
+ pld_context->ops->modem_status(&pdev->dev,
+ PLD_BUS_TYPE_PCIE, state);
+}
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * pld_pcie_runtime_suspend() - PM runtime suspend
+ * @pdev: PCIE device
+ *
+ * PM runtime suspend callback function.
+ *
+ * Return: int
+ */
+static int pld_pcie_runtime_suspend(struct pci_dev *pdev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->runtime_suspend)
+ return pld_context->ops->runtime_suspend(&pdev->dev,
+ PLD_BUS_TYPE_PCIE);
+
+ return -ENODEV;
+}
+
+/**
+ * pld_pcie_runtime_resume() - PM runtime resume
+ * @pdev: PCIE device
+ *
+ * PM runtime resume callback function.
+ *
+ * Return: int
+ */
+static int pld_pcie_runtime_resume(struct pci_dev *pdev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->runtime_resume)
+ return pld_context->ops->runtime_resume(&pdev->dev,
+ PLD_BUS_TYPE_PCIE);
+
+ return -ENODEV;
+}
+#endif
+#endif
+
+/**
+ * pld_pcie_suspend() - Suspend callback function for power management
+ * @pdev: PCIE device
+ * @state: power state
+ *
+ * This function is to suspend the PCIE device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ return pld_context->ops->suspend(&pdev->dev,
+ PLD_BUS_TYPE_PCIE, state);
+}
+
+/**
+ * pld_pcie_resume() - Resume callback function for power management
+ * @pdev: PCIE device
+ *
+ * This function is to resume the PCIE device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_pcie_resume(struct pci_dev *pdev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ return pld_context->ops->resume(&pdev->dev, PLD_BUS_TYPE_PCIE);
+}
+
+static struct pci_device_id pld_pcie_id_table[] = {
+ { 0x168c, 0x003c, PCI_ANY_ID, PCI_ANY_ID },
+ { 0x168c, 0x003e, PCI_ANY_ID, PCI_ANY_ID },
+ { 0x168c, 0x0041, PCI_ANY_ID, PCI_ANY_ID },
+ { 0x168c, 0xabcd, PCI_ANY_ID, PCI_ANY_ID },
+ { 0x168c, 0x7021, PCI_ANY_ID, PCI_ANY_ID },
+ { 0 }
+};
+
+#ifdef CONFIG_CNSS
+#ifdef FEATURE_RUNTIME_PM
+struct cnss_wlan_runtime_ops runtime_pm_ops = {
+ .runtime_suspend = pld_pcie_runtime_suspend,
+ .runtime_resume = pld_pcie_runtime_resume,
+};
+#endif
+
+struct cnss_wlan_driver pld_pcie_ops = {
+ .name = "pld_pcie",
+ .id_table = pld_pcie_id_table,
+ .probe = pld_pcie_probe,
+ .remove = pld_pcie_remove,
+ .reinit = pld_pcie_reinit,
+ .shutdown = pld_pcie_shutdown,
+ .crash_shutdown = pld_pcie_crash_shutdown,
+ .modem_status = pld_pcie_notify_handler,
+#ifdef CONFIG_PM
+ .suspend = pld_pcie_suspend,
+ .resume = pld_pcie_resume,
+#endif
+#ifdef FEATURE_RUNTIME_PM
+ .runtime_ops = &runtime_pm_ops,
+#endif
+};
+
+/**
+ * pld_pcie_register_driver() - Register PCIE device callback functions
+ *
+ * Return: int
+ */
+int pld_pcie_register_driver(void)
+{
+ return cnss_wlan_register_driver(&pld_pcie_ops);
+}
+
+/**
+ * pld_pcie_unregister_driver() - Unregister PCIE device callback functions
+ *
+ * Return: void
+ */
+void pld_pcie_unregister_driver(void)
+{
+ cnss_wlan_unregister_driver(&pld_pcie_ops);
+}
+#else
+struct pci_driver pld_pcie_ops = {
+ .name = "pld_pcie",
+ .id_table = pld_pcie_id_table,
+ .probe = pld_pcie_probe,
+ .remove = pld_pcie_remove,
+#ifdef CONFIG_PM
+ .suspend = pld_pcie_suspend,
+ .resume = pld_pcie_resume,
+#endif
+};
+
+int pld_pcie_register_driver(void)
+{
+ return pci_register_driver(&pld_pcie_ops);
+}
+
+void pld_pcie_unregister_driver(void)
+{
+ pci_unregister_driver(&pld_pcie_ops);
+}
+#endif
+
+/**
+ * pld_pcie_get_ce_id() - Get CE number for the provided IRQ
+ * @irq: IRQ number
+ *
+ * Return: CE number
+ */
+int pld_pcie_get_ce_id(int irq)
+{
+ int ce_id = irq - 100;
+ if (ce_id < CE_COUNT_MAX && ce_id >= 0)
+ return ce_id;
+
+ return -EINVAL;
+}
+
+#ifdef CONFIG_CNSS
+#ifdef QCA_WIFI_3_0_ADRASTEA
+/**
+ * pld_pcie_wlan_enable() - Enable WLAN
+ * @config: WLAN configuration data
+ * @mode: WLAN mode
+ * @host_version: host software version
+ *
+ * This function enables WLAN FW. It passed WLAN configuration data,
+ * WLAN mode and host software version to FW.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_pcie_wlan_enable(struct pld_wlan_enable_cfg *config,
+ enum pld_driver_mode mode, const char *host_version)
+{
+ struct cnss_wlan_enable_cfg cfg;
+ enum cnss_driver_mode cnss_mode;
+
+ cfg.num_ce_tgt_cfg = config->num_ce_tgt_cfg;
+ cfg.ce_tgt_cfg = (struct cnss_ce_tgt_pipe_cfg *)
+ config->ce_tgt_cfg;
+ cfg.num_ce_svc_pipe_cfg = config->num_ce_svc_pipe_cfg;
+ cfg.ce_svc_cfg = (struct cnss_ce_svc_pipe_cfg *)
+ config->ce_svc_cfg;
+ cfg.num_shadow_reg_cfg = config->num_shadow_reg_cfg;
+ cfg.shadow_reg_cfg = (struct cnss_shadow_reg_cfg *)
+ config->shadow_reg_cfg;
+
+ switch (mode) {
+ case PLD_FTM:
+ cnss_mode = CNSS_FTM;
+ break;
+ case PLD_EPPING:
+ cnss_mode = CNSS_EPPING;
+ break;
+ default:
+ cnss_mode = CNSS_MISSION;
+ break;
+ }
+ return cnss_wlan_enable(&cfg, cnss_mode, host_version);
+}
+
+/**
+ * pld_pcie_wlan_disable() - Disable WLAN
+ * @mode: WLAN mode
+ *
+ * This function disables WLAN FW. It passes WLAN mode to FW.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_pcie_wlan_disable(enum pld_driver_mode mode)
+{
+ return cnss_wlan_disable(CNSS_OFF);
+}
+
+/**
+ * pld_pcie_set_fw_debug_mode() - Set FW debug mode
+ * @mode: 0 for QXDM, 1 for WMI
+ *
+ * Switch Fw debug mode between DIAG logging and WMI logging.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_pcie_set_fw_debug_mode(bool mode)
+{
+ return cnss_set_fw_debug_mode(mode);
+}
+#endif
+
+/**
+ * pld_pcie_get_fw_files_for_target() - Get FW file names
+ * @pfw_files: buffer for FW file names
+ * @target_type: target type
+ * @target_version: target version
+ *
+ * Return target specific FW file names to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_pcie_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+ u32 target_type, u32 target_version)
+{
+ int ret = 0;
+ struct cnss_fw_files cnss_fw_files;
+
+ if (pfw_files == NULL)
+ return -ENODEV;
+
+ ret = cnss_get_fw_files_for_target(&cnss_fw_files,
+ target_type, target_version);
+ if (0 != ret)
+ return ret;
+
+ memcpy(pfw_files, &cnss_fw_files, sizeof(*pfw_files));
+ return 0;
+}
+
+/**
+ * pld_pcie_get_fw_image() - Get FW image descriptor
+ * @image_desc_info: buffer for image descriptor
+ *
+ * Return FW image descriptor to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_pcie_get_fw_image(struct pld_image_desc_info *image_desc_info)
+{
+ int ret = 0;
+ struct image_desc_info cnss_image_desc_info;
+
+ if (image_desc_info == NULL)
+ return -ENODEV;
+
+ ret = cnss_get_fw_image(&cnss_image_desc_info);
+ if (0 != ret)
+ return ret;
+
+ memcpy(image_desc_info, &cnss_image_desc_info,
+ sizeof(*image_desc_info));
+ return 0;
+}
+
+/**
+ * pld_pcie_get_codeswap_struct() - Get codeswap structure
+ * @swap_seg: buffer to codeswap information
+ *
+ * Return codeswap structure information to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_pcie_get_codeswap_struct(struct pld_codeswap_codeseg_info *swap_seg)
+{
+ int ret = 0;
+ struct codeswap_codeseg_info cnss_swap_seg;
+
+ if (swap_seg == NULL)
+ return -ENODEV;
+
+ ret = cnss_get_codeswap_struct(&cnss_swap_seg);
+ if (0 != ret)
+ return ret;
+
+ memcpy(swap_seg, &cnss_swap_seg, sizeof(*swap_seg));
+ return 0;
+}
+
+/**
+ * pld_pcie_get_platform_cap() - Get platform capabilities
+ * @cap: buffer to the capabilities
+ *
+ * Return capabilities to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_pcie_get_platform_cap(struct pld_platform_cap *cap)
+{
+ int ret = 0;
+ struct cnss_platform_cap cnss_cap;
+
+ if (cap == NULL)
+ return -ENODEV;
+
+ ret = cnss_get_platform_cap(&cnss_cap);
+ if (0 != ret)
+ return ret;
+
+ memcpy(cap, &cnss_cap, sizeof(*cap));
+ return 0;
+}
+
+/**
+ * pld_pcie_set_driver_status() - Set driver status
+ * @status: driver status
+ *
+ * Return: void
+ */
+void pld_pcie_set_driver_status(enum pld_driver_status status)
+{
+ enum cnss_driver_status cnss_status;
+
+ switch (status) {
+ case PLD_UNINITIALIZED:
+ cnss_status = CNSS_UNINITIALIZED;
+ break;
+ case PLD_INITIALIZED:
+ cnss_status = CNSS_INITIALIZED;
+ break;
+ default:
+ cnss_status = CNSS_LOAD_UNLOAD;
+ break;
+ }
+ cnss_set_driver_status(cnss_status);
+}
+#endif
+
+#endif
diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h
new file mode 100644
index 000000000000..adc830e4cda7
--- /dev/null
+++ b/core/pld/src/pld_pcie.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __PLD_PCIE_H__
+#define __PLD_PCIE_H__
+
+#include "pld_common.h"
+
+#ifndef CONFIG_PCI
+static inline int pld_pcie_register_driver(void)
+{
+ return 0;
+}
+
+static inline void pld_pcie_unregister_driver(void)
+{
+ return;
+}
+
+static inline int pld_pcie_get_ce_id(int irq)
+{
+ return 0;
+}
+#else
+int pld_pcie_register_driver(void);
+void pld_pcie_unregister_driver(void);
+int pld_pcie_get_ce_id(int irq);
+#endif
+
+#if (!defined(CONFIG_CNSS)) || (!defined(QCA_WIFI_3_0_ADRASTEA))
+static inline int pld_pcie_wlan_enable(struct pld_wlan_enable_cfg *config,
+ enum pld_driver_mode mode, const char *host_version)
+{
+ return 0;
+}
+static inline int pld_pcie_wlan_disable(enum pld_driver_mode mode)
+{
+ return 0;
+}
+static inline int pld_pcie_set_fw_debug_mode(bool enablefwlog)
+{
+ return 0;
+}
+static inline void cnss_intr_notify_q6(void)
+{
+ return;
+}
+#else
+int pld_pcie_wlan_enable(struct pld_wlan_enable_cfg *config,
+ enum pld_driver_mode mode, const char *host_version);
+int pld_pcie_wlan_disable(enum pld_driver_mode mode);
+int pld_pcie_set_fw_debug_mode(bool enablefwlog);
+#endif
+
+#if (!defined(CONFIG_CNSS)) || (!defined(CONFIG_CNSS_SECURE_FW))
+static inline int cnss_get_sha_hash(const u8 *data,
+ u32 data_len, u8 *hash_idx, u8 *out)
+{
+ return 0;
+}
+static inline void *cnss_get_fw_ptr(void)
+{
+ return NULL;
+}
+#endif
+
+#if (!defined(CONFIG_CNSS)) || (!defined(CONFIG_PCI_MSM))
+static inline int cnss_wlan_pm_control(bool vote)
+{
+ return 0;
+}
+#endif
+
+#ifndef CONFIG_CNSS
+static inline int
+pld_pcie_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+ u32 target_type, u32 target_version)
+{
+ return 0;
+}
+static inline int
+pld_pcie_get_fw_image(struct pld_image_desc_info *image_desc_info)
+{
+ return 0;
+}
+static inline void cnss_wlan_pci_link_down(void)
+{
+ return;
+}
+static inline int cnss_pcie_shadow_control(bool enable)
+{
+ return 0;
+}
+static inline int
+pld_pcie_get_codeswap_struct(struct pld_codeswap_codeseg_info *swap_seg)
+{
+ return 0;
+}
+static inline int
+cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count)
+{
+ return 0;
+}
+static inline int cnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list,
+ u16 *ch_count, u16 buf_len)
+{
+ return 0;
+}
+static inline int cnss_wlan_set_dfs_nol(void *info, u16 info_len)
+{
+ return 0;
+}
+static inline int cnss_wlan_get_dfs_nol(void *info, u16 info_len)
+{
+ return 0;
+}
+static inline void *cnss_get_virt_ramdump_mem(unsigned long *size)
+{
+ return NULL;
+}
+static inline void cnss_device_crashed(void)
+{
+ return;
+}
+static inline void cnss_device_self_recovery(void)
+{
+ return;
+}
+static inline void cnss_request_pm_qos(u32 qos_val)
+{
+ return;
+}
+static inline void cnss_remove_pm_qos(void)
+{
+ return;
+}
+static inline int cnss_request_bus_bandwidth(int bandwidth)
+{
+ return 0;
+}
+static inline int pld_pcie_get_platform_cap(struct pld_platform_cap *cap)
+{
+ return 0;
+}
+static inline void pld_pcie_set_driver_status(enum pld_driver_status status)
+{
+ return;
+}
+static inline int cnss_get_bmi_setup(void)
+{
+ return 0;
+}
+static inline int cnss_auto_suspend(void)
+{
+ return 0;
+}
+static inline int cnss_auto_resume(void)
+{
+ return 0;
+}
+static void cnss_lock_pm_sem(void)
+{
+ return;
+}
+static void cnss_release_pm_sem(void)
+{
+ return;
+}
+#else
+int pld_pcie_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+ u32 target_type, u32 target_version);
+int pld_pcie_get_fw_image(struct pld_image_desc_info *image_desc_info);
+int pld_pcie_get_codeswap_struct(struct pld_codeswap_codeseg_info *swap_seg);
+int pld_pcie_get_platform_cap(struct pld_platform_cap *cap);
+void pld_pcie_set_driver_status(enum pld_driver_status status);
+#endif
+
+#endif
diff --git a/core/pld/src/pld_snoc.c b/core/pld/src/pld_snoc.c
new file mode 100644
index 000000000000..40cee705ea9d
--- /dev/null
+++ b/core/pld/src/pld_snoc.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_ICNSS
+#include <soc/qcom/icnss.h>
+#endif
+
+#include "pld_common.h"
+#include "pld_internal.h"
+
+#ifdef CONFIG_ICNSS
+/**
+ * pld_snoc_probe() - Probe function for platform driver
+ * @dev: device
+ *
+ * The probe function will be called when platform device
+ * is detected.
+ *
+ * Return: int
+ */
+static int pld_snoc_probe(struct device *dev)
+{
+ struct pld_context *pld_context;
+ unsigned long flags;
+ struct dev_node *dev_node;
+ int ret = 0;
+
+ pld_context = pld_get_global_context();
+ if (!pld_context) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ dev_node = kzalloc(sizeof(*dev_node), GFP_KERNEL);
+ if (dev_node == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ dev_node->dev = dev;
+ dev_node->bus_type = PLD_BUS_TYPE_SNOC;
+
+ spin_lock_irqsave(&pld_context->pld_lock, flags);
+ list_add_tail(&dev_node->list, &pld_context->dev_list);
+ spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+ return pld_context->ops->probe(dev, PLD_BUS_TYPE_SNOC,
+ NULL, NULL);
+
+out:
+ return ret;
+}
+
+/**
+ * pld_snoc_remove() - Remove function for platform device
+ * @dev: device
+ *
+ * The remove function will be called when platform device
+ * is disconnected
+ *
+ * Return: void
+ */
+static void pld_snoc_remove(struct device *dev)
+{
+ struct pld_context *pld_context;
+ unsigned long flags;
+ struct dev_node *dev_node, *tmp;
+
+ pld_context = pld_get_global_context();
+
+ if (!pld_context)
+ return;
+
+ spin_lock_irqsave(&pld_context->pld_lock, flags);
+ list_for_each_entry_safe(dev_node, tmp, &pld_context->dev_list, list) {
+ if (dev_node->dev == dev) {
+ list_del(&dev_node->list);
+ kfree(dev_node);
+ }
+ }
+ spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+ pld_context->ops->remove(dev, PLD_BUS_TYPE_SNOC);
+}
+
+/**
+ * pld_snoc_reinit() - SSR re-initialize function for platform device
+ * @dev: device
+ *
+ * During subsystem restart(SSR), this function will be called to
+ * re-initialize platform device.
+ *
+ * Return: int
+ */
+static int pld_snoc_reinit(struct device *dev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->reinit)
+ return pld_context->ops->reinit(dev, PLD_BUS_TYPE_SNOC,
+ NULL, NULL);
+
+ return -ENODEV;
+}
+
+/**
+ * pld_snoc_shutdown() - SSR shutdown function for platform device
+ * @dev: device
+ *
+ * During SSR, this function will be called to shutdown platform device.
+ *
+ * Return: void
+ */
+static void pld_snoc_shutdown(struct device *dev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->shutdown)
+ pld_context->ops->shutdown(dev, PLD_BUS_TYPE_SNOC);
+}
+
+/**
+ * pld_snoc_crash_shutdown() - Crash shutdown function for platform device
+ * @dev: device
+ *
+ * This function will be called when a crash is detected, it will shutdown
+ * platform device.
+ *
+ * Return: void
+ */
+static void pld_snoc_crash_shutdown(void *dev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (pld_context->ops->crash_shutdown)
+ pld_context->ops->crash_shutdown(dev, PLD_BUS_TYPE_SNOC);
+}
+
+/**
+ * pld_snoc_suspend() - Suspend callback function for power management
+ * @dev: device
+ * @state: power state
+ *
+ * This function is to suspend the platform device when power management
+ * is enabled.
+ *
+ * Return: void
+ */
+static int pld_snoc_suspend(struct device *dev, pm_message_t state)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ return pld_context->ops->suspend(dev, PLD_BUS_TYPE_SNOC, state);
+}
+
+/**
+ * pld_snoc_resume() - Resume callback function for power management
+ * @pdev: device
+ *
+ * This function is to resume the platform device when power management
+ * is enabled.
+ *
+ * Return: void
+ */
+static int pld_snoc_resume(struct device *dev)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ return pld_context->ops->resume(dev, PLD_BUS_TYPE_SNOC);
+}
+
+struct icnss_driver_ops pld_snoc_ops = {
+ .name = "pld_snoc",
+ .probe = pld_snoc_probe,
+ .remove = pld_snoc_remove,
+ .shutdown = pld_snoc_shutdown,
+ .reinit = pld_snoc_reinit,
+ .crash_shutdown = pld_snoc_crash_shutdown,
+ .suspend = pld_snoc_suspend,
+ .resume = pld_snoc_resume,
+};
+
+/**
+ * pld_snoc_register_driver() - Register platform device callback functions
+ *
+ * Return: int
+ */
+int pld_snoc_register_driver(void)
+{
+ return icnss_register_driver(&pld_snoc_ops);
+}
+
+/**
+ * pld_snoc_unregister_driver() - Unregister platform device callback functions
+ *
+ * Return: void
+ */
+void pld_snoc_unregister_driver(void)
+{
+ icnss_unregister_driver(&pld_snoc_ops);
+}
+
+/**
+ * pld_snoc_wlan_enable() - Enable WLAN
+ * @config: WLAN configuration data
+ * @mode: WLAN mode
+ * @host_version: host software version
+ *
+ * This function enables WLAN FW. It passed WLAN configuration data,
+ * WLAN mode and host software version to FW.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_snoc_wlan_enable(struct pld_wlan_enable_cfg *config,
+ enum pld_driver_mode mode, const char *host_version)
+{
+ struct icnss_wlan_enable_cfg cfg;
+ enum icnss_driver_mode icnss_mode;
+
+ cfg.num_ce_tgt_cfg = config->num_ce_tgt_cfg;
+ cfg.ce_tgt_cfg = (struct ce_tgt_pipe_cfg *)
+ config->ce_tgt_cfg;
+ cfg.num_ce_svc_pipe_cfg = config->num_ce_svc_pipe_cfg;
+ cfg.ce_svc_cfg = (struct ce_svc_pipe_cfg *)
+ config->ce_svc_cfg;
+ cfg.num_shadow_reg_cfg = config->num_shadow_reg_cfg;
+ cfg.shadow_reg_cfg = (struct icnss_shadow_reg_cfg *)
+ config->shadow_reg_cfg;
+
+ switch (mode) {
+ case PLD_FTM:
+ icnss_mode = ICNSS_FTM;
+ break;
+ case PLD_EPPING:
+ icnss_mode = ICNSS_EPPING;
+ break;
+ default:
+ icnss_mode = ICNSS_MISSION;
+ break;
+ }
+ return icnss_wlan_enable(&cfg, icnss_mode, host_version);
+}
+
+/**
+ * pld_snoc_wlan_disable() - Disable WLAN
+ * @mode: WLAN mode
+ *
+ * This function disables WLAN FW. It passes WLAN mode to FW.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_snoc_wlan_disable(enum pld_driver_mode mode)
+{
+ return icnss_wlan_disable(ICNSS_OFF);
+}
+
+/**
+ * pld_snoc_get_soc_info() - Get SOC information
+ * @info: buffer to SOC information
+ *
+ * Return SOC info to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+int pld_snoc_get_soc_info(struct pld_soc_info *info)
+{
+ int ret = 0;
+ struct icnss_soc_info icnss_info;
+
+ if (info == NULL)
+ return -ENODEV;
+
+ ret = icnss_get_soc_info(&icnss_info);
+ if (0 != ret)
+ return ret;
+
+ memcpy(info, &icnss_info, sizeof(*info));
+ return 0;
+}
+
+#endif
diff --git a/core/pld/src/pld_snoc.h b/core/pld/src/pld_snoc.h
new file mode 100644
index 000000000000..321710680cf2
--- /dev/null
+++ b/core/pld/src/pld_snoc.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __PLD_SNOC_H__
+#define __PLD_SNOC_H__
+
+#include "pld_common.h"
+
+#ifndef CONFIG_ICNSS
+static inline int pld_snoc_register_driver(void)
+{
+ return 0;
+}
+
+static inline void pld_snoc_unregister_driver(void)
+{
+ return;
+}
+static inline int pld_snoc_wlan_enable(struct pld_wlan_enable_cfg *config,
+ enum pld_driver_mode mode, const char *host_version)
+{
+ return 0;
+}
+static inline int pld_snoc_wlan_disable(enum pld_driver_mode mode)
+{
+ return 0;
+}
+static inline int icnss_ce_request_irq(unsigned int ce_id,
+ irqreturn_t (*handler)(int, void *),
+ unsigned long flags, const char *name, void *ctx)
+{
+ return 0;
+}
+static inline int icnss_ce_free_irq(unsigned int ce_id, void *ctx)
+{
+ return 0;
+}
+static inline void icnss_enable_irq(unsigned int ce_id)
+{
+ return;
+}
+static inline void icnss_disable_irq(unsigned int ce_id)
+{
+ return;
+}
+static inline int icnss_get_soc_info(struct pld_soc_info *info)
+{
+ return 0;
+}
+static inline int icnss_get_ce_id(int irq)
+{
+ return 0;
+}
+static inline int pld_snoc_get_soc_info(struct pld_soc_info *info)
+{
+ return 0;
+}
+#else
+int pld_snoc_register_driver(void);
+void pld_snoc_unregister_driver(void);
+int pld_snoc_wlan_enable(struct pld_wlan_enable_cfg *config,
+ enum pld_driver_mode mode, const char *host_version);
+int pld_snoc_wlan_disable(enum pld_driver_mode mode);
+int pld_snoc_get_soc_info(struct pld_soc_info *info);
+#endif
+
+#endif
diff --git a/core/sap/dfs/inc/dfs.h b/core/sap/dfs/inc/dfs.h
index 56187cbcdc8b..74c0add523a5 100644
--- a/core/sap/dfs/inc/dfs.h
+++ b/core/sap/dfs/inc/dfs.h
@@ -101,6 +101,16 @@
#define DFS_80P80_SEG0 0
#define DFS_80P80_SEG1 1
+/**
+ * @DFS_RADAR_SUMMARY_REPORT_VERSION_2: DFS-2 radar summary report
+ * @DFS_RADAR_SUMMARY_REPORT_VERSION_3: DFS-3 radar summary report
+ */
+enum {
+ DFS_RADAR_SUMMARY_REPORT_VERSION_2 = 1,
+ DFS_RADAR_SUMMARY_REPORT_VERSION_3 = 2,
+};
+
+
/*
* Constants to use for chirping detection.
*
@@ -286,6 +296,19 @@ struct dfs_event {
uint32_t re_freq_hi; /* Upper bounds of frequency, KHz */
int sidx; /* Pulse Index as in radar summary report */
int radar_80p80_segid; /* 80p80 segment ID as in radar sum report */
+ int delta_peak; /* delta peak reported in radar summary */
+ int delta_diff; /* delta diff reported in radar summary */
+ int agc_total_gain; /* agc total gain reported in radar summary */
+ int agc_mb_gain; /* agc mb gain reported in radar summary */
+ int radar_subchan_mask; /* subchan mask reported in radar summary */
+ int pulse_height; /* pulse height reported in radar summary */
+ int triggering_agc_event; /* triggering agc reported in radar summary */
+ int pulse_rssi; /* rssi of phyerr reported in radar summary */
+ int radar_fft_pri80_inband_power; /* Pri80MHz pwr reported in summary */
+ int radar_fft_ext80_inband_power; /* Ext80MHz pwr reported in summary */
+ int rsu_version; /* Radar summary report version */
+ int phyerr_serial_num; /* phyerr seq num queued for pattern matching */
+ int peak_mag; /* Peak mag reported in radar search FFT report */
STAILQ_ENTRY(dfs_event) re_list; /* List of radar events */
} qdf_packed;
#ifdef WIN32
@@ -737,6 +760,30 @@ struct dfs_phy_err {
* when SAP is operating in 80p80 channel width.
*/
int radar_80p80_segid;
+ /* delta peak reported in radar summary */
+ int delta_peak;
+ /* delta diff reported in radar summary */
+ int delta_diff;
+ /* agc total gain reported in radar summary */
+ int agc_total_gain;
+ /* agc mb gain reported in radar summary */
+ int agc_mb_gain;
+ /* subchan mask reported in radar summary */
+ int radar_subchan_mask;
+ /* pulse height reported in radar summary */
+ int pulse_height;
+ /* triggering agc reported in radar summary */
+ int triggering_agc_event;
+ /* rssi of phyerr reported in radar summary */
+ int pulse_rssi;
+ /* Pri80MHz pwr reported in summary */
+ int radar_fft_pri80_inband_power;
+ /* Ext80MHz pwr reported in summary */
+ int radar_fft_ext80_inband_power;
+ /* Peak mag reported in radar search FFT report */
+ int peak_mag;
+ /* Radar summary report version */
+ int rsu_version;
};
/* Attach, detach, handle ioctl prototypes */
diff --git a/core/sap/dfs/src/dfs_phyerr_tlv.c b/core/sap/dfs/src/dfs_phyerr_tlv.c
index 3ac1d08c1071..058e321d1c38 100644
--- a/core/sap/dfs/src/dfs_phyerr_tlv.c
+++ b/core/sap/dfs/src/dfs_phyerr_tlv.c
@@ -35,16 +35,6 @@
#include "dfs_phyerr.h"
#include "dfs_phyerr_tlv.h"
-/**
- * enum RADAR_SUMMARY_VERSION - Radar summary report version
- * @DFS_RADAR_SUMMARY_REPORT_VERSION_2: DFS-2 radar summary report
- * @DFS_RADAR_SUMMARY_REPORT_VERSION_3: DFS-3 radar summary report
- */
-typedef enum {
-DFS_RADAR_SUMMARY_REPORT_VERSION_2 = 1,
-DFS_RADAR_SUMMARY_REPORT_VERSION_3 = 2,
-} RADAR_SUMMARY_VERSION;
-
/*
* Parsed radar status
*/
@@ -62,7 +52,7 @@ struct rx_radar_status {
int agc_mb_gain;
/*Parsed only for DFS-3*/
int radar_subchan_mask;
- RADAR_SUMMARY_VERSION rsu_version;
+ int rsu_version;
/*
* The parameters below are present only in
* DFS-3 radar summary report and need to be
@@ -882,8 +872,23 @@ dfs_process_phyerr_bb_tlv(struct ath_dfs *dfs, void *buf, uint16_t datalen,
* Copy the segment ID from the radar summary report
* only when radar summary report version is DFS-3.
*/
- if (rs.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3)
+ if (rs.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) {
e->radar_80p80_segid = rs.radar_80p80_segid;
+ e->delta_peak = rs.delta_peak;
+ e->delta_diff = rs.delta_diff;
+ e->agc_total_gain = rs.agc_total_gain;
+ e->agc_mb_gain = rs.agc_mb_gain;
+ e->radar_subchan_mask = rs.radar_subchan_mask;
+ e->pulse_height = rs.pulse_height;
+ e->triggering_agc_event = rs.triggering_agc_event;
+ e->pulse_rssi = rs.pulse_rssi;
+ e->radar_fft_pri80_inband_power =
+ rs.radar_fft_pri80_inband_power;
+ e->radar_fft_ext80_inband_power =
+ rs.radar_fft_ext80_inband_power;
+ e->rsu_version = rs.rsu_version;
+ e->peak_mag = rsfr.peak_mag;
+ }
/*
* XXX TODO: add a "chirp detection enabled" capability or config
* bit somewhere, in case for some reason the hardware chirp
diff --git a/core/sap/dfs/src/dfs_process_phyerr.c b/core/sap/dfs/src/dfs_process_phyerr.c
index 8725236b08a8..a78b4ef4ad54 100644
--- a/core/sap/dfs/src/dfs_process_phyerr.c
+++ b/core/sap/dfs/src/dfs_process_phyerr.c
@@ -560,6 +560,9 @@ dfs_process_phyerr(struct ieee80211com *ic, void *buf, uint16_t datalen,
r_fulltsf, &e,
enable_log) == 0) {
dfs->dfs_phyerr_reject_count++;
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+ "%s:Rejected phyerr count after parsing=%d\n",
+ __func__, dfs->dfs_phyerr_reject_count);
return;
} else {
if (dfs->dfs_phyerr_freq_min > e.freq)
@@ -737,6 +740,22 @@ dfs_process_phyerr(struct ieee80211com *ic, void *buf, uint16_t datalen,
event->re_chanindex = dfs->dfs_curchan_radindex;
event->re_flags = 0;
event->sidx = e.sidx;
+ if (e.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) {
+ event->delta_peak = e.delta_peak;
+ event->delta_diff = e.delta_diff;
+ event->agc_total_gain = e.agc_total_gain;
+ event->agc_mb_gain = e.agc_mb_gain;
+ event->radar_subchan_mask = e.radar_subchan_mask;
+ event->pulse_height = e.pulse_height;
+ event->triggering_agc_event = e.triggering_agc_event;
+ event->pulse_rssi = e.pulse_rssi;
+ event->radar_fft_pri80_inband_power =
+ e.radar_fft_pri80_inband_power;
+ event->radar_fft_ext80_inband_power =
+ e.radar_fft_ext80_inband_power;
+ event->rsu_version = e.rsu_version;
+ event->peak_mag = e.peak_mag;
+ }
/*
* Copy the segment ID of the phyerror
* from the radar summary report only
@@ -825,6 +844,35 @@ dfs_process_phyerr(struct ieee80211com *ic, void *buf, uint16_t datalen,
event->re_ts = (e.rs_tstamp) & DFS_TSMASK;
event->re_rssi = e.rssi;
event->sidx = e.sidx;
+ if (e.rsu_version ==
+ DFS_RADAR_SUMMARY_REPORT_VERSION_3) {
+ event->delta_peak = e.delta_peak;
+ event->delta_diff = e.delta_diff;
+ event->agc_total_gain = e.agc_total_gain;
+ event->agc_mb_gain = e.agc_mb_gain;
+ event->radar_subchan_mask = e.radar_subchan_mask;
+ event->pulse_height = e.pulse_height;
+ event->triggering_agc_event =
+ e.triggering_agc_event;
+ event->pulse_rssi = e.pulse_rssi;
+ event->radar_fft_pri80_inband_power =
+ e.radar_fft_pri80_inband_power;
+ event->radar_fft_ext80_inband_power =
+ e.radar_fft_ext80_inband_power;
+ event->rsu_version = e.rsu_version;
+ event->phyerr_serial_num =
+ dfs->dfs_phyerr_queued_count;
+ event->peak_mag = e.peak_mag;
+ }
+ /*
+ * Copy the segment ID of the phyerror
+ * from the radar summary report only
+ * if SAP is operating in 80p80 mode
+ * and both primary and extension segments
+ * are DFS.
+ */
+ if (chan->ic_80p80_both_dfs)
+ event->radar_80p80_segid = e.radar_80p80_segid;
/*
* Handle chirp flags.
diff --git a/core/sap/dfs/src/dfs_process_radarevent.c b/core/sap/dfs/src/dfs_process_radarevent.c
index 30392b1b41cc..e77d71178642 100644
--- a/core/sap/dfs/src/dfs_process_radarevent.c
+++ b/core/sap/dfs/src/dfs_process_radarevent.c
@@ -115,8 +115,6 @@ static inline uint8_t dfs_process_pulse_dur(struct ath_dfs *dfs, uint8_t re_dur)
int dfs_process_radarevent(struct ath_dfs *dfs,
struct dfs_ieee80211_channel *chan)
{
-/* commenting for now to validate radar indication msg to SAP */
-/* #if 0 */
struct dfs_event re, *event;
struct dfs_state *rs = NULL;
struct dfs_filtertype *ft;
@@ -129,9 +127,7 @@ int dfs_process_radarevent(struct ath_dfs *dfs,
struct dfs_pulseline *pl;
static uint32_t diff_ts;
int ext_chan_event_flag = 0;
-#if 0
- int pri_multiplier = 2;
-#endif
+ int is_hw_chirp = 0;
int i;
int seg_id = DFS_80P80_SEG0;
struct dfs_delayline *dl;
@@ -404,11 +400,30 @@ int dfs_process_radarevent(struct ath_dfs *dfs,
dfs->radar_log[i].dur = re.re_dur;
dfs->dfs_event_log_count++;
}
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
- "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx",
- __func__, __LINE__, (uint32_t) this_ts, re.re_dur,
- re.re_rssi, diff_ts,
- (unsigned long long)pl->pl_elems[index].p_time);
+ if (re.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) {
+ if ((re.re_flags & DFS_EVENT_HW_CHIRP) ==
+ DFS_EVENT_HW_CHIRP)
+ is_hw_chirp = 1;
+
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+ "\n %s[%d]:PHYERR# = %d ts = %u diff_ts = %u ppdu_rssi = %u dur = %u is_hw_chirp = %d segid = %d sidx = %d peak_mag = %d delta_peak = %d delta_diff = %d agc_total_gain = %d agc_mb_gain = %d radar_subchan_mask = 0x%x pulse_height = %d triggering_agc_event = %d rs_pulse_rssi = %d pri80_inband_power = %d ext80_inband_power = %d \n",
+ __func__, __LINE__,
+ re.phyerr_serial_num, (uint32_t) this_ts,
+ diff_ts, re.re_rssi, re.re_dur, is_hw_chirp,
+ re.radar_80p80_segid, re.sidx, re.peak_mag,
+ re.delta_peak, re.delta_diff,
+ re.agc_total_gain, re.agc_mb_gain,
+ re.radar_subchan_mask, re.pulse_height,
+ re.triggering_agc_event, re.pulse_rssi,
+ re.radar_fft_pri80_inband_power,
+ re.radar_fft_ext80_inband_power);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+ "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx",
+ __func__, __LINE__, (uint32_t) this_ts, re.re_dur,
+ re.re_rssi, diff_ts,
+ (unsigned long long)pl->pl_elems[index].p_time);
+ }
/* If diff_ts is very small, we might be getting false pulse detects
* due to heavy interference. We might be getting spectral splatter
diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c
index 78b71b4b0c3e..7d76f9cd3cf1 100644
--- a/core/sap/src/sap_api_link_cntl.c
+++ b/core/sap/src/sap_api_link_cntl.c
@@ -507,128 +507,6 @@ wlansap_roam_process_ch_change_success(tpAniSirGlobal mac_ctx,
}
/**
- * wlansap_set_hw_mode_on_channel_switch() - Set hw mode before channel switch
- * @sap_ctx: Global SAP context
- * @target_channel: Target channel
- *
- * Sets hw mode, if needed, before doing a channel switch
- *
- * Return: None
- */
-static QDF_STATUS wlansap_set_hw_mode_on_channel_switch(tpAniSirGlobal mac_ctx,
- ptSapContext sap_ctx,
- uint32_t target_channel)
-{
- QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
- cds_context_type *cds_ctx;
- enum cds_conc_next_action action;
-
- cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
- if (!cds_ctx) {
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
- FL("Invalid CDS Context"));
- return status;
- }
-
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
-
- action = cds_get_pref_hw_mode_for_chan(sap_ctx->sessionId,
- target_channel);
-
- if ((action != CDS_DBS_DOWNGRADE) && (action != CDS_MCC_UPGRADE)) {
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
- FL("Invalid action: %d"), action);
- goto done;
- }
-
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
- FL("action:%d session id:%d"),
- action, sap_ctx->sessionId);
-
- /* For MCC, opportunistic timer will be trigerred. We do not
- * want to do hw mode change here to avoid the ping pong effect.
- * e.g., If a new connection is immediately coming up, we could be
- * moving in and out of MCC. The timer after DBS_OPPORTUNISTIC_TIME
- * seconds will check if the driver can move to MCC or not.
- *
- * 1. Start opportunistic timer
- * 2. Do vdev restart on the new channel
- * 3. PM will check if MCC upgrade can be done after timer expiry
- */
- if (action == CDS_MCC_UPGRADE) {
- qdf_mc_timer_stop(&cds_ctx->dbs_opportunistic_timer);
- qdf_status = qdf_mc_timer_start(
- &cds_ctx->dbs_opportunistic_timer,
- DBS_OPPORTUNISTIC_TIME *
- 1000);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status))
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
- FL("Failed to start dbs opportunistic timer"));
- else
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
- FL("opportunistic timer for MCC upgrade"));
- goto done;
- }
-
- /* For DBS, we want to move right away to DBS mode. Else, we could
- * be doing MCC momentarily.
- *
- * 1. PM will initiate HW mode change to DBS rightaway
- * 2. Do vdev restart on the new channel
- */
- status = cds_next_actions(sap_ctx->sessionId, action,
- SIR_UPDATE_REASON_CHANNEL_SWITCH);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
- FL("no set hw mode command was issued"));
- goto done;
- }
-done:
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
- /* success must be returned only when a set hw mode was done */
- return status;
-}
-
-/**
- * wlansap_update_hw_mode() - Set the hw mode for the new channel switch
- * @hal: HAL pointer
- * @sap_ctx: SAP context
- *
- * Sets the hw mode, if needed, for the driver based on the new channel
- * to which the vdev is going to switch to
- *
- * Return: None
- */
-void wlansap_update_hw_mode(tHalHandle hal, ptSapContext sap_ctx)
-{
- QDF_STATUS status = QDF_STATUS_E_FAILURE;
- tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
- tCsrRoamInfo roam_info = {0};
-
- if (mac_ctx->policy_manager_enabled &&
- wma_is_hw_dbs_capable() == true) {
- status = wlansap_set_hw_mode_on_channel_switch(mac_ctx, sap_ctx,
- mac_ctx->sap.SapDfsInfo.target_channel);
- }
-
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
- FL("status:%d"), status);
-
- /*
- * If no set hw mode was done, proceed as before by doing set channel.
- * If set hw mode was done, perform the following in the callback so
- * that the set channel operations are done after the driver moves to
- * the required hw mode.
- */
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- csr_roam_call_callback(mac_ctx, sap_ctx->sessionId,
- &roam_info, 0,
- eCSR_ROAM_STATUS_UPDATE_HW_MODE,
- eCSR_ROAM_RESULT_UPDATE_HW_MODE);
- }
-}
-
-/**
* wlansap_roam_process_dfs_chansw_update() - handles the case for
* eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS in wlansap_roam_callback()
*
@@ -1097,10 +975,6 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
FL("Received Chan Sw Update Notification"));
break;
- case eCSR_ROAM_STATUS_UPDATE_HW_MODE:
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
- FL("Received HW mode update notification"));
- break;
case eCSR_ROAM_SET_CHANNEL_RSP:
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
FL("Received set channel response"));
@@ -1316,26 +1190,8 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
&qdf_ret_status);
break;
case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS:
- /* eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS indicates the
- * completion of sending (E)CSA IEs. After these IEs are sent,
- * in eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS state, check
- * for DBS downgrade/MCC upgrade is done.
- * (1) From this state
- * eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS, on MCC upgrade,
- * transition immediately happens to the state
- * eCSR_ROAM_RESULT_UPDATE_HW_MODE, where the vdev restart
- * happens internally.
- * (2) From this state,
- * eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS, on DBS downgrade,
- * transition happens to the state
- * eCSR_ROAM_RESULT_UPDATE_HW_MODE to do vdev restart only after
- * SME received the set HW mode response.
- */
- wlansap_update_hw_mode(hal, sap_ctx);
- break;
- case eCSR_ROAM_RESULT_UPDATE_HW_MODE:
wlansap_roam_process_dfs_chansw_update(hal, sap_ctx,
- &qdf_ret_status);
+ &qdf_ret_status);
break;
case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS:
wlansap_roam_process_ch_change_success(mac_ctx, sap_ctx,
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index ae0c98749e4f..802afc321f1d 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -270,7 +270,12 @@ typedef struct tagCsrScanRequest {
tCsrChannelInfo ChannelInfo;
uint32_t minChnTime; /* in units of milliseconds */
uint32_t maxChnTime; /* in units of milliseconds */
- uint32_t restTime; /* in units of milliseconds */
+ /* In units of milliseconds, ignored when not connected */
+ uint32_t restTime;
+ /* In units of milliseconds, ignored when not connected */
+ uint32_t min_rest_time;
+ /* In units of milliseconds, ignored when not connected */
+ uint32_t idle_time;
uint32_t uIEFieldLen;
uint8_t *pIEField;
eCsrRequestType requestType; /* 11d scan or full scan */
@@ -492,9 +497,9 @@ typedef enum {
/* Channel sw update notification */
eCSR_ROAM_DFS_CHAN_SW_NOTIFY,
eCSR_ROAM_EXT_CHG_CHNL_IND,
- eCSR_ROAM_STATUS_UPDATE_HW_MODE,
eCSR_ROAM_DISABLE_QUEUES,
eCSR_ROAM_ENABLE_QUEUES,
+ eCSR_ROAM_STA_CHANNEL_SWITCH,
} eRoamCmdStatus;
/* comment inside indicates what roaming callback gets */
@@ -591,7 +596,6 @@ typedef enum {
eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE,
eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS,
eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND,
- eCSR_ROAM_RESULT_UPDATE_HW_MODE,
} eCsrRoamResult;
/*----------------------------------------------------------------------------
@@ -940,7 +944,6 @@ typedef struct tagCsrRoamHTProfile {
uint8_t htRecommendedTxWidthSet;
ePhyChanBondState htSecondaryChannelOffset;
uint8_t vhtCapability;
- uint8_t vhtTxChannelWidthSet;
uint8_t apCenterChan;
uint8_t apChanWidth;
} tCsrRoamHTProfile;
@@ -1096,6 +1099,11 @@ typedef struct tagCsrConfigParam {
/* number of channels combined for P2P in each split scan operation */
uint8_t nNumP2PChanCombinedConc;
#endif
+ /*In units of milliseconds*/
+ uint32_t min_rest_time_conc;
+ /*In units of milliseconds*/
+ uint32_t idle_time_conc;
+
/*
* in dBm, the maximum TX power The actual TX power is the lesser of
* this value and 11d. If 11d is disable, the lesser of this and
@@ -1222,6 +1230,7 @@ typedef struct tagCsrConfigParam {
uint32_t obss_active_dwelltime;
uint32_t obss_passive_dwelltime;
bool ignore_peer_ht_opmode;
+ bool enable_fatal_event;
} tCsrConfigParam;
/* Tush */
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index 15ce478fd687..17c806f2c585 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -283,7 +283,12 @@ typedef struct tagCsrChannel {
typedef struct tagScanProfile {
uint32_t minChnTime;
uint32_t maxChnTime;
- uint32_t restTime; /* This is ignored if not associated */
+ /* In units of milliseconds, ignored when not connected */
+ uint32_t restTime;
+ /* In units of milliseconds, ignored when not connected */
+ uint32_t min_rest_time;
+ /* In units of milliseconds, ignored when not connected */
+ uint32_t idle_time;
uint32_t numOfChannels;
uint8_t *pChannelList;
tSirScanType scanType;
@@ -545,6 +550,11 @@ typedef struct tagCsrConfig {
uint32_t nActiveMinChnTimeConc; /* in units of milliseconds */
uint32_t nActiveMaxChnTimeConc; /* in units of milliseconds */
uint32_t nRestTimeConc; /* in units of milliseconds */
+ /* In units of milliseconds */
+ uint32_t min_rest_time_conc;
+ /* In units of milliseconds */
+ uint32_t idle_time_conc;
+
/* number of channels combined for Sta in each split scan operation */
uint8_t nNumStaChanCombinedConc;
/* number of channels combined for P2P in each split scan operation */
@@ -639,6 +649,7 @@ typedef struct tagCsrConfig {
uint32_t obss_active_dwelltime;
uint32_t obss_passive_dwelltime;
bool ignore_peer_ht_opmode;
+ bool enable_fatal_event;
} tCsrConfig;
typedef struct tagCsrChannelPowerInfo {
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index d836a36a0389..7b74226e7fde 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -988,7 +988,7 @@ bool sme_is_any_session_in_connected_state(tHalHandle h_hal);
QDF_STATUS sme_pdev_set_pcl(tHalHandle hal,
struct sir_pcl_list msg);
-QDF_STATUS sme_soc_set_hw_mode(tHalHandle hal,
+QDF_STATUS sme_pdev_set_hw_mode(tHalHandle hal,
struct sir_hw_mode msg);
void sme_register_hw_mode_trans_cb(tHalHandle hal,
hw_mode_transition_cb callback);
@@ -1096,6 +1096,17 @@ static inline QDF_STATUS sme_send_egap_conf_params(uint32_t enable,
void sme_update_fine_time_measurement_capab(tHalHandle hal, uint32_t val);
QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hHal, uint32_t vdev_id);
+QDF_STATUS sme_set_tsfcb(tHalHandle hHal,
+ int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx);
+
+#ifdef WLAN_FEATURE_TSF
+QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue);
+#else
+static inline QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue)
+{
+ return QDF_STATUS_E_FAILURE;
+}
+#endif
QDF_STATUS sme_update_mimo_power_save(tHalHandle hHal,
uint8_t is_ht_smps_enabled,
@@ -1106,4 +1117,13 @@ bool sme_is_sta_smps_allowed(tHalHandle hHal, uint8_t session_id);
QDF_STATUS sme_add_beacon_filter(tHalHandle hal,
uint32_t session_id, uint32_t *ie_map);
QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id);
+QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal,
+ void (*pbpf_get_offload_cb)(void *,
+ struct sir_bpf_get_offload *));
+
+QDF_STATUS sme_get_bpf_offload_capabilities(tHalHandle hal);
+QDF_STATUS sme_set_bpf_instructions(tHalHandle hal,
+ struct sir_bpf_set_offload *);
+
+QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, uint8_t *bssid);
#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
index 9e27ba2d2307..6414ae8a243e 100644
--- a/core/sme/inc/sme_internal.h
+++ b/core/sme/inc/sme_internal.h
@@ -197,6 +197,8 @@ typedef struct tagSmeStruct {
bool enableSelfRecovery;
tCsrLinkStatusCallback linkStatusCallback;
void *linkStatusContext;
+ int (*get_tsf_cb)(void *pcb_cxt, struct stsf *ptsf);
+ void *get_tsf_cxt;
/* get temperature event context and callback */
void *pTemperatureCbContext;
void (*pGetTemperatureCb)(int temperature, void *context);
@@ -232,7 +234,8 @@ typedef struct tagSmeStruct {
ocb_callback dcc_stats_event_callback;
sme_set_thermal_level_callback set_thermal_level_cb;
void *saved_scan_cmd;
- struct csa_offload_params saved_csa_params;
+ void (*pbpf_get_offload_cb)(void *context,
+ struct sir_bpf_get_offload *);
} tSmeStruct, *tpSmeStruct;
#endif /* #if !defined( __SMEINTERNAL_H ) */
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index c12aef820c50..03a9ee6bcad4 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -155,8 +155,6 @@ static QDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg)
struct sir_set_hw_mode_resp *param;
enum sir_conn_update_reason reason;
tSmeCmd *saved_cmd;
- tCsrRoamInfo roam_info = {0};
- QDF_STATUS status;
sms_log(mac, LOG1, FL("%s"), __func__);
param = (struct sir_set_hw_mode_resp *)msg;
@@ -251,34 +249,6 @@ static QDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg)
saved_cmd = NULL;
mac->sme.saved_scan_cmd = NULL;
}
- } else if (reason == SIR_UPDATE_REASON_CHANNEL_SWITCH) {
- csr_roam_call_callback(mac,
- command->u.set_hw_mode_cmd.session_id,
- &roam_info, 0,
- eCSR_ROAM_STATUS_UPDATE_HW_MODE,
- eCSR_ROAM_RESULT_UPDATE_HW_MODE);
- } else if (reason == SIR_UPDATE_REASON_CHANNEL_SWITCH_STA) {
- struct sir_saved_csa_params *msg;
-
- sms_log(mac, LOG1, FL("process channel switch sta"));
- msg = qdf_mem_malloc(sizeof(*msg));
- if (!msg) {
- sms_log(mac, LOGE,
- FL("memory alloc fail for csa "));
- goto end;
- }
-
- msg->message_type = SIR_LIM_CSA_POST_HW_MODE_CHANGE;
- msg->length = sizeof(*msg);
- msg->session_id = command->u.set_hw_mode_cmd.session_id;
-
- status = cds_send_mb_message_to_mac(msg);
- if (!QDF_IS_STATUS_SUCCESS(status))
- sms_log(mac, LOGE,
- FL("failed to process csa params"));
- else
- sms_log(mac, LOG1,
- FL("csa after hw mode change"));
}
end:
@@ -651,8 +621,16 @@ tSmeCmd *sme_get_command_buffer(tpAniSirGlobal pMac)
sme_command_queue_full++;
csr_ll_unlock(&pMac->roam.roamCmdPendingList);
- /* panic with out-of-command */
- QDF_BUG(0);
+ if (pMac->roam.configParam.enable_fatal_event)
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
+ false,
+ pMac->sme.enableSelfRecovery ? true : false);
+ else if (pMac->sme.enableSelfRecovery)
+ cds_trigger_recovery();
+ else
+ QDF_BUG(0);
}
/* memset to zero */
@@ -2805,6 +2783,14 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg)
qdf_mem_free(pMsg->bodyptr);
}
break;
+ case eWNI_SME_TSF_EVENT:
+ if (pMac->sme.get_tsf_cb) {
+ pMac->sme.get_tsf_cb(pMac->sme.get_tsf_cxt,
+ (struct stsf *)pMsg->bodyptr);
+ }
+ if (pMsg->bodyptr)
+ qdf_mem_free(pMsg->bodyptr);
+ break;
#ifdef WLAN_FEATURE_NAN
case eWNI_SME_NAN_EVENT:
if (pMsg->bodyptr) {
@@ -7300,6 +7286,60 @@ QDF_STATUS sme_preferred_network_found_ind(tHalHandle hHal, void *pMsg)
#endif /* FEATURE_WLAN_SCAN_PNO */
+/*
+ * sme_set_tsfcb() - Set callback for TSF capture
+ * @h_hal: Handler return by mac_open
+ * @cb_fn: Callback function pointer
+ * @db_ctx: Callback data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_tsfcb(tHalHandle h_hal,
+ int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx)
+{
+ tpAniSirGlobal mac = PMAC_STRUCT(h_hal);
+ QDF_STATUS status;
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ mac->sme.get_tsf_cb = cb_fn;
+ mac->sme.get_tsf_cxt = cb_ctx;
+ sme_release_global_lock(&mac->sme);
+ }
+ return status;
+}
+
+#ifdef WLAN_FEATURE_TSF
+/*
+ * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tef
+ * @h_hal: Handler return by mac_open
+ * @pinvalue: gpio pin id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue)
+{
+ QDF_STATUS status;
+ cds_msg_t tsf_msg = {0};
+ tpAniSirGlobal mac = PMAC_STRUCT(h_hal);
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ tsf_msg.type = WMA_TSF_GPIO_PIN;
+ tsf_msg.reserved = 0;
+ tsf_msg.bodyval = pinvalue;
+
+ status = cds_mq_post_message(CDS_MQ_ID_WMA, &tsf_msg);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ sms_log(mac, LOGE, "Unable to post WMA_TSF_GPIO_PIN");
+ status = QDF_STATUS_E_FAILURE;
+ }
+ sme_release_global_lock(&mac->sme);
+ }
+ return status;
+}
+#endif
+
QDF_STATUS sme_get_cfg_valid_channels(tHalHandle hHal, uint8_t *aValidChannels,
uint32_t *len)
{
@@ -11650,19 +11690,41 @@ void sme_save_active_cmd_stats(tHalHandle hHal)
void active_list_cmd_timeout_handle(void *userData)
{
- if (NULL == userData)
- return;
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
- "%s: Active List command timeout Cmd List Count %d", __func__,
- csr_ll_count(&((tpAniSirGlobal) userData)->sme.
- smeCmdActiveList));
- sme_get_command_q_status((tHalHandle) userData);
+ tHalHandle hal = (tHalHandle)userData;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
- if (((tpAniSirGlobal) userData)->sme.enableSelfRecovery) {
- sme_save_active_cmd_stats((tHalHandle) userData);
+ if (NULL == mac_ctx) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: mac_ctx is null", __func__);
+ return;
+ }
+ /* Return if no cmd pending in active list as
+ * in this case we should not be here.
+ */
+ if (0 == csr_ll_count(&mac_ctx->sme.smeCmdActiveList))
+ return;
+ sms_log(mac_ctx, LOGE,
+ FL("Active List command timeout Cmd List Count %d"),
+ csr_ll_count(&mac_ctx->sme.smeCmdActiveList));
+ sme_get_command_q_status(hal);
+
+ if (mac_ctx->roam.configParam.enable_fatal_event)
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_SME_COMMAND_STUCK,
+ false,
+ mac_ctx->sme.enableSelfRecovery ? true : false);
+ else
+ qdf_trace_dump_all(mac_ctx, 0, 0, 500, 0);
+
+ if (mac_ctx->sme.enableSelfRecovery) {
+ sme_save_active_cmd_stats(hal);
cds_trigger_recovery();
} else {
- QDF_BUG(0);
+ if (!mac_ctx->roam.configParam.enable_fatal_event &&
+ !(cds_is_load_or_unload_in_progress() ||
+ cds_is_driver_recovering()))
+ QDF_BUG(0);
}
}
@@ -14383,7 +14445,7 @@ QDF_STATUS sme_wifi_start_logger(tHalHandle hal,
status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sms_log(mac, LOGE,
- FL("vos_mq_post_message failed!(err=%d)"),
+ FL("cds_mq_post_message failed!(err=%d)"),
status);
qdf_mem_free(req_msg);
status = QDF_STATUS_E_FAILURE;
@@ -14856,14 +14918,14 @@ QDF_STATUS sme_pdev_set_pcl(tHalHandle hal,
}
/*
- * sme_soc_set_hw_mode() - Send WMI_SOC_SET_HW_MODE_CMDID to the WMA
+ * sme_pdev_set_hw_mode() - Send WMI_PDEV_SET_HW_MODE_CMDID to the WMA
* @hal: Handle returned by macOpen
* @msg: HW mode structure containing hw mode and callback details
*
- * Sends the command to CSR to send WMI_SOC_SET_HW_MODE_CMDID to FW
+ * Sends the command to CSR to send WMI_PDEV_SET_HW_MODE_CMDID to FW
* Return: QDF_STATUS_SUCCESS on successful posting
*/
-QDF_STATUS sme_soc_set_hw_mode(tHalHandle hal,
+QDF_STATUS sme_pdev_set_hw_mode(tHalHandle hal,
struct sir_hw_mode msg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -15567,3 +15629,150 @@ QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id)
}
return qdf_status;
}
+
+/**
+ * sme_get_bpf_offload_capabilities() - Get length for BPF offload
+ * @hal: Global HAL handle
+ * This function constructs the cds message and fill in message type,
+ * post the same to WDA.
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_get_bpf_offload_capabilities(tHalHandle hal)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ cds_msg_t cds_msg;
+
+ sms_log(mac_ctx, LOG1, FL("enter"));
+
+ status = sme_acquire_global_lock(&mac_ctx->sme);
+ if (QDF_STATUS_SUCCESS == status) {
+ /* Serialize the req through MC thread */
+ cds_msg.bodyptr = NULL;
+ cds_msg.type = WDA_BPF_GET_CAPABILITIES_REQ;
+ status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Post bpf get offload msg fail"));
+ status = QDF_STATUS_E_FAILURE;
+ }
+ sme_release_global_lock(&mac_ctx->sme);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("sme_acquire_global_lock error"));
+ }
+ sms_log(mac_ctx, LOG1, FL("exit"));
+ return status;
+}
+
+
+/**
+ * sme_set_bpf_instructions() - Set BPF bpf filter instructions.
+ * @hal: HAL handle
+ * @bpf_set_offload: struct to set bpf filter instructions.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_set_bpf_instructions(tHalHandle hal,
+ struct sir_bpf_set_offload *req)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ cds_msg_t cds_msg;
+ struct sir_bpf_set_offload *set_offload;
+
+ set_offload = qdf_mem_malloc(sizeof(*set_offload));
+
+ if (NULL == set_offload) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Failed to alloc set_offload"));
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ set_offload->session_id = req->session_id;
+ set_offload->filter_id = req->filter_id;
+ set_offload->current_offset = req->current_offset;
+ set_offload->total_length = req->total_length;
+ if (set_offload->total_length) {
+ set_offload->current_length = req->current_length;
+ set_offload->program = qdf_mem_malloc(sizeof(uint8_t) *
+ req->current_length);
+ qdf_mem_copy(set_offload->program, req->program,
+ set_offload->current_length);
+ }
+ status = sme_acquire_global_lock(&mac_ctx->sme);
+ if (QDF_STATUS_SUCCESS == status) {
+ /* Serialize the req through MC thread */
+ cds_msg.bodyptr = set_offload;
+ cds_msg.type = WDA_BPF_SET_INSTRUCTIONS_REQ;
+ status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg);
+
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Post BPF set offload msg fail"));
+ status = QDF_STATUS_E_FAILURE;
+ if (set_offload->total_length)
+ qdf_mem_free(set_offload->program);
+ qdf_mem_free(set_offload);
+ }
+ sme_release_global_lock(&mac_ctx->sme);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("sme_acquire_global_lock failed"));
+ if (set_offload->total_length)
+ qdf_mem_free(set_offload->program);
+ qdf_mem_free(set_offload);
+ }
+ return status;
+}
+
+/**
+ * sme_bpf_offload_register_callback() - Register get bpf offload callbacK
+ *
+ * @hal - MAC global handle
+ * @callback_routine - callback routine from HDD
+ *
+ * This API is invoked by HDD to register its callback in SME
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal,
+ void (*pbpf_get_offload_cb)(void *context,
+ struct sir_bpf_get_offload *))
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ mac->sme.pbpf_get_offload_cb = pbpf_get_offload_cb;
+ sme_release_global_lock(&mac->sme);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("sme_acquire_global_lock failed"));
+ }
+ return status;
+}
+
+/**
+ * sme_create_mon_session() - post message to create PE session for monitormode
+ * operation
+ * @hal_handle: Handle to the HAL
+ * @bssid: pointer to bssid
+ *
+ * Return: QDF_STATUS_SUCCESS on success, non-zero error code on failure.
+ */
+QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id)
+{
+ QDF_STATUS status = QDF_STATUS_E_FAILURE;
+ struct sir_create_session *msg;
+
+ msg = qdf_mem_malloc(sizeof(*msg));
+ if (NULL != msg) {
+ msg->type = eWNI_SME_MON_INIT_SESSION;
+ msg->msg_len = sizeof(*msg);
+ qdf_mem_copy(msg->bss_id.bytes, bss_id, QDF_MAC_ADDR_SIZE);
+ status = cds_send_mb_message_to_mac(msg);
+ }
+ return status;
+}
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index ee72ae9a44c9..0326f313a30c 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -1292,6 +1292,8 @@ static void init_config_param(tpAniSirGlobal pMac)
pMac->roam.configParam.nPassiveMinChnTimeConc =
CSR_PASSIVE_MIN_CHANNEL_TIME_CONC;
pMac->roam.configParam.nRestTimeConc = CSR_REST_TIME_CONC;
+ pMac->roam.configParam.min_rest_time_conc = CSR_MIN_REST_TIME_CONC;
+ pMac->roam.configParam.idle_time_conc = CSR_IDLE_TIME_CONC;
pMac->roam.configParam.nNumStaChanCombinedConc =
CSR_NUM_STA_CHAN_COMBINED_CONC;
pMac->roam.configParam.nNumP2PChanCombinedConc =
@@ -2057,10 +2059,11 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pMac->roam.configParam.nPassiveMinChnTimeConc =
pParam->nPassiveMinChnTimeConc;
}
- if (pParam->nRestTimeConc) {
- pMac->roam.configParam.nRestTimeConc =
- pParam->nRestTimeConc;
- }
+ pMac->roam.configParam.nRestTimeConc = pParam->nRestTimeConc;
+ pMac->roam.configParam.min_rest_time_conc =
+ pParam->min_rest_time_conc;
+ pMac->roam.configParam.idle_time_conc = pParam->idle_time_conc;
+
if (pParam->nNumStaChanCombinedConc) {
pMac->roam.configParam.nNumStaChanCombinedConc =
pParam->nNumStaChanCombinedConc;
@@ -2353,6 +2356,8 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pParam->early_stop_scan_min_threshold;
pMac->roam.configParam.early_stop_scan_max_threshold =
pParam->early_stop_scan_max_threshold;
+ pMac->roam.configParam.enable_fatal_event =
+ pParam->enable_fatal_event;
}
return status;
@@ -2398,6 +2403,8 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pParam->nPassiveMaxChnTimeConc = cfg_params->nPassiveMaxChnTimeConc;
pParam->nPassiveMinChnTimeConc = cfg_params->nPassiveMinChnTimeConc;
pParam->nRestTimeConc = cfg_params->nRestTimeConc;
+ pParam->min_rest_time_conc = cfg_params->min_rest_time_conc;
+ pParam->idle_time_conc = cfg_params->idle_time_conc;
pParam->nNumStaChanCombinedConc = cfg_params->nNumStaChanCombinedConc;
pParam->nNumP2PChanCombinedConc = cfg_params->nNumP2PChanCombinedConc;
#endif
@@ -2536,6 +2543,8 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pParam->enableHtSmps = pMac->roam.configParam.enableHtSmps;
pParam->htSmps = pMac->roam.configParam.htSmps;
pParam->send_smps_action = pMac->roam.configParam.send_smps_action;
+ pParam->enable_fatal_event =
+ pMac->roam.configParam.enable_fatal_event;
return QDF_STATUS_SUCCESS;
}
@@ -5942,7 +5951,6 @@ static void csr_roam_copy_ht_profile(tCsrRoamHTProfile *dst_profile,
dst_profile->htSecondaryChannelOffset =
src_profile->htSecondaryChannelOffset;
dst_profile->vhtCapability = src_profile->vhtCapability;
- dst_profile->vhtTxChannelWidthSet = src_profile->vhtTxChannelWidthSet;
dst_profile->apCenterChan = src_profile->apCenterChan;
dst_profile->apChanWidth = src_profile->apChanWidth;
}
@@ -8672,6 +8680,10 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac,
"CSR SmeReassocReq failed with statusCode= 0x%08X [%d]",
pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode);
result = eCsrReassocFailure;
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_ROAM_FAIL,
+ true, false);
if ((eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE ==
pSmeJoinRsp->statusCode)
|| (eSIR_SME_FT_REASSOC_FAILURE ==
@@ -10250,6 +10262,7 @@ csr_roam_chk_lnk_swt_ch_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
uint32_t sessionId = CSR_SESSION_ID_INVALID;
QDF_STATUS status;
tpSirSmeSwitchChannelInd pSwitchChnInd;
+ tCsrRoamInfo roamInfo;
/* in case of STA, the SWITCH_CHANNEL originates from its AP */
sms_log(mac_ctx, LOGW, FL("eWNI_SME_SWITCH_CHL_IND from SME"));
@@ -10272,6 +10285,12 @@ csr_roam_chk_lnk_swt_ch_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
session->pConnectBssDesc->channelId =
(uint8_t) pSwitchChnInd->newChannelId;
}
+
+ qdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+ roamInfo.chan_info.chan_id = pSwitchChnInd->newChannelId;
+ status = csr_roam_call_callback(mac_ctx, sessionId,
+ &roamInfo, 0, eCSR_ROAM_STA_CHANNEL_SWITCH,
+ eCSR_ROAM_RESULT_NONE);
}
}
@@ -18709,6 +18728,7 @@ void csr_roam_synch_callback(tpAniSirGlobal mac_ctx,
struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
tpAddBssParams add_bss_params;
QDF_STATUS status = QDF_STATUS_SUCCESS;
+ uint16_t len;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
tSirSmeHTProfile *src_profile = NULL;
tCsrRoamHTProfile *dst_profile = NULL;
@@ -18869,6 +18889,19 @@ void csr_roam_synch_callback(tpAniSirGlobal mac_ctx,
FL("LFR3:Clear Connected info"));
csr_roam_free_connected_info(mac_ctx,
&session->connectedInfo);
+ len = roam_synch_data->join_rsp->parsedRicRspLen;
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+ FL("LFR3: RIC length - %d"), len);
+ if (len) {
+ session->connectedInfo.pbFrames =
+ qdf_mem_malloc(len);
+ if (session->connectedInfo.pbFrames != NULL) {
+ qdf_mem_copy(session->connectedInfo.pbFrames,
+ roam_synch_data->join_rsp->frames, len);
+ session->connectedInfo.nRICRspLength =
+ roam_synch_data->join_rsp->parsedRicRspLen;
+ }
+ }
conn_profile->vht_channel_width =
roam_synch_data->join_rsp->vht_channel_width;
add_bss_params = (tpAddBssParams)roam_synch_data->add_bss_params;
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
index 87ceec5baa58..c337db354395 100644
--- a/core/sme/src/csr/csr_api_scan.c
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -256,6 +256,11 @@ static void csr_set_default_scan_timing(tpAniSirGlobal pMac, tSirScanType scanTy
}
pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc;
+ pScanRequest->min_rest_time =
+ pMac->roam.configParam.min_rest_time_conc;
+ pScanRequest->idle_time =
+ pMac->roam.configParam.idle_time_conc;
+
/* Return so that fields set above will not be overwritten. */
return;
}
@@ -278,8 +283,12 @@ static void csr_set_default_scan_timing(tpAniSirGlobal pMac, tSirScanType scanTy
pMac->roam.configParam.nPassiveMinChnTime;
}
#ifdef WLAN_AP_STA_CONCURRENCY
- /* No rest time if no sessions are connected. */
+
+ /* No rest time/Idle time if no sessions are connected. */
pScanRequest->restTime = 0;
+ pScanRequest->min_rest_time = 0;
+ pScanRequest->idle_time = 0;
+
#endif
}
@@ -546,9 +555,14 @@ QDF_STATUS csr_scan_request(tpAniSirGlobal pMac, uint16_t sessionId,
scan_req->minChnTime, scan_req->maxChnTime);
}
#ifdef WLAN_AP_STA_CONCURRENCY
- /* Need to set restTime only if at least one session is connected */
+ /*
+ * Need to set restTime/min_Ret_time/idle_time
+ * only if at least one session is connected
+ */
if (scan_req->restTime == 0 && csr_is_any_session_connected(pMac)) {
scan_req->restTime = cfg_prm->nRestTimeConc;
+ scan_req->min_rest_time = cfg_prm->min_rest_time_conc;
+ scan_req->idle_time = cfg_prm->idle_time_conc;
if (scan_req->scanType == eSIR_ACTIVE_SCAN) {
scan_req->maxChnTime = cfg_prm->nActiveMaxChnTimeConc;
scan_req->minChnTime = cfg_prm->nActiveMinChnTimeConc;
@@ -2916,8 +2930,8 @@ static void csr_move_temp_scan_results_to_main_list(tpAniSirGlobal pMac,
return;
}
}
- csr_elected_country_info(pMac);
- csr_learn_11dcountry_information(pMac, NULL, NULL, true);
+ if (csr_elected_country_info(pMac))
+ csr_learn_11dcountry_information(pMac, NULL, NULL, true);
}
static tCsrScanResult *csr_scan_save_bss_description(tpAniSirGlobal pMac,
@@ -3313,6 +3327,8 @@ bool csr_elected_country_info(tpAniSirGlobal pMac)
uint8_t i, j = 0;
if (!pMac->scan.countryCodeCount) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
+ "No AP with 11d Country code is present in scan list");
return fRet;
}
maxVotes = pMac->scan.votes11d[0].votes;
@@ -4162,6 +4178,11 @@ bool csr_scan_complete(tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp)
pCommand->u.scanCmd.abortScanDueToBandChange = false;
}
csr_save_scan_results(pMac, pCommand->u.scanCmd.reason, sessionId);
+ /* filter scan result based on valid channel list number */
+ if (pMac->scan.fcc_constraint) {
+ sms_log(pMac, LOG1, FL("Clear BSS from invalid channels"));
+ csr_scan_filter_results(pMac);
+ }
#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
csr_diag_scan_complete(pMac, pCommand, pScanRsp);
#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
@@ -4984,8 +5005,12 @@ QDF_STATUS csr_send_mb_scan_req(tpAniSirGlobal pMac, uint16_t sessionId,
pMsg->maxChannelTime = maxChnTime;
/* hidden SSID option */
pMsg->hiddenSsid = pScanReqParam->hiddenSsid;
- /* rest time */
+ /* maximum rest time */
pMsg->restTime = pScanReq->restTime;
+ /* Minimum rest time */
+ pMsg->min_rest_time = pScanReq->min_rest_time;
+ /* Idle time */
+ pMsg->idle_time = pScanReq->idle_time;
pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch;
/* All the scan results caching will be done by Roaming */
/* We do not want LIM to do any caching of scan results, */
@@ -7244,6 +7269,8 @@ void csr_scan_active_list_timeout_handle(void *userData)
FL(" Failed to post message to LIM"));
qdf_mem_free(msg);
}
+ csr_save_scan_results(mac_ctx, scan_cmd->u.scanCmd.reason,
+ scan_cmd->sessionId);
csr_release_scan_command(mac_ctx, scan_cmd, eCSR_SCAN_FAILURE);
return;
}
diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h
index 829c4f604b64..5537bf317f39 100644
--- a/core/sme/src/csr/csr_inside_api.h
+++ b/core/sme/src/csr/csr_inside_api.h
@@ -53,6 +53,8 @@
#define CSR_ACTIVE_MIN_CHANNEL_TIME_CONC 20
#define CSR_REST_TIME_CONC 100
+#define CSR_MIN_REST_TIME_CONC 50
+#define CSR_IDLE_TIME_CONC 25
#define CSR_NUM_STA_CHAN_COMBINED_CONC 3
#define CSR_NUM_P2P_CHAN_COMBINED_CONC 1
diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c
index 4667d82ef3ab..e285f5394a84 100644
--- a/core/sme/src/csr/csr_neighbor_roam.c
+++ b/core/sme/src/csr/csr_neighbor_roam.c
@@ -1397,8 +1397,8 @@ static void csr_neighbor_roam_info_ctx_init(
ngbr_roam_info->is11rAssoc = true;
} else
ngbr_roam_info->is11rAssoc = false;
- NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"),
- ngbr_roam_info->is11rAssoc);
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH,
+ FL("11rAssoc is = %d"), ngbr_roam_info->is11rAssoc);
#ifdef FEATURE_WLAN_ESE
/* Based on the auth scheme tell if we are 11r */
@@ -1408,9 +1408,9 @@ static void csr_neighbor_roam_info_ctx_init(
ngbr_roam_info->isESEAssoc = true;
} else
ngbr_roam_info->isESEAssoc = false;
- NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
- FL("isESEAssoc is = %d ft = %d"),
- ngbr_roam_info->isESEAssoc, init_ft_flag);
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH,
+ FL("isESEAssoc is = %d ft = %d"),
+ ngbr_roam_info->isESEAssoc, init_ft_flag);
#endif
/* If "Legacy Fast Roaming" is enabled */
if (csr_roam_is_fast_roam_enabled(pMac, session_id))
diff --git a/core/sme/src/csr/csr_tdls_process.c b/core/sme/src/csr/csr_tdls_process.c
index d6baf4ea1525..bfd589fb4b6d 100644
--- a/core/sme/src/csr/csr_tdls_process.c
+++ b/core/sme/src/csr/csr_tdls_process.c
@@ -129,6 +129,8 @@ QDF_STATUS csr_tdls_send_mgmt_req(tHalHandle hHal, uint8_t sessionId,
tdlsSendMgmtCmd->u.tdlsCmd.size = sizeof(tTdlsSendMgmtCmdInfo);
sme_push_command(pMac, tdlsSendMgmtCmd, false);
status = QDF_STATUS_SUCCESS;
+ sms_log(pMac, LOG1,
+ FL("Successfully posted eSmeCommandTdlsSendMgmt to SME"));
return status;
}
@@ -201,6 +203,8 @@ QDF_STATUS csr_tdls_change_peer_sta(tHalHandle hHal, uint8_t sessionId,
sizeof(tTdlsAddStaCmdInfo);
sme_push_command(pMac, tdlsAddStaCmd, false);
status = QDF_STATUS_SUCCESS;
+ sms_log(pMac, LOG1,
+ FL("Successfully posted eSmeCommandTdlsAddPeer to SME to modify peer "));
}
}
@@ -271,6 +275,8 @@ QDF_STATUS csr_tdls_send_link_establish_params(tHalHandle hHal,
sizeof(tTdlsLinkEstablishCmdInfo);
sme_push_command(pMac, tdlsLinkEstablishCmd, false);
status = QDF_STATUS_SUCCESS;
+ sms_log(pMac, LOG1,
+ FL("Successfully posted eSmeCommandTdlsLinkEstablish to SME"));
}
}
@@ -308,6 +314,8 @@ QDF_STATUS csr_tdls_add_peer_sta(tHalHandle hHal, uint8_t sessionId,
sizeof(tTdlsAddStaCmdInfo);
sme_push_command(pMac, tdlsAddStaCmd, false);
status = QDF_STATUS_SUCCESS;
+ sms_log(pMac, LOG1,
+ FL("Successfully posted eSmeCommandTdlsAddPeer to SME"));
}
}
@@ -344,6 +352,8 @@ QDF_STATUS csr_tdls_del_peer_sta(tHalHandle hHal, uint8_t sessionId,
sizeof(tTdlsDelStaCmdInfo);
sme_push_command(pMac, tdlsDelStaCmd, false);
status = QDF_STATUS_SUCCESS;
+ sms_log(pMac, LOG1,
+ FL("Successfully posted eSmeCommandTdlsDelPeer to SME"));
}
}
@@ -423,7 +433,7 @@ QDF_STATUS csr_tdls_process_send_mgmt(tpAniSirGlobal pMac, tSmeCmd *cmd)
}
/* Send the request to PE. */
- sms_log(pMac, LOG1, "sending TDLS Mgmt Frame req to PE ");
+ sms_log(pMac, LOG1, FL("sending TDLS Mgmt Frame req to PE "));
status = tdls_send_message(pMac, eWNI_SME_TDLS_SEND_MGMT_REQ,
(void *)tdlsSendMgmtReq,
sizeof(tSirTdlsSendMgmtReq) +
diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c
index 1a3a2b67d7fb..7e44a7c12371 100644
--- a/core/sme/src/csr/csr_util.c
+++ b/core/sme/src/csr/csr_util.c
@@ -788,7 +788,9 @@ uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx,
(intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq))))
intf_ch = 0;
} else if (intf_ch && sap_ch != intf_ch &&
- cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE) {
+ ((cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE) ||
+ (cc_switch_mode ==
+ QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION))) {
if (!((intf_ch < 14 && sap_ch < 14) ||
(intf_ch > 14 && sap_ch > 14)))
intf_ch = 0;
diff --git a/core/sme/src/qos/sme_qos.c b/core/sme/src/qos/sme_qos.c
index 1aaf22a735b5..641943e38f76 100644
--- a/core/sme/src/qos/sme_qos.c
+++ b/core/sme/src/qos/sme_qos.c
@@ -4632,7 +4632,12 @@ QDF_STATUS sme_qos_process_reassoc_success_ev(tpAniSirGlobal mac_ctx,
if (csr_roam_session &&
csr_roam_session->connectedInfo.nRICRspLength) {
status = sme_qos_process_ft_reassoc_rsp_ev(
- mac_ctx, sessionid, event_info);
+ mac_ctx, sessionid,
+ event_info);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SME,
+ QDF_TRACE_LEVEL_ERROR, FL(
+ "session or RIC data is not present"));
}
}
#ifdef FEATURE_WLAN_ESE
diff --git a/core/utils/epping/inc/epping_internal.h b/core/utils/epping/inc/epping_internal.h
index 664076d7a523..3ae69fbfe09f 100644
--- a/core/utils/epping/inc/epping_internal.h
+++ b/core/utils/epping/inc/epping_internal.h
@@ -111,7 +111,7 @@ typedef struct epping_context {
void *p_cds_context; /* CDS context */
struct device *parent_dev; /* Pointer to the parent device */
epping_ctx_state_t e_ctx_state;
- int wow_nack;
+ bool wow_nack;
void *epping_adapter;
HTC_HANDLE HTCHandle;
HTC_ENDPOINT_ID EppingEndpoint[EPPING_MAX_NUM_EPIDS];
diff --git a/core/utils/epping/inc/epping_main.h b/core/utils/epping/inc/epping_main.h
index 6d29f0f175a7..813109fecade 100644
--- a/core/utils/epping/inc/epping_main.h
+++ b/core/utils/epping/inc/epping_main.h
@@ -41,10 +41,6 @@
#include <qdf_lock.h>
#include <qdf_types.h>
-#define WLAN_IS_EPPING_ENABLED(x) (x == QDF_GLOBAL_EPPING_MODE)
-#define WLAN_IS_EPPING_IRQ(x) 1
-#define WLAN_IS_EPPING_FW_UART(x) 0
-
/* epping_main signatures */
int epping_open(void);
void epping_close(void);
diff --git a/core/utils/epping/src/epping_main.c b/core/utils/epping/src/epping_main.c
index a0ebc9cc9b7d..44ddc824b9ca 100644
--- a/core/utils/epping/src/epping_main.c
+++ b/core/utils/epping/src/epping_main.c
@@ -151,10 +151,13 @@ void epping_close(void)
qdf_mem_free(to_free);
}
-static void epping_target_suspend_acknowledge(void *context)
+/**
+ * epping_target_suspend_acknowledge() - process wow ack/nack from fw
+ * @context: HTC_INIT_INFO->context
+ * @wow_nack: true when wow is rejected
+ */
+static void epping_target_suspend_acknowledge(void *context, bool wow_nack)
{
- int wow_nack = *((int *)context);
-
if (NULL == g_epping_ctx) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: epping_ctx is NULL", __func__);
@@ -165,6 +168,27 @@ static void epping_target_suspend_acknowledge(void *context)
}
/**
+ * epping_update_ol_config - API to update ol configuration parameters
+ *
+ * Return: void
+ */
+static void epping_update_ol_config(void)
+{
+ struct ol_config_info cfg;
+ struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
+
+ if (!ol_ctx)
+ return;
+
+ cfg.enable_self_recovery = 0;
+ cfg.enable_uart_print = 0;
+ cfg.enable_fw_log = 0;
+ cfg.enable_ramdump_collection = 0;
+ cfg.enable_lpass_support = 0;
+
+ ol_init_ini_config(ol_ctx, &cfg);
+}
+/**
* epping_enable(): End point ping driver enable Function
*
* This is the driver enable function - called by HDD to enable
@@ -221,6 +245,7 @@ int epping_enable(struct device *parent_dev)
pEpping_ctx->target_type = tgt_info->target_type;
ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
+ epping_update_ol_config();
#ifndef FEATURE_BMI_2
/* Initialize BMI and Download firmware */
if (bmi_download_firmware(ol_ctx)) {
diff --git a/core/utils/host_diag_log/inc/host_diag_core_event.h b/core/utils/host_diag_log/inc/host_diag_core_event.h
index 0c8d963e7389..c7cce228a80a 100644
--- a/core/utils/host_diag_log/inc/host_diag_core_event.h
+++ b/core/utils/host_diag_log/inc/host_diag_core_event.h
@@ -299,6 +299,86 @@ struct host_event_wlan_log_complete {
uint32_t reserved;
};
+/**
+ * struct host_event_tdls_teardown - tdls teardown diag event
+ * @reason: reason for tear down
+ * @peer_mac: peer mac
+ *
+ * This structure contains tdls teardown diag event info
+ */
+struct host_event_tdls_teardown {
+ uint32_t reason;
+ uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
+};
+
+/**
+ * struct host_event_tdls_enable_link - tdls enable link event
+ * @peer_mac: peer mac
+ * @is_off_chan_supported: if off channel supported
+ * @is_off_chan_configured: if off channel configured
+ * @is_off_chan_established: if off channel established
+ *
+ * This structure contain tdls enable link diag event info
+ */
+struct host_event_tdls_enable_link {
+ uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
+ uint8_t is_off_chan_supported;
+ uint8_t is_off_chan_configured;
+ uint8_t is_off_chan_established;
+};
+
+/**
+ * struct host_event_suspend - suspend/resume state
+ * @state: suspend/resume state
+ *
+ * This structure contains suspend resume diag event info
+ */
+struct host_event_suspend {
+ uint8_t state;
+};
+
+/**
+ * struct host_event_offload_req - offload state
+ * @offload_type: offload type
+ * @state: enabled or disabled state
+ *
+ * This structure contains offload diag event info
+ */
+struct host_event_offload_req {
+ uint8_t offload_type;
+ uint8_t state;
+};
+
+/**
+ * struct host_event_tdls_scan_rejected - scan
+ * rejected due to tdls
+ * @status: rejected status
+ *
+ * This structure contains scan rejected due to
+ * tdls event info
+ */
+struct host_event_tdls_scan_rejected {
+ uint8_t status;
+};
+
+/**
+ * struct host_event_tdls_tx_rx_mgmt - for TX RX management frame
+ * @event_id: event ID
+ * @tx_rx: tx or rx
+ * @type: type of frame
+ * @action_sub_type: action frame type
+ * @peer_mac: peer mac
+ *
+ * This structure contains tdls TX RX management frame info
+ */
+struct host_event_tdls_tx_rx_mgmt {
+ uint8_t event_id;
+ uint8_t tx_rx;
+ uint8_t type;
+ uint8_t action_sub_type;
+ uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
+};
+
/*-------------------------------------------------------------------------
Function declarations and documenation
------------------------------------------------------------------------*/
diff --git a/core/utils/host_diag_log/inc/host_diag_event_defs.h b/core/utils/host_diag_log/inc/host_diag_event_defs.h
index ca250c592db2..6b658ba37b81 100644
--- a/core/utils/host_diag_log/inc/host_diag_event_defs.h
+++ b/core/utils/host_diag_log/inc/host_diag_event_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -54,6 +54,12 @@ typedef enum {
EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */
EVENT_WLAN_BEACON_RECEIVED = 0xAA6, /* FW event: 2726 */
EVENT_WLAN_LOG_COMPLETE = 0xAA7, /* 16 bytes payload */
+ EVENT_WLAN_TDLS_TEARDOWN = 0xAB5,
+ EVENT_WLAN_TDLS_ENABLE_LINK = 0XAB6,
+ EVENT_WLAN_SUSPEND_RESUME = 0xAB7,
+ EVENT_WLAN_OFFLOAD_REQ = 0xAB8,
+ EVENT_TDLS_SCAN_BLOCK = 0xAB9,
+ EVENT_WLAN_TDLS_TX_RX_MGMT = 0xABA,
EVENT_MAX_ID = 0x0FFF
} event_id_enum_type;
diff --git a/core/utils/logging/inc/wlan_logging_sock_svc.h b/core/utils/logging/inc/wlan_logging_sock_svc.h
index 1850a0138466..d0b76d1aed9a 100644
--- a/core/utils/logging/inc/wlan_logging_sock_svc.h
+++ b/core/utils/logging/inc/wlan_logging_sock_svc.h
@@ -46,6 +46,7 @@ int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length);
void wlan_logging_set_per_pkt_stats(void);
void wlan_logging_set_log_level(void);
void wlan_logging_set_fw_flush_complete(void);
+void wlan_flush_host_logs_for_fatal(void);
#ifdef FEATURE_WLAN_DIAG_SUPPORT
void wlan_report_log_completion(uint32_t is_fatal,
uint32_t indicator,
@@ -57,5 +58,9 @@ static inline void wlan_report_log_completion(uint32_t is_fatal,
{
return;
}
+static inline void wlan_flush_host_logs_for_fatal(void)
+{
+}
+
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
#endif /* WLAN_LOGGING_SOCK_SVC_H */
diff --git a/core/utils/logging/src/wlan_logging_sock_svc.c b/core/utils/logging/src/wlan_logging_sock_svc.c
index 15687a2f7e15..c0c854f05bd4 100644
--- a/core/utils/logging/src/wlan_logging_sock_svc.c
+++ b/core/utils/logging/src/wlan_logging_sock_svc.c
@@ -39,6 +39,7 @@
#include <wlan_ptt_sock_svc.h>
#include "pktlog_ac.h"
#include <host_diag_core_event.h>
+#include "cds_utils.h"
#define LOGGING_TRACE(level, args ...) \
QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args)
@@ -505,14 +506,19 @@ void wlan_report_log_completion(uint32_t is_fatal,
void send_flush_completion_to_user(void)
{
uint32_t is_fatal, indicator, reason_code;
+ bool recovery_needed;
- cds_get_log_completion(&is_fatal, &indicator, &reason_code);
+ cds_get_and_reset_log_completion(&is_fatal,
+ &indicator, &reason_code, &recovery_needed);
/* Error on purpose, so that it will get logged in the kmsg */
LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR,
"%s: Sending flush done to userspace", __func__);
wlan_report_log_completion(is_fatal, indicator, reason_code);
+
+ if (recovery_needed)
+ cds_trigger_recovery();
}
/**
@@ -525,6 +531,7 @@ static int wlan_logging_thread(void *Arg)
{
int ret_wait_status = 0;
int ret = 0;
+ unsigned long flags;
set_user_nice(current, -2);
@@ -561,6 +568,10 @@ static int wlan_logging_thread(void *Arg)
ret = send_filled_buffers_to_user();
if (-ENOMEM == ret)
msleep(200);
+ if (WLAN_LOG_INDICATOR_HOST_ONLY ==
+ cds_get_log_indicator()) {
+ send_flush_completion_to_user();
+ }
}
if (test_and_clear_bit(HOST_LOG_PER_PKT_STATS,
@@ -582,6 +593,12 @@ static int wlan_logging_thread(void *Arg)
send_flush_completion_to_user();
} else {
gwlan_logging.is_flush_complete = true;
+ /* Flush all current host logs*/
+ spin_lock_irqsave(&gwlan_logging.spin_lock,
+ flags);
+ wlan_queue_logmsg_for_app();
+ spin_unlock_irqrestore(&gwlan_logging.spin_lock,
+ flags);
set_bit(HOST_LOG_DRIVER_MSG,
&gwlan_logging.eventFlag);
set_bit(HOST_LOG_PER_PKT_STATS,
@@ -804,10 +821,35 @@ void wlan_logging_set_log_level(void)
*/
void wlan_logging_set_fw_flush_complete(void)
{
- if (gwlan_logging.is_active == false)
+ if (gwlan_logging.is_active == false ||
+ !cds_is_fatal_event_enabled())
return;
set_bit(HOST_LOG_FW_FLUSH_COMPLETE, &gwlan_logging.eventFlag);
wake_up_interruptible(&gwlan_logging.wait_queue);
}
+
+/**
+ * wlan_flush_host_logs_for_fatal() - Flush host logs
+ *
+ * This function is used to send signal to the logger thread to
+ * Flush the host logs
+ *
+ * Return: None
+ */
+void wlan_flush_host_logs_for_fatal(void)
+{
+ unsigned long flags;
+
+ if (cds_is_log_report_in_progress()) {
+ pr_info("%s:flush all host logs Setting HOST_LOG_POST_MASK\n",
+ __func__);
+ spin_lock_irqsave(&gwlan_logging.spin_lock, flags);
+ wlan_queue_logmsg_for_app();
+ spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags);
+ set_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag);
+ wake_up_interruptible(&gwlan_logging.wait_queue);
+ }
+}
+
#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */
diff --git a/core/utils/nlink/src/wlan_nlink_srv.c b/core/utils/nlink/src/wlan_nlink_srv.c
index 80055a64f656..d3b56faef10b 100644
--- a/core/utils/nlink/src/wlan_nlink_srv.c
+++ b/core/utils/nlink/src/wlan_nlink_srv.c
@@ -258,9 +258,6 @@ static void nl_srv_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return;
}
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
- "NLINK: Received NL msg type [%d]", type);
-
/* turn type into dispatch table offset */
type -= WLAN_NL_MSG_BASE;
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index ff9dca2f5a70..3f1ac3b5fac4 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -63,6 +63,15 @@
#define WMA_CRASH_INJECT_TIMEOUT 5000
+/* MAC ID to PDEV ID mapping is as given below
+ * MAC_ID PDEV_ID
+ * 0 1
+ * 1 2
+ * SOC Level WMI_PDEV_ID_SOC
+ */
+#define WMA_MAC_TO_PDEV_MAP(x) ((x) + (1))
+#define WMA_PDEV_TO_MAC_MAP(x) ((x) - (1))
+
/* In prima 12 HW stations are supported including BCAST STA(staId 0)
* and SELF STA(staId 1) so total ASSOC stations which can connect to Prima
* SoftAP = 12 - 1(Self STa) - 1(Bcast Sta) = 10 Stations.
@@ -1972,11 +1981,11 @@ QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle,
struct wmi_pcl_chan_weights *msg);
-QDF_STATUS wma_send_soc_set_hw_mode_cmd(tp_wma_handle wma_handle,
+QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle,
struct sir_hw_mode *msg);
QDF_STATUS wma_get_scan_id(uint32_t *scan_id);
-QDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle,
+QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle,
struct sir_dual_mac_config *msg);
QDF_STATUS wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle,
struct sir_antenna_mode_param *msg);
@@ -2039,5 +2048,12 @@ QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma_handle,
int32_t vdev_id);
QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma,
struct obss_ht40_scanind *req);
+
+int wma_get_bpf_caps_event_handler(void *handle,
+ u_int8_t *cmd_param_info,
+ u_int32_t len);
+QDF_STATUS wma_get_bpf_capabilities(tp_wma_handle wma);
+QDF_STATUS wma_set_bpf_instructions(tp_wma_handle wma,
+ struct sir_bpf_set_offload *bpf_set_offload);
#endif
struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma_handle);
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
index cec1e1e705ab..039202571f2a 100644
--- a/core/wma/inc/wma_api.h
+++ b/core/wma/inc/wma_api.h
@@ -65,6 +65,8 @@ typedef enum {
GEN_PARAM_DUMP_PCIE_ACCESS_LOG,
#endif
GEN_PARAM_MODULATED_DTIM,
+ GEN_PARAM_CAPTURE_TSF,
+ GEN_PARAM_RESET_TSF_GPIO,
} GEN_PARAM;
#define VDEV_CMD 1
@@ -121,7 +123,7 @@ int wma_runtime_suspend(void);
int wma_runtime_resume(void);
int wma_bus_suspend(void);
QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr);
-void wma_target_suspend_acknowledge(void *context);
+void wma_target_suspend_acknowledge(void *context, bool wow_nack);
int wma_bus_resume(void);
QDF_STATUS wma_resume_target(WMA_HANDLE handle);
QDF_STATUS wma_disable_wow_in_fw(WMA_HANDLE handle);
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index 42c2c9d6fe3f..2f47901d9143 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -1072,6 +1072,38 @@ QDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,
auto_sh_cmd);
#endif
+#ifdef WLAN_FEATURE_TSF
+int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len);
+QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id);
+QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id);
+QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin);
+#else
+static inline QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle,
+ uint32_t vdev_id)
+{
+ return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle,
+ uint32_t vdev_id)
+{
+ return QDF_STATUS_SUCCESS;
+}
+
+static inline int wma_vdev_tsf_handler(void *handle, uint8_t *data,
+ uint32_t data_len)
+{
+ return 0;
+}
+
+static inline QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin)
+{
+ return QDF_STATUS_E_INVAL;
+}
+#endif
+
+
+
#ifdef WLAN_FEATURE_NAN
QDF_STATUS wma_nan_req(void *wma_ptr, tpNanRequest nan_req);
diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h
index 94c5b05fca14..e6a8c86a9f80 100644
--- a/core/wma/inc/wma_tgt_cfg.h
+++ b/core/wma/inc/wma_tgt_cfg.h
@@ -165,5 +165,6 @@ struct wma_tgt_cfg {
bool egap_support;
#endif
uint32_t fine_time_measurement_cap;
+ bool bpf_enabled;
};
#endif /* WMA_TGT_CFG_H */
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index c82cfa033a33..252d271220f0 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -432,6 +432,7 @@
#endif
#define WMA_SET_SCAN_MAC_OUI_REQ SIR_HAL_SET_SCAN_MAC_OUI_REQ
+#define WMA_TSF_GPIO_PIN SIR_HAL_TSF_GPIO_PIN_REQ
#ifdef DHCP_SERVER_OFFLOAD
#define WMA_SET_DHCP_SERVER_OFFLOAD_CMD SIR_HAL_SET_DHCP_SERVER_OFFLOAD
@@ -467,6 +468,9 @@
#define WMA_ADD_BCN_FILTER_CMDID SIR_HAL_ADD_BCN_FILTER_CMDID
#define WMA_REMOVE_BCN_FILTER_CMDID SIR_HAL_REMOVE_BCN_FILTER_CMDID
+#define WDA_BPF_GET_CAPABILITIES_REQ SIR_HAL_BPF_GET_CAPABILITIES_REQ
+#define WDA_BPF_SET_INSTRUCTIONS_REQ SIR_HAL_BPF_SET_INSTRUCTIONS_REQ
+
/* 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 572b7d91a1d8..b49200cbc46a 100644
--- a/core/wma/src/wma_data.c
+++ b/core/wma/src/wma_data.c
@@ -999,6 +999,7 @@ QDF_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(uint32_t
mcc_adaptive_scheduler)
{
tp_wma_handle wma = NULL;
+ uint32_t pdev_id;
wma = cds_get_context(QDF_MODULE_ID_WMA);
if (NULL == wma) {
@@ -1006,8 +1007,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.
+ */
+ if (wma->wlan_resource_config.use_pdev_id)
+ pdev_id = WMA_MAC_TO_PDEV_MAP(0);
+ else
+ pdev_id = WMI_PDEV_ID_SOC;
+
return wmi_unified_set_enable_disable_mcc_adaptive_scheduler_cmd(
- wma->wmi_handle, mcc_adaptive_scheduler);
+ wma->wmi_handle, mcc_adaptive_scheduler, pdev_id);
}
/**
@@ -2675,11 +2685,15 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
chanfreq = wma_handle->interfaces[vdev_id].scan_info.chan_freq;
WMA_LOGI("%s: Preauth frame on channel %d", __func__, chanfreq);
} else if (pFc->subType == SIR_MAC_MGMT_PROBE_RSP) {
- chanfreq = wma_handle->interfaces[vdev_id].mhz;
- WMA_LOGI("%s: Probe response frame on channel %d", __func__,
- chanfreq);
- WMA_LOGI("%s: Probe response frame on vdev id %d", __func__,
- vdev_id);
+ if ((wma_is_vdev_in_ap_mode(wma_handle, vdev_id)) &&
+ (0 != wma_handle->interfaces[vdev_id].mhz))
+ chanfreq = wma_handle->interfaces[vdev_id].mhz;
+ else
+ chanfreq = channel_freq;
+ WMA_LOGI("%s: Probe response frame on channel %d vdev:%d",
+ __func__, chanfreq, vdev_id);
+ if (wma_is_vdev_in_ap_mode(wma_handle, vdev_id) && !chanfreq)
+ WMA_LOGE("%s: AP oper chan is zero", __func__);
} else if (pFc->subType == SIR_MAC_MGMT_ACTION) {
chanfreq = channel_freq;
} else {
@@ -2704,14 +2718,19 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
mgmt_param.tx_complete_cb = tx_frm_download_comp_cb;
mgmt_param.tx_ota_post_proc_cb = tx_frm_ota_comp_cb;
mgmt_param.chanfreq = chanfreq;
- mgmt_param.wmi_desc = wmi_desc_get(wma_handle);
mgmt_param.pdata = pData;
mgmt_param.qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
-
- status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle,
- &mgmt_param);
- if (status)
- wmi_desc_put(wma_handle, mgmt_param.wmi_desc);
+ mgmt_param.wmi_desc = wmi_desc_get(wma_handle);
+ if (NULL == mgmt_param.wmi_desc) {
+ WMA_LOGE(FL("Failed to get wmi descriptor"));
+ status = QDF_STATUS_E_FAILURE;
+ } else {
+ status = wmi_mgmt_unified_cmd_send(
+ wma_handle->wmi_handle,
+ &mgmt_param);
+ if (status)
+ wmi_desc_put(wma_handle, mgmt_param.wmi_desc);
+ }
} else {
/* Hand over the Tx Mgmt frame to TxRx */
status = ol_txrx_mgmt_send_ext(txrx_vdev, tx_frame,
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index 7526499d390c..c0ebf22a7339 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -54,6 +54,7 @@
#include "lim_session_utils.h"
#include "cds_utils.h"
+#include "cds_concurrency.h"
#if !defined(REMOVE_PKT_LOG)
#include "pktlog_ac.h"
@@ -73,6 +74,8 @@
#include <cdp_txrx_cfg.h>
#include <cdp_txrx_cmn.h>
+#include "cds_concurrency.h"
+
/**
* wma_find_vdev_by_addr() - find vdev_id from mac address
* @wma: wma handle
@@ -204,6 +207,8 @@ enum wlan_op_mode wma_get_txrx_vdev_type(uint32_t type)
vdev_type = wlan_op_mode_ocb;
break;
case WMI_VDEV_TYPE_MONITOR:
+ vdev_type = wlan_op_mode_monitor;
+ break;
default:
WMA_LOGE("Invalid vdev type %u", type);
vdev_type = wlan_op_mode_unknown;
@@ -790,6 +795,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
if (NULL == mac_ctx) {
WMA_LOGE("%s: Failed to get mac_ctx", __func__);
+ cds_set_do_hw_mode_change_flag(false);
return -EINVAL;
}
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
@@ -798,12 +804,14 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) cmd_param_info;
if (!param_buf) {
WMA_LOGE("Invalid start response event buffer");
+ cds_set_do_hw_mode_change_flag(false);
return -EINVAL;
}
resp_event = param_buf->fixed_param;
if (!resp_event) {
WMA_LOGE("Invalid start response event buffer");
+ cds_set_do_hw_mode_change_flag(false);
return -EINVAL;
}
@@ -820,8 +828,20 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
resp_event->cfgd_rx_streams;
wma->interfaces[resp_event->vdev_id].chain_mask =
resp_event->chain_mask;
- wma->interfaces[resp_event->vdev_id].mac_id =
- resp_event->mac_id;
+ if (wma->wlan_resource_config.use_pdev_id) {
+ if (resp_event->pdev_id == WMI_PDEV_ID_SOC) {
+ WMA_LOGE("%s: soc level id received for mac id",
+ __func__);
+ QDF_BUG(0);
+ return -EINVAL;
+ }
+ wma->interfaces[resp_event->vdev_id].mac_id =
+ WMA_PDEV_TO_MAC_MAP(resp_event->pdev_id);
+ } else {
+ wma->interfaces[resp_event->vdev_id].mac_id =
+ resp_event->mac_id;
+ }
+
WMA_LOGI("%s: vdev:%d tx ss=%d rx ss=%d chain mask=%d mac=%d",
__func__,
resp_event->vdev_id,
@@ -845,6 +865,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
wma->interfaces[resp_event->vdev_id].bssid,
&param) != QDF_STATUS_SUCCESS) {
WMA_LOGE("%s : failed to send vdev up", __func__);
+ cds_set_do_hw_mode_change_flag(false);
return -EEXIST;
}
qdf_atomic_set(&wma->interfaces[resp_event->vdev_id].
@@ -859,6 +880,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
if (!req_msg) {
WMA_LOGE("%s: Failed to lookup request message for vdev %d",
__func__, resp_event->vdev_id);
+ cds_set_do_hw_mode_change_flag(false);
return -EINVAL;
}
@@ -877,6 +899,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
if (!params) {
WMA_LOGE("%s: channel switch params is NULL for vdev %d",
__func__, resp_event->vdev_id);
+ cds_set_do_hw_mode_change_flag(false);
return -EINVAL;
}
@@ -889,8 +912,11 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
}
params->smpsMode = host_map_smps_mode(resp_event->smps_mode);
params->status = resp_event->status;
- if (resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT &&
- (iface->type == WMI_VDEV_TYPE_STA)) {
+ if (((resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT) &&
+ (iface->type == WMI_VDEV_TYPE_STA)) ||
+ ((resp_event->resp_type == WMI_VDEV_START_RESP_EVENT) &&
+ (iface->type == WMI_VDEV_TYPE_MONITOR))) {
+
param.vdev_id = resp_event->vdev_id;
param.assoc_id = iface->aid;
status = wmi_unified_vdev_up_send(wma->wmi_handle,
@@ -901,6 +927,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
__func__, resp_event->vdev_id);
wma->interfaces[resp_event->vdev_id].vdev_up =
false;
+ cds_set_do_hw_mode_change_flag(false);
} else {
wma->interfaces[resp_event->vdev_id].vdev_up =
true;
@@ -920,6 +947,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
iface->bssid,
&param) != QDF_STATUS_SUCCESS) {
WMA_LOGE(FL("failed to send vdev up"));
+ cds_set_do_hw_mode_change_flag(false);
return -EEXIST;
}
iface->vdev_up = true;
@@ -1552,7 +1580,8 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
if (((self_sta_req->type == WMI_VDEV_TYPE_AP) &&
(self_sta_req->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) ||
- (self_sta_req->type == WMI_VDEV_TYPE_OCB)) {
+ (self_sta_req->type == WMI_VDEV_TYPE_OCB) ||
+ (self_sta_req->type == WMI_VDEV_TYPE_MONITOR)) {
WMA_LOGA("Creating self peer %pM, vdev_id %hu",
self_sta_req->self_mac_addr, self_sta_req->session_id);
status = wma_create_peer(wma_handle, txrx_pdev,
@@ -1777,7 +1806,7 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma,
*/
params.is_dfs = req->is_dfs;
params.is_restart = isRestart;
- if (req->is_dfs) {
+ if ((QDF_GLOBAL_MONITOR_MODE != cds_get_conparam()) && req->is_dfs) {
params.flag_dfs = WMI_CHAN_FLAG_DFS;
temp_chan_info |= (1 << WMI_CHAN_FLAG_DFS);
params.dis_hw_ack = true;
@@ -3790,6 +3819,7 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
&param) != QDF_STATUS_SUCCESS) {
WMA_LOGP("%s: Failed to send vdev up cmd: vdev %d bssid %pM",
__func__, params->smesessionId, params->bssId);
+ cds_set_do_hw_mode_change_flag(false);
status = QDF_STATUS_E_FAILURE;
} else {
wma->interfaces[params->smesessionId].vdev_up = true;
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 447aa417635b..00c2df030d6f 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -267,6 +267,192 @@ end:
wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY);
}
+#ifdef WLAN_FEATURE_TSF
+/**
+ * wma_vdev_tsf_handler() - handle tsf event indicated by FW
+ * @handle: wma context
+ * @data: event buffer
+ * @data len: length of event buffer
+ *
+ * Return: 0 on success
+ */
+int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
+{
+ cds_msg_t tsf_msg = {0};
+ WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf;
+ wmi_vdev_tsf_report_event_fixed_param *tsf_event;
+ struct stsf *ptsf;
+
+ if (data == NULL) {
+ WMA_LOGE("%s: invalid pointer", __func__);
+ return -EINVAL;
+ }
+ ptsf = qdf_mem_malloc(sizeof(*ptsf));
+ if (NULL == ptsf) {
+ WMA_LOGE("%s: failed to allocate tsf data structure", __func__);
+ return -ENOMEM;
+ }
+
+ param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)data;
+ tsf_event = param_buf->fixed_param;
+
+ ptsf->vdev_id = tsf_event->vdev_id;
+ ptsf->tsf_low = tsf_event->tsf_low;
+ ptsf->tsf_high = tsf_event->tsf_high;
+
+ WMA_LOGD("%s: receive WMI_VDEV_TSF_REPORT_EVENTID ", __func__);
+ WMA_LOGD("%s: vdev_id = %u,tsf_low =%u, tsf_high = %u", __func__,
+ ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
+
+ tsf_msg.type = eWNI_SME_TSF_EVENT;
+ tsf_msg.bodyptr = ptsf;
+ tsf_msg.bodyval = 0;
+
+ if (QDF_STATUS_SUCCESS !=
+ cds_mq_post_message(CDS_MQ_ID_SME, &tsf_msg)) {
+
+ WMA_LOGP("%s: Failed to post eWNI_SME_TSF_EVENT", __func__);
+ qdf_mem_free(ptsf);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * wma_capture_tsf() - send wmi to fw to capture tsf
+ * @wma_handle: wma handler
+ * @vdev_id: vdev id
+ *
+ * Return: wmi send state
+ */
+QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ wmi_buf_t buf;
+ wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
+ int ret;
+ int len = sizeof(*cmd);
+
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGP("%s: failed to allocate memory for cap tsf cmd",
+ __func__);
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) wmi_buf_data(buf);
+ cmd->vdev_id = vdev_id;
+ cmd->tsf_action = TSF_TSTAMP_CAPTURE_REQ;
+
+ WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_REQ", __func__,
+ cmd->vdev_id);
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
+
+ ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
+ if (ret != EOK) {
+ WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
+ status = QDF_STATUS_E_FAILURE;
+ goto error;
+ }
+
+ return QDF_STATUS_SUCCESS;
+
+error:
+ if (buf)
+ wmi_buf_free(buf);
+ return status;
+}
+
+/**
+ * wma_reset_tsf_gpio() - send wmi to fw to reset GPIO
+ * @wma_handle: wma handler
+ * @vdev_id: vdev id
+ *
+ * Return: wmi send state
+ */
+QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ wmi_buf_t buf;
+ wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
+ int ret;
+ int len = sizeof(*cmd);
+ uint8_t *buf_ptr;
+
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGP("%s: failed to allocate memory for reset tsf gpio",
+ __func__);
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ buf_ptr = (uint8_t *) wmi_buf_data(buf);
+ cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) buf_ptr;
+ cmd->vdev_id = vdev_id;
+ cmd->tsf_action = TSF_TSTAMP_CAPTURE_RESET;
+
+ WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_RESET", __func__,
+ cmd->vdev_id);
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
+
+ ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
+
+ if (ret != EOK) {
+ WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
+ status = QDF_STATUS_E_FAILURE;
+ goto error;
+ }
+ return QDF_STATUS_SUCCESS;
+
+error:
+ if (buf)
+ wmi_buf_free(buf);
+ return status;
+}
+
+/**
+ * wma_set_tsf_gpio_pin() - send wmi cmd to configure gpio pin
+ * @handle: wma handler
+ * @pin: GPIO pin id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin)
+{
+ tp_wma_handle wma = (tp_wma_handle)handle;
+ struct pdev_params pdev_param = {0};
+ int32_t ret;
+
+ if (!wma || !wma->wmi_handle) {
+ WMA_LOGE("%s: WMA is closed, can not set gpio", __func__);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ WMA_LOGD("%s: set tsf gpio pin: %d", __func__, pin);
+
+ pdev_param.param_id = WMI_PDEV_PARAM_WNTS_CONFIG;
+ pdev_param.param_value = pin;
+ ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+ &pdev_param,
+ WMA_WILDCARD_PDEV_ID);
+ if (ret) {
+ WMA_LOGE("%s: Failed to set tsf gpio pin (%d)", __func__, ret);
+ return QDF_STATUS_E_FAILURE;
+ }
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+
#ifdef FEATURE_WLAN_LPHB
/**
* wma_lphb_conf_hbenable() - enable command of LPHB configuration requests
@@ -3060,7 +3246,7 @@ QDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle)
#endif /* CONFIG_CNSS */
qdf_event_reset(&wma->target_suspend);
- wma->wow_nack = 0;
+ wma->wow_nack = false;
host_credits = wmi_get_host_credits(wma->wmi_handle);
wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle);
@@ -5739,14 +5925,14 @@ QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr)
/**
* wma_target_suspend_acknowledge() - update target susspend status
- * @context: wma context
+ * @context: HTC_INIT_INFO->context
+ * @wow_nack: true when wow is rejected
*
* Return: none
*/
-void wma_target_suspend_acknowledge(void *context)
+void wma_target_suspend_acknowledge(void *context, bool wow_nack)
{
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
- int wow_nack = *((int *)context);
if (NULL == wma) {
WMA_LOGE("%s: wma is NULL", __func__);
@@ -6718,3 +6904,172 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
return ret;
}
+/**
+ * wma_get_bpf_caps_event_handler() - Event handler for get bpf capability
+ * @handle: WMA global handle
+ * @cmd_param_info: command event data
+ * @len: Length of @cmd_param_info
+ *
+ * Return: 0 on Success or Errno on failure
+ */
+int wma_get_bpf_caps_event_handler(void *handle,
+ u_int8_t *cmd_param_info,
+ u_int32_t len)
+{
+ WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *param_buf;
+ wmi_bpf_capability_info_evt_fixed_param *event;
+ struct sir_bpf_get_offload *bpf_get_offload;
+ tpAniSirGlobal pmac = (tpAniSirGlobal)cds_get_context(
+ QDF_MODULE_ID_PE);
+
+ if (!pmac) {
+ WMA_LOGE("%s: Invalid pmac", __func__);
+ return -EINVAL;
+ }
+ if (!pmac->sme.pbpf_get_offload_cb) {
+ WMA_LOGE("%s: Callback not registered", __func__);
+ return -EINVAL;
+ }
+
+ param_buf = (WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *)cmd_param_info;
+ event = param_buf->fixed_param;
+ bpf_get_offload = qdf_mem_malloc(sizeof(*bpf_get_offload));
+
+ if (!bpf_get_offload) {
+ WMA_LOGP("%s: Memory allocation failed.", __func__);
+ return -ENOMEM;
+ }
+
+ bpf_get_offload->bpf_version = event->bpf_version;
+ bpf_get_offload->max_bpf_filters = event->max_bpf_filters;
+ bpf_get_offload->max_bytes_for_bpf_inst =
+ event->max_bytes_for_bpf_inst;
+ WMA_LOGD("%s: BPF capabilities version: %d max bpf filter size: %d",
+ __func__, bpf_get_offload->bpf_version,
+ bpf_get_offload->max_bytes_for_bpf_inst);
+
+ WMA_LOGD("%s: sending bpf capabilities event to hdd", __func__);
+ pmac->sme.pbpf_get_offload_cb(pmac->hHdd, bpf_get_offload);
+ qdf_mem_free(bpf_get_offload);
+ return 0;
+}
+
+/**
+ * wma_get_bpf_capabilities - Send get bpf capability to firmware
+ * @wma_handle: wma handle
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS wma_get_bpf_capabilities(tp_wma_handle wma)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ wmi_bpf_get_capability_cmd_fixed_param *cmd;
+ wmi_buf_t wmi_buf;
+ uint32_t len;
+ u_int8_t *buf_ptr;
+
+ if (!wma || !wma->wmi_handle) {
+ WMA_LOGE(FL("WMA is closed, can not issue get BPF capab"));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+ WMI_SERVICE_BPF_OFFLOAD)) {
+ WMA_LOGE(FL("BPF cababilities feature bit not enabled"));
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ len = sizeof(*cmd);
+ wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!wmi_buf) {
+ WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
+ cmd = (wmi_bpf_get_capability_cmd_fixed_param *) buf_ptr;
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_bpf_get_capability_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_bpf_get_capability_cmd_fixed_param));
+
+ if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
+ WMI_BPF_GET_CAPABILITY_CMDID)) {
+ WMA_LOGE(FL("Failed to send BPF capability command"));
+ wmi_buf_free(wmi_buf);
+ return QDF_STATUS_E_FAILURE;
+ }
+ return status;
+}
+
+/**
+ * wma_set_bpf_instructions - Set bpf instructions to firmware
+ * @wma: wma handle
+ * @bpf_set_offload: Bpf offload information to set to firmware
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wma_set_bpf_instructions(tp_wma_handle wma,
+ struct sir_bpf_set_offload *bpf_set_offload)
+{
+ wmi_bpf_set_vdev_instructions_cmd_fixed_param *cmd;
+ wmi_buf_t wmi_buf;
+ uint32_t len = 0, len_aligned = 0;
+ u_int8_t *buf_ptr;
+
+ if (!wma || !wma->wmi_handle) {
+ WMA_LOGE("%s: WMA is closed, can not issue set BPF capability",
+ __func__);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+ WMI_SERVICE_BPF_OFFLOAD)) {
+ WMA_LOGE(FL("BPF offload feature Disabled"));
+ return QDF_STATUS_E_NOSUPPORT;
+ }
+
+ if (bpf_set_offload->total_length) {
+ len_aligned = roundup(bpf_set_offload->current_length,
+ sizeof(A_UINT32));
+ len = len_aligned + WMI_TLV_HDR_SIZE;
+ }
+
+ len += sizeof(*cmd);
+ wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!wmi_buf) {
+ WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
+ cmd = (wmi_bpf_set_vdev_instructions_cmd_fixed_param *) buf_ptr;
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_bpf_set_vdev_instructions_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_bpf_set_vdev_instructions_cmd_fixed_param));
+ cmd->vdev_id = bpf_set_offload->session_id;
+ cmd->filter_id = bpf_set_offload->filter_id;
+ cmd->total_length = bpf_set_offload->total_length;
+ cmd->current_offset = bpf_set_offload->current_offset;
+ cmd->current_length = bpf_set_offload->current_length;
+
+ if (bpf_set_offload->total_length) {
+ buf_ptr +=
+ sizeof(wmi_bpf_set_vdev_instructions_cmd_fixed_param);
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, len_aligned);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+ qdf_mem_copy(buf_ptr, bpf_set_offload->program,
+ bpf_set_offload->current_length);
+ qdf_mem_free(bpf_set_offload->program);
+ }
+
+ if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
+ WMI_BPF_SET_VDEV_INSTRUCTIONS_CMDID)) {
+ WMA_LOGE(FL("Failed to send config bpf instructions command"));
+ wmi_buf_free(wmi_buf);
+ return QDF_STATUS_E_FAILURE;
+ }
+ return QDF_STATUS_SUCCESS;
+}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 723ff4921eb8..347c745c95d8 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -247,6 +247,9 @@ static void wma_set_default_tgt_config(tp_wma_handle wma_handle)
tgt_cfg.rx_decap_mode = CFG_TGT_RX_DECAP_MODE_NWIFI;
}
#endif /* PERE_IP_HDR_ALIGNMENT_WAR */
+ if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
+ tgt_cfg.rx_decap_mode = CFG_TGT_RX_DECAP_MODE_RAW;
+
wma_handle->wlan_resource_config = tgt_cfg;
}
@@ -919,6 +922,12 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
privcmd->param_value,
privcmd->param_sec_value);
break;
+ case GEN_PARAM_CAPTURE_TSF:
+ ret = wma_capture_tsf(wma, privcmd->param_value);
+ break;
+ case GEN_PARAM_RESET_TSF_GPIO:
+ ret = wma_reset_tsf_gpio(wma, privcmd->param_value);
+ break;
#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
case GEN_PARAM_DUMP_PCIE_ACCESS_LOG:
htc_dump(wma->htc_handle, PCIE_DUMP, false);
@@ -1672,6 +1681,13 @@ QDF_STATUS wma_open(void *cds_context,
wma_handle->wma_runtime_resume_lock =
qdf_runtime_lock_init("wma_runtime_resume");
+ /* Initialize max_no_of_peers for wma_get_number_of_peers_supported() */
+ wma_init_max_no_of_peers(wma_handle, mac_params->maxStation);
+ /* Cap maxStation based on the target version */
+ mac_params->maxStation = wma_get_number_of_peers_supported(wma_handle);
+ /* Reinitialize max_no_of_peers based on the capped maxStation value */
+ wma_init_max_no_of_peers(wma_handle, mac_params->maxStation);
+
/* initialize default target config */
wma_set_default_tgt_config(wma_handle);
@@ -1733,8 +1749,6 @@ QDF_STATUS wma_open(void *cds_context,
if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
wma_utf_attach(wma_handle);
#endif /* QCA_WIFI_FTM */
- wma_init_max_no_of_peers(wma_handle, mac_params->maxStation);
- mac_params->maxStation = wma_get_number_of_peers_supported(wma_handle);
mac_params->maxBssId = WMA_MAX_SUPPORTED_BSS;
mac_params->frameTransRequired = 0;
@@ -2052,6 +2066,10 @@ QDF_STATUS wma_open(void *cds_context,
WMI_PEER_DELETE_RESP_EVENTID,
wma_peer_delete_handler,
WMA_RX_SERIALIZER_CTX);
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_BPF_CAPABILIY_INFO_EVENTID,
+ wma_get_bpf_caps_event_handler,
+ WMA_RX_SERIALIZER_CTX);
return QDF_STATUS_SUCCESS;
err_dbglog_init:
@@ -2263,7 +2281,7 @@ static int wma_flush_complete_evt_handler(void *handle,
reason_code);
status = cds_set_log_completion(WLAN_LOG_TYPE_FATAL,
WLAN_LOG_INDICATOR_FIRMWARE,
- reason_code);
+ reason_code, false);
if (QDF_STATUS_SUCCESS != status) {
WMA_LOGE("%s: Failed to set log trigger params",
__func__);
@@ -2284,23 +2302,24 @@ static int wma_flush_complete_evt_handler(void *handle,
}
/**
- * wma_soc_set_hw_mode_resp_evt_handler() - Set HW mode resp evt handler
+ * wma_pdev_set_hw_mode_resp_evt_handler() - Set HW mode resp evt handler
* @handle: WMI handle
* @event: Event recevied from FW
* @len: Length of the event
*
- * Event handler for WMI_SOC_SET_HW_MODE_RESP_EVENTID that is sent to host
- * driver in response to a WMI_SOC_SET_HW_MODE_CMDID being sent to WLAN firmware
+ * Event handler for WMI_PDEV_SET_HW_MODE_RESP_EVENTID that is sent to host
+ * driver in response to a WMI_PDEV_SET_HW_MODE_CMDID being sent to WLAN
+ * firmware
*
* Return: Success on receiving valid params from FW
*/
-static int wma_soc_set_hw_mode_resp_evt_handler(void *handle,
+static int wma_pdev_set_hw_mode_resp_evt_handler(void *handle,
uint8_t *event,
uint32_t len)
{
- WMI_SOC_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf;
- wmi_soc_set_hw_mode_response_event_fixed_param *wmi_event;
- wmi_soc_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
+ WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf;
+ wmi_pdev_set_hw_mode_response_event_fixed_param *wmi_event;
+ wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
uint32_t i;
struct sir_set_hw_mode_resp *hw_mode_resp;
tp_wma_handle wma = (tp_wma_handle) handle;
@@ -2322,9 +2341,9 @@ static int wma_soc_set_hw_mode_resp_evt_handler(void *handle,
return QDF_STATUS_E_NULL_VALUE;
}
- param_buf = (WMI_SOC_SET_HW_MODE_RESP_EVENTID_param_tlvs *) event;
+ param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *) event;
if (!param_buf) {
- WMA_LOGE("Invalid WMI_SOC_SET_HW_MODE_RESP_EVENTID event");
+ WMA_LOGE("Invalid WMI_PDEV_SET_HW_MODE_RESP_EVENTID event");
/* Need to send response back to upper layer to free
* active command list
*/
@@ -2341,13 +2360,20 @@ static int wma_soc_set_hw_mode_resp_evt_handler(void *handle,
wmi_event->cfgd_hw_mode_index,
wmi_event->num_vdev_mac_entries);
vdev_mac_entry =
- param_buf->wmi_soc_set_hw_mode_response_vdev_mac_mapping;
+ param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping;
/* Store the vdev-mac map in WMA and prepare to send to PE */
for (i = 0; i < wmi_event->num_vdev_mac_entries; i++) {
- uint32_t vdev_id, mac_id;
+ uint32_t vdev_id, mac_id, pdev_id;
vdev_id = vdev_mac_entry[i].vdev_id;
- mac_id = vdev_mac_entry[i].mac_id;
+ pdev_id = vdev_mac_entry[i].pdev_id;
+ if (pdev_id == WMI_PDEV_ID_SOC) {
+ WMA_LOGE("%s: soc level id received for mac id)",
+ __func__);
+ QDF_BUG(0);
+ goto fail;
+ }
+ mac_id = WMA_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id);
WMA_LOGI("%s: vdev_id:%d mac_id:%d",
__func__, vdev_id, mac_id);
@@ -2370,7 +2396,7 @@ static int wma_soc_set_hw_mode_resp_evt_handler(void *handle,
WMA_LOGI("%s: Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
__func__, wma->old_hw_mode_index, wma->new_hw_mode_index);
- wma_send_msg(wma, SIR_HAL_SOC_SET_HW_MODE_RESP,
+ wma_send_msg(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP,
(void *) hw_mode_resp, 0);
return QDF_STATUS_SUCCESS;
@@ -2380,33 +2406,33 @@ fail:
hw_mode_resp->status = SET_HW_MODE_STATUS_ECANCELED;
hw_mode_resp->cfgd_hw_mode_index = 0;
hw_mode_resp->num_vdev_mac_entries = 0;
- wma_send_msg(wma, SIR_HAL_SOC_SET_HW_MODE_RESP,
+ wma_send_msg(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP,
(void *) hw_mode_resp, 0);
return QDF_STATUS_E_FAILURE;
}
/**
- * wma_soc_hw_mode_transition_evt_handler() - HW mode transition evt handler
+ * wma_pdev_hw_mode_transition_evt_handler() - HW mode transition evt handler
* @handle: WMI handle
* @event: Event recevied from FW
* @len: Length of the event
*
- * Event handler for WMI_SOC_HW_MODE_TRANSITION_EVENTID that indicates an
+ * Event handler for WMI_PDEV_HW_MODE_TRANSITION_EVENTID that indicates an
* asynchronous hardware mode transition. This event notifies the host driver
* that firmware independently changed the hardware mode for some reason, such
* as Coex, LFR 3.0, etc
*
* Return: Success on receiving valid params from FW
*/
-static int wma_soc_hw_mode_transition_evt_handler(void *handle,
+static int wma_pdev_hw_mode_transition_evt_handler(void *handle,
uint8_t *event,
uint32_t len)
{
uint32_t i;
- WMI_SOC_HW_MODE_TRANSITION_EVENTID_param_tlvs *param_buf;
- wmi_soc_hw_mode_transition_event_fixed_param *wmi_event;
- wmi_soc_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
+ WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *param_buf;
+ wmi_pdev_hw_mode_transition_event_fixed_param *wmi_event;
+ wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
struct sir_hw_mode_trans_ind *hw_mode_trans_ind;
tp_wma_handle wma = (tp_wma_handle) handle;
@@ -2416,10 +2442,10 @@ static int wma_soc_hw_mode_transition_evt_handler(void *handle,
return QDF_STATUS_E_NULL_VALUE;
}
- param_buf = (WMI_SOC_HW_MODE_TRANSITION_EVENTID_param_tlvs *) event;
+ param_buf = (WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *) event;
if (!param_buf) {
/* This is an async event. So, not sending any event to LIM */
- WMA_LOGE("Invalid WMI_SOC_HW_MODE_TRANSITION_EVENTID event");
+ WMA_LOGE("Invalid WMI_PDEV_HW_MODE_TRANSITION_EVENTID event");
return QDF_STATUS_E_FAILURE;
}
@@ -2439,13 +2465,22 @@ static int wma_soc_hw_mode_transition_evt_handler(void *handle,
wmi_event->new_hw_mode_index, wmi_event->num_vdev_mac_entries);
vdev_mac_entry =
- param_buf->wmi_soc_set_hw_mode_response_vdev_mac_mapping;
+ param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping;
/* Store the vdev-mac map in WMA and prepare to send to HDD */
for (i = 0; i < wmi_event->num_vdev_mac_entries; i++) {
- uint32_t vdev_id, mac_id;
+ uint32_t vdev_id, mac_id, pdev_id;
vdev_id = vdev_mac_entry[i].vdev_id;
- mac_id = vdev_mac_entry[i].mac_id;
+ pdev_id = vdev_mac_entry[i].pdev_id;
+
+ if (pdev_id == WMI_PDEV_ID_SOC) {
+ WMA_LOGE("%s: soc level id received for mac id)",
+ __func__);
+ QDF_BUG(0);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ mac_id = WMA_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id);
WMA_LOGI("%s: vdev_id:%d mac_id:%d",
__func__, vdev_id, mac_id);
@@ -2462,32 +2497,32 @@ static int wma_soc_hw_mode_transition_evt_handler(void *handle,
__func__, wma->old_hw_mode_index, wma->new_hw_mode_index);
/* Pass the message to PE */
- wma_send_msg(wma, SIR_HAL_SOC_HW_MODE_TRANS_IND,
+ wma_send_msg(wma, SIR_HAL_PDEV_HW_MODE_TRANS_IND,
(void *) hw_mode_trans_ind, 0);
return QDF_STATUS_SUCCESS;
}
/**
- * wma_soc_set_dual_mode_config_resp_evt_handler() - Dual mode evt handler
+ * wma_pdev_set_dual_mode_config_resp_evt_handler() - Dual mode evt handler
* @handle: WMI handle
* @event: Event received from FW
* @len: Length of the event
*
* Notifies the host driver of the completion or failure of a
- * WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID command. This event would be returned to
+ * WMI_PDEV_SET_MAC_CONFIG_CMDID command. This event would be returned to
* the host driver once the firmware has completed a reconfiguration of the Scan
* and FW mode configuration. This changes could include entering or leaving a
* dual mac configuration for either scan and/or more permanent firmware mode.
*
* Return: Success on receiving valid params from FW
*/
-static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle,
+static int wma_pdev_set_dual_mode_config_resp_evt_handler(void *handle,
uint8_t *event,
uint32_t len)
{
- WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID_param_tlvs *param_buf;
- wmi_soc_set_dual_mac_config_response_event_fixed_param *wmi_event;
+ WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID_param_tlvs *param_buf;
+ wmi_pdev_set_mac_config_response_event_fixed_param *wmi_event;
tp_wma_handle wma = (tp_wma_handle) handle;
struct sir_dual_mac_config_resp *dual_mac_cfg_resp;
@@ -2508,7 +2543,7 @@ static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle,
return QDF_STATUS_E_NULL_VALUE;
}
- param_buf = (WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID_param_tlvs *)
+ param_buf = (WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID_param_tlvs *)
event;
if (!param_buf) {
WMA_LOGE("%s: Invalid event", __func__);
@@ -2531,7 +2566,7 @@ static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle,
}
/* Pass the message to PE */
- wma_send_msg(wma, SIR_HAL_SOC_DUAL_MAC_CFG_RESP,
+ wma_send_msg(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
(void *) dual_mac_cfg_resp, 0);
return QDF_STATUS_SUCCESS;
@@ -2539,7 +2574,7 @@ static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle,
fail:
WMA_LOGE("%s: Sending fail response to LIM", __func__);
dual_mac_cfg_resp->status = SET_HW_MODE_STATUS_ECANCELED;
- wma_send_msg(wma, SIR_HAL_SOC_DUAL_MAC_CFG_RESP,
+ wma_send_msg(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
(void *) dual_mac_cfg_resp, 0);
return QDF_STATUS_E_FAILURE;
@@ -2755,6 +2790,16 @@ QDF_STATUS wma_start(void *cds_ctx)
goto end;
}
+ status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_VDEV_TSF_REPORT_EVENTID,
+ wma_vdev_tsf_handler,
+ WMA_RX_SERIALIZER_CTX);
+ if (0 != status) {
+ WMA_LOGP("%s: Failed to register tsf callback", __func__);
+ qdf_status = QDF_STATUS_E_FAILURE;
+ goto end;
+ }
+
/* Initialize the log flush complete event handler */
status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID,
@@ -2766,10 +2811,10 @@ QDF_STATUS wma_start(void *cds_ctx)
goto end;
}
- /* Initialize the WMI_SOC_SET_HW_MODE_RESP_EVENTID event handler */
+ /* Initialize the wma_pdev_set_hw_mode_resp_evt_handler event handler */
status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
- WMI_SOC_SET_HW_MODE_RESP_EVENTID,
- wma_soc_set_hw_mode_resp_evt_handler,
+ WMI_PDEV_SET_HW_MODE_RESP_EVENTID,
+ wma_pdev_set_hw_mode_resp_evt_handler,
WMA_RX_SERIALIZER_CTX);
if (status != QDF_STATUS_SUCCESS) {
WMA_LOGE("Failed to register set hw mode resp event cb");
@@ -2779,8 +2824,8 @@ QDF_STATUS wma_start(void *cds_ctx)
/* Initialize the WMI_SOC_HW_MODE_TRANSITION_EVENTID event handler */
status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
- WMI_SOC_HW_MODE_TRANSITION_EVENTID,
- wma_soc_hw_mode_transition_evt_handler,
+ WMI_PDEV_HW_MODE_TRANSITION_EVENTID,
+ wma_pdev_hw_mode_transition_evt_handler,
WMA_RX_SERIALIZER_CTX);
if (status != QDF_STATUS_SUCCESS) {
WMA_LOGE("Failed to register hw mode transition event cb");
@@ -2790,8 +2835,8 @@ QDF_STATUS wma_start(void *cds_ctx)
/* Initialize the set dual mac configuration event handler */
status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
- WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID,
- wma_soc_set_dual_mode_config_resp_evt_handler,
+ WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID,
+ wma_pdev_set_dual_mode_config_resp_evt_handler,
WMA_RX_SERIALIZER_CTX);
if (status != QDF_STATUS_SUCCESS) {
WMA_LOGE("Failed to register hw mode transition event cb");
@@ -3901,6 +3946,20 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info,
return -EINVAL;
}
+ /* mac_id is replaced with pdev_id in converged firmware to have
+ * multi-radio support. In order to maintain backward compatibility
+ * with old fw, host needs to check WMI_SERVICE_DEPRECATED_REPLACE
+ * in service bitmap from FW and host needs to set use_pdev_id in
+ * wmi_resource_config to true. If WMI_SERVICE_DEPRECATED_REPLACE
+ * service is not set, then host shall not expect MAC ID from FW in
+ * VDEV START RESPONSE event and host shall use PDEV ID.
+ */
+ if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+ WMI_SERVICE_DEPRECATED_REPLACE))
+ wma_handle->wlan_resource_config.use_pdev_id = true;
+ else
+ wma_handle->wlan_resource_config.use_pdev_id = false;
+
/* register the Enhanced Green AP event handler */
wma_register_egap_event_handle(wma_handle);
@@ -5107,6 +5166,10 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
wma_get_temperature(wma_handle);
qdf_mem_free(msg->bodyptr);
break;
+ case WMA_TSF_GPIO_PIN:
+ wma_set_tsf_gpio_pin(wma_handle, msg->bodyval);
+ break;
+
#ifdef DHCP_SERVER_OFFLOAD
case WMA_SET_DHCP_SERVER_OFFLOAD_CMD:
wma_process_dhcpserver_offload(wma_handle,
@@ -5171,8 +5234,8 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
(struct wmi_pcl_chan_weights *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
- case SIR_HAL_SOC_SET_HW_MODE:
- wma_send_soc_set_hw_mode_cmd(wma_handle,
+ case SIR_HAL_PDEV_SET_HW_MODE:
+ wma_send_pdev_set_hw_mode_cmd(wma_handle,
(struct sir_hw_mode *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
@@ -5216,8 +5279,8 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
(struct sir_dcc_update_ndl *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
- case SIR_HAL_SOC_DUAL_MAC_CFG_REQ:
- wma_send_soc_set_dual_mac_config(wma_handle,
+ case SIR_HAL_PDEV_DUAL_MAC_CFG_REQ:
+ wma_send_pdev_set_dual_mac_config(wma_handle,
(struct sir_dual_mac_config *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
@@ -5259,6 +5322,13 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
wma_remove_beacon_filter(wma_handle, msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
+ case WDA_BPF_GET_CAPABILITIES_REQ:
+ wma_get_bpf_capabilities(wma_handle);
+ break;
+ case WDA_BPF_SET_INSTRUCTIONS_REQ:
+ wma_set_bpf_instructions(wma_handle, msg->bodyptr);
+ qdf_mem_free(msg->bodyptr);
+ break;
default:
WMA_LOGD("unknow msg type %x", msg->type);
@@ -5347,7 +5417,7 @@ QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle,
}
/**
- * wma_send_soc_set_hw_mode_cmd() - Send WMI_SOC_SET_HW_MODE_CMDID to FW
+ * wma_send_pdev_set_hw_mode_cmd() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
* @wma_handle: WMA handle
* @msg: Structure containing the following parameters
*
@@ -5360,7 +5430,7 @@ QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle,
*
* Return: Success if the cmd is sent successfully to the firmware
*/
-QDF_STATUS wma_send_soc_set_hw_mode_cmd(tp_wma_handle wma_handle,
+QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle,
struct sir_hw_mode *msg)
{
struct sir_set_hw_mode_resp *param;
@@ -5395,13 +5465,13 @@ fail:
param->cfgd_hw_mode_index = 0;
param->num_vdev_mac_entries = 0;
WMA_LOGE("%s: Sending HW mode fail response to LIM", __func__);
- wma_send_msg(wma_handle, SIR_HAL_SOC_SET_HW_MODE_RESP,
+ wma_send_msg(wma_handle, SIR_HAL_PDEV_SET_HW_MODE_RESP,
(void *) param, 0);
return QDF_STATUS_SUCCESS;
}
/**
- * wma_send_soc_set_dual_mac_config() - Set dual mac config to FW
+ * wma_send_pdev_set_dual_mac_config() - Set dual mac config to FW
* @wma_handle: WMA handle
* @msg: Dual MAC config parameters
*
@@ -5409,9 +5479,11 @@ fail:
*
* Return: QDF_STATUS. 0 on success.
*/
-QDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle,
+QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle,
struct sir_dual_mac_config *msg)
{
+ QDF_STATUS status;
+
if (!wma_handle) {
WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
__func__);
@@ -5423,11 +5495,17 @@ QDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle,
return QDF_STATUS_E_NULL_VALUE;
}
+ status = wmi_unified_pdev_set_dual_mac_config_cmd(
+ wma_handle->wmi_handle,
+ (struct wmi_dual_mac_config *)msg);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ WMA_LOGE("%s: Failed to send WMI_PDEV_SET_DUAL_MAC_CONFIG_CMDID: %d",
+ __func__, status);
+ return status;
+ }
- if (wmi_unified_soc_set_dual_mac_config_cmd(wma_handle->wmi_handle,
- (struct wmi_dual_mac_config *)msg))
- WMA_LOGE("%s: Failed to send WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID",
- __func__);
+ wma_handle->dual_mac_cfg.req_scan_config = msg->scan_config;
+ wma_handle->dual_mac_cfg.req_fw_mode_config = msg->fw_mode_config;
return QDF_STATUS_SUCCESS;
}
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index e7a0ca05d3ab..60ac1ba4454a 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -2343,6 +2343,7 @@ void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
&param);
if (QDF_IS_STATUS_ERROR(status)) {
WMA_LOGE("%s : failed to send vdev up", __func__);
+ cds_set_do_hw_mode_change_flag(false);
return;
}
wma->interfaces[vdev_id].vdev_up = true;
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index fc08eef58e72..841b04e8acb8 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -51,12 +51,14 @@
#include "qdf_types.h"
#include "qdf_mem.h"
#include "ol_txrx_peer_find.h"
+#include "ol_htt_api.h"
#include "wma_types.h"
#include "lim_api.h"
#include "lim_session_utils.h"
#include "cds_utils.h"
+#include "cds_concurrency.h"
#if !defined(REMOVE_PKT_LOG)
#include "pktlog_ac.h"
@@ -237,19 +239,21 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
cmd->repeat_probe_time =
cmd->dwell_time_active / WMA_SCAN_NPROBES_DEFAULT;
- /* CSR sends only one value restTime for staying on home channel
- * to continue data traffic. Rome fw has facility to monitor the traffic
- * and move to next channel. Stay on the channel for at least half
- * of the requested time and then leave if there is no traffic.
+ /* CSR sends min_rest_Time, max_rest_time and idle_time
+ * for staying on home channel to continue data traffic.
+ * Rome fw has facility to monitor the traffic
+ * and move to next channel. Stay on the channel for min_rest_time
+ * and then leave if there is no traffic.
*/
- cmd->min_rest_time = scan_req->restTime / 2;
+ cmd->min_rest_time = scan_req->min_rest_time;
cmd->max_rest_time = scan_req->restTime;
/* Check for traffic at idle_time interval after min_rest_time.
* Default value is 25 ms to allow full use of max_rest_time
* when voice packets are running at 20 ms interval.
*/
- cmd->idle_time = WMA_SCAN_IDLE_TIME_DEFAULT;
+ cmd->idle_time = scan_req->idle_time;
+
/* Large timeout value for full scan cycle, 30 seconds */
cmd->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
@@ -295,20 +299,6 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
WMA_3PORT_CONC_SCAN_MAX_BURST_DURATION;
break;
}
- if (wma_is_sap_active(wma_handle)) {
- /* Background scan while SoftAP is sending beacons.
- * Max duration of CTS2self is 32 ms, which limits
- * the dwell time.
- */
- cmd->dwell_time_active =
- QDF_MIN(scan_req->maxChannelTime,
- (WMA_CTS_DURATION_MS_MAX -
- WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME));
- cmd->dwell_time_passive =
- cmd->dwell_time_active;
- cmd->burst_duration = 0;
- break;
- }
if (wma_handle->miracast_value &&
wma_is_mcc_24G(wma_handle)) {
cmd->max_rest_time =
@@ -414,6 +404,20 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
}
}
+ if (wma_is_sap_active(wma_handle)) {
+ /* P2P/STA scan while SoftAP is sending beacons.
+ * Max duration of CTS2self is 32 ms, which limits the
+ * dwell time.
+ */
+ cmd->dwell_time_active =
+ QDF_MIN(scan_req->maxChannelTime,
+ (WMA_CTS_DURATION_MS_MAX -
+ WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME));
+ cmd->dwell_time_passive =
+ cmd->dwell_time_active;
+ cmd->burst_duration = 0;
+ }
+
cmd->n_probes = (cmd->repeat_probe_time > 0) ?
cmd->dwell_time_active / cmd->repeat_probe_time : 0;
if (scan_req->channelList.numChannels) {
@@ -2078,15 +2082,12 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event,
goto cleanup_label;
}
bss_desc_ptr = qdf_mem_malloc(sizeof(tSirBssDescription) + ie_len);
- roam_synch_ind_ptr->join_rsp = qdf_mem_malloc(sizeof(tSirSmeJoinRsp));
- if ((NULL == roam_synch_ind_ptr->join_rsp) || (NULL == bss_desc_ptr)) {
+ if (NULL == bss_desc_ptr) {
WMA_LOGE("LFR3: mem alloc failed!");
QDF_ASSERT(bss_desc_ptr != NULL);
- QDF_ASSERT(roam_synch_ind_ptr->join_rsp != NULL);
status = -ENOMEM;
goto cleanup_label;
}
- qdf_mem_zero(roam_synch_ind_ptr->join_rsp, sizeof(tSirSmeJoinRsp));
qdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription) + ie_len);
wma->pe_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
roam_synch_ind_ptr, bss_desc_ptr);
@@ -2446,6 +2447,112 @@ void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id)
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
/**
+ * wma_switch_channel() - WMA api to switch channel dynamically
+ * @wma: Pointer of WMA context
+ * @req: Pointer vdev_start having channel switch info.
+ *
+ * Return: 0 for success, otherwise appropriate error code
+ */
+QDF_STATUS wma_switch_channel(tp_wma_handle wma, struct wma_vdev_start_req *req)
+{
+
+ wmi_buf_t buf;
+ wmi_channel *cmd;
+ int32_t len, ret;
+ WLAN_PHY_MODE chanmode;
+ struct wma_txrx_node *intr = wma->interfaces;
+ tpAniSirGlobal pmac;
+
+ pmac = cds_get_context(QDF_MODULE_ID_PE);
+
+ if (pmac == NULL) {
+ WMA_LOGE("%s: vdev start failed as pmac is NULL", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ len = sizeof(*cmd);
+ buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+ return QDF_STATUS_E_NOMEM;
+ }
+ cmd = (wmi_channel *)wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_channel,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
+
+ /* Fill channel info */
+ cmd->mhz = cds_chan_to_freq(req->chan);
+ chanmode = wma_chan_to_mode(req->chan, req->chan_width,
+ req->vht_capable, req->dot11_mode);
+
+ intr[req->vdev_id].chanmode = chanmode; /* save channel mode */
+ intr[req->vdev_id].ht_capable = req->ht_capable;
+ intr[req->vdev_id].vht_capable = req->vht_capable;
+ intr[req->vdev_id].config.gtx_info.gtxRTMask[0] =
+ CFG_TGT_DEFAULT_GTX_HT_MASK;
+ intr[req->vdev_id].config.gtx_info.gtxRTMask[1] =
+ CFG_TGT_DEFAULT_GTX_VHT_MASK;
+ intr[req->vdev_id].config.gtx_info.gtxUsrcfg =
+ CFG_TGT_DEFAULT_GTX_USR_CFG;
+ intr[req->vdev_id].config.gtx_info.gtxPERThreshold =
+ CFG_TGT_DEFAULT_GTX_PER_THRESHOLD;
+ intr[req->vdev_id].config.gtx_info.gtxPERMargin =
+ CFG_TGT_DEFAULT_GTX_PER_MARGIN;
+ intr[req->vdev_id].config.gtx_info.gtxTPCstep =
+ CFG_TGT_DEFAULT_GTX_TPC_STEP;
+ intr[req->vdev_id].config.gtx_info.gtxTPCMin =
+ CFG_TGT_DEFAULT_GTX_TPC_MIN;
+ intr[req->vdev_id].config.gtx_info.gtxBWMask =
+ CFG_TGT_DEFAULT_GTX_BW_MASK;
+ intr[req->vdev_id].mhz = cmd->mhz;
+
+ WMI_SET_CHANNEL_MODE(cmd, chanmode);
+ cmd->band_center_freq1 = cmd->mhz;
+
+ if (chanmode == MODE_11AC_VHT80)
+ cmd->band_center_freq1 =
+ cds_chan_to_freq(req->ch_center_freq_seg0);
+
+ if ((chanmode == MODE_11NA_HT40) || (chanmode == MODE_11NG_HT40) ||
+ (chanmode == MODE_11AC_VHT40)) {
+ if (req->chan_width == CH_WIDTH_80MHZ)
+ cmd->band_center_freq1 += 10;
+ else
+ cmd->band_center_freq1 -= 10;
+ }
+ cmd->band_center_freq2 = 0;
+
+ /* Set half or quarter rate WMI flags */
+ if (req->is_half_rate)
+ WMI_SET_CHANNEL_FLAG(cmd, WMI_CHAN_FLAG_HALF_RATE);
+ else if (req->is_quarter_rate)
+ WMI_SET_CHANNEL_FLAG(cmd, WMI_CHAN_FLAG_QUARTER_RATE);
+
+ /* Find out min, max and regulatory power levels */
+ WMI_SET_CHANNEL_REG_POWER(cmd, req->max_txpow);
+ WMI_SET_CHANNEL_MAX_TX_POWER(cmd, req->max_txpow);
+
+
+ WMA_LOGE("%s: freq %d channel %d chanmode %d center_chan %d center_freq2 %d reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x",
+ __func__, cmd->mhz, req->chan, chanmode,
+ cmd->band_center_freq1, cmd->band_center_freq2,
+ cmd->reg_info_1, cmd->reg_info_2, req->max_txpow);
+
+
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_PDEV_SET_CHANNEL_CMDID);
+
+ if (ret < 0) {
+ WMA_LOGP("%s: Failed to send vdev start command", __func__);
+ qdf_nbuf_free(buf);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
* wma_set_channel() - set channel
* @wma: wma handle
* @params: switch channel parameters
@@ -2521,17 +2628,30 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
(params->restart_on_chan_switch == true))
wma->interfaces[req.vdev_id].is_channel_switch = true;
- status = wma_vdev_start(wma, &req,
+ if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() &&
+ wma_is_vdev_up(vdev_id)) {
+ status = wma_switch_channel(wma, &req);
+ if (status != QDF_STATUS_SUCCESS)
+ WMA_LOGE("%s: wma_switch_channel failed %d\n", __func__,
+ status);
+
+ ol_htt_mon_note_chan(pdev, req.chan);
+ } else {
+ status = wma_vdev_start(wma, &req,
wma->interfaces[req.vdev_id].is_channel_switch);
- if (status != QDF_STATUS_SUCCESS) {
- wma_remove_vdev_req(wma, req.vdev_id,
- WMA_TARGET_REQ_TYPE_VDEV_START);
- WMA_LOGP("%s: vdev start failed status = %d", __func__, status);
- goto send_resp;
- }
+ if (status != QDF_STATUS_SUCCESS) {
+ wma_remove_vdev_req(wma, req.vdev_id,
+ WMA_TARGET_REQ_TYPE_VDEV_START);
+ WMA_LOGP("%s: vdev start failed status = %d", __func__, status);
+ goto send_resp;
+ }
+
+ if (wma->interfaces[req.vdev_id].is_channel_switch)
+ wma->interfaces[req.vdev_id].is_channel_switch = false;
- if (wma->interfaces[req.vdev_id].is_channel_switch)
- wma->interfaces[req.vdev_id].is_channel_switch = false;
+ if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
+ ol_htt_mon_note_chan(pdev, req.chan);
+ }
return;
send_resp:
WMA_LOGD("%s: channel %d ch_width %d txpower %d status %d", __func__,
diff --git a/target/inc/wlan_tgt_def_config.h b/target/inc/wlan_tgt_def_config.h
index 0a142008cde2..b1a2582fa19d 100644
--- a/target/inc/wlan_tgt_def_config.h
+++ b/target/inc/wlan_tgt_def_config.h
@@ -125,6 +125,8 @@
#define CFG_TGT_RX_DECAP_MODE (0x2)
/* Decap to native Wifi header */
#define CFG_TGT_RX_DECAP_MODE_NWIFI (0x1)
+/* Decap to raw mode header */
+#define CFG_TGT_RX_DECAP_MODE_RAW (0x0)
/* maximum number of pending scan requests */
#define CFG_TGT_DEFAULT_SCAN_MAX_REQS 0x4
diff --git a/uapi/linux/osapi_linux.h b/uapi/linux/osapi_linux.h
index 21f8ff629ab1..a62b96d3f613 100644
--- a/uapi/linux/osapi_linux.h
+++ b/uapi/linux/osapi_linux.h
@@ -231,7 +231,6 @@ void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q);
#include "ath_carr_pltfrm.h"
#endif /* QCA_PARTNER_PLATFORM */
-#define SLOTS_PER_DATAPATH_TX 2
#else /* __KERNEL__ */
#ifdef __GNUC__